Evaulating a multiple valued function at multiple points

7 Ansichten (letzte 30 Tage)
I have a function that is a family of similar but different functions. An example would be 1*sin(1*x) and 2*sin(2*x). I have computed special points (the minimum) of this family of equations. I would like to be able to evaluate each equation within the family at the special point for that specific equation. When I try, I get a n-by-n sym array, because Matlab evaluates each equation at the special point for each equation, instead of evaluating each equation at the special point of that equation.
In slightly less abstract terms, I'm attempting to calculate the trajectory of a rocket, and I have a family of acceleration curves (in type symfun) that differ only in the time to reach a certain altitude. The function that provides the acceleration family of curves also provides a vector of the time at which the accel is at it's minimum. When I try to evaluate the accel curve family at the (vector valued) minimum accel time, I end up with a 1x6 cell, each of which consists of a 1x6 sym.
Is there some way to call my acceleration function with the (vector valued) min accel time in a single line or command? I've even tried to make an empty vector of the appropriate size and fill in each value individually, but I haven't been able to get anywhere.
Example code:
[a_v, v_v, p_v, t_ascent, t_flip, t_max_decel] = rocketLibrary.getLinearCurves(targetAltitude, a_y_0, true, [0.75 0.85 0.95 1.05 1.15 1.25])
maxDecel = zeros(1, length(t_max_decel))
for i = 1:length(t_max_decel)
maxDecel(1, i) = a_v((double(t_max_decel(i))))(i) % Error on this line, as it can't access
%the ith element of the vector that a_v passes back.
end

Akzeptierte Antwort

Joel McReynolds
Joel McReynolds am 28 Okt. 2023
What I ended up doing was using the below code to evaluate the function once at each point, then grab the value that I wanted at each evaluation. Not particularly efficient, but it works.
% given a vector of time values t_max_decel and a function that returns
% multiple values for each, first create a zero filled vector of the appropriate
% length. Then, go through the time values and evaluate the function at
% each of the time values you have and choose the value that you want to
% keep for that time value.
maxDecel = zeros(1, max(size(t_max_decel)))
for i = 1:length(t_max_decel)
temp = a_v((double(t_max_decel(1, i))));
maxDecel(1, i) = temp(i)
end
  2 Kommentare
Matt J
Matt J am 28 Okt. 2023
Was efficiency the point? You're already using symbolic computation, which is inefficient in general.
Joel McReynolds
Joel McReynolds am 28 Okt. 2023
No, efficiency wasn't really the point. I'm just enough of an experienced programmer to notice and be annoyed at the extra values that are calculated and discarded. For anyone following up on this, the below is the code that I ended up with
[a_v, v_v, p_v, t_ascent, t_flip, t_max_decel] = rocketLibrary.getLinearCurves(targetAltitude, a_y_0, [0.8 0.85 0.9 0.95 1])
maxDecel = evalAtPoints(a_v, t_max_decel)
function returnValues = evalAtPoints(f_x, xValues)
returnValues = zeros(1, max(size(xValues)));
for i = 1:length(xValues)
temp = f_x((double(xValues(1, i))));
returnValues(1, i) = temp(i);
end
end

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

Matt J
Matt J am 28 Okt. 2023
Bearbeitet: Matt J am 28 Okt. 2023
Is there some way to call my acceleration function with the (vector valued) min accel time in a single line or command?
Yes, One way is to have the individual functions be held in cells, e.g.,
syms t
for i=1:6, a_v{i}=symfun(t+i,t); end
t_max_decel=(10:10:60); %times
out = arrayfun(@(f,t)double( f{1}(t) ), a_v , t_max_decel)
out = 1×6
11 22 33 44 55 66
  2 Kommentare
Joel McReynolds
Joel McReynolds am 28 Okt. 2023
In addition to the code snippet that I gave you above, I am also writing the code within the rocketLibrary that generates the a_v function. Currently, that code is along the lines of a_v = t_ascent * g(t). If t_ascent is a single value (the normal case when I'm looking at a single trajectory), a_v is a symfun and all is well. If t_ascent is a vector, a_v is still a symfun, but now it is multivalued. How would I convert it to be an array of cells instead, to take advantage of your answer?
Matt J
Matt J am 28 Okt. 2023
Bearbeitet: Matt J am 28 Okt. 2023
You could do something like this,
syms t
f(t)= [1,2,3]*sin(t) %a vector valued symfun
f(t) = 
a_v=cellfun(@(z)symfun(z,t), sym2cell(f(t)) ,'uni',0); %a cell array of symfuns
a_v{:}
ans(t) = 
ans(t) = 
ans(t) = 

Melden Sie sich an, um zu kommentieren.


Matt J
Matt J am 28 Okt. 2023
Bearbeitet: Matt J am 28 Okt. 2023
Another way is to make it so that the time variable t is vector-valued as well:
syms t [1,4]
f(t)= t.^(1:4)
f(t1, t2, t3, t4) = 
Times=3:6; %evaluate at these times
T=num2cell(Times);
f(T{:})
ans = 1×4
3 16 125 1296

Produkte


Version

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by