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

jot-dot again

89 views
Skip to first unread message

luserdroog

unread,
Jun 9, 2014, 2:28:22 AM6/9/14
to
Using the definition for Outer Product from the Iverson paper "Programming Style
In APL", R←A∘.fB, for array A of rank 3 and array B of rank 4,
R[H;I;J;K;L;M;N]←→A[H;I;J] f B[K;L;M;N]
, and the further notion of converting multiple indices into a single index
on the ravel, I've implemented a new jotdot for inca2.

https://github.com/luser-dr00g/inca/blob/318dc7677c6b8c7c5e63d9b0d2aba33d2058706a/inca2.c#L302

I idx(I*vec,I*dims,I n){
I z=*vec;
DO(n-1,z*=dims[i+1];z+=vec[i+1])
R z;
}

I *vdx(I ind,I*dims,I n){
I t=ind,*z=ma(n);
DO(n,z[n-1-i]=t%dims[n-1-i];t/=dims[n-1-i])
R z;
}

ARC jotdot(ARC a, I f, ARC w){
I *d=ma(AR(a)+AR(w));
mv(d,AD(a),AR(a));
mv(d+AR(a),AD(w),AR(w));
ARC z=ga(AT(w),AR(a)+AR(w),d);
ARC sa,sw,sz;
switch(AT(z)){
CASE INT: sa=scalarI(0); sw=scalarI(0);
DO(AN(z),
*AV(sa)=AV(a)[idx(vdx(i,d,AR(z)),d,AR(a))];
*AV(sw)=AV(w)[idx(vdx(i,d,AR(z))+AR(a),d+AR(a),AR(w))];
sz=vd(f,sa,sw);
AV(z)[i]=*AV(sz); )
CASE DBL: sa=scalarD(0); sw=scalarD(0);
DO(AN(z),
*(D*)AV(sa)=((D*)AV(a))[idx(vdx(i,d,AR(z)),d,AR(a))];
*(D*)AV(sw)=((D*)AV(w))[idx(vdx(i,d,AR(z)),d+AR(a),AR(w))];
sz=vd(f,sa,sw);
((D*)AV(z))[i]=*(D*)AV(sz); )
}

R z;
}

This code has the appalling inefficiency of allocating a new index vector
(twice!) for every element. And no GC, yet. So that's really really bad.

On the other hand: It's producing results!

I've eliminated the "jot" symbol so I don't have to devote a symbol to it,
and jot-dot follows a monadic-operator syntax, following the function, Af.B .

./inca2
a<~4
2:4
0 1 2 3

b<a+.a
2:4 4
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6

b+.b
2:4 4 4 4
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6


1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7


2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8


3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9




1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7


2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8


3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9


4 5 6 7
5 6 7 8
6 7 8 9
7 8 9 10




2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8


3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9


4 5 6 7
5 6 7 8
6 7 8 9
7 8 9 10


5 6 7 8
6 7 8 9
7 8 9 10
8 9 10 11




3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9


4 5 6 7
5 6 7 8
6 7 8 9
7 8 9 10


5 6 7 8
6 7 8 9
7 8 9 10
8 9 10 11


6 7 8 9
7 8 9 10
8 9 10 11
9 10 11 12





b+.a
2:4 4 4
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6


1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7


2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8


3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9



luserdroog

unread,
Jun 11, 2014, 6:21:10 AM6/11/14
to
On Monday, June 9, 2014 1:28:22 AM UTC-5, luserdroog wrote:
> Using the definition for Outer Product from the Iverson paper "Programming Style
>
> In APL", R←A∘.fB, for array A of rank 3 and array B of rank 4,
>
> R[H;I;J;K;L;M;N]←→A[H;I;J] f B[K;L;M;N]
>
> , and the further notion of converting multiple indices into a single index
> on the ravel, I've implemented a new jotdot for inca2.
>
> https://github.com/luser-dr00g/inca/blob/318dc7677c6b8c7c5e63d9b0d2aba33d2058706a/inca2.c#L302
>
>

