diff --git a/.github/workflows/BuildDocs.yml b/.github/workflows/BuildDocs.yml index 9e93f1c..903ece1 100644 --- a/.github/workflows/BuildDocs.yml +++ b/.github/workflows/BuildDocs.yml @@ -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 diff --git a/docs/Project.toml b/docs/Project.toml index 776a9bb..f3befe7 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -6,3 +6,6 @@ TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c" [compat] Documenter = "1" + +[sources] +SymEngine = {path = ".."} diff --git a/docs/make.jl b/docs/make.jl index d7b05e6..53301fa 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -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) diff --git a/docs/src/basicUsage.md b/docs/src/basicUsage.md index 7bf7d3f..ac25525 100644 --- a/docs/src/basicUsage.md +++ b/docs/src/basicUsage.md @@ -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++. @@ -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) @@ -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. diff --git a/docs/src/index.md b/docs/src/index.md index b340a79..d14cb9d 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -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. diff --git a/src/calculus.jl b/src/calculus.jl index 837188d..f930635 100644 --- a/src/calculus.jl +++ b/src/calculus.jl @@ -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) diff --git a/src/dense-matrix.jl b/src/dense-matrix.jl index b7de976..48de660 100644 --- a/src/dense-matrix.jl +++ b/src/dense-matrix.jl @@ -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) diff --git a/src/mathfuns.jl b/src/mathfuns.jl index b282480..06bbb3a 100644 --- a/src/mathfuns.jl +++ b/src/mathfuns.jl @@ -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}), diff --git a/src/numerics.jl b/src/numerics.jl index 74ea3a3..af1cda6 100644 --- a/src/numerics.jl +++ b/src/numerics.jl @@ -55,6 +55,8 @@ end ################################################## # N """ + N(a) + N(Val(:Type), b::Basic) Convert a SymEngine numeric value into a Julian number diff --git a/src/subs.jl b/src/subs.jl index 0d4d39e..2689cf0 100644 --- a/src/subs.jl +++ b/src/subs.jl @@ -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 @@ -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 @@ -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 diff --git a/src/types.jl b/src/types.jl index 86c6fb2..f9fb92d 100644 --- a/src/types.jl +++ b/src/types.jl @@ -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] @@ -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") @@ -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] @@ -255,20 +262,32 @@ 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) @@ -276,7 +295,11 @@ function has_symbol(ex::SymbolicType, x::SymbolicType) 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) @@ -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) @@ -309,7 +336,11 @@ 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) @@ -317,7 +348,11 @@ function get_name(ex::Basic) 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) diff --git a/src/utils.jl b/src/utils.jl index 1f17287..ba88e53 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -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 @@ -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 @@ -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