Symbolic Solutions That Populate a Vector

5 vues (au cours des 30 derniers jours)
Justin
Justin le 11 Mar 2020
Commenté : Walter Roberson le 11 Mar 2020
I am trying to approximate a solution to the Riccati equation. To do this, I have a final value and work backwards to obtain all previous values. The issue is that in this particular case the solution needs to be symbolic bexause it depends on a function of time that will be calculated later. The code I came up with is listed below. This works very well when there is no symbolic variable to deal with.
% P(tf)
P_11(length(t)) = F(1,1);
P_12(length(t)) = F(1,2);
P_22(length(t)) = F(2,2);
% Solve Riccati eqn backwards
syms z;
for n=length(t) : -1 : 2
P_11_dot = P_12(n)^2 + 3*z*P_12(n) + 3*P_12(n)*z - 1;
P_12_dot = 2*P_12(n) - P_11(n) + P_12(n)*P_22(n) + 3*P_22(n)*z;
P_22_dot = 4*P_22(n) - 2*P_12(n) + P_22(n)^2;
P_11(n-1) = P_11(n) - P_11_dot*step;
P_12(n-1) = P_12(n) - P_12_dot*step;
P_22(n-1) = P_22(n) - P_22_dot*step;
end
the error message i get is this;
The following error occurred converting from sym to double:
Unable to convert expression into double array.
Error in LTV_SYS (line 56)
P_11(n-1) = P_11(n) - P_11_dot*step;
The idea is to then calculate z using the code below. Here, I know the initial conditions and since my symbolic variable (z) is a state, I should be able to substitute in for it. The problem is I can't get to this point because of the above error.
% Initialize state vector
x(:,1) = x0;
% Solve for optimal state and control
for n=1 : length(t)-1
z = x(1,n);
A = [0 1; -3*z -2];
P = [P_11(n) P_12(n); P_12(n) P_22(n)];
K(n,:) = inv(R)*B'*P;
U(n+1) = -K(n,:)*x(:,n);
x_dot = A*x(:,n)+B*U(n+1);
x(:,n+1) = x(:,n) + x_dot*step;
end
I appreciate any help that anyone can offer.

Réponses (1)

Walter Roberson
Walter Roberson le 11 Mar 2020
P_11(length(t)) = sym(F(1,1));
P_12(length(t)) = sym(F(1,2));
P_22(length(t)) = sym(F(2,2));
  7 commentaires
Justin
Justin le 11 Mar 2020
I tried using vpa in the P loop as shown below. It is now approximating the rational coefficients as decimals. This seems like a good start but I think it is still providing too much precision which is slowing down computation. Is there a way to round the results to, say 5, decimal places?
for n=length(t) : -1 : 2
P_11_dot = vpa(P_12(n)^2 + 3*z*P_12(n) + 3*P_12(n)*z - 1);
P_12_dot = vpa(2*P_12(n) - P_11(n) + P_12(n)*P_22(n) + 3*P_22(n)*z);
P_22_dot = vpa(4*P_22(n) - 2*P_12(n) + P_22(n)^2);
P_11(n-1) = vpa(P_11(n) - P_11_dot*step);
P_12(n-1) = vpa(P_12(n) - P_12_dot*step);
P_22(n-1) = vpa(P_22(n) - P_22_dot*step);
end
Walter Roberson
Walter Roberson le 11 Mar 2020
"You can use digits() to control the precision you want to execute to."

Connectez-vous pour commenter.

Tags

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by