## `Dom::Product` -- homogeneous direct products

#### Introduction

`Dom::Product``(Set, n)` is an n-fold direct product of the domain Set.

#### Domain

`Dom::Product(Set <, n>)`

#### Parameters

`Set` | - | an arbitrary domain of elements, i.e., a domain of category `Cat::BaseCategory`
`n` | - | the dimension of the product (a positive integer); default is 1

#### Creating Elements

``Dom::Product`(Set <, n>)(e1, e2..., en)`
``Dom::Product`(Set <, n>)(List)`

#### Parameters

`e1, e2..., en` | - | elements of `Set` or objects convertible into such
`List` | - | a list of `n` elements of `Set` or objects convertible into such

#### Categories

`Cat::HomogeneousFiniteProduct(Set)`

#### Details

- `Dom::Product``(Set, n)(e1, e2..., en)` creates the n-tuple (e1, e2, ..., en.

  The objects `e1`, `e2`..., `en` must be convertible into elements of the domain `Set`, otherwise an error message is issued.

- `Dom::Product``(Set, n)(List)` creates the n-tuple (l1, l2, ..., ln).

  The n elements li of `List` must be convertible into elements of the domain `Set`, otherwise an error message is issued.

  The list must consist of exactly `n` elements, otherwise an error message is issued.

- Following to the definition of a direct product many of the methods such as `"D"` and `"_negate"` just map the operation to all the components of the tuple.

  Most n-ary methods like `"_plus"` and `"_mult"` apply the operation component-wise to the tuples.

#### Entries

card

  is the cardinal number of `Dom::Product``(Set, n)`, which is equal to `n`.

coeffRing

  is the domain `S`.

one

  is the n-tuple `(Set::one, Set::one, ..., Set::one)`. This entry only exists if `Set` is a monoid, i.e., a domain of category `Cat::Monoid`.

zero

  is the n-tuple `(Set::zero, Set::zero, ..., Set::zero)`. This entry only exists if `Set` is an Abelian group, i.e., a domain of category `Cat::AbelianGroup`.

#### Method _divide: divide tuples

- `_divide(dom x, dom y)`
- - This method divides the tuple `x` by `y`, i.e., it divides the ith component of `x` by the ith component of `y` (i ranges from 1 to n).
  - This method only exists if `Set` is a (multiplicative) group, i.e., a domain of category `Cat::Group`.
  - This method overloads the function `_divide` for n-tuples, i.e., one may use it in the form `x / y`, or in functional notation: `_divide(x, y)`.

#### Method _invert: computes the inverse of a tuple

- `_invert(dom x)`
- - The inverse of a tuple is the inverse of each component of `x`.
  - This method only exists if `Set` is a (multiplicative) group, i.e., a domain of category `Cat::Group`.
  - This method overloads the function `_invert` for n-tuples, i.e., one may use it in the form `1/x` or `x^(-1)`, or in functional notation: `_inverse(x)`.

#### Method _less: less-than relation

- `_less(dom x, dom y)`
- - returns `TRUE` if `x` is lexically smaller than `y`.
  - An implementation is provided only if `Set` is an ordered set, i.e., a domain of category `Cat::OrderedSet`.
  - This method overloads the function `_less` for n-tuples, i.e., one may use it in the form `x < y`, or in functional notation: `_less(x, y)`.

#### Method _mult: multiplies tuples by tuples and scalars

- `_mult(any x, any y...)`
- - If `x` and `y` both are n-tuples defined over `Set` the n-tuple with the ith component defined by x[i] * y[i] (i ranges from 1 to n) is returned.
  - If `x` is not of the type `Dom::Product``(Set,n)`, it is considered as a scalar which is multiplied to each component of the n-tuple `y` (and vice versa).
  - This method only exists if `Set` is a semigroup, i.e., a domain of category `Cat::SemiGroup`.
  - This method also handles more than two arguments. In this case, the argument list is split into two parts of the same length which both are multiplied with the function `_mult`. These two result are multiplied again with `_mult` whose result then is returned.
  - This method overloads the function `_mult` for n-tuples, i.e., one may use it in the form `x * y`, or in functional notation: `_mult(x, y)`.

#### Method _negate: negates an n-tuple

- `_negate(dom x)`
- - The negative of an n-tuple is the negative of each of its components.
  - This method overloads the function `_negate` for n-tuples, i.e., one may use it in the form `-x`, or in functional notation: `_negate(x)`.

#### Method _power: the ith power of a tuple

- `_power(dom x, integer i)`
- - This method raises each component of `x` to the ith power.
  - An implementation is provided only if `Set` is a semigroup, i.e., a domain of category `Cat::SemiGroup`.
  - This method overloads the function `_power` for n-tuples, i.e., one may use it in the form `x^i`, or in functional notation: `_power(x, i)`.

#### Method _plus: adds tuples

- `_plus(dom x, dom y...)`
- - Returns the sum x + y + ....
  - The sum of two n-tuples x and y is defined component-wise as (x[1]+y[1], ..., x[n]+y[m]).
  - This method overloads the function `_plus` for n-tuples, i.e., one may use it in the form `x + y`, or in functional notation: `_plus(x, y)`.

#### Method D: the differential operator

- `D(dom x)`
- - This method returns the n-tuple which results from taking the derivative of each component of `x` using the method `"D"` of the domain `S`.
  - An implementation is provided only if `Set` is a partial differential ring, i.e., a domain of category `Cat::PartialDifferentialRing`.
  - This method overloads the operator `D` for n-tuples, i.e., one may use it in the form `D(x)`.

#### Method diff: differentiation of n-tuples

- `diff(dom a,` variable x)
- - This method returns the n-tuples which results from differentiating each component of `a` using the method `"diff"` of the domain `S`.
  - This method overloads the function `diff` for n-tuples, i.e., one may use it in the form `diff(a, x)`.
  - An implementation is provided only if `Set` is a partial differential ring, i.e., a domain of category `Cat::PartialDifferentialRing`.

