## `+` -- add expressions

#### Introduction

`x + y + ...` computes the sum of `x`, `y` etc.

#### Call(s)

x + y + ... `_plus(x, y...)`

#### Parameters

`x, y, ...` | - | arithmetical expressions, polynomials of type `DOM_POLY`, or sets

#### Returns

an arithmetical expression, a polynomial, or a set.

### Overloadable:

`x`, `y`, ``, `...`

#### Related Functions

`_invert`, `_negate`, `^`, `/`, `*`, `-`, `poly`, `sum`, `Pref::keepOrder`

#### Details

- `x + y + ...` is equivalent to the function call `_plus(x, y, ...)`.
- All terms that are numbers of type `Type::Numeric` are automatically combined to a single number.
- Terms of a symbolic sum may be rearranged internally. Cf. example 1. The user can control the ordering by the preference `Pref::keepOrder`. See also the documentation for `print`.
- `_plus` accepts an arbitrary number of arguments. In conjunction with the sequence operator `$`, this function is the recommended tool for computing finite sums. Cf. example 2. The function `sum` may also serve for computing such sums. However, `sum` is designed for the computation of symbolic and infinite sums. It is slower than `_plus`.
- `x - y` is internally represented as `x + y*(-1)` = `_plus(x, _mult(y, -1))`. See `_subtract` for details.
- Many library domains overload `_plus` by an appropriate slot `"_plus"`. Sums involving elements of library domains are processed as follows:

  A sum `x + y + ...` is searched for elements of library domains from left to right. Let `z` be the first term that is not of one of the basic types provided by the kernel (numbers, expressions, etc.). If the domain `d` = `z::dom` = `domtype(z)` has a slot `"_plus"`, it is called in the form `d::_plus(x, y, ...)`. The result returned by `d::_plus` is the result of `x + y + ...`.

  Users should implement the slot `d::_plus` of their domains `d` according to the following convention:

  - If all terms are elements of `d`, an appropriate sum of type `d` should be returned.
  - If at least one term cannot be converted to an element of `d`, the slot should return `FAIL`.
  - Care must be taken if there are terms that are not of type `d`, but can be converted to type `d`. Such terms should be converted only if the mathematical semantics is obvious to any user who uses this domain as a 'black box' (e.g., integers may be regarded as rational numbers because of the natural mathematical embedding). If in doubt, the `"_plus"` method should return `FAIL` instead of using implicit conversions. If implicit conversions are used, they must be well-documented.
  Cf. examples 5 and 6.

  Most of the library domains in MuPAD's standard installation comply with this convention.

- `_plus()` returns the number 0.
- Polynomials of type `DOM_POLY` are added by `+`, if they have the same indeterminates and the same coefficient ring.
- For finite sets `X`, `Y`, the sum `X + Y` is the set {x + y; x in X; y in Y}.
- `_plus` is a function of the system kernel.

#### Example 1

Numerical terms are simplified automatically:

    >> 3 + x + y + 2*x + 5*x - 1/2 - sin(4) + 17/4

                              8 x + y - sin(4) + 27/4

The ordering of the terms of a sum is not necessarily the same as on input:

    >> x + y + z + a + b + c

                               a + b + c + x + y + z

    >> 1 + x + x^2 + x^10

                                      2    10
                                 x + x  + x   + 1

Internally, this sum is a symbolic call of `_plus`:

    >> op(%, 0), type(%)

                                  _plus, "_plus"

#### Example 2

The functional equivalent `_plus` of the operator `+` is a handy tool for computing finite sums. In the following, the terms are generated via the sequence operator `$`:

    >> _plus(i^2 $ i = 1..100)

                                      338350

E.g., it is easy to add up all elements in a set:

    >> S := {a, b, 1, 2, 27}: _plus(op(S))

                                    a + b + 30

The following command ``zips'' two lists by adding corresponding elements:

    >> L1 := [a, b, c]: L2 := [1, 2, 3]: zip(L1, L2, _plus)

                               [a + 1, b + 2, c + 3]

    >> delete S, L1, L2:

#### Example 3

Polynomials of type `DOM_POLY` are added by `+`, if they have the same indeterminates and the same coefficient ring:

    >> poly(x^2 + 1, [x]) + poly(x^2 + x - 1, [x])

                                        2
                                poly(2 x  + x, [x])

