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

Adam Danz 2022 年 9 月 29 日 (編集日時: 2024 年 1 月 11 日)
最新アクティビティ Mehul Gajwani さんによる返信 (2022 年 10 月 2 日)

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 2022 年 9 月 30 日
Great content, Adam!
Adam Danz
Adam Danz 2022 年 9 月 30 日
Thanks Vinay!
Mehul Gajwani
Mehul Gajwani 2022 年 9 月 30 日
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 2022 年 9 月 30 日
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 2022 年 10 月 2 日
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.