How to extract a matrix of symbolic functions in Matlab - matlab

syms c A(t) v(t)
A(t) =
0
c*sin(tt(t))
c*cos(tt(t))
How I can get X = A(2) = c*sin(tt(t)); (the function at second row)? If I type A(2), the result will be as below (it substitutes a constant for the function, which is not my desire):
>> A(2)
ans =
0
c*sin(tt(2))
c*cos(tt(2))

The problem is that you've defined A as a symbolic function (symfun), not as an array of symbolic expressions. Instead:
syms c A tt(t)
A = [0;
c*sin(tt(t));
c*sin(tt(t))];
Now A(2) will return c*sin(tt(t)).
Alternatively, if you can't change the definition of A(t), you'll need to assign it to an intermediate variable to convert it to an array of symbolic expressions:
syms c A(t) tt(t)
A(t) = [0;
c*sin(tt(t));
c*cos(tt(t))];
B = A(t);
Then, B(2) will return c*sin(tt(t)). You can also use formula to extract the underlying expressions:
B = formula(A):

In matlab you must to use "subs(f)" function to evaluate functions.
First create the function:
syms g(x)
g(x) = x^3;
After that asign the X value:
x=2;
then if you evaluate g using the subs function, the result is the expected value 8, but it is assigned to a symbolic function, gnew. This new symbolic function formally depends on the variable x.
gnew = subs(g)
The function call, g(x), returns the value of g for the current value of x. For example, if you assigned the value 2 to the variable x, then calling g(x) is equivalent to calling g(2)
g2 = g(x)
g2 =
4
g2 = g(2)
g2 =
4

Related

How to describe the derivative of matlab symbolic variable?

For example, I named the variables x(t), xdot(t) about time: syms t x(t) xdot(t);, and the derivative of x about time is xdot, xdot=diff(x,t).
But when I calculate diff (x, t), the result is not xdot. How can I set the display of diff (x, t) in the calculation result to xdot?
In addition, the time variable in the calculation result is displayed in the form of variable(t). How to set the result to display only variable?
syms t x(t) xdot(t);
xdot=diff(x,t);
y=diff(x,t);
y
the result of y is displayed as , however, I want it to be xdot
Consider the following code:
a = 3;
b = 3;
b
It appears to me, you would like this to display b = a, instead of b = 3. This is not how MATLAB works. Both a and b are equal to 3, but that doesn't mean a is b.
The same is true for the code:
a = 3;
b = a;
b
This gives b = 3, not b = a. I won't go into details about why this is the case (and why it has to be the case in MATLAB). It's enough to know that this is how it works.
You have assigned diff(x,t) to two different variables, xdot and y. This means that, while xdot and y have the same value, xdot is not y.
If you do xdot = 3 after your code, then y would still be dx/dt.
Side note: Why do you want this behaviour? Are you sure it's necessary? You can always print the result however you like:
fprintf('xdot = %s', y(t))
xdot = diff(x(t), t)
Ugly workaround to do something I don't understand why you would do:
Create a function:
function res = xdot(t)
syms x(t) res;
res = diff(x,t);
end
And then define y as a function handle:
y = #xdot
y = function_handle with value:
#xdot
Now y(t) will still give dx/dt, but y will give xdot
I strongly recommend you don't do this.

Adding function handlers in cell array in MATLAB

