Calculating the expected value of a transformed random variable in MATLAB? - matlab

I am trying to compute the following expected value for Z being lognormally distributed
E[Z^eta w(F_Z (Z))^-eta]
where eta is a real number, F_Z the distribution function of Z and w:[0,1]->[0,1] an increasing function.
First of all, I am pretty new to Matlab so I don't know which way of integrating is the better one, numerically or symbolically. I tried symbolically.
My idea was to subsequently define functions:
syms x;
g_1(x) = x^eta;
g_2(x) = logncdf(x);
g_2(x) = w(x)^-eta;
g_4(x) = g_1(x) * g_3(g_2(x));
And then
exp = int(g_4(x),x,0,inf)
Unfortunately this doesn't work and MATLAB just posts the whole expression of g_4...
Is it better to use the numerical integration quadqk? What am I doing wrong here? I already read something about MATLAB not being the best program for integration but I have to use it so switching to a different program does not help.
Thanks a lot!

Related

Is there an inverse factorial expression I can use in Matlab?

I want to edit this to get numberOfCircuits on its own on the left. Is there a possible way to do this in MATLAB?
e1=power(offeredTraffic,numberOfCircuits)/factorial(numberOfCircuits)/sum
The math for this problem is given in https://math.stackexchange.com/questions/61755/is-there-a-way-to-solve-for-an-unknown-in-a-factorial, but it's unclear how to do this with Matlab's functionality.
I'm guessing the easy part is rearranging:
fact_to_invert = power(offeredTraffic,numberOfCircuits)/sum/e1;
Inverting can be done, for instance, by using fzero. First define a continuous factorial based on the gamma function:
fact = #(n) gamma(n+1);
Then use fzero to invert it numerically:
numberOfCircuits_from_inverse = fzero(#(x) fact(x)-fact_to_invert,1);
Of course you should round the result for safe measure, and if it's not an integer then something's wrong.
Note: it's very bad practice (and brings 7 years bad luck) to name a variable with a name which is also a built-in, such as sum in your example.

Unable to code non linear equation in MATLAB R2013a - MATLAB giving warning message

I wanted to solve the following equation in MATLAB R2013a using the Symbolic Math Toolbox.
(y/x)-(((1+r)^n)-1)/r=0 where y,x and n>3 are given and r is the dependent variable
I tried myself & coded as follows:
f=solve('(y/x)-(((1+r)^n)-1)/r','r')
but as the solution for r is not exact i.e. it is converging on successive iterations hence MATLAB is giving a warning output with the message
Warning: Explicit solution could not be found.
f =
[ empty sym ]
How do I code this?
There are an infinite number of solutions to this for an unspecified value of n > 3 and unknown r. I hope that it's pretty clear why – it's effectively asking for a greater and greater number of roots of (1+r)^n. You can find solutions for fixed values of n, however. Note that as n becomes larger there are more and more solutions and of course some of them are complex. I'm going to assume that you're only interested in real values of r. You can use solve and symbolic math for n = 4, n = 5, and n = 6 (for n = 6, the solution may not be in a convenient form):
y = 441361;
x = 66990;
n = 5;
syms r;
rsol = solve(y/x-((1+r)^n-1)/r==0,r,'IgnoreAnalyticConstraints',true)
double(rsol)
However, the question is "do you need all the solutions or just a particular solution for a given value of n"? If you just need a particular solution, you shouldn't be using symbolic math at all as it's slower and has practical issues like the ones you're experiencing. You can instead just use a numerical approach to find a zero of the equation that is near a specified initial guess. fzero is the standard function for solving this sort of problem in a single variable:
y = 441361;
x = 66990;
n = 5;
f = #(r)y/x-((1+r).^n-1)./r;
r0 = 1;
rsol = fzero(f,r0)
You'll see that the value returned is the same as one of the solutions from the symbolic solution above. If you adjust the initial guess r0 (say r0 = -3), it will return the other solution. When using numeric approaches in cases when there are multiple solutions, if you want specific solutions you'll need to know about the behavior of your function and you'll need to add some clever extra code to choose initial guesses.
I think you forgot to define n as well.
f=solve('(y/x)-(((1+r)^n)-1)/r=0','n-3>0','r','n')
Should solve your problem :)

Issue with Matlab solve function?

