Error in fi divide for embedded fi object (2024)

13 views (last 30 days)

Show older comments

Life is Wonderful on 14 Oct 2021

  • Link

    Direct link to this question

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object

  • Link

    Direct link to this question

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object

Edited: Life is Wonderful on 26 Oct 2021

Accepted Answer: Tom Bryan

Open in MATLAB Online

Hi

I am trying to make a fixed point calculation with below code. But I run into error , I don't understand what is wrong in my code.

Note : Error results

clearvars;clc;

% define ranage for input data

base = fi([-1:-1:-(2^3),1:1:(2^3)],1,32,27);

exp = fi([-(2^4-6):1:-1,1:1:(2^4-6)],1,32,27);

power = 1;

if (exp > 0)

while(exp~=0)

power = power * base;

exp = accumneg(exp, 1);

end

else

while(exp~=0)

power = power * 1/base;

exp = accumpos(exp , 1);

end

end

Error using embedded.fi/mrdivide>fidivide (line 56)
For fi objects, B must be a scalar in A/B.

Error in / (line 23)
c = fidivide(a,b);

Without fi object code, below code is fine

clearvars;clc;

% define ranage for input data

base = [-1:-1:-(2^3),1:1:(2^3)];

exp = [-(2^4-6):1:-1,1:1:(2^4-6)];

power = 1;

fprintf('%20s|%20s|%20s|%20s|%20s|%20s|\n','i','j','power','base','exponent','NBits')

for i = 1:length(base)

for j = 1:length(exp)

power(i,j) = power_flpt(base(i),exp(j));

Bits = power(i,j);

NBits = log2(Bits);

fprintf('%20d|%20d|%20f|%20f|%20f|%20f|\n',i,j,power(i,j),base(i),exp(j),NBits);

end

end

function power = power_flpt(base,exp)

power = 1;

if (exp > 0)

while(exp~=0)

power = power * base;

exp = accumneg(exp, 1);

end

else

while(exp~=0)

power = power * 1/base;

exp = accumpos(exp , 1);

end

end

end

0 Comments

Show -2 older commentsHide -2 older comments

Sign in to comment.

Sign in to answer this question.

Accepted Answer

Tom Bryan on 14 Oct 2021

  • Link

    Direct link to this answer

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#answer_808666

  • Link

    Direct link to this answer

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#answer_808666

Open in MATLAB Online

The error is telling you that 1/base isn't supported in fi because base is a vector. The error is telling you that base must be a scalar for mrdivide (matrix right-divide). Element-wise division is 1./base, which would not have thrown an error, but the first code was logically incorrect anyway. The first code didn't give the right answer with double either. It was using things like "if (exp > 0)" where exp is a vector, so the if condition was never entered. Also the "while(exp~=0)" condition was never entered either.

The second code works with both fixed-point and floating-point becasue the power_fltpt function only uses scalars.

Also, both exp and power are builtin MATLAB functions, so you should think about renaming them. MATLAB is forgiving about overloading other functions, but it may interfere if you ever want to use the exp or power functions.

Enclosed below is your second code running with both fixed-point and floating point, and comparing the answers at the end.

clearvars;clc;

% define ranage for input data

base = fi([-1:-1:-(2^3),1:1:(2^3)],1,32,27);

exp = fi([-(2^4-6):1:-1,1:1:(2^4-6)],1,32,27);

fprintf('\n---------------------------------\n')

fprintf('Fixed Point\n')

power_fixedpoint = power_loop(base,exp);

fprintf('\n---------------------------------\n')

fprintf('Double\n')

power_float = power_loop(double(base),double(exp));

fprintf('\n---------------------------------\n')

fprintf('Difference\n')

difference = power_float - double(power_fixedpoint) %#ok<NOPTS>

max_difference = max(abs(difference(:))) %#ok<NOPTS>

function power = power_loop(base,exp)

power = ones(length(base),length(exp));

fprintf('%20s|%20s|%20s|%20s|%20s|%20s|\n','i','j','power','base','exponent','NBits')

for i = 1:length(base)

for j = 1:length(exp)

power(i,j) = power_scalar_function(base(i),exp(j));

Bits = power(i,j);

NBits = log2(Bits);

