Mercurial > hg > octave-nkf
comparison liboctave/CColVector.cc @ 458:38cb88095913
[project @ 1994-06-06 00:41:10 by jwe]
Initial revision
author | jwe |
---|---|
date | Mon, 06 Jun 1994 00:41:10 +0000 |
parents | |
children | 2ca256b77602 |
comparison
equal
deleted
inserted
replaced
457:3d4b4f0fa5ba | 458:38cb88095913 |
---|---|
1 // ColumnVector manipulations. -*- C++ -*- | |
2 /* | |
3 | |
4 Copyright (C) 1992, 1993, 1994 John W. Eaton | |
5 | |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with Octave; see the file COPYING. If not, write to the Free | |
20 Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
21 | |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include "config.h" | |
26 #endif | |
27 | |
28 #if defined (__GNUG__) | |
29 #pragma implementation | |
30 #endif | |
31 | |
32 #include <iostream.h> | |
33 | |
34 #include <Complex.h> | |
35 | |
36 #include "mx-base.h" | |
37 #include "mx-inlines.cc" | |
38 #include "f77-uscore.h" | |
39 #include "lo-error.h" | |
40 | |
41 // Fortran functions we call. | |
42 | |
43 extern "C" | |
44 { | |
45 int F77_FCN (zgemm) (const char*, const char*, const int*, | |
46 const int*, const int*, const Complex*, | |
47 const Complex*, const int*, const Complex*, | |
48 const int*, const Complex*, Complex*, const int*, | |
49 long, long); | |
50 } | |
51 | |
52 /* | |
53 * Complex Column Vector class | |
54 */ | |
55 | |
56 #define KLUDGE_VECTORS | |
57 #define TYPE Complex | |
58 #define KL_VEC_TYPE ComplexColumnVector | |
59 #include "mx-kludge.cc" | |
60 #undef KLUDGE_VECTORS | |
61 #undef TYPE | |
62 #undef KL_VEC_TYPE | |
63 | |
64 ComplexColumnVector::ComplexColumnVector (const ColumnVector& a) | |
65 : Array<Complex> (a.length ()) | |
66 { | |
67 for (int i = 0; i < length (); i++) | |
68 elem (i) = a.elem (i); | |
69 } | |
70 | |
71 #if 0 | |
72 ComplexColumnVector& | |
73 ComplexColumnVector::resize (int n) | |
74 { | |
75 if (n < 0) | |
76 { | |
77 (*current_liboctave_error_handler) | |
78 ("can't resize to negative dimension"); | |
79 return *this; | |
80 } | |
81 | |
82 Complex *new_data = (Complex *) NULL; | |
83 if (n > 0) | |
84 { | |
85 new_data = new Complex [n]; | |
86 int min_len = len < n ? len : n; | |
87 | |
88 for (int i = 0; i < min_len; i++) | |
89 new_data[i] = data[i]; | |
90 } | |
91 | |
92 delete [] data; | |
93 len = n; | |
94 data = new_data; | |
95 | |
96 return *this; | |
97 } | |
98 | |
99 ComplexColumnVector& | |
100 ComplexColumnVector::resize (int n, double val) | |
101 { | |
102 int old_len = len; | |
103 resize (n); | |
104 for (int i = old_len; i < len; i++) | |
105 data[i] = val; | |
106 | |
107 return *this; | |
108 } | |
109 | |
110 ComplexColumnVector& | |
111 ComplexColumnVector::resize (int n, const Complex& val) | |
112 { | |
113 int old_len = len; | |
114 resize (n); | |
115 for (int i = old_len; i < len; i++) | |
116 data[i] = val; | |
117 | |
118 return *this; | |
119 } | |
120 #endif | |
121 | |
122 int | |
123 ComplexColumnVector::operator == (const ComplexColumnVector& a) const | |
124 { | |
125 int len = length (); | |
126 if (len != a.length ()) | |
127 return 0; | |
128 return equal (data (), a.data (), len); | |
129 } | |
130 | |
131 int | |
132 ComplexColumnVector::operator != (const ComplexColumnVector& a) const | |
133 { | |
134 return !(*this == a); | |
135 } | |
136 | |
137 // destructive insert/delete/reorder operations | |
138 | |
139 ComplexColumnVector& | |
140 ComplexColumnVector::insert (const ColumnVector& a, int r) | |
141 { | |
142 int a_len = a.length (); | |
143 if (r < 0 || r + a_len - 1 > length ()) | |
144 { | |
145 (*current_liboctave_error_handler) ("range error for insert"); | |
146 return *this; | |
147 } | |
148 | |
149 for (int i = 0; i < a_len; i++) | |
150 elem (r+i) = a.elem (i); | |
151 | |
152 return *this; | |
153 } | |
154 | |
155 ComplexColumnVector& | |
156 ComplexColumnVector::insert (const ComplexColumnVector& a, int r) | |
157 { | |
158 int a_len = a.length (); | |
159 if (r < 0 || r + a_len - 1 > length ()) | |
160 { | |
161 (*current_liboctave_error_handler) ("range error for insert"); | |
162 return *this; | |
163 } | |
164 | |
165 for (int i = 0; i < a_len; i++) | |
166 elem (r+i) = a.elem (i); | |
167 | |
168 return *this; | |
169 } | |
170 | |
171 ComplexColumnVector& | |
172 ComplexColumnVector::fill (double val) | |
173 { | |
174 int len = length (); | |
175 if (len > 0) | |
176 for (int i = 0; i < len; i++) | |
177 elem (i) = val; | |
178 return *this; | |
179 } | |
180 | |
181 ComplexColumnVector& | |
182 ComplexColumnVector::fill (const Complex& val) | |
183 { | |
184 int len = length (); | |
185 if (len > 0) | |
186 for (int i = 0; i < len; i++) | |
187 elem (i) = val; | |
188 return *this; | |
189 } | |
190 | |
191 ComplexColumnVector& | |
192 ComplexColumnVector::fill (double val, int r1, int r2) | |
193 { | |
194 int len = length (); | |
195 if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len) | |
196 { | |
197 (*current_liboctave_error_handler) ("range error for fill"); | |
198 return *this; | |
199 } | |
200 | |
201 if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; } | |
202 | |
203 for (int i = r1; i <= r2; i++) | |
204 elem (i) = val; | |
205 | |
206 return *this; | |
207 } | |
208 | |
209 ComplexColumnVector& | |
210 ComplexColumnVector::fill (const Complex& val, int r1, int r2) | |
211 { | |
212 int len = length (); | |
213 if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len) | |
214 { | |
215 (*current_liboctave_error_handler) ("range error for fill"); | |
216 return *this; | |
217 } | |
218 | |
219 if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; } | |
220 | |
221 for (int i = r1; i <= r2; i++) | |
222 elem (i) = val; | |
223 | |
224 return *this; | |
225 } | |
226 | |
227 ComplexColumnVector | |
228 ComplexColumnVector::stack (const ColumnVector& a) const | |
229 { | |
230 int len = length (); | |
231 int nr_insert = len; | |
232 ComplexColumnVector retval (len + a.length ()); | |
233 retval.insert (*this, 0); | |
234 retval.insert (a, nr_insert); | |
235 return retval; | |
236 } | |
237 | |
238 ComplexColumnVector | |
239 ComplexColumnVector::stack (const ComplexColumnVector& a) const | |
240 { | |
241 int len = length (); | |
242 int nr_insert = len; | |
243 ComplexColumnVector retval (len + a.length ()); | |
244 retval.insert (*this, 0); | |
245 retval.insert (a, nr_insert); | |
246 return retval; | |
247 } | |
248 | |
249 ComplexRowVector | |
250 ComplexColumnVector::hermitian (void) const | |
251 { | |
252 int len = length (); | |
253 return ComplexRowVector (conj_dup (data (), len), len); | |
254 } | |
255 | |
256 ComplexRowVector | |
257 ComplexColumnVector::transpose (void) const | |
258 { | |
259 int len = length (); | |
260 return ComplexRowVector (dup (data (), len), len); | |
261 } | |
262 | |
263 ColumnVector | |
264 real (const ComplexColumnVector& a) | |
265 { | |
266 int a_len = a.length (); | |
267 ColumnVector retval; | |
268 if (a_len > 0) | |
269 retval = ColumnVector (real_dup (a.data (), a_len), a_len); | |
270 return retval; | |
271 } | |
272 | |
273 ColumnVector | |
274 imag (const ComplexColumnVector& a) | |
275 { | |
276 int a_len = a.length (); | |
277 ColumnVector retval; | |
278 if (a_len > 0) | |
279 retval = ColumnVector (imag_dup (a.data (), a_len), a_len); | |
280 return retval; | |
281 } | |
282 | |
283 ComplexColumnVector | |
284 conj (const ComplexColumnVector& a) | |
285 { | |
286 int a_len = a.length (); | |
287 ComplexColumnVector retval; | |
288 if (a_len > 0) | |
289 retval = ComplexColumnVector (conj_dup (a.data (), a_len), a_len); | |
290 return retval; | |
291 } | |
292 | |
293 // resize is the destructive equivalent for this one | |
294 | |
295 ComplexColumnVector | |
296 ComplexColumnVector::extract (int r1, int r2) const | |
297 { | |
298 if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; } | |
299 | |
300 int new_r = r2 - r1 + 1; | |
301 | |
302 ComplexColumnVector result (new_r); | |
303 | |
304 for (int i = 0; i < new_r; i++) | |
305 result.elem (i) = elem (r1+i); | |
306 | |
307 return result; | |
308 } | |
309 | |
310 // column vector by column vector -> column vector operations | |
311 | |
312 ComplexColumnVector& | |
313 ComplexColumnVector::operator += (const ColumnVector& a) | |
314 { | |
315 int len = length (); | |
316 if (len != a.length ()) | |
317 { | |
318 (*current_liboctave_error_handler) | |
319 ("nonconformant vector += operation attempted"); | |
320 return *this; | |
321 } | |
322 | |
323 if (len == 0) | |
324 return *this; | |
325 | |
326 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
327 | |
328 add2 (d, a.data (), len); | |
329 return *this; | |
330 } | |
331 | |
332 ComplexColumnVector& | |
333 ComplexColumnVector::operator -= (const ColumnVector& a) | |
334 { | |
335 int len = length (); | |
336 if (len != a.length ()) | |
337 { | |
338 (*current_liboctave_error_handler) | |
339 ("nonconformant vector -= operation attempted"); | |
340 return *this; | |
341 } | |
342 | |
343 if (len == 0) | |
344 return *this; | |
345 | |
346 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
347 | |
348 subtract2 (d, a.data (), len); | |
349 return *this; | |
350 } | |
351 | |
352 ComplexColumnVector& | |
353 ComplexColumnVector::operator += (const ComplexColumnVector& a) | |
354 { | |
355 int len = length (); | |
356 | |
357 if (len != a.length ()) | |
358 { | |
359 (*current_liboctave_error_handler) | |
360 ("nonconformant vector += operation attempted"); | |
361 return *this; | |
362 } | |
363 | |
364 if (len == 0) | |
365 return *this; | |
366 | |
367 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
368 | |
369 add2 (d, a.data (), len); | |
370 return *this; | |
371 } | |
372 | |
373 ComplexColumnVector& | |
374 ComplexColumnVector::operator -= (const ComplexColumnVector& a) | |
375 { | |
376 int len = length (); | |
377 if (len != a.length ()) | |
378 { | |
379 (*current_liboctave_error_handler) | |
380 ("nonconformant vector -= operation attempted"); | |
381 return *this; | |
382 } | |
383 | |
384 if (len == 0) | |
385 return *this; | |
386 | |
387 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
388 | |
389 subtract2 (d, a.data (), len); | |
390 return *this; | |
391 } | |
392 | |
393 // column vector by scalar -> column vector operations | |
394 | |
395 ComplexColumnVector | |
396 operator + (const ComplexColumnVector& v, double s) | |
397 { | |
398 int len = v.length (); | |
399 return ComplexColumnVector (add (v.data (), len, s), len); | |
400 } | |
401 | |
402 ComplexColumnVector | |
403 operator - (const ComplexColumnVector& v, double s) | |
404 { | |
405 int len = v.length (); | |
406 return ComplexColumnVector (subtract (v.data (), len, s), len); | |
407 } | |
408 | |
409 ComplexColumnVector | |
410 operator * (const ComplexColumnVector& v, double s) | |
411 { | |
412 int len = v.length (); | |
413 return ComplexColumnVector (multiply (v.data (), len, s), len); | |
414 } | |
415 | |
416 ComplexColumnVector | |
417 operator / (const ComplexColumnVector& v, double s) | |
418 { | |
419 int len = v.length (); | |
420 return ComplexColumnVector (divide (v.data (), len, s), len); | |
421 } | |
422 | |
423 // scalar by column vector -> column vector operations | |
424 | |
425 ComplexColumnVector | |
426 operator + (double s, const ComplexColumnVector& a) | |
427 { | |
428 int a_len = a.length (); | |
429 return ComplexColumnVector (add (a.data (), a_len, s), a_len); | |
430 } | |
431 | |
432 ComplexColumnVector | |
433 operator - (double s, const ComplexColumnVector& a) | |
434 { | |
435 int a_len = a.length (); | |
436 return ComplexColumnVector (subtract (s, a.data (), a_len), a_len); | |
437 } | |
438 | |
439 ComplexColumnVector | |
440 operator * (double s, const ComplexColumnVector& a) | |
441 { | |
442 int a_len = a.length (); | |
443 return ComplexColumnVector (multiply (a.data (), a_len, s), a_len); | |
444 } | |
445 | |
446 ComplexColumnVector | |
447 operator / (double s, const ComplexColumnVector& a) | |
448 { | |
449 int a_len = a.length (); | |
450 return ComplexColumnVector (divide (s, a.data (), a_len), a_len); | |
451 } | |
452 | |
453 // column vector by row vector -> matrix operations | |
454 | |
455 ComplexMatrix | |
456 operator * (const ComplexColumnVector& v, const ComplexRowVector& a) | |
457 { | |
458 int len = v.length (); | |
459 int a_len = a.length (); | |
460 if (len != a_len) | |
461 { | |
462 (*current_liboctave_error_handler) | |
463 ("nonconformant vector multiplication attempted"); | |
464 return ComplexMatrix (); | |
465 } | |
466 | |
467 if (len == 0) | |
468 return ComplexMatrix (len, len, 0.0); | |
469 | |
470 char transa = 'N'; | |
471 char transb = 'N'; | |
472 Complex alpha (1.0); | |
473 Complex beta (0.0); | |
474 int anr = 1; | |
475 | |
476 Complex *c = new Complex [len * a_len]; | |
477 | |
478 F77_FCN (zgemm) (&transa, &transb, &len, &a_len, &anr, &alpha, | |
479 v.data (), &len, a.data (), &anr, &beta, c, &len, | |
480 1L, 1L); | |
481 | |
482 return ComplexMatrix (c, len, a_len); | |
483 } | |
484 | |
485 // column vector by column vector -> column vector operations | |
486 | |
487 ComplexColumnVector | |
488 operator + (const ComplexColumnVector& v, const ColumnVector& a) | |
489 { | |
490 int len = v.length (); | |
491 if (len != a.length ()) | |
492 { | |
493 (*current_liboctave_error_handler) | |
494 ("nonconformant vector addition attempted"); | |
495 return ComplexColumnVector (); | |
496 } | |
497 | |
498 if (len == 0) | |
499 return ComplexColumnVector (0); | |
500 | |
501 return ComplexColumnVector (add (v.data (), a.data (), len), len); | |
502 } | |
503 | |
504 ComplexColumnVector | |
505 operator - (const ComplexColumnVector& v, const ColumnVector& a) | |
506 { | |
507 int len = v.length (); | |
508 if (len != a.length ()) | |
509 { | |
510 (*current_liboctave_error_handler) | |
511 ("nonconformant vector subtraction attempted"); | |
512 return ComplexColumnVector (); | |
513 } | |
514 | |
515 if (len == 0) | |
516 return ComplexColumnVector (0); | |
517 | |
518 return ComplexColumnVector (subtract (v.data (), a.data (), len), len); | |
519 } | |
520 | |
521 ComplexColumnVector | |
522 product (const ComplexColumnVector& v, const ColumnVector& a) | |
523 { | |
524 int len = v.length (); | |
525 if (len != a.length ()) | |
526 { | |
527 (*current_liboctave_error_handler) | |
528 ("nonconformant vector product attempted"); | |
529 return ComplexColumnVector (); | |
530 } | |
531 | |
532 if (len == 0) | |
533 return ComplexColumnVector (0); | |
534 | |
535 return ComplexColumnVector (multiply (v.data (), a.data (), len), len); | |
536 } | |
537 | |
538 ComplexColumnVector | |
539 quotient (const ComplexColumnVector& v, const ColumnVector& a) | |
540 { | |
541 int len = v.length (); | |
542 if (len != a.length ()) | |
543 { | |
544 (*current_liboctave_error_handler) | |
545 ("nonconformant vector quotient attempted"); | |
546 return ComplexColumnVector (); | |
547 } | |
548 | |
549 if (len == 0) | |
550 return ComplexColumnVector (0); | |
551 | |
552 return ComplexColumnVector (divide (v.data (), a.data (), len), len); | |
553 } | |
554 | |
555 // other operations | |
556 | |
557 ComplexColumnVector | |
558 map (c_c_Mapper f, const ComplexColumnVector& a) | |
559 { | |
560 ComplexColumnVector b (a); | |
561 b.map (f); | |
562 return b; | |
563 } | |
564 | |
565 ColumnVector | |
566 map (d_c_Mapper f, const ComplexColumnVector& a) | |
567 { | |
568 int a_len = a.length (); | |
569 ColumnVector b (a_len); | |
570 for (int i = 0; i < a_len; i++) | |
571 b.elem (i) = f (a.elem (i)); | |
572 return b; | |
573 } | |
574 | |
575 void | |
576 ComplexColumnVector::map (c_c_Mapper f) | |
577 { | |
578 for (int i = 0; i < length (); i++) | |
579 elem (i) = f (elem (i)); | |
580 } | |
581 | |
582 Complex | |
583 ComplexColumnVector::min (void) const | |
584 { | |
585 int len = length (); | |
586 if (len == 0) | |
587 return 0.0; | |
588 | |
589 Complex res = elem (0); | |
590 double absres = abs (res); | |
591 | |
592 for (int i = 1; i < len; i++) | |
593 if (abs (elem (i)) < absres) | |
594 { | |
595 res = elem (i); | |
596 absres = abs (res); | |
597 } | |
598 | |
599 return res; | |
600 } | |
601 | |
602 Complex | |
603 ComplexColumnVector::max (void) const | |
604 { | |
605 int len = length (); | |
606 if (len == 0) | |
607 return 0.0; | |
608 | |
609 Complex res = elem (0); | |
610 double absres = abs (res); | |
611 | |
612 for (int i = 1; i < len; i++) | |
613 if (abs (elem (i)) > absres) | |
614 { | |
615 res = elem (i); | |
616 absres = abs (res); | |
617 } | |
618 | |
619 return res; | |
620 } | |
621 | |
622 // i/o | |
623 | |
624 ostream& | |
625 operator << (ostream& os, const ComplexColumnVector& a) | |
626 { | |
627 // int field_width = os.precision () + 7; | |
628 for (int i = 0; i < a.length (); i++) | |
629 os << /* setw (field_width) << */ a.elem (i) << "\n"; | |
630 return os; | |
631 } | |
632 | |
633 istream& | |
634 operator >> (istream& is, ComplexColumnVector& a) | |
635 { | |
636 int len = a.length(); | |
637 | |
638 if (len < 1) | |
639 is.clear (ios::badbit); | |
640 else | |
641 { | |
642 double tmp; | |
643 for (int i = 0; i < len; i++) | |
644 { | |
645 is >> tmp; | |
646 if (is) | |
647 a.elem (i) = tmp; | |
648 else | |
649 break; | |
650 } | |
651 } | |
652 } | |
653 | |
654 /* | |
655 ;;; Local Variables: *** | |
656 ;;; mode: C++ *** | |
657 ;;; page-delimiter: "^/\\*" *** | |
658 ;;; End: *** | |
659 */ |