Filter löschen
Filter löschen

Do Orphaned sym Objects in the Symbolic Engine Matter?

4 Ansichten (letzte 30 Tage)
Paul
Paul am 24 Dez. 2023
Kommentiert: Paul am 8 Jan. 2024
Suppose I execute the following code
func
a. Did I just create an object in the symbolic engine that I have no way to access?
b. If so, is that object an orphan in the sense that I can't access it for any subsequent commands in the base workspace?
c. Or, is there a way that the object in the symbolic engine can be 'poofed' back into a symbolic object in the base workspace?
d. If so, can that happen without me knowing about it?
e. Is there anyway for the exsistence of that object in engine and its associated assumption to have any silent impact on subsequent symbolic computations?
f. Can I count on other functions, like @doc:solve in the parameters output argument, that create objects in the engine, to not be affected by the existence of the orphaned object? For example, the symbolic variable in parameters is typically called 'k' if it's an integer. Will there be a problem if the orphaned object is named 'k'? Or will parameters use a different variable?
The more I think about it, the more I think that symengine orphans must be a non-issue, because I can do something as mundane as
f = sym('x') + sym('y');
f = 
clear f
after which the Matlab variable f is no lonnger in the base workspace, but x and y are still hanging around in some form in the engine, aren't they? In other words, orphans can arise all the time, so (hopefully) shouldn't be a problem.
function func
sym('z','positive');
end

Akzeptierte Antwort

Walter Roberson
Walter Roberson am 24 Dez. 2023
func
assumptions()
ans = 
z = sym('z')
z = 
z
assumptions()
ans = 
syms z
assumptions()
ans = Empty sym: 1-by-0
function func
sym('z','positive');
end
So, no you did not create an orphan object: you can get it back with sym() (but not syms() )
  10 Kommentare
Walter Roberson
Walter Roberson am 7 Jan. 2024
When you
syms x
that is equivalent to first telling the symbolic engine that you are interested in a variable named x, and then resetting any internal symbolic engine assumptions associated with x, and returning an abstract reference to x out of the symbolic engine, then storing the abstract reference in a sym object, and lastly assigning x at the MATLAB level to be the sym object.
Then as you use x then the sym object is consulted to get the abstract internal reference, the abstract internal reference is passed to the symbolic engine along with instructions to perform whatever operation, returning an abstract reference out that gets wrapped in a sym object and the sym object gets returned.
z = x + 1;
results in z at the MATLAB level being a sym object that contains an abstract reference such as '_symans_[[32,0,36]]' -- without creating any variable z at the symbolic level.
As long as you do not call evalin(symengine) or feval(symengine) yourself, the variables that live at the level of the symbolic engine are restricted to what you have syms or sym or symmatrix into existence, together with the automatically created variable z that is used in rootOf structures, and variables automatically created by solve() to hold parameters. And as long as you do not call evalin(symengine) or feval(symengine) yourself, variables at the symbolic engine level just hold information about their names and assumptions.
x = x + 1;
would result in x at the MATLAB level being a sym object that holds an internal reference such as '_symans_[[32,0,38]]' and that internal reference would be to _plus(x,1) . If you were to
x = x + 1;
again then x at the MATLAB level would become a sym object that holds an internal reference such as '_symans_[[38,0,143]]' and that internal reference would be to _plus(x,2)
Under the restriction that you do not call evalin(symengine) or feval(symengine) yourself then the symbolic engine will hold only simple variable names that represent themselves -- together with a bunch of anonymous expressions known only by their _symans_ references. The MATLAB level holds the _symans_ references.
f = sym('x') + sym('y');
There is no symboic variable named f at the symbolic engine level -- there is just x and y and there is a _sysmans_ representing the expression _plus(x,y)
Because of this, the only thing you can do that affects "the real x" that is held in the symbolic engine is to change the assumptions associated with it. No matter how complicated of an expression you build up, the symbolic engine level will only know simple variables x and y (and other variables you sym() or syms() into existence) and everything else is a _symans_ at the symbolic engine level. f = sym('x') + sym('y') will absolutely not result in a symbolic variable f being created a the symbolic engine level.
So.... you can play around with variables as much as you want inside of functions, and at most you will affect the assumptions on variables and possibly pop a few more variables into (simple) existanence . The rest is all _symans_ stuff. If you previously had f = sym('x') + sym('y') in effect and in a function you do f = exp(sym('x')) then you get a _symans out that is written into a local MATLAB variable f and absolutely nothing about the previous expression is affected. If you restore the assumptions and then return from the function, everything is fine.
(How garbage collection is done on the various _symans_ is an excellent question; I do not know the answer.)
Paul
Paul am 8 Jan. 2024
What I meant is a situation like this.
syms z positive
Now call a function that does something and returns a symbolic expression
h = myfunc()
h = 
assumptions
ans = 
The expression returned from the function is now subject to the assumptions on z made in the base workspace, even if those assumption were temporarily removed in the function and weren't intended to apply to the returned expression.
solve(h)
ans = 
1
It seems like the only way to avoid this is to make sure that the returned expression doesn't depend on any of the assumptions made outside the called function.
function f = myfunc()
held_assumptions = assumptions;
assume(assumptions,'clear')
z = sym('z');
f = (z-1)*(z+1);
assume(held_assumptions)
end

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Produkte


Version

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by