RWalib C Array Library User Guide > Linear Algebra > alibOuter
  

alibOuter
Outer (tensor) product generalized to any binary operator. The routine applies an operator to each pair (x,y), where x is from one array and y is from a second array. If for example the operator is multiplication and arrays are x and y, the elements of the result are x[i]*y[j] where j varies fastest. This essentially two-dimensional operation has a general multidimensional interpretation: If x and y are interpreted as m-dimensional and n-dimensional, respectively, the result is interpreted as the (m+n)-dimensional tensor product of x and y, where the first m dimensions are from x and the last n dimensions are from y. The PV-WAVE API for this routine is the undocumented TENSORT function which is used like z=TENSORT(f,x,y), where f is a string designating a PV-WAVE binary operator and where x and y are arrays of the same data-type. TENSORT is the row-major equivalent of the column-major PV-WAVE TENSOR functions, and the possible values of f are the suffixes on the names of the TENSOR functions.
Prototypes
void alibOuterb( void (*f)(), wvlong m, wvlong n, UCHAR *p, UCHAR *q, wvlong *k, UCHAR *r, UCHAR *s )
void alibOuters( void (*f)(), wvlong m, wvlong n, short *p, short *q, wvlong *k, short *r, UCHAR *s )
void alibOuteri( void (*f)(), wvlong m, wvlong n, int *p, int *q, wvlong *k, int *r, UCHAR *s )
void alibOuterl( void (*f)(), wvlong m, wvlong n, wvlong *p, wvlong *q, wvlong *k, wvlong *r, UCHAR *s )
void alibOuterf( void (*f)(), wvlong m, wvlong n, float *p, float *q, wvlong *k, float *r, UCHAR *s )
void alibOuterd( void (*f)(), wvlong m, wvlong n, double *p, double *q, wvlong *k, double *r, UCHAR *s )
void alibOuterc( void (*f)(), wvlong m, wvlong n, COMPLEX *p, COMPLEX *q, wvlong *k, COMPLEX *r, UCHAR *s )
void alibOuterz( void (*f)(), wvlong m, wvlong n, DCOMPLEX *p, DCOMPLEX *q, wvlong *k, DCOMPLEX *r, UCHAR *s )
Parameters
(*f)() — (Input) The name of one of the following functions:
 
 
 
where the asterisk represents the letter-code for a supported data-type.
m — (Input) The number of elements in the first array operand.
n — (Input) The number of elements in the second array operand.
*p — (Input) The m-element source array. A scalar p[i] is the first operand in each call to f(), i = 0, ..., m–1.
*q — (Input) NULL if f is alibPowI*, and otherwise, q is the n-element source array used as the second operand in each call to f().
*k — (Input) NULL if f is not alibPowI*, and otherwise, k is the n-element source array used as the second operand in each call to f().
*r — (Input/Output) NULL if f is one of alibEq*, alibNe*, alibLe*, alibGe*, alibLt*, or alibGt*. Otherwise r is an mn-element destination array, and on return r[n*i+j]=p[i]@q[j], where @ is the operation connected with f().
*s — (Input/Output) NULL if f is not one of alibEq*, alibNe*, alibLe*, alibGe*, alibLt*, or alibGt*. Otherwise s is an mn-element destination array, and on return s[n*i+j]=p[i]@q[j], where @ is the operation connected with f().
Example
Besides demonstrating each of the three basic ways to call this routine, this example also demonstrates how to interpret results for multi-dimensional input arrays (see RWalib Introduction.), and how to use the routine to generate index arrays for matrix subdiagonals, superdiagonals, and full/strict lower/upper-triangles.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "alib.h"
void main() {
   /* input and output arrays for the examples */
   UCHAR  lb[16];
   wvlong l[24], l0[6], l1[4];
   float  f[24], f0[6];
   /* make up some data for the input arrays */
      alibinit( NULL, NULL, NULL, NULL );
      alibIndexl( 6, 0, 1, l0 );
      alibIndexf( 6, 0, 1, f0 );
      alibIndexl( 4, 1, 1, l1 );
   printf( "\n\n show 4-element vector f0 and 3-element vector l1" );
      alibPrintArrayf( 1, 1, 1, 4, f0, NULL );
      alibPrintArrayl( 1, 1, 1, 3, l1, NULL );
   printf( "\n\n show the matrix of the values f0[i] to integer power l1[j]" );
      alibOuterf( alibPowIf, 4, 3, f0, NULL, l1, f, NULL );
      alibPrintArrayf( 1, 1, 4, 3, f, NULL );
   printf( "\n\n show 4-element vectors l0 and l1" );
      alibPrintArrayl( 1, 1, 1, 4, l0, "%4lld" );
      alibPrintArrayl( 1, 1, 1, 4, l1, "%4lld" );
   printf( "\n\n show the matrix of the values l0[i] == l1[j]" );
      alibOuterl( alibEql, 4, 4, l0, l1, NULL, NULL, lb );
      alibPrintArrayb( 1, 1, 4, 4, lb, NULL );
   printf( "\n\n this procedure also yields indices of the subdiagonal" );
      alibFindb( 3, lb, l );
      alibPrintArrayl( 1, 1, 1, 3, l, "%4lld" );
   printf( "\n\n interchange l0 and l1 to get indices of the superdiagonal" );
      alibOuterl( alibEql, 4, 4, l1, l0, NULL, NULL, lb );
      alibFindb( 3, lb, l );
      alibPrintArrayl( 1, 1, 1, 3, l, "%4lld" );
   printf( "\n\n similar procedure finds indices of lower-triangular matrix" );
      alibOuterl( alibGel, 4, 4, l0, l0, NULL, NULL, lb );
      alibFindb( 10, lb, l );
      alibPrintArrayb( 1, 1, 4, 4, lb, NULL );
      alibPrintArrayl( 1, 1, 1, 10, l, "%4lld" );
   printf( "\n\n or finds indices of strictly lower-triangular matrix" );
      alibOuterl( alibGtl, 4, 4, l0, l0, NULL, NULL, lb );
      alibFindb( 6, lb, l );
      alibPrintArrayb( 1, 1, 4, 4, lb, NULL );
      alibPrintArrayl( 1, 1, 1, 6, l, "%4lld" );
   printf( "\n\n or finds indices of upper-triangular matrix" );
      alibOuterl( alibLel, 4, 4, l0, l0, NULL, NULL, lb );
      alibFindb( 10, lb, l );
      alibPrintArrayb( 1, 1, 4, 4, lb, NULL );
      alibPrintArrayl( 1, 1, 1, 10, l, "%4lld" );
   printf( "\n\n or finds indices of strictly upper-triangular matrix" );
      alibOuterl( alibLtl, 4, 4, l0, l0, NULL, NULL, lb );
      alibFindb( 6, lb, l );
      alibPrintArrayb( 1, 1, 4, 4, lb, NULL );
      alibPrintArrayl( 1, 1, 1, 6, l, "%4lld" );
   printf( "\n\n show (2,3) array l0 and 4-element vector l1" );
      alibPrintArrayl( 1, 1, 2, 3, l0, "%4lld" );
      alibPrintArrayl( 1, 1, 1, 4, l1, "%4lld" );
   printf( "\n\n show outer (tensor) product of 2d array l0 and 1d array l1" );
      alibOuterl( alibMultl, 6, 4, l0, l1, NULL, l, NULL );
      alibPrintArrayl( 1, 2, 3, 4, l, "%4lld" );
   printf( "\n\n show (2,2) arrays l0 and l1" );
      alibPrintArrayl( 1, 1, 2, 2, l0, "%4lld" );
      alibPrintArrayl( 1, 1, 2, 2, l1, "%4lld" );
   printf( "\n\n show 4d result of tensor product of 2d arrays l0 and l1" );
      alibOuterl( alibMultl, 4, 4, l0, l1, NULL, l, NULL );
      alibPrintArrayl( 2, 2, 2, 2, l, "%4lld" );
}
 
