home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / octave-1.1.1-src.lha / octave-1.1.1 / liboctave / CColVector.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-04  |  13.4 KB  |  657 lines

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