Vectorizing a symbol with more than one value in a for loop in MATLAB - matlab

I would like to export the answers of an equation with the order of 2 into a vector. The input is R01and the variable is n.
The problem is where I want to "double" the symbol for each step of i, I get the following error:
In an assignment A(I)=B, the number of elements in B and I must be the
same.
There will be no error if I do not use a for loop. What is my mistake and how can I modify it that I could get the data as a matrix or vector.
R01=[0.07941 0.07942 0.07952 0.07946 0.07951 0.07947]
syms n
for i=1:length(R01)
eq3=((1+n)^2)*R01(i)-(n-1)^2
sol1=solve([eq3]);
nsol(i)=double(sol1);
end

The efficient way to solve the problem (by Daniel):
syms n
for i=1:length(R01)
eq3=((1+n)^2)*R01(i)-(n-1)^2
sol1=solve([eq3]);
nsol(i,:)=double(sol1);
end

Related

Calling an element of a vector inside a function in Matlab

I am new to Matlab and trying to define a simple function but keep running into an error. Details are:
1) V is a 31x1 vector;
2) The function mypi takes one input, which is a scalar (between 0 to 30). It finds the corresponding element in V vector and saves it in z.
3) Matrix A is a row vector with two elements 0 and z-10.
4) y, which is what I am interested in calculating is a linear function of the max of vector A.
Matlab, however, gives an error and is not recognizing element x in vector V. Can anyone please guide me how I should fix this problem? I will be grateful. Thank you.
function y=mypi(x)
z=V(x);
A=[0, z-10];
y=500+50*max(A);
end
you must pass V to mypi or make it visible to this function by defining it as global. But why bother passing both V and index x to this function instead of passing V(x) or z directly?
function y=mypi(z)
A=[0, z-10];
y=500+50*max(A);
end
and call it by mypi(V(x))

Vectorization of function in Matlab

I'm trying to vectorize one function in Matlab, but I have a problem with assigning values.
function [val] = clenshaw(coeffs,x)
b=zeros(1,length(coeffs)+2);
for k=length(coeffs):-1:2
b(k)=coeffs(k)-b(k+2)+2*b(k+1).*x;
end
val=coeffs(1)-b(3)+b(2).*x;
The purpose of this function is to use Clenshaw's algorithm to compute a value of one polynomial with coefficients "coeffs" at point x.
It work fine when x is a single value, but I'd like it to work with vector of arguments too.
When I try to pass a vector I get an error:
Unable to perform assignment because the left
and right sides have a different number of
elements.
Error in clenshaw (line 7)
b(k)=coeffs(k)-b(k+2)+2*b(k+1).*x;
I understand that there is a problem, because I'm trying to assign vector to a scalar variable b(k).
I tried making b a matrix instead of a vector, however I still cannot get the return output I'd like to have which would be a vector of values of this function at points from vector x.
Thank you for helping and sorry if something isn't entirely clear, because English is not my native language.
The vectorized version of your function looks like this:
function [val] = clenshaw(coeffs,x)
b=zeros(length(x),length(coeffs)+2);
for k=length(coeffs):-1:2
b(:,k)=coeffs(k)-b(:,k+2)+2*b(:,k+1).*transpose(x);
end
val=coeffs(1)-b(:,3)+b(:,2).*transpose(x);
end
b needs to be a matrix. In your loop, you have to perform every operation per row of b. So you need to write b(:,k) instead of b(k). Since b(:,k) is a vector and not a scalar, you also have to be careful with the dimensions when using the .* operator. To get the correct results, you need to transpose x. The same goes for the calculation of val. If you don't like the transposition, just swap the rows and cols of b and you get this:
function [val] = clenshaw(coeffs,x)
b=zeros(length(coeffs)+2, length(x));
for k=length(coeffs):-1:2
b(k,:)=coeffs(k)-b(k+2,:)+2*b(k+1,:).*x;
end
val=coeffs(1)-b(3,:)+b(2,:).*x;
end
However, the first version returns a column vector and the second a row vector. So you might need to transpose the result if the vector type is important.

MiniZinc can not find a solution when output statement introduced

I have a simple model written in minizinc and I use gecode to solve it by compiling it into flat-zinc first. As an input, the model takes some constants, arrays, and matrices (in the form of 2-dimensional arrays). The output of the model is another 2d matrix that has to satisfy some constraints.
Target optimization is to minimize the value of "target" which is a particular function of the output matrix and defined as following:
var float: target = sum(i in 1..nodes, j in 1..nodes) (F(i, j) * output_matrix[i, j]);
solve minimize target;
When I execute this model as follows:
mzn2fzn model.mzn model.dzn
fzn-gecode -a model.fzn
I can see a stream of possible solutions with the last one in the list to be the optimal. However, if I add an output statement into the model to print the value of the "target" variable - gecode hangs for hours without finding any solutions at all and prints ==UNKNOWN== if interrupted.
output [
"target: ", show(target), "\n"
];
Is this is an expected behavior, if so, could you explain why?
Cheers
This happens because output statement has influence on variables order during the solve phase.
In your case you output "target", so solver will try to assign value first to "target", then assign values to F matrix (i assume that F is your decision variables?), and this order of solving might take forever.
2 options:
Try to output your matrix F first, then target variable
output [show(F),show(target)];
Directs solver to assign values to F first during solve
solve ::int_search(array1d(F),input_order, indomain, complete) minimize target;
output [ "target: " ++ show(target) ++ "\n"];

