How to create a matrix in Matlab with every entry being the output of a bivariate function - matlab

I want to create a 4 x 4 matrix with each entry representing f(x,y) where both x and y take values 0, 1, 2 and 3. So the first entry would be f(0,0), all the way to f(3,3).
The function f(x,y) is:
3 * cos(0*x + 0*y) + 2 * cos(0*x + 1*y) + 3 * cos(0*x + 2*y) + 8 * cos(0*x + 3*y)
+ 3 * cos(1*x + 0*y) + 25 * cos(1*x + 1*y) + 3 * cos(1*x + 2*y)
+ 8 * cos(1*x + 3*y)
+ 3 * cos(2*x + 0*y) + 25 * cos(2*x + 1*y) + 3 * cos(2*x + 2*y)
+ 8 * cos(2*x + 3*y)
+ 3 * cos(3*x + 0*y) + 25 * cos(3*x + 1*y) + 3 * cos(3*x + 2*y)
- 90 * cos(3*x + 3*y)
I haven't used Matlab much, and it's been a while. I have tried turning f(x,y) into a #f(x,y) function; using the .* operator; meshing x and y, etc. All of it without success...

Not sure, what you've tried exactly, but using meshgrid is the correct idea.
% Function defintion (abbreviated)
f = #(x, y) 3 * cos(0*x + 0*y) + 2 * cos(0*x + 1*y) + 3 * cos(0*x + 2*y)
% Set up x and y values.
x = 0:3
y = 0:3
% Generate grid.
[X, Y] = meshgrid(x, y);
% Rseult matrix.
res = f(X, Y)
Generated output:
f =
#(x, y) 3 * cos (0 * x + 0 * y) + 2 * cos (0 * x + 1 * y) + 3 * cos (0 * x + 2 * y)
x =
0 1 2 3
y =
0 1 2 3
res =
8.00000 8.00000 8.00000 8.00000
2.83216 2.83216 2.83216 2.83216
0.20678 0.20678 0.20678 0.20678
3.90053 3.90053 3.90053 3.90053

Related

solve complex equations in MATLAB (Variable Equations)