Inner product appears to have a similar definition that's more
complicated to implement. R←Af.gB, for array A of rank 3 and array B of rank 4,

R[H;I;J;K] ←→ f / A[H;I;] g B[;J;K]

This way requires taking slices of the arrays. The slices of A are always
on the first dimension, so that's easy, but the other one ... ?? Still working
on that.

But it simplifies to the same case if we shuffle off the complexity to
the transpose function. Then just transpose B appropriately and take the
easy row slices.

But there are at least two other ways I've run across, one using enclose
each and axis.

f/¨ (⊂[⍴⍴A]A)∘.g⊂[1]B

And one using just axis slices.

z[i;j]←→f/x[i;] g y[;j]

And then Roger Hui's "row-at-a-time" version.

z[i;]←→f⌿x[i;] g[0] y

So, it's looks like the choice is: axis operator/function syntax
or crazy transposes. Ack!

Thanks for listening.

luserdroog

unread,
Jun 20, 2014, 1:53:17 AM6/20/14
to
On Wednesday, June 11, 2014 5:21:10 AM UTC-5, luserdroog wrote:
> On Monday, June 9, 2014 1:28:22 AM UTC-5, luserdroog wrote:
>
> > , and the further notion of converting multiple indices into a single index
> > on the ravel,

This appears to be much more crucial than just a "notion",
but yet another generalized, unifying concept. Converting
a vector of indices into a single index on the ravel is
our old friend base-decode with a weighting-vector,
motherfuckin' "Horner's Rule", yall!

And the reverse task of converting an index on the ravel
to a new indexing vector, from a new "interpretation" of
the implicit *linear* ordering, is the old trick duo mod
and integer-divide (or floor(div())), in a loop or an
iteration or a recursive decomposition or something.
Unless there's a simpler, cooler way I don't know about,
you have to do it over and over again to peel-off each
digit. This is the same technique I wrote about over on
code-golf describing ASCII85.
http://codegolf.stackexchange.com/a/8849/2381
The same way you print integers in assembly class (+0x30,
of course). "Digital" arithmetic, Holmes.

>>I've implemented a new jotdot for inca2.
> >
> > https://github.com/luser-dr00g/inca/blob/318dc7677c6b8c7c5e63d9b0d2aba33d2058706a/inca2.c#L302
> >
> >
>
> Inner product appears to have a similar definition that's more
> complicated to implement. R←Af.gB, for array A of rank 3 and array B of rank 4,
>
> R[H;I;J;K] ←→ f / A[H;I;] g B[;J;K]
>
> This way requires taking slices of the arrays. The slices of A are always
> on the first dimension, so that's easy, but the other one ... ?? Still working
> on that.
>
> But it simplifies to the same case if we shuffle off the complexity to
> the transpose function. Then just transpose B appropriately and take the
> easy row slices.
>
> But there are at least two other ways I've run across, one using enclose
> each and axis.
>
> f/¨ (⊂[⍴⍴A]A)∘.g⊂[1]B
>
> And one using just axis slices.
>
> z[i;j]←→f/x[i;] g y[;j]
>
> And then Roger Hui's "row-at-a-time" version.
>
> z[i;]←→f⌿x[i;] g[0] y
>
> So, it's looks like the choice is: axis operator/function syntax
> or crazy transposes. Ack!
>
> Thanks for listening.

Still haven't written this stuff. But I think this dawning significance
of the linear combination/digits epiphany will yield results given the
appropriate nurture. Theretofore I have just polished off two 70's data
structures books. (What ever happened to SNOBOL?) And I'm now going
through "APL: The Language and its Usage", circa 1975.

I'm thinking a lot about how to add the char type concisely.
Should it "overflow" into an int when subjected to arithmetic?
Or it that normally a domain error?


--
in defiance of Carl Sagan's edict, I only read
Kant while stoned.
0 new messages