changeset 2354:2ce6e1ec9b53

[project @ 1996-08-20 22:44:25 by jwe]
author jwe
date Tue, 20 Aug 1996 22:45:36 +0000
parents 383ce9cdcf31
children c9f70d39255f
files liboctave/CMatrix.cc liboctave/CMatrix.h liboctave/ChangeLog liboctave/dMatrix.cc liboctave/dMatrix.h src/ChangeLog src/minmax.cc
diffstat 7 files changed, 410 insertions(+), 499 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/CMatrix.cc
+++ b/liboctave/CMatrix.cc
@@ -41,6 +41,8 @@
 #include "CmplxSVD.h"
 #include "f77-fcn.h"
 #include "lo-error.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
 #include "lo-utils.h"
 #include "mx-base.h"
 #include "mx-inlines.cc"
@@ -97,6 +99,8 @@
 				   const int&, double*); 
 }
 
+static const Complex Complex_NaN_result (octave_NaN, octave_NaN);
+
 // Complex Matrix class
 
 ComplexMatrix::ComplexMatrix (const Matrix& a)
@@ -3296,62 +3300,53 @@
   return d;
 }
 
-// XXX FIXME XXX -- it would be nice to share some code among all the
-// min/max functions below.  It would also be nice to combine the
-// min/max and min_loc/max_loc functions.
+bool
+ComplexMatrix::row_is_real_only (int i) const
+{
+  bool retval = true;
+
+  int nc = columns ();
+
+  for (int j = 0; j < nc; j++)
+    {
+      if (imag (elem (i, j)) != 0.0)
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;	      
+}
+
+bool
+ComplexMatrix::column_is_real_only (int j) const
+{
+  bool retval = true;
+
+  int nr = rows ();
+
+  for (int i = 0; i < nr; i++)
+    {
+      if (imag (elem (i, j)) != 0.0)
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;	      
+}
 
 ComplexColumnVector
 ComplexMatrix::row_min (void) const
 {
-  ComplexColumnVector result;
-
-  int nr = rows ();
-  int nc = cols ();
-  if (nr > 0 && nc > 0)
-    {
-      result.resize (nr);
-
-      for (int i = 0; i < nr; i++)
-	{
-	  int row_is_real_only = 1;
-	  for (int j = 0; j < nc; j++)
-	    if (imag (elem (i, j)) != 0.0)
-	      {
-		row_is_real_only = 0;
-		break;
-	      }
-	      
-	  if (row_is_real_only)
-	    {
-	      double res = real (elem (i, 0));
-	      for (int j = 1; j < nc; j++)
-		{
-		  double tmp = real (elem (i, j));
-		  if (tmp < res)
-		    res = tmp;
-		}
-	      result.elem (i) = res;
-	    }
-	  else
-	    {
-	      Complex res = elem (i, 0);
-	      double absres = abs (res);
-	      for (int j = 1; j < nc; j++)
-		if (abs (elem (i, j)) < absres)
-		  {
-		    res = elem (i, j);
-		    absres = abs (res);
-		  }
-	      result.elem (i) = res;
-	    }
-	}
-    }
-
-  return result;
+  Array<int> index;
+  return row_min (index);
 }
 
 ComplexColumnVector
-ComplexMatrix::row_min_loc (void) const
+ComplexMatrix::row_min (Array<int>& index) const
 {
   ComplexColumnVector result;
 
@@ -3361,38 +3356,43 @@
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
+      index.resize (nr);
 
       for (int i = 0; i < nr; i++)
         {
-	  int column_is_real_only = 1;
-	  for (int j = 0; j < nc; j++)
-	    if (imag (elem (i, j)) != 0.0)
-	      {
-		column_is_real_only = 0;
-		break;
-	      }
-	      
-	  if (column_is_real_only)
-	    {
-	      double res = 0;
-	      double tmp = real (elem (i, 0));
-	      for (int j = 1; j < nc; j++)
-		if (real (elem (i, j)) < tmp)
-		  res = j;
-
-	      result.elem (i) = res + 1;
-	    }
+	  int idx = 0;
+
+	  Complex tmp_min = elem (i, idx);
+
+	  bool real_only = row_is_real_only (i);
+
+	  double abs_min = real_only ? real (tmp_min) : abs (tmp_min);
+
+	  if (xisnan (tmp_min))
+	    idx = -1;
 	  else
 	    {
-	      Complex res = 0;
-	      double absres = abs (elem (i, 0));
 	      for (int j = 1; j < nc; j++)
-		if (abs (elem (i, j)) < absres)
-		  {
-		    res = j;
-		    absres = abs (elem (i, j));
-		  }
-	      result.elem (i) = res + 1;
+		{
+		  Complex tmp = elem (i, j);
+
+		  double abs_tmp = real_only ? real (tmp) : abs (tmp);
+
+		  if (xisnan (tmp))
+		    {
+		      idx = -1;
+		      break;
+		    }
+		  else if (abs_tmp < abs_min)
+		    {
+		      idx = j;
+		      tmp_min = tmp;
+		      abs_min = abs_tmp;
+		    }
+		}
+
+	      result.elem (i) = (idx < 0) ? Complex_NaN_result : tmp_min;
+	      index.elem (i) = idx;
 	    }
         }
     }
@@ -3403,56 +3403,12 @@
 ComplexColumnVector
 ComplexMatrix::row_max (void) const
 {
-  ComplexColumnVector result;
-
-  int nr = rows ();
-  int nc = cols ();
-
-  if (nr > 0 && nc > 0)
-    {
-      result.resize (nr);
-
-      for (int i = 0; i < nr; i++)
-	{
-	  int row_is_real_only = 1;
-	  for (int j = 0; j < nc; j++)
-	    if (imag (elem (i, j)) != 0.0)
-	      {
-		row_is_real_only = 0;
-		break;
-	      }
-	      
-	  if (row_is_real_only)
-	    {
-	      double res = real (elem (i, 0));
-	      for (int j = 1; j < nc; j++)
-		{
-		  double tmp = real (elem (i, j));
-		  if (tmp > res)
-		    res = tmp;
-		}
-	      result.elem (i) = res;
-	    }
-	  else
-	    {
-	      Complex res = elem (i, 0);
-	      double absres = abs (res);
-	      for (int j = 1; j < nc; j++)
-		if (abs (elem (i, j)) > absres)
-		  {
-		    res = elem (i, j);
-		    absres = abs (res);
-		  }
-	      result.elem (i) = res;
-	    }
-	}
-    }
-
-  return result;
+  Array<int> index;
+  return row_max (index);
 }
 
 ComplexColumnVector
-ComplexMatrix::row_max_loc (void) const
+ComplexMatrix::row_max (Array<int>& index) const
 {
   ComplexColumnVector result;
 
@@ -3462,38 +3418,43 @@
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
+      index.resize (nr);
 
       for (int i = 0; i < nr; i++)
         {
-	  int column_is_real_only = 1;
-	  for (int j = 0; j < nc; j++)
-	    if (imag (elem (i, j)) != 0.0)
-	      {
-		column_is_real_only = 0;
-		break;
-	      }
-	      
-	  if (column_is_real_only)
-	    {
-	      double res = 0;
-	      double tmp = real (elem (i, 0));
-	      for (int j = 1; j < nc; j++)
-		if (real (elem (i, j)) > tmp)
-		  res = j;
-
-	      result.elem (i) = res + 1;
-	    }
+	  int idx = 0;
+
+	  Complex tmp_max = elem (i, idx);
+
+	  bool real_only = row_is_real_only (i);
+
+	  double abs_max = real_only ? real (tmp_max) : abs (tmp_max);
+
+	  if (xisnan (tmp_max))
+	    idx = -1;
 	  else
 	    {
-	      Complex res = 0;
-	      double absres = abs (elem (i, 0));
 	      for (int j = 1; j < nc; j++)
-		if (abs (elem (i, j)) > absres)
-		  {
-		    res = j;
-		    absres = abs (elem (i, j));
-		  }
-	      result.elem (i) = res + 1;
+		{
+		  Complex tmp = elem (i, j);
+
+		  double abs_tmp = real_only ? real (tmp) : abs (tmp);
+
+		  if (xisnan (tmp))
+		    {
+		      idx = -1;
+		      break;
+		    }
+		  else if (abs_tmp > abs_max)
+		    {
+		      idx = j;
+		      tmp_max = tmp;
+		      abs_max = abs_tmp;
+		    }
+		}
+
+	      result.elem (i) = (idx < 0) ? Complex_NaN_result : tmp_max;
+	      index.elem (i) = idx;
 	    }
         }
     }
@@ -3504,56 +3465,12 @@
 ComplexRowVector
 ComplexMatrix::column_min (void) const
 {
-  ComplexRowVector result;
-
-  int nr = rows ();
-  int nc = cols ();
-
-  if (nr > 0 && nc > 0)
-    {
-      result.resize (nc);
-
-      for (int j = 0; j < nc; j++)
-	{
-	  int column_is_real_only = 1;
-	  for (int i = 0; i < nr; i++)
-	    if (imag (elem (i, j)) != 0.0)
-	      {
-		column_is_real_only = 0;
-		break;
-	      }
-	      
-	  if (column_is_real_only)
-	    {
-	      double res = real (elem (0, j));
-	      for (int i = 1; i < nr; i++)
-		{
-		  double tmp = real (elem (i, j));
-		  if (tmp < res)
-		    res = tmp;
-		}
-	      result.elem (j) = res;
-	    }
-	  else
-	    {
-	      Complex res = elem (0, j);
-	      double absres = abs (res);
-	      for (int i = 1; i < nr; i++)
-		if (abs (elem (i, j)) < absres)
-		  {
-		    res = elem (i, j);
-		    absres = abs (res);
-		  }
-	      result.elem (j) = res;
-	    }
-	}
-    }
-
-  return result;
+  Array<int> index;
+  return column_min (index);
 }
 
 ComplexRowVector
-ComplexMatrix::column_min_loc (void) const
+ComplexMatrix::column_min (Array<int>& index) const
 {
   ComplexRowVector result;
 
@@ -3563,38 +3480,43 @@
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
+      index.resize (nc);
 
       for (int j = 0; j < nc; j++)
         {
-	  int column_is_real_only = 1;
-	  for (int i = 0; i < nr; i++)
-	    if (imag (elem (i, j)) != 0.0)
-	      {
-		column_is_real_only = 0;
-		break;
-	      }
-	      
-	  if (column_is_real_only)
-	    {
-	      double res = 0;
-	      double tmp = real (elem (0, j));
-	      for (int i = 1; i < nr; i++)
-		if (real (elem (i, j)) < tmp)
-		  res = i;
-
-	      result.elem (j) = res + 1;
-	    }
+	  int idx = 0;
+
+	  Complex tmp_min = elem (idx, j);
+
+	  bool real_only = column_is_real_only (j);
+
+	  double abs_min = real_only ? real (tmp_min) : abs (tmp_min);
+
+	  if (xisnan (tmp_min))
+	    idx = -1;
 	  else
 	    {
-	      Complex res = 0;
-	      double absres = abs (elem (0, j));
 	      for (int i = 1; i < nr; i++)
-		if (abs (elem (i, j)) < absres)
-		  {
-		    res = i;
-		    absres = abs (elem (i, j));
-		  }
-	      result.elem (j) = res + 1;
+		{
+		  Complex tmp = elem (i, j);
+
+		  double abs_tmp = real_only ? real (tmp) : abs (tmp);
+
+		  if (xisnan (tmp))
+		    {
+		      idx = -1;
+		      break;
+		    }
+		  else if (abs_tmp < abs_min)
+		    {
+		      idx = i;
+		      tmp_min = tmp;
+		      abs_min = abs_tmp;
+		    }
+		}
+
+	      result.elem (j) = (idx < 0) ? Complex_NaN_result : tmp_min;
+	      index.elem (j) = idx;
 	    }
         }
     }
@@ -3605,56 +3527,12 @@
 ComplexRowVector
 ComplexMatrix::column_max (void) const
 {
-  ComplexRowVector result;
-
-  int nr = rows ();
-  int nc = cols ();
-
-  if (nr > 0 && nc > 0)
-    {
-      result.resize (nc);
-
-      for (int j = 0; j < nc; j++)
-	{
-	  int column_is_real_only = 1;
-	  for (int i = 0; i < nr; i++)
-	    if (imag (elem (i, j)) != 0.0)
-	      {
-		column_is_real_only = 0;
-		break;
-	      }
-	      
-	  if (column_is_real_only)
-	    {
-	      double res = real (elem (0, j));
-	      for (int i = 1; i < nr; i++)
-		{
-		  double tmp = real (elem (i, j));
-		  if (tmp > res)
-		    res = tmp;
-		}
-	      result.elem (j) = res;
-	    }
-	  else
-	    {
-	      Complex res = elem (0, j);
-	      double absres = abs (res);
-	      for (int i = 1; i < nr; i++)
-		if (abs (elem (i, j)) > absres)
-		  {
-		    res = elem (i, j);
-		    absres = abs (res);
-		  }
-	      result.elem (j) = res;
-	    }
-	}
-    }
-
-  return result;
+  Array<int> index;
+  return column_max (index);
 }
 
 ComplexRowVector
-ComplexMatrix::column_max_loc (void) const
+ComplexMatrix::column_max (Array<int>& index) const
 {
   ComplexRowVector result;
 
@@ -3664,38 +3542,43 @@
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
+      index.resize (nc);
 
       for (int j = 0; j < nc; j++)
         {
-	  int column_is_real_only = 1;
-	  for (int i = 0; i < nr; i++)
-	    if (imag (elem (i, j)) != 0.0)
-	      {
-		column_is_real_only = 0;
-		break;
-	      }
-	      
-	  if (column_is_real_only)
-	    {
-	      double res = 0;
-	      double tmp = real (elem (0, j));
-	      for (int i = 1; i < nr; i++)
-		if (real (elem (i, j)) > tmp)
-		  res = i;
-
-	      result.elem (j) = res + 1;
-	    }
+	  int idx = 0;
+
+	  Complex tmp_max = elem (idx, j);
+
+	  bool real_only = column_is_real_only (j);
+
+	  double abs_max = real_only ? real (tmp_max) : abs (tmp_max);
+
+	  if (xisnan (tmp_max))
+	    idx = -1;
 	  else
 	    {
-	      Complex res = 0;
-	      double absres = abs (elem (0, j));
 	      for (int i = 1; i < nr; i++)
-		if (abs (elem (i, j)) > absres)
-		  {
-		    res = i;
-		    absres = abs (elem (i, j));
-		  }
-	      result.elem (j) = res + 1;
+		{
+		  Complex tmp = elem (i, j);
+
+		  double abs_tmp = real_only ? real (tmp) : abs (tmp);
+
+		  if (xisnan (tmp))
+		    {
+		      idx = -1;
+		      break;
+		    }
+		  else if (abs_tmp > abs_max)
+		    {
+		      idx = i;
+		      tmp_max = tmp;
+		      abs_max = abs_tmp;
+		    }
+		}
+
+	      result.elem (j) = (idx < 0) ? Complex_NaN_result : tmp_max;
+	      index.elem (j) = idx;
 	    }
         }
     }
--- a/liboctave/CMatrix.h
+++ b/liboctave/CMatrix.h
@@ -335,17 +335,20 @@
   ComplexColumnVector diag (void) const;
   ComplexColumnVector diag (int k) const;
 
-  ComplexColumnVector row_min (void) const;
-  ComplexColumnVector row_min_loc (void) const;
+  bool row_is_real_only (int) const;
+  bool column_is_real_only (int) const;
 
+  ComplexColumnVector row_min (void) const;
   ComplexColumnVector row_max (void) const;
-  ComplexColumnVector row_max_loc (void) const;
+
+  ComplexColumnVector row_min (Array<int>& index) const;
+  ComplexColumnVector row_max (Array<int>& index) const;
 
   ComplexRowVector column_min (void) const;
-  ComplexRowVector column_min_loc (void) const;
+  ComplexRowVector column_max (void) const;
 
-  ComplexRowVector column_max (void) const;
-  ComplexRowVector column_max_loc (void) const;
+  ComplexRowVector column_min (Array<int>& index) const;
+  ComplexRowVector column_max (Array<int>& index) const;
 
   // i/o
 
--- a/liboctave/ChangeLog
+++ b/liboctave/ChangeLog
@@ -1,3 +1,30 @@
+Tue Aug 20 17:38:46 1996  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* CMatrix.cc (ComplexMatrix::row_max, ComplexMatrix::row_min,
+	ComplexMatrix::column_max, ComplexMatrix::column_min):
+	Rewrite.  Also return index as a reference arg.
+	(ComplexMatrix::row_max_loc, ComplexMatrix::row_min_loc,
+	ComplexMatrix::column_max_loc, ComplexMatrix::column_min_loc):
+	Delete.
+
+	* dMatrix.cc (Matrix::row_max, Matrix::row_min,
+	Matrix::column_max, Matrix::column_min):
+	Rewrite.  Also return index as a reference arg.
+	(Matrix::row_max_loc, Matrix::row_min_loc,
+	Matrix::column_max_loc, Matrix::column_min_loc): Delete.
+
+Fri Aug  9 05:01:04 1996  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* dMatrix.cc (Matrix::row_min, Matrix::row_min_loc,
+	Matrix::row_max, Matrix::row_max_loc, Matrix::column_min,
+	Matrix::column_min_loc, Matrix::column_max,
+	Matrix::column_max_loc): Ignore leading NaNs.
+	* CMatrix.cc (ComplexMatrix::row_min, ComplexMatrix::row_min_loc,
+	ComplexMatrix::row_max, ComplexMatrix::row_max_loc,
+	ComplexMatrix::column_min, ComplexMatrix::column_min_loc,
+	ComplexMatrix::column_max, ComplexMatrix::column_max_loc): Ignore
+	leading NaNs.
+
 Thu Aug  8 16:04:17 1996  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* QPSOL.cc (QPSOL::do_minimize): Insert linear constraint bounds
--- a/liboctave/dMatrix.cc
+++ b/liboctave/dMatrix.cc
@@ -40,6 +40,8 @@
 #include "dbleSVD.h"
 #include "f77-fcn.h"
 #include "lo-error.h"
+#include "lo-ieee.h"
+#include "lo-mappers.h"
 #include "lo-utils.h"
 #include "mx-base.h"
 #include "mx-inlines.cc"
@@ -2296,30 +2298,12 @@
 ColumnVector
 Matrix::row_min (void) const
 {
-  ColumnVector result;
-
-  int nr = rows ();
-  int nc = cols ();
-
-  if (nr > 0 && nc > 0)
-    {
-      result.resize (nr);
-
-      for (int i = 0; i < nr; i++)
-	{
-	  double res = elem (i, 0);
-	  for (int j = 1; j < nc; j++)
-	    if (elem (i, j) < res)
-	      res = elem (i, j);
-	  result.elem (i) = res;
-	}
-    }
-
-  return result;
+  Array<int> index;
+  return row_min (index);
 }
 
 ColumnVector
-Matrix::row_min_loc (void) const
+Matrix::row_min (Array<int>& index) const
 {
   ColumnVector result;
 
@@ -2329,14 +2313,37 @@
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
+      index.resize (nr);
 
       for (int i = 0; i < nr; i++)
         {
-          int res = 0;
-          for (int j = 0; j < nc; j++)
-            if (elem (i, j) < elem (i, res))
-              res = j;
-          result.elem (i) = (double) (res + 1);
+	  int idx = 0;
+
+	  double tmp_min = elem (i, idx);
+
+	  if (xisnan (tmp_min))
+	    idx = -1;
+	  else
+	    {
+	      for (int j = 1; j < nc; j++)
+		{
+		  double tmp = elem (i, j);
+
+		  if (xisnan (tmp))
+		    {
+		      idx = -1;
+		      break;
+		    }
+		  else if (tmp < tmp_min)
+		    {
+		      idx = j;
+		      tmp_min = tmp;
+		    }
+		}
+	    }
+
+	  result.elem (i) = (idx < 0) ? octave_NaN : tmp_min;
+	  index.elem (i) = idx;
         }
     }
 
@@ -2346,30 +2353,12 @@
 ColumnVector
 Matrix::row_max (void) const
 {
-  ColumnVector result;
-
-  int nr = rows ();
-  int nc = cols ();
-
-  if (nr > 0 && nc > 0)
-    {
-      result.resize (nr);
-
-      for (int i = 0; i < nr; i++)
-	{
-	  double res = elem (i, 0);
-	  for (int j = 1; j < nc; j++)
-	    if (elem (i, j) > res)
-	      res = elem (i, j);
-	  result.elem (i) = res;
-	}
-    }
-
-  return result;
+  Array<int> index;
+  return row_max (index);
 }
 
 ColumnVector
-Matrix::row_max_loc (void) const
+Matrix::row_max (Array<int>& index) const
 {
   ColumnVector result;
 
@@ -2379,14 +2368,37 @@
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
+      index.resize (nr);
 
       for (int i = 0; i < nr; i++)
         {
-          int res = 0;
-          for (int j = 0; j < nc; j++)
-            if (elem (i, j) > elem (i, res))
-              res = j;
-          result.elem (i) = (double) (res + 1);
+	  int idx = 0;
+
+	  double tmp_max = elem (i, idx);
+
+	  if (xisnan (tmp_max))
+	    idx = -1;
+	  else
+	    {
+	      for (int j = 1; j < nc; j++)
+		{
+		  double tmp = elem (i, j);
+
+		  if (xisnan (tmp))
+		    {
+		      idx = -1;
+		      break;
+		    }
+		  else if (tmp > tmp_max)
+		    {
+		      idx = j;
+		      tmp_max = tmp;
+		    }
+		}
+	    }
+
+	  result.elem (i) = (idx < 0) ? octave_NaN : tmp_max;
+	  index.elem (i) = idx;
         }
     }
 
@@ -2396,29 +2408,12 @@
 RowVector
 Matrix::column_min (void) const
 {
-  RowVector result;
-
-  int nr = rows ();
-  int nc = cols ();
-
-  if (nr > 0 && nc > 0)
-    {
-      result.resize (nc);
-
-      for (int j = 0; j < nc; j++)
-	{
-	  double res = elem (0, j);
-	  for (int i = 1; i < nr; i++)
-	    if (elem (i, j) < res)
-	      res = elem (i, j);
-	  result.elem (j) = res;
-	}
-    }
-
-  return result;
+  Array<int> index;
+  return column_min (index);
 }
+
 RowVector
-Matrix::column_min_loc (void) const
+Matrix::column_min (Array<int>& index) const
 {
   RowVector result;
 
@@ -2428,23 +2423,52 @@
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
+      index.resize (nc);
 
       for (int j = 0; j < nc; j++)
         {
-          int res = 0;
-          for (int i = 0; i < nr; i++)
-            if (elem (i, j) < elem (res, j))
-              res = i;
-          result.elem (j) = (double) (res + 1);
+	  int idx = 0;
+
+	  double tmp_min = elem (idx, j);
+
+	  if (xisnan (tmp_min))
+	    idx = -1;
+	  else
+	    {
+	      for (int i = 1; i < nr; i++)
+		{
+		  double tmp = elem (i, j);
+
+		  if (xisnan (tmp))
+		    {
+		      idx = -1;
+		      break;
+		    }
+		  else if (tmp < tmp_min)
+		    {
+		      idx = i;
+		      tmp_min = tmp;
+		    }
+		}
+	    }
+
+	  result.elem (j) = (idx < 0) ? octave_NaN : tmp_min;
+	  index.elem (j) = idx;
         }
     }
 
   return result;
 }
 
+RowVector
+Matrix::column_max (void) const
+{
+  Array<int> index;
+  return column_max (index);
+}
 
 RowVector
-Matrix::column_max (void) const
+Matrix::column_max (Array<int>& index) const
 {
   RowVector result;
 
@@ -2454,39 +2478,37 @@
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
-
-      for (int j = 0; j < nc; j++)
-	{
-	  double res = elem (0, j);
-	  for (int i = 1; i < nr; i++)
-	    if (elem (i, j) > res)
-	      res = elem (i, j);
-	  result.elem (j) = res;
-	}
-    }
-
-  return result;
-}
-
-RowVector
-Matrix::column_max_loc (void) const
-{
-  RowVector result;
-
-  int nr = rows ();
-  int nc = cols ();
-
-  if (nr > 0 && nc > 0)
-    {
-      result.resize (nc);
+      index.resize (nc);
 
       for (int j = 0; j < nc; j++)
         {
-          int res = 0;
-          for (int i = 0; i < nr; i++)
-            if (elem (i, j) > elem (res, j))
-              res = i;
-          result.elem (j) = (double) (res + 1);
+	  int idx = 0;
+
+	  double tmp_max = elem (idx, j);
+
+	  if (xisnan (tmp_max))
+	    idx = -1;
+	  else
+	    {
+	      for (int i = 1; i < nr; i++)
+		{
+		  double tmp = elem (i, j);
+
+		  if (xisnan (tmp))
+		    {
+		      idx = -1;
+		      break;
+		    }
+		  else if (tmp > tmp_max)
+		    {
+		      idx = i;
+		      tmp_max = tmp;
+		    }
+		}
+	    }
+
+	  result.elem (j) = (idx < 0) ? octave_NaN : tmp_max;
+	  index.elem (j) = idx;
         }
     }
 
--- a/liboctave/dMatrix.h
+++ b/liboctave/dMatrix.h
@@ -223,16 +223,16 @@
   ColumnVector diag (int k) const;
 
   ColumnVector row_min (void) const;
-  ColumnVector row_min_loc (void) const;
+  ColumnVector row_max (void) const;
 
-  ColumnVector row_max (void) const;
-  ColumnVector row_max_loc (void) const;
+  ColumnVector row_min (Array<int>& index) const;
+  ColumnVector row_max (Array<int>& index) const;
 
   RowVector column_min (void) const;
-  RowVector column_min_loc (void) const;
+  RowVector column_max (void) const;
 
-  RowVector column_max (void) const;
-  RowVector column_max_loc (void) const;
+  RowVector column_min (Array<int>& index) const;
+  RowVector column_max (Array<int>& index) const;
 
   // i/o
 
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+Tue Aug 20 17:41:19 1996  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* minmax.cc (Fmin, Fmax): Deal with changes to Matrix class
+	min/max methods.
+
 Thu Jul 25 01:42:38 1996  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* input.cc (generate_possible_completions): Force the names to be
--- a/src/minmax.cc
+++ b/src/minmax.cc
@@ -24,6 +24,7 @@
 #include <config.h>
 #endif
 
+#include "lo-ieee.h"
 #include "oct-math.h"
 
 #include "defun-dld.h"
@@ -394,15 +395,7 @@
 
   if (nargin == 1 && (nargout == 1 || nargout == 0))
     {
-      if (arg1.is_real_scalar ())
-	{
-	  retval(0) = arg1.double_value ();
-	}
-      else if (arg1.is_complex_scalar ())
-	{
-	  retval(0) = arg1.complex_value ();
-	}
-      else if (arg1.is_real_type ())
+      if (arg1.is_real_type ())
 	{
 	  Matrix m = arg1.matrix_value ();
 
@@ -427,39 +420,24 @@
 	    }
 	}
       else
-	{
-	  gripe_wrong_type_arg ("min", arg1);
-	  return retval;
-	}
+	gripe_wrong_type_arg ("min", arg1);
     }
   else if (nargin == 1 && nargout == 2)
     {
-      if (arg1.is_real_scalar ())
-	{
-	  retval(1) = 1;
-	  retval(0) = arg1.double_value ();
-	}
-      else if (arg1.is_complex_scalar ())
-	{
-	  retval(1) = 1;
-	  retval(0) = arg1.complex_value ();
-	}
-      else if (arg1.is_real_type ())
+      Array<int> index;
+
+      if (arg1.is_real_type ())
 	{
 	  Matrix m = arg1.matrix_value ();
 
 	  if (! error_state)
 	    {
+	      retval.resize (2);
+
 	      if (m.rows () == 1)
-		{
-		  retval(1) = m.row_min_loc ();
-		  retval(0) = m.row_min ();
-		}
+		retval(0) = m.row_min (index);
 	      else
-		{
-		  retval(1) = octave_value (m.column_min_loc (), 0);
-		  retval(0) = octave_value (m.column_min (), 0);
-		}
+		retval(0) = octave_value (m.column_min (index), 0);
 	    }
 	}
       else if (arg1.is_complex_type ())
@@ -468,22 +446,30 @@
 
 	  if (! error_state)
 	    {
+	      retval.resize (2);
+
 	      if (m.rows () == 1)
-		{
-		  retval(1) = m.row_min_loc ();
-		  retval(0) = m.row_min ();
-		}
+		retval(0) = m.row_min (index);
 	      else
-		{
-		  retval(1) = octave_value (m.column_min_loc (), 0);
-		  retval(0) = octave_value (m.column_min (), 0);
-		}
+		retval(0) = octave_value (m.column_min (index), 0);
 	    }
 	}
       else
