home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-base.tgz / octave-1.1.1p1-base.tar / fsf / octave / src / f-find.cc < prev    next >
C/C++ Source or Header  |  1995-02-08  |  4KB  |  200 lines

  1. // f-find.cc                                           -*- C++ -*-
  2. /*
  3.  
  4. Copyright (C) 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 "tree-const.h"
  29. #include "error.h"
  30. #include "gripes.h"
  31. #include "help.h"
  32. #include "defun-dld.h"
  33.  
  34. static Octave_object
  35. find_to_fortran_idx (const ColumnVector i_idx, const ColumnVector j_idx,
  36.              const tree_constant& val, int nr, int nc, int nargout)
  37. {
  38.   Octave_object retval;
  39.  
  40.   switch (nargout)
  41.     {
  42.     case 0:
  43.     case 1:
  44.       {
  45.     int count = i_idx.length ();
  46.     ColumnVector tmp (count);
  47.     for (int i = 0; i < count; i++)
  48.       tmp (i) = nr * (j_idx (i) - 1.0) + i_idx (i);
  49.  
  50. // If the original argument was a row vector, force a row vector of
  51. // indices to be returned.
  52.  
  53.     retval(0) = tree_constant (tmp, (nr != 1));
  54.       }
  55.       break;
  56.  
  57.     case 3:
  58.       retval(2) = val;
  59. // Fall through!
  60.  
  61.     case 2:
  62.       retval(1) = tree_constant (j_idx, 1);
  63.       retval(0) = tree_constant (i_idx, 1);
  64. // If you want this to work more like Matlab, use the following line
  65. // instead of the previous one.
  66. //    retval(0) = tree_constant (i_idx, (nr != 1));
  67.       break;
  68.  
  69.     default:
  70.       panic_impossible ();
  71.       break;
  72.     }
  73.  
  74.   return retval;
  75. }
  76.  
  77. static Octave_object
  78. find_nonzero_elem_idx (const Matrix& m, int nargout)
  79. {
  80.   int count = 0;
  81.   int m_nr = m.rows ();
  82.   int m_nc = m.columns ();
  83.  
  84.   int i, j;
  85.   for (j = 0; j < m_nc; j++)
  86.     for (i = 0; i < m_nr; i++)
  87.       if (m.elem (i, j) != 0.0)
  88.     count++;
  89.  
  90.   Octave_object retval (((nargout == 0) ? 1 : nargout), Matrix ());
  91.  
  92.   if (count == 0)
  93.     return retval;
  94.  
  95.   ColumnVector i_idx (count);
  96.   ColumnVector j_idx (count);
  97.   ColumnVector v (count);
  98.  
  99.   count = 0;
  100.   for (j = 0; j < m_nc; j++)
  101.     for (i = 0; i < m_nr; i++)
  102.       {
  103.     double d = m.elem (i, j);
  104.     if (d != 0.0)
  105.       {
  106.         i_idx (count) = i + 1;
  107.         j_idx (count) = j + 1;
  108.         v (count) = d;
  109.         count++;
  110.       }
  111.       }
  112.  
  113.   tree_constant tmp (v, 1);
  114.   return find_to_fortran_idx (i_idx, j_idx, tmp, m_nr, m_nc, nargout);
  115. }
  116.  
  117. static Octave_object
  118. find_nonzero_elem_idx (const ComplexMatrix& m, int nargout)
  119. {
  120.   int count = 0;
  121.   int m_nr = m.rows ();
  122.   int m_nc = m.columns ();
  123.  
  124.   int i, j;
  125.   for (j = 0; j < m_nc; j++)
  126.     for (i = 0; i < m_nr; i++)
  127.       if (m.elem (i, j) != 0.0)
  128.     count++;
  129.  
  130.   Octave_object retval (((nargout == 0) ? 1 : nargout), Matrix ());
  131.  
  132.   if (count == 0)
  133.     return retval;
  134.  
  135.   ColumnVector i_idx (count);
  136.   ColumnVector j_idx (count);
  137.   ComplexColumnVector v (count);
  138.  
  139.   count = 0;
  140.   for (j = 0; j < m_nc; j++)
  141.     for (i = 0; i < m_nr; i++)
  142.       {
  143.     Complex c = m.elem (i, j);
  144.     if (c != 0.0)
  145.       {
  146.         i_idx (count) = i + 1;
  147.         j_idx (count) = j + 1;
  148.         v (count) = c;
  149.         count++;
  150.       }
  151.       }
  152.  
  153.   tree_constant tmp (v, 1);
  154.   return find_to_fortran_idx (i_idx, j_idx, tmp, m_nr, m_nc, nargout);
  155. }
  156.  
  157. DEFUN_DLD_BUILTIN ("find", Ffind, Sfind, 2, 3,
  158.   "find (X) or [I, J, V] = find (X): Return indices of nonzero elements")
  159. {
  160.   Octave_object retval;
  161.  
  162.   int nargin = args.length ();
  163.  
  164.   if (nargin != 1 || nargout > 3)
  165.     {
  166.       print_usage ("find");
  167.       return retval;
  168.     }
  169.  
  170.   tree_constant arg = args(0);
  171.  
  172.   if (arg.is_real_type ())
  173.     {
  174.       Matrix m = arg.matrix_value ();
  175.  
  176.       if (! error_state)
  177.     retval = find_nonzero_elem_idx (m, nargout);
  178.     }
  179.   else if (arg.is_complex_type ())
  180.     {
  181.       ComplexMatrix m = arg.complex_matrix_value ();
  182.  
  183.       if (! error_state)
  184.     retval = find_nonzero_elem_idx (m, nargout);
  185.     }
  186.   else
  187.     {
  188.       gripe_wrong_type_arg ("find", arg);
  189.     }
  190.  
  191.   return retval;
  192. }
  193.  
  194. /*
  195. ;;; Local Variables: ***
  196. ;;; mode: C++ ***
  197. ;;; page-delimiter: "^/\\*" ***
  198. ;;; End: ***
  199. */
  200.