inconsitency in behavior of 'size'

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

inconsitency in behavior of 'size'

Sergei Steshenko
Hello  All,

I am using an old self-built octave-3.6.4 and observe the following - see copy-paste of an interactive session:

"
octave:39> im = \
> [
> 1 90 100
> 2 80 110
> 3 70 105
> 4 60 104
> ]
im =

     1    90   100
     2    80   110
     3    70   105
     4    60   104

octave:40> ([_1,_2] = sort(im(:, 3), "descend"))
_1 =

   110
   105
   104
   100

_2 =

   2
   3
   4
   1

octave:41> size(([_1,_2] = sort(im(:, 3), "descend")))
ans =

   4   1

octave:42> size([_1,_2])
ans =

   4   2

octave:43> [_1,_2]
ans =

   110     2
   105     3
   104     4
   100     1

octave:44>
".

IMO the inconsistency is in command 41 output, which is

4  1

, i.e. 4 rows and 1 column vs output of command 42, which is

4  2

, i.e. 4 rows and 2 columns, and I think the latter is the correct output.

Pay attention that in both cases essentially size of [_1,_2] expression is calculated, but in the first case the expression is also first assigned its value from call to 'sort' while in the second case it's just the expression.

Is it the way it is supposed to be ? If yes, is it described somewhere in Octave documentation ?

How does Matlab behave in the same case ?

...

Yet another point I'm trying to make is that type of the [_1,_2] expression is inherited from the call to 'sort', and also the type is induced by the two output arguments call, and IMO the type shouldn't changed unless forced to change by some other function/conversion.

Thanks,
  Sergei.


-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: inconsitency in behavior of 'size'

nrjank
On Fri, Mar 9, 2018 at 1:37 PM, Sergei Steshenko <[hidden email]> wrote:
Hello  All,

I am using an old self-built octave-3.6.4 and observe the following - see copy-paste of an interactive session:

"
octave:39> im = \
> [
> 1 90 100
> 2 80 110
> 3 70 105
> 4 60 104
> ]
im =

     1    90   100
     2    80   110
     3    70   105
     4    60   104

octave:40> ([_1,_2] = sort(im(:, 3), "descend"))
_1 =

   110
   105
   104
   100

_2 =

   2
   3
   4
   1

octave:41> size(([_1,_2] = sort(im(:, 3), "descend")))
ans =

   4   1

octave:42> size([_1,_2])
ans =

   4   2

octave:43> [_1,_2]
ans =

   110     2
   105     3
   104     4
   100     1

octave:44>
".

IMO the inconsistency is in command 41 output, which is

4  1

, i.e. 4 rows and 1 column vs output of command 42, which is

4  2

, i.e. 4 rows and 2 columns, and I think the latter is the correct output.

Pay attention that in both cases essentially size of [_1,_2] expression is calculated, but in the first case the expression is also first assigned its value from call to 'sort' while in the second case it's just the expression.

Is it the way it is supposed to be ? If yes, is it described somewhere in Octave documentation ?

How does Matlab behave in the same case ?



