MATLAB Answers

0

Multiplication of specific column vector elements

Asked by John Slugg on 4 Dec 2019 at 23:19
Latest activity Commented on by John Slugg on 5 Dec 2019 at 1:08
I am trying to multiply specific elements of column vectors togerther, however matlab returns the error:
" Undefined operator '*' for input arguments of type 'cell'. "
The section of code I am having issues with is as follows:
% Non-linear torque equations
Tx=hd(1:1)+hwxd+(obo(2:1)*h(3:1)-obo(3:1)*h(2:1))+(obo(2:1)*hwz-obo(3:1))*hwy
Ty=hd(2:1)+hwyd+(obo(3:1)*h(1:1)-obo(1:1)*h(3:1))+(obo(3:1)*hwx-obo(1:1))*hwz
Tz=hd(3:1)+hwzd+(obo(1:1)*h(2:1)-obo(2:1)*h(1:1))+(obo(1:1)*hwy-obo(2:1))*hwx
where hwx, hwy, hwx, hwxd, hwyd, hwzd are scalar variables and h, hd, obo are 3x1 column vectors.
The full code is as follows:
clear;
clc;
% NAME KEY;
% obo = angluar velocity of body frame W.R.T. inertial frame
% o0 = angular velocity of the satellite in orbit
% h = system angular momentum
% hwx,hwy,hwz = momentum exchange device angular momentum components
% I = moment of inertia tensor
% Tx = Torque about satellite CM W.R.T. inertial frame X axis
% Ty = Torque about satellite CM W.R.T. inertial frame Y axis
% Tz = Torque about satellite CM W.R.T. inertial frame Z axis
% Variables
syms theta(t) phi(t) psi(t) Ixx Ixy Ixz Iyy Iyz Izz hwx hwy hwz mu R;
% Definitions
o0=sqrt(mu/(R^3));
thetad=diff(theta); phid=diff(phi); psid=diff(psi);
thetadd=diff(theta,2); phidd=diff(phi,2); psidd=diff(psi,2);
hwxd=diff(hwx);
hwyd=diff(hwy);
hwzd=diff(hwz);
% Angular Velocity of Body Frame W.R.T. Inertial frame
obo=[phid-psid*sin(theta)-(cos(theta)*sin(phi))*o0;thetad*cos(phi)+psid*cos(theta)*sin(phi)-(cos(phi)*cos(psi)+sin(phi)*sin(theta)*sin(psi))*o0;psid*cos(theta)*cos(phi)-thetad*sin(phi)-(-sin(phi)*cos(psi)+cos(phi)*sin(theta)*sin(psi))*o0];
% Moment of Inertia Tensor
I=[Ixx -Ixy -Ixz;-Ixy Iyy -Iyz;-Ixz -Iyz Izz];
% Angular momentum
h=I*obo;
% Derivative of angular momentum
hd=diff(h);
% Non-linear torque equations
Tx=hd(1:1)+hwxd+(obo(2:1)*h(3:1)-obo(3:1)*h(2:1))+(obo(2:1)*hwz-obo(3:1))*hwy
Ty=hd(2:1)+hwyd+(obo(3:1)*h(1:1)-obo(1:1)*h(3:1))+(obo(3:1)*hwx-obo(1:1))*hwz
Tz=hd(3:1)+hwzd+(obo(1:1)*h(2:1)-obo(2:1)*h(1:1))+(obo(1:1)*hwy-obo(2:1))*hwx
% input given constant values
Ixx=6; Iyy=8; Izz=4; p=(2*(pi))/o0; mu=(3.986*(10^14)); R=500;

  3 Comments

obo(3:1) is empty. 3:1 is empty. 3:-1:1 would be [3, 2, 1]
Walter,
is the syntax for element extration not " Matrix(row : column) "?
I suppose I am confused as to why there are three entries in your extration term (3:-1:1). I am also a bit confused as to what your [3, 2, 1] vector represents? would that not just be the transpose of obo in reverse order?
Thanks,
John
is the syntax for element extration not " Matrix(row : column) "?
No, it is Matrix(row, column) . The : operator is used for creating lists

Sign in to comment.

1 Answer

Answer by Walter Roberson
on 5 Dec 2019 at 0:27
Edited by Walter Roberson
on 5 Dec 2019 at 0:32

You have symbolic functions with array valued outputs -- obo is a symbolic function with a 3 x 1 body for example.
In MATLAB, when you invoke a symbolic function with a vector or array argument, then instead of forming an array output that is size(function body) by size(input) , MATLAB creates a cell array output that is size(function body) in size and each element contains the evaluation of the corresponding body member on each input. Thus for example when you invoke obo() on the 1 x 2 array 2:-1:1, then you would get back a 3 x 1 cell array with each element being a 1 x 2 array.
Unfortunately, at least up to R2019b, cell2mat() cannot work directly on the result. However you can assign the result to a variable and then use vertcat() or horzcat() or cat() as appropriate, such as
t = obo(2:-1:1);
tm = vertcat(t{:});
which would get you a 3 x 2 array of sym.
obo(2:1)*h(3:1)
I think you need to look more carefully at the sizes you expect from each of the operations.
I almost wonder if when you write obo(2:1) if you are intending something more like obo(2,1) and that you intend by that to get the second element of what you defined through
obo=[phid-psid*sin(theta)-(cos(theta)*sin(phi))*o0;thetad*cos(phi)+psid*cos(theta)*sin(phi)-(cos(phi)*cos(psi)+sin(phi)*sin(theta)*sin(psi))*o0;psid*cos(theta)*cos(phi)-thetad*sin(phi)-(-sin(phi)*cos(psi)+cos(phi)*sin(theta)*sin(psi))*o0];
If so then you did not happen to notice the fact that when you take thetad=diff(theta) where theta is a function, then what you get back is not an expression but rather a function -- thetad will be a function , so obo ends up being a function rather than an expression. And using a function with an argument invokes the function rather than doing indexing.
The only supported way to index a function with non-scalar output is to invoke the function and index into the result. Like
obo_vec = obo(t);
obo_vec(3)

  1 Comment

I was in fact going for something like obo(2,1). I have yet to get back on the computer to plug it in, however I believe the last part of your explanation is exactly what I need. Thank you!

Sign in to comment.