Transformation of State Space model - matlab

I have a state space model with 23 states, 5 inputs and 9 outputs. So the matrices A,B,C and D are known.
I am looking for a way to calculate the state space model for a different set of inputs and outputs, by transforming the initial matrices A,B,C and D?
Example: Let's say that the initial system is:
X' = A.X + B.U with U = [u1 ; u2 ; u3 ; u4 ; u5] and X is the state vector.
Y = C.X + D.U with Y = [y1 ; y2 ; y3 ; y4 ; y5 ; y6 ; y7 ; y8 ; y9]
and A, B, C and D are known.
How can I transform this model into a new model with another set of inputs and outputs like:
U_new = [y1 ; y2 ; y3 ; y4 ; y5]
Y_new = [y6 ; y7 ; y8 ; y9]
which are basically two subsets of the original output vector Y.
Is it possible without transforming the State Space Model into Transfer Functions?
I appreciate your help.
Best regards. A1ireza

Related

How to specifically fprintf an array on a file

Lets say for example we have this array:
x =
0.5920 0.4635
0.6451 0.2118
-0.1206 -0.6036
0.2417 0.4773
0.3029 0.5172
What code would I need to write in order to print in such a way that it looks like this:
coords
x1 0.5920 y1 0.4635
x2 0.6451 y2 0.2118
x3 -0.1206 y3 -0.6036
x4 0.2417 y4 0.4773
x5 0.3029 y5 0.5172
I've tried this:
x = gallery('uniformdata',[1,10],0);
y = gallery('uniformdata',[1,10],1);
[v,c] = voronoin([x(:) y(:)]); %returns an array V with vertices and a cell array C with a matrix for each cell of the diagram.
c
for k = 1 : numel(c)
c{k} = c{k}(c{k} ~= 1)
end
fileID = fopen('cords.txt' , 'w');
for i=1:10
coord = v(c{i},:);
fprintf(fileID,'shape %d:\nx \t y\n', i);
fprintf(fileID,'%.4f %.4f\n', coord(:,1), coord(:,2));
end
fclose(fileID);
but im getting an output like this:
shape 10:
x y
0.5920 0.6451 %notice how the .6451 is on the right side when it should be on the bottom
-0.1206 0.2417
0.3029 0.4635
0.2118 -0.6036
0.4773 0.5172
The fprintf function reads the input variables in a column first manner and sends each value to its appropriate place in the string. So, in your code what happens is that even when you specify two different vectors per %.4f in your code, Matlab ignores that ordering. It puts the first value of coord(:, 1) in the first %.4f and the second value of coord(:, 1) in the second %.4f. Then it breaks the line. Then it again picks up the third value from coord(:, 1) and puts it in the first %.4f and so on. It only picks values from coord(:, 2) when all values of the first vector are exhausted.
The simplest fix is to transpose the coord matrix and then input it to Matlab like this:
fprintf(fileID,'%.4f %.4f\n', coord.'); % .' tranposes the matrix
Edit:
To get the format as x1 0.5920 y1 0.4635, we can make use of the column first ordering that Matlab follows to access a variable
% First we make a new matrix that has each of the required elements for the desired format
% The index of x, the value of x, the index of y and the value of y
tempCoord = [1:size(coord, 1); coord(:, 1).'; 1:size(coord, 1); coord(:, 2).'];
% Now we change the string specification for fprintf
fprintf(fileID,'x%d %.4f y%d %.4f\n', tempCoord);
Why does this work?
If you look at tempCoord, you will see that each of its columns has the format needed for the string specifier, i.e., the index of x, the value of x, the index of y and the value of y
tempCoord =
1.000000000000000 2.000000000000000 3.000000000000000 4.000000000000000 5.000000000000000
0.592000000000000 0.645100000000000 -0.120600000000000 0.241700000000000 0.302900000000000
1.000000000000000 2.000000000000000 3.000000000000000 4.000000000000000 5.000000000000000
0.463500000000000 0.211800000000000 -0.603600000000000 0.477300000000000 0.517200000000000
Now each column becomes each row of the printed file and you get the following output:
x1 0.5920 y1 0.4635
x2 0.6451 y2 0.2118
x3 -0.1206 y3 -0.6036
x4 0.2417 y4 0.4773
x5 0.3029 y5 0.5172

Matlab get symbols from matrix to assign value

I am creating a matrix of symbols and I declare a function using them:
x = syms('x', [1 2]);
f = x(1) + x(2)
So x and f are:
x = [x1 x2];
f = x1 + x2
Now I want to give values to x1 and x2 in a for loop and evaluate f. But when I use:
x(1) = value;
then x becomes:
x = [1 x2]
and x1 is lost, so I cannot evaluate f. How can I assign a value to x1, x2, ..., xn and then evaluate f?
You should use subs like the following:
subs(f,x1,value)
instead of replacing symbol of x1 with a value.
You can see the details of the function here.

Get row of functions from a matrix of functions

Before overwhelming you with examples where I try to encapsulate every aspect of my issue I'll try to just state the problem as simply as possible:
If f11 , ... , fnm is n*m real valued funtions that I wish to evaluate m at a time in n steps, through some higher order function b i.e.
v = []
f1 = #(x) [f11(x) f12(x) ... f1m(x)]
v = [v b(f1)]
f2 = #(x) [f21(x) f22(x) ... f2m(x)]
v = [v b(f2)]
How would I solve this through iteration? i.e. something like this:
f = #(x) [f11(x) ... f1m(x) ; ... ; fn1(x) ... fnm(x)];
% now iterate over the rows of f
for i=1:n
v = [v b(f(i,:)) ]
end
Here's an example of what I have (it grew in order to not miss out any details of my actual real-world problem but I have tried to make it as small as possible):
% 4 functions that take a 1x2 real valued vector as argument
% and return a real value
f11 = #(x) x(1) + x(2);
f12 = #(x) x(1) - x(2);
f21 = #(x) x(2) - x(1);
f22 = #(x) x(1) * x(2);
% we'll run function b for 2 steps, then 4 steps
steps = [2 4];
% start value
x = [1 2];
% vector to hold results
v = []
% get the result of passing the 1:st 2 functions to b with steps(1)
f1 = #(x) [f11(x) f12(x)];
v = [v ;b(x, f1, steps(1))]
% update x
x = v(end,:)
% add the result of passing the 2:nd 2 functions to b with steps(2)
f2 = #(x) [f21(x) f22(x)];
v = [v ;b(x, f2, steps(2))];
% update x
x = v(end,:)
Where b is a function defined as follows:
function [ X ] = b( x, f, n )
% #param:
% x = an 1x2 real valued vector
% f = a real valued function returning
% a 1x2 real valued vector
% n = an integer defining the rows of return matrix
%
% #return:
% X = an nx2 real valued matrix defined as below
X = zeros(n,2);
for i=1:n
% apply the functions on x
a = f(x+1);
b = f(x+2);
% update x
x = a+b
% add x to return matrix
X(i,:) = x;
end
end
The above code could be generalized as:
% n*m functions that take a 1xm real valued vector as argument
% and return a real value
f11 = #(x) ... ;
f12 = #(x) ... ;
.
.
.
fnm = #(x) ... ;
% we'll run function b for a1 steps, then a2 steps, ... , then an steps
steps = [a1 a2 ... an];
% start value
x = [1 2 ... m];
% vector to hold results
v = []
% get the result of passing the 1:st m functions to b with steps(1)
f1 = #(x) [f11(x) ... f1m(x)];
v = [v ;b(x, f1, steps(1))]
% update x
x = v(end,:)
% add the result of passing the 2:nd m functions to b with steps(2)
f2 = #(x) [f21(x) ... f2m(x)];
v = [v ;b(x, f2, steps(2))];
% update x
x = v(end,:)
.
.
.
% add the result of passing the n:ed m functions to b with steps(n)
fn = #(x) [fn1(x) ... fnm(x)];
v = [v ;b(x, fn, steps(n))];
% update x
x = v(end,:)
Where b is any function that returns an steps(i) x m matrix.
I wonder if both the small concrete example and the general example should be solvable through a general iteration, something like this:
% let f hold all the functions as a matrix
f = #(x) [f11(x) ... f1m(x) ; ... ; fn1(x) ... fnm(x)];
% now iterate over the rows of f
for i=1:n
v = [v ; b(x, f(i,:), steps(i)) ]
end
So the trick is in defining your functions as a cell matrix and then using some vectorization to solve the problem. This is the code that I came up with:
%First define your functions in a cell matrix
fn_mat = {#(x) x(1) + x(2), #(x) x(1) - x(2); ...
#(x) x(2) - x(1), #(x) x(1) * x(2)};
%Store the sixe of this matrix in two variables
[n, m] = size(fn_mat);
%Number of steps
steps = [2, 4];
% start value
x = [1 2];
% vector to hold results
v = [];
%This will run the required code for n iterations
for ii = 1:n
%This is the tricky part. What I have done is used arrayfun to run over
%all the functions in the row defined by ii and pass x as an argument
%each time. The rest is same as before
fn = #(x) arrayfun(#(a, b) fn_mat{ii, a}(b{:}), 1:m, repmat({x}, 1, m));
v = [v; b(x, fn, steps(ii))];
x = v(ii, :);
end
For the current values, the output is:
v =
12 -2
26 28
-28 -13
30 610
1160 38525
74730 89497060
The for loop is general enough to accommodate any size of fn_mat.

Matlab: Test the system is linear or not

I have an equation: y(n) = a^x(n).
where x1(n) ={0,1,2,3}, x2(n)={1,2,3,4}, a1=a2=1, a=2.
So, How can i write MATLAB code to test the system is linear or not?
Just apply the definition.
Consider a system S, such that the output to an input signal x(n) is S( x(n) ). S is linear if and only if
S( x1(n) + x2(n) ) = S( x1(n) ) + S( x2(n) ) for any inputs x1, x2 (additivity)
S( b * x1(n) ) = b * S( x1(n) ) for any input x1 and any number b (homogeneity)
In your case it's clear that neither 1 nor 2 hold, so the system y(n) = S( x(n) ) is not linear.
To test it with code: randomly generate many examples of x1, x2 and b and check if the equalities above hold. Note that this way you will never be sure that the system is linear. You can only be sure it isn't, namely when you find x1, x2, b for which either 1 or 2 do not hold.
Example
>> a = 2; n = 3;
>> S = #(x) a*x.^n; %// anonymous function describing your system
>> x1 = 1:4; %// test input signal
>> x2 = 11:14; %// test input signal. Same length
>> S(x1)+S(x2)
ans =
2664 3472 4448 5616
>> S(x1+x2)
ans =
3456 5488 8192 11664
Since the results are different, the system does not satisfy property 1, and therefore it's not linear.

Plotting a function of x over a range of D

I am trying to plot this function in MATLAB:
f(x) = (1./(2*b))*((erf(1./(2*D)+((x/b)-2*n)/D)+ erf(1./(2*D)-((x/b)-2*n)/D)));
The function is to plotted as a sum of n values from 0 to N, where N is a real number and b is a constant; for a range of D values. I am supposed to have different plots for each value in range D representing the function. How can I go about this please?
The different ranges of D can be done like this:
f = #(x, D)(x + D);
x = -10:10; %// pick a good range
D = 1:5; %// pick a good range
figure()
hold all
for d = D
plot(x, f(x, d))
end
I'm not 100% sure what you mean about the summing 0:N bit but maybe it's something of this form:
figure()
hold all
x= -10:10;
for d = 1:5
y = zeros(size(x)); %// Preallocation of memory for speed
for n = 0:10
y = y + n*x + d
end
plot(x, y)
end