Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

array processing in Lisp

46 views
Skip to first unread message

metaperl.com

unread,
Dec 8, 2007, 6:24:07 PM12/8/07
to
hello,

1 - the term "displaced" is used here:
http://www.lispworks.com/documentation/HyperSpec/Body/15_aacaa.htm

but not defined. What exactly does that mean?


2 - I am wondering if there are any libraries for n-dimensional array
processing built on top of the standard common lisp facilities. I'm
aware of LUSH, but unfortunately, that is not common lisp based.


The reason I ask is that I implemented a good bit of the J (apl
descendant) functionality in Scheme, but am interested in moving
things over to Common Lisp.

Rainer Joswig

unread,
Dec 8, 2007, 6:53:39 PM12/8/07
to
In article
<e9944a6b-563a-4bc1...@f3g2000hsg.googlegroups.com>,
"metaperl.com" <meta...@gmail.com> wrote:

> hello,
>
> 1 - the term "displaced" is used here:
> http://www.lispworks.com/documentation/HyperSpec/Body/15_aacaa.htm
>
> but not defined. What exactly does that mean?

See the :DISPLACED-TO keyword to MAKE-ARRAY.

http://www.lispworks.com/documentation/HyperSpec/Body/f_mk_ar.htm#make-array

In Common Lisp you can create an array that shares the
contents with another array, but maybe differently accessed.
For example the original array could be multi-dimensional
and then you create another array that is single-dimensional,
but points to the contents of the multi-dimensional array.

> 2 - I am wondering if there are any libraries for n-dimensional array
> processing built on top of the standard common lisp facilities. I'm
> aware of LUSH, but unfortunately, that is not common lisp based.
>
>
> The reason I ask is that I implemented a good bit of the J (apl
> descendant) functionality in Scheme, but am interested in moving
> things over to Common Lisp.

--
http://lispm.dyndns.org/

David Golden

unread,
Dec 8, 2007, 7:12:45 PM12/8/07
to
metaperl.com wrote:

> hello,
>
> 1 - the term "displaced" is used here:
> http://www.lispworks.com/documentation/HyperSpec/Body/15_aacaa.htm
>
> but not defined. What exactly does that mean?


http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_d.htm#displaced_array


> 2 - I am wondering if there are any libraries for n-dimensional array
> processing built on top of the standard common lisp facilities. I'm
> aware of LUSH, but unfortunately, that is not common lisp based.
>

http://nlisp.info/index.html ...quite array-y.

http://www.cliki.net/Mathematics - some of these are symbolic, some
numeric.


*** What's the lowest ARRAY-RANK-LIMIT seen in a modern lisp? SBCL
returns 65529, which "ought to be enough for anyone" :-), but I could
see APLers chafing at the minimal standard-compliant limit of 8...


I *thought* I had an unfinished APLoid (using actual APL charset) REPL
in lisp lying about myself, but I seem to have misplaced it or deleted
it (it was crappy anyway, and it became mostly a tiresome exercise in
charset issues). Nowadays there's a de-facto standard APL<->unicode
mapping *, and several lisps support unicode... hmm...

* http://vector.org.uk/resource/uniref.pdf

redick.metaperl.com

unread,
Dec 8, 2007, 7:19:05 PM12/8/07
to
> 2 - I am wondering if there are any libraries for n-dimensional array
> processing built on top of the standard common lisp facilities. I'm
> aware of LUSH, but unfortunately, that is not common lisp based.

Bruno Daniel has crafted up a nifty and efficient interface to MAXIMA:
http://www.math.utexas.edu/pipermail/maxima/2007/009143.html

So that is also something to consider.

redick.metaperl.com

unread,
Dec 8, 2007, 7:38:51 PM12/8/07
to
On Dec 8, 7:12 pm, David Golden <david.gol...@oceanfree.net> wrote:
> metaperl.com wrote:

>
> > 2 - I am wondering if there are any libraries for n-dimensional array
> > processing built on top of the standard common lisp facilities. I'm
> > aware of LUSH, but unfortunately, that is not common lisp based.
>
> http://nlisp.info/index.html...quite array-y.

