Human sensible outputs from finverse - matlab

I am using finverse and it is giving strange simplifications as an example
>> syms x
>> f = -0.0185*x^2 + 12.4698;
>> finverse(f)
ans =
(2^(1/2)*185^(1/2)*(62349 - 5000*x)^(1/2))/185
Rather than the much simpler
sqrt(12.4698 - x) / sqrt(0.0185)
Or something to that effect. Is there a way to force "human sensible outputs"? I tried simplify but it didn't help very much.

You can used function simple
syms x
f = -0.0185*x^2 + 12.4698;
Z = finverse(f)
V = simple(Z);
Z =
(2^(1/2)*185^(1/2)*(62349 - 5000*x)^(1/2))/185
>> V
V =
(23069130 - 1850000*x)^(1/2)/185
Remove ; at the end of function calls, that to see at different simplification.

Related

How to use integral2 to evaluate integral of (apparently) non-vectorized functions?

I've noticed some weird facts about integral2. These are probably due to my limitations in understanding how it works. I have some difficulties in integrating out variables when I have particular functions. For instance, look at the following Code:
function Output = prova(p,Y)
x = p(1);
y = p(2);
w = p(3);
z = p(4);
F1 = #(Data,eta_1,eta_2,x,y,w,z) F2(eta_1,eta_2,Data) .* normpdf(eta_1,x,y) .* normpdf(eta_2,w,z);
Output = integral2(#(eta_1,eta_2)F1(Y,eta_1,eta_2,0,1,10,2),-5,5,-5,5);
end
function O = F2(pp1,pp2,D)
O = pp1 + pp2 + sum(D);
end
In this case the are no problems in evaluating the integral. But if I change the code in this way I obtain some errors, although the output of F2 is exactly the same:
function Output = prova(p,Y)
x = p(1);
y = p(2);
w = p(3);
z = p(4);
F1 = #(Data,eta_1,eta_2,x,y,w,z) F2(eta_1,eta_2,Data) .* normpdf(eta_1,x,y) .* normpdf(eta_2,w,z);
Output = integral2(#(eta_1,eta_2)F1(Y,eta_1,eta_2,0,1,10,2),-5,5,-5,5);
end
function O = F2(pp1,pp2,D)
o = sum([pp1 pp2]);
O = o + sum(D);
end
The problems increase if F2 for example have some matrix multiplication in which "eta_1" and "eta_2", which I want to integrate out, are involved. This problems makes practically impossible to solve computations in which, for instance, we have to integrate out a variable X which is inside a Likelihood Function (whose calculation could require some internal Loop, or Sum, or Prod involving our variable X). What is the solution?

How to simplify functions in matlab?

Hello Let's say I have theres two functions
F1= a*x^(2) + b
F2 = c*x
Where a, b and c are a constant and x is a variablem how do can I make matlab gives me a simplified version of F1*F2 so the answer may be
a*c*x^(3) + b*c*x
This is what I have in matlab
syms x a b c
F1 = a*x^(2) +b;
F2 = c*x^(2);
simplify(F1*F2)
ans =
c*x^2*(a*x^2 + b)
When I multiply in matlab it's just giving me (ax^(2) + b)(c*x)
Try this commands:
syms a x b c
F1= a*x^(2) + b
F2 = c*x
F=F1*F2
collect(F)
which will give you:
ans =
a*c*x^3 + b*c*x
The command collect is useful when working with polynoms. The opposite command is pretty. It will give you c*x*(a*x^2 + b)

Series expansion of a function about infinity - how to return coefficients of series as a Matlab array?

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.

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')

Matlab discontiniuos functions

Any simple way to define a discontinuous function (such as f(x)=5 if x>5, f(x)=6x if x<5) and evaluate it in a interval (such as [0 6]).
How about this:
f = #(x) 5*(x>5) + 6*x.*(x<5);
as in
t = 0:0.001:6;
f = #(x) 5*(x>5) + 6*x.*(x<5);
plot(t,f(t));
You may want to change your definition to make sure you define the case when x = 5, to be one of the following:
f = #(x) 5*(x>5) + 6*x.*(x<=5);
or
f = #(x) 5*(x>=5) + 6*x.*(x<5);