Symbolic sums are returned if the indeterminates or the coefficient rings do not match:

    >> poly(x, [x]) + poly(x, [x, y])

                          poly(x, [x]) + poly(x, [x, y])

    >> poly(x, [x]) + poly(x, [x], Dom::Integer)

                     poly(x, [x]) + poly(x, [x], Dom::Integer)

#### Example 4

For finite sets `X`, `Y`, the sum `X + Y` is the set {x + y; x in X; y in Y}:

    >> {a, b, c} + {1, 2}

                    {a + 1, a + 2, b + 1, b + 2, c + 1, c + 2}

#### Example 5

Various library domains such as matrix domains overload `_plus`:

    >> x := Dom::Matrix(Dom::Integer)([1, 2]):
       y := Dom::Matrix(Dom::Rational)([2, 3]):
       x + y, y + x

                                 +-   -+  +-   -+
                                 |  3  |  |  3  |
                                 |     |, |     |
                                 |  5  |  |  5  |
                                 +-   -+  +-   -+

If the terms in a sum `x + y` are of different type, the first term `x` tries to convert `y` to the data type of `x`. If successful, the sum is of the same type as `x`. In the previous example, `x` and `y` have different types (both are matrices, but the component domains differ). Hence the sums `x + y` and `y + x` differ syntactically, because they inherit their type from the first term:

    >> bool(x + y = y + x)

                                       FALSE

    >> domtype(x + y), domtype(y + x)

               Dom::Matrix(Dom::Integer), Dom::Matrix(Dom::Rational)

If `x` does not succeed to convert `y`, then `FAIL` is returned. In the following call, the component `2/3` cannot be converted to an integer:

    >> y := Dom::Matrix(Dom::Rational)([2/3, 3]): x + y

                                       FAIL

    >> delete x, y:

#### Example 6

This example demonstrates how to implement a slot `"_plus"` for a domain. The following domain `myString` is to represent character strings. The sum of such strings is to be the concatenation of the strings.

The `"new"` method uses `expr2text` to convert any MuPAD object to a string. This string is the internal representation of elements of `myString`. The `"print"` method turns this string into the screen output:

    >> myString := newDomain("myString"):
       myString::new := proc(x)
       begin
         if args(0) = 0 then x := "": end_if;
         case domtype(x)
           of myString do return(x);
           of DOM_STRING do return(new(dom, x));
           otherwise return(new(dom, expr2text(x)));
         end_case
       end_proc:
       myString::print := x -> extop(x, 1):

Without a `"_plus"` method, the system function `_plus` handles elements of this domain like any symbolic object:

    >> y := myString(y): z := myString(z): 1 + x + y + z + 3/2

                                  x + y + z + 5/2

Now, we implement the `"_plus"` method. It checks all arguments. Arguments are converted, if they are not of type `myString`. Generally, such an implicit conversion should be avoided. In this case, however, any object has a corresponding string representation via `expr2text` and an implicit conversion is implemented. Finally, the sum of `myString` objects is defined as the concatenation of the internal strings:

    >> myString::_plus := proc()
       local n, Arguments, i;
       begin
         userinfo(10, "myString::_plus called with the arguments:",
                  args()):
         n := args(0):
         Arguments := [args()];
         for i from 1 to n do
           if domtype(Arguments[i]) <> myString then
             // convert the i-th term to myString
             Arguments[i] := myString::new(Arguments[i]):
           end_if;
         end_for:
         myString::new(_concat(extop(Arguments[i], 1) $ i = 1..n))
       end_proc:

       setuserinfo(myString::_plus, 10):

Now, `myString` objects can be added:

    >> myString("This ") + myString("is ") + myString("a string")

          Info: myString::_plus called with the arguments:, This , is , \
          a string

                                 This is a string

In the following sum, `y` and `z` are elements of `myString`. The term `y` is the first term that is an element of a library domain. Its `"_plus"` method is called and concatenates all terms to a string of type `myString`:

    >> 1 + x + y + z + 3/2;

          Info: myString::_plus called with the arguments:, 1, x, y, z, \
          3/2

                                      1xyz3/2

    >> delete myString, y, z:

#### Changes

- no changes

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