Matlab substitution within matrices not working as intended - matlab

Where does the following matlab code go wrong?
C=sym('a',[2,1]);
A=sym('aa',2);
A(1,1)=C(1)-10*C(2)*C(2);
A(2,2)=C(2);
subs(A(1,1),C(1),solve(trace(A)==1,C(1)));
disp(A);
As I understand it, the diagonal elements of A are set to functions of a1 and a2. Then, in the expression at position A(1,1), substitute for C(1) (which is a1), the solution to trace(A)==1 for the variable C(1). But when you display the matrix A, it seems unchanged.
What is the error? Why is subs not working as intended? The above is the smallest non-working example of large code.

There is no error in the code. The subs = subs(s, old, new) function returns by definition a copy of s after all occurrences of old are replaced with new, and then evaluates s.
What your code does is: Define A, call subs and then display A. Since subs does not effect the entries of A by the above explanation, you get the "old" A displayed.
Hence, if you want to replace the value A(1, 1) with the expression which subs created for you, you should e.g. use
A(1, 1) = subs(C(1) , solve(trace(A) == 1, C(1)));

As I understand you try to replace the element at A(1,1) with the result from solving the equation. In this case, you should do something like that:
C = sym('a',[2,1]);
A = sym('aa',2);
A(1,1) = C(1);
A(2,2) = C(2);
A(1,1) = subs(C(1),solve(trace(A) == 1, C(1)));
disp(A);
This will display the following:
[ 1 - a2, aa1_2]
[ aa2_1, a2]

Related

Fourier series graph generation from given coefficients an, bn in Matlab(Scilab)

I've calculated coefficients an, bn (100, T=2*pi) in c++ and checked that they are correct using few sources. Now i try to generate Fourier series graph for given example function in Scilab:
(x+2)*abs(cos(2*x*(x-pi/6)))
M=csvRead(filename, ";", [], 'double')
n=size(M,1)
for i = 1:n
A(i)=M(i)
B(i)=M(i + n)
end
function series=solution(x)
series=A(1)/2;
for i = 2:n
series=series+(A(i)*cos(i*x)+B(i)*sin(i*x));
end
endfunction
function series=solution2(x)
series=(x+2).*abs(cos(2.*x.*(x-%pi/6)));
endfunction
x = -%pi:%pi/100:%pi
plot2d(x, solution(x), 3)
x2 = -%pi:%pi/100:%pi
plot2d(x2, solution2(x2), 4)
Here is the result:
It clearly looks that tendency is ok but the beginning and the end of the period are wrong (reversed?). Do you see any issues in Scilab code? What could cause the problem - values in sin/cos in function solution(x)? Should i provide an, bn values and check for miscalculation there?
I don't know how did you calculated your A & B coefficients, but I assume that you used the usual notations to get the first line of the below formula:
Thus n starts from 1. Since Scilab starts vector indexing from 1, you correctly made your loop from 2, but forgot to compensate for this "offset".
Your function should be something like this:
function series=solution(x)
series=A(1)/2;
for i = 2:n
series=series+(A(i)*cos((i-1)*x)+B(i)*sin((i-1)*x));
end
endfunction
Since you didn't provided A & B, I can not check the result.
Additional note: Syntactically more correct if you explicitly define all input variables in a function, like this:
function series=solution(x,A,B)
This way you may be sure that your input is not changed somewhere else in the code.

How do functions really work in MATLAB?

function [dhdt, x] = velocity(t, h)
dhdt = -9.8 * t;
x = 4 * t;
end
So this is basically my function (with filename velocity.m). At first I thought that what's between the brackets [] would be the output. When I typed in the Command Window I only got one answer.
velocity(1)
%// -9.8
I expected to get a two-element vector containing both dhdt and x
velocity(1)
%// -9.8 4
Why is this?
Matlab only displays one output if you don't store them to variables... Type [dhdt, x] = velocity(1) and you'll see both values, as well as having them stored to variables.
Also, you only get away in this case with not providing the h parameter because it's not used in the function. If you used h in velocity() and called velocity(1) it would break.

Please Help: In an assignment A(I) = B, the number of elements in B and I must be the same. MATLAB