fprintf('%20d|%20d|%20f|%20f|%20f|%20f|\n',i,j,power(i,j),base(i),exp(j),NBits);

end

end

end

function power = power_scalar_function(base,exp)

power = 1;

if (exp > 0)

while(exp~=0)

power(:) = power * base;

exp = accumneg(exp, 1);

end

else

while(exp~=0)

power(:) = power * 1/base;

exp = accumpos(exp , 1);

end

end

end

Best wishes,

Tom Bryan

15 Comments

Show 13 older commentsHide 13 older comments

Life is Wonderful on 14 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1784656

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1784656

Open in MATLAB Online

Thanks for Nice and clear explanation !!

May be your right but it seems

power(:) = power * base;

is causing Error and i am stuck

In fi .* non-fi, or non-fi .* fi, the non-fi must be a constant.

Can you please share your input to resolve Error .

Thank you!!

Tom Bryan on 14 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1784726

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1784726

I have a few follow up questions to know how to answer:

  1. Are you trying to do code generation? This error only occurs during code generation.
  2. You have defined the variable power to be floating-point double. Do you want the code to be purely fixed-point?
  3. Do you want to generate C code? or a MEX function to simulate in MATLAB?

Best wishes,

Tom Bryan

Life is Wonderful on 15 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1785216

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1785216

Edited: Life is Wonderful on 15 Oct 2021

Please find inline answers ( Italics and Monospace)

Are you trying to do code generation? This error only occurs during code generation.

Yes, that's right requirement

You have defined the variable power to be floating-point double. Do you want the code to be purely fixed-point?

Yes, code is purely fixed point

Do you want to generate C code? or a MEX function to simulate in MATLAB?

Generate C Code

Thank you!!

Tom Bryan on 15 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786316

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786316

I'm using the methods described in article Best Practices for Converting MATLAB Code to Fixed Point. I'm the person who created the fi object and the "cast-like" syntax described there. By using this method, your code can run both fixed-point and floating-point.

A few notes about the code listed below:

  • The range of the magnitude of the output is between Error in fi divide for embedded fi object (7) and Error in fi divide for embedded fi object (8). This means that you need at least 30 integer bits, and 30 fractional bits in the output. The output is also positive and negative. To accomodate this, I chose a signed fixed-point type with a 64 bit word length and 32 bit fraction length.
  • You can see in the generated code that the large word length of the output means that multiple words of builtin C types were needed for intermediate products and sums.
  • I changed the names of the variables from base, exp, power to b, e, p respectively so the builtin functions of the same name would not be overloaded.
  • I separated out the functions that you want to generate code for from the test bench.
  • The test bench compiles and runs fixed-point as a MATLAB Executable (MEX).
  • The test bench also generates C code for the fixed-point function.
  • Run MATLAB script test_bench to test and compile the code.
  • Save each of the functions enclosed below in their own file.

Best wishes,

Tom Bryan

Tom Bryan on 15 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786321

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786321

Open in MATLAB Online

%% test_bench

%% Define input data

b = fi([-1:-1:-(2^3),1:1:(2^3)],1,32,27);

e = fi([-(2^4-6):1:-1,1:1:(2^4-6)],1,32,27);

%% Generate a MEX function for fixed-point inputs

codegen power_scalar_function -args {b(1),e(1)} ...

-o power_scalar_function_fixedpoint_mex -config:mex

%% Run fixed point

fprintf('\n---------------------------------\n')

fprintf('Fixed Point\n')

power_fixedpoint = power_loop(b,e);

%% Run floating point

fprintf('\n---------------------------------\n')

fprintf('Double\n')

power_float = power_loop(double(b),double(e));

%% Compare fixed point to floating point

fprintf('\n---------------------------------\n')

fprintf('Difference\n')

difference = power_float - double(power_fixedpoint) %#ok<NOPTS>

max_difference = max(abs(difference(:))) %#ok<NOPTS>

%% Generate C code

codegen power_scalar_function -args {b(1),e(1)} -config:lib -launchreport

%% Look at the stored integer values of power_fixedpoint

stored_integer_values = storedInteger(power_fixedpoint) %#ok<NOPTS>

Tom Bryan on 15 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786326

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786326

Open in MATLAB Online

function p = power_loop(b,e)