Yes, it is. I looked at the code. I did not see any support for
creating functions which operate gracefully over arrays of different
rank. That is one of the main contributions of J/APL to array
processing.


>
> http://www.cliki.net/Mathematics - some of these are symbolic, some
> numeric.
>

Thanks for the link. Axiom looks quite good. As does the Octave
interface. And of course Maxima.

> *** What's the lowest ARRAY-RANK-LIMIT seen in a modern lisp? SBCL
> returns 65529, which "ought to be enough for anyone" :-),

ah, so I know what value to use for infinite rank for my verbs now.

> but I could
> see APLers chafing at the minimal standard-compliant limit of 8...
>
> I *thought* I had an unfinished APLoid (using actual APL charset) REPL
> in lisp lying about myself, but I seem to have misplaced it or deleted
> it (it was crappy anyway, and it became mostly a tiresome exercise in
> charset issues).

Yes, J improved on the APL syntax issue of using that non-ASCII
character set. However, J is still a difficult read for most
programmers for a few reasons:

* ambiguous use of symbols
* use of symbols instead of english for functions
* use of symbols which look very similar, thus forcing a lot of visual
parsing... for instance * versus *. versus *:

And of course, the issue for many programmers is that J is not open
source.

David Golden

unread,
Dec 8, 2007, 10:17:11 PM12/8/07
to
redick.metaperl.com wrote:
>
> Yes, it is. I looked at the code. I did not see any support for
> creating functions which operate gracefully over arrays of different
> rank. That is one of the main contributions of J/APL to array
> processing.
>

If you are careful to build up your functions using the primitive nlisp
array functions, they should themselves end up rank agnostic? e.g.
(defun .bloogy (a) (.+ a a)).

You may have meant something else though. nlisp does do some
"agreement" for multi-arg functions. Classic APL only supported
same-shape and scalar-extension, least according to [1], and nlisp
definitely does those. J has "rank conjunction" and more
general "prefix" extension rules though.

nlisp hovers somewhere in-between, at least upon my cursory
investigation (I don't actually use nlisp, preferring my own
half-bakery (yeah, kinda the "lisp disease", I guess)) - it does scalar
extension, for other cases looks like it does a best-effort agreement
with row-major-aref. N.B. I really don't know J remotely well enough
(the not open source thing...) to be authoritative on this, and I don't
doubt it is possible for a competent J programmer to code up whatever
rules they want: J's default rules are (probably, my opinion based
mainly on [1]) far from the only possible ones: think like opengl
texture edge handling rules, so not sure if, even if nlisp was extended
with J's rules, that it would be the right choice.

And also note that IIRC one of nlisp's design goals may be to be
lightweight and "lisp world compatible" - so the row-major-aref
strategy for agreement could be a principle-of-least-surprise thing,
how Joe Lisper would probably first think to do it.

> Yes, J improved on the APL syntax issue of using that non-ASCII
> character set.

I never considered the ASCIIfied APLoids an improvement, myself.:-) Your
other reasons were, after all, related to the ASCIIfication. Obviously,
classic APL had a larger set of distinct non-alphanumeric symbols...

[1] http://burks.bton.ac.uk/burks/language/apl/j4apl/j4apl.htm

Alan Crowe

unread,
Dec 9, 2007, 11:22:07 AM12/9/07
to
"metaperl.com" <meta...@gmail.com> writes:
> 1 - the term "displaced" is used here:
> http://www.lispworks.com/documentation/HyperSpec/Body/15_aacaa.htm
>
> but not defined. What exactly does that mean?
>

I've done a fair bit of assembler in my time. I used to the
idea that one have a block memory and can interpret it in
different ways. For example 12 locations might be both 12 in
a row and a three by four grid.

When you move to a language with array bounds checking you
expect to lose this. If there is a compacting garbage
collector it turns your data into a herd of wildbeest, prone
to disappear on long migrations and your pointer must turn
into leopards and stalk them.

I think that the displacement stuff tries to let you have
the same flexibility that you have in assembler, in
combination with the high-level goodies.

make an array, there is a block a data and a header
describing it
CL-USER> (defparameter *v*
(make-array 12))