I have a bunch of anonymous functions stored in a cell array as follows:
F = {#(x) x + 1, #(x) x * x}
I want to create a new anonymous function to add them all up and average the result given an input x. F can have arbitrary number of function handles and is generated at run time. If F is known, then it is simply f = #(x) (F{1}(x) + F{2}(x)) / length(F). But I don't know how to append all elements of F onto this new anonymous function (presumably in a loop?) How would I do this?
Use cellfun to define a function that evaluates each function f in F using just one line. An anonymous function handle for arbitrary F and x is as follows:
F = {#(x) x + 1, #(x) x * x};
%// Build anonymous function that evaluates each function, sums,
%// divides by length of F
new_F = #(x,F)sum(cellfun(#(f)f(x), F)) / length(F);
Then, to evaluate, simply call:
x = 2; %// data to apply fcns on
result = new_F(x, F)

feval with multivariate function and vectorization

I need feval called with a bivariate function f and two vectors v1 and v2 (let us say that v1 are the x's and v2 the y's) to return a vector z=[f(v1(1),v2(1)) ... f(v1(n),v2(n)].
How can I do that ?
The following example does not work:
function z = f(x,y)
if x>0.5
z=x+y;
else
z=x+2*y;
end
end
indeed,
feval(f,[0.4 2 3],[4 5 6])
returns: [8.4 12 15]
instead of [8.4 7 9].
What is the correct syntax ?
The if condition doesn't work element-wise, as you seem to expect. Rather, the if branch is entered only if all the elements in the expression (x>0.5 in your case) evaluate to true.
To achieve what you want, change your function to
function z = f(x,y)
ind = x>.5;
z(ind) = x(ind) + y(ind);
z(~ind) = x(~ind) + 2*y(~ind);
end
Note that the logical index ind takes the place of your if.
For your particular function, the code could be simplified to
function z = f(x,y)
z = x + y + (x<=.5).*y;
end

Explicit polyfit with variables

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

Using inline function with constant arguments in MATLAB

This is a part of my code.
clear all;
clc;
p = 50;
t = [-6 : 0.01 : 6];
f = inline('(t+2).*sin(t)', 't')
v = inline('3*f(p*t+2)','t','f','p')
plot(t,f(t));
v(t,f,p);
figure;
plot(t,v(t,f,p));
Here I have two questions.
Why I have to pass p into the function v even though p is a constant which has already declared ?
How I can get an expression for v completely in terms of t as 3*[(50*t+2)*sin(50*t+2)] or in its simplified form ?
Update
This is an update for the second question
Let
f(x) = 1 + x - x^2
g(x) = sin(x)
If I give f(g(x)), I wanna get the output in words, like this
f(g(x)) = (cos(X))^2 + sin(x)
not in numerical value. Is there any function capable to do that?
1) Why do I have to pass p to v even though p is a constant which has already been declared?
Well, a MATLAB's inline function object has an eval wrapper, so the only variables in its scope are those which were automatically captured from the expression or explicitly specified.
In other words, if you want v to recognize p, you have no other option but declaring it when creating the inline object and passing it to v explicitly. The same goes for f as well!
2) How I can get an expression for v completely in terms of t as 3*[(50*t+2)*sin(50*t+2)] or in its simplified form?
Use anonymous functions, like Shai suggested. They are more powerful, more elegant and much faster. For instance:
v = #(t)(3*(50*t+2)*sin(50*t+2))
Note that if you use a name, which is already in use by a variable, as an argument, the anonymous function will treat it as an argument first. It does see other variables in the scope, so doing something like g = #(x)(x + p) is also possible.
EDIT #1:
Here's another example, this time a function of a function:
x = 1:5;
f = #(x)(x .^ 3); %// Here x is a local variable, not as defined above
g = #(x)(x + 2); %// Here x is also a local variable
result = f(g(x));
or alternatively define yet another function that implements that:
h = #(x)f(g(x)); %// Same result as h = #(x)((x + 2) .^ 3)
result = h(x);
The output should be the same.
EDIT #2:
If you want to make an anonymous function out of the expression string, concatenate the '#(x)' (or the correct anonymous header, as you see fit) to the beginning and apply eval, for example:
expr = '(x + 2) .^ 3';
f = eval(['#(x)', expr]) %// Same result as f = #(x)((x + 2) .^ 3)
Note that you can also do char(f) to convert it back into a string, but you'll have to manually get rid of the '#(...)' part.
EDIT #3:
If you're looking for a different solution, you can explore the Symbolic Toolbox. For example, try:
syms x
f(x) = x + 2
g(x) = x ^ 3
or can also use sym, like so:
f(x) = sym('x + 2');
g(x) = sym('x ^ 3');
Use subs to substitute values and evaluate the symbolic expression.
How about using anonymous functions:
p = 50;
t = -6:0.01:6;
f = #(x) (x+2).*sin(x);
v = #(x) 3*f(p*x+2);
figure;
subplot(1,2,1); plot( t, f(t) ); title('f(t)');
subplot(1,2,2); plot( t, v(t) ); title('v(t)');
Is this what you wanted?
Adding a constant into an inline can be done during its definition.
Instead of
p = 50;
v = inline('3*f(p*t+2)','t','f','p')
You can write
p = 50;
v = inline( sprintf('3*f(%f*t+2)', p), 't','f')