I'm in a discussion with someone from Mathworks re: the unwrap
function which has a "bug" in it for jump tolerances other than π, and would like to get some other perspectives:
Description
Q = unwrap(P)
corrects the radian phase angles in a vector P by adding multiples of ±2π when absolute jumps between consecutive elements of P are greater than or equal to the default jump tolerance of π radians. If P is a matrix, unwrap operates columnwise. If P is a multidimensional array, unwrap operates on the first nonsingleton dimension.
Q = unwrap(P,tol)
uses a jump tolerance tol instead of the default value, π.
There are two possible interpretations of the documentation:
Q = unwrap(P,tol)
corrects the radian phase angles in a vector P by adding multiples of ±2π when absolute jumps between consecutive elements of P are greater than or equal to tol radians. If P is a matrix, unwrap operates columnwise. If P is a multidimensional array, unwrap operates on the first nonsingleton dimension.
Example:
>> x = mod(0:20:200,100); unwrap(x, 50)
ans =
0 20.0000 40.0000 60.0000 80.0000 81.6814 101.6814 121.6814 141.6814 161.6814 163.3628
Q = unwrap(P,tol)
corrects the elements in a vector P by adding multiples of ±2*tol when absolute jumps between consecutive elements of P are greater than or equal to tol. If P is a matrix, unwrap operates columnwise. If P is a multidimensional array, unwrap operates on the first nonsingleton dimension.
Example:
>> x = mod(0:20:200,100); unwrap(x, 50)
ans =
0 20 40 60 80 100 120 140 160 180 200
The actual behavior of unwrap()
in MATLAB (at least up to R2010a) is #1. My interpretation of unwrap()
is that it's supposed to be #2, and therefore there is a bug in the behavior. If unwrap()
's behavior matched #2, then unwrap could be used as an inverse for mod for slowly-varying inputs, i.e. unwrap(mod(x,T),T/2) = x
for vectors x where successive elements vary by less than tol=T/2.
Note that this 2nd interpretation is more general than angles, and can unwrap anything with a wraparound period T. (whether a default of T=2π for radians, 360 for degrees, 256 for 8-bit numbers, 65536 for 16-bit numbers, etc.)
So my question is:
Are there possible uses for behavior #1? Which interpretation makes more sense?
Interpretation #1 is how I read the documentation and I think it makes sense. I could imagine to use it for reconstructing the driven distance from a wheel encoder. For slow speeds the tolerance doesn't matter, but for high speeds (high enough to violate the sampling theorem, i.e. you have less than two samples per wheel rotation), the tolerance helps you to get the right reconstruction if you know the direction.
Another reason why #1 makes more sense is probably that the ordinary unwrap can be extended easily to a generic one and therefore there's no direct need for the period to be a parameter.
% example for 16 bit integers
>> x1 = [10 5 0 65535 65525];
T = 65536;
x2 = T * unwrap(x1 * 2 * pi / T) / (2 * pi)
x2 =
10.0000 5.0000 0 -1.0000 -11.0000
Or just make your own function:
function ret = generic_unwrap(x, T)
ret = T * unwrap(x * 2 * pi / T) / (2 * pi);
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With