How can I plot 3 equations with 3 variables in MATLAB? - matlab

I am trying to plot this system:
x1 - x2 + 3x3 = 8
2x1 - x2 + 4x3 = 11
- x1 + 2x2 -4x3 = -11
I tried with ezsurf and meshgrid, but I wasn't able to do it.
clc
clear all
close all
A = [1 -1 3; 2 -1 4; -1 2 -4];
B = [8 11 -11]';
C = [A B];
R = rref(C);
% R =
% 1 0 0 1
% 0 1 0 -1
% 0 0 1 2
D = R(:,4); % salvo la 4 colonna che contiene le soluzioni
disp('Le soluzioni del sistema proposto sono:');
disp(D);
figure(1);
hold on
grid on
syms x y z
eq = x + y + 3*z - 8;
Z = solve(eq,z)
ezsurf('8/3 - y/3 - x/3');
scatter3(D(1),D(2),D(3));
How can I plot this system of equations?

Maybe I'm missing something, but you have 3 unknown x1, x2 and x3 for 3 equations, therefore there is a unique solution (provided the determinant of the matrix is not zero):
>> A = [1 -1 3; 2 -1 4; -1 2 -4];
>> B = [8 11 -11]';
>> x = A\B
x =
1
-1
2
So there is nothing to plot other than a single point?

Related

Find intersections of a general vector with zeros MATLAB

