2.3.5 Creating a pseudo-index
A binary operation applied between two arrays of numbers yields an array of results in Yorick -- the operation is performed once for each corresponding pair of elements of the operands. Hence, if rho and vol are each four-by-three arrays, the expression rho*vol will be a four-by-three array of products, starting with rho(1,1)*vol(1,1).
This extension of binary operations to array operands is not always appropriate. Instead of operating on the corresponding elements of arrays of the same shape, you may want to perform the operation between all pairs of elements. The most common example is the outer product of two vectors x and y:
Here, if x were a four element vector, and y were a three element vector, outer would be the four-by-three array [[x(1)*y(1), x(2)*y(1), x(3)*y(1), x(4)*y(1)], [x(1)*y(2), x(2)*y(2), x(3)*y(2), x(4)*y(2)], [x(1)*y(3), x(2)*y(3), x(3)*y(3), x(4)*y(3)]].
In Yorick, this type of multiplication is still commutative. That is, x*y(-,) is the same as y(-,)*x. To produce the three-by-four transpose of the array outer, you would write x(-,)*y.
I call the - sign, when used as an index, a pseudo-index because it actually inserts an additional dimension into the result array which was not present in the array being indexed. By itself, the expression y(-,) is a one-by-three array (with the same three values as the three element vector y). You may insert as many pseudo-indices into a list of subscripts as you like, at any location you like relative to the actual dimensions of the array you are indexing. Hence, outer(-,-,,-,) would be a one-by-one-by-four-by-one-by-three array.
By default, a pseudo-index produces a result dimension of length one. However, by appending an index range to the - sign, separated by a colon, you can produce a new dimension of any convenient length:
x = span(-10, 10, 100)(,-:1:50); y = span(-5, 5, 50)(-:1:100,); gauss2d = exp(-0.5*(x^2+y^2))/(2.0*pi);
computes a normalized 2-D Gaussian function on a 100-by-50 rectangular grid of points in the xy-plane. The pseudo-index -:1:50 has 50 elements, and -:1:100 has 100. For a pseudo-index of non-unit length, the values along the actual dimensions are simply copied, so that span(-10, 10, 100)(,-:1:50) is a 100-by-50 array consisting of 50 copies of span(-10, 10, 100).
If only the result gauss2d were required, a single default pseudo-index would have sufficed:
gauss2d = exp(-0.5*( span(-10,10,100)^2 + span(-5,5,50)(-,)^2 )) / (2.0*pi);
However, the rectangular grid of points (x,y) is often required -- as input to plotting routines for example.