Two arrays need not have identical shape in order for a binary operation between them to make perfect sense:
y = a*x^3 + b*x^2 + c*x + d; |
The obvious intent of this assignment statement is that y should have the same shape as x, each value of y being the value of the polynomial at the corresponding y.
Alternatively, array valued coefficients a, b, ..., represent an array of several polynomials – perhaps Legendre polynomials. Then, if x is a scalar value, the meaning is again obvious; y should have the same shape as the coefficient arrays, each y being the value of the corresponding polynomial.
A binary operation is performed once for each element, so that a+b, say, means
a(i,j,k,l) + b(i,j,k,l) |
for every i, j, k, l (taking a and b to be four dimensional). The lengths of corresponding indices must match in order for this procedure to make sense; Yorick signals a “conformability error” when the shapes of binary operands do not match.
However, if a had only three dimensions, a+b still makes sense as:
a(i,j,k) + b(i,j,k,l) |
This sense extends to two dimensional, one dimensional, and finally to scalar a:
a + b(i,j,k,l) |
which is how Yorick interpreted the monomial x^3 in the first example of this section. The shapes of a and b are conformable as long as the dimensions which they have in common all have the same lengths; the shorter operand simply repeats its values for every index of a dimension it doesn’t have. This repitition is called “broadcasting”.
Broadcasting is the key to Yorick’s array syntax. In practical situations, it is just as likely for the a array to be missing the second (j) dimension of the b array as its last (l) dimension. To handle this case, Yorick will broadcast any unit-length dimension in addition to a missing final dimension. Hence, if the a array has a second dimension of length one, a+b means:
a(i,1,k,l) + b(i,j,k,l) |
for every i, j, k, l. The pseudo-index can be used to generate such unit length indices when necessary (see Pseudo-Index).