#### Method equal: test on equality of n-tuples

- `equal(dom x, dom y)`
- - This method tests if the tuple `x` is equal to `y`, and returns `TRUE`, `FALSE` or `UNKNOWN`, respectively. `x` and `y` are equal if and only if for each index i from 1 to n the ith components of `x` and `y` are equal.

#### Method intmult: multiple of a tuple

- `intmult(dom x, integer k)`
- - The k-multiple of an n-tuple is the tuple consisting of the k-multiples of its components (which are calculated by the method `"intmult"` of `Set`).
  - An implementation is provided only if `Set` is an Abelian semigroup, i.e., a domain of category `Cat::AbelianSemiGroup`.

#### Method iszero: test on zero

- `iszero(dom x)`
- - This method checks whether the tuple `x` consists of zero components only and returns `TRUE`, `FALSE` and `UNKNOWN`, respectively.
  - Note that there may be more than one representation of the zero n-tuple if `R` does not have `Ax::canonicalRep`.
  - This method overloads the function `iszero` for n-tuples, i.e., one may use it in the form `iszero(x)`.

#### Method random: random tuple generation

- `random()`
- - This method returns a random n-tuple. It uses the method `"random"` of the domain `Set` to randomly generate the components of the tuple.

#### Method _index: tuple indexing

- `_index(dom x, index i)`
- - Returns the ith component of the tuple `x` (an error message is issued if `i` is less than one or greater than the number of components of `x`).
  - See also the method `"op"`.
  - This method overloads the function `_index` for n-tuples, i.e., one may use it in the form `x[i]`, or in functional notation: `_index(x, i)`.

#### Method map: apply a function to tuple components

- `map(dom x, function func <, any expr...>)`
- - This method maps the function `func` onto the components of the n-tuple `x`, with the additional function parameters `expr...` passed to `func`, if given.

    See the system function `map` for details.

  - Note that the function values will not be implicitly converted into elements of the domain `Set`. One has to take care that the function calls return elements of the domain type `Set`.

  - This method overloads the function `map` for n-tuples, i.e., one may use it in the form `map(x, func...)`.

#### Method mapCanFail: apply a function to tuple components

- `mapCanFail(dom x, function func <, any expr...>)`
- - This method works like the method `"map"` but returns `FAIL` if one of the function calls returned `FAIL`.

#### Method op: components of a tuple

- `op(dom x, positive integer i)`
- - Returns the ith component of the tuple `x`, or `FAIL` if `i` is greater than the number of components of `x`.
  - See also the method `"_index"`.
  - This method overloads the function `op` for n-tuples, i.e., one may use it in the form `op(x, i)`.
- `op(dom x)`
- - Returns a sequence of all components of `x`.

#### Method set_index: assigning tuple components

- `set_index(dom x, index i, Set e)`
- - Replaces the ith component of the tuple `x` by `e`.
  - See also the method `"subsop"`.

  - This method does not check whether `e` has the correct type.

  - This method overloads the indexed assignment `_assign` for n-tuples, i.e., one may use it in the form `x[i] := e`, or in functional notation: `_assign(x[i], e)`.

#### Method subs: substitution of tuple components