I was asked in an assignment to use Euler's method to determine the values of t and y from t=0:1000. I have all the basic code and parameters down but when i put my Euler's equation in I get the error code
In an assignment A(I) = B, the number of
elements in B and I must be the same.
Error in Project1 (line 24)
Ay(i+1) = Ay(i) + (dAy)*x;
How could I change these variables between vectors and scalars to allow the equation to run? My full code can be found below:
dt=x;
Ay=zeros(1,1001);
Ay0=1250;
Ay(1) = Ay0;
t=0;
y=0;
t=0:dt:1000;
for i=1:1000
if y > 10
Qout=3*(y-10).^1.5;
else
Qout=0;
end
Qin=1350*sin(t).^2;
dAy=Qin-Qout;
Ay(i+1) = Ay(i) + dAy*dt;
end
plot(t,y);
The issue is that your variable "Qin" is not a number it is a vector containing sin values of the whole vector t. Similarly your "dAy" is also a vector. Hence it cannot be stored in a variable Ay.
if your dt =x = 1, just replace sin(t) with sin(i) i.e.
replace
Qin=1350*sin(t).^2;
by
Qin=1350*sin(i).^2;
The problem lies in the line of your code:
Ay(i+1) = Ay(i) + dAy*dt;
dAy*dt returns a vector.
When you add it to Ay(i) you still end up with a vector.
Ay(i+1) is a SINGLE element within a vector.
You Cannot assign a vector quantity to an element within a vector.

octave plot does not work properly

CODE DELETED
Hi, the code above is my (slightly modified) rooo.m file.
I'm just trying to plot the function by typing into (octave) terminal
x = 1:1:40;
plot(x, rooo(x), '+');
But this will only print the graph of y=1.
I believe it's because of the y = 1; in the first line (btw the function itself returns the right value, say when I type rooo(3)).
When I change it to some other number (say b), the graph will show y =b.
Does anyone have an idea why this is happening??
I think it's not working because if you type rooo(x) at the command line, it will return a scalar result of 1, instead of a vector. The 1 < n logical condition doesn't work as you intended to when n is a vector.
Here is a suggestion to make it work (maybe not the most elegant but it seems to work):
CODE DELETED
Which, when called as in your question, gives the following plot
The results seem to be different from the ones reported in MATLAB though.
An alternative, if you don't want to modify your function, is to change the way you call it:
>> x = 1:1:40;
>> y = ones(size(x));
>> for k=1:length(x)
y(k) = rooo(x(k));
end
>> plot(x,y,'+')
This gives the same result as the above suggestion.
It's not working because you never enter the while loop with x starting at 1. Since
1 < n == 1 < x is false at the very beginning, the function returns.
However when you call rooo(3) or actually rooo(Anything > 1) it does work. With x = 1.1:1:40 the plot looks like this ( I made it with Matlab) :

My fft2 function not work with me

I faced a problem when I convert these two statements from build in to my own function:
gaus=gauss/sum(gauss(:));
BeforeAbs=fft2(gaus,size(im,1),size(im,2));
And it gave me [Attempted to access X(2); index out of bounds because numel(X)=1]
%--------Start convert from build in to my own function of Fourier transformation of 1 D
gaus=gauss/sum(gauss(:));
for u=1:(gaus)
summ=0;
for x=1:1
w2=(-1*(sqrt(-1)))*2*pi*((u*x)/(gaus+1))
summ=summ+(gaus(x)*exp(w2));
end
PQ2(u)=summ;
end%
X=size(im,1);
for u=1:(X)
summ=0;
for x=1:1
w3=(-1*(sqrt(-1)))*2*pi*((u*x)/(X+1))
summ=summ+(X(x)*exp(w3));
end
PQ3(u)=summ;
end
BeforeAbs=[PQ2 PQ3];
Can anyone tell me why this error appears with me?
In your code, the statement
X=size(im,1);
returns the size of the variable im along its first dimension. That would return a scalar value. However, you have a for loop:
for x=1:2
...
summ=summ+(X(x)*exp(w3));
end
that iterates over the values x = 1 and x = 2. When you try to evaluate X(x) when x = 2, you get the error because X has only one element.
Basically, you are doing something equivalent to this:
X = 5
X(2)
Also, your for-loop for u:
for u=0:(X-1)
starts from u = 0, but later you try to set
PQ3(u)=summ;
However, array indexing in MATLAB is 1-based, so PQ3(0) would result in an error. You should start indexing from 1: PQ3(1) = summ.