+	gripe_wrong_type_arg ("min", arg1);
+
+      int len = index.length ();
+
+      if (len > 0)
 	{
-	  gripe_wrong_type_arg ("min", arg1);
-	  return retval;
+	  RowVector idx (len);
+
+	  for (int i = 0; i < len; i++)
+	    {
+	      int tmp = index.elem (i) + 1;
+	      idx.elem (i) = (tmp <= 0) ? octave_NaN : (double) tmp;
+	    }
+
+	  retval(1) = octave_value (idx, 0);
 	}
     }
   else if (nargin == 2)
@@ -622,15 +608,7 @@
 
   if (nargin == 1 && (nargout == 1 || nargout == 0))
     {
-      if (arg1.is_real_scalar ())
-	{
-	  retval(0) = arg1.double_value ();
-	}
-      else if (arg1.is_complex_scalar ())
-	{
-	  retval(0) = arg1.complex_value ();
-	}
-      else if (arg1.is_real_type ())
+      if (arg1.is_real_type ())
 	{
 	  Matrix m = arg1.matrix_value ();
 
@@ -655,39 +633,24 @@
 	    }
 	}
       else
-	{
-	  gripe_wrong_type_arg ("max", arg1);
-	  return retval;
-	}
+	gripe_wrong_type_arg ("max", arg1);
     }
   else if (nargin == 1 && nargout == 2)
     {
-      if (arg1.is_real_scalar ())
-	{
-	  retval(1) = 1;
-	  retval(0) = arg1.double_value ();
-	}
-      else if (arg1.is_complex_scalar ())
-	{
-	  retval(1) = 1;
-	  retval(0) = arg1.complex_value ();
-	}
-      else if (arg1.is_real_type ())
+      Array<int> index;
+
+      if (arg1.is_real_type ())
 	{
 	  Matrix m = arg1.matrix_value ();
 
 	  if (! error_state)
 	    {
+	      retval.resize (2);
+
 	      if (m.rows () == 1)
-		{
-		  retval(1) = m.row_max_loc ();
-		  retval(0) = m.row_max ();
-		}
+		retval(0) = m.row_max (index);
 	      else
-		{
-		  retval(1) = octave_value (m.column_max_loc (), 0);
-		  retval(0) = octave_value (m.column_max (), 0);
-		}
+		retval(0) = octave_value (m.column_max (index), 0);
 	    }
 	}
       else if (arg1.is_complex_type ())
@@ -696,22 +659,30 @@
 
 	  if (! error_state)
 	    {
+	      retval.resize (2);
+
 	      if (m.rows () == 1)
-		{
-		  retval(1) = m.row_max_loc ();
-		  retval(0) = m.row_max ();
-		}
+		retval(0) = m.row_max (index);
 	      else
-		{
-		  retval(1) = octave_value (m.column_max_loc (), 0);
-		  retval(0) = octave_value (m.column_max (), 0);
-		}
+		retval(0) = octave_value (m.column_max (index), 0);
 	    }
 	}
       else
+	gripe_wrong_type_arg ("max", arg1);
+
+      int len = index.length ();
+
+      if (len > 0)
 	{
-	  gripe_wrong_type_arg ("max", arg1);
-	  return retval;
+	  RowVector idx (len);
+
+	  for (int i = 0; i < len; i++)
+	    {
+	      int tmp = index.elem (i) + 1;
+	      idx.elem (i) = (tmp <= 0) ? octave_NaN : (double) tmp;
+	    }
+
+	  retval(1) = octave_value (idx, 0);
 	}
     }
   else if (nargin == 2)