An issue with matlabFunction
5 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Mohammad Shojaei Arani
le 11 Déc 2023
Commenté : Dyuman Joshi
le 12 Déc 2023
Hello,
I have a question and I think the best is to explain via an example. So, consider the following
mu=@(x,par)par(1).*x;sigma=@(x,par)par(2);
syms x0 x dt
par = sym('par', [1, 2]);
LL = -1 / 2 * (log(2 * pi * dt * sigma(x0, par)^2) + ((x - x0 - mu(x0, par) * dt) / (sigma(x0, par) * sqrt(dt)))^2);
h_LL = hessian(LL,par);
h_LL=matlabFunction(h_LL)
Now, assume that V is a 1-by-n given vector and x0=V(1:n-1), x=V(2:n), dt and par's are given scalars. for instance, assume that dt=1, x0=1:100, x=2:101, par1=par2=1. What I want to do is to calculate the following sum over the elements of V:
h_LL(1,1,1,1,2)+h_LL(1,1,1,2,3)+h_LL(1,1,1,3,4)+ ... + h_LL(1,1,1,100,101)
Of course I can calculate this sum using a for-loop. But, my actual 'n' and the number of my actual parameters are very big making this scheme impractical. The idea that comes to my mind is to find a way to remove the 'reshape' in the above function handle h_LL and supply the entire vevtors x and x0 rather than doing so element by element.
Unfortunately, I haver no control over matlabFunction and cannot tell it please give me a matrix rather than applying reshape to a scalar.
Any idea?
Thanks in advance,
Babak
2 commentaires
Réponse acceptée
Dyuman Joshi
le 11 Déc 2023
Modifié(e) : Dyuman Joshi
le 11 Déc 2023
mu=@(x,par)par(1).*x;
sigma=@(x,par)par(2);
syms x0 x dt
par = sym('par', [1, 2]);
LL = -1 / 2 * (log(2 * pi * dt * sigma(x0, par)^2) + ((x - x0 - mu(x0, par) * dt) / (sigma(x0, par) * sqrt(dt)))^2);
temp = hessian(LL, par)
%Reshape the hessian as a column vector
h_LL = reshape(temp, [], 1)
%Convert to a function handle
fun=matlabFunction(h_LL);
%Sample inputs
DT=1; X0=1:100; X=2:101; PAR1=1; PAR2=1;
%Provide x0 and x as row vectors
out = fun(DT, PAR1, PAR2, X, X0)
%Convert the output to a 3D array,
%where each 2D matrix is a corresponding output
out = reshape(out, 2, 2, [])
%For comparison
subs(temp, [dt x0 x par], [DT X0(1) X(1) PAR1 PAR2])
subs(temp, [dt x0 x par], [DT X0(2) X(2) PAR1 PAR2])
2 commentaires
Plus de réponses (1)
Walter Roberson
le 11 Déc 2023
matlabFunction can produce vectorized code only if all of the following are true:
- the expression is scalar for scalar inputs
- the expression does not use piecewise()
- the expression does not involve an integral, unless the integral is one that has a closed-form solution. This applies regardless of whether the symbolic parameters appear in the expression to be integrated, or in the bounds of the integral (but for different reasons for those two situations)
- the expression does not use symmatrix (matlabFunction refuses to process those)
I might be forgetting some other cases.
The idea that comes to my mind is to find a way to remove the 'reshape' in the above function handle h_LL
You would have to do that by post processing, such as by having matlabFunction use the 'File' option and edit the file afterwards. Unless you wanted to risk putting a reshape.m on your MATLAB path, but that would be distinctly risky.
So what is the official solution for this kind of problem?
- You can loop; or
- You can use arrayfun() to apply the function to "corresponding" matrix inputs, which will automatically wrap the results; you would 'uniform', 0 to get a cell array of results. You could reshape() or permute() that cell to be 1 x 1 x n and then use cell2mat() -- or you could do cat(3, ThatCell{:}) to concatenate along the third dimension.
0 commentaires
Voir également
Catégories
En savoir plus sur Conversion Between Symbolic and Numeric dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!