Output:
 
 show 4-element vector f0 and 3-element vector l1
 
   0.000e+00   1.000e+00   2.000e+00   3.000e+00
 
                    1                    2                    3
 
 show the matrix of the values f0[i] to integer power l1[j]
 
   0.000e+00   0.000e+00   0.000e+00
   1.000e+00   1.000e+00   1.000e+00
   2.000e+00   4.000e+00   8.000e+00
   3.000e+00   9.000e+00   2.700e+01
 
 show 4-element vectors l0 and l1
 
   0   1   2   3
 
   1   2   3   4
 
 show the matrix of the values l0[i] == l1[j]
 
   0   0   0   0
   1   0   0   0
   0   1   0   0
   0   0   1   0
 
 this procedure also yields indices of the subdiagonal
 
   4   9  14
 
 interchange l0 and l1 to get indices of the superdiagonal
 
   1   6  11
 
 similar procedure finds indices of lower-triangular matrix
 
   1   0   0   0
   1   1   0   0
   1   1   1   0
   1   1   1   1
 
   0   4   5   8   9  10  12  13  14  15
 
 or finds indices of strictly lower-triangular matrix
 
   0   0   0   0
   1   0   0   0
   1   1   0   0
   1   1   1   0
 
   4   8   9  12  13  14
 
 or finds indices of upper-triangular matrix
 
   1   1   1   1
   0   1   1   1
   0   0   1   1
   0   0   0   1
 
   0   1   2   3   5   6   7  10  11  15
 
 or finds indices of strictly upper-triangular matrix
 
   0   1   1   1
   0   0   1   1
   0   0   0   1
   0   0   0   0
 
   1   2   3   6   7  11
 
 show (2,3) array l0 and 4-element vector l1
 
   0   1   2
   3   4   5
 
   1   2   3   4
 
 show outer (tensor) product of 2d array l0 and 1d array l1
 
   0   0   0   0
   1   2   3   4
   2   4   6   8
 
   3   6   9  12
   4   8  12  16
   5  10  15  20
 
 show (2,2) arrays l0 and l1
 
   0   1
   2   3
 
   1   2
   3   4
 
 show 4d result of tensor product of 2d arrays l0 and l1
 
   0   0
   0   0
 
   1   2
   3   4
 
   2   4
   6   8
 
   3   6
   9  12

Version 2017.1
Copyright © 2019, Rogue Wave Software, Inc. All Rights Reserved.