home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-src.tgz / tar.out / fsf / octave / liboctave / MArray.cc < prev    next >
C/C++ Source or Header  |  1996-09-28  |  11KB  |  546 lines

  1. // MArray.cc                                             -*- 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 "MArray.h"
  29. #include "lo-error.h"
  30.  
  31. // Nothing like a little CPP abuse to brighten everyone's day.  Would
  32. // have been nice to do this with template functions but as of 2.5.x,
  33. // g++ seems to fail to resolve them properly.
  34.  
  35. #define DO_VS_OP(OP) \
  36.   int l = a.length (); \
  37.   T *result = 0; \
  38.   if (l > 0) \
  39.     { \
  40.       result = new T [l]; \
  41.       const T *x = a.data (); \
  42.       for (int i = 0; i < l; i++) \
  43.     result[i] = x[i] OP s; \
  44.     }
  45.  
  46. #define DO_SV_OP(OP) \
  47.   int l = a.length (); \
  48.   T *result = 0; \
  49.   if (l > 0) \
  50.     { \
  51.       result = new T [l]; \
  52.       const T *x = a.data (); \
  53.       for (int i = 0; i < l; i++) \
  54.     result[i] = s OP x[i]; \
  55.     }
  56.  
  57. #define DO_VV_OP(OP) \
  58.   T *result = 0; \
  59.   if (l > 0) \
  60.     { \
  61.       result = new T [l]; \
  62.       const T *x = a.data (); \
  63.       const T *y = b.data (); \
  64.       for (int i = 0; i < l; i++) \
  65.     result[i] = x[i] OP y[i]; \
  66.     }
  67.  
  68. #define NEG_V \
  69.   int l = a.length (); \
  70.   T *result = 0; \
  71.   if (l > 0) \
  72.     { \
  73.       result = new T [l]; \
  74.       const T *x = a.data (); \
  75.       for (int i = 0; i < l; i++) \
  76.     result[i] = -x[i]; \
  77.     }
  78.  
  79. /*
  80.  * One dimensional array with math ops.
  81.  */
  82.  
  83. // Element by element MArray by scalar ops.
  84.  
  85. template <class T>
  86. MArray<T>
  87. operator + (const MArray<T>& a, const T& s)
  88. {
  89.   DO_VS_OP (+);
  90.   return MArray<T> (result, l);
  91. }
  92.  
  93. template <class T>
  94. MArray<T>
  95. operator - (const MArray<T>& a, const T& s)
  96. {
  97.   DO_VS_OP (-);
  98.   return MArray<T> (result, l);
  99. }
  100.  
  101. template <class T>
  102. MArray<T>
  103. operator * (const MArray<T>& a, const T& s)
  104. {
  105.   DO_VS_OP (*);
  106.   return MArray<T> (result, l);
  107. }
  108.  
  109. template <class T>
  110. MArray<T>
  111. operator / (const MArray<T>& a, const T& s)
  112. {
  113.   DO_VS_OP (/);
  114.   return MArray<T> (result, l);
  115. }
  116.  
  117. // Element by element scalar by MArray ops.
  118.  
  119. template <class T>
  120. MArray<T>
  121. operator + (const T& s, const MArray<T>& a)
  122. {
  123.   DO_SV_OP (+);
  124.   return MArray<T> (result, l);
  125. }
  126.  
  127. template <class T>
  128. MArray<T>
  129. operator - (const T& s, const MArray<T>& a)
  130. {
  131.   DO_SV_OP (-);
  132.   return MArray<T> (result, l);
  133. }
  134.  
  135. template <class T>
  136. MArray<T>
  137. operator * (const T& s, const MArray<T>& a)
  138. {
  139.   DO_SV_OP (*);
  140.   return MArray<T> (result, l);
  141. }
  142.  
  143. template <class T>
  144. MArray<T>
  145. operator / (const T& s, const MArray<T>& a)
  146. {
  147.   DO_SV_OP (/);
  148.   return MArray<T> (result, l);
  149. }
  150.  
  151. // Element by element MArray by MArray ops.
  152.  
  153. template <class T>
  154. MArray<T>
  155. operator + (const MArray<T>& a, const MArray<T>& b)
  156. {
  157.   int l = a.length ();
  158.   if (l != b.length ())
  159.     {
  160.       (*current_liboctave_error_handler)
  161.     ("nonconformant array addition attempted");
  162.       return MArray<T> ();
  163.     }
  164.  
  165.   if (l == 0)
  166.     return MArray<T> ();
  167.  
  168.   DO_VV_OP (+);
  169.   return MArray<T> (result, l);
  170. }
  171.  
  172. template <class T>
  173. MArray<T>
  174. operator - (const MArray<T>& a, const MArray<T>& b)
  175. {
  176.   int l = a.length ();
  177.   if (l != b.length ())
  178.     {
  179.       (*current_liboctave_error_handler)
  180.     ("nonconformant array subtraction attempted");
  181.       return MArray<T> ();
  182.     }
  183.  
  184.   if (l == 0)
  185.     return MArray<T> ();
  186.  
  187.   DO_VV_OP (-);
  188.   return MArray<T> (result, l);
  189. }
  190.  
  191. template <class T>
  192. MArray<T>
  193. product (const MArray<T>& a, const MArray<T>& b)
  194. {
  195.   int l = a.length ();
  196.   if (l != b.length ())
  197.     {
  198.       (*current_liboctave_error_handler)
  199.     ("nonconformant array product attempted");
  200.       return MArray<T> ();
  201.     }
  202.  
  203.   if (l == 0)
  204.     return MArray<T> ();
  205.  
  206.   DO_VV_OP (*);
  207.   return MArray<T> (result, l);
  208. }
  209.  
  210. template <class T>
  211. MArray<T>
  212. quotient (const MArray<T>& a, const MArray<T>& b)
  213. {
  214.   int l = a.length ();
  215.   if (l != b.length ())
  216.     {
  217.       (*current_liboctave_error_handler)
  218.     ("nonconformant array quotient attempted");
  219.       return MArray<T> ();
  220.     }
  221.  
  222.   if (l == 0)
  223.     return MArray<T> ();
  224.  
  225.   DO_VV_OP (/);
  226.   return MArray<T> (result, l);
  227. }
  228.  
  229. // Unary MArray ops.
  230.  
  231. template <class T>
  232. MArray<T>
  233. operator - (const MArray<T>& a)
  234. {
  235.   NEG_V;
  236.   return MArray<T> (result, l);
  237. }
  238.  
  239. /*
  240.  * Two dimensional array with math ops.
  241.  */
  242.  
  243. template <class T>
  244. MArray2<T>::MArray2 (const MDiagArray<T>& a)
  245.   : Array2<T> (a.rows (), a.cols (), T (0))
  246. {
  247.   for (int i = 0; i < a.length (); i++)
  248.     elem (i, i) = a.elem (i, i);
  249. }
  250.  
  251. // Element by element MArray2 by scalar ops.
  252.  
  253. template <class T>
  254. MArray2<T>
  255. operator + (const MArray2<T>& a, const T& s)
  256. {
  257.   DO_VS_OP (+);
  258.   return MArray2<T> (result, a.rows (), a.cols ());
  259. }
  260.  
  261. template <class T>
  262. MArray2<T>
  263. operator - (const MArray2<T>& a, const T& s)
  264. {
  265.   DO_VS_OP (-);
  266.   return MArray2<T> (result, a.rows (), a.cols ());
  267. }
  268.  
  269. template <class T>
  270. MArray2<T>
  271. operator * (const MArray2<T>& a, const T& s)
  272. {
  273.   DO_VS_OP (*);
  274.   return MArray2<T> (result, a.rows (), a.cols ());
  275. }
  276.  
  277. template <class T>
  278. MArray2<T>
  279. operator / (const MArray2<T>& a, const T& s)
  280. {
  281.   DO_VS_OP (/);
  282.   return MArray2<T> (result, a.rows (), a.cols ());
  283. }
  284.  
  285. // Element by element scalar by MArray2 ops.
  286.  
  287. template <class T>
  288. MArray2<T>
  289. operator + (const T& s, const MArray2<T>& a)
  290. {
  291.   DO_SV_OP (+);
  292.   return MArray2<T> (result, a.rows (), a.cols ());
  293. }
  294.  
  295. template <class T>
  296. MArray2<T>
  297. operator - (const T& s, const MArray2<T>& a)
  298. {
  299.   DO_SV_OP (-);
  300.   return MArray2<T> (result, a.rows (), a.cols ());
  301. }
  302.  
  303. template <class T>
  304. MArray2<T>
  305. operator * (const T& s, const MArray2<T>& a)
  306. {
  307.   DO_SV_OP (*);
  308.   return MArray2<T> (result, a.rows (), a.cols ());
  309. }
  310.  
  311. template <class T>
  312. MArray2<T>
  313. operator / (const T& s, const MArray2<T>& a)
  314. {
  315.   DO_SV_OP (/);
  316.   return MArray2<T> (result, a.rows (), a.cols ());
  317. }
  318.  
  319. // Element by element MArray2 by MArray2 ops.
  320.  
  321. template <class T>
  322. MArray2<T>
  323. operator + (const MArray2<T>& a, const MArray2<T>& b)
  324. {
  325.   int r = a.rows ();
  326.   int c = a.cols ();
  327.   if (r != b.rows () || c != b.cols ())
  328.     {
  329.       (*current_liboctave_error_handler)
  330.     ("nonconformant array addition attempted");
  331.       return MArray2<T> ();
  332.     }
  333.  
  334.   if (r == 0 || c == 0)
  335.     return MArray2<T> ();
  336.  
  337.   int l = a.length ();
  338.   DO_VV_OP (+);
  339.   return MArray2<T> (result, r, c);
  340. }
  341.  
  342. template <class T>
  343. MArray2<T>
  344. operator - (const MArray2<T>& a, const MArray2<T>& b)
  345. {
  346.   int r = a.rows ();
  347.   int c = a.cols ();
  348.   if (r != b.rows () || c != b.cols ())
  349.     {
  350.       (*current_liboctave_error_handler)
  351.     ("nonconformant array subtraction attempted");
  352.       return MArray2<T> ();
  353.     }
  354.  
  355.   if (r == 0 || c == 0)
  356.     return MArray2<T> ();
  357.  
  358.   int l = a.length ();
  359.   DO_VV_OP (-);
  360.   return MArray2<T> (result, r, c);
  361. }
  362.  
  363. template <class T>
  364. MArray2<T>
  365. product (const MArray2<T>& a, const MArray2<T>& b)
  366. {
  367.   int r = a.rows ();
  368.   int c = a.cols ();
  369.   if (r != b.rows () || c != b.cols ())
  370.     {
  371.       (*current_liboctave_error_handler)
  372.     ("nonconformant array product attempted");
  373.       return MArray2<T> ();
  374.     }
  375.  
  376.   if (r == 0 || c == 0)
  377.     return MArray2<T> ();
  378.  
  379.   int l = a.length ();
  380.   DO_VV_OP (*);
  381.   return MArray2<T> (result, r, c);
  382. }
  383.  
  384. template <class T>
  385. MArray2<T>
  386. quotient (const MArray2<T>& a, const MArray2<T>& b)
  387. {
  388.   int r = a.rows ();
  389.   int c = a.cols ();
  390.   if (r != b.rows () || c != b.cols ())
  391.     {
  392.       (*current_liboctave_error_handler)
  393.     ("nonconformant array quotient attempted");
  394.       return MArray2<T> ();
  395.     }
  396.  
  397.   if (r == 0 || c == 0)
  398.     return MArray2<T> ();
  399.  
  400.   int l = a.length ();
  401.   DO_VV_OP (/);
  402.   return MArray2<T> (result, r, c);
  403. }
  404.  
  405. // Unary MArray2 ops.
  406.  
  407. template <class T>
  408. MArray2<T>
  409. operator - (const MArray2<T>& a)
  410. {
  411.   NEG_V;
  412.   return MArray2<T> (result, a.rows (), a.cols ());
  413. }
  414.  
  415. /*
  416.  * Two dimensional diagonal array with math ops.
  417.  */
  418.  
  419. // Element by element MDiagArray by scalar ops.
  420.  
  421. template <class T>
  422. MDiagArray<T>
  423. operator * (const MDiagArray<T>& a, const T& s)
  424. {
  425.   DO_VS_OP (*);
  426.   return MDiagArray<T> (result, a.rows (), a.cols ());
  427. }
  428.  
  429. template <class T>
  430. MDiagArray<T>
  431. operator / (const MDiagArray<T>& a, const T& s)
  432. {
  433.   DO_VS_OP (/);
  434.   return MDiagArray<T> (result, a.rows (), a.cols ());
  435. }
  436.  
  437. // Element by element scalar by MDiagArray ops.
  438.  
  439. template <class T>
  440. MDiagArray<T>
  441. operator * (const T& s, const MDiagArray<T>& a)
  442. {
  443.   DO_SV_OP (*);
  444.   return MDiagArray<T> (result, a.rows (), a.cols ());
  445. }
  446.  
  447. // Element by element MDiagArray by MDiagArray ops.
  448.  
  449. template <class T>
  450. MDiagArray<T>
  451. operator + (const MDiagArray<T>& a, const MDiagArray<T>& b)
  452. {
  453.   int r = a.rows ();
  454.   int c = a.cols ();
  455.   if (r != b.rows () || c != b.cols ())
  456.     {
  457.       (*current_liboctave_error_handler)
  458.     ("nonconformant diagonal array addition attempted");
  459.       return MDiagArray<T> ();
  460.     }
  461.  
  462.   if (c == 0 || r == 0)
  463.     return MDiagArray<T> ();
  464.  
  465.   int l = a.length ();
  466.   DO_VV_OP (+);
  467.   return MDiagArray<T> (result, r, c);
  468. }
  469.  
  470. template <class T>
  471. MDiagArray<T>
  472. operator - (const MDiagArray<T>& a, const MDiagArray<T>& b)
  473. {
  474.   int r = a.rows ();
  475.   int c = a.cols ();
  476.   if (r != b.rows () || c != b.cols ())
  477.     {
  478.       (*current_liboctave_error_handler)
  479.     ("nonconformant diagonal array subtraction attempted");
  480.       return MDiagArray<T> ();
  481.     }
  482.  
  483.   if (c == 0 || r == 0)
  484.     return MDiagArray<T> ();
  485.  
  486.   int l = a.length ();
  487.   DO_VV_OP (-);
  488.   return MDiagArray<T> (result, r, c);
  489. }
  490.  
  491. template <class T>
  492. MDiagArray<T>
  493. product (const MDiagArray<T>& a, const MDiagArray<T>& b)
  494. {
  495.   int r = a.rows ();
  496.   int c = a.cols ();
  497.   if (r != b.rows () || c != b.cols ())
  498.     {
  499.       (*current_liboctave_error_handler)
  500.     ("nonconformant diagonal array product attempted");
  501.       return MDiagArray<T> ();
  502.     }
  503.  
  504.   if (c == 0 || r == 0)
  505.     return MDiagArray<T> ();
  506.  
  507.   int l = a.length ();
  508.   DO_VV_OP (*);
  509.   return MDiagArray<T> (result, r, c);
  510. }
  511.  
  512. // Unary MDiagArray ops.
  513.  
  514. template <class T>
  515. MDiagArray<T>
  516. operator - (const MDiagArray<T>& a)
  517. {
  518.   NEG_V;
  519.   return MDiagArray<T> (result, a.rows (), a.cols ());
  520. }
  521.  
  522. #undef DO_SV_OP
  523. #undef DO_VS_OP
  524. #undef DO_VV_OP
  525. #undef NEG_V
  526.  
  527. #if 0
  528. #ifdef OCTAVE
  529. typedefMArray<double>      octave_mad_template_type;
  530. typedefMArray2<double>     octave_ma2d_template_type;
  531. typedefMDiagArray<double>  octave_mdad_template_type;
  532.  
  533. #include <Complex.h>
  534. typedefMArray<Complex>     octave_mac_template_type;
  535. typedefMArray2<Complex>    octave_ma2c_template_type;
  536. typedefMDiagArray<Complex> octave_mdac_template_type;
  537. #endif
  538. #endif
  539.  
  540. /*
  541. ;;; Local Variables: ***
  542. ;;; mode: C++ ***
  543. ;;; page-delimiter: "^/\\*" ***
  544. ;;; End: ***
  545. */
  546.