octave:5> pkg load symbolic octave:6> syms x z Symbolic pkg v3.0.1: Python communication link active, SymPy v1.11.1. octave:7> syms Symbolic variables in current scope: x z octave:8> x x = (sym) x octave:9> syms x_0 octave:10> xu-0 error: 'xu' undefined near line 1, column 1 octave:11> x_0 x_0 = (sym) x₀ octave:12> v = x + 2 v = (sym) x + 2 octave:13> w = x * z w = (sym) x⋅z octave:14> help subs error: help: 'subs' not found octave:15> help @sym/subs '@sym/subs' is a function from the file /usr/share/octave/packages/symbolic-3.0.1/@sym /subs.m -- Method on @sym: subs (F, X, Y) -- Method on @sym: subs (F, Y) -- Method on @sym: subs (F) Replace symbols in an expression with other expressions. Example substituting a value for a variable: syms x y f = x*y; subs(f, x, 2) ⇒ ans = (sym) 2⋅y If X is omitted, ‘symvar’ is called on F to determine an appropriate variable. X and Y can also be vectors or lists of syms to replace: subs(f, {x y}, {sin(x) 16}) ⇒ ans = (sym) 16⋅sin(x) F = [x x*y; 2*x*y y]; subs(F, {x y}, [2 sym(pi)]) ⇒ ans = (sym 2×2 matrix) ⎡ 2 2⋅π⎤ ⎢ ⎥ ⎣4⋅π π ⎦ With only one argument, ‘subs(F)’ will attempt to find values for each symbol in F by searching the workspace: f = x*y ⇒ f = (sym) x⋅y x = 42; f ⇒ f = (sym) x⋅y Here assigning a numerical value to the variable ‘x’ did not change the expression (because symbols are not the same as variables!) However, we can automatically update ‘f’ by calling: subs(f) ⇒ ans = (sym) 42⋅y *Warning*: ‘subs’ cannot be easily used to substitute a ‘double’ matrix; it will cast Y to a ‘sym’. Instead, create a “function handle” from the symbolic expression, which can be efficiently evaluated numerically. For example: syms x f = exp(sin(x)) ⇒ f = (sym) sin(x) ℯ fh = function_handle(f) ⇒ fh = @(x) exp (sin (x)) fh(linspace(0, 2*pi, 700)') ⇒ ans = 1.0000 1.0090 1.0181 1.0273 1.0366 ... *Note*: Mixing scalars and matrices may lead to trouble. We support the case of substituting one or more symbolic matrices in for symbolic scalars, within a scalar expression: f = sin(x); g = subs(f, x, [1 sym('a'); pi sym('b')]) ⇒ g = (sym 2×2 matrix) ⎡sin(1) sin(a)⎤ ⎢ ⎥ ⎣ 0 sin(b)⎦ When using multiple variables and matrix substitions, it may be helpful to use cell arrays: subs(y*sin(x), {x, y}, {3, [2 sym('a')]}) ⇒ ans = (sym) [2⋅sin(3) a⋅sin(3)] (1×2 matrix) subs(y*sin(x), {x, y}, {[2 3], [2 sym('a')]}) ⇒ ans = (sym) [2⋅sin(2) a⋅sin(3)] (1×2 matrix) *Caution*, multiple interdependent substitutions can be ambiguous and results may depend on the order in which you specify them. A cautionary example: syms y(x) A B u = y + diff(y, x) ⇒ u(x) = (symfun) d y(x) + ──(y(x)) dx subs(u, {y, diff(y, x)}, {A, B}) ⇒ ans = (sym) A subs(u, {diff(y, x), y}, {B, A}) ⇒ ans = (sym) A + B Here it would be clearer to explicitly avoid the ambiguity by calling ‘subs’ twice: subs(subs(u, diff(y, x), B), y, A) ⇒ ans = (sym) A + B See also: @sym/symfun. Additional help for built-in functions and operators is available in the online version of the manual. Use the command 'doc ' to search the manual index. Help and information about Octave is also available on the WWW at https://www.octave.org and via the help@octave.org mailing list. octave:16> syms r octave:17> w w = (sym) x⋅z octave:18> subs(w, z, r) ans = (sym) r⋅x octave:19> solve(x + 3 == 5, x) ans = (sym) 2 octave:20> octave:20> syms a b c octave:21> solve(a*x^2 + b*x + c, x) ans = (sym 2×1 matrix) ⎡ _____________⎤ ⎢ ╱ 2 ⎥ ⎢ b ╲╱ -4⋅a⋅c + b ⎥ ⎢- ─── - ────────────────⎥ ⎢ 2⋅a 2⋅a ⎥ ⎢ ⎥ ⎢ _____________⎥ ⎢ ╱ 2 ⎥ ⎢ b ╲╱ -4⋅a⋅c + b ⎥ ⎢- ─── + ────────────────⎥ ⎣ 2⋅a 2⋅a ⎦ octave:22> help @sym/solve '@sym/solve' is a function from the file /usr/share/octave/packages/symbolic-3.0.1/@sy m/solve.m -- Method on @sym: SOL = solve (EQN) -- Method on @sym: SOL = solve (EQN, VAR) -- Method on @sym: SOL = solve (EQN1, ..., EQNN) -- Method on @sym: SOL = solve (EQN1, ..., EQNN, VAR1, ..., VARM) -- Method on @sym: SOL = solve (EQNS, VARS) -- Method on @sym: [S1, ..., SN] = solve (EQNS, VARS) Symbolic solutions of equations, inequalities and systems. Examples syms x solve(x == 2*x + 6, x) ⇒ ans = (sym) -6 solve(x^2 + 6 == 5*x, x); sort(ans) ⇒ ans = (sym 2×1 matrix) ⎡2⎤ ⎢ ⎥ ⎣3⎦ Sometimes its helpful to assume an unknown is real: syms x real solve(abs(x) == 1, x); sort(ans) ⇒ ans = (sym 2×1 matrix) ⎡-1⎤ ⎢ ⎥ ⎣1 ⎦ In general, the output will be a list of dictionaries. Each entry of the list is one a solution, and the variables that make up that solutions are keys of the dictionary (fieldnames of the struct). syms x y d = solve(x^2 == 4, x + y == 1); % the first solution d{1}.x ⇒ (sym) -2 d{1}.y ⇒ (sym) 3 % the second solution d{2}.x ⇒ (sym) 2 d{2}.y ⇒ (sym) -1 But there are various special cases for the output (single versus multiple variables, single versus multiple solutions, etc). FIXME: provide a ’raw_output’ argument or something to always give the general output. Alternatively: [X, Y] = solve(x^2 == 4, x + y == 1, x, y) ⇒ X = (sym 2×1 matrix) ⎡-2⎤ ⎢ ⎥ ⎣2 ⎦ ⇒ Y = (sym 2×1 matrix) ⎡3 ⎤ ⎢ ⎥ ⎣-1⎦ You can solve inequalities and systems involving mixed inequalities and equations. For example: solve(x^2 == 4, x > 0) ⇒ ans = (sym) x = 2 syms x solve(x^2 - 1 > 0, x < 10) ⇒ ans = (sym) (-∞ < x ∧ x < -1) ∨ (1 < x ∧ x < 10) See also: @sym/eq, @sym/dsolve. Additional help for built-in functions and operators is available in the online version of the manual. Use the command 'doc ' to search the manual index. Help and information about Octave is also available on the WWW at https://www.octave.org and via the help@octave.org mailing list. octave:23> eqs = [x + z == 14; x - z == 6] :7: SymPyDeprecationWarning: non-Expr objects in a Matrix is deprecated. Matrix represents a mathematical matrix. To represent a container of non-numeric entities, Use a list of lists, TableForm, NumPy array, or some other data structure instead. See https://docs.sympy.org/latest/explanation/active-deprecations.html#deprecated-non- expr-in-matrix for details. This has been deprecated since SymPy version 1.9. It will be removed in a future version of SymPy. eqs = (sym 2×1 matrix) ⎡x + z = 14⎤ ⎢ ⎥ ⎣x - z = 6 ⎦ octave:24> soln = solve(eqs, [x z]) soln = scalar structure containing the fields: x = z = octave:25> soln.x ans = (sym) 10 octave:26> soln.z ans = (sym) 4 octave:27> help subs error: help: 'subs' not found octave:28> help @sym/subs '@sym/subs' is a function from the file /usr/share/octave/packages/symbolic-3.0.1/@sym /subs.m -- Method on @sym: subs (F, X, Y) -- Method on @sym: subs (F, Y) -- Method on @sym: subs (F) Replace symbols in an expression with other expressions. Example substituting a value for a variable: syms x y f = x*y; subs(f, x, 2) ⇒ ans = (sym) 2⋅y If X is omitted, ‘symvar’ is called on F to determine an appropriate variable. X and Y can also be vectors or lists of syms to replace: subs(f, {x y}, {sin(x) 16}) ⇒ ans = (sym) 16⋅sin(x) F = [x x*y; 2*x*y y]; subs(F, {x y}, [2 sym(pi)]) ⇒ ans = (sym 2×2 matrix) ⎡ 2 2⋅π⎤ ⎢ ⎥ ⎣4⋅π π ⎦ With only one argument, ‘subs(F)’ will attempt to find values for each symbol in F by searching the workspace: f = x*y ⇒ f = (sym) x⋅y x = 42; f ⇒ f = (sym) x⋅y Here assigning a numerical value to the variable ‘x’ did not change the expression (because symbols are not the same as variables!) However, we can automatically update ‘f’ by calling: subs(f) ⇒ ans = (sym) 42⋅y *Warning*: ‘subs’ cannot be easily used to substitute a ‘double’ matrix; it will cast Y to a ‘sym’. Instead, create a “function handle” from the symbolic expression, which can be efficiently evaluated numerically. For example: syms x f = exp(sin(x)) ⇒ f = (sym) sin(x) ℯ fh = function_handle(f) ⇒ fh = @(x) exp (sin (x)) fh(linspace(0, 2*pi, 700)') ⇒ ans = 1.0000 1.0090 1.0181 1.0273 1.0366 ... *Note*: Mixing scalars and matrices may lead to trouble. We support the case of substituting one or more symbolic matrices in for symbolic scalars, within a scalar expression: f = sin(x); g = subs(f, x, [1 sym('a'); pi sym('b')]) ⇒ g = (sym 2×2 matrix) ⎡sin(1) sin(a)⎤ ⎢ ⎥ ⎣ 0 sin(b)⎦ When using multiple variables and matrix substitions, it may be helpful to use cell arrays: subs(y*sin(x), {x, y}, {3, [2 sym('a')]}) ⇒ ans = (sym) [2⋅sin(3) a⋅sin(3)] (1×2 matrix) subs(y*sin(x), {x, y}, {[2 3], [2 sym('a')]}) ⇒ ans = (sym) [2⋅sin(2) a⋅sin(3)] (1×2 matrix) *Caution*, multiple interdependent substitutions can be ambiguous and results may depend on the order in which you specify them. A cautionary example: syms y(x) A B u = y + diff(y, x) ⇒ u(x) = (symfun) d y(x) + ──(y(x)) dx subs(u, {y, diff(y, x)}, {A, B}) ⇒ ans = (sym) A subs(u, {diff(y, x), y}, {B, A}) ⇒ ans = (sym) A + B Here it would be clearer to explicitly avoid the ambiguity by calling ‘subs’ twice: subs(subs(u, diff(y, x), B), y, A) ⇒ ans = (sym) A + B See also: @sym/symfun. Additional help for built-in functions and operators is available in the online version of the manual. Use the command 'doc ' to search the manual index. Help and information about Octave is also available on the WWW at https://www.octave.org and via the help@octave.org mailing list. octave:29> eqn(1) error: 'eqn' undefined near line 1, column 1 octave:30> eqs(1) ans = (sym) x + z = 14 octave:31> subs(eqs(1), {x, z}, {soln.x, soln.z}) ans = (sym) True octave:32> syms n octave:33> solve(n^2 == 4, n) ans = (sym 2×1 matrix) ⎡-2⎤ ⎢ ⎥ ⎣2 ⎦ octave:34> assume n positive octave:35> assumptions ans = { [1,1] = n: positive } octave:36> solve(n^2 == 4, n) ans = (sym) 2 octave:37> assume n error: assume: general algebraic assumptions are not supported error: called from assert at line 109 column 11 assume at line 65 column 3 octave:38> syms n octave:39> assumptions ans = {}(0x0) octave:40> help @sym/assume '@sym/assume' is a function from the file /usr/share/octave/packages/symbolic-3.0.1/@s ym/assume.m -- Method on @sym: X = assume (X, COND, COND2, ...) -- Method on @sym: X = assume (X, 'clear') -- Method on @sym: [X, Y] = assume ([X Y], ...) -- Method on @sym: assume (X, COND, COND2, ...) -- Method on @sym: assume (X, 'clear') -- Method on @sym: assume ([X Y], ...) New assumptions on a symbolic variable (replace old if any). This function has two different behaviours depending on whether it has an output argument or not. The first form is simpler; it returns a new sym with assumptions given by COND, for example: syms x x1 = x; x = assume(x, 'positive'); assumptions(x) ⇒ ans = { [1,1] = x: positive } assumptions(x1) % empty, x1 still has the original x ⇒ ans = {}(0x0) Another example to help clarify: x1 = sym('x', 'positive') ⇒ x1 = (sym) x x2 = assume(x1, 'negative') ⇒ x2 = (sym) x assumptions(x1) ⇒ ans = { [1,1] = x: positive } assumptions(x2) ⇒ ans = { [1,1] = x: negative } The second form—with no output argument—is different; it attempts to find *all* instances of symbols with the same name as X and replace them with the new version (with COND assumptions). For example: syms x x1 = x; f = sin(x); assume(x, 'positive'); assumptions(x) ⇒ ans = { [1,1] = x: positive } assumptions(x1) ⇒ ans = { [1,1] = x: positive } assumptions(f) ⇒ ans = { [1,1] = x: positive } To clear assumptions on a variable use ‘assume(x, 'clear')’, for example: syms x positive f = sin (x); assume (x, 'clear') isempty (assumptions (f)) ⇒ ans = 1 *Warning*: the second form operates on the caller’s workspace via evalin/assignin. So if you call this from other functions, it will operate in your function’s workspace (and not the ‘base’ workspace). This behaviour is for compatibility with other symbolic toolboxes. FIXME: idea of rewriting all sym vars is a bit of a hack, not well tested (for example, with global vars.) See also: @sym/assumeAlso, assume, assumptions, sym, syms. Additional help for built-in functions and operators is available in the online version of the manual. Use the command 'doc ' to search the manual index. Help and information about Octave is also available on the WWW at https://www.octave.org and via the help@octave.org mailing list. octave:41> assume n positive octave:42> assumptions ans = { [1,1] = n: positive } octave:43> assume n clear octave:44> assumptions ans = {}(0x0) octave:45> exp(log(x)) ans = (sym) x octave:46> e^(log(x)) ans = (sym) x octave:47> x + 3 ans = (sym) x + 3 octave:48> (x + 3)*(1/x + 3) ans = (sym) ⎛ 1⎞ ⎜3 + ─⎟⋅(x + 3) ⎝ x⎠ octave:49> (x + 3)*(1/(x + 3)) ans = (sym) 1 octave:50> help @sym/simplify '@sym/simplify' is a function from the file /usr/share/octave/packages/symbolic-3.0.1/ @sym/simplify.m -- Method on @sym: simplify (X) Simplify an expression. Example: syms x p = x^2 + x + 1 ⇒ p = (sym) 2 x + x + 1 q = horner (p) ⇒ q = (sym) x⋅(x + 1) + 1 d = p - q ⇒ d = (sym) 2 x - x⋅(x + 1) + x isAlways(p == q) ⇒ 1 simplify(p - q) ⇒ (sym) 0 Please note that ‘simplify’ is not a well-defined mathematical operation: its precise behaviour can change between software versions (and certainly between different software packages!) See also: @sym/isAlways, @sym/factor, @sym/expand, @sym/rewrite. Additional help for built-in functions and operators is available in the online version of the manual. Use the command 'doc ' to search the manual index. Help and information about Octave is also available on the WWW at https://www.octave.org and via the help@octave.org mailing list. octave:51> (x + 3)^2 + (x + 3) + (x + 3)^2 ans = (sym) 2 x + 2⋅(x + 3) + 3 octave:52> simplify((x + 3)^2 + (x + 3) + (x + 3)^2) ans = (sym) 2 x + 2⋅(x + 3) + 3 octave:53> expand((x + 3)^2 + (x + 3) + (x + 3)^2) ans = (sym) 2 2⋅x + 13⋅x + 21 octave:54> collect((x + 3)^2 + (x + 3) + (x + 3)^2) error: 'collect' undefined near line 1, column 1 octave:55> combine error: 'combine' undefined near line 1, column 1 octave:56> factor error: Invalid call to factor. Correct usage is: -- PF = factor (Q) -- [PF, N] = factor (Q) Additional help for built-in functions and operators is available in the online version of the manual. Use the command 'doc ' to search the manual index. Help and information about Octave is also available on the WWW at https://www.octave.org and via the help@octave.org mailing list. octave:57> expand((x + 3)^2 + (x + 3) + (x + 3)^2) ans = (sym) 2 2⋅x + 13⋅x + 21 octave:58> factor(ans) ans = (sym) (x + 3)⋅(2⋅x + 7) octave:59> partfrac error: 'partfrac' undefined near line 1, column 1 octave:60> help @sym/partfrac '@sym/partfrac' is a function from the file /usr/share/octave/packages/symbolic-3.0.1/ @sym/partfrac.m -- Method on @sym: partfrac (F) -- Method on @sym: partfrac (F, X) Compute partial fraction decomposition of a rational function. Examples: syms x f = 2/(x + 4)/(x + 1) ⇒ f = (sym) 2 ─────────────── (x + 1)⋅(x + 4) partfrac(f) ⇒ ans = (sym) 2 2 - ───────── + ───────── 3⋅(x + 4) 3⋅(x + 1) Other examples: syms x y partfrac(y/(x + y)/(x + 1), x) ⇒ ans = (sym) y y - ─────────────── + ─────────────── (x + y)⋅(y - 1) (x + 1)⋅(y - 1) partfrac(y/(x + y)/(x + 1), y) ⇒ ans = (sym) x 1 - ─────────────── + ───── (x + 1)⋅(x + y) x + 1 See also: @sym/factor. Additional help for built-in functions and operators is available in the online version of the manual. Use the command 'doc ' to search the manual index. Help and information about Octave is also available on the WWW at https://www.octave.org and via the help@octave.org mailing list. octave:61> octave:61> octave:61> octave:61> octave:61> octave:61> partfrac((x^7+x^2)/(x^3 - 3*x + 2)) ans = (sym) 4 2 124 25 2 x + 3⋅x - 2⋅x + 9 - ───────── + ───────── + ────────── 9⋅(x + 2) 9⋅(x - 1) 2 3⋅(x - 1) octave:62> (x^7+x^2)/(x^3 - 3*x + 2) ans = (sym) 7 2 x + x ──────────── 3 x - 3⋅x + 2 octave:63> p = [1 2 3 4] p = 1 2 3 4 octave:64> poly2sim(p, x) error: 'poly2sim' undefined near line 1, column 1 octave:65> syms f(y) octave:66> syms Symbolic variables in current scope: a ans b c eqs f (symfun) n r v w x x_0 y z octave:67> f f(y) = (symfun) f(y) octave:68> f(y) = y^2 f(y) = (symfun) 2 y octave:69> f f(y) = (symfun) 2 y octave:70> finverse error: 'finverse' undefined near line 1, column 1 The 'finverse' function belongs to the symbolic package from Octave Forge but has not yet been implemented. Please read to learn how you can contribute missing functionality. octave:71> syms t octave:72> int(1/t, 1, x) ans = (sym) log(x) octave:73> int(1/t, .5, x) warning: passing floating-point values to sym is dangerous, see "help sym" warning: called from double_to_sym_heuristic at line 50 column 7 sym at line 379 column 13 int at line 138 column 7 ans = (sym) log(x) + log(2) octave:74> x^2 ans = (sym) 2 x octave:75> x^2 + 5 ans = (sym) 2 x + 5 octave:76> diff(x^2 + 5) ans = (sym) 2⋅x octave:77> diff(x^2 + z^3 + 5) ans = (sym) 2⋅x octave:78> diff(x^2 + z^3 + 5, z) ans = (sym) 2 3⋅z octave:79> syms y(t) a octave:80> diff(y) == a*y ans = (sym) d ──(y(t)) = a⋅y(t) dt octave:81> dsolve(diff(y) == a*y, t) error: Python exception: AttributeError: 'Symbol' object has no attribute 'lhs' occurred at line 7 of the Python code block: ics = {ics.lhs: ics.rhs} error: called from pycall_sympy__ at line 179 column 7 dsolve at line 198 column 8 octave:82> dirac(x) ans = (sym) δ(x) octave:83> laplace(dirac(x)) ans = (sym) 1 octave:84> laplace(dirac(x - 1)) ans = (sym) -s ℯ octave:85> (1:5)(2) ans = 2 octave:86>