Conversion of symbolic expression to double without obtaining complex numbers
5 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Hello,
I have written a function which should return the inserted values x0 of the partial derivatives of a mathematical function fun. My variables in the mathematical function are symbolic and at the end I need to convert Y, because I want to get some double values. My MATLAB function looks as follows:
function Y = patial_derivatives(fun, x0)
syms x y z P real
variables = [x y z];
for i = 1:numel(x0)
P(i) = diff(fun, variables(i));
end
Y = subs(P,{x,y,z},{x0(1),x0(2),x0(3)});
end
and I want to call the function like this:
patial_derivatives(@(x,y,z) x^ y*exp(z), [-10 1 100])
One derivative of my function obtains the logarithm and that is where it is geeting complex when I want to convert it to a double value. Does anybody have an idea how I can avoid complex numbers here?
8 comentarios
Walter Roberson
el 8 de Ag. de 2023
Looking at the code:
Things that are not symbolic variables or sym() class get sym() applied to them. And sym() of a function handle creates a symbolic expression.
The documented permitted values for the item to be differentiated are stricter than what is actually accepted. For example the documentation lists single and double but not any of the integer data types, but the integer types are accepted as well
diff(uint8(1:5), sym('x'))
Paul
el 8 de Ag. de 2023
Editada: Paul
el 8 de Ag. de 2023
Thanks for pointing out that use of sym that takes in a function handle and creates a symbolic expression.
I'm almost there.
7. Object functions
An object function accepts a particular class of object in its input argument list. When there are multiple object functions with the same name, MATLAB checks the classes of the input arguments to determine which function to use.
In this case, there is no object function diff for a function_handle, so we go to the object function diff for class sym. So I don't think this is a dominant class situation (but I'm probably wrong). And I don't know what happens if the argument list contains two (or more) objects of different classess that have a same-named object function, but neither class is inferior to the other. Probably goes left to right.
Anyway, now that Matlab has determined that sym->diff is to be called, it applies sym() to the first argument. Is that a rule that's always applied in classes in general? That is, if there's not an exact signature match for the object function being called, Matlab will always try to make a matching signature by applying the class constructor to the non-matching arguments? I don't do OO programming in Matlab, so I might be asking basic questions.
Regardless of how it gets done, it appears that the first argument to sym->-diff will try to get converted by sym() if it's not already sym-like (like a symfun, or symmatrix) that I assume don't need sym() applied if they are the first argument. But, if that's the case, then (as I think you're alluding to) the documentation is overly restrictive in the list of acceptable data types. Seems like it should either list all of the types that are convertible to a sym (including function_handle and uint_8) or get rid of that "single | double" and replace it with language to the effect of "anything convertible to a sym." As written, a reasonable reader might infer that a function_handle, or uint_8, should throw an error (or result in undefined behavior) because the doc explicitly calls out only single and double.
Respuestas (2)
VBBV
el 8 de Ag. de 2023
Editada: VBBV
el 8 de Ag. de 2023
oneway, is to use a conditional statement for negative input values through abs function. But if you want to avoid complex value then simply use real function
patial_derivatives(@(x,y,z) (x)^y*exp(z), [-10 1 100])
function Y = patial_derivatives(fun, x0)
syms x y z P real
variables = [x y z];
for k = 1:numel(x0)
P(k) = diff(fun, variables(k));
end
Y = real(subs(P,{x,y,z},{x0(1),x0(2),x0(3)}));
end
0 comentarios
Dyuman Joshi
el 8 de Ag. de 2023
Editada: Dyuman Joshi
el 8 de Ag. de 2023
"Is there any possibility to garantuee that Matlab takes the abs values for the log if I get the log inside my derivative"
You can try this -
out = patial_derivatives(@(x,y,z) (x)^y*exp(z), [-10 1 100])
function Y = patial_derivatives(fun, x0)
syms x y z P
variables = [x y z];
for k = 1:numel(x0)
P(k) = diff(fun, variables(k));
end
%Changing log() terms to log(abs())
P = subs(P,log(variables),log(abs(variables)))
Y = subs(P,variables,x0);
end
Note that this only changes for log(), if the input has any other function that returns complex values for particular inputs, that will require additional modifiction.
You should also keep in mind what @Walter Roberson commented - "But that would mean working with a different function, one that has discontinuous derivatives at x == 0."
0 comentarios
Ver también
Categorías
Más información sobre Assumptions en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!