Highlights
Segui


Adam Danz

New in MATLAB R2022b: determine if a vector is uniformly spaced

Adam Danz il 29 Set 2022 (Modificato il 11 Gen 2024)
Ultime attività Replicato da Mehul Gajwani il 2 Ott 2022

Uniform spacing and the problem of round-off error
The vector [3 4 5 6 7 8 9] is uniformly spaced with a step size of 1. So is [3 2 1 0 -1 -2] but with a step size of -1.
The vector [1 2 4 8] is not uniformly spaced.
A vector v with uniform spacing has the same finite interval or step size between consecutive elements of the vector. But sometimes round-off error poses a problem in calculating uniformity.
Take, for example, the vector produced by
format shortg
v = linspace(1,9,7)
v = 1x7
1 2.3333 3.6667 5 6.3333 7.6667 9
Linspace produces linearly spaced vectors but the intervals between elements of v, computed by diff(v), are not identical.
dv = diff(v)
dv = 1x6
1.3333 1.3333 1.3333 1.3333 1.3333 1.3333
dv == dv(1)
ans = 1×6 logical array
1 0 0 1 0 1
diff(dv)
ans = 1x5
4.4409e-16 0 -4.4409e-16 8.8818e-16 -8.8818e-16
Some extra steps are therefore necessary to set a tolerance that ignores error introduced by floating point arithmetic.
New in R2022b: isuniform
Determining uniformity of a vector became a whole lot easier in MATLAB R2022b with the new isuniform function.
isuniform returns a logical scalar indicating whether vector v is uniformly spaced within a round-off tolerance and returns the step size (or NaN if v is not uniform).
Let's look at the results for our vector v,
[tf,step] = isuniform(v)
tf = logical
1
step =
1.3333
How about non-uniformly spaced vector?
[tf,step] = isuniform(logspace(1,5,4))
tf = logical
0
step =
NaN
Give it a shot in MATLAB R2022b
  • What happens when all elements of v are equal?
  • Can you produce a vector with uniform spacing without using colons or linspace?
  • What additional steps would be needed to use isuniform with circular data?
References
This article is attached as a live script.
Vinay Nambiar
Vinay Nambiar il 30 Set 2022
Great content, Adam!
Adam Danz
Adam Danz il 30 Set 2022
Thanks Vinay!
Mehul Gajwani
Mehul Gajwani il 30 Set 2022
Hi Adam, this looks great. However, can I ask, why not include the ability for the user to specify the tolerance as a second parameter? If you have vector entries on the order of 1000 and want to see if they differ by a small amount you will have to create a new routine for that - would it have been possible to build in this functionality/why did you choose not to? If this is not possible/recommended, why not (for my own learning)? Thanks.
Adam Danz
Adam Danz il 30 Set 2022
Interesting use-case, Mehul, thanks for sharing. I'm not the developer of this feature but I have some thoughts on your ideas.
> If you have vector entries on the order of 1000 and want to see if they differ by a small amount you will have to create a new routine for that
Could you share an example that you would expect to work with isuniform but doesn't work?
isuniform does not define a constant tolerance applied to every vector. Instead, it defines a tolerance based on the values in the vector using floating point relative accuracy (see eps).
If a second argument allowed users to set their own tolerance level, there would have to be some limitations to prevent misuse of the function named is-uniform. For example, isuniform(v,5) using the the vector v below with a tolerance of 5, would return true even though the vector is far from having uniform spacing.
v = [0 5 6 7 12 13 15 20];
diff(v)
ans = 1x7
5 1 1 5 1 2 5
Mehul Gajwani
Mehul Gajwani il 2 Ott 2022
An example could be
isuniform([0 999.99 2000.4 2998.965]) % should this return true or false?
Sorry, in my original post, I should have said - let the second parameter be optional for the user.
If unspecified, it can follow the current implementation.
Adding the option for the user to input a second parameter gives the user flexibility and convenience, and I think this outweighs any possible confusion/unusual behaviour.