T = power_types(b);

p = ones(length(b),length(e),'like',T.p);

fprintf('%20s|%20s|%20s|%20s|%20s|%20s|\n','i','j','power','base','exponent','NBits')

for i = 1:length(b)

for j = 1:length(e)

if isfi(b)

p(i,j) = power_scalar_function_fixedpoint_mex(b(i),e(j));

else

p(i,j) = power_scalar_function(b(i),e(j));

end

Bits = p(i,j);

NBits = log2(double(Bits));

fprintf('%20d|%20d|%20f|%20f|%20f|%20f|\n',i,j,p(i,j),b(i),e(j),NBits);

end

end

end

Tom Bryan on 15 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786331

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786331

Open in MATLAB Online

function p = power_scalar_function(b,e)

T = power_types(b);

p = cast(1,'like',T.p);

if (e > 0)

while(e~=0)

p(:) = p * b;

e = accumneg(e, 1);

end

else

while(e~=0)

p(:) = p * 1/b;

e = accumpos(e , 1);

end

end

end

Tom Bryan on 15 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786336

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786336

Open in MATLAB Online

function T = power_types(prototype)

if isfi(prototype)

% The range of the magnitude of the output is between 2^30 and

% 2^-30. This means that you need at least 30 integer bits, and 30

% fractional bits in the output. The output is also positive and

% negative. To accomodate this, I chose a signed fixed-point type

% with a 64 bit word length and 32 bit fraction length.

T.p = fi([],1,64,32);

else

% If not fixed-point, cast the output to the same type as the

% input.

T.p = cast([],'like',prototype);

end

end

Life is Wonderful on 16 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786926

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786926

Edited: Life is Wonderful on 16 Oct 2021

Dear @Tom Bryan,

Thanks a lot for sharing such flawless notes and implementation.

It's the best shared answer ( communication , making user understand/guidelines how to use code generation in a perfect way and technically correct soulution to match floating and fixed point implementation) . Personally, I haven't seen any thing exceeding current solution in the entire Mathworks community. It shows your experience and hard work to reach such heigths.

One request and recommendation, if you think current power implementation cover's all bases/corner cases, please replace existing power function Code generation in MathWorks. It is buggy - doesn't work.

I will do more test , share my feedback ( i see if can break it ) otherwise I will close/accept the answer.

Cheers,

best regards

Tom Bryan on 16 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786991

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786991

Thanks. It's my pleasure.

Could you provide a reproduction step to show me a bug in code generation for the power function?

For example, it would be a function using power that has a bug when you do codegen on it.

Best wishes,

Tom Bryan

Life is Wonderful on 16 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787226

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787226

Edited: Life is Wonderful on 16 Oct 2021

Open in MATLAB Online

Hi Tom,