fill it with distinct items
CL-USER> (dotimes (i 12 *v*)
(setf (aref *v* i) (gensym)))
#(#:G1563 #:G1564 #:G1565 #:G1566 #:G1567 #:G1568 #:G1569 #:G1570 #:G1571
#:G1572 #:G1573 #:G1574)

Make another array, different header, but reusing the same
data block
CL-USER> (defparameter *m*
(make-array '(3 4) :displaced-to *v*))

Look at the data block through both our astragal
windows. When we see the same item in both panes, print the
indices
CL-USER> (dotimes (i 12)
(dotimes (j 3)
(dotimes (k 4)
(when (eql (aref *v* i)
(aref *m* j k))
(print (list i j k))))))

(0 0 0)
(1 0 1)
(2 0 2)
(3 0 3)
(4 1 0)
(5 1 1)
(6 1 2)
(7 1 3)
(8 2 0)
(9 2 1)
(10 2 2)
(11 2 3)
NIL

I think it gets confusing because adjust-array follows a
different metaphor.

Alan Crowe
Edinburgh
Scotland

lin8080

unread,
Dec 9, 2007, 6:23:54 PM12/9/07
to

Hallo

It is just an idea so please proof.
In cl there is (complex 2.4 3.8) possible. And a complex number is z =
a + ib. Unsualy you go along the x-axis to a = 2.4 and make an
orthogonal plane where you find ib = 3.8 as the single point z.
Now take your z and use it on the y-axis. You get 2 planes defined as
infinite. With growing b's you will find a number of points you can
accsess from the x, y -axes. This is a clear line you can see as a two
dimensional array when you repeat the method z on that line. That needs
4 numbers to describe.
In using the z-coordinate as a complex axis you can find one point in
x(z), y(z) dimension. Here it differs from the array theorie. A cube
like this can be used to adress a virtual memory space or for
cryptology.
...

Albert Krewinkel

unread,
Dec 9, 2007, 6:55:43 PM12/9/07
to
Alan Crowe <al...@cawtech.freeserve.co.uk> writes:

> "metaperl.com" <meta...@gmail.com> writes:
>> 1 - the term "displaced" is used here:
>> http://www.lispworks.com/documentation/HyperSpec/Body/15_aacaa.htm
>>
>> but not defined. What exactly does that mean?
>>
>
> I've done a fair bit of assembler in my time. I used to the
> idea that one have a block memory and can interpret it in
> different ways. For example 12 locations might be both 12 in
> a row and a three by four grid.
>
> When you move to a language with array bounds checking you
> expect to lose this. If there is a compacting garbage
> collector it turns your data into a herd of wildbeest, prone
> to disappear on long migrations and your pointer must turn
> into leopards and stalk them.
>
> I think that the displacement stuff tries to let you have
> the same flexibility that you have in assembler, in
> combination with the high-level goodies.
>

[snip: intuitive code examples]


>
> I think it gets confusing because adjust-array follows a
> different metaphor.
>
> Alan Crowe
> Edinburgh
> Scotland

Though I don't need this often and can work around this problem, but I'm
wondering for quite a while now: Is there a way of displacing an array
column instead of a row? The only way I came up with seems, well,
cumbersome at best (I didn't implement this):

I'd place the actual array values in cons cells, so that it's easy to
pass 'pointers' when copying some (non-adjecent) parts of the array.

(defparameter *v1*
(make-array '(2 3) :initial-contents
(list (mapcar #'list '(1 2 3))
(mapcar #'list '(4 5 6)))))
(defparameter *v2*
(let ((array (make-array 2)))
(setf (aref array 0) (aref *v1* 0 0)
(aref array 1) (aref *v1* 0 1))
array))

*v2* => #((1) (2))

(setf (car (aref *v2* 0)) 9)

*v2* => #((9) (2))

*v1* => #2A(((9) (2) (3)) ((4) (5) (6)))

Of course, macros/setf-specializers would make the handling of such
constructs quite easy, but it just doesn't seem right. I believe/fear
that understanding this could be essential to 'get' efficient handling
of arrays in CL. Hints are higly appreciated.

--
Albert Krewinkel

metaperl.com

unread,
Dec 10, 2007, 5:40:11 AM12/10/07
to
On Dec 8, 10:17 pm, David Golden <david.gol...@oceanfree.net> wrote:

> with row-major-aref. N.B. I really don't know J remotely well enough
> (the not open source thing...) to be authoritative on this,

The best reference for how J deals with array rank when executing a
function is described in J for C Programmers:
http://www.jsoftware.com/help/jforc/loopless_code_i_verbs_have_r.htm#_Toc141157986
http://www.jsoftware.com/help/jforc/loopless_code_i_verbs_have_r.htm#_Toc141157992

It is exactly what my Scheme code was based on.


>
> And also note that IIRC one of nlisp's design goals may be to be
> lightweight and "lisp world compatible" - so the row-major-aref
> strategy for agreement could be a principle-of-least-surprise thing,
> how Joe Lisper would probably first think to do it.

A lot of J primitives operate on array "items" - items being a list of
the "inner arrays"... so if you have a 2x3x4 array, it would have 2
items of dimension 3x4.

The chicken scheme array-lib library had a sweet function called array-
split that you could give any dimension of an array and it would
return a list of subarrays, splitting the original array at that
dimension... it was a highly useful function.

>
> > Yes, J improved on the APL syntax issue of using that non-ASCII
> > character set.
>
> I never considered the ASCIIfied APLoids an improvement, myself.:-)

oh, basically both J and APL are a huge eyesore to anyone with a
background in "normal" languages. Meaning anything else you see in the
Alioth Shootout. English function names beat glyphs and cryptic ASCII
for me (and most people turned off by J/APL).

> Your
> other reasons were, after all, related to the ASCIIfication. Obviously,
> classic APL had a larger set of distinct non-alphanumeric symbols...

symbols have to be learned... English names are pretty innate.

metaperl.com

unread,
Dec 10, 2007, 6:06:47 AM12/10/07
to
On Dec 9, 11:22 am, Alan Crowe <a...@cawtech.freeserve.co.uk> wrote:

>
> I think that the displacement stuff tries to let you have
> the same flexibility that you have in assembler, in
> combination with the high-level goodies.

Ok, I get it, you have the ability to perceive and manipulate the same
data elements but with different rank paradigms. The 12 items below
were made into a rank-1 array. And then "displaced" as a rank-2 array.
And could've been displaced as a rank-3 array.

However, I have never encountered a case where this degree of
flexibility was useful. Can you provide a case where this is valuable?

>
> make an array, there is a block a data and a header
> describing it

Yes, you are using the word "header" to mean a plist/alist/etc which
tells you how to conceptualize the data. The header would probably
consist of a dimension list.


> CL-USER> (defparameter *v*
> (make-array 12))
>
> fill it with distinct items
> CL-USER> (dotimes (i 12 *v*)

I managed to get this to work without listing *v* in dotimes:
(dotimes (i 12) (setf (aref v i) (gensym)))

Thanks for the explanation,
Terrence

jivest...@gmail.com

unread,
Dec 10, 2007, 7:08:59 AM12/10/07
to
About the usefulness of displacements:

Displaced-to can be very useful when mapping from many dimensions to
one dimension,
since CL has rather few operations that operate on multi-dimensional
arrays,
but many that operate on sequences.

Example:
(defun set-array! (a val)
(let ((result (make-array (array-total-size a) :displaced-to a)))
(map-into result #'(lambda (x) val) result)
a))

CL-USER> (set-array! (make-array '(2 2 2)) 4)
#3A(((4 4) (4 4)) ((4 4) (4 4)))

Similar examples can be made for map, copy and find, as well as
general iterations.

Jørn Inge


David Golden

unread,
Dec 10, 2007, 7:27:48 AM12/10/07
to
metaperl.com wrote:

> However, I have never encountered a case where this degree of
> flexibility was useful. Can you provide a case where this is valuable?
>

Note, for example, that if I had a 2x3x4 array in lisp, I could use
displacement to e.g. make a 2-element vector with elements that are 3x4
arrays out of it (without the overhead of copying, though one
must then be careful since there will be structure-sharing, as
illustrated below).

Now, say I wanted to implement some functional language that worked in
terms of arrays being composed of subarray "items", efficiently...


(let* ((a (make-array '(2 3 4) :initial-contents
'((( 0 1 2 3) ( 4 5 6 7) ( 8 9 10 11))
((12 13 14 15) (16 17 18 19) (20 21 22 23)))
))
(b (make-array 2 :initial-contents
(list (make-array '(3 4) :displaced-to a
:displaced-index-offset 0)
(make-array '(3 4) :displaced-to a
:displaced-index-offset (* 3 4))))))
(print "A is:")
(print a)
(print "B is:")
(print b)
(setf (aref a 1 1 1) 666)
(print "A is now:")
(print a)
(print "B is now:")
(print b)
nil)


David Golden

unread,
Dec 10, 2007, 7:28:58 AM12/10/07
to
metaperl.com wrote:
>
> symbols have to be learned... English names are pretty innate.

Innate?! Er. "English" names are learned too. English isn't
some sort of language of the gods. Anyway, I wasn't arguing for APL
symbols particularly, but given the choice between the full set of
visually distinctive APL symbols and the ASCIIfication attempts, I
prefer the APL symbols. And hey, they're now in unicode (though of
course that doesn't mean all fonts actually include them, several do).

Alan Crowe

unread,
Dec 10, 2007, 11:06:00 AM12/10/07
to
"metaperl.com" <meta...@gmail.com> writes:

> On Dec 9, 11:22 am, Alan Crowe <a...@cawtech.freeserve.co.uk> wrote:
>
> >
> > I think that the displacement stuff tries to let you have
> > the same flexibility that you have in assembler, in
> > combination with the high-level goodies.
>
> Ok, I get it, you have the ability to perceive and manipulate the same
> data elements but with different rank paradigms. The 12 items below
> were made into a rank-1 array. And then "displaced" as a rank-2 array.
> And could've been displaced as a rank-3 array.
>
> However, I have never encountered a case where this degree of
> flexibility was useful. Can you provide a case where this is valuable?

The only example I know is in computing Discrete Fourier
Transforms. You can compute a 35 point transform as seven 5
point transforms, a bit of twiddling, five 7 point
transforms and an unshuffle.

> > CL-USER> (dotimes (i 12 *v*)
>
> I managed to get this to work without listing *v* in dotimes:
> (dotimes (i 12) (setf (aref v i) (gensym)))

Did you spot that when you left out the *v* the dotimes form
returned NIL?

Alan Crowe
Edinburgh
Scotland

John Thingstad

unread,
Dec 10, 2007, 3:48:23 PM12/10/07
to
På Mon, 10 Dec 2007 12:06:47 +0100, skrev metaperl.com
<meta...@gmail.com>:

> On Dec 9, 11:22 am, Alan Crowe <a...@cawtech.freeserve.co.uk> wrote:
>
>>
>> I think that the displacement stuff tries to let you have
>> the same flexibility that you have in assembler, in
>> combination with the high-level goodies.
>
> Ok, I get it, you have the ability to perceive and manipulate the same
> data elements but with different rank paradigms. The 12 items below
> were made into a rank-1 array. And then "displaced" as a rank-2 array.
> And could've been displaced as a rank-3 array.
>
> However, I have never encountered a case where this degree of
> flexibility was useful. Can you provide a case where this is valuable?
>

I wrote a tic-tac-toe implementation earlier this year.

http://home.online.no/~jpthing/games/tictactoe.html

(defconstant +rule-list+
'(((#\- #\O #\O) (#\O #\O #\O))
((#\O #\- #\O) (#\O #\O #\O))
((#\O #\O #\-) (#\O #\O #\O))
((#\- #\X #\X) (#\O #\X #\X))
((#\X #\- #\X) (#\X #\O #\X))
((#\X #\X #\-) (#\X #\X #\O))
((#\- #\X #\-) (#\O #\X #\-))
((#\- #\- #\X) (#\- #\O #\X))
((#\X #\- #\-) (#\X #\O #\-))
((#\- #\X #\O) (#\O #\X #\O))
((#\- #\O #\X) (#\O #\O #\X))
((#\X #\- #\O) (#\X #\O #\O))
((#\X #\O #\-) (#\X #\O #\O))
((#\O #\- #\X) (#\O #\O #\X))
((#\O #\X #\-) (#\O #\X #\O))
((#\- #\- #\O) (#\O #\- #\O))
((#\- #\O #\-) (#\O #\O #\-))
((#\O #\- #\-) (#\O #\- #\O))
((#\- #\- #\-) (#\- #\O #\-))))

(defun match-row (board f1 f2 f3 rule)
(destructuring-bind (pattern substitution) rule
(destructuring-bind (v1 v2 v3) pattern
(if (and (char= (row-major-aref board f1) v1)
(char= (row-major-aref board f2) v2)
(char= (row-major-aref board f3) v3))
(destructuring-bind (s1 s2 s3) substitution
(setf (row-major-aref board f1) s1)
(setf (row-major-aref board f2) s2)
(setf (row-major-aref board f3) s3)
substitution)
nil))))

(defun try-moves (board rules)
(dolist (rule rules)
(let ((move (or (match-row board 0 4 8 rule)
(match-row board 2 4 6 rule)
(match-row board 0 1 2 rule)
(match-row board 3 4 5 rule)
(match-row board 6 7 8 rule)
(match-row board 0 3 6 rule)
(match-row board 1 4 7 rule)
(match-row board 2 5 8 rule))))
(when move (return-from try-moves move)))))

This looks for the pattern on the rows, columns and diagonals and applies
the substitution is there is a match.
When displaying the board I see it as a 3x3 array. When matching it I see
it as a flat 9 element array.
This simplifies the logic here as I can specify only one value for each
element instead of a tuple.
(Note that instead of using row-major-aref I could just as easily have
used a displaced array to achieve this.)

--------------
John Thingstad

Bruno Daniel

unread,
Dec 11, 2007, 8:33:12 AM12/11/07
to
> Yes, J improved on the APL syntax issue of using that non-ASCII
> character set. However, J is still a difficult read for most
> programmers for a few reasons:
>
> * ambiguous use of symbols
> * use of symbols instead of english for functions
> * use of symbols which look very similar, thus forcing a lot of visual
> parsing... for instance * versus *. versus *:

Most J fans would prefer symbols to english names for the same reason that
mathematicians and physicists prefer symbols to operators in their formulas:
They can understand an expression at a single glance. Think of Maxwell's
equations or the Schroedinger equation using English words instead of symbols
and you'll see what I mean.

On the other hand I don't think that J really accomplishes this. In order to
be able to read a formula fast, the symbols have to be quite distinct from
each other, avoiding ambiguity at all costs. It is especially problematic that
on fast reading you cannot immediately see whether a verb is used monadically
or dyadically because this depends on its position in a verb train and whether
the whole train is a hook or a fork; the matter is further complicated by
adverbs and conjunctions. Only after knowing for each verb the valence in the
expression (i.e. its being monadic or dyadic) you can understand a J
expression. For a long tacit expression you would have to write the valences
down first and this is not what I consider reading at a single glance.

This can be fixed by learning a lesson from Lisp: If you require the
programmer to separate atoms by spaces from each other (you cannot write (+3a)
in Lisp but you'll have to use (+ 3 a) or (nfx 3 + a) in the infix package
http://www.cliki.net/infix ) , you are free to introduce combinations of
multiple symbols and alphanumeric characters as function names (or verbs,
adverbs and conjunctions in J lingo) names. That's why I propse the following
changes for a future version of J:

* Require the programmer to separate atoms by spaces (of course not after
or before opening and closing parentheses, like in (3 + a) * 4).
* Allow all combinations of printable ASCII characters as symbols, e.g.
2* (for monadic +:), ^2 (for monadic *:), %2 (for monadic -:), ++ (for
monadic >:), -- (for monadic <:).
* Use these combinations for disambiguating most monads from dyads, e.g.
## for copy and # for tally, ~ for passive, ~~ for reflex, / for insert,
// for table, & for bond, oo for compose, || (for monadic |, meaning abs),
| for (dyadic |, meaning residue),
and for introducing abbreviations, e.g. int1 for monadic 1 & + @: i.,
** for +/ . *, ^T for monadic transpose,
and common idioms that constitute a notion in themselves, like /\ for
/ \, +/ for + /
* Introduce as a convention that user-defined adverbs carry a dot in the end
of the name and conjunctions in the beginning. Then Emacs and other editors
will be able to display them in different colors (maybe even making the
dot invisible, the same could be done for cap) and it will be easy to read
even very complicated tacit verbs.
* I also don't like using [, {, ", ( unpaired, but that is just a matter of
taste.

Here are some examples:

;; An adverb for a table of the Chebyshev coefficients
;; in standard J (see
;; http://www.jsoftware.com/help/jforc/a_first_look_at_j_programs.htm#_Toc141157970)
;; chebft =: adverb define :
;; f =. u 0.5 * (+/y) - (-/y) * 2 o. o. (0.5 + i. x) % x
;; (2 % x) * +/ f * 2 o. o. (0.5 + i. x) *"0 1 (i. x) % x
;; )
;; proposal:
chebftable. .= (f -> n ab ->
(fvals .= f %2 (+/ ab) - (-/ ab) * cos pi* (int.5 n) % n)
((2 % n) * +/ fvals * cos pi* (int.5 n) * '01 (int n) % n))

;; Histogram
;; standard J, see
;; http://www.jsoftware.com/help/jforc/forks_hooks_and_compound_adv.htm#_Toc141158229
;; histogram =: ~. ,. #/.~
;; proposal
histogram =. distinct ,. # on-keys. ~~

;; wordcount, (same page)
;; WS =: ' ',TAB,LF
;; wc3 =: (# , (*. -.@(|.!.0))@(e.&WS) , +/@(LF&=))@ReadFile
;; proposal:
whitespace .= " \t\n"
word-count =. (# , (and not o (shift :with 0)) o (in & whitespace) ,
+/ o ("\n" & =)) o read-file

;; Hamming code
;; standard J:
;; ham=: 3 : 'y{.(2 3 5&([: /:~@~.@, ] , */))^:((+:y)>:#)^:_] 1'
;; proposal:
hamming .=. (y -> y take
(2 3 5 & (cp sort-up o distinct o flatten y_ , *//))
.while ((2* y) >= #) 1)

;; Quicksort
;; Standard J:
;; quicksort=: (($:@(<#[) , (=#[) , $:@(>#[)) ({~ ?@#)) ^: (1<#)
;; proposal:
quicksort .=. ((self o (< ## x_) , (= ## x_) , self o (> ## y_))
(@~ roll o #))
.if (1 < #)

;; Display the Mandelbrot set in ascii characters:
;; standard J:
;; {&'#.' @ (2:<|) @ ((+*:)^:400 0:) (18 %~ i:_20) j.~/ 28 %~ _59+i.75
;; proposal:
(c -> @ "#." 2 < || (z -> c + ^2 z) .^ 400 (0))
(18 %~ int -20) <j ~ // 28 %~ -59 + int 75

;; Gram-Schmidt in standard J, see
;; http://www.nabble.com/reduce-fold-in-J-as-an-adverb-or-conjuction-to13844580s24193.html#a13844580
;; mp=:+/.*
;; norm=:%%:@mp~
;; orth=:]-+/@(mp*[)
;; GS1=:,:@norm@{.([,norm@orth)R.}.
;; Gram-Schmidt:
renorm =. 1% sqrt o **~~
orth =. y_ - +/ o (** * x_) ;; x = vectors so far, y = new vector
gram-schmidt .=. ,: o renorm o head (x_ , renorm o orth) reduce. behead

pi-approx .= 6 * (2 ^ 8) * (sqrt (%2 1- sqrt (1- ^2 x))) .^ 8 (0.5)
mean .=. +/ % #
dev .=. (- mean) '1
sum-sqr-dev .=. +/ o ^2 o dev
variance .=. (sum-sqr-dev % -- o #) '1
std-dev .=. sqrt o variance
sum-cross-prods .=. (** ~ ^T) o dev
covariance .=. sum-cross-prods % -- o #
correlation .=. covariance % */ o std-dev
harmonic-mean .=. mean .u. 1%
geometric-mean .=. mean .u. ln
geometric-mean .=. */ root ~ #
weighted-sum .=. * % +/ o. y_

... and so on.

Best regards
Bruno Daniel

0 new messages