diff liboctave/dNDArray.cc @ 4844:9f7ef92b50b0

[project @ 2004-04-02 17:26:53 by jwe]
author jwe
date Fri, 02 Apr 2004 17:26:54 +0000
parents 4908c82cd1a1
children bd043a433918
line wrap: on
line diff
--- a/liboctave/dNDArray.cc
+++ b/liboctave/dNDArray.cc
@@ -656,6 +656,156 @@
   MX_ND_REAL_OP_REDUCTION (+= elem (iter_idx), 0);
 }
 
+NDArray
+NDArray::max (int dim) const
+{
+  ArrayN<int> dummy_idx;
+  return max (dummy_idx, dim);
+}
+
+NDArray
+NDArray::max (ArrayN<int>& idx_arg, int dim) const
+{
+  dim_vector dv = dims ();
+  dim_vector dr = dims ();
+
+  if (dv.numel () == 0 || dim > dv.length () || dim < 0)
+    return NDArray ();
+  
+  dr(dim) = 1;
+
+  NDArray result (dr);
+  idx_arg.resize (dr);
+
+  int x_stride = 1;
+  int x_len = dv(dim);
+  for (int i = 0; i < dim; i++)
+    x_stride *= dv(i);
+
+  for (int i = 0; i < dr.numel (); i++)
+    {
+      int x_offset;
+      if (x_stride == 1)
+	x_offset = i * x_len;
+      else
+	{
+	  int x_offset2 = 0;
+	  x_offset = i;
+	  while (x_offset >= x_stride)
+	    {
+	      x_offset -= x_stride;
+	      x_offset2++;
+	    }
+	  x_offset += x_offset2 * x_stride * x_len;
+	}
+
+      int idx_j;
+
+      double tmp_max = octave_NaN;
+
+      for (idx_j = 0; idx_j < x_len; idx_j++)
+	{
+	  tmp_max = elem (idx_j * x_stride + x_offset);
+	  
+	  if (! octave_is_NaN_or_NA (tmp_max))
+	    break;
+	}
+
+      for (int j = idx_j+1; j < x_len; j++)
+	{
+	  double tmp = elem (j * x_stride + x_offset);
+
+	  if (octave_is_NaN_or_NA (tmp))
+	    continue;
+	  else if (tmp > tmp_max)
+	    {
+	      idx_j = j;
+	      tmp_max = tmp;
+	    }
+	}
+
+      result.elem (i) = tmp_max;
+      idx_arg.elem (i) = octave_is_NaN_or_NA (tmp_max) ? 0 : idx_j;
+    }
+
+  return result;
+}
+
+NDArray
+NDArray::min (int dim) const
+{
+  ArrayN<int> dummy_idx;
+  return min (dummy_idx, dim);
+}
+
+NDArray
+NDArray::min (ArrayN<int>& idx_arg, int dim) const
+{
+  dim_vector dv = dims ();
+  dim_vector dr = dims ();
+
+  if (dv.numel () == 0 || dim > dv.length () || dim < 0)
+    return NDArray ();
+  
+  dr(dim) = 1;
+
+  NDArray result (dr);
+  idx_arg.resize (dr);
+
+  int x_stride = 1;
+  int x_len = dv(dim);
+  for (int i = 0; i < dim; i++)
+    x_stride *= dv(i);
+
+  for (int i = 0; i < dr.numel (); i++)
+    {
+      int x_offset;
+      if (x_stride == 1)
+	x_offset = i * x_len;
+      else
+	{
+	  int x_offset2 = 0;
+	  x_offset = i;
+	  while (x_offset >= x_stride)
+	    {
+	      x_offset -= x_stride;
+	      x_offset2++;
+	    }
+	  x_offset += x_offset2 * x_stride * x_len;
+	}
+
+      int idx_j;
+
+      double tmp_min = octave_NaN;
+
+      for (idx_j = 0; idx_j < x_len; idx_j++)
+	{
+	  tmp_min = elem (idx_j * x_stride + x_offset);
+	  
+	  if (! octave_is_NaN_or_NA (tmp_min))
+	    break;
+	}
+
+      for (int j = idx_j+1; j < x_len; j++)
+	{
+	  double tmp = elem (j * x_stride + x_offset);
+
+	  if (octave_is_NaN_or_NA (tmp))
+	    continue;
+	  else if (tmp < tmp_min)
+	    {
+	      idx_j = j;
+	      tmp_min = tmp;
+	    }
+	}
+
+      result.elem (i) = tmp_min;
+      idx_arg.elem (i) = octave_is_NaN_or_NA (tmp_min) ? 0 : idx_j;
+    }
+
+  return result;
+}
+
 int
 NDArray::cat (const NDArray& ra_arg, int dim, int iidx, int move)
 {
@@ -776,6 +926,141 @@
   return is;
 }
 
+// XXX FIXME XXX -- it would be nice to share code among the min/max
+// functions below.
+
+#define EMPTY_RETURN_CHECK(T) \
+  if (nel == 0)	\
+    return T (dv);
+
+NDArray
+min (double d, const NDArray& m)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (d, m (i));
+    }
+
+  return result;
+}
+
+NDArray
+min (const NDArray& m, double d)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (d, m (i));
+    }
+
+  return result;
+}
+
+NDArray
+min (const NDArray& a, const NDArray& b)
+{
+  dim_vector dv = a.dims ();
+  int nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg min expecting args of same size");
+      return NDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmin (a (i), b (i));
+    }
+
+  return result;
+}
+
+NDArray
+max (double d, const NDArray& m)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (d, m (i));
+    }
+
+  return result;
+}
+
+NDArray
+max (const NDArray& m, double d)
+{
+  dim_vector dv = m.dims ();
+  int nel = dv.numel ();
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (d, m (i));
+    }
+
+  return result;
+}
+
+NDArray
+max (const NDArray& a, const NDArray& b)
+{
+  dim_vector dv = a.dims ();
+  int nel = dv.numel ();
+
+  if (dv != b.dims ())
+    {
+      (*current_liboctave_error_handler)
+	("two-arg max expecting args of same size");
+      return NDArray ();
+    }
+
+  EMPTY_RETURN_CHECK (NDArray);
+
+  NDArray result (dv);
+
+  for (int i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = xmax (a (i), b (i));
+    }
+
+  return result;
+}
+
 NDS_CMP_OPS(NDArray, , double, )
 NDS_BOOL_OPS(NDArray, double, 0.0)