On Apr 16, 1:11 am, Jeff Bezanson <
jeff.bezan...@gmail.com> wrote:
> I concede that since we now drop trailing dimensions on ref, it might
> make sense to drop dimensions instead of add them when combining
> shapes.
Yes, sometimes! I argue that not all operations can use the same rule
for this.
> But there is an important subtlety, which is that "singleton
> dimensions" is not really the appropriate concept. We don't drop
> dimensions just because they are of size 1, but because they were
> indexed with scalars. So I'm not too sure.
I'm all against depending on whether an Array dimension is singleton,
for pretty much all other purposes than to decide whether to throw an
error.
Maybe my frequent use of the word "singleton" was confusing, so I
changed my wording to _intentional_ and _nuisance_ dimensions (please
see the end of my last mail for the precise definition of
"intentional!")
What I want to do is to see when I can figure out that some dimension
is a nuisance, relying only on the types of function arguments. The
tool to do this is some small assumptions about which kinds of
operation/argument combinations the user intends/should be allowed to
invoke.
> Actually, we might be able
> to go back to insisting on exact shape matches, since A[:,i]+v will
> now work under that rule.
I haven't thought it through, but I don't think it's a good idea.
There's still two many sources of nuisance dimensions, and there
always will be as long as Array has to overapproximate the set of
intentional dimensions with a range 1:ndims.
> It is weird that v'*v gives a size (1,1) or (1,) array which is
> supposed to be a scalar, but a scalar is more naturally a 0-d array.
> We can't have a vector behave like a scalar just because it has length
> 1. No idea what to do about that. This makes me think that
> mathematically v'*v is not really the same operation as dot(v,v) even
> though they compute the same number. But now I'm out of my depth and
> must step aside.
The way I think about what happens is that
* When v is a vector, intention of v'*v is to produce a scalar, or
possibly a 0-dimensional array.
* Unfortunately, the intermediate step of forming v' adds a nuisance
dimension: the first dimension of v'. (The second dimension of v' is
the original first of v; the intentional one.)
* When it's time to evaluate the product (v')*v, there's no way for *
to know that the second dimension of v' is not intentional.
* So the nuisance dimension (the first of v') remains as a nuisance
dimension in v'*v; this is why it becomes a vector instead of a
scalar.
Mathematically, v'*v should have been a scalar, or at least a 0-d
Array, but v' changed the result.
Now, by writing dot(v, v), the user asserts that the intended result
was indeed a scalar (that's the whole difference between v'*v and
dot(v, v) ), so dot is free to create a scalar result, or throw an
error if it's not possible.
I'm definitely not saying to make all single-element vectors behave
like scalars. I'm just saying that if the only type of value that is
valid in a given situation is a scalar, it's fine to promote an Array
that's passed in to become one (if has numel=1, of course!)