I have a vector of symbolic function of the following form defined in MATLAB R2021a:
O_BF(t) =
[JTP*(diff(theta(t), t)*(w1 + w3 - w4 - w2*(cos(beta)*cos(gamma) +
sin(alpha)*sin(beta)*sin(gamma))) - w2*(cos(gamma)*sin(beta) -
cos(beta)*sin(alpha)*sin(gamma))*diff(say(t), t)), -JTP*(diff(phi(t), t)*(w1 + w3 - w4 - w2*
(cos(beta)*cos(gamma) + sin(alpha)*sin(beta)*sin(gamma))) +
w2*cos(alpha)*sin(gamma)*diff(say(t), t)), JTP*(w2*(cos(gamma)*sin(beta) -
cos(beta)*sin(alpha)*sin(gamma))*diff(phi(t), t) + w2*cos(alpha)*sin(gamma)*diff(theta(t),
t))]
And I want the following results, which obviously is the extracted parts of the above vector:
[JTP*(diff(theta(t), t)*(w1 + w3 - w4 - w2*(cos(beta)*cos(gamma) +
sin(alpha)*sin(beta)*sin(gamma))) - w2*(cos(gamma)*sin(beta) -
cos(beta)*sin(alpha)*sin(gamma))*diff(say(t), t))
-JTP*(diff(phi(t), t)*(w1 + w3 - w4 - w2*
(cos(beta)*cos(gamma) + sin(alpha)*sin(beta)*sin(gamma))) +
w2*cos(alpha)*sin(gamma)*diff(say(t), t))
JTP*(w2*(cos(gamma)*sin(beta) -
cos(beta)*sin(alpha)*sin(gamma))*diff(phi(t), t) +
w2*cos(alpha)*sin(gamma)*diff(theta(t),
t))]
As You can see, this is clearly a vector, but I cannot extract the arrays because MATLAB considers this vector as a function of time. How can I do that?
O_BF(t) in your question is a symbolic function with respect to t that returns a matrix.
This a common issue when working with symbolic functions and Matlab symfun objects. Here's a simpler example that I think reproduces the behavior observed in the question:
syms t a; %define symbolic variables
f(t) = [t a*t 2*t^2]; %define symfun array as function of t
Calling f(1) evaluates the symfun for t = 1 rather than extracting the first element of the 1-by-3 array:
>> f(1)
ans =
[1, a, 2]
To access the elements of the underlying array one must assign the contents to an intermediate symbolic variable:
g = f(t); %or even f=f(t) to redefine f as sym rather than symfun
g(1)
>> g(1)
ans =
t
This is equivalent to using the formula function:
g = formula(f);
g(1)
>> g(1)
ans =
t
I know of no current way to directly access the elements of an array defined as a symfun without going through the above steps.
Related
I have a pulse shape that is a function of t, call it h(t), that is in the form of:
h = #(t) function of t
I want to create a pulse train that is consisted of N pulses h(t).
I did this by:
for n=0:N-1
comb = comb + h(t - n);
end
However, once I do that I can't change t in the train.
How can I create this train so that it will also be a function of t?
Thanks.
You just need to make comb an anonymous function too. You can initialise it to some trivial function (i.e. it always outputs 0), and then repeatedly modify it. Since variables declared before an anonymous function declaration, including anonymous functions, are kind of "frozen" to the definition at that point this will work.
h = #(t) _______ % some function of 't'
comb = #(t) 0;
for n = 0:N-1
comb = #(t) comb(t) + h(t - n);
end
We can test this with h = #(t) sin(t) and N=3:
>> comb(pi/2)
ans = 1.1242
>> h(pi/2) + h(pi/2-1) + h(pi/2-2)
ans = 1.1242
Note that just displaying comb can be a bit misleading, since information about the recursive definition is somewhat lost
disp(comb)
#(t)comb(t)+h(t-n)
I have a problem in using fmincon in Matlab when the variables are using various indices instead of fixed indices. In brief, I have Matlab code as below example:
x = fmincon(objfun,x0,A,b,Aeq,beq,lb,ub)
function f = objfun(x)
f = a(1,1)*((1 - x(1))*(b(1) + c(1)) + a(2,1)*((1 - x(2))*(b(2) + c(1))
+ a(1,2)*((1 - x(1))*(b(1) + c(2)) + a(2,2)*((1 - x(2))*(b(2) + c(2))
end
In this case, I want to make a general equation for f as follows:
f = a(i,j)*((1 - x(i))*(b(i) + c(j))
What do I need to add to f function to realize the same result as the first f formula?
This question is connected to this one. Suppose again the following code:
syms x
f = 1/(x^2+4*x+9)
Now taylor allows the function f to be expanded about infinity:
ts = taylor(f,x,inf,'Order',100)
But the following code
c = coeffs(ts)
produces errors, because the series does not contain positive powers of x (it contains negative powers of x).
In such a case, what code should be used?
Since the Taylor Expansion around infinity was likely performed with the substitution y = 1/x and expanded around 0, I would explicitly make that substitution to make the power positive for use on coeffs:
syms x y
f = 1/(x^2+4x+9);
ts = taylor(f,x,inf,'Order',100);
[c,ty] = coeffs(subs(ts,x,1/y),y);
tx = subs(ty,y,1/x);
The output from taylor is not a multivariate polynomial, so coeffs won't work in this case. One thing you can try is using collect (you may get the same or similar result from using simplify):
syms x
f = 1/(x^2 + 4*x + 9);
ts = series(f,x,Inf,'Order',5) % 4-th order Puiseux series of f about 0
c = collect(ts)
which returns
ts =
1/x^2 - 4/x^3 + 7/x^4 + 8/x^5 - 95/x^6
c =
(x^4 - 4*x^3 + 7*x^2 + 8*x - 95)/x^6
Then you can use numden to extract the numerator and denominator from either c or ts:
[n,d] = numden(ts)
which returns the following polynomials:
n =
x^4 - 4*x^3 + 7*x^2 + 8*x - 95
d =
x^6
coeffs can then be used on the numerator. You may find other functions listed here helpful as well.
I am using polyfit to get the following 4-degree polynomial:
0.5152 -1.0687 0.0269 1.1781 -0.4943
I need this polynomial explicitly, i.e., I need to have the variables in it, too. That is I need it as a symbolic expression, e.g.,
f(q) = 0.5152 q^4 -1.0687 q^3 0.0269 q^2 1.1781 q -0.4943
because my function f(q) is the input of another function g(q). Example: I am having function g as:
g(q) = q^2
and I need f(q) WITH variable q in it so that I can evaluate g at f symbolically. That is, the result should be a SYMBOLIC function g:
g(f(q)) = ( 0.5152 q^4 -1.0687 q^3 0.0269 q^2 1.1781 q -0.4943 )^2
Any ideas how I can represent f(q) from polyfit such that I can use it as symbolic input in g?
Use poly2sym to transform the vector of coefficients into a symbolic polynomial:
>> poly2sym([1 2 3],'x')
ans =
x^2 + 2*x + 3
I have to solve a system of ordinary differential equations of the form:
dx/ds = 1/x * [y* (g + s/y) - a*x*f(x^2,y^2)]
dy/ds = 1/x * [-y * (b + y) * f()] - y/s - c
where x, and y are the variables I need to find out, and s is the independent variable; the rest are constants. I've tried to solve this with ode45 with no success so far:
y = ode45(#yprime, s, [1 1]);
function dyds = yprime(s,y)
global g a v0 d
dyds_1 = 1./y(1) .*(y(2) .* (g + s ./ y(2)) - a .* y(1) .* sqrt(y(1).^2 + (v0 + y(2)).^2));
dyds_2 = - (y(2) .* (v0 + y(2)) .* sqrt(y(1).^2 + (v0 + y(2)).^2))./y(1) - y(2)./s - d;
dyds = [dyds_1; dyds_2];
return
where #yprime has the system of equations. I get the following error message:
YPRIME returns a vector of length 0, but the length of initial
conditions vector is 2. The vector returned by YPRIME and the initial
conditions vector must have the same number of elements.
Any ideas?
thanks
Certainly, you should have a look at your function yprime. Using some simple model that shares the number of differential state variables with your problem, have a look at this example.
function dyds = yprime(s, y)
dyds = zeros(2, 1);
dyds(1) = y(1) + y(2);
dyds(2) = 0.5 * y(1);
end
yprime must return a column vector that holds the values of the two right hand sides. The input argument s can be ignored because your model is time-independent. The example you show is somewhat difficult in that it is not of the form dy/dt = f(t, y). You will have to rearrange your equations as a first step. It will help to rename x into y(1) and y into y(2).
Also, are you sure that your global g a v0 d are not empty? If any one of those variables remains uninitialized, you will be multiplying state variables with an empty matrix, eventually resulting in an empty vector dyds being returned. This can be tested with
assert(~isempty(v0), 'v0 not initialized');
in yprime, or you could employ a debugging breakpoint.
the syntax for ODE solvers is [s y]=ode45(#yprime, [1 10], [2 2])
and you dont need to do elementwise operation in your case i.e. instead of .* just use *