Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/workflows/BuildDocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@ jobs:
- uses: actions/checkout@v5
- uses: julia-actions/setup-julia@v2
with:
version: '1.6'
version: '1'
- name: Install dependencies
shell: julia --project=docs/ --color=yes {0}
run: |
using Pkg
Pkg.develop(PackageSpec(path=pwd()))
Pkg.instantiate()
run: using Pkg; Pkg.instantiate()
- name: Build Docs
run: julia --project=docs/ --color=yes docs/make.jl
- name: Deploy Documentation
Expand Down
3 changes: 3 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c"

[compat]
Documenter = "1"

[sources]
SymEngine = {path = ".."}
10 changes: 7 additions & 3 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
push!(LOAD_PATH,"../src/")

using Documenter, SymEngine

makedocs(sitename="Symengine Julia API Docs")
pages = [
"index.md",
"basicUsage.md",
"apidocs.md",
]

makedocs(sitename="Symengine Julia API Docs"; pages)
9 changes: 2 additions & 7 deletions docs/src/basicUsage.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SymEngine.jl
# Basic usage

Julia wrappers for [SymEngine](https://github.com/symengine/symengine), a fast symbolic manipulation library, written in C++.

Expand Down Expand Up @@ -344,7 +344,7 @@ If `TermInterface` is loaded (below), the `operation` method returns the outermo

The `Basic` type is a Julia type wrapping an underlying symengine object. When a Julia method is called on symbolic objects, the method almost always resolves to some call (via `ccall`) into the `libsymengine` C++ library. The design typically involves mutating a newly constructed `Basic` variable. Some allocations can be saved by calling the mutating version of the operations:

```
```julia
@vars x
a = Basic()
SymEngine.sin!(a, x)
Expand Down Expand Up @@ -394,8 +394,3 @@ replace_head(tan(sin(tan(x))), tan, cos)
## `SymEngine.jl` and symengine

This package only wraps those parts of symengine that are exposed through its [C wrapper](https://github.com/symengine/symengine/blob/master/symengine/cwrapper.cpp). The underlying C++ library has more functionality.


## License

`SymEngine.jl` is licensed under the MIT open source license.
6 changes: 5 additions & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ This site contains the documentation and `julia` language bindings for the [Syme
## Installation
The package and dependencies can be obtained with standard `Pkg` calls.

```julia
```julia-repl
julia> Pkg.add("SymEngine")
```

## License

`SymEngine.jl` is licensed under the MIT open source license.
2 changes: 2 additions & 0 deletions src/calculus.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ diff(ex::SymbolicType, bs::Tuple, ns::Tuple) =
diff(b1::SymbolicType, x::Union{String,Symbol}) = diff(b1, Basic(x))

"""
series(ex, x, x0=0, n=6)

Series expansion to order `n` about point `x0`
"""
function series(ex::SymbolicType, x::SymbolicType, x0=0, n::Union{Integer, Basic}=6)
Expand Down
2 changes: 1 addition & 1 deletion src/dense-matrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ LinearAlgebra.factorize(M::CDenseMatrix) = factorize(convert(Matrix, M))
"""
LU decomposition for CDenseMatrix, dense matrices of symbolic values

Also: lufact(a, val{:false}) for non-pivoting lu factorization
Also: `lufact(a, Val{:false})` for non-pivoting lu factorization
"""
function LinearAlgebra.lu(a::CDenseMatrix)
l, u = dense_matrix_LU(a)
Expand Down
6 changes: 5 additions & 1 deletion src/mathfuns.jl
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,11 @@ for (meth, libnm) in [(:nextprime,:nextprime)
eval(Expr(:export, meth))
end

"Return coefficient of `x^n` term, `x` a symbol"
"""
coeff!(a, b, x, n)

Return coefficient of `x^n` term, `x` a symbol
"""
function coeff!(a::Basic, b::Basic, x, n)
out = ccall((:basic_coeff, libsymengine), Nothing,
(Ref{Basic},Ref{Basic},Ref{Basic},Ref{Basic}),
Expand Down
2 changes: 2 additions & 0 deletions src/numerics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ end
##################################################
# N
"""
N(a)
N(Val(:Type), b::Basic)

Convert a SymEngine numeric value into a Julian number

Expand Down
17 changes: 11 additions & 6 deletions src/subs.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@


"""
subs
subs(ex, var, val)
subs(ex, d::AbstractDict)
subs(ex, y::Tuple)
subs(ex)

Substitute values into a symbolic expression.

Examples
```
### Examples

```julia
@vars x y
ex = x^2 + y^2
subs(ex, x, 1) # 1 + y^2
Expand Down Expand Up @@ -126,8 +130,9 @@ end
walk_expression(b) = convert(Expr, b)

"""
lambdify
evaluates a symbolless expression or returns a function
lambdify(ex, vars=[]; cse=false)

Evaluates a symbol-less expression or returns a function
"""
function lambdify(ex, vars=[])
if length(vars) == 0
Expand Down Expand Up @@ -170,7 +175,7 @@ end
function _lambdify(ex::Expr, vars)
try
fn = eval(Expr(:function,
Expr(:call, gensym(), map(Symbol,vars)...),
Expr(:call, gensym(), map(Symbol,vars)...),
ex))
(args...) -> invokelatest(fn, args...) # https://github.com/JuliaLang/julia/pull/19784
catch err
Expand Down
59 changes: 47 additions & 12 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ const symengine_classes = _get_symengine_classes()
const symengine_classes_val = [Val(c) for c in SymEngine.symengine_classes]
const symengine_classes_val_type = [Val{c} for c in SymEngine.symengine_classes]

"Get SymEngine class of an object (e.g. 1=>:Integer, 1//2 =:Rational, sin(x) => :Sin, ..."
"""
get_symengine_class(s)

Get SymEngine class of an object `s`.
(e.g. `1=>:Integer`, `1//2 =>:Rational`, `sin(x) => :Sin`, ...)
"""
get_symengine_class(s::Basic) = symengine_classes[get_type(s) + 1]
get_symengine_class_val(s::Basic) = symengine_classes_val[get_type(s) + 1]
get_symengine_class_val_type(s::Basic) = symengine_classes_val_type[get_type(s) + 1]
Expand All @@ -128,11 +133,13 @@ _symbol(s::Symbol) = _symbol(string(s))

## use SymPy name here, but no assumptions
"""
symbols(::Symbol)

`symbols(::Symbol)` construct symbolic value
Construct symbolic value.

Examples:
```
### Examples

```julia
a = symbols(:a)
x = symbols("x")
x,y = symbols("x y")
Expand All @@ -156,7 +163,7 @@ end

Macro to define 1 or more variables or symbolic function

Example
### Examples
```
@vars x y z
@vars x[1:4]
Expand Down Expand Up @@ -255,28 +262,44 @@ BasicTrigFunction = Union{[SymEngine.BasicType{Val{i}} for i in trig_types]...}

###

"Is expression constant"
"""
is_constant(ex)

Is expression constant
"""
function is_constant(ex::Basic)
syms = CSetBasic()
ccall((:basic_free_symbols, libsymengine), Nothing, (Ref{Basic}, Ptr{Cvoid}), ex, syms.ptr)
Base.length(syms) == 0
end

"Is expression a symbol"
"""
is_symbol(x::)

Is expression a symbol
"""
function is_symbol(x::SymbolicType)
res = ccall((:is_a_Symbol, libsymengine), Cuint, (Ref{Basic},), x)
Bool(convert(Int,res))
end

"Does expression contain the symbol"
"""
has_symbol(ex, x)

Does expression `ex` contain the symbol `x`
"""
function has_symbol(ex::SymbolicType, x::SymbolicType)
is_symbol(x) || throw(ArgumentError("Not a symbol"))
res = ccall((:basic_has_symbol, libsymengine), Cuint, (Ref{Basic},Ref{Basic}), ex, x)
Bool(convert(Int, res))
end


" Return free symbols in an expression as a `Set`"
"""
free_symbols(ex)

Return free symbols in an expression `ex` as a `Set`
"""
function free_symbols(ex::Basic)
syms = CSetBasic()
free_symbols!(syms, ex)
Expand All @@ -294,7 +317,11 @@ _flat(A) = mapreduce(x->isa(x,Array) ? _flat(x) : x, vcat, A, init=Basic[]) # f
free_symbols(exs::Array{T}) where {T<:SymbolicType} = unique(_flat([free_symbols(ex) for ex in exs]))
free_symbols(exs::Tuple) = unique(_flat([free_symbols(ex) for ex in exs]))

"Return function symbols in an expression as a `Set`"
"""
function_symbols(ex)

Return function symbols in an expression `ex` as a `Set`
"""
function function_symbols(ex::Basic)
syms = CSetBasic()
function_symbols!(syms, ex)
Expand All @@ -309,15 +336,23 @@ function_symbols(ex::BasicType) = function_symbols(Basic(ex))
function_symbols(exs::Array{T}) where {T<:SymbolicType} = unique(_flat([function_symbols(ex) for ex in exs]))
function_symbols(exs::Tuple) = unique(_flat([function_symbols(ex) for ex in exs]))

"Return name of function symbol"
"""
get_name(ex)

Return name of function symbol
"""
function get_name(ex::Basic)
a = ccall((:function_symbol_get_name, libsymengine), Cstring, (Ref{Basic}, ), ex)
string = unsafe_string(a)
ccall((:basic_str_free, libsymengine), Nothing, (Cstring, ), a)
return string
end

"Return arguments of a function call as a vector of `Basic` objects"
"""
get_args(ex)

Return arguments of a function call as a vector of `Basic` objects
"""
function get_args(ex::Basic)
args = CVecBasic()
get_args!(args, ex)
Expand Down
18 changes: 15 additions & 3 deletions src/utils.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
"Helper function to lookup a symbol from libsymengine"
"""
get_symbol(sym)

Helper function to lookup a symbol from libsymengine
"""
function get_symbol(sym::Symbol)
handle = Libdl.dlopen_e(libsymengine)
if handle == C_NULL
Expand All @@ -8,7 +12,11 @@ function get_symbol(sym::Symbol)
end
end

"Get libsymengine version"
"""
get_libversion()

Get libsymengine version
"""
function get_libversion()
func = get_symbol(:symengine_version)
if func != C_NULL
Expand All @@ -20,7 +28,11 @@ function get_libversion()
end
end

"Check whether libsymengine was compiled with comp"
"""
have_component(comp::String)

Check whether libsymengine was compiled with component `comp`
"""
function have_component(comp::String)
func = get_symbol(:symengine_have_component)
if func != C_NULL
Expand Down
Loading