I have written an IML module to compute a table created by the application of a dyadic function ( '+', '#', '/', etc.) applied to two numeric vectors.
start o_p( dyadic_fcn, x, y ) ;
/* purpose: compute outer product of vectors x, y by applying dyadic function
*
* parameters:
* dyadic_fcn ::= quoted dyadic function, e.g., + - = ^= # ## < > , &cetera
* x ::= numeric scalar or vector
* y ::= numeric scalar or vector
*
* returns outer product of column vector x <dyadic function> row vector y
*
* example:
* a = 1 : 4 ; b = 1 : 5 ;
*
* c = op( '/', a, b ) ;
*/
tmp_x = colvec( x ) ; n_row_x = nrow( tmp_x ) ;
tmp_y = rowvec( y ) ; n_col_y = ncol( tmp_y ) ;
x_mat = repeat( tmp_x, 1, n_col_y ) ;
y_mat = repeat( tmp_y, n_row_x, 1 ) ;
call execute( 'rslt = x_mat', dyadic_fcn, 'y_mat ;' ) ;
return rslt ;
finish o_p ;
For example,
x = 1 : 5 ;
y = 1 : 3 ;
z1 = o_p( '<', x, y ) ;
z2 = o_p( '+', x, y ) ;
z3 = o_p( '^=', x, y ) ;
z4 = o_p( '#', x, y ) ;
print x y, z1[ l="dyadic function =' '<'"] " " z2[l="dyadic function = '+'"] " " z3[l="dyadic function = '^='"] " " z4[l="dyadic function = '#'"] ;
z = o_p( '#', 1, { 2 3 4 5 } ) ;
print z ;
produces the results
x y
1 2 3 4 5 1 2 3
dyadic function =' '<' dyadic function = '+' dyadic function = '^=' dyadic function = '#'
0 1 1 2 3 4 0 1 1 1 2 3
0 0 1 3 4 5 1 0 1 2 4 6
0 0 0 4 5 6 1 1 0 3 6 9
0 0 0 5 6 7 1 1 1 4 8 12
0 0 0 6 7 8 1 1 1 5 10 15
z
2 3 4 5
I have solved the problem using conformable matrices, but it would be nice if there were an IML function to perform the same task more efficiently. I also know that I can use the APPLY function, but I have to define the particular dyadic function for two arguments, and this is an inelegant and inefficient use of APPLY, IMHO. The statement
z = colvec( x ) * rowvec( y ) ;
produces the same result as z = o_p( '#', x, y ) but this is the only case of a built-in IML outer product function that I know of. Is there any equivalent in IML for general dyadic functions?