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

Dyalog / APL2000 discrepancy

76 views
Skip to first unread message

Charles Brenner

unread,
Oct 9, 2011, 3:43:53 PM10/9/11
to
­ 1 2+.× (100 200) (400 500)
Seems straightforward, and Dyalog gives me a depth 2 result of
⊂2100 4200.

To my surprise, APL2000 (or APL-PLUS, DOS version 5 or 6) gives an
extra level of nesting, a result of
⊂⊂2100 4200.

I discovered this in the process of porting an application. Apparently
I had coded around the APL+ result by experiment, but I do not see the
justification for it.

Charles

Bob Smith

unread,
Oct 9, 2011, 10:01:47 PM10/9/11
to
On 10/9/2011 3:43 PM, Charles Brenner wrote:
> ­ 1 2+.× (100 200) (400 500)
> Seems straightforward, and Dyalog gives me a depth 2 result of
> ⊂2100 4200.

That is, ⊂900 1200.

> To my surprise, APL2000 (or APL-PLUS, DOS version 5 or 6) gives an
> extra level of nesting, a result of
> ⊂⊂2100 4200.

Interestingly there is a schism amongst APL vendors as to the result depth:

3: APL+Win 3.6, APLX 5.0.5/7.0, APL2 V2.0 SL 16
2: Dyalog 12.1, NARS2000 0.0.3.3

The APL2 Language Reference Manual (p. 165) documents the result as

+/¨(⊂[1]1 2)∘.×⊂[1](100 200)(400 500)
←→ ⊂⊂900 1200

My experience with such expressions is that it is rare for reduction on
nested arrays not to be preceded with disclose, and correspondingly +/¨
should follow ⊃¨, so I would define inner product as the above
expression starting with ⊃¨.

--
_________________________________________
Bob Smith -- bsm...@sudleydeplacespam.com

To reply to me directly, delete "despam".

Charles Brenner

unread,
Oct 9, 2011, 10:45:15 PM10/9/11
to
On Oct 9, 7:01 pm, Bob Smith <bsm...@sudleydeplacespam.com> wrote:
> On 10/9/2011 3:43 PM, Charles Brenner wrote:
>
> >   ­ 1 2+.× (100 200) (400 500)
> > Seems straightforward, and Dyalog gives me a depth 2 result of
> > ⊂2100 4200.
>
> That is, ⊂900 1200.

Yes, bad editing on my part.

> > To my surprise, APL2000 (or APL-PLUS, DOS version 5 or 6) gives an
> > extra level of nesting, a result of
> > ⊂⊂2100 4200.
>
> Interestingly there is a schism amongst APL vendors as to the result depth:
>
> 3:  APL+Win 3.6, APLX 5.0.5/7.0, APL2 V2.0 SL 16
> 2:  Dyalog 12.1, NARS2000 0.0.3.3
>
> The APL2 Language Reference Manual (p. 165) documents the result as
>
> +/¨(⊂[1]1 2)∘.×⊂[1](100 200)(400 500)
> ←→ ⊂⊂900 1200
>
> My experience with such expressions is that it is rare for reduction on
> nested arrays not to be preceded with disclose,

Yes, it's almost instinct. ("preceded" in the sense of order on the
line -- "followed" in the sense of order of operations).

> and correspondingly +/¨ should follow ⊃¨,

That does seem the corresponding thing to do.

> so I would define inner product as the above
> expression starting with ⊃¨.

I think you're right. Someone wanted do define inner product in terms
of other primitives and found an expression that works for non-nested
values. Then -- whatever the historical order -- the same definition
some got slipped in without re-assessment for nested values. Polishing
up with ⊃¨ does no harm in the non-nested case and must be right in
general.

Björn Helgason

unread,
Oct 10, 2011, 12:17:42 PM10/10/11
to
For the lovers of alternate solutions

In J you can do it like this:

1 2 +/ . * > 100 200;400 500
900 1200

or like this:

1 2 * &.> 100 200;400 500
┌───────┬────────┐
│100 200│800 1000│
└───────┴────────┘
and then:

+/ > 1 2 * &.> 100 200;400 500
900 1200

James J. Weinkam

unread,
Oct 11, 2011, 1:30:16 AM10/11/11
to
Bob Smith wrote:
> On 10/9/2011 3:43 PM, Charles Brenner wrote:
>> ­ 1 2+.× (100 200) (400 500)
>> Seems straightforward, and Dyalog gives me a depth 2 result of
>> ⊂2100 4200.
>
> That is, ⊂900 1200.
>
>> To my surprise, APL2000 (or APL-PLUS, DOS version 5 or 6) gives an
>> extra level of nesting, a result of
>> ⊂⊂2100 4200.
>
> Interestingly there is a schism amongst APL vendors as to the result depth:
>
> 3: APL+Win 3.6, APLX 5.0.5/7.0, APL2 V2.0 SL 16
> 2: Dyalog 12.1, NARS2000 0.0.3.3
>
> The APL2 Language Reference Manual (p. 165) documents the result as
>
> +/¨(⊂[1]1 2)∘.×⊂[1](100 200)(400 500)
> ←→ ⊂⊂900 1200
>
> My experience with such expressions is that it is rare for reduction on nested arrays not to be
> preceded with disclose, and correspondingly +/¨ should follow ⊃¨, so I would define inner product as
> the above expression starting with ⊃¨.
>
As I understand it, the "extra" disclose is a consequence of the fact that the right argument is a
nested array. If both arguments are simple arrays so is the result. Since an argument is nested it
seems to me that is is reasonable for the result to be nested.

Bob Smith

unread,
Oct 11, 2011, 4:57:37 PM10/11/11
to

We all agree that the result should be nested -- the question is at what
depth.

