There is currently a bug report related to this issue:
The syntax of the linspace function
vec linspace(double from, double to, int length = 100);
indicates that the first value is exactly equal to "from" and the last value
is exactly equal to "to". With the current implementation the last value of
the vector will however be slightly offset from "to", due to numerical errors.
There are two proposed solutions:
change linspace() function so that the last generated value will be exactly to. With this approach the generated vector does not have a constant step, but the implementation complies with MATLAB
add a second function linspaces(double from, double to, int step = 1) which is the equivalent of "from:step:to" in MATLAB so that the generated vector has a constant step and the last value is less or equal than to.
Could you please comment on these two solutions and vote for the best one ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Regarding the bug report ID:3010881, I would like to share my views.
In short, the interface of the current linspace function is as follows:
vec linspace(double from, double to, int length = 100)
The problem is that the current implementation can produce an output where the
last element is larger or smaller (depending on the system and architecture it
is run on) than the specified to value.
This is because the function computes a step_size as step_size = (to-
from)/(length-1), and next applies this fix step_size between each neighboring
vector element. The problem arises when the correct step_size cannot be
represented exactly in double precision, and is thus rounded to the closes
double precision point. In this case the last element will, due to numerical
errors (that grow with increasing length of the vector), be slightly larger or
smaller than the specified to value.
Hence we have a problem where the interface is difficult to fulfill. On one
hand, the naming of the function indicates that there should be a “linear”
spacing between the elements, but on the other hand the input parameters let
you specify the last element to, (this contract is currently not fulfilled).
When the step_size cannot be expressed in exact binary precision, both of
these contracts cannot be fulfilled at the same time.
In my view, the interface contract of the input parameters is more explicit
than the naming of the function and should therefore supersede, and we should
therefore alter the implementation as, suggested in the above bug-report, so
that the last element is always equal to the specified to value, at the cost
of having a jittering in the step_size (note that the step_size is not part of
the interface) when it cannot be represented in binary precision. This is also
the behavior adopted in the corresponding function in Matlab. My basic
question is, why is it more correct to repeatedly apply a static but
numerically incorrect step_size than to jitter about the correct step_size to
fulfill the contract of the specified to value.
Regarding the solution in 2) above, I presume that the intended interface is
really:
vec linspaces(double from, double to, double step = 1.0);
where the step is given as a double (not an int). Personally I think that this
formulation is inconvenient since the user would have to compute both the step
size and the to value (which as discussed above can be conflicting).
Typically the user is interested in either the step size or the to value.
Moreover, there will still not be a way for the user to create a vector with a
specific from and to value, where the samples are as uniform as
numerically possible.
My proposal to fulfill both needs is as follows:
We change the behavior of the linspace function such that the first and last
elements of the vector corresponds to the given from and to values, and
the sample spacing is as uniform as numerically possible.
We also introduce a new function with the syntax
vec linspace_fix_step(double from, double step_size, int length = 100)
which can be used to enforce a specific given step_size. Here we will not have
a problem with numeric precision since the step_size is explicitly given (and
thus exactly represented by double precision), and moreover there is no to
value in the interface that can be violated.
Any thoughts on this issue?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
To employ two linspace functions is a good idea, which could be effectively
solve the bug above. But If we have to choose one of solutions, I personally
prefer the first one.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
linspace() has been changed so that the last element is always "to". A new
function has been added linspace_fix_step(double from, double step_size,
double length = 1.0) in order to have from:step:to from MATLAB.
Changes have been committed to trunk and tests have been made on openSUSE
11.3. Please test on other distros and report any problems.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There is currently a bug report related to this issue:
vec linspace(double from, double to, int length = 100);
indicates that the first value is exactly equal to "from" and the last value
is exactly equal to "to". With the current implementation the last value of
the vector will however be slightly offset from "to", due to numerical errors.
There are two proposed solutions:
Could you please comment on these two solutions and vote for the best one ?
Hi all,
Regarding the bug report ID:3010881, I would like to share my views.
In short, the interface of the current linspace function is as follows:
vec linspace(double from, double to, int length = 100)
The problem is that the current implementation can produce an output where the
last element is larger or smaller (depending on the system and architecture it
is run on) than the specified to value.
This is because the function computes a step_size as step_size = (to-
from)/(length-1), and next applies this fix step_size between each neighboring
vector element. The problem arises when the correct step_size cannot be
represented exactly in double precision, and is thus rounded to the closes
double precision point. In this case the last element will, due to numerical
errors (that grow with increasing length of the vector), be slightly larger or
smaller than the specified to value.
Hence we have a problem where the interface is difficult to fulfill. On one
hand, the naming of the function indicates that there should be a “linear”
spacing between the elements, but on the other hand the input parameters let
you specify the last element to, (this contract is currently not fulfilled).
When the step_size cannot be expressed in exact binary precision, both of
these contracts cannot be fulfilled at the same time.
In my view, the interface contract of the input parameters is more explicit
than the naming of the function and should therefore supersede, and we should
therefore alter the implementation as, suggested in the above bug-report, so
that the last element is always equal to the specified to value, at the cost
of having a jittering in the step_size (note that the step_size is not part of
the interface) when it cannot be represented in binary precision. This is also
the behavior adopted in the corresponding function in Matlab. My basic
question is, why is it more correct to repeatedly apply a static but
numerically incorrect step_size than to jitter about the correct step_size to
fulfill the contract of the specified to value.
Regarding the solution in 2) above, I presume that the intended interface is
really:
vec linspaces(double from, double to, double step = 1.0);
where the step is given as a double (not an int). Personally I think that this
formulation is inconvenient since the user would have to compute both the step
size and the to value (which as discussed above can be conflicting).
Typically the user is interested in either the step size or the to value.
Moreover, there will still not be a way for the user to create a vector with a
specific from and to value, where the samples are as uniform as
numerically possible.
My proposal to fulfill both needs is as follows:
We change the behavior of the linspace function such that the first and last
elements of the vector corresponds to the given from and to values, and
the sample spacing is as uniform as numerically possible.
We also introduce a new function with the syntax
vec linspace_fix_step(double from, double step_size, int length = 100)
which can be used to enforce a specific given step_size. Here we will not have
a problem with numeric precision since the step_size is explicitly given (and
thus exactly represented by double precision), and moreover there is no to
value in the interface that can be violated.
Any thoughts on this issue?
To employ two linspace functions is a good idea, which could be effectively
solve the bug above. But If we have to choose one of solutions, I personally
prefer the first one.
linspace() has been changed so that the last element is always "to". A new
function has been added linspace_fix_step(double from, double step_size,
double length = 1.0) in order to have from:step:to from MATLAB.
Changes have been committed to trunk and tests have been made on openSUSE
11.3. Please test on other distros and report any problems.
sorry, the new function signature is
linspace_fix_step(double from, double to, double step = 1.0)