I have 4 buttons on an FPGA dev board so I wrote
function [HEX0] = Bar(KEY)
n = uint8(sum(KEY, 'native'));
...
Unfortunately, HDL Coder turned it into the following chunk of VHDL:
y := '0';
FOR k IN 0 TO 3 LOOP
y := y OR KEY(k);
END LOOP;
y_0 := '0' & '0' & '0' & '0' & '0' & '0' & '0' & y;
Which I just don't get. Can you help me figure out what's going on here?
To understand this, you have to understand the matlab sum with logical inputs and native option. The sum of logicals is a logical. Thus sum could be replaced with an or
sum([true,true],'native')
And this is exactly what your Coder puts out. The for-Loop implements the sum (sum(KEY, 'native')), where the coder recognizes that it could be implemented using a OR.
Finally, conversion from logical to uint8 is done padding 7 zero bits.
Related
I'm trying to build a function in Matlab which generates a Taylor series around 0 for sine and the user can insert x (the value for which the sine is approximated) and a maximum error. Thus I want the function to check the maximum error and from this maximum it generates the amount of elements in the Taylor series.
I get the following error:
Error using factorial (line 20)
N must be an array of real non-negative integers.
Error in maxError (line 19)
y(x) = y(x) + (-1)^(j) * x^(2j+1)/factorial(2j+1)
Below my code.
function [n] = maxError(x,e);
%Computes number of iterations needed for a given absolute error.
n=1;
while abs(x)^(n+1)/factorial(n+1) >= e
n = n+1;
end
if mod(n,2) == 0
n=n+1;
end
y=#(x) x;
j=1;
while j<n
y(x) = y(x) + (-1)^(j) * x^(2j+1)/factorial(2j+1)
j=j+1;
end
return
I think I get the error because the factorial function can only take up integers, but the way I see it, I am feeding it an integer. Since j=1; and then gets larger by one per iteration, I don't see how Matlab can perceive this as something else than a integer.
Any help is appreciated.
You are using j as an indexing variable, which is also the complex number in Matlab, and your are forgetting a * multiply.
You can use j as a variable (not recommended!) but when you are putting a number in front of it, Matlab will stil interpret is as the complex number, and not as the variable.
Adding the multiplication symbol will solve the issue, but using i and j as variables will give you these hard to debug errors. If you had used a, the error would have been easier to understand:
>> a=10;
>> 2a+1
2a+1
↑
Error: Invalid expression. Check for missing multiplication operator, missing or
unbalanced delimiters, or other syntax error. To construct matrices, use brackets
instead of parentheses.
I'm using the following code:
for t = linspace(0,2,500)
x(t) = 1+ t^2;
y(t) = 2*t;
r(t) = sqrt((x(t))^2+(y(t))^2);
radius = 1.6
if r(t) > 0.999*radius & r(t) < 1.001*radius then
solucion = t;
end
end;
disp(solucion, "the solution is:")
Which works fine with t > 1 and different radius values.
But I get error 21: Invalid index when t takes values between 0 and 1.
I need to work with those values as well. How do I handle this?
Just so this shows up as answered in the overview:
Array indices in Scilab and MATLAB have to be positive integers (or logicals, but that is definitely not what you want here). If you need your t to vary over a range starting at 0, always write x(t+1). If you need non- integer values, still iterate over integers and compute the non-integral values from the loop index.
I have tried to implement the algorithm described in here to find primitive roots for a prime number.
It works for small prime numbers, however as I try big numbers, it doesn't return correct answers anymore.
I then notice that a^(p-1)/pi tends to be a big number, it returns inf in MATLAB, so I thought factorizing (p-1) could help, but I am failing to see how.
I wrote a small piece of code in MATLABand here it is.
clear all
clc
%works with prime =23,31,37,etc.
prime=761; %doesn't work for this value
F=factor(prime-1); % the factors of prime-1
for i = 2: prime-1
a=i;
tag =1;
for j= 1 :prime-1
if (isprime(j))
p_i = j;
if(mod(a^((prime-1)/p_i),prime)== 1)
tag=0;
break
else
tag = tag +1;
end
end
end
if (tag > 1 )
a %it should only print the primitive root
break
end
end
Any input is welcome.
Thanks
What Matlab does in this case is it calculates a^((p-1)/p) before taking the modulus. As a^((p-1)/p) quite quickly becomes too large to handle, Matlab seems to resolve this by turning it into a floating point number, losing some resolution and yielding the wrong result when you take the modulus.
As mentioned by #rayreng, you could use an arbitrary precision toolbox to resolve this.
Alternatively, you could split the exponentiation into parts, taking the modulus at each stage. This should be faster, as it is less memory intensive. You could dump this in a function and just call that.
% Calculates a^b mod c
i = 0;
result = 1;
while i < b
result = mod(result*a, c);
i = i + 1;
end
I am trying out the questions in programming assignment of Coursera course on Matlab programming as an exercise. This is my Question:
Write a function called sort3 that takes three scalar arguments. It uses if-statements, possibly nested, to
return the three values of these arguments in a single row-vector in increasing order (or more precisely,
non-decreasing order), i.e., element one of the output vector equals the smallest input argument and
element three of the output vector equals the largest input argument.
Here is my code:
function sv = sort3(x,y,z)
if nargin < 3
error('must have at least three input argument');
else
if ~isscalar(x) || x ~= fix(x)
error('x needs to be a scalar');
end
if ~isscalar(y) || y ~= fix(y)
error('y needs to be a scalar');
end
if ~isscalar(z) || z ~= fix(z)
error('z needs to be a scalar');
end
end
a=x;
b=y;
c=z;
if a >= b
t=a;
a=b;
b=t;
end
if b >= c
t=b;
b=c;
c=t;
end
if a >= b
t=a;
a=b;
b=t;
end
if nargout == 1
sv=[a b c];
end
I got the below result on Matlab.
Problem 3 (sort3):
Feedback: Your program made an error for argument(s) -1.3719900292403, -0.639443998445333, 1.04704952581735
Please help me.
Thanks.
When you compare x with fix(x) your program moves to the command error that you have written.
When you pass to your function a decimal number, obviously x is always not equal to fix(x) and then your function will always end with an error.
If you want to work only with scalars or integers, you can think to apply function fix to your input before to start with your algorithm.
I try to compile the following code with Dymola:
class abc
import Modelica.SIunits;
parameter SIunits.Time delta_t=0.5;
constant Real a[:]={4,2,6,-1,3,5,7,4,-3,-6};
Real x;
Integer j(start=1);
Integer k=size(a, 1);
algorithm
when {(sample(0, delta_t) and j < k),j == 1} then
x := a[j];
j := j + 1;
end when;
end abc;
and for time = 0 the variable j starts with 2. But it should start with j = 1.
Does anybody have an idea for this problem?
Keep in mind that sample(x,y) means that sample is true at x+i*y where i starts at zero. Which is to say that sample(0, ...) becomes true at time=0.
Since j starts at 1 and k is presumably more than 1, it doesn't seem unexpected to me that sample(0, delta_t) and j<k should become true at the start of the simulation.
I suspect what you want is:
class abc
import Modelica.SIunits;
parameter SIunits.Time delta_t=0.5;
constant Real a[:]={4,2,6,-1,3,5,7,4,-3,-6};
Real x;
Integer j(start=1);
Integer k=size(a, 1);
algorithm
when {(sample(delta_t, delta_t) and j < k),j == 1} then
x := a[pre(j)];
j := pre(j) + 1;
end when;
end abc;
I don't really see the point of the j==1 condition. It is true at the outset which means it doesn't "become" true then. And since j is never decremented, I don't see why it should ever return to the value 1 once it increments for the first time.
Note that I added a pre around the right-hand side values for j. If this were in an
equation section, I'm pretty sure the pre would be required. Since it is an algorithm section, it is mainly to document the intent of the code. It also makes the code robust to switching from equation to algorithm section.
Of course, there is an event at time = 0 triggered by the expression sample(0, delta_t) and j<k which becomes true.
But in older versions of Dymola there is an bug with the initialization of discrete variables. For instance even if you remove sample(0.0, delta_t) and j<k in dymola74, j will become 2 at time=0. The issue was that the pre values of when clauses, where not initialized correct. As far as I know this is corrected at least in the version FD1 2013.