LAL  7.5.0.1-ec27e42
MatrixOps.c
Go to the documentation of this file.
1 /**
2  * \defgroup MatrixOps_c Module MatrixOps.c
3  * \ingroup MatrixUtils_h
4  * \author Creighton, T. D.
5  *
6  * \brief Routines to perform basic matrix operations.
7  *
8  * ### Prototypes ###
9  *
10  * \code
11  * void
12  * LAL<typecode>MatrixMultiply( LALStatus *stat,
13  * <datatype>Array *out,
14  * <datatype>Array *in1,
15  * <datatype>Array *in2 )
16  *
17  * void
18  * LAL<typecode>MatrixTranspose( LALStatus *stat,
19  * <datatype>Array *out,
20  * <datatype>Array *in )
21  * \endcode
22  *
23  * ### Description ###
24  *
25  * The routines <tt>LAL<datatype>MatrixMultiply()</tt> perform matrix
26  * multiplication, contracting the columns of <tt>*in1</tt> against the
27  * rows of <tt>*in2</tt>, and storing the result in <tt>*out</tt>. The
28  * number of columns of <tt>*in1</tt> must equal the number of rows of
29  * <tt>*in2</tt>, and <tt>*out</tt> must have the same number of columns as
30  * <tt>*in1</tt> and the same number of rows as <tt>*in2</tt>.
31  *
32  * The routines <tt>LAL<datatype>MatrixTranspose()</tt> take the transpose
33  * of the matrix <tt>*in</tt> and store the result in <tt>*out</tt>. The
34  * number of rows of <tt>*out</tt> must equal the number of columns of
35  * <tt>*in</tt>, and vice-versa.
36  *
37  * The prototype templates above in fact refer to several separate routines
38  * each, corresponding to different numerical atomic datatypes
39  * <tt><datatype></tt> referred to by <tt><typecode></tt>:
40  *
41  * <table><tr><th><typecode></th><th><datatype></th><th><typecode></th><th><datatype></th></tr>
42  * <tr><td> D</td><td>REAL8</td><td></td><td></td></tr>
43  * </table>
44  *
45  * ### Algorithm ###
46  *
47  * The matrix product \f$\mathsf{Z}^a{}_b=\mathsf{X}^a{}_c
48  * \mathsf{Y}^c{}_b\f$ of two matrices \f$\mathsf{X}^a{}_c\f$ and
49  * \f$\mathsf{Y}^c{}_b\f$ is given by the element formula
50  * \f$Z^i{}_j=\sum_{k=1}^N X^i{}_k Y^k{}_j\f$, where \f$N\f$ is the number of
51  * columns of \f$\mathsf{X}^a{}_c\f$ \e and the number of rows of
52  * \f$\mathsf{Y}^c{}_b\f$. This can also be used to compute the inner
53  * product of two vectors \f$\mathsf{x}^a\f$ and \f$\mathsf{y}^a\f$: simply store
54  * the transpose \f$(\mathsf{x}^T)_a\f$ as a row vector (single-row matrix)
55  * as the first operand, and \f$\mathsf{y}^a\f$ as a column vector
56  * (single-column matrix) as the second operand. To compute the vector
57  * outer product, simply transpose the second argument rather than the
58  * first. These computations involve \f$N\f$ additions and multiplications
59  * per element of the output matrix.
60  *
61  * The transpose \f$(\mathsf{X}^T){}^a{}_b\f$ of a matrix
62  * \f$\mathsf{X}^a{}_b\f$ is given by \f$(X^T){}^i{}_j=X^j{}_i\f$.
63  * Transposition involves no arithmetic operations, just one assignment per
64  * element of the output.
65  */
66 
67 #include <lal/LALStdlib.h>
68 #include <lal/MatrixUtils.h>
69 
70 void
72 {
73  UINT4 i, j, k, ni, nj, nk; /* dimension indices and ranges */
74  UINT4 ij, ik, kj, in, kn; /* array indices */
75  REAL8 *outData, *in1Data, *in2Data; /* data pointers */
76 
77  INITSTATUS(stat);
78 
79  /* Check for valid input arguments. */
83  ASSERT( out->dimLength->data, stat, MATRIXUTILSH_ENUL,
88  ASSERT( in1->dimLength->data, stat, MATRIXUTILSH_ENUL,
93  ASSERT( in2->dimLength->data, stat, MATRIXUTILSH_ENUL,
95  ASSERT( out->dimLength->length == 2, stat, MATRIXUTILSH_EDIM,
97  ASSERT( in1->dimLength->length == 2, stat, MATRIXUTILSH_EDIM,
99  ASSERT( in2->dimLength->length == 2, stat, MATRIXUTILSH_EDIM,
101  ni = out->dimLength->data[0];
102  nj = out->dimLength->data[1];
103  nk = in1->dimLength->data[1];
104  ASSERT( in1->dimLength->data[0] == ni, stat, MATRIXUTILSH_EDIM,
106  ASSERT( in2->dimLength->data[0] == nk, stat, MATRIXUTILSH_EDIM,
108  ASSERT( in2->dimLength->data[1] == nj, stat, MATRIXUTILSH_EDIM,
110 
111  /* Do multiplication. */
112  outData = out->data;
113  in1Data = in1->data;
114  in2Data = in2->data;
115  for ( i = 0, in = 0, kn = 0; i < ni; i++, in += nj, kn += nk ) {
116  for ( j = 0, ij = in; j < nj; j++, ij++ ) {
117  outData[ij] = 0.0;
118  for ( k = 0, ik = kn, kj = j; k < nk; k++, ik++, kj += nj ) {
119  outData[ij] += in1Data[ik]*in2Data[kj];
120  }
121  }
122  }
123  RETURN( stat );
124 }
125 
126 
127 void
129 {
130  UINT4 i, j, ni, nj; /* dimension indices and ranges */
131  UINT4 ij, ji, in; /* array indices */
132  REAL8 *outData, *in1Data; /* data pointers */
133 
134  INITSTATUS(stat);
135 
136  /* Check for valid input arguments. */
140  ASSERT( out->dimLength->data, stat, MATRIXUTILSH_ENUL,
145  ASSERT( in1->dimLength->data, stat, MATRIXUTILSH_ENUL,
147  ASSERT( out->dimLength->length == 2, stat, MATRIXUTILSH_EDIM,
149  ASSERT( in1->dimLength->length == 2, stat, MATRIXUTILSH_EDIM,
151  ni = out->dimLength->data[0];
152  nj = out->dimLength->data[1];
153  ASSERT( in1->dimLength->data[1] == ni, stat, MATRIXUTILSH_EDIM,
155  ASSERT( in1->dimLength->data[0] == nj, stat, MATRIXUTILSH_EDIM,
157 
158  /* Do transposition. */
159  outData = out->data;
160  in1Data = in1->data;
161  for ( i = 0, in = 0; i < ni; i++, in += nj ) {
162  for ( j = 0, ij = in, ji = i; j < nj; j++, ij++, ji += ni ) {
163  outData[ij] = in1Data[ji];
164  }
165  }
166  RETURN( stat );
167 }
#define ASSERT(assertion, statusptr, code, mesg)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define MATRIXUTILSH_MSGEDIM
Definition: MatrixUtils.h:138
#define MATRIXUTILSH_MSGENUL
Definition: MatrixUtils.h:137
double REAL8
Double precision real floating-point number (8 bytes).
uint32_t UINT4
Four-byte unsigned integer.
void LALDMatrixMultiply(LALStatus *stat, REAL8Array *out, REAL8Array *in1, REAL8Array *in2)
Definition: MatrixOps.c:71
void LALDMatrixTranspose(LALStatus *stat, REAL8Array *out, REAL8Array *in1)
Definition: MatrixOps.c:128
#define MATRIXUTILSH_ENUL
Unexpected null pointer in arguments.
Definition: MatrixUtils.h:128
#define MATRIXUTILSH_EDIM
Bad matrix dimensions.
Definition: MatrixUtils.h:129
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
Multidimentional array of REAL8, see DATATYPE-Array types for more details.
Definition: LALDatatypes.h:226
UINT4Vector * dimLength
Vector of array dimensions.
Definition: LALDatatypes.h:227
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:228
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:122
UINT4 * data
Pointer to the data array.
Definition: LALDatatypes.h:123