'LUT for sin: calculation sin of x in Matlab
I test sin computation via LUT in Matlab.
Nsamples_LUT = 2^10;
Nbits_sine_LUT = 14;
sine_LUT = sin( (0:Nsamples_LUT-1) / Nsamples_LUT * 2 * pi ) * (2^(Nbits_sine_LUT-1)-1) ;
I have created a sin LUT and it is given an angle.
In Maltab I wrote :
k = find(sinLUT==angle) % to find an index
phi = sinLUT(k)
but it didnt find an index .
How should I find a sin value from LUT?
Solution 1:[1]
It's not really clear what you're trying to do, but assuming you're trying to get a tabulated value...
You need to distinguish between the lookup table input (an angle if the intent is to calculate sin
) and the output (from a table of sin
values of various angles). Your sin_LUT
in the first fragment has some scaled values of sine, but that variable stores no information about how those values were produced, and in particular no information about what angles they correspond to. That is, the (0:Nsamples...
is not stored as part of sin_LUT
. You need a second table with the input values. A typical look-up table in Matlab would be done like this:
angles = linspace(0, 2 * pi, 2^10);
angles = angles(:); % interp1q requirs a column vector
sinLUT = sin(angles);
angle = 2 * pi * rand;
ansLUT = interp1q(angles, sinLUT, angle);
fprintf('angle %g, sin %g, from LUT %g\n', angle, sin(angle), ansLUT);
There's also the function interp1
which is more general than interp1q
. The latter is faster but is only for linear interpolation, and the table of input values (angles
above) must be monotonically increasing. The former can do other types of interpolation, not just linear.
Doing find(table == value)
will get the indexes where table
exactly matches value
. It may return 0 or multiple values. If value
happens to have some floating point rounding error, you'll get nothing (this may be what's happening for you).
If you have a linearly-spaced array of values and you want to find the bucket where some particular value falls, you're better off subtracting the first array value, dividing by the spacing, and rounding to an integer. That will give you the position immediately without having to search like find
. And it is robust against slight rounding errors.
Solution 2:[2]
Your lookup table is populated with the sine results. Even if you fixed the floating point comparison errors (which 100% are hosing you, too) you're not actually making a valid check here because your lookup table doesn't have any angle information in it to poll at all.
You need to get the same scaling you used to create the table and use that scaling to convert your angle to an index. Then you can pass that index to your lookup table and get the result.
The only thing you will find in your lookup table are the sine results, not angles.
:EDIT:
Two downvotes on this answer lol, but maybe people aren't understanding what I'm saying? OP cannot do the following:
find(sinLUT==angle)
because sinLUT
does not have an angle in it. You will never find anything beyond the range of +/- 1 because the min/max output of sine is +/- 1.
What OP needs to do is to convert the angle to an index and use that index to access the values in the lookup table. For example, if you make your lookup table in millidegree increments, then you would convert 30.2 degrees to 30200 and get your sine value as result = sinLUT(30200);
.
But again, as I stated above, you can't just pass any arbitrary angle to the lookup table, you have to pass an angle that corresponds to an index in the table. You can interpolate based on neighboring entries, but that's beyond the scope of this question.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | bg2b |
Solution 2 |