Passing dependence on variable through nested symbolic functions

39 vues (au cours des 30 derniers jours)
big ted
big ted le 25 Fév 2023
I am struggling to get to grips with the symbolic math tools. Namely, I am trying to figure out how to make one function be a function of another. I have (functions simplified for clarity):
syms f1(x);
f1(x) = 2*x;
If I run argnames(f1) at this point the return is x, as expected.
syms f2(f1);
f2(f1) = sqrt(f1);
Now argnames(f1) returns an empty symbolic variable. Somehow the second two lines have redefined f1(x).
Further down my code I would like to compute the integral:
int(f2(f1)/(sqrt((x^2 + 4))),[0 1])
Where the integration is with respect to x. Since I cannot seem to carry forward the dependence of f2 on x, I am unable to do this.
Replacing the 3rd line with
syms f2(f1(x))
Returns an indexing error, as Matlab seems to be interpretting the parentheses as indices.
Any help would be very much appreciated.
  1 commentaire
Stephen23
Stephen23 le 25 Fév 2023
Modifié(e) : Stephen23 le 25 Fév 2023
"Somehow the second two lines have redefined f1(x)."
The SYMS documentation states "syms f(var1,...,varN) creates the symbolic function f of type symfun and the symbolic scalar variables var1,...,varN of type sym... This syntax clears all previous definitions of var1,...,varN including symbolic assumptions."
So you obliterate f1 and f2 when you call SYMS each time like that. Why not just use the simple approach?:
syms x
f1 = 2*x
f1 = 
f2 = sqrt(f1)
f2 = 
tmp = int(f2/(sqrt((x^2+4))),[0,1])
tmp = 
vpa(tmp)
ans = 
0.44877071695822453274281671949784

Connectez-vous pour commenter.

Réponses (1)

Walter Roberson
Walter Roberson le 25 Fév 2023
syms f1(x);
f1(x) = 2*x;
The first of those lines is equivalent to
clear f1 x
x = sym('x');
f1 = symfun('f1(x)', x);
and then the second line is equivalent to
f1 = symfun(2*x, x);
which overwrites the MATLAB-level f1 with a reference to a symfun, overwriting the previous f1 = symfun('f1(x)', x) . You could also have coded
syms x
f1(x) = 2*x
to have the same effect.
syms f2(f1);
That line is equivalent to
clear f2 f1
f1 = sym('f1');
f2 = symfun('f2(f1)', f1);
which clears the existing f1 definition of 2*x first.
That is why argnames(f1) is now empty -- because the MATLAB-level f1 was overwritten with just a symbol.
Namely, I am trying to figure out how to make one function be a function of another.
The "native" way to define a symbolic function is using the form NAME = symfun(EXPRESSION, VARIABLES) . The code syms f1(x) is a convenient way to define f1 as a symbolic function that evaluates to itself, which is internally done by using assignment and symfun(). Code of the form f1(x) = 2*x is a convenient syntax that is internally done by using assignment and symfun()
In each of the three cases, because it internally translates to an assignment to a variable and a symfun call, the entire symfun is evaluated the same way as any other MATLAB expression -- namely the parameters are fully evaluated first in-order left to right, and only after all of the parameters have been evaluated, symfun() is called passing in the parameters. So something like
syms f1(x)
f2(x) = sqrt(f1)
is evaluated pretty much as
x = sym('x');
f1 = symfun('f1(x)', x);
vars = argnames(f1)
varscell = num2cell(vars)
temp1 = sqrt(f1(varscell{:}))
temp2 = symfun(temp1, vars)
vars2 = argnames(temp2)
if ~isequal(sort(vars2), x)
error because the parameters for the generated function sqrt(f1) does not match
the parameters required by the assignment
end
f2 = symfun(formula(temp2), x)
The assignment f2(x) = does not know what the variable names are for the function sqrt(f1) until after it has fully evaluated the sqrt(f1) -- which builds a temporary symbolic function as it goes. And then tears it apart to slap the new set of variables on it, but only provided that the variables are compatible (I might have missed some detail in the compatibility check.)
Notice the temp1 = sqrt(f1(varscell{:})) -- that is, f1 is evaluated, passing in its named parameters and returning a expression . And then sqrt() of the expression is taken.
So no -- f2 does not know that it is dependent on f1 . f2 is only the temporary symbolic function resulting from the expression to work with.
Another way of stating this is that f2(x) = sqrt(f1) fully evaluates the right hand side losing the reference to f1 . f1 is involved only in having been evaluated to return an expression.
There is, in short, no (non-hack) way of marking a symbolic function as being dependent on a symbolic function that was already given a definition.
If you had had
syms f1(x)
f2(x) = sqrt(f1)
then you would get f1(x)^(1/2) as the function body -- and you could later subs() a function for f1 .
A function cannot be defined as taking a function as a parameter -- only defined as taking variables as parameters.

Produits


Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by