How to use do matrix operations without using symbols

2 views (last 30 days)
I am trying to design a matlab function that uses matrices to take the input/output data of a set of measurements the desired order of transfer function desired (for example: 3rd order) and then graph the original data on the same plot as each order leading up to the one selected. (in my example, plotting the 1st,2nd, and 3rd order on the same figure. I have the graphing completely figured out. In pursuit of this function I made a script that does all of these things manually, which is very inefficient and covers the screen in code that must be expanded upon for each increase in order of equation. This is for a least squares style calculation and comparison of transfer functions. attached is my script.
How could I make a function that would take two sets of numbers (input and output) of ANY (equal to eachother of course) length and perform the same matrix operations?
syms f1 f2 f3 f4 f5 f6 f7 f8 f9 f0 a b c y1 y2 y3 y4 y5 y6 y7 y8 y9 y0
f1=38.68;f2=7.84; f3=5.14; f4=3.92; f5=3.14; f6=2.62; f7=2.22; f8=1.98;f9=1.74;f0=1.55;
y1=0.04;y2=0.2;y3=0.3;y4=0.4;y5=0.5;y6=0.6;y7=0.7;y8=0.8;y9=0.9;y0=1;
%first order
A1 =[1 f1;1 f2;1 f3;1 f4;1 f5;1 f6;1 f7;1 f8;1 f9;1 f0];
At1 =[1 1 1 1 1 1 1 1 1 1;f1 f2 f3 f4 f5 f6 f7 f8 f9 f0];
B =[y1;y2;y3;y4;y5;y6;y7;y8;y9;y0];
AtA1=At1*A1;
AtAinverse1=inv(At1*A1);
AtB1=At1*B;
X1 = inv(At1*A1) * (At1*B);
%second order
A2 =[1 f1 f1.^2;1 f2 f2.^2;1 f3 f3.^2;1 f4 f4.^2;1 f5 f5.^2;1 f6 f6.^2;1 f7 f7.^2;1 f8 f8.^2;1 f9 f9.^2;1 f0 f0.^2];
At2 =[1 1 1 1 1 1 1 1 1 1;f1 f2 f3 f4 f5 f6 f7 f8 f9 f0;f1.^2 f2.^2 f3.^2 f4.^2 f5.^2 f6.^2 f7.^2 f8.^2 f9.^2 f0.^2];
AtA2=At2*A2;
AtAinverse2= inv(At2*A2) ;
AtB2=At2*B;
X2 = inv(At2*A2) * (At2*B);
%third order
A3 =[1 f1 f1.^2 f1.^3;1 f2 f2.^2 f2.^3;1 f3 f3.^2 f3.^3;1 f4 f4.^2 f4.^3;1 f5 f5.^2 f5.^3;1 f6 f6.^2 f6.^3;1 f7 f7.^2 f7.^3;1 f8 f8.^2 f8.^3;1 f9 f9.^2 f9.^3;1 f0 f0.^2 f0.^3];
At3 =[1 1 1 1 1 1 1 1 1 1;f1 f2 f3 f4 f5 f6 f7 f8 f9 f0;f1.^2 f2.^2 f3.^2 f4.^2 f5.^2 f6.^2 f7.^2 f8.^2 f9.^2 f0.^2;f1.^3 f2.^3 f3.^3 f4.^3 f5.^3 f6.^3 f7.^3 f8.^3 f9.^3 f0.^3];
AtA3=At3*A3;
AtAinverse3= inv(At3*A3);
AtB3=At3*B;
X3 = inv(At3*A3) * (At3*B);
As you can see each time I want to raise the order I need to add another summation to the matrices in the operations I use. can this be done with a set of numbers instead of using syms?

Accepted Answer

Stephen23
Stephen23 on 14 Sep 2020
Edited: Stephen23 on 14 Sep 2020
Your approach makes this task complex and inefficient. In particular:
  • Numbering variables like that is a sign that you are doing something wrong. Instead you should use arrays/matrices/vectors, just like MATLAB was designed for. Using arrays/matrices/vectors will make your code more generalized and easier to expand.
  • Do not use inv (its documentation explains why). The recommended efficient and (more) numerically stable way to solve for systems of equations is to use mldivide or mrdivide.
  • Avoid creating lots of unused variables.
The more efficient MATLAB approach would be something like this:
>> F = [38.68,7.84,5.14,3.92,3.14,2.62,2.22,1.98,1.74,1.55];
>> Y = [0.04,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1];
>> N = 2;
>> A = bsxfun(@power,F(:),0:N);
>> At = A.';
>> X = (At*A) \ (At*Y(:))
X =
1.0655202
-0.1536969
0.0032898

More Answers (0)

Tags

Products


Release

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!