The following command
syms x real;
f = #(x) log(x^2)*exp(-1/(x^2));
fp(x) = diff(f(x),x);
fpp(x) = diff(fp(x),x);
and
solve(fpp(x)>0,x,'Real',true)
return the result
solve([0.0 < (8.0*exp(-1.0/x^2))/x^4 - (2.0*exp(-1.0/x^2))/x^2 -
(6.0*log(x^2)*exp(-1.0/x^2))/x^4 + (4.0*log(x^2)*exp(-1.0/x^2))/x^6],
[x == RD_NINF..RD_INF])
which is not what I expect.
The first question: Is it possible to force Matlab's solve to return the set of all solutions?
(This is related to this question.) Moreover, when I try to solve the equation
solve(fpp(x)==0,x,'Real',true)
which returns
ans =
-1.5056100417680902125994180096313
I am not satisfied since all solutions are not returned (they are approximately -1.5056, 1.5056, -0.5663 and 0.5663 obtained from WolframAlpha).
I know that vpasolve with some initial guess can handle this. But, I have no idea how I can generally find initial guessed values to obtain all solutions, which is my second question.
Other solutions or suggestions for solving these problems are welcomed.
As I indicated in my comment above, sym/solve is primarily meant to solve for analytic solutions of equations. When this fails, it tries to find a numeric solution. Some equations can have an infinite number of numeric solutions (e.g., periodic equations), and thus, as per the documentation: "The numeric solver does not try to find all numeric solutions for [the] equation. Instead, it returns only the first solution that it finds."
However, one can access the features of MuPAD from within Matlab. MuPAD's numeric::solve function has several additional capabilities. In particular is the 'AllRealRoots' option. In your case:
syms x real;
f = #(x)log(x^2)*exp(-1/(x^2));
fp(x) = diff(f(x),x);
fpp(x) = diff(fp(x),x);
s = feval(symengine,'numeric::solve',fpp(x)==0,x,'AllRealRoots')
which returns
s =
[ -1.5056102995536617698689500437312, -0.56633904710786569620564475006904, 0.56633904710786569620564475006904, 1.5056102995536617698689500437312]
as well as a warning message.
My answer to this question provides other way that various MuPAD solvers can be used, particularly if you can isolate and bracket your roots.
The above is not going to directly help with your inequalities other than telling you where the function changes sign. For those you could try:
s = feval(symengine,'solve',fpp(x)>0,x,'Real')
which returns
s =
(Dom::Interval(0, Inf) union Dom::Interval(-Inf, 0)) intersect solve(0 < 2*log(x^2) - 3*x^2*log(x^2) + 4*x^2 - x^4, x, Real)
Try plotting this function along with fpp.
While this is not a bug per se, The MathWorks still might be interested in this difference in behavior and poor performance of sym/solve (and the underlying symobj::solvefull) relative to MuPAD's solve. File a bug report if you like. For the life of me I don't understand why they can't better unify these parts of Matlab. The separation makes not sense from the perspective of a user.

convolution of experimental data with a singular function in Matlab

this is likely a few lines of code but I cannot figure it out...
I need to perform a convolution operation of experimental data with an analytical function which is singular at the beginning of the integration range. So if I use "conv" it won't work...
I have two experimental vectors, phi(time) and time
then want to calculate T(t)
T = \int_{0}^{t}\phi \left ( t-\tau \right )\frac{\textup{d}\tau}{\tau ^{1/2}}
So the the singularity at tau = 0 makes "conv" not work. I've been fiddling with anonymous functions and using quadgk to handle the singularity and the like, but can't make anything work. I would have bet anything that this is a solved problem but can't find anything like it. Any help is very much appreciated.
EDIT: solved it this way:
function T = TCalc(time, power)
warning off MATLAB:quadgk:NonFiniteValue %suppress warning at the zero point
T=zeros(size(time));
for par = 1:numel(time)
T(par) = s1(time(par));
end
function y = r1(t)
y = interp1q(time,power,t');%notice that t is transposed! to make interp1q work.
y = y';
end
function y = s1(tfin)
y = quadgk(#(t) (r1(tfin-t))./t.^(0.5),0,tfin,'RelTol',1.e-2);
end
end
I guess, the inelegant trick here is to make Matlab think the experimental data is an analytical function by passing through interp1, and using quadgk to tolerate a singularity at the limit of integration. About one second for 1000-point vectors. Ignoring or setting the tau = 0 point to a small value doesn't work, it still perceives a singularity and the result is wrong.

Calculating Symmetric Mean Percentage Error (SMAPE) in MATLAB

I am trying to write some code that will automatically calculate the (so-called) Symmetric Mean Percentage Error in relation to a series of forecasts.
The relevant equation is depicted here .
I have written the following code to accomplish this task.
SMAPE = (sum(abs(Results(:,3)) ./ ((abs(Results(:,1))+
abs(Results(:,2))) /2))) * ((numel(Results(:,3)))^(-1));
My code works but has been criticized on the grounds that it is too long and difficult to read, and I agree that it is difficult to read. Could I have accomplished the same thing in a briefer way
How about defining the variables y and f, then it would be as simple as:
y = Results(:,2);
f = Results(:,3);
0.5*mean(abs(y-f)./(abs(y)+abs(f)))
I think it would be
2.0*mean(abs(y-f)./(abs(y)+abs(f)))