LAL  7.5.0.1-b72065a
VectorMultiply.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 #include <complex.h>
21 #include <math.h>
22 #include <lal/LALStdlib.h>
23 #include <lal/VectorOps.h>
24 
25 /**
26  * \addtogroup VectorMultiply_c
27  * \author J. D. E. Creighton, T. D. Creighton, A. M. Sintes
28  *
29  * \brief Multiply two vectors.
30  *
31  * Let \c u, \c v, and \c w be objects of type
32  * \c COMPLEX8Vector, and let \c a, \c b, and \c c be
33  * objects of type \c REAL4Vector.
34  *
35  * The \ref LALCCVectorMultiply "LALCCVectorMultiply( &status, &w, &u, &v )" function computes:<br>
36  * <tt>w.data[i]= u.data[i] x v.data[i]</tt>
37  *
38  * The \ref LALCCVectorMultiplyConjugate "LALCCVectorMultiplyConjugate( &status, &w, &u, &v )" function computes:<br>
39  * <tt>w.data[i]=u.data[i] x v.data[i]*</tt>.
40  *
41  * The \ref LALCCVectorDivide "LALCCVectorDivide( &status, &w, &u, &v )" function computes:<br>
42  * <tt>w.data[i]= u.data[i] / v.data[i]</tt>
43  *
44  * The \ref LALSCVectorMultiply "LALSCVectorMultiply( &status, &w, &a, &v )" function computes:<br>
45  * <tt>w.data[i]=a.data[i] x v.data[i]</tt>
46  *
47  * The \ref LALSSVectorMultiply "LALSSVectorMultiply( &status, &c, &a, &b )" function computes:<br>
48  * <tt>c.data[i]=a.data[i] x b.data[i]</tt>
49  *
50  * The double-precison multiply routines (with \c D or \c Z names) work similarly.
51  *
52  * ### Algorithm ###
53  *
54  * The algorithm for complex division is described in
55  * Sec. 5.4 of Ref. \cite ptvf1992 . The formula used is:
56  * \f[
57  * \frac{a + ib}{c + id} = \left\{
58  * \begin{array}{ll}
59  * \frac{[a + b(d/c)] + i[b - a(d/c)]}{c + d(d/c)} & |c| \ge |d| \\
60  * \frac{[a(c/d) + b] + i[b(c/d) - a]}{c(c/d) + d} & |c| < |d|.
61  * \end{array}
62  * \right.
63  * \f]
64  */
65 
66 /** @{ */
67 
69  COMPLEX8Vector *out,
70  const COMPLEX8Vector *in1,
71  const COMPLEX8Vector *in2
72  )
73 {
74  COMPLEX8 *a;
75  COMPLEX8 *b;
76  COMPLEX8 *c;
77  INT4 n;
78 
79  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
81  if ( ! out->length )
83  if ( in1->length != out->length || in2->length != out->length )
85 
86  a = in1->data;
87  b = in2->data;
88  c = out->data;
89  n = out->length;
90 
91  while (n-- > 0)
92  *c++ = *a++ / *b++;
93 
94  return out;
95 }
96 
97 
99  COMPLEX16Vector *out,
100  const COMPLEX16Vector *in1,
101  const COMPLEX16Vector *in2
102  )
103 {
104  COMPLEX16 *a;
105  COMPLEX16 *b;
106  COMPLEX16 *c;
107  INT4 n;
108 
109  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
111  if ( ! out->length )
113  if ( in1->length != out->length || in2->length != out->length )
115 
116  a = in1->data;
117  b = in2->data;
118  c = out->data;
119  n = out->length;
120 
121  while (n-- > 0)
122  *c++ = *a++ / *b++;
123 
124  return out;
125 }
126 
127 
129  COMPLEX8Vector *out,
130  const COMPLEX8Vector *in1,
131  const COMPLEX8Vector *in2
132  )
133 {
134  COMPLEX8 *a;
135  COMPLEX8 *b;
136  COMPLEX8 *c;
137  INT4 n;
138 
139  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
141  if ( ! out->length )
143  if ( in1->length != out->length || in2->length != out->length )
145 
146  a = in1->data;
147  b = in2->data;
148  c = out->data;
149  n = out->length;
150 
151  while (n-- > 0)
152  *c++ = *a++ * *b++;
153 
154  return out;
155 }
156 
157 
159  COMPLEX16Vector *out,
160  const COMPLEX16Vector *in1,
161  const COMPLEX16Vector *in2
162  )
163 {
164  COMPLEX16 *a;
165  COMPLEX16 *b;
166  COMPLEX16 *c;
167  INT4 n;
168 
169  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
171  if ( ! out->length )
173  if ( in1->length != out->length || in2->length != out->length )
175 
176  a = in1->data;
177  b = in2->data;
178  c = out->data;
179  n = out->length;
180 
181  while (n-- > 0)
182  *c++ = *a++ * *b++;
183 
184  return out;
185 }
186 
187 
189  COMPLEX8Vector *out,
190  const COMPLEX8Vector *in1,
191  const COMPLEX8Vector *in2
192  )
193 {
194  COMPLEX8 *a;
195  COMPLEX8 *b;
196  COMPLEX8 *c;
197  INT4 n;
198 
199  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
201  if ( ! out->length )
203  if ( in1->length != out->length || in2->length != out->length )
205 
206  a = in1->data;
207  b = in2->data;
208  c = out->data;
209  n = out->length;
210 
211  while (n-- > 0)
212  *c++ = *a++ * conjf(*b++);
213 
214  return out;
215 }
216 
217 
219  COMPLEX16Vector *out,
220  const COMPLEX16Vector *in1,
221  const COMPLEX16Vector *in2
222  )
223 {
224  COMPLEX16 *a;
225  COMPLEX16 *b;
226  COMPLEX16 *c;
227  INT4 n;
228 
229  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
231  if ( ! out->length )
233  if ( in1->length != out->length || in2->length != out->length )
235 
236  a = in1->data;
237  b = in2->data;
238  c = out->data;
239  n = out->length;
240 
241  while (n-- > 0)
242  *c++ = *a++ * conj(*b++);
243 
244  return out;
245 }
246 
247 
249  COMPLEX8Vector *out,
250  const REAL4Vector *in1,
251  const COMPLEX8Vector *in2
252  )
253 {
254  REAL4 *a;
255  COMPLEX8 *b;
256  COMPLEX8 *c;
257  INT4 n;
258 
259  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
261  if ( ! out->length )
263  if ( in1->length != out->length || in2->length != out->length )
265 
266  a = in1->data;
267  b = in2->data;
268  c = out->data;
269  n = out->length;
270 
271  while (n-- > 0)
272  *c++ = *a++ * *b++;
273 
274  return out;
275 }
276 
278  COMPLEX16Vector *out,
279  const REAL8Vector *in1,
280  const COMPLEX16Vector *in2
281  )
282 {
283  REAL8 *a;
284  COMPLEX16 *b;
285  COMPLEX16 *c;
286  INT4 n;
287 
288  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
290  if ( ! out->length )
292  if ( in1->length != out->length || in2->length != out->length )
294 
295  a = in1->data;
296  b = in2->data;
297  c = out->data;
298  n = out->length;
299 
300  while (n-- > 0)
301  *c++ = *a++ * *b++;
302 
303  return out;
304 }
305 
306 
308  REAL4Vector *out,
309  const REAL4Vector *in1,
310  const REAL4Vector *in2
311  )
312 {
313  REAL4 *a;
314  REAL4 *b;
315  REAL4 *c;
316  INT4 n;
317 
318  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
320  if ( ! out->length )
322  if ( in1->length != out->length || in2->length != out->length )
324 
325  a = in1->data;
326  b = in2->data;
327  c = out->data;
328  n = out->length;
329 
330  while (n-- > 0)
331  *c++ = (*a++)*(*b++);
332 
333  return out;
334 }
335 
336 
338  REAL8Vector *out,
339  const REAL8Vector *in1,
340  const REAL8Vector *in2
341  )
342 {
343  REAL8 *a;
344  REAL8 *b;
345  REAL8 *c;
346  INT4 n;
347 
348  if ( ! out || ! in1 || !in2 || ! out->data || ! in1->data || ! in2->data )
350  if ( ! out->length )
352  if ( in1->length != out->length || in2->length != out->length )
354 
355  a = in1->data;
356  b = in2->data;
357  c = out->data;
358  n = out->length;
359 
360  while (n-- > 0)
361  *c++ = (*a++)*(*b++);
362 
363  return out;
364 }
365 
366 
367 /*
368  *
369  * LAL Routines.
370  *
371  */
372 
373 
374 
375 /** UNDOCUMENTED */
376 void
378  LALStatus *status,
379  COMPLEX8Vector *out,
380  const COMPLEX8Vector *in1,
381  const COMPLEX8Vector *in2
382  )
383 {
385 
388 
390 
394 
396  ASSERT (in1->length == out->length, status,
398  ASSERT (in2->length == out->length, status,
400 
401  XLALCCVectorDivide(out, in1, in2);
402 
403  RETURN (status);
404 }
405 
406 
407 
408 void
410  LALStatus *status,
411  COMPLEX16Vector *out,
412  const COMPLEX16Vector *in1,
413  const COMPLEX16Vector *in2
414  )
415 {
417 
420 
422 
426 
428  ASSERT (in1->length == out->length, status,
430  ASSERT (in2->length == out->length, status,
432 
433  XLALZZVectorDivide(out, in1, in2);
434 
435  RETURN (status);
436 }
437 
438 
439 
440 /** UNDOCUMENTED */
441 void
443  LALStatus *status,
444  COMPLEX8Vector *out,
445  const COMPLEX8Vector *in1,
446  const COMPLEX8Vector *in2
447  )
448 {
450 
453 
455 
459 
461  ASSERT (in1->length == out->length, status,
463  ASSERT (in2->length == out->length, status,
465 
466  XLALCCVectorMultiply(out, in1, in2);
467 
468  RETURN (status);
469 }
470 
471 
472 
473 void
475  LALStatus *status,
476  COMPLEX16Vector *out,
477  const COMPLEX16Vector *in1,
478  const COMPLEX16Vector *in2
479  )
480 {
482 
485 
487 
491 
493  ASSERT (in1->length == out->length, status,
495  ASSERT (in2->length == out->length, status,
497 
498  XLALZZVectorMultiply(out, in1, in2);
499 
500  RETURN (status);
501 }
502 
503 
504 /** UNDOCUMENTED */
505 void
507  LALStatus *status,
508  COMPLEX8Vector *out,
509  const COMPLEX8Vector *in1,
510  const COMPLEX8Vector *in2
511  )
512 {
514 
517 
519 
523 
525  ASSERT (in1->length == out->length, status,
527  ASSERT (in2->length == out->length, status,
529 
530  XLALCCVectorMultiplyConjugate(out, in1, in2);
531 
532  RETURN (status);
533 }
534 
535 
536 
537 void
539  LALStatus *status,
540  COMPLEX16Vector *out,
541  const COMPLEX16Vector *in1,
542  const COMPLEX16Vector *in2
543  )
544 {
546 
549 
551 
555 
557  ASSERT (in1->length == out->length, status,
559  ASSERT (in2->length == out->length, status,
561 
562  XLALZZVectorMultiplyConjugate(out, in1, in2);
563 
564  RETURN (status);
565 }
566 
567 
568 /** UNDOCUMENTED */
569 void
571  LALStatus *status,
572  COMPLEX8Vector *out,
573  const REAL4Vector *in1,
574  const COMPLEX8Vector *in2
575  )
576 {
578 
581 
583 
587 
589  ASSERT (in1->length == out->length, status,
591  ASSERT (in2->length == out->length, status,
593 
594  XLALSCVectorMultiply(out, in1, in2);
595 
596  RETURN (status);
597 }
598 
599 
600 
601 void
603  LALStatus *status,
604  COMPLEX16Vector *out,
605  const REAL8Vector *in1,
606  const COMPLEX16Vector *in2
607  )
608 {
610 
613 
615 
619 
621  ASSERT (in1->length == out->length, status,
623  ASSERT (in2->length == out->length, status,
625 
626  XLALDZVectorMultiply(out, in1, in2);
627 
628  RETURN (status);
629 }
630 
631 
632 /** UNDOCUMENTED */
633 void
635  LALStatus *status,
636  REAL4Vector *out,
637  const REAL4Vector *in1,
638  const REAL4Vector *in2
639  )
640 {
642 
645 
647 
651 
653  ASSERT (in1->length == out->length, status,
655  ASSERT (in2->length == out->length, status,
657 
658  XLALSSVectorMultiply(out, in1, in2);
659 
660  RETURN (status);
661 }
662 
663 
664 
665 void
667  LALStatus *status,
668  REAL8Vector *out,
669  const REAL8Vector *in1,
670  const REAL8Vector *in2
671  )
672 {
674 
677 
679 
683 
685  ASSERT (in1->length == out->length, status,
687  ASSERT (in2->length == out->length, status,
689 
690  XLALDDVectorMultiply(out, in1, in2);
691 
692  RETURN (status);
693 }
694 /** @} */
#define ASSERT(assertion, statusptr, code, mesg)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define VECTOROPSH_MSGESIZE
Definition: VectorOps.h:59
#define VECTOROPSH_MSGESZMM
Definition: VectorOps.h:60
#define VECTOROPSH_MSGENULL
Definition: VectorOps.h:58
double complex COMPLEX16
Double-precision floating-point complex number (16 bytes total)
double REAL8
Double precision real floating-point number (8 bytes).
float complex COMPLEX8
Single-precision floating-point complex number (8 bytes total)
int32_t INT4
Four-byte signed integer.
float REAL4
Single precision real floating-point number (4 bytes).
static const INT4 a
Definition: Random.c:79
void LALZZVectorMultiply(LALStatus *status, COMPLEX16Vector *out, const COMPLEX16Vector *in1, const COMPLEX16Vector *in2)
void LALCCVectorDivide(LALStatus *status, COMPLEX8Vector *out, const COMPLEX8Vector *in1, const COMPLEX8Vector *in2)
UNDOCUMENTED.
void LALDZVectorMultiply(LALStatus *status, COMPLEX16Vector *out, const REAL8Vector *in1, const COMPLEX16Vector *in2)
COMPLEX8Vector * XLALSCVectorMultiply(COMPLEX8Vector *out, const REAL4Vector *in1, const COMPLEX8Vector *in2)
COMPLEX16Vector * XLALZZVectorMultiply(COMPLEX16Vector *out, const COMPLEX16Vector *in1, const COMPLEX16Vector *in2)
void LALZZVectorDivide(LALStatus *status, COMPLEX16Vector *out, const COMPLEX16Vector *in1, const COMPLEX16Vector *in2)
REAL4Vector * XLALSSVectorMultiply(REAL4Vector *out, const REAL4Vector *in1, const REAL4Vector *in2)
void LALSSVectorMultiply(LALStatus *status, REAL4Vector *out, const REAL4Vector *in1, const REAL4Vector *in2)
UNDOCUMENTED.
COMPLEX8Vector * XLALCCVectorMultiply(COMPLEX8Vector *out, const COMPLEX8Vector *in1, const COMPLEX8Vector *in2)
void LALSCVectorMultiply(LALStatus *status, COMPLEX8Vector *out, const REAL4Vector *in1, const COMPLEX8Vector *in2)
UNDOCUMENTED.
COMPLEX16Vector * XLALZZVectorDivide(COMPLEX16Vector *out, const COMPLEX16Vector *in1, const COMPLEX16Vector *in2)
void LALCCVectorMultiplyConjugate(LALStatus *status, COMPLEX8Vector *out, const COMPLEX8Vector *in1, const COMPLEX8Vector *in2)
UNDOCUMENTED.
REAL8Vector * XLALDDVectorMultiply(REAL8Vector *out, const REAL8Vector *in1, const REAL8Vector *in2)
void LALZZVectorMultiplyConjugate(LALStatus *status, COMPLEX16Vector *out, const COMPLEX16Vector *in1, const COMPLEX16Vector *in2)
COMPLEX16Vector * XLALZZVectorMultiplyConjugate(COMPLEX16Vector *out, const COMPLEX16Vector *in1, const COMPLEX16Vector *in2)
void LALCCVectorMultiply(LALStatus *status, COMPLEX8Vector *out, const COMPLEX8Vector *in1, const COMPLEX8Vector *in2)
UNDOCUMENTED.
COMPLEX8Vector * XLALCCVectorMultiplyConjugate(COMPLEX8Vector *out, const COMPLEX8Vector *in1, const COMPLEX8Vector *in2)
COMPLEX16Vector * XLALDZVectorMultiply(COMPLEX16Vector *out, const REAL8Vector *in1, const COMPLEX16Vector *in2)
COMPLEX8Vector * XLALCCVectorDivide(COMPLEX8Vector *out, const COMPLEX8Vector *in1, const COMPLEX8Vector *in2)
void LALDDVectorMultiply(LALStatus *status, REAL8Vector *out, const REAL8Vector *in1, const REAL8Vector *in2)
#define VECTOROPSH_ESIZE
Invalid input size.
Definition: VectorOps.h:52
#define VECTOROPSH_ENULL
Null pointer.
Definition: VectorOps.h:51
#define VECTOROPSH_ESZMM
Size mismatch.
Definition: VectorOps.h:53
#define XLAL_ERROR_NULL(...)
Macro to invoke a failure from a XLAL routine returning a pointer.
Definition: XLALError.h:713
@ XLAL_EBADLEN
Inconsistent or invalid length.
Definition: XLALError.h:419
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
Vector of type COMPLEX16, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:172
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:176
COMPLEX16 * data
Pointer to the data array.
Definition: LALDatatypes.h:177
Vector of type COMPLEX8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:163
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:167
COMPLEX8 * data
Pointer to the data array.
Definition: LALDatatypes.h:168
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
Vector of type REAL4, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:145
REAL4 * data
Pointer to the data array.
Definition: LALDatatypes.h:150
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:149
Vector of type REAL8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:154
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:159
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:158