- `subs(dom x...)`
- - This method applies the function `subs` with additionally given parameters to the entries of the tuple `x`.

  - The objects obtained by the substitutions will not be implicitly converted into elements of the domain `Set`. One has to take care that the substitutions return elements of the domain `Set`.

  - This method overloads the function `subs` for n-tuples, i.e., one may use it in the form `subs(x...)`. See `subs` for details and calling sequences.

#### Method testEach: check every component for a certain condition

- `testEach(dom x, function func <, any expr...>)`
- - This method maps the function `func` onto the components of the tuple `x`, with the additional function parameters `expr...` passed to `func`, if given.

    It returns `TRUE` if all of these function calls returned `TRUE`, and `FALSE` otherwise.

  - `func` must return either `TRUE` or `FALSE`, otherwise a runtime error is raised.

#### Method testOne: check an component for a certain condition

- `testOne(dom x, function func <, any expr...>)`
- - This method maps the function `func` onto the components of the tuple `x`, with the additional function parameters `expr...` passed to `func`, if given.

    It returns `TRUE` if one of these function calls returned `TRUE`, and `FALSE` otherwise.

  - `func` must return either `TRUE` or `FALSE`, otherwise a runtime error is raised.

#### Method zip: combine tuples component-wise

- `zip(dom x, y, function func <, any expr...>)`
- - This method combines the tuples `x` and `y` component-wise, where the function call `func(a, b <, expr...>)` is executed for each pair (xi, yi) of tuple components xi of `x` and yi of `y`.

    See the system function `zip` for details.

  - The function values will not be implicitly converted into elements of the domain `Set`. One has to take care that the function calls return elements of the domain `Set`.

  - This method overloads the function `zip` for n-tuples, i.e., one may use it in the form `zip(x, y, func, ...)`.

#### Method zipCanFail: combine tuples component-wise

- `zipCanFail(dom x, y, function func <, any expr...>)`
- - This method works like the method `"zip"` but returns `FAIL` if one of the function calls return `FAIL`.

#### Method convert: conversion into an n-tuple

- `convert(list List)`
- - Tries to convert `List` into an element of the domain `Dom::Product``(Set, n)`. This can be done if `List` is a list of `n` elements where each element can be converted into an element of the domain `Set`.
  - `FAIL` is returned if this conversion fails.
- `convert(any e1 <, any e2...>)`
- - Tries to convert the arguments into an element of the domain `Dom::Product``(Set, n)`. This can be done if exactly `n` arguments are given where each argument can be converted into an element of the domain `Set`.
  - `FAIL` is returned if this conversion fails.

#### Method expr: conversion into an object of a kernel domain

- `expr(dom x)`
- - This method maps the method `"expr"` of `Set` to each element of `x` and returns a list of the converted elements, i.e., an object of type `DOM_LIST`.
  - This method overloads the function `expr` for n-tuples, i.e., one may use it in the form `expr(x)`.

#### Example 1

Define the 3-fold direct product of the rational numbers:

    >> P3 := Dom::Product(Dom::Rational, 3)

                          Dom::Product(Dom::Rational, 3)

and create elements:

    >> a := P3([1, 2/3, 0])

                                    [1, 2/3, 0]

    >> b := P3(2/3, 4, 1/2)

                                   [2/3, 4, 1/2]

We use the standard arithmetical operators to calculate with such tuples:

    >> a + b, a*b, 2*a

                   [5/3, 14/3, 1/2], [2/3, 8/3, 0], [2, 4/3, 0]

Some system functions were overloaded for such elements, such as `diff`, `map` or `zip` (see the description of the corresponding methods `"diff"`, `"map"` and `"zip"` above).

For example, to divide each component of `a` by 2 we enter:

    >> map(a, `/`, 2)

                                   [1/2, 1/3, 0]

The quoted character ``/`` is another notation for the function `_divide`, the functional form of the division operator `/`.

Be careful that the mapping function returns elements of the domain the product is defined over. This is not checked by the function `map` (for efficiency reasons) and may lead to ``invalid'' tuples. For example:

    >> b := map(a, sin); domtype(b)

                               [sin(1), sin(2/3), 0]

                          Dom::Product(Dom::Rational, 3)

But the components of `b` are no longer rational numbers!

#### Super-Domain

`Dom::BaseDomain`

#### Axioms

if `Set` has `Ax::canonicalRep`, then
`Ax::canonicalRep`
if `Set` has `Cat::AbelianMonoid` and `Set` has `Ax::normalRep`, then
`Ax::normalRep`

#### Changes

- New entry `coeffRing`.

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