BRL-CAD
bn_complex.c
Go to the documentation of this file.
1 /* B N _ C O M P L E X . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2013-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "bu.h"
28 #include "bn.h"
29 
30 static int
31 test_bn_cx_div(int argc, char **argv)
32 {
33  /* We don't need an actual_result because bn_cx_div stores the
34  result in ap */
35  bn_complex_t expected_result = { 0.0, 0.0 };
36  bn_complex_t ap = { 0.0, 0.0 };
37  bn_complex_t bp = { 0.0, 0.0 };
38 
39  if (argc != 5) {
40  bu_exit(1, "ERROR: input format is APre,APim BPre,BPim expected_re,expected_im [%s]\n", argv[0]);
41  }
42 
43  sscanf(argv[2], "%lg,%lg", &bn_cx_real(&ap), &bn_cx_imag(&ap));
44  sscanf(argv[3], "%lg,%lg", &bn_cx_real(&bp), &bn_cx_imag(&bp));
45  sscanf(argv[4], "%lg,%lg", &bn_cx_real(&expected_result), &bn_cx_imag(&expected_result));
46 
47  bn_cx_div(&ap, &bp);
48 
49  bu_log("result: %g + %g * i\n", bn_cx_real(&ap), bn_cx_imag(&ap));
50 
51  return !(NEAR_EQUAL(bn_cx_real(&expected_result), bn_cx_real(&ap), BN_TOL_DIST)
52  && NEAR_EQUAL(bn_cx_imag(&expected_result), bn_cx_imag(&ap), BN_TOL_DIST));
53 }
54 
55 static int
56 test_bn_cx_mul(int argc, char **argv)
57 {
58  /* We need an actual_result even though bn_cx_mul stores the
59  result in ap because we also test bn_cx_mul2 */
60  bn_complex_t expected_result = { 0.0, 0.0 };
61  bn_complex_t actual_result = { 0.0, 0.0 };
62  bn_complex_t ap = { 0.0, 0.0 };
63  bn_complex_t bp = { 0.0, 0.0 };
64 
65  if (argc != 5) {
66  bu_exit(1, "ERROR: input format is APre,APim BPre,BPim expected_re,expected_im [%s]\n", argv[0]);
67  }
68 
69  sscanf(argv[2], "%lg,%lg", &bn_cx_real(&ap), &bn_cx_imag(&ap));
70  sscanf(argv[3], "%lg,%lg", &bn_cx_real(&bp), &bn_cx_imag(&bp));
71  sscanf(argv[4], "%lg,%lg", &bn_cx_real(&expected_result), &bn_cx_imag(&expected_result));
72 
73  bn_cx_mul2(&actual_result, &ap, &bp)
74  bn_cx_mul(&ap, &bp);
75 
76  bu_log("bn_cx_mul: result: %g + %g * i\n", bn_cx_real(&ap), bn_cx_imag(&ap));
77  bu_log("bn_cx_mul2: result: %g + %g * i\n", bn_cx_real(&ap), bn_cx_imag(&ap));
78 
79  return !(NEAR_EQUAL(bn_cx_real(&expected_result), bn_cx_real(&actual_result), BN_TOL_DIST)
80  && NEAR_EQUAL(bn_cx_imag(&expected_result), bn_cx_imag(&actual_result), BN_TOL_DIST)
81  && NEAR_EQUAL(bn_cx_real(&expected_result), bn_cx_real(&ap), BN_TOL_DIST)
82  && NEAR_EQUAL(bn_cx_imag(&expected_result), bn_cx_imag(&ap), BN_TOL_DIST));
83 }
84 
85 static int
86 test_bn_cx_sub(int argc, char **argv)
87 {
88  /* We don't need an actual_result because bn_cx_sub stores the
89  result in ap */
90  bn_complex_t expected_result = { 0.0, 0.0 };
91  bn_complex_t ap = { 0.0, 0.0 };
92  bn_complex_t bp = { 0.0, 0.0 };
93 
94  if (argc != 5) {
95  bu_exit(1, "ERROR: input format is APre,APim BPre,BPim expected_re,expected_im [%s]\n", argv[0]);
96  }
97 
98  sscanf(argv[2], "%lg,%lg", &bn_cx_real(&ap), &bn_cx_imag(&ap));
99  sscanf(argv[3], "%lg,%lg", &bn_cx_real(&bp), &bn_cx_imag(&bp));
100  sscanf(argv[4], "%lg,%lg", &bn_cx_real(&expected_result), &bn_cx_imag(&expected_result));
101 
102  bn_cx_sub(&ap, &bp);
103 
104  bu_log("result: %g + %g * i\n", bn_cx_real(&ap), bn_cx_imag(&ap));
105 
106  return !(NEAR_EQUAL(bn_cx_real(&expected_result), bn_cx_real(&ap), BN_TOL_DIST)
107  && NEAR_EQUAL(bn_cx_imag(&expected_result), bn_cx_imag(&ap), BN_TOL_DIST));
108 }
109 
110 static int
111 test_bn_cx_add(int argc, char **argv)
112 {
113  /* We don't need an actual_result because bn_cx_add stores the
114  result in ap */
115  bn_complex_t expected_result = { 0.0, 0.0 };
116  bn_complex_t ap = { 0.0, 0.0 };
117  bn_complex_t bp = { 0.0, 0.0 };
118 
119  if (argc != 5) {
120  bu_exit(1, "ERROR: input format is APre,APim BPre,BPim expected_re,expected_im [%s]\n", argv[0]);
121  }
122 
123  sscanf(argv[2], "%lg,%lg", &bn_cx_real(&ap), &bn_cx_imag(&ap));
124  sscanf(argv[3], "%lg,%lg", &bn_cx_real(&bp), &bn_cx_imag(&bp));
125  sscanf(argv[4], "%lg,%lg", &bn_cx_real(&expected_result), &bn_cx_imag(&expected_result));
126 
127  bn_cx_add(&ap, &bp);
128 
129  bu_log("result: %g + %g * i\n", bn_cx_real(&ap), bn_cx_imag(&ap));
130 
131  return !(NEAR_EQUAL(bn_cx_real(&expected_result), bn_cx_real(&ap), BN_TOL_DIST)
132  && NEAR_EQUAL(bn_cx_imag(&expected_result), bn_cx_imag(&ap), BN_TOL_DIST));
133 }
134 
135 static int
136 test_bn_cx_sqrt(int argc, char **argv)
137 {
138  bn_complex_t expected_result = { 0.0, 0.0 };
139  bn_complex_t actual_result = { 0.0, 0.0 };
140  bn_complex_t ip = { 0.0, 0.0 };
141 
142  if (argc != 4) {
143  bu_exit(1, "ERROR: input format is IPre,IPim expected_re,expected_im [%s]\n", argv[0]);
144  }
145 
146  sscanf(argv[2], "%lg,%lg", &bn_cx_real(&ip), &bn_cx_imag(&ip));
147  sscanf(argv[3], "%lg,%lg", &bn_cx_real(&expected_result), &bn_cx_imag(&expected_result));
148 
149  bn_cx_sqrt(&actual_result, &ip);
150 
151  bu_log("result: %g + %g * i\n", bn_cx_real(&actual_result), bn_cx_imag(&actual_result));
152 
153  return !(NEAR_EQUAL(bn_cx_real(&expected_result), bn_cx_real(&actual_result), BN_TOL_DIST)
154  && NEAR_EQUAL(bn_cx_imag(&expected_result), bn_cx_imag(&actual_result), BN_TOL_DIST));
155 }
156 
157 static int
158 test_bn_cx_neg(int argc, char **argv)
159 {
160  /* We don't need an actual_result because bn_cx_neg stores the
161  result in ip */
162  bn_complex_t expected_result = { 0.0, 0.0 };
163  bn_complex_t ip = { 0.0, 0.0 };
164 
165  if (argc != 4) {
166  bu_exit(1, "ERROR: input format is IPre,IPim expected_re,expected_im [%s]\n", argv[0]);
167  }
168 
169  sscanf(argv[2], "%lg,%lg", &bn_cx_real(&ip), &bn_cx_imag(&ip));
170  sscanf(argv[3], "%lg,%lg", &bn_cx_real(&expected_result), &bn_cx_imag(&expected_result));
171 
172  bn_cx_neg(&ip);
173 
174  bu_log("result: %g + %g * i\n", bn_cx_real(&ip), bn_cx_imag(&ip));
175 
176  return !(NEAR_EQUAL(bn_cx_real(&expected_result), bn_cx_real(&ip), BN_TOL_DIST)
177  && NEAR_EQUAL(bn_cx_imag(&expected_result), bn_cx_imag(&ip), BN_TOL_DIST));
178 }
179 
180 static int
181 test_bn_cx_conj(int argc, char **argv)
182 {
183  /* We don't need an actual_result because bn_cx_conj stores the
184  result in ip */
185  bn_complex_t expected_result = { 0.0, 0.0 };
186  bn_complex_t ip = { 0.0, 0.0 };
187 
188  if (argc != 4) {
189  bu_exit(1, "ERROR: input format is IPre,IPim expected_re,expected_im [%s]\n", argv[0]);
190  }
191 
192  sscanf(argv[2], "%lg,%lg", &bn_cx_real(&ip), &bn_cx_imag(&ip));
193  sscanf(argv[3], "%lg,%lg", &bn_cx_real(&expected_result), &bn_cx_imag(&expected_result));
194 
195  bn_cx_conj(&ip);
196 
197  bu_log("result: %g + %g * i\n", bn_cx_real(&ip), bn_cx_imag(&ip));
198 
199  return !(NEAR_EQUAL(bn_cx_real(&expected_result), bn_cx_real(&ip), BN_TOL_DIST)
200  && NEAR_EQUAL(bn_cx_imag(&expected_result), bn_cx_imag(&ip), BN_TOL_DIST));
201 }
202 
203 static int
204 test_bn_cx_parts(int argc, char **argv)
205 {
206  fastf_t expected_re = 0;
207  fastf_t actual_re = 0;
208  fastf_t expected_im = 0;
209  fastf_t actual_im = 0;
210  bn_complex_t ip = { 0.0, 0.0 };
211 
212  if (argc != 4) {
213  bu_exit(1, "ERROR: input format is IPre,IPim expected_re,expected_im [%s]\n", argv[0]);
214  }
215 
216  sscanf(argv[2], "%lg,%lg", &bn_cx_real(&ip), &bn_cx_imag(&ip));
217  sscanf(argv[3], "%lg,%lg", &expected_re, &expected_im);
218 
219  actual_re = bn_cx_real(&ip);
220  actual_im = bn_cx_imag(&ip);
221 
222  bu_log("real: %g", actual_re);
223  bu_log("imaginary: %g", actual_im);
224 
225  return !(NEAR_EQUAL(expected_re, actual_re, BN_TOL_DIST)
226  && NEAR_EQUAL(expected_im, actual_im, BN_TOL_DIST));
227 }
228 
229 int
230 main(int argc, char *argv[])
231 {
232  int function_num = 0;
233 
234  if (argc < 3) {
235  bu_exit(1, "ERROR: input format is function_num function_test_args [%s]\n", argv[0]);
236  }
237 
238  sscanf(argv[1], "%d", &function_num);
239  if (function_num < 1 || function_num > 8)
240  function_num = 0;
241 
242  switch (function_num) {
243  case 1:
244  return test_bn_cx_div(argc, argv);
245  case 2:
246  return test_bn_cx_mul(argc, argv);
247  case 3:
248  return test_bn_cx_sub(argc, argv);
249  case 4:
250  return test_bn_cx_add(argc, argv);
251  case 5:
252  return test_bn_cx_sqrt(argc, argv);
253  case 6:
254  return test_bn_cx_neg(argc, argv);
255  case 7:
256  return test_bn_cx_conj(argc, argv);
257  case 8:
258  return test_bn_cx_parts(argc, argv);
259  }
260 
261  bu_log("ERROR: function_num %d is not valid [%s]\n", function_num, argv[0]);
262  return 1;
263 }
264 
265 
266 /** @} */
267 /*
268  * Local Variables:
269  * mode: C
270  * tab-width: 8
271  * indent-tabs-mode: t
272  * c-file-style: "stroustrup"
273  * End:
274  * ex: shiftwidth=4 tabstop=8
275  */
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define bn_cx_sub(ap, bp)
Definition: complex.h:58
int main(int argc, char *argv[])
Definition: bn_complex.c:230
Header file for the BRL-CAD common definitions.
void bu_exit(int status, const char *fmt,...) _BU_ATTR_NORETURN _BU_ATTR_PRINTF23
Definition: bomb.c:195
unsigned char * bp
Definition: rot.c:56
#define bn_cx_real(cp)
Definition: complex.h:48
#define bn_cx_add(ap, bp)
Definition: complex.h:51
#define BN_TOL_DIST
Definition: tol.h:109
#define bn_cx_mul2(ap, bp, cp)
Definition: complex.h:66
void bn_cx_div(bn_complex_t *ap, const bn_complex_t *bp)
Divide one complex by another.
#define bn_cx_neg(cp)
Definition: complex.h:47
#define bn_cx_mul(ap, bp)
Definition: complex.h:60
Complex numbers.
Definition: complex.h:39
double fastf_t
Definition: defines.h:300
void bn_cx_sqrt(bn_complex_t *op, const bn_complex_t *ip)
Compute square root of complex number.
Definition: complex.c:66
#define bn_cx_imag(cp)
Definition: complex.h:49
#define bn_cx_conj(cp)
Definition: complex.h:54