matlab 2017b cannot handle the 'assignment within size' construct  (it also doesn't like variables starting with _ or double quotes)



>> size([a1,a2] = sort(im(:,3),'descend'))
 size([a1,a2] = sort(im(:,3),'descend'))
              ↑
Error: The expression to the left of the equals sign
is not a valid target for an assignment.
 

but
>> size([a1,a2])

ans =

     4     2


-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: inconsitency in behavior of 'size'

Mike Miller-4
In reply to this post by Sergei Steshenko
On Fri, Mar 09, 2018 at 18:37:02 +0000, Sergei Steshenko wrote:
> Pay attention that in both cases essentially size of [_1,_2]
> expression is calculated, but in the first case the expression is also
> first assigned its value from call to 'sort' while in the second case
> it's just the expression.

I think it might help first to agree that '[x,y]' is syntax that
declares an array, but '[x,y] = something' is a different assignment
syntax that assigns two return values to x and y independently.

If you have a background in C you might assume that the *value* of the
overall assignment expression is the same as the value '[x,y]'. But it's
very important to note that '[x,y]' in assigment syntax is not actually
instantiating an array composed from x and y.

Now, compare the values of the following

    ([_1,_2] = sort(im(:, 3), "descend"))
    ([_1,_2] = sort(im(:, 3), "descend"))(:)
    [[_1,_2] = sort(im(:, 3), "descend")]
    {[_1,_2] = sort(im(:, 3), "descend")}

I don't have any documentation or code to point at, but I would venture
to say that when an assignment to multiple return values is used in
another expression, the value of the expression is that of the first
return value only.

> How does Matlab behave in the same case ?

Matlab does not allow assignments to be used as expressions.

--
mike


-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: inconsitency in behavior of 'size'

Sergei Steshenko





________________________________
From: Mike Miller <[hidden email]>
To: [hidden email]
Sent: Friday, March 9, 2018 9:28 PM
Subject: Re: inconsitency in behavior of 'size'


On Fri, Mar 09, 2018 at 18:37:02 +0000, Sergei Steshenko wrote:
> Pay attention that in both cases essentially size of [_1,_2]
> expression is calculated, but in the first case the expression is also
> first assigned its value from call to 'sort' while in the second case
> it's just the expression.

I think it might help first to agree that '[x,y]' is syntax that
declares an array, but '[x,y] = something' is a different assignment
syntax that assigns two return values to x and y independently.

If you have a background in C you might assume that the *value* of the
overall assignment expression is the same as the value '[x,y]'. But it's
very important to note that '[x,y]' in assigment syntax is not actually
instantiating an array composed from x and y.

Now, compare the values of the following

    ([_1,_2] = sort(im(:, 3), "descend"))
    ([_1,_2] = sort(im(:, 3), "descend"))(:)
    [[_1,_2] = sort(im(:, 3), "descend")]
    {[_1,_2] = sort(im(:, 3), "descend")}

I don't have any documentation or code to point at, but I would venture
to say that when an assignment to multiple return values is used in
another expression, the value of the expression is that of the first
return value only.


> How does Matlab behave in the same case ?

Matlab does not allow assignments to be used as expressions.

--
mike

-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018

-----------------------------------------

"
I think it might help first to agree that '[x,y]' is syntax that
declares an array, but '[x,y] = something' is a different assignment
syntax that assigns two return values to x and y independently" - I don't agree with that. Because the final result, which is
[_1,_2], is the same - regardless whether I do the assignment as

([_1,_2] = sort(im(:, 3), "descend"))

or

[_1,_2] = sort(im(:, 3), "descend").

Really, don't create the entities beyond the necessary, i.e. don't change type beyond the necessary.

Thanks,
  Sergei.


-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: inconsitency in behavior of 'size'

Mike Miller-4
On Fri, Mar 09, 2018 at 21:42:37 +0000, Sergei Steshenko wrote:
> I don't agree with that. Because the final result, which is
> [_1,_2], is the same - regardless whether I do the assignment as
>
> ([_1,_2] = sort(im(:, 3), "descend"))
>
> or
>
> [_1,_2] = sort(im(:, 3), "descend").

Then that seems to be where your misunderstanding is. Both of those
statements are equivalent, but the syntax [_1,_2] on the left hand side
of the assignment is not a matrix, it is a comma-separated list.

https://www.gnu.org/software/octave/doc/interpreter/Comma-Separated-Lists.html
https://www.mathworks.com/help/matlab/matlab_prog/comma-separated-lists.html

--
mike


-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: inconsitency in behavior of 'size'

Sergei Steshenko





________________________________
From: Mike Miller <[hidden email]>
To: "[hidden email]" <[hidden email]>
Sent: Saturday, March 10, 2018 10:44 AM
Subject: Re: inconsitency in behavior of 'size'


On Fri, Mar 09, 2018 at 21:42:37 +0000, Sergei Steshenko wrote:
> I don't agree with that. Because the final result, which is
> [_1,_2], is the same - regardless whether I do the assignment as
>
> ([_1,_2] = sort(im(:, 3), "descend"))
>
> or
>
> [_1,_2] = sort(im(:, 3), "descend").

Then that seems to be where your misunderstanding is. Both of those
statements are equivalent, but the syntax [_1,_2] on the left hand side
of the assignment is not a matrix, it is a comma-separated list.

https://www.gnu.org/software/octave/doc/interpreter/Comma-Separated-Lists.html
https://www.mathworks.com/help/matlab/matlab_prog/comma-separated-lists.html


--
mike

-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018

-----------------------------------------

"it is a comma-separated list" - again, doesn't make sense to me.

Because you are telling me that <FOO> and (<FOO>) are different.

And exactly because of my familiarity with "C" I consider them to be the same, and the parenthesis are just for readability.

I.e. in "C"

foo = bar = f(doo); and "foo = (bar = f(doo));" is the same, and "if(foo = f(doo))" and "if((foo = f(doo)))" are the same, though the compiler rightly suggests parenthesis in the former case because it suspects the programmer meant '==' instead of '='.

...

Never mind, Matlab/Octave language sucks anyway.


--Sergei.


-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: inconsitency in behavior of 'size'

Mike Miller-4
On Sat, Mar 10, 2018 at 13:26:18 +0000, Sergei Steshenko wrote:
> Because you are telling me that <FOO> and (<FOO>) are different.

No, if you read what I wrote, I said that they are exactly equivalent.
You are right that the parentheses don't change the value of FOO.

Let me try again to be very clear about what I have been telling you is
different.

In the statement

    A = [x, y]

the syntax "[x, y]" creates a matrix by concatenating the values of x
and y. If x and y are each 4-by-1 vectors, "[x, y]" is a 4-by-2 matrix.
Here, the "[]" characters are acting as a concatenation operator.

In the statement

    [x, y] = sort((1:4)')

the syntax "[x, y]" does *not* create a matrix. On the left side of an
assignment, the "[]" characters are a different operator. It happens to
look like matrix concatenation, but it is not the same thing. x and y
have each been assigned the values of 4-by-1 vectors, but there is no
4-by-2 matrix. Adding parentheses around the whole statement and trying
to capture the value of concenating x and y isn't going to work because
no concatenation operation has happened.

I know you know this is true if you think about it, because a function
can return any number of values of different shapes and sizes that can't
be concatenated. In the case of sort, they happen to have the same size
and type, but there is no concatenation of return values.

> "it is a comma-separated list" - again, doesn't make sense to me.

The return value from a function is a comma-separated list, which is a
particular type in both Octave and Matlab. The syntax for slicing values
out of a comma-separated list looks a lot like matrix concatenation, but
it is not. That is a syntax confusion that Matlab created decades ago
and we have to keep it if we want to remain compatible.

--
mike


-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: inconsitency in behavior of 'size'

Sergei Steshenko



From: Mike Miller <[hidden email]>
To: [hidden email]
Sent: Saturday, March 10, 2018 9:16 PM
Subject: Re: inconsitency in behavior of 'size'

On Sat, Mar 10, 2018 at 13:26:18 +0000, Sergei Steshenko wrote:
> Because you are telling me that <FOO> and (<FOO>) are different.

No, if you read what I wrote, I said that they are exactly equivalent.
You are right that the parentheses don't change the value of FOO.

Let me try again to be very clear about what I have been telling you is
different.

In the statement

    A = [x, y]

the syntax "[x, y]" creates a matrix by concatenating the values of x
and y. If x and y are each 4-by-1 vectors, "[x, y]" is a 4-by-2 matrix.
Here, the "[]" characters are acting as a concatenation operator.

In the statement

    [x, y] = sort((1:4)')

the syntax "[x, y]" does *not* create a matrix. On the left side of an
assignment, the "[]" characters are a different operator. It happens to
look like matrix concatenation, but it is not the same thing. x and y
have each been assigned the values of 4-by-1 vectors, but there is no
4-by-2 matrix. Adding parentheses around the whole statement and trying
to capture the value of concenating x and y isn't going to work because
no concatenation operation has happened.

I know you know this is true if you think about it, because a function
can return any number of values of different shapes and sizes that can't
be concatenated. In the case of sort, they happen to have the same size
and type, but there is no concatenation of return values.

> "it is a comma-separated list" - again, doesn't make sense to me.

The return value from a function is a comma-separated list, which is a
particular type in both Octave and Matlab. The syntax for slicing values
out of a comma-separated list looks a lot like matrix concatenation, but
it is not. That is a syntax confusion that Matlab created decades ago
and we have to keep it if we want to remain compatible.


--
mike

-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------


"The syntax for slicing values out of a comma-separated list looks a lot like matrix concatenation" - which is obfuscation.

I.e. [foo, bar] should always mean the same. The situation is really bad - see copy-paste of a session:

"
octave:9> [a1, a2] = sort([1 2 3; 4 5 6](:,1))
a1 =

   1
   4

a2 =

   1
   2

octave:10> foo = [a1, a2] = sort([1 2 3; 4 5 6](:,1))
foo =

   1
   4

octave:11>
"

Output of command 9 shows TWO columns, while output of command 10 shows ONE column, and the difference is that in command 10 output of command 9 is assigned to a variable.

--Sergei.




-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: inconsitency in behavior of 'size'

Przemek Klosowski-7
On 03/10/2018 07:21 PM, Sergei Steshenko wrote:
"The syntax for slicing values out of a comma-separated list looks a lot like matrix concatenation" - which is obfuscation.

I.e. [foo, bar] should always mean the same. The situation is really bad - see copy-paste of a session:

octave:9> [a1, a2] = sort([1 2 3; 4 5 6](:,1))
a1 =

   1
   4

a2 =

   1
   2

octave:10> foo = [a1, a2] = sort([1 2 3; 4 5 6](:,1))
foo =

   1
   4

Output of command 9 shows TWO columns, while output of command 10 shows ONE column, and the difference is that in command 10 output of command 9 is assigned to a variable.

Given the compatibility requirement that [] on the left of '=' is not the same as [] on the right size, it does make sense.

[a1,a2] = ... assigns two variables.

foo = [a1,a2] = ... is equivalent to

<return object> = ...

[a1,a2] = <return object>

foo = <return object>

In both of those cases, a1=[1;4], a2=[1;2], foo = [1;4]

foo = [a1, a2]

is different: foo = [1,1;4,2], because in this case [] is matrix concatenation. It's not really bad---it's just the way it is given Matlab design from back in the 1970s.



-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: inconsitency in behavior of 'size'

nrjank


On Mon, Mar 12, 2018 at 12:57 PM, Przemek Klosowski <[hidden email]> wrote:
On 03/10/2018 07:21 PM, Sergei Steshenko wrote:
"The syntax for slicing values out of a comma-separated list looks a lot like matrix concatenation" - which is obfuscation.

I.e. [foo, bar] should always mean the same. The situation is really bad - see copy-paste of a session:


...

another example that highlights one of Mike's explanations:


---------------
>> fzero(@sin, 1)
ans = 0

>> [a,b] = fzero(@sin,1)
a = 0
b = 0

>> [a,b,c,d] = fzero(@sin,1)
a = 0
b = 0
c =  1
d =

  scalar structure containing the fields:

    iterations = 0
    funcCount =  4
    bracketx =

       0    0

    brackety =

       0    0
------------------------

quite obviously, [] as a multi-element list assignment operator cannot require that it form a valid matrix, as the return values don't even have to be the same type, yet alone the same size.


-----------------------------------------
Join us March 12-15 at CERN near Geneva
Switzerland for OctConf 2018.  More info:
https://wiki.octave.org/OctConf_2018
-----------------------------------------