## `subs` -- substitute into an object

#### Introduction

`subs(`f, old = new`)` returns a copy of the object `f` in which all operands matching `old` are replaced by the value `new`.

#### Call(s)

`subs(f, old = new <, Unsimplified>)`
`subs(f, old1 = new1, old2 = new2... <, Unsimplified>)`
`subs(f, [old1 = new1, old2 = new2...] <, Unsimplified>)`
`subs(f, {old1 = new1, old2 = new2...} <, Unsimplified>)`
`subs(f, table(old1 = new1, old2 = new2...) <, Unsimplified>)`
`subs(f, s1, s2... <, Unsimplified>)`

#### Parameters

`f` | - | an arbitrary MuPAD object
`old, old1, old2, ...` | - | arbitrary MuPAD objects
`new, new1, new2, ...` | - | arbitrary MuPAD objects
`s1, s2, ...` | - | either equations `old = new`, or lists or sets of such equations, or tables whose entries are interpreted as such equations.

#### Options

`Unsimplified` | - | prevents simplification of the returned object after substitution

#### Returns

a copy of the input object with replaced operands.

### Overloadable:

`f`

#### Related Functions

`extnops`, `extop`, `extsubsop`, `has`, `map`, `match`, `op`, `subsex`, `subsop`

#### Details

- `subs` returns a modified copy of the object, but does not change the object itself.
- `subs(`f, old = new`)` searches `f` for operands matching `old`. Each such operand is replaced by `new`. Cf. example 1.
- The call `subs(`f, old1 = new1, old2 = new2, ...`)` invokes a ``sequential substitution'': the specified substitutions are processed in sequence from left to right. Each substitution is carried out and the result is processed further with the next substitution. Cf. example 3.
- The call `subs(`f, [old1 = new1, old2 = new2, ...]`)` invokes a ``parallel substitution''; each substitution refers to the operands of the original input object `f`, not to the operands of ``intermediate results'' produced by previous substitutions. If multiple substitutions of an operand are specified, only the first one is carried out. Parallel substitution is also invoked when the substitutions are specified by sets or tables. Cf. example 4.
- The call `subs(`f, s1, s2, ...`)` describes the most general form of substitution which may combine sequential and parallel substitutions. This call is equivalent to `subs(... subs(subs(f, s1), s2), ...)`. Depending on the form of `s1`, `s2`, ..., sequential or parallel substitutions as described above are carried out in each step. Cf. example 5.
- Only operands accessible via the function `op` are replaced (``syntactical substitution''). A more ``semantical'' substitution is available with the function `subsex`, which also identifies and replaces partial sums and products. Cf. example 6.
- After substitution, the result is not evaluated. Use the function `eval` to enforce evaluation. Cf. example 7.
- Operands of expression sequences can be replaced by `subs`. Such objects are not flattened. Cf. example 8.
- The call `subs(`f`)` is allowed; it returns `f` without modifications.
- `subs` is a function of the system kernel.

#### Option: Unsimplified

- As the last step of a substitution, the modified object is simplified (however, not evaluated). This option suppresses this final simplification. Cf. example 9.

#### Example 1

We demonstrate some simple substitutions:

    >> subs(a + b*a, a = 4)

                                      4 b + 4

    >> subs([a * (b + c), sin(b +c)], b + c = a)

                                     2
                                   [a , sin(a)]

#### Example 2

To replace the sine function in an expression, one has to prevent the evaluation of the identifier `sin` via `hold`. Otherwise, `sin` is replaced by its value, i.e., by the function environment defining the system's sine function. Inside the expression `sin(x)`, the 0-th operand `sin` is the identifier, not the function environment:

    >> domtype(sin), domtype(hold(sin)), domtype(op(sin(x), 0));

                        DOM_FUNC_ENV, DOM_IDENT, DOM_IDENT

    >> subs(sin(x), sin = cos), subs(sin(x), hold(sin) = cos)

                                  sin(x), cos(x)

#### Example 3

The following call leads to a sequential substitution `x` -> `y` -> `z`:

    >> subs(x^3 + y*z, x = y, y = z)

                                       2    3
                                      z  + z

