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 / mx-kludge.cc < prev    next >
C/C++ Source or Header  |  1996-09-28  |  10KB  |  502 lines

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