It is simple , From the current / your proposal you can see with following changes ( no change in your proposed solution

function p = power_scalar_function(b,e)

T = power_types(b);

p = cast(1,'like',T.p);

p = power(b,e);

% if (e > 0)

% while(e~=0)

% p(:) = p * b;

% e = accumneg(e, 1);

% end

% else

% while(e~=0)

% p(:) = p * 1/b;

% e = accumpos(e , 1);

% end

% end

end

Error - Message

??? ProductMode must be SpecifyPrecision when the power exponent input is not constant. This assures that the output data type can be determined at compile time.

Error in ==> power_scalar_function Line: 4 Column: 9

Code generation failed: View Error Report

Error using codegen

Error in testbench (line 7)

codegen power_scalar_function -args {b(1),e(1)} ...

  • Debugging data for your reference

>> testbench

Code generation successful.

---------------------------------

Fixed Point

i| j| power| base| exponent| NBits|

1| 1| 1.000000000000000| -1.000000| -10.000000| 0.000000|

K>> class(b)

ans =

'embedded.fi'

K>> class(e)

ans =

'embedded.fi'

K>> power(b,e)

Error using fixed.internal.power.validateK (line 13)

Exponent input to 'power' must be a real scalar and the value must be a non-negative integer.

Error in fixed.internal.power.powImpl>validateInputs (line 39)

fixed.internal.power.validateK(k);

Error in fixed.internal.power.powImpl (line 9)

validateInputs(a, k);

Error in .^ (line 32)

y = fixed.internal.power.powImpl(a, k);

Also , for your refernce, I have another issue open.

Link -

Issue Description

https://in.mathworks.com/matlabcentral/answers/1464099-stop-bit-growth-for-power-computation?s_tid=srchtitle

Test cases

https://in.mathworks.com/matlabcentral/answers/1464099-stop-bit-growth-for-power-computation#comment_1763044

It would nice , if you have a look and suggest MathWorks ( if you agree )

Thank you

best regards,

Life is Wonderful on 16 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787241

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787241

Edited: Life is Wonderful on 26 Oct 2021

Open in MATLAB Online

function T = power_types(prototype)

https://in.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1786336

Need suggestion and advice on your Code generation ,

I have used "accumneg" and "accumpos" function to avoid MultiWord but I still see MultiWord~ ( making word length shorter 32 bit could lead to inaccuracies and lower total harmonic distortion ) therby I need your help and guidence.

I choose a signed fixed-point type with a 64 bit word length and 32 bit fraction length

- is generating MultiWord* , is there a suggestion to overcome this hurdle since it considerably slows down the DSP implementation [ i need 32 bit implementation and not higher ] and it take some efforts/ intelligence/ rework to make the code fast.

If you have guide/document link , tricks to eliminate or script , I welcome your inputs.

Note -

T.p = fi([],1,64,32); % original

T.p = fi([],1,32,32); % modified -Reducing WL, No MultiWord* is generated but accuracy suffers

Thank you in advance .

Tom Bryan on 16 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787471

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787471

Can you tell me about the overall problem you're trying to solve? In what context are you using this function?

It may be possible to refactor the original problem into something that requires much less dynamic range. For example, it is often possible to work in the logarithmic domain instead of the exponential domain.

Best wishes,

Tom Bryan

tbryan@mathworks.com

Tom Bryan on 16 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787511

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787511

The error with the builtin fi power method is a limitation but not a bug. The error message is telling you how to set the fimath to meet the requirements to use with a fi object: "Exponent input to 'power' must be a real scalar and the value must be a non-negative integer." See the documentation for fimath for how to use it with a fi object.

After setting fimath, you will run into another limitation with the builtin fi power method. It only works with positive exponents, and your example uses positive and negative exponents. Again, this is a limitation but not a bug.

Life is Wonderful on 17 Oct 2021

Direct link to this comment

https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787716

  • Link

    Direct link to this comment

    https://support.mathworks.com/matlabcentral/answers/1563361-error-in-fi-divide-for-embedded-fi-object#comment_1787716

Many thanks . Yes , I can understand limitation !!

best regards

Sign in to comment.

More Answers (0)

Sign in to answer this question.

See Also

Categories

Code GenerationMATLAB CoderGenerating Code

Find more on Generating Code in Help Center and File Exchange

Tags

  • fidivide error

Products

  • MATLAB

Release

R2021b

Community Treasure Hunt

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

Start Hunting!

An Error Occurred

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.


Error in fi divide for embedded fi object (20)

Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list

Americas

  • América Latina (Español)
  • Canada (English)
  • United States (English)

Europe

  • Belgium (English)
  • Denmark (English)
  • Deutschland (Deutsch)
  • España (Español)
  • Finland (English)
  • France (Français)
  • Ireland (English)
  • Italia (Italiano)
  • Luxembourg (English)
  • Netherlands (English)
  • Norway (English)
  • Österreich (Deutsch)
  • Portugal (English)
  • Sweden (English)
  • Switzerland
    • Deutsch
    • English
    • Français
  • United Kingdom(English)

Asia Pacific

Contact your local office

Error in fi divide for embedded fi object (2024)

References

Top Articles
Latest Posts
Article information

Author: Van Hayes

Last Updated:

Views: 5430

Rating: 4.6 / 5 (46 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Van Hayes

Birthday: 1994-06-07

Address: 2004 Kling Rapid, New Destiny, MT 64658-2367

Phone: +512425013758

Job: National Farming Director

Hobby: Reading, Polo, Genealogy, amateur radio, Scouting, Stand-up comedy, Cryptography

Introduction: My name is Van Hayes, I am a thankful, friendly, smiling, calm, powerful, fine, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.