#### Example 4

We demonstrate the difference between sequential and parallel substitutions. Sequential substitutions produce the following results:

    >> subs(a^2 + b^3, a = b, b = a)

                                       2    3
                                      a  + a

    >> subs(a^2 + b^3, b = a, a = b)

                                       2    3
                                      b  + b

In contrast to this, parallel substitution swaps the identifiers:

    >> subs(a^2 + b^3, [a = b, b = a])

                                       3    2
                                      a  + b

In the following call, substitution of `y + x` for `a` yields the intermediate result `y + 2*x`. From there, substitution of `z` for `x` yields `y + 2 z`:

    >> subs(a + x, a = x + y, x = z)

                                      y + 2 z

Parallel substitution produces a different result. In the next call, `x + y` is substituted for `a`. Simultaneously, the operand `x` of the original expression `a + x` is replaced by `z`:

    >> subs(a + x, [a = x + y, x = z])

                                     x + y + z

The same happens when the substitutions are specified by a set of equations:

    >> subs(a + x, {a = x + y, x = z})

                                     x + y + z

Further, parallel substitution is used when specifying the substitutions by a table:

    >> T := table(): T[a] := x + y: T[x] := z: T

                                    table(
                                      x = z,
                                      a = x + y
                                    )

    >> subs(a + x, T)

                                     x + y + z

    >> delete T:

#### Example 5

We combine sequential and parallel substitutions:

    >> subs(a + x, {a = x + y, x = z}, x = y)

                                      2 y + z

#### Example 6

Only operands found by `op` are replaced. The following expression contains the subexpression `x + y` as the operand `op(f, [1, 2])`:

    >> f := sin(z*(x + y)): op(f, [1, 2]);

                                       x + y

Consequently, this subexpression can be replaced:

    >> subs(f, x + y = z)

                                           2
                                      sin(z )

Syntactically, the following sum does not contain the subexpression `x + y`. Consequently, it is not replaced by the following call:

    >> subs(x + y + z, x + y = z)

                                     x + y + z

In contrast to `subs`, the function `subsex` finds and replaces partial sums and products:

    >> subsex(x + y + z, x + y = z)

                                        2 z

    >> subs(a*b*c, a*c = 5), subsex(a*b*c, a*c = 5)

                                    a b c, 5 b

    >> delete f:

#### Example 7

The result of `subs` is not evaluated. In the following call, the identifier `sin` is not replaced by its value, i.e., by the procedure defining the behavior of the system's sine function. Consequently, `sin(PI)` is not simplified to 0 by this procedure:

    >> subs(sin(x), x = PI)

                                      sin(PI)

The function `eval` enforces evaluation:

    >> eval(subs(sin(x), x = PI))

                                         0

#### Example 8

Operands of expression sequences can be subtituted. Note that sequences need to be enclosed in brackets:

    >> subs((a, b, a*b), a = x)

                                     x, b, b x

#### Example 9

The option Unsimplified suppresses simplification:

    >> subs(a + b + 2, a = 1, b = 0, Unsimplified)

                                     1 + 0 + 2

#### Example 10

If we try to substitute something in a domain, the substitution is ignored. We define a new domain with the methods `"foo"` and `"bar"`:

    >> mydomain := newDomain("Test"):
       mydomain::foo := x -> 4*x:
       mydomain::bar := x -> 4*x^2:

Now we try to replace every 4 inside the domain by 3:

    >> mydomain := subs(mydomain, 4 = 3):

However, this substitution did not have any effect:

    >> mydomain::foo(x), mydomain::bar(x)

                                             2
                                     4 x, 4 x

To substitute objects in a domain method, we have to substitute in the individual methods:

    >> mydomain::foo := subs(mydomain::foo, 4 = 3):
       mydomain::bar := subs(mydomain::bar, 4 = 3):
       mydomain::foo(x), mydomain::bar(x)

                                             2
                                     3 x, 3 x

    >> delete mydomain:

#### Changes

- `subs` does not longer substitute inside domains. Cf. example 10.

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000