开发者

MATLAB: unwrap function

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:

开发者_Go百科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:

  1. 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
    
  2. 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


Behavor #1 makes sense, since the input is assumed to be radians, not degrees. The adjustment adds pi/2 if you're above jump tolerance, so that's fine.

What would be nice was if unwrap had a feature that allowed it to work on any kind of series, not simply on radian angles.

The jump tolerance is not sufficient to tell whether you have a series in radian, or degree, or any other kind, so there would need to be an additional input.


I had always assumed that the second behavior was the actual one, but never tested it out. A literal reading of the help file does indicate behavior #1. But that's not what one would ever want to do. As a simple example, consider doing an unwrapping in degrees

x = mod(0:30:720, 360)
y = unwrap(x,180)

obviously you would want y = 0:30:720, but instead you get ...

y =

Columns 1 through 7

     0   30.0000   60.0000   90.0000  120.0000  150.0000  180.0000

Columns 8 through 14

210.0000  240.0000  270.0000  300.0000  330.0000  333.0088  363.0088

Columns 15 through 21

393.0088  423.0088  453.0088  483.0088  513.0088  543.0088  573.0088

Columns 22 through 25

603.0088  633.0088  663.0088  666.0176

which is wrong (y no longer corresponds to the same angle as x, which is the point of unwrap)

Can anyone give an example of when you would want behavior #1 (the current behavior?)


x = mod(0:30*pi/180:4*pi, 2*pi);
y = unwrap(x)*180/pi;

It works in radians, but not in degrees.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