colon expression to use integer operands

The following code does not work because the colon operands are not integer values
stepSize = (pi/512);
thRadDbl = (0:stepSize:(2*pi - stepSize));
Question :How to rewrite the colon expression to use integer operands ?

2 Comments

I get this error while converting into fixed point code
Colon operands must have integer values when interacting with type 'embedded.fi'.
Error in ==>> init_data_fixpt Line: 13 Column: 15
Code generation failed: View Error Report
As per the documentation :
If your code uses non-integer operands, rewrite the colon expression so that the operands are integers.The following code does not work because the colon operands are not integer values.
Fs = fi(100);
n = 1000;
t = (0:1/Fs:(n/Fs - 1/Fs));
Rewrite the colon expression to use integer operands.
Fs = fi(100);
n = 1000;
t = (0:(n-1))/Fs;
ATTENTION!
I received an email - someone deleted answer ! Don't know / can't track what was that.

Sign in to comment.

 Accepted Answer

1)
For embedded designs, if at all possible consider changing your design to work with revolutions instead of radians.
1 revolution = 360 degrees = 2*pi radians
Many angle sensors are perfectly matched for recording angles in revolutions. For example, a spec. sheet may say that each angle sensor pulse equals 360 degrees / 4096. This is equivalent to 2^-12 revolutions per pulse. Equivalently, 4096 pulses equals one revolution. For this sensor, great data types for the angle would be
numerictype(0,12,12) % 0 to just under 1 revolution
numerictype(0,16,12) % 0 to just under 16 revolutions
Updating this angle would be lossless and would require a simple increment or add. In contrast, trying to record the angle in degrees or radians would always involve precision loss for representing 360/4096 or 2*pi/4096, and would require more math and bigger types.
To compute things like sine or cosine, it is generally useful to do a modulo first. A huge advantage to angles in revolutions with binary scaled fixed point is that modulo 1 revolution is lossless and trival. Just a simple masking operation to keep all the fraction bits and drop any integer bits. In contrast, attempting to do module 360 or 2*pi requires more costly calculations and can introduce precision losses.
2)
To create your evenspaced vector of n elements, covering the closed open interval [0, valueMax).
2a)
You gave an example of n = 1000.
If possible consider changing to an exact power of two like n = 1024 = 2^10. It will generally make the math nicer, and if using revolutions, then the math will be lossless too.
2b)
You need to pick one fixed-point data type for the entire vector. You cannot use different data types for each element of the vector. First determine, the level of accuracy required. For example, if the angle will be coming from the sensor example above with 4096 ticks per revolution, then a Fraction Length of 12 is a perfect choice. Based on the desired FractionLength, the rest of the data type attributes can be determined
2c)
The attached script
evenAngleVecCalc.m
shows how to set the output data type and compute the vector.
-Andy

6 Comments

