-
Notifications
You must be signed in to change notification settings - Fork 4
work on extensions #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
00b7982
work on extensions
jverzani fc40a8a
SymbolicUtils, not TermInterface; use .py
jverzani 072ad2d
WIP
jverzani a5e0b11
WIP
jverzani 1359575
needed init!
jverzani 3ab988a
add core numbers
jverzani f355167
edit
jverzani e7cf818
work on docs
jverzani File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
module SymPyPythonCallSymbolicsExt | ||
|
||
# from https://github.com/JuliaSymbolics/Symbolics.jl/pull/957/ | ||
# by @jClugstor | ||
using SymPyPythonCall | ||
const PythonCall = SymPyPythonCall.PythonCall | ||
import SymPyPythonCall.PythonCall: Py, pyisinstance, pyconvert | ||
|
||
import Symbolics | ||
import Symbolics: @variables | ||
const sp = SymPyPythonCall.sympy | ||
|
||
# rule functions | ||
function pyconvert_rule_sympy_symbol(::Type{Symbolics.Num}, x::Py) | ||
if !pyisinstance(x,sp.Symbol) | ||
return PythonCall.pyconvert_unconverted() | ||
end | ||
name = PythonCall.pyconvert(Symbol,x.name) | ||
return PythonCall.pyconvert_return(Symbolics.variable(name)) | ||
end | ||
|
||
function pyconvert_rule_sympy_pow(::Type{Symbolics.Num}, x::Py) | ||
if !pyisinstance(x,sp.Pow) | ||
return PythonCall.pyconvert_unconverted() | ||
end | ||
expbase = pyconvert(Symbolics.Num,x.base) | ||
exp = pyconvert(Symbolics.Num,x.exp) | ||
return PythonCall.pyconvert_return(expbase^exp) | ||
end | ||
|
||
function pyconvert_rule_sympy_mul(::Type{Symbolics.Num}, x::Py) | ||
if !pyisinstance(x,sp.Mul) | ||
return PythonCall.pyconvert_unconverted() | ||
end | ||
mult = reduce(*,PythonCall.pyconvert.(Symbolics.Num,x.args)) | ||
return PythonCall.pyconvert_return(mult) | ||
end | ||
|
||
function pyconvert_rule_sympy_add(::Type{Symbolics.Num}, x::Py) | ||
if !pyisinstance(x,sp.Add) | ||
return PythonCall.pyconvert_unconverted() | ||
end | ||
sum = reduce(+, PythonCall.pyconvert.(Symbolics.Num,x.args)) | ||
return PythonCall.pyconvert_return(sum) | ||
end | ||
|
||
function pyconvert_rule_sympy_equality(::Type{Symbolics.Equation}, x::Py) | ||
if !pyisinstance(x,sp.Equality) | ||
return PythonCall.pyconvert_unconverted() | ||
end | ||
rhs = pyconvert(Symbolics.Num,x.rhs) | ||
lhs = pyconvert(Symbolics.Num,x.lhs) | ||
return PythonCall.pyconvert_return(rhs ~ lhs) | ||
end | ||
|
||
function pyconvert_rule_sympy_derivative(::Type{Symbolics.Num}, x::Py) | ||
if !pyisinstance(x,sp.Derivative) | ||
return PythonCall.pyconvert_unconverted() | ||
end | ||
variables = pyconvert.(Symbolics.Num,x.variables) | ||
derivatives = prod(var -> Differential(var), variables) | ||
expr = pyconvert(Symbolics.Num, x.expr) | ||
return PythonCall.pyconvert_return(derivatives(expr)) | ||
end | ||
|
||
function pyconvert_rule_sympy_function(::Type{Symbolics.Num}, x::Py) | ||
if !pyisinstance(x,sp.Function) | ||
return PythonCall.pyconvert_unconverted() | ||
end | ||
name = pyconvert(Symbol,x.name) | ||
args = pyconvert.(Symbolics.Num,x.args) | ||
func = @variables $name(..) | ||
return PythonCall.pyconvert_return(first(func)(args...)) | ||
end | ||
|
||
# added rules | ||
PythonCall.pyconvert_add_rule("sympy.core.power:Pow", Symbolics.Num, pyconvert_rule_sympy_pow) | ||
|
||
PythonCall.pyconvert_add_rule("sympy.core.symbol:Symbol", Symbolics.Num, pyconvert_rule_sympy_symbol) | ||
|
||
PythonCall.pyconvert_add_rule("sympy.core.mul:Mul", Symbolics.Num, pyconvert_rule_sympy_mul) | ||
|
||
PythonCall.pyconvert_add_rule("sympy.core.add:Add", Symbolics.Num, pyconvert_rule_sympy_add) | ||
|
||
PythonCall.pyconvert_add_rule("sympy.core.relational:Equality", Symbolics.Equation, pyconvert_rule_sympy_equality) | ||
|
||
PythonCall.pyconvert_add_rule("sympy.core.function:Derivative",Symbolics.Num, pyconvert_rule_sympy_derivative) | ||
|
||
PythonCall.pyconvert_add_rule("sympy.core.function:Function",Symbolics.Num, pyconvert_rule_sympy_function) | ||
|
||
|
||
|
||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
module SymPyPythonCallTermInterfaceExt | ||
|
||
import SymPyPythonCall | ||
import TermInterface | ||
|
||
#== | ||
Check if x represents an expression tree. If returns true, it will be assumed that operation(::T) and arguments(::T) methods are defined. Definining these three should allow use of SymbolicUtils.simplify on custom types. Optionally symtype(x) can be defined to return the expected type of the symbolic expression. | ||
==# | ||
function TermInterface.istree(x::SymPyPythonCall.SymbolicObject) | ||
!(convert(Bool, x.is_Atom)) | ||
end | ||
|
||
#== | ||
f x is a term as defined by istree(x), exprhead(x) must return a symbol, corresponding to the head of the Expr most similar to the term x. If x represents a function call, for example, the exprhead is :call. If x represents an indexing operation, such as arr[i], then exprhead is :ref. Note that exprhead is different from operation and both functions should be defined correctly in order to let other packages provide code generation and pattern matching features. | ||
==# | ||
function TermInterface.exprhead(x::SymPyPythonCall.SymbolicObject) | ||
:call # this is not right | ||
end | ||
|
||
#== | ||
Returns the head (a function object) performed by an expression tree. Called only if istree(::T) is true. Part of the API required for simplify to work. Other required methods are arguments and istree | ||
==# | ||
function TermInterface.operation(x::SymPyPythonCall.SymbolicObject) | ||
@assert TermInterface.istree(x) | ||
nm = Symbol(SymPyPythonCall.Introspection.funcname(x)) | ||
|
||
λ = get(SymPyPythonCall.Introspection.funcname2function, nm, nothing) | ||
if isnothing(λ) | ||
return getfield(Main, nm) | ||
else | ||
return λ | ||
end | ||
end | ||
|
||
|
||
#== | ||
Returns the arguments (a Vector) for an expression tree. Called only if istree(x) is true. Part of the API required for simplify to work. Other required methods are operation and istree | ||
==# | ||
function TermInterface.arguments(x::SymPyPythonCall.SymbolicObject) | ||
collect(SymPyPythonCall.Introspection.args(x)) | ||
end | ||
|
||
#== | ||
Construct a new term with the operation f and arguments args, the term should be similar to t in type. if t is a SymbolicUtils.Term object a new Term is created with the same symtype as t. If not, the result is computed as f(args...). Defining this method for your term type will reduce any performance loss in performing f(args...) (esp. the splatting, and redundant type computation). T is the symtype of the output term. You can use SymbolicUtils.promote_symtype to infer this type. The exprhead keyword argument is useful when creating Exprs. | ||
==# | ||
function TermInterface.similarterm(t::SymPyPythonCall.SymbolicObject, f, args, symtype=nothing; | ||
metadata=nothing, exprhead=TermInterface.exprhead(t)) | ||
f(args...) # default | ||
end | ||
|
||
|
||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TermInterface was effectively deprecated. Doing this directly on the terms in SymbolicUtils would be more helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for that detail!