#188 linspace: numerical errors in last value

David Hammarwall

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.

This is particularly cumbersome when there values in the vector har used as input to another function that for example asserts that the input is lower, or equal, to the "to" value, in which case that function will randomly trigger the assertion depending on the system or OS.

Attached to this bug report is a patch file, that resolves the problem without any additional complexity


  • Patch file for linspace

  • Bogdan Cristea
    Bogdan Cristea

    Your patch solves this problem, but the generated vector will no longer have a constant step, which is the purpose of this function. Maybe another function is needed with the following signature vec linspaces(double from, double to, int step = 1);

  • Granted that the generated function will not have a constant step in all cases, so there is a trade off between interests. However, I persist in my position that the input "to" parameter is more inportant than the constant step considering the following
    1) I don't agree that the purpose of the function is to have a constant step, rather I belieave that the purpose is to have a vector starting with "from" and ending with "to", with the specified numer of intermeadiate elements spaced as evenly as possible.
    2) There is only a problem in the first place if the exact (correct) step size cannot be represented exactly in binary precision
    3) If the correct step size cannot be represented, why is it more correct to persist in using the same "incorrect" step size between every element as opposed to alternating it so that the errors are not aggregated to result in a significant error on the last element
    4) It is highly non-intuitive to have an output vector where the largest element is larger than the specified "to" value.
    5) The linspace funciton is inspired by the conterpart in Matlab and commonality of the behavior in C++ and Matlab are highly desirable. Running the following code in matlab will show that the step size indeed changes in Matlab, but the last element is exactly 10, as specified by the input.
    format long;

    With this in mind, I hope that you will consider revising your decision on not fixing this issue.

    Regarding your alternate function, it seems to be ambigous considering that it uses the same types as the original function. Moreover, I don't really see what the int step parameter would do.

  • Bogdan Cristea
    Bogdan Cristea

    1) The approach you propose is the same as the one used by MATLAB for the same function
    2) I still think that this is contrary to the purpose of linspace() function. The step between elements is no longer constant. Following your reasoning, if a function asserts that the input vector should have a constant step, the assert will fail. Even if the last element is not exactly to, this could be seen as an error.
    3) the new function I propose has a different name, even if the arguments' type is the same linspaces() and should correspond to MATLAB syntax: "from:s:to". In this case the step is guaranteed to be s and the last element will be always less or equal than to.

    Before starting to change linspace() or implement linspaces(), I would like to have other opinions related to this issue. I would propose to open a new thread in the Open Discussion forum.

  • Bogdan Cristea
    Bogdan Cristea

    Changed linspace() function according to the submitted patch
    Added vec linspace_fixed_step(double from, double to, double step = 1.0) in order to provide the functionality provided in MATLAB by from:step:to

  • Bogdan Cristea
    Bogdan Cristea

    • status: open --> accepted
    • Group: --> release_2.3.x
  • Bogdan Cristea
    Bogdan Cristea

    • status: accepted --> closed