Thu 14 Jan 2016 04:00:24 AM UTC, comment #9:
Oops. The previous patch printed the fractional part too often (|| instead of &&). Version 2 should work.
(file #36022)
|
Mon 11 Jan 2016 10:07:12 AM UTC, comment #8:
Lachlan's patch for the error message seems good
to me.
Also, the "and only return values up to 1000 as Matlab does,"
is likely a good choice. But, there may be other ideas??
Michael
|
Mon 11 Jan 2016 06:52:11 AM UTC, comment #7:
Here is a patch to show small fractional parts of indices in the error message, as Michael suggested. It shows
It looks a little unwieldy, but I think it is clearer than hex, and certainly less misleading than omitting the fractional part.
However, the main problem remains: given sum(ones(1001,1))==1001, why does the range contain a non-integer final value? I assume the problem is in
We could check for integrality of the base and step and not return a fractional rng_limit, but that would slow things down.
My vote would be to treat the upper limit literally, and only return values up to 1000 as Matlab does, even if that confuses some people...
(file #35984)
|
Mon 11 Jan 2016 05:03:45 AM UTC, comment #6:
Michale, I like your idea of showing that the answer isn't exactly an integer.
Many of the comments below are about the fact that the end-point is not well defined if floating point is involved. However, the real puzzle is that adding integers much less than the mantissa size gives a non-integer result.
Representing 1000 only takes 10 bits, whereas a double should be able to do integer arithmetic for numbers up to 52 bits without error, shouldn't it?
|
Sat 09 Jan 2016 10:04:24 PM UTC, comment #5:
I did a little playing around in Matlab and it seems that they consider float values to be equal if they are within +/- eps(x)/2.
E.g.
% Matlab
x = 500
x == (x+eps(x)/2)
x == (x+eps(x)/1.99999999)
500
1
0
Likewise,
numel(1:(x-eps(x)/2))
numel(1:(x-eps(x)/1.99999999))
500
499
Doing the same thing in Octave gives
% Octave
500
1
0
and
500
500
So it looks like Octave's range function is using different logic to determine whether to include the endpoint. It seems to allow a wider tolerance up to about 6-7 times eps(x):
numel(1:(x-eps(x)*6))
500
numel(1:(x-eps(x)*7))
499
|
Sat 09 Jan 2016 05:29:01 PM UTC, comment #4:
John: Right, finding the "best" solution is not easy.
Matlab compatibility is a consideration, but does not
dictate the right way to do it.
A part of this that may confuse users is:
Maybe enhancing the message:
error: x(1000): subscripts must be either integers 1 to (2^31)-1 or logicals
by displaying the failing subscript in hex or at least somehow
indicating explicitly that it does not have an exact integer
value.
|
Sat 09 Jan 2016 04:35:38 PM UTC, comment #3:
I agree that there is a bug of some sort, and certainly an incompatibility with Matlab. But I don't know what the best solution is.
In any case, my experience has been that when people come across things I like this they typically expect something different. the usual expectation is that the result of T/dt should be exactly 1001 and that the range 2:T/dt should have 1000 elements, not 999. And that's what Octave tries to do here, but then there is still a possible bug because it sets the end point of the range to the result of the floating point calculation T/dt instead of 1001 even though the beginning of the range and the increment are both integers, and (again, if we were doing exact arithmetic) the endpoint would be as well.
These sorts of things have given us all kinds of trouble, and trying to be "smart" about them by going to great lengths to compute the "proper" number of elements for ranges can NEVER give the results that please everyone all the time.
|
Sat 09 Jan 2016 03:43:37 PM UTC, comment #2:
Matlab 2015a says:
So, it is a bug.
|
Sat 09 Jan 2016 03:42:23 PM UTC, comment #1:
Also Matlab 2013a runs this script without complaint. The final values of the variables are:
>> T
T =
4.0040
>> dt
dt =
0.0040
>> i
i =
1000
>>
|
Sat 09 Jan 2016 02:21:21 PM UTC, original submission:
T=1001/250;
dt=1/250;
x(1)=10;
for i=2:T/dt
x(i)=x(i-1)+randn();
end
These commands give the following error message (since T/dt is not exactly equal to 1001):
error: subscript indices must be either positive integers less than 2^31 or logicals
When T=1000/250, for instance, the error is not produced and the result is correct.
I have checked with other software (Scilab and R) and this mistake is not produced.
|