Documentation |
Add expressions
This functionality does not run in MATLAB.
x + y + ... _plus(x, y, …)
x + y + ... computes the sum of x, y etc.
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.
For adding equalities, inequalities, and comparisons, the following rules are implemented:
Adding an arithmetical expression adds the expression to both sides.
Adding an equality adds the left hand sides and the right hand sides separately.
Adding a comparison does likewise, taking care of the correct operator. Adding a comparison to an inequality is not permitted.
Cf. Example 4.
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.
Most of the library domains in the MuPAD^{®} 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 .
Numerical terms are simplified automatically:
3 + x + y + 2*x + 5*x - 1/2 - sin(4) + 17/4
The ordering of the terms of a sum is not necessarily the same as on input:
x + y + z + a + b + c
1 + x + x^2 + x^10
Internally, this sum is a symbolic call of _plus:
op(%, 0), type(%)
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)
E.g., it is easy to add up all elements in a set:
S := {a, b, 1, 2, 27}: _plus(op(S))
The following command "zips" two lists by adding corresponding elements:
L1 := [a, b, c]: L2 := [1, 2, 3]: zip(L1, L2, _plus)
delete S, L1, L2:
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])
If the indeterminates or the coefficient rings do not match, _plus returns an error:
poly(x, [x]) + poly(x, [x, y])
Error: The argument is invalid. [_plus]
poly(x, [x]) + poly(x, [x], Dom::Integer)
Error: The argument is invalid. [_plus]
Adding a constant to an equality, an inequality, or a comparison amounts to adding it to both sides:
(a = b) + c, (a <> b) + c, (a <= b) + c, (a < b) + c
Adding an equality is performed by adding the left hand sides and the right hand sides separately:
(a = b) + (c = d), (a <> b) + (c = d), (a <= b) + (c = d), (a < b) + (c = d)
Inequalities can only be added to equalities:
(a = b) + (c <> d), (a <> b) + (c <> d), (a <= b) + (c <> d), (a < b) + (c <> d)
The addition of comparisons takes of the difference between < and <= into account. Note that MuPAD uses only these two comparison operators; a > b and a ≥ b are automatically rewritten:
(a = b) + (c <= d), (a <> b) + (c <= d), (a <= b) + (c <= d), (a < b) + (c <= d);
(a = b) + (c < d), (a <> b) + (c < d), (a <= b) + (c < d), (a < b) + (c < d);
(a = b) + (c >= d), (a <> b) + (c >= d), (a <= b) + (c >= d), (a < b) + (c >= d);
(a = b) + (c > d), (a <> b) + (c > d), (a <= b) + (c > d), (a < b) + (c > d);
For finite sets X, Y, the sum X + Y is the set :
{a, b, c} + {1, 2}
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
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)
domtype(x + y), domtype(y + x)
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
delete x, y:
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
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 print(Unquoted, "Info: 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:
Now, myString objects can be added:
myString("This ") + myString("is ") + myString("a string")
Info: myString::_plus called with the arguments:, 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;
3 Info: myString::_plus called with the arguments:, 1, x, y, z, - 2
delete myString, y, z:
x, y, … |
arithmetical expressions, polynomials of type DOM_POLY, sets, equations, inequalities, or comparisons |