Consider a general vector which represent some non-linear function
for example:
x = [1 2 3 4 5 6 7 8 9 10];
f = [-1 6 8 7 5 2 0.1 -2 -3];
Is there a method in matlab that can find the solutions of f(x)=0? with some given accuracy
If you think about it, when you have a random distribution f, finding zeros can only be done with linear interpolation between the data points:
For your example, I would define a function myFunc as:
function y = myFunc(val)
x = [1 2 3 4 5 6 7 8 9 10];
f = [-1 6 8 7 5 2 0.1 -2 -3 3];
P = griddedInterpolant (x, f, 'linear', 'linear');
y = P(val);
end
and apply a root searching algorithm via something like fzero:
val = 0;
x = [1 2 3 4 5 6 7 8 9 10];
x = [-inf x inf]; % Look outside boundary too
fun = #myFunc;
sol = zeros(1, numel(x)-1);
cnt = 0;
for i = 1:length(x)-1 % fzero stops at the 1st zero hence the loop over each interval
bound = [x(i) x(i+1)];
try
z = fzero(fun, bound);
cnt = cnt+1;
sol(cnt) = z;
catch
% No answer within the boundary
end
end
sol(cnt+1:end) = [];
Maybe you can try interp1 in arrayfun like below (linear interpolation was adopted)
x0 = arrayfun(#(k) interp1(f(k:k+1),x(k:k+1),0),find(sign(f(1:end-1).*f(2:end))<0));
such that
x0 =
1.1429 7.0476 9.5000
DATA
x = [1 2 3 4 5 6 7 8 9 10];
f = [-1 6 8 7 5 2 0.1 -2 -3 3];
I've made a function that does it, but feel it is something quite "regular" that matlab must have built in answers...so if someone has any write it down and I will accept it as an answer.
function sol = find_zeros(x,f)
f_vec = round(f*10^2)/10^2;
ind=find(diff(sign(f_vec))~=0);
K = length(ind);
if (K>0)
sol = zeros(1,K);
for k=1:K
if (f_vec(ind(k))<f_vec(ind(k)+1))
df = f_vec(ind(k)):0.01:f_vec(ind(k)+1);
else
df = flip(f_vec(ind(k)+1):0.01:f_vec(ind(k)));
end
dx = linspace(x(ind(k)),x(ind(k)+1),length(df));
j = find(df==0);
sol(k) = dx(j);
end
else
sol=[];
end
sol=unique(sol);
end

Set length of a column vector equal to the length of a submatrix

I am trying to use the convhull function in a loop and for that I need to split matrices into submatrices of different sizes. Here is the code I am using:
x1=data(:,5); % x centre location
y1=data(:,16); % y centre location
z1=phi*90; % phi angle value
n=300;
%Create regular grid across data space
[X,Y] = meshgrid(linspace(min(x1),max(x1),n), linspace(min(y1),max(y1),n));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% PLOT USING SCATTER - TRYING TO ISOLATE SOME REGIONS %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
c=z1>10 & z1 < 20;
c=c.*1;
j=1;
for i=1:length(z1)
if z1(i)< 20 && z1(i)> 10
c(i) = 1;
else
c(i)= 0;
end
end
C=[c c c];
C = ~C;
elementalLengthA = cellfun('length',regexp(sprintf('%i',all(C,2)),'1+','match'));
elementalStartA = regexp(sprintf('%i',all(C,2)),'1+','start');
result = cell(length(elementalLengthA),1);
for i = 1:length(elementalLengthA)
result(i) = {C(elementalStartA(i):elementalStartA(i)+elementalLengthA(i)-1,:)};
length(x1(i))=length(cell2mat(result(i)));
length(y1(i))=length(cell2mat(result(i)));
end
My for loop doens't work properly and I get this error: ??? Subscript indices must either be real positive integers or
logicals.
My matrix C is an nx3 matrix made of lines of 1 and 0. With the result(i) line I am splitting the C matrix into submatrices of 1. Let's say
c = [1 1 1;
0 0 0;
0 0 0;
1 1 1;
1 1 1;
1 1 1;
0 0 0;
1 1 1;
1 1 1;]
Then
>> cell2mat(result(1))
ans =
1 1 1
>> cell2mat(result(2))
ans =
1 1 1
1 1 1
1 1 1
>> cell2mat(result(3))
ans =
1 1 1
1 1 1
Now x1 and y1 are two vector column nx1. And I want to split them according to the length of C submatrices. so length(x1(1)) should be 1, length(x1(2))=3, length(x1(3))=2 and same for the y vector.
Is it possible to do that?
EDIT:
Just to make it more clear
For instance
x1 =
1
2
3
4
5
6
7
8
9
and
y1 =
2
4
6
8
10
12
14
16
18
I want to get this as an output:
x1(1)=[1], x1(2)=[4 5 6]' and x1(3)=[8 9]'
y1(1)=[2], y1(2)[8 10 12]' and y1(3)=[16 18]'
Thanks
Dorian

Creating Matrix with a loop in Matlab

I want to create a matrix of the following form
Y = [1 x x.^2 x.^3 x.^4 x.^5 ... x.^100]
Let x be a column vector.
or even some more variants such as
Y = [1 x1 x2 x3 (x1).^2 (x2).^2 (x3).^2 (x1.x2) (x2.x3) (x3.x1)]
Let x1,x2 and x3 be column vectors
Let us consider the first one. I tried using something like
Y = [1 : x : x.^100]
But this also didn't work because it means take Y = [1 x 2.*x 3.*x ... x.^100] ?
(ie all values between 1 to x.^100 with difference x)
So, this also cannot be used to generate such a matrix.
Please consider x = [1; 2; 3; 4];
and suggest a way to generate this matrix
Y = [1 1 1 1 1;
1 2 4 8 16;
1 3 9 27 81;
1 4 16 64 256];
without manually having to write
Y = [ones(size(x,1)) x x.^2 x.^3 x.^4]
Use this bsxfun technique -
N = 5; %// Number of columns needed in output
x = [1; 2; 3; 4]; %// or [1:4]'
Y = bsxfun(#power,x,[0:N-1])
Output -
Y =
1 1 1 1 1
1 2 4 8 16
1 3 9 27 81
1 4 16 64 256
If you have x = [1 2; 3 4; 5 6] and you want Y = [1 1 1 2 4; 1 3 9 4 16; 1 5 25 6 36] i.e. Y = [ 1 x1 x1.^2 x2 x2.^2 ] for column vectors x1, x2 ..., you can use this one-liner -
[ones(size(x,1),1) reshape(bsxfun(#power,permute(x,[1 3 2]),1:2),size(x,1),[])]
Using an adapted Version of the code found in Matlabs vander()-Function (which is also to be found in the polyfit-function) one can get a significant speedup compared to Divakars nice and short solution if you use something like this:
N = 5;
x = [1:4]';
V(:,n+1) = ones(length(x),1);
for j = n:-1:1
V(:,j) = x.*V(:,j+1);
end
V = V(:,end:-1:1);
It is about twice as fast for the example given and it gets about 20 times as fast if i set N=50 and x = [1:40]'. Although I state that is not easy to compare the times, just as an option if speed is an issue, you might have a look at this solution.
in octave, broadcasting allows to write
N=5;
x = [1; 2; 3; 4];
y = x.^(0:N-1)
output -
y =
1 1 1 1 1
1 2 4 8 16
1 3 9 27 81
1 4 16 64 256

Assigning indexes in MatLab using sub2ind

I have 3 data sets, two with coordinates and one with data with the length of n with a loop I would assign the data in this way
MAT = zeros(m, n);
for i = 1:n
MAT(Z(i), X(i)) = MAT(Z(i), X(i)) + DATA(i);
end
I want to do it without a loop since what I am trying to do is something like:
MAT = zeros(m, n);
mn = size(MAT);
MAT(sub2ind(mn, Z, X)) = MAT(sub2ind(mn, Z, X)) + DATA;
Anyone has an idea how to make it properly and efficiently?
Cheers.
You should use the function accumarray, for example:
Let:
>> Z = [ 1 2 4 3 1];
>> X = [3 2 1 4 3];
>> D = [5 6 7 8 -10];
>> m = 4;n = 4;
Then we have:
>> MAT = accumarray([Z(:),X(:)],D(:),[m,n])
MAT =
0 0 -5 0
0 6 0 0
0 0 0 8
7 0 0 0

Solving a MATLAB equation

I have the following equation:
((a^3)-(4*a^2))+[1 0 2;-1 4 6;-1 1 1] = 0
How do I solve this in MATLAB?
Here is one possibility:
% A^3 - 4*A^2 + [1 0 2;-1 4 6;-1 1 1] = 0
% 1) Change base to diagonalize the constant term
M = [1 0 2;-1 4 6;-1 1 1];
[V, L] = eig(M);
% 2) Solve three equations "on the diagonal", i.e. find a root of
% x^4 - 4*x^3 + eigenvalue = 0 for each eigenvalue of M
% (in this example, for each eigenvalue I choose the 3rd root,
% which happens to be real)
roots1 = roots([1 -4 0 L(1,1)]); r1 = roots1(3);
roots2 = roots([1 -4 0 L(2,2)]); r2 = roots2(3);
roots3 = roots([1 -4 0 L(3,3)]); r3 = roots3(3);
% 3) Build matrix solution and transform with inverse change of base
SD = diag([r1, r2, r3]);
A = V*SD*inv(V) % This is your solution
% The error should be practically zero
error = A^3 - 4*A^2 + [1 0 2;-1 4 6;-1 1 1]
norm(error)
(The error is actually of the order of 10^-14.)