For the below given input and output, the matrix A can be found out by pseudoinverse or mrdivision in MATLAB. Similarly, I would now like to know, how to determine A, if my output signal Y matrix contains additive zero mean, uncorrelated, Gaussian noise?
x1 = [1 1 1]';
x2 = [0 1 1]';
x3 = [0 0 1]';
x4 = [1 0 1]';
y1 = [1 2 0]';
y2 = [-1 0 3]';
y3 = [3 1 1]';
y4 = [5 3 -2]';
X = [x1 x2 x3 x4];
Y = [y1 y2 y3 y4];
A = Y/X
Also, I have modelled the unknown noisy output as below:
y1_n = y1 + sqrt(var(y1))*randn(size(y1));
y2_n = y2 + sqrt(var(y2))*randn(size(y2));
y3_n = y3 + sqrt(var(y3))*randn(size(y3));
y4_n = y4 + sqrt(var(y4))*randn(size(y4));
Y = [y1_n y2_n y3_n y4_n];
The statement A = Y/X solves the linear system of equations A*X = Y. If the system is overdetermined, as in your case, the solution given is the least squares solution. Thus, if you have additive, zero mean, uncorrelated, Gaussian noise on Y, then A = Y/X will give you the best possible, unbiased, estimate of A.
Note that the noise you add to your Y matrix is quite large, hence the estimate of A is far away from the ideal. If you add less noise, the estimate will be closer:
x1 = [1 1 1]';
x2 = [0 1 1]';
x3 = [0 0 1]';
x4 = [1 0 1]';
X = [x1 x2 x3 x4];
y1 = [1 2 0]';
y2 = [-1 0 3]';
y3 = [3 1 1]';
y4 = [5 3 -2]';
Y = [y1 y2 y3 y4];
for n = [1,0.1,0.01,0]
Y_n = Y + n*randn(size(Y));
A = Y_n/X;
fprintf('n = %f, A = \n',n)
disp(A)
end
Output:
n = 1.000000, A =
2.9728 -5.5407 2.8011
2.6563 -1.3166 0.6596
-3.3366 1.1349 1.5342
n = 0.100000, A =
2.0011 -4.0256 2.9402
1.9223 -1.0029 1.0921
-3.1383 1.9874 1.0913
n = 0.010000, A =
1.9903 -3.9912 2.9987
1.9941 -1.0001 1.0108
-3.0015 2.0001 1.0032
n = 0.000000, A =
2.0000 -4.0000 3.0000
2.0000 -1.0000 1.0000
-3.0000 2.0000 1.0000
Of course if you make X and Y larger by adding more vectors you'll get a better estimate too, and will be able to compensate more noisy data.
Related
I have a matrix y and a vector x, I need to find all the possible vectors resulted from the mapping of each value in x into each vector in y.
That is difficult to be understood; let's explain is with an example:
Here is an example, I have the vector x = [0.7 + 0.7i; 0.7-0.7i]; The matrix y = [1 0; 2 0; 1 2]; the resulted matrix is supposed to be like this one Z = [0.7 + 0.7i 0; 0.7-0.7i 0; 0 0.7 + 0.7i; 0 0.7-0.7i; 0.7 + 0.7i 0.7 + 0.7i; 0.7 + 0.7i 0.7-0.7i; 0.7 - 0.7i 0.7-0.7i ; 0.7 - 0.7i 0.7+0.7i]; . That is equivalent into Z = [x_1 0; x_2 0; 0 x_1; 0 x_2; x_1 x_1; x_1 x_2; x_2 x_2; x_2 x_1];. That means it map each value in x into the row of Z according to the index value in y.
Here is my try code:
clear all; clc;
y = [];
G = 2;
v = 1 : G;
for i = 1: G
x=nchoosek(v,i);
m = zeros(size(x,1),G-i);
y =[y ; x m]; % creat the matrix y
end
x = [0.7 + 0.7i; 0.7-0.7i];
Z = []; s = zeros(G,1);
for k=1:size(x,1)
for i=1:size(y,1)
n=y(i,:);
n=n(n ~= 0);
s(n)=x(k);
Z=[Z s];
s = zeros(G,1);
end
end
The problem in my code that matrix Z show the inverse, it means it takes the input x_1 from x and then map it into all possible values in y. For example the matrix Z starts with [x_1 0; 0 x_1; x_1 x_1 ….], however that should be the inverse, which means takes each values in x and map it as shown in the above example [x_1 0; x_2 0; x_3 0 …..]. The second issue, when y contains more than non-zeros values, my code cannot get all possible vectors, it can only get [x_1 x_1; x_2 x_2]; but I cannot map the other possibilities which are [x_1 x_2; x_2 x_1] and so on.
How can I solve that issue?
UPDATE
Here is the updated question with clear description. I have the vector x and matrix y, I need to fill the matrix z following the index taken from each row in matrix y. For example, if the first row in matrix y is [1 0] or [0 1]; then I will take all possible values from x and put it in z following the number taken from the row in y which is 1 in this case. Then, the same case for row 2 in matrix y which is [2 0] or [0 2]; it means that second column in z will be filled with all possible values in x.
Then, the two columns in z can be filled which is equivalent into the case [1 2] in y, so it will take the first value from x and fill it with all other possible values from x, and so on. The rows in z should not be repeated.
The matrix Z is exactly as shown with below answer of AboAmmar below, but using the loop if with longer vector x and bigger matrix y will be little bit complicated.
As you describe it, there are 4 distinct cases for each row of y and the corresponding output:
[0 1] or [1 0] => [x 0]
[0 2] or [2 0] => [0 x]
[1 2] => [x1 x1; x1 x2; x2 x2; x2 x1]
[2 1] => [x1 x1; x2 x1; x2 x2; x1 x2]
These don't seem to follow any obvious rule. So, the easiest (but not smartest) solution is to use if-else and select the suitable case from the above. We don't have all the information about the possible indices, or if rows like [1 1] and [2 2] might happen, so the following solution is by no means exhaustive; surprising errors might happen if other inputs are fed into y matrix.
y = [];
G = 2;
v = 1 : G;
for i = 1: G
x = nchoosek(v,i);
m = zeros(size(x,1),G-i);
y = [y ; x m]; % creat the matrix y
end
Z = [];
x = [0.7 + 0.7i; 0.7-0.7i]
for i = 1:size(y,1)
r = y(i,:);
if ismember(r, [1 0; 0 1], 'rows')
Z(end+1:end+2,:) = [x [0; 0]];
elseif ismember(r, [2 0; 0 2], 'rows')
Z(end+1:end+2,:) = [[0; 0] x];
elseif ismember(r, [1 2], 'rows')
Z(end+1:end+4,:) = [x(1) x(1); x(1) x(2); x(2) x(2); x(2) x(1)];
elseif ismember(r, [2 1], 'rows')
Z(end+1:end+4,:) = [x(1) x(1); x(2) x(1); x(2) x(2); x(1) x(2)];
end
end
Z =
0.7000 + 0.7000i 0.0000 + 0.0000i
0.7000 - 0.7000i 0.0000 + 0.0000i
0.0000 + 0.0000i 0.7000 + 0.7000i
0.0000 + 0.0000i 0.7000 - 0.7000i
0.7000 + 0.7000i 0.7000 + 0.7000i
0.7000 + 0.7000i 0.7000 - 0.7000i
0.7000 - 0.7000i 0.7000 - 0.7000i
0.7000 - 0.7000i 0.7000 + 0.7000i
Your code is valid if you have fix length in y, for example if each vector in y has one value and others are zeros, or two non-zeros values ...etc.
So you can do your code for each length separately and then build the matrix Z by combining all other matrices.
I want to use solve() to solve a large system of linear equations. The solve() function needs equations and variables. I use a loop to generate the equations and my variables are contained in a large array. This is a simple code of what I am trying to do:
x = sym('x',[1 3])
eqn = sym('eqn', [1,3])
eqn1 = 2*x1 + x2 + x3 - 2 == 0
eqn2 = 2*x2 -x2 -x1- x3 == 3
eqn3 = 2*x2+ x1 + 3*x3 == -10
Y = solve(eqn, x)
MATLAB does not recognize my variable x1. I have solved the same system using the following code:
syms x1 x2 x3
eqn1 = 2*x1 + x2 + x3 == 2
eqn2 = 2*x2 -x2 -x1 - x3 == 3
eqn3 = 2*x2+ x1 + 3*x3 == -10
X = solve([eqn1, eqn2, eqn3, eqn4], [x1 x2 x3])
structfun(#subs,X)
But this is useless for a very large number of equations. What am I doing wrong?
You don't need symbolic (syms) for that. This is a standard linear system of equations that can be represented as:
Ax = b where A = [2 1 1; -1 1 -1; 1 2 3], x = [x1; x2; x3] and b = [0; 3; -10]
To solve for x, you would first define
A = [2 1 1; -1 1 -1; 1 2 3]
and
b = [0; 3; -10]
and then solve using
x = A\b
PS. There are some odd things in your question, eg. in eq.2 eqn2 = 2*x2 -x2 -x1- x3 == 3 I assume you omitted simplying this to -x1 +x2 -x3 ==3.
PS2. This is pretty standard Matlab, you can find a lot of info under the standard mldivide page in the documentation along with a lot similar questions here on SO.
I have some data which comes from a linear function (y=mx+c) where m=4, c=1 (so: y=4x+1).
When I try to get back the coefficients using regress, I'm getting an R2<1 and a seemingly random m value:
x = [1 2 3 4]
y = [5 9 13 17]
[m,bint,r,rint,stats] = regress(y',x');
%{
>> R = stats(1) % Coefficient of determination
R =
1
>> m % Linear function coefficients
m =
4.333333333333333
%}
Whereas polyfit does this correctly:
P = polyfit(x,y,1);
%{
>> P(1)
ans =
4.000000000000000
>> P(2)
ans =
1.000000000000000
%}
Why is this happening?
The source of your problem is not following the documentation or regress which states that:
b = regress(y,X) returns a vector b of coefficient estimates for a multiple linear regression of the responses in vector y on the predictors in matrix X. The matrix X must include a column of ones.
If we include a column of ones in the 2nd input, we get the desired result:
x = [1 2 3 4].';
y = [5 9 13 17].';
[m,bint,r,rint,stats] = regress(y,[ones(size(x)) x]);
%{
Results:
m =
1.0000
4.0000
bint =
1.0000 1.0000
4.0000 4.0000
r =
1.0e-14 *
0.1776
0.1776
0.1776
0
rint =
1.0e-13 *
0.0178 0.0178
-0.2190 0.2545
-0.2190 0.2545
-0.2141 0.2141
stats =
1.0e+31 *
0.0000 1.6902 0.0000 0.0000
%}
I have a 2 column vector with different lengths y1 and y2. I want to mixed them together in one matrix.
This matrix should have y1 and y2 as a rows, but they have different lengths. Is it possible to add 0 to shorter vector that it has the same length as longer one?
Many ways to do this, here is one:
>> y1 = [1;2;3;4;5];
>> y2 = [7;8;9];
>> z = zeros(2, max(length(y1), length(y2)));
>> z(1, 1:length(y1)) = y1;
>> z(2, 1:length(y2)) = y2
z =
1 2 3 4 5
7 8 9 0 0
vec2mat does that easily:
vec2mat([y1; y2], max(numel(y1), numel(y2)))
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?