# *, _mult

Multiply expressions

### Use only in the MuPAD Notebook Interface.

This functionality does not run in MATLAB.

## Syntax

````x * y * ...`
_mult(`x, y, …`)
```

## Description

`x * y * ...` computes the product of `x`, `y` etc.

`x * y * ...` is equivalent to the function call `_mult(x, y, ...)`.

All terms that are numbers of type `Type::Numeric` are automatically combined to a single number.

The terms of a symbolic product may be rearranged internally if no term belongs to a library domain that overloads `_mult`: on terms composed of kernel domains (numbers, identifiers, expressions etc.), multiplication is assumed to be commutative. Cf. Example 1.

Via overloading, the user can implement a non-commutative product for special domains.

`_mult` accepts an arbitrary number of arguments. In conjunction with the sequence operator `\$`, this function is the recommended tool for computing finite products. Cf. Example 2. The function `product` may also serve for computing such products. However, `product` is designed for the computation of symbolic and infinite products. It is slower than `_mult`.

The quotient `x/y` is internally represented as `x * (1/y)` = `_mult(x, _power(y, -1))`. See `_divide` for details.

Many library domains overload `_mult` by an appropriate slot`"_mult"`. Products involving elements of library domains are processed as follows:

A product `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`"_mult"`, it is called in the form `d::_mult(x, y, ...)`. The result returned by `d::_mult` is the result of ```x * y * ...```.

Cf. Example 6 and Example 7.

`_mult()` returns the number 1.

Polynomials of type `DOM_POLY` are multiplied by `*`, if they have the same indeterminates and the same coefficient ring. Use `multcoeffs` to multiply polynomials with scalar factors.

For finite sets `X`, `Y`, the product `X * Y` is the set .

Equalities, inequalities, and comparisons can be multiplied with one another or with arithmetical expressions. The results of such combinations are demonstrated in Example 5.

## Examples

### Example 1

Numerical terms are simplified automatically:

`3 * x * y * (1/18) * sin(4) * 4`

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

`x * y * 3 * z * a * b * c`

Internally, this product is a symbolic call of `_mult`:

`op(%, 0), type(%)`

Note that the screen output does not necessarily reflect the internal order of the terms in a product:

`op(%2)`

In particular, a numerical factor is internally stored as the last operand. On the screen, a numerical factor is displayed in front of the remaining terms:

`3 * x * y * 4`

`op(%)`

### Example 2

The functional equivalent `_mult` of the operator `*` is a handy tool for computing finite products. In the following, the terms are generated via the sequence operator `\$`:

`_mult(i \$ i = 1..20)`

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

`S := {a, b, 1, 2, 27}: _mult(op(S))`

The following command "zips" two lists by multiplying corresponding elements:

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

`delete S, L1, L2:`

### Example 3

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

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

If the indeterminates or the coefficient rings do not match, `_mult` returns an error:

`poly(x, [x]) * poly(x, [x, y])`
```Error: The argument is invalid. [_mult] ```
`poly(x, [x]) * poly(x, [x], Dom::Integer)`
```Error: The argument is invalid. [_mult] ```

Using `*`, you can multiply polynomials by scalar factors:

`2 * y * poly(x, [x])`

Use `multcoeffs` instead:

`multcoeffs(poly(x^2 - 2, [x]), 2*y)`

### Example 4

For finite sets `X`, `Y`, the product `X * Y` is the set :

`{a, b, c} * {1, 2}`

Note that complex numbers of type `DOM_INT`, `DOM_RAT`, `DOM_COMPLEX`, `DOM_FLOAT`, and identifiers are implicitly converted to one-element sets:

`2 * {a, b, c}`

`a * {b, c}, PI * {3, 4}`

### Example 5

Multiplying by a constant expression is performed on both sides of an equation:

`(a = b) * c`

For inequalities, this step is only performed if the constant is known to be non-zero:

```assume(d <> 0): (a <> b) * c, (a <> b) * d; delete d:```

The multiplication of a comparison with a constant is only defined for real numbers. Even for these, the result depends on the sign of the constant, since multiplication with a negative constant changes the direction of the comparison:

`(a < b) * 2, (a < b) * (-3)`

`(a < b) * I`
```Error: Inequalities must not be multiplied by complex numbers. [_less::_mult] ```
`(a < b) * c, (a <= b) * c`

Multiplication of two equalities is performed by multiplying the left hand sides and the right hand sides separately:

`(a = b) * (c = d)`

Inequalities cannot be multiplied with one another or with comparisons; multiplication with equalities is, however, defined, if at least one operand of the equation is known to be non-zero:

```assume(d <> 0): (a <> b) * (c = d); delete d:```

In other cases, the product is not expanded:

```delete c, d: (a <> b) * (c = d)```

Multiplication of comparisons with equalities and comparisons is performed similar to the cases above:

```assume(c > 0): (a < b) * (c = d); delete c:```

`(a <= b) * (c <= d)`

### Example 6

Various library domains such as matrix domains overload `_mult`. The multiplication is not commutative:

```x := Dom::Matrix(Dom::Integer)([[1, 2], [3, 4]]): y := Dom::Matrix(Dom::Rational)([[10, 11], [12, 13]]): x * y, y * x```

If the terms in `x * y` are of different type, the first term `x` tries to convert `y` to the data type of `x`. If successful, the product 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 `x * y` and `y * x` have different types that is inherited from the first term:

`domtype(x * y), domtype(y * x)`

If `x` does not succeed to convert `y`, then `y` tries to convert `x`. In the following call, the component `27/2` cannot be converted to an integer. Consequently, in `x * y`, the term `y` converts `x` and produces a result that coincides with the domain type of `y`:

```y := Dom::Matrix(Dom::Rational)([[10, 11], [12, 27/2]]): x * y, y * x```

`domtype(x * y), domtype(y * x)`

`delete x, y:`

### Example 7

This example demonstrates how to implement a slot`"_mult"` for a domain. The following domain `myString` is to represent character strings. Via overloading of `_mult`, integer multiples of such strings should produce the concatenation of an appropriate number of copies of the string.

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 `"_mult"` method, the system function `_mult` handles elements of this domain like any symbolic object:

```y := myString(y): z := myString(z): 4 * x * y * z * 3/2```

Now, we implement the `"_mult"` method. It uses `split` to pick out all integer terms in its argument list and multiplies them. The result is an integer `n`. If there is exactly one other term left (this must be a string of type `myString`), it is copied `n` times. The concatenation of the copies is returned:

```myString::_mult:= proc() local Arguments, intfactors, others, dummy, n; begin print(Unquoted, "Info: myString::_mult called with the arguments:", args()); Arguments := [args()]; // split the argument list into integers and other factors: [intfactors, others, dummy] := split(Arguments, testtype, DOM_INT); // multiply all integer factors: n := _mult(op(intfactors)); if nops(others) <> 1 then return(FAIL) end_if; myString::new(_concat(extop(others[1], 1) \$ n)) end_proc:```

Now, integer multiples of `myString` objects can be constructed via the `*` operator:

`2 * myString("string") * 3`
```Info: myString::_mult called with the arguments:, 2, string, 3 ```

Only products of integers and `myString` objects are allowed:

`3/2 * myString("a ") * myString("string")`
``` 3 Info: myString::_mult called with the arguments:, -, a , string 2 ```

`delete myString, y, z:`

## Parameters

 `x, y, …`

## Return Values

Arithmetical expression, a polynomial, a set, an equation, an inequality, or a comparison.

`x`, ` y`