To clear up my muddled explanation above, the APL Language Manual for L
LO.RO R says:
----------------------------------
Formally, for nonscalar arguments, inner product is defined in origin-1 as:

LO/¨(⊂[⍴⍴L] L)∘.RO ⊂[1] R
----------------------------------
whereas Charles and I think it should be

⊃¨LO/¨(⊂[⍴⍴L] L)∘.RO ⊂[1] R

Looking at the question from a different point, if the operands to inner
product are primitive scalar functions, I see no reason that the result
should be any deeper than the arguments.

Björn Helgason

unread,
Oct 11, 2011, 5:50:10 PM10/11/11
to
-- We all agree that the result should be nested
-- the question is at what depth.


<<(([: > {.) +/ .* [: > }.) 1 2;100 200;400 500
┌──────────┐
│┌────────┐│
││900 1200││
│└────────┘│
└──────────┘

Phil Last

unread,
Oct 12, 2011, 2:21:32 PM10/12/11
to
While agreeing with Bob's "I see no reason that the result should be
any deeper than the arguments" it would be interesting if anyone could
quote the ISO EAS whether it agrees with the IBM APL2 description or
not.

Roger Hui

unread,
Oct 13, 2011, 1:14:14 AM10/13/11
to
I have two models of inner product in
http://www.jsoftware.com/papers/innerproduct/ip.htm
from 2009, and both of them agree with the Dyalog
and NARS2000 result.

dotc ← {↑ (↓⍺) ∘.(⍺⍺{⍺⍺/⍺ ⍵⍵ ⍵}⍵⍵) ↓(¯1⌽⍳⍴⍴⍵)⍉⍵}
dotr ← {↑ (↓⍺) ⍺⍺{⍺⍺⌿⍺ ⍵⍵[0] ⍵}⍵⍵¨ ⊂⍵}

disp 1 2 + dotc × (100 200) (400 500)
┌────────┐
│900 1200│
└~──────→┘
disp 1 2 + dotr × (100 200) (400 500)
┌────────┐
│900 1200│
└~──────→┘

In the EAS, Section 9.3.2, page 121, both the Informal Description
and the Evaluation Sequence sections call for f/x g y in this case,
and:

disp +/ 1 2 × (100 200) (400 500)
┌────────┐
│900 1200│
└~──────→┘

Bob Smith

unread,
Oct 13, 2011, 8:33:40 AM10/13/11
to
On 10/11/2011 4:57 PM, Bob Smith wrote:
[...]

> whereas Charles and I think it should be
>
> ⊃¨LO/¨(⊂[⍴⍴L] L)∘.RO ⊂[1] R

The situation is more complicated than I had thought: a simple leading
⊃¨ alone doesn't fix it -- we also need to turn g into a scalar function
as in g¨.

On vectors (the simplest case from which array arguments are a simple
structural-only generalization), the APL2 definition is

Lf.gR ←→ f/¨(⊂[⍴⍴L] L)∘. g ⊂[1] R
←→ f/¨(⊂[1 ] L)∘. g ⊂[1] R
←→ f/¨(⊂ L)∘. g ⊂ R
←→ f/¨ ⊂ L g R
←→ ⊂ f/LgR

whereas Dyalog/NARS2000 both use

Lf.gR ←→ ⊃¨f/¨(⊂[⍴⍴L] L)∘.(g¨)⊂[1] R
←→ ⊃¨f/¨(⊂[1 ] L)∘.(g¨)⊂[1] R
←→ ⊃¨f/¨(⊂ L)∘.(g¨)⊂ R
←→ ⊃¨f/¨ ⊂ L g¨ R
←→ ⊃¨⊂f/ L g¨ R
←→ ⊂⊃ f/ L g¨ R
←→ f/Lg¨R

For example, 1 2+.⍴3 4 in APL2 yields

⊂+/1 2⍴3 4
←→ ⊂1⍴7

and the same expression in Dyalog/NARS2000 yields

+/1 2⍴¨3 4
←→ +/(1⍴3) (2⍴4)
←→ ⊂2⍴7

I like the f/Lg¨R form for several reasons:

* The each applies g as a scalar function and for scalar g it is
equivalent to f/LgR;

* The (expected) scalar result for Vf.gV comes naturally out of
reduction of a vector, not from an explicit enclose;

* The reduction is always on a vector and so there is no question as
there is the APL2 definition when LgR produces (say) a matrix as to why
the reduction in f/LgR should apply along the last coordinate instead of
(say) the first coordinate.

I don't expect anyone to change their implementation, so we all need to
be careful around this sharp edge.

Side note: I'm amazed it has taken us this long to realize there is
such a big difference between the various implementations.

Aaron W. Hsu

unread,
Oct 13, 2011, 8:20:44 PM10/13/11
to
On Thu, 13 Oct 2011 08:33:40 -0400, Bob Smith
<bsm...@sudleydeplacespam.com> wrote:

> I like the f/Lg¨R form for several reasons:
> * The each applies g as a scalar function and for scalar g it is
> equivalent to f/LgR;
> * The (expected) scalar result for Vf.gV comes naturally out of
> reduction of a vector, not from an explicit enclose;
> * The reduction is always on a vector and so there is no question as
> there is the APL2 definition when LgR produces (say) a matrix as to why
> the reduction in f/LgR should apply along the last coordinate instead of
> (say) the first coordinate.
> I don't expect anyone to change their implementation, so we all need to
> be careful around this sharp edge.

I don't know enough about APL to properly comment on the *right* way, but
I have to admit that the algebra above leads me to like the f/LgR form
better. :-) At least it is good to know that this difference exists!

Aaron W. Hsu


--
Programming is just another word for the Lost Art of Thinking.

0 new messages