I have some equations which include some parameters and variables.
Each variable defines and also exists in other equations. these are my equations:
syms Pof s Pon teta landa PIon PIof PISC
Pof = (s * y - teta + T * teta - landa + Pi * landa + alpha * p + Pon * b1 + w * b2)/(2 * b2);
s = -(y * (w - Pof))/q;
Pon = (q * s * y + 2 * w * y - 2 * w * y^2 + 2 * q * alpha + 2 * q * Pi * landa - q * teta + 3 * q * T * teta - q * landa + q * Pi * landa - q * alpha * p - 2 * y * Pof + 2 * y^2 * Pof + C * q * b1 + q * w * b2)/(2 * q * b1);
teta = (C - 3 * C * T - Pon + 3 * T * Pon)/2 * q;
landa = (-1/2) * (-1 + Pi) * (C - Pon);
Don = (1-p) * alpha - b1 * Pon + b2 * Pof - (1-y) * s + T * teta + landa * Pi;
Dof = p * alpha - b1 * Pof + b2 * Pon + y * s - (1-T) * teta - landa * (1-Pi);
PIon = (Pon-C) * Don - (1/2) * n * teta^2 - (1/2) * q * landa^2;
PIof = (Pof-w) * Dof - (1/2) * L * s^2;
PISC = PIon + PIof;
How I can solve these in order to get a numeric answer for each variable?
(I don't want parametric answers)
The equations as stated are
which can be arranged as a linear system A x = b as follows
which you solve in Matlab as x = A \ b
On further investigation, it seems A is singular since it's 10×8 in size and cannot be inverted. So a least-squares solution is needed where
x = inv(AT* A)* AT b

Matlab: Nonlinear Eq: error

I have the code from a previous question, however, this one is similar, just more equations added. However, I get an error and I'm not sure how to fix it.
Link to my previous question: Matlab: Nonlinear equation solver
function F = fcn(x)
F=[x(6) + x(7) + x(8) + x(9) + x(10) - 2 ;
x(6)*x(1) + x(7)*x(2) + x(8)*x(3) + x(9)*x(4) + x(10)*x(5) ;
x(6)*x(1)^2 + x(7)*x(2)^2 + x(8)*x(3)^2 + x(9)*x(4)^2 + x(10)*x(5) - 2/3 ;
x(6)*x(1)^3 + x(7)*x(2)^3 + x(8)*x(3)^3 + x(9)*x(4)^3 + x(10)*x(5) ;
x(6)*x(1)^4 + x(7)*x(2)^4 + x(8)*x(3)^4 + x(9)*x(4)^4 + x(10)*x(5) -2/5 ;
x(6)*x(1)^5 + x(7)*x(2)^5 + x(8)*x(3)^5 + x(9)*x(4)^5 + x(10)*x(5) ;
x(6)*x(1)^6 + x(7)*x(2)^6 + x(8)*x(3)^6 + x(9)*x(4)^6 + x(10)*x(5) -2/7 ;
x(6)*x(1)^7 + x(7)*x(2)^7 + x(8)*x(3)^7 + x(9)*x(4)^7 + x(10)*x(5) ;
x(6)*x(1)^8 + x(7)*x(2)^8 + x(8)*x(3)^8 + x(9)*x(4)^8 + x(10)*x(5) -2/9 ;
x(6)*x(1)^9 + x(7)*x(2)^9 + x(8)*x(3)^9 + x(9)*x(4)^9 + x(10)*x(5)
];
end
clc
clear all;
format long
x0 = [0.9; 0.5; 0.1; -0.5; -0.9; 0.2; 0.4; 0.5; 0.4; 0.2]; %Guess
F0 = fcn(x0);
[x,fval]=fsolve(#fcn, x0) %solve without optimization
options = optimset('MaxFunEvals',10000, 'MaxIter', 10000); %optimization criteria
[x,fval]=fsolve(#fcn, x0, options) %solve with optimization
The error that I get are:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in fcn(line 4) %This is from the function script
F=[x(6) + x(7) + x(8) + x(9) + x(10)
- 2 ;
Error in fcncall (line 7) %This is from the main script
F0 = fcn(x0);
This is a very subtle error I've encountered before. When creating an array literal as you are doing fcn, negative signs that are directly attached to numbers and preceded by a space, as in rows 5, 7, and 9 of your array literal, are viewed as unary operators (i.e., the - makes the number negative and does not act as a binary minus operation). Therefore, because Matlab allows the delimiting of columns to be made with spaces, the indicated rows are interpreted to have two columns; row 5 column 1 is x(6)*x(1)^4 ... x(10)*x(5), and row 5 column 2 is -2/5.
So, either put a space between the three numbers or eliminate all spaces between the minus signs. For example:
x(6)*x(1)^4 + x(7)*x(2)^4 + x(8)*x(3)^4 + x(9)*x(4)^4 + x(10)*x(5) - 2/5;
or
x(6)*x(1)^4 + x(7)*x(2)^4 + x(8)*x(3)^4 + x(9)*x(4)^4 + x(10)*x(5)-2/5;
That problem wasn't easy to find. Not using a blank before the minus at the end of the rows, you created a row with two elements instead of one. For a simplified example compare this:
>> [2 - 2]
ans =
0
>> [2 -2]
ans =
2 -2
>> [(2 -2)]
ans =
0
Now the corrected version of your code:
F=[x(6) + x(7) + x(8) + x(9) + x(10) - 2 ;
x(6)*x(1) + x(7)*x(2) + x(8)*x(3) + x(9)*x(4) + x(10)*x(5) ;
x(6)*x(1)^2 + x(7)*x(2)^2 + x(8)*x(3)^2 + x(9)*x(4)^2 + x(10)*x(5) - 2/3 ; ...either set a space
x(6)*x(1)^3 + x(7)*x(2)^3 + x(8)*x(3)^3 + x(9)*x(4)^3 + x(10)*x(5) ;
(x(6)*x(1)^4 + x(7)*x(2)^4 + x(8)*x(3)^4 + x(9)*x(4)^4 + x(10)*x(5) -2/5); ...or use brackets
x(6)*x(1)^5 + x(7)*x(2)^5 + x(8)*x(3)^5 + x(9)*x(4)^5 + x(10)*x(5) ; ...both fixes the problem
x(6)*x(1)^6 + x(7)*x(2)^6 + x(8)*x(3)^6 + x(9)*x(4)^6 + x(10)*x(5) - 2/7 ;
x(6)*x(1)^7 + x(7)*x(2)^7 + x(8)*x(3)^7 + x(9)*x(4)^7 + x(10)*x(5) ;
x(6)*x(1)^8 + x(7)*x(2)^8 + x(8)*x(3)^8 + x(9)*x(4)^8 + x(10)*x(5) - 2/9 ;
x(6)*x(1)^9 + x(7)*x(2)^9 + x(8)*x(3)^9 + x(9)*x(4)^9 + x(10)*x(5) ];

Double sum and how to make a matrix to plot in 3D? (surface plot)

Edit
To clarify. I have a function f that takes in 5 arguments z,x,y,n,m. The order of events should go as follows:
Upon calling the function test, the variable z is assigned, say z = 1.
A linear combination is created by adding f with with each of elements of ni inserted and the result is stored in fn, as such (z = 1, so no more z variable):
fn = x + 2.*y + exp(0) - sqrt(m) +
x + 2.*y + exp(2) - sqrt(m) +
x + 2.*y + exp(4) - sqrt(m) +
x + 2.*y + exp(6) - sqrt(m) +
x + 2.*y + exp(8) - sqrt(m) +
x + 2.*y + exp(10) - sqrt(m) =
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(m) =
6*x + 12*y + 25473.8 - 6*sqrt(m)
A linear combination is created by adding fn with each of elements of mi inserted and the result is stored in fnm. (I don't know how to do 1. and 2. simultaneously. If you do, please let me know):
fnm = 6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(0) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(2) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(4) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(6) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(8) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(10) =
6*x + 12*y + 25453.1
A surface is plotted by plugging in x and y from arrays xi and yi into fnm
and of Edit
I'm having trouble with the double summation over the function f. I tried to follow the example in the last answer presented here, but it's not working for some reason. Because my variables x and y are not defined beforehand, I included them into #() in the arrayfun. I was first getting the error Z must be a matrix, not a scalar or vector. , so I changed the function handle fnm to a symbolic function after reading about it here. But now the whole thing exploded ... I don't know what's going on. Why is it saying there aren't enough inputs? fn should only be a function of x, y, m on line 11 since z is already defined to be some number (lets say 1) and n's just got summed over.
function test(z)
f = #(z,x,y,n,m) z.*x + 2.*y + exp(n) - sqrt(m);
function s(z)
ni = 0:2:10;
mi = 0:2:10;
xi = -5:5;
yi = -5:5;
fn = #(n) arrayfun(#(z, x, y, ni, m) sum(f(z, x, y, ni, m)),n);
fnm = #(m) arrayfun(#(x, y, mi) sum(fn(x, y, mi)),m);
zz = sym(fnm);
[xx,yy] = meshgrid(xi,yi);
surf(xx,yy,zz)
end
s
end
so many errors :(
Error using test2>#(x,y,mi)sum(fn(x,y,mi)) (line 11)
Not enough input arguments.
Error in test2>#(m)arrayfun(#(x,y,mi)sum(fn(x,y,mi)),m) (line 11)
fnm = #(m) arrayfun(#(x, y, mi) sum(fn(x, y, mi)),m);
Error in sym>funchandle2ref (line 1209)
S = x(S{:});
Error in sym>tomupad (line 1114)
x = funchandle2ref(x);
Error in sym (line 151)
S.s = tomupad(x);
Error in test2/s (line 12)
zz = sym(fnm);
Error in test2 (line 18)
s
Are you trying to do this?. I am not optimizing anything, for you to understand it clearly....
function test(zi)
syms z x y n m fn fnm;
f0=symfun(z.*x + 2.*y + exp(n) - sqrt(m),[z x y n m]);
z=zi;
ni=0:2:10;
mi=0:2:10;
fn=0;
for i=1:length(ni);
fn=symfun(fn+f0(z,x,y,ni(i),m),[x y m]);
end
fnm=0;
for i=1:length(mi)
fnm=symfun(fnm+fn(x,y,mi(i)),[x y]);
end
xi=-5:5;
yi=-5:5;
for i=1:length(xi)
for j=1:length(yi)
zz(i,j)=eval(fnm(xi(i),yi(j)));
end
end
[xx,yy]=meshgrid(xi,yi);
mesh(xx,yy,zz);
So, test(1) produces this:
Beware of the symfun calls, which shall be put there in order every summation keeps onto a "symbolic" framework. The arrayfun could be used, though they are neat, they could be not necesarily efficient... Let that exercise as homework!! XD..

Solving a linear system of equation with two variables in MATLAB

It might seem a simple question. I need it, though. Let's assume we have two equations:
2 * y + x + 1 = 0
and
y - 2 * x = 0
I would like to find their bisection which can be calculated from this equation:
|x + 2 * y + 1| |-2 *x + y |
------------------- = -----------------
(sqrt(2^2 + 1^2)) (sqrt(1^2 + 2^2))
To make the long story short, we only need to solve this below system of equation:
2 * y + x + 1 = -2 *x + y
and
2 * y + x + 1 = 2 *x - y
However, using solve function of MATLAB:
syms x y
eqn1 = 2 * y + x + 1 == -2 *x + y ;
eqn2 = 2 * y + x + 1 == 2 *x - y ;
[x, y] = solve (eqn1 , eqn2, x, y) ;
Will give me:
x = -1/5 and y = -2/5
But, I am looking for the result equations, which is:
y = -3 * x - 1 and 3 * y = 2 * x - 1
So, does anyone know how I can get the above line equation instead of the result point? Thanks,
The following should solve both equations with y on the left-hand-side:
y1 = solve(eqn1,y)
y2 = solve(eqn2,y)
Result:
y1 =
- 3*x - 1
y2 =
x/3 - 1/3
As an aside, it would be much faster to solve this system by thinking of it it as a matrix inversion problem Ax=b rather than using MATLAB's symbolic tools:
A = [1 2; -2 1];
b = [-1; 0];
x = A\b
Result:
x =
-0.2000
-0.4000

Matlab Vectorization : How to avoid this "for" loop?

I have following matrices :
X=1 2 3
Y=4 5 6
A=1 2 3
4 5 6
7 8 9
I Want to do
for each (i,j) in A
v = A(i,j)*X - Y
B(i,j) = v * v'
i.e. each element of A is multiplied by vector X, then resultant vector subtracts Y from itself and finally we take inner product of that vector to bring a single number.
Can it be done without for loop ?
One thing often forgotten in Matlab: The operator ' takes the conjugate transposed (.' is the ordinary transposed). In other words, A' == conj(trans(A)), whereas A.' == trans(A), which makes a difference if A is a complex matrix.
Ok, let's apply some mathematics to your equations. We have
v = A(i,j)*X - Y
B(i,j) = v * v'
= (A(i,j)*X - Y) * (A(i,j)*X - Y)'
= A(i,j)*X * conj(A(i,j))*X' - Y * conj(A(i,j))*X'
- A(i,j)*X * Y' + Y * Y'
= A(i,j)*conj(A(i,j)) * X*X' - conj(A(i,j)) * Y*X' - A(i,j) * X*Y' + Y*Y'
So a first result would be
B = A.*conj(A) * (X*X') - conj(A) * (Y*X') - A * (X*Y') + Y*Y'
In the case of real matrices/vectors, one has the identities
X*Y' == Y*X'
A == conj(A)
which means, you can reduce the expression to
B = A.*A * (X*X') - 2*A * (X*Y') + Y*Y'
= A.^2 * (X*X') - 2*A * (X*Y') + Y*Y'
An alternative method:
X = [1 2 3]
Y = [4 5 6]
A = [1 2 3; 4 5 6; 7 8 9]
V = bsxfun(#minus, A(:)*X, [4 5 6])
b = sum((V.^2)')
B = reshape(b , 3, 3)
I get the result:
B = 27 5 11
45 107 197
315 461 635