@Andy Bartlett,Pretty well explained and it's serving the useful stuff.
If possible consider changing to an exact power of two like n = 1024 = 2^10. It will generally make the math nicer, and if using revolutions, then the math will be lossless too.
Including your suggested proposal & below is the modified code - test results
outFracLen = 29;
valueMax = 1; % revolutions
n = 2^10;
% Computed values
%
outWordLen = ceil(log2(valueMax*(2^outFracLen)));
nt = numerictype(0,outWordLen, outFracLen);
fiStep = fi( valueMax/n, nt );
intWordLength = ceil(log2(n-1));
intVals = fi( (0:(n-1)).', 0, intWordLength, 0);
tempVec = fiStep .* intVals; % full precision produce will be bigger than nt
vec = fi( tempVec, nt ); % put in the desired final type
Do you have an explanation why we see the difference and please help me for improving it
[cordicsin(vec,10),sin(vec)]
0.0012 0
0.0012 0.0009
0.0012 0.0019
0.0012 0.0029
0.0051 0.0038
0.0051 0.0048
0.0051 0.0058
0.0051 0.0068
0.0090 0.0078
0.0090 0.0087
0.0090 0.0097
0.0090 0.0107
0.0129 0.0117
0.0129 0.0126
0.0129 0.0136
0.0129 0.0146
0.0168 0.0155
0.0168 0.0166
0.0168 0.0175
0.0168 0.0185
0.0207 0.0194
Hi
Keep in mind that
sin
cordicsin
expect the input to be in radians, not revolutions.
I'm guessing you're trying to get baseline by calling sin(vec).
I suggest you create the baseline using doubles math rather than fixed-point math.
See the attached script.
The math will not be perfect. There will be some inaccuracies due to fixed-point approximations.
-Andy
Makes sense
For
cordicsine - Input in Radains
sin - Input in Radains ( corrected typo was degree)
  • Please see my conversion in below figure and it makes sense to have have errror in fixed point stuff.
  • Since cordicsin does contain smaller LookUp table but with bigger latency /computational , I wanted to make comparision and please see below plot.
  • Please comment, Can I use cordicsin instead of sin function ?
sind() would expect input in degrees. sin() would expect input in radians.
I am pretty well on my way in resolving the problem, I have two choice ,
  1. To have a short lookup table (32bit ) - In the moment , I have 128 size bit lookup table
I am facing problem in getting the sine function output in Q12.20 > higher than 16bit output Q15.xx
2. To have cordicsin function
I have 10 iteration cordicsin function that add to latency/computation complexity
Can you please suggest which is good option to work upon ?
- Thanks

Sign in to comment.

More Answers (2)

Not true. That code runs fine.
Maybe you want to consider linspace though. Or if you're going to use it as indexes, then round the values.
Seems to work fine for me.
stepSize = (pi/512);
thRadDbl = (0:stepSize:(2*pi - stepSize));
thRadDbl(1:5)
ans = 1×5
0 0.0061 0.0123 0.0184 0.0245
There's no way you're going to be able to use thRadDbl as a vector of indices since arrays in MATLAB have neither an element 0 nor an element pi/512.
One thing you could do is to wait to multiply by pi until after you've constructed the vector.
step = (1/512);
v = pi*(0:step:(2-step));
v(1:5)
ans = 1×5
0 0.0061 0.0123 0.0184 0.0245
Or perhaps the sinpi and/or cospi functions would be of interest to you.

7 Comments

step = (1/512);
v = pi*(0:step:(2-step));
v(1:5)
This is not helping - still having the same error
Colon operands must have integer values when interacting with type 'embedded.fi'.
Note : I won't go for sinpi /cospi - I am using cordicsin/cordiccos
Thank you!
I got the right logic
step = (pi/512);
n = 1024;
% = (0:pi/512 :(2*pi -pi/512)) = Expansion
v = (0:(n-1))*step;
You can check and see data sanity is matching.
Thanks a lot.
Both of your last two code snippets run without error. They do different things.
I don't know what variable type 'embedded.fi' is - there must be something you have not told us, like the entire error message. A complete error message will have additional information, like the actual line of code that threw the error as well as a traceback for all prior lines of code that you stepped into before you got to the line of code that threw the error. What is "init_data_fixpt Line: 13 Column: 15"?
Next time, include ALL the red text, not just some of it.
Your v will still be a floating point array with a starting value of 0.
FYI embedded.fi is a class in Fixed-Point Designer. Instances of that class are created using the fi function.
This seems to work when I tried it in release R2020b.
p = fi(pi)
p =
3.1416 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
step = (1/512);
v = 0:step:(2-step);
pv = p*v;
pv(1:5)
ans =
0 0.0061 0.0123 0.0184 0.0245 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 32 FractionLength: 27
I don't know if this is exactly what you're looking for, but I don't work with Fixed-Point Designer really at all, mainly just occasionally reading its documentation to answer questions on Answers.
Hi
Sorry but I am also in same situation with lots of unknow in the begining. For me the problem statement is as mentioned in the begining phase I wrote. The range needs to converted into fixed point values and we have fixed point coder throwing the error.
The first steps is resolved current logic to a format which is best understood by fixed point coder.
@Image Analyst I see error "init_data_fixpt Line: 13 Column: 15"? I see error thRadDbl = (0:stepSize:(2*pi - stepSize));
Coder is coverting to fixed point as below which is incorrect
thRadDbl = fi((fi(0, 0, 1, 0, fm):stepSize:(fi_signed(fi(2*pi, 0, 32, 29, fm)) - stepSize)), 0, 32, 29, fm)
Then I worked out new /diferent logic - breakdown the range & do expansion
step = (pi/512);
n = 1024;
% = (0:pi/512 :(2*pi -pi/512)) = Expansion
v = (0:(n-1))*step;
we have floatpt to fixpt code as below
step = fi((pi/512), 0, 32, 39, fm);
n = fi(1024, 0, 11, 0, fm);
% = (0:pi/512 :(2*pi -pi/512)) = Expansion
v = fi((fi(0, 0, 1, 0, fm):(fi_signed(n)-fi(1, 0, 1, 0, fm)))*step, 0, 32, 29, fm);
@Steven Lord, In case i add your suggestion
step = (1/512);
v = 0:step:(2-step);
pv = p*v;
then fixed point coder have following code which doesnot seems to work
p = fi(pi);
step = fi((1/512), 0, 32, 40, fm);
v = fi(fi(0, 0, 1, 0, fm):step:(fi_signed(fi(2, 0, 2, 0, fm))-step), 0, 32, 31, fm);
pv = p*v;
& we have error in floating to fixed point conversion
??? Colon operands must have integer values when interacting with type 'embedded.fi'.
@Image Analyst & @Steven Lord, the challenge is how to get right settings for word & fractional length so that rms error is minimum.
I hope i tried my best to share full information here ! Again many thanks for sharing quick and meaningful information . Please share your feedback (I will account all above feedback in future discussion). Thanks a lot .
We've about exhausted my knowledge of the fi data type so I don't think I can provide any more assistance.
Call tech support.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!