Using a value from a matrix as a multiplier in an equation?

Started using MatLab a couple of weeks ago, I don't know much proper syntax / terminology.
I'm trying to use a value in a 3x1 matrix as a multiplier in an equation later.
This is to draw a circle with radius and centre point defined by values input by the user.
I have a pop-up window, the values are input by the user and stored in this 3x1 cell (labelled answer).
How do I use the second value of that matrix, answer(2), in the following equation:
x = 'answer(2)' * cos(theta) + xCentre;
This error message appears:
Error using .*
Matrix dimensions must agree.
Error in Disks (line 40)
x = 'answer(2)'.* cos(theta) + xCentre;
In MATLAB, apostrophes ('') define a string. If the name of your matrix is answer, you can refer to its second value by the command answer(2) as mentioned by #Schorsch. For more infos on vectors and matrices, you can check this site.
In addition to what the previous answer says, its important to understand what exactly you are doing before you do it. Only add the ('') if you are defining a string, which generally occurs when dealing with variables. In your case, you simply have a matrix, which is not a string, but rather a set of numbers. You can simply do answer(2) as aforementioned, because answer(2) calls up the second value in your matrix while 'answer(2)' has you trying to define some variable that does not exist.
the most important thing is truly understanding what you are doing to avoid the basic syntax errors.

matlab matrices and fold list

i have two problems in mathematica and want to do them in matlab:
measure := RandomReal[] - 0.5
m = 10000;
data = Table[measure, {m}];
fig1 = ListPlot[data, PlotStyle -> {PointSize[0.015]}]
Histogram[data]
matlab:
measure =# (m) rand(1,m)-0.5
m=10000;
for i=1:m
data(:,i)=measure(:,i);
end
figure(1)
plot(data,'b.','MarkerSize',0.015)
figure(2)
hist(data)
And it gives me :
??? The following error occurred
converting from function_handle to
double: Error using ==> double
If i do :
measure =rand()-0.5
m=10000;
data=rand(1,m)-0.5
then, i get the right results in plot1 but in plot 2 the y=axis is wrong.
Also, if i have this in mathematica :
steps[m_] := Table[2 RandomInteger[] - 1, {m}]
steps[20]
Walk1D[n_] := FoldList[Plus, 0, steps[n]]
LastPoint1D[n_] := Fold[Plus, 0, steps[n]]
ListPlot[Walk1D[10^4]]
I did this :
steps = # (m) 2*randint(1,m,2)-1;
steps(20)
Walk1D =# (n) cumsum(0:steps(n)) --> this is ok i think
LastPointold1D= # (n) cumsum(0:steps(n))
LastPoint1D= # (n) LastPointold1D(end)-->but here i now i must take the last "folding"
Walk1D(10)
LastPoint1D(10000)
plot(Walk1D(10000),'b')
and i get an empty matrix and no plot..
Since #Itamar essentially answered your first question, here is a comment on the second one. You did it almost right. You need to define
Walk1D = # (n) cumsum(steps(n));
since cumsum is a direct analog of FoldList[Plus,0,your-list]. Then, the plot in your code works fine. Also, notice that, either in your Mathematica or Matlab code, it is not necessary to define LastPoint1D separately - in both cases, it is the last point of your generated list (vector) steps.
EDIT:
Expanding a bit on LastPoint1D: my guess is that you want it to be a last point of the walk computed by Walk1D. Therefore, it would IMO make sense to just make it a function of a generated walk (vector), that returns its last point. For example:
lastPoint1D = #(walk) (walk(end));
Then, you use it as:
walk = Walk1D(10000);
lastPoint1D(walk)
HTH
You have a few errors/mistakes translating your code to Matlab:
If I am not wrong, the line data = Table[measure, {m}]; creates m copies of measure, which in your case will create a random vector of size (1,m). If that is true, in Matlab it would simply be data = measure(m);
The function you define gets a single argument m, therefor it makes no sense using a matrix notation (the :) when calling it.
Just as a side-note, if you insert data into a matrix inside a for loop, it will run much faster if you allocate the matrix in advance, otherwise Matlab will re-allocate memory to resize the matrix in each iteration. You do this by data = zeros(1,m);.
What do you mean by "in plot 2 the y=axis is wrong"? What do you expect it to be?
EDIT
Regarding your 2nd question, it would be easier to help you if you describe in words what you want to achieve, rather than trying to read your (error producing) code. One thing which is clearly wrong is using expression like 0:steps(n), since you use m:n with two scalars m and n to produce a vector, but steps(n) produces a vector, not a scalar. You probably get an empty matrix since the first value in the vector returned by steps(n) might be -1, and 0:-1 produces an empty vector.