diff liboctave/Array-util.cc @ 4588:19bfd295f400

[project @ 2003-11-10 17:18:48 by jwe]
author jwe
date Mon, 10 Nov 2003 17:22:02 +0000
parents
children 77566be8b9e9
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/liboctave/Array-util.cc
@@ -0,0 +1,517 @@
+/*
+
+Copyright (C) 2003 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Array-util.h"
+
+bool
+index_in_bounds (const Array<int>& ra_idx, const dim_vector& dimensions)
+{
+  bool retval = true;
+
+  int n = ra_idx.length ();
+
+  if (n == dimensions.length ())
+    {
+      for (int i = 0; i < n; i++)
+	{
+	  if (ra_idx(i) < 0 || ra_idx(i) > dimensions (i))
+	    {
+	      retval = false;
+	      break;
+	    }
+	}
+    }
+  else
+    retval = false;
+
+  return retval;
+}
+
+void
+increment_index (Array<int>& ra_idx, const dim_vector& dimensions,
+		 int start_dimension)
+{
+  ra_idx(start_dimension)++;
+
+  int n = ra_idx.length () - 1;
+
+  for (int i = start_dimension; i < n; i++)
+    {
+      if (ra_idx(i) < dimensions(i))
+ 	break;
+      else
+ 	{
+ 	  ra_idx(i) = 0;
+ 	  ra_idx(i+1)++;
+ 	}
+    }
+}
+
+int
+get_scalar_idx (Array<int>& idx, dim_vector& dims)
+{
+  int retval (-1);
+
+  int n = idx.length ();
+
+  if (n > 0)
+    {
+      retval = idx(--n);
+
+      while (--n >= 0)
+	{      		
+	  retval *= dims (n);
+	
+	  retval += idx(n);
+	}
+    }
+  return retval;
+}
+
+int
+num_ones (const Array<int>& ra_idx)
+{
+  int retval (0);
+  for (int i = 0; i < ra_idx.length (); i++)
+    {
+      if (ra_idx (i) == 1)
+	retval++;
+    }
+  return retval;
+}
+
+bool
+is_scalar (const dim_vector& dim)
+{
+  bool retval = true;
+
+  int n = dim.length ();
+
+  if (n == 0)
+    {
+      retval = false;
+    }
+  else
+    {
+      for (int i = 0; i < n; i ++)
+	{
+	  if (dim (i) != 1)
+	    {
+	      retval = false;
+	
+	      break;
+	    }
+	}
+    }
+  return retval;
+}
+
+bool
+any_ones (const Array<int>& arr)
+{
+  bool retval = false;
+
+  for (int i = 0; i < arr.length (); i++)
+    {
+      if (arr (i) == 1)
+	{
+	  retval = true;
+	
+	  break;
+	}
+    }
+  return retval;
+}
+
+int
+compute_index (const Array<int>& ra_idx, const dim_vector& dims)
+{
+  int retval = -1;
+
+  int n = dims.length ();
+
+  if (n > 0 && n == ra_idx.length ())
+    {
+      retval = ra_idx(--n);
+
+      while (--n >= 0)
+	{
+	  retval *= dims(n);
+	
+	  retval += ra_idx(n);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("ArrayN<T>::compute_index: invalid ra_idxing operation");
+
+  return retval;
+}
+
+Array<int>
+conv_to_int_array (const Array<idx_vector>& a)
+{
+  Array<int> retval (a.length ());
+
+  for (int i = 0; i < a.length (); i++)
+    retval (i) = a(i).elem (0);
+
+  return retval;
+}
+
+Array<idx_vector>
+conv_to_array (const idx_vector *tmp, const int len)
+{
+  Array<idx_vector> retval (len);
+
+  for (int i = 0; i < len; i++)
+      retval (i) = tmp[i];
+
+  return retval;
+}
+
+dim_vector
+freeze (Array<idx_vector>& ra_idx, const dim_vector& dimensions, int resize_ok)
+{
+  dim_vector retval;
+
+  int n = ra_idx.length ();
+
+  assert (n == dimensions.length ());
+
+  retval.resize (n);
+
+  for (int i = 0; i < n; i++)
+    retval(i) = ra_idx(i).freeze (dimensions(i), "XXX FIXME XXX", resize_ok);
+
+  return retval;
+}
+
+bool
+vector_equivalent (const Array<int>& ra_idx)
+{
+  int n = ra_idx.length ();
+
+  bool found_first = false;
+
+  for (int i = 0; i < n; i++)
+    {
+      if (ra_idx(i) != 1)
+        {
+	  if (! found_first)
+	    found_first = true;
+	  else
+	    return false;
+	}
+    }
+
+  return true;
+}
+
+bool
+equal_arrays (const dim_vector& a, const dim_vector& b)
+{
+  bool retval = true;
+
+  if (a.length () != b.length ())
+    retval = false;
+  else
+    {
+      for (int i = 0; i < a.length (); i++)
+	{
+	  if (a(i) != b(i))
+	    retval = false;
+	}
+    }
+
+  return retval;
+}
+
+bool
+all_ok (const Array<idx_vector>& ra_idx)
+{
+  bool retval = true;
+
+  int n = ra_idx.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      if (! ra_idx(i))
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+bool
+any_orig_empty (const Array<idx_vector>& ra_idx)
+{
+  bool retval = false;
+
+  int n = ra_idx.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      if (ra_idx(i).orig_empty ())
+	{
+	  retval = true;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+bool
+any_zero_len (const dim_vector& frozen_lengths)
+{
+  bool retval = false;
+
+  int n = frozen_lengths.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      if (frozen_lengths(i) == 0)
+	{
+	  retval = true;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+dim_vector
+get_zero_len_size (const dim_vector& frozen_lengths,
+		   const dim_vector& dimensions)
+{
+  dim_vector retval;
+  assert (0);
+  return retval;
+}
+
+bool
+all_colon_equiv (const Array<idx_vector>& ra_idx,
+		 const dim_vector& frozen_lengths)
+{
+  bool retval = true;
+
+  int idx_n = ra_idx.length ();
+
+  int n = frozen_lengths.length ();
+
+  assert (idx_n == n);
+
+  for (int i = 0; i < n; i++)
+    {
+      if (! ra_idx(i).is_colon_equiv (frozen_lengths(i)))
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+bool
+is_in (int num, const idx_vector& idx)
+{
+  int n = idx.capacity ();
+
+  for (int i = 0; i < n; i++)
+    if (idx.elem (i) == num)
+      return true;
+
+  return false;
+}
+
+int
+how_many_lgt (const int num, idx_vector& idxv)
+{
+  int retval = 0;
+
+  int n = idxv.capacity ();
+
+  for (int i = 0; i < n; i++)
+    {
+      if (num > idxv.elem (i))
+	retval++;
+    }
+
+  return retval;
+}
+
+bool
+all_ones (const Array<int>& arr)
+{
+  bool retval = true;
+
+  for (int i = 0; i < arr.length (); i++)
+    {
+      if (arr(i) != 1)
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+Array<int>
+get_elt_idx (const Array<idx_vector>& ra_idx, const Array<int>& result_idx)
+{
+  int n = ra_idx.length ();
+
+  Array<int> retval (n);
+
+  for (int i = 0; i < n; i++)
+    retval(i) = ra_idx(i).elem (result_idx(i));
+
+  return retval;
+}
+
+int
+number_of_elements (const dim_vector ra_idx)
+{
+  int retval = 1;
+
+  int n = ra_idx.length ();
+
+  if (n == 0)
+    retval = 0;
+
+  for (int i = 0; i < n; i++)
+    retval *= ra_idx(i);
+
+  return retval;
+}
+
+Array<int>
+get_ra_idx (int idx, const dim_vector& dims)
+{
+  Array<int> retval;
+
+  int n_dims = dims.length ();
+
+  retval.resize (n_dims);
+
+  for (int i = 0; i < n_dims; i++)
+    retval(i) = 0;
+
+  assert (idx > 0 || idx < number_of_elements (dims));
+
+  for (int i = 0; i < idx; i++)
+    increment_index (retval, dims);
+
+  // XXX FIXME XXX -- the solution using increment_index is not
+  // efficient.
+
+#if 0
+  int var = 1;
+  for (int i = 0; i < n_dims; i++)
+    {
+      std::cout << "idx: " << idx << ", var: " << var << ", dims(" << i << "): " << dims(i) <<"\n";
+      retval(i) = ((int)floor(((idx) / (double)var))) % dims(i);
+      idx -= var * retval(i);
+      var = dims(i);
+    }
+#endif
+
+  return retval;
+}
+
+dim_vector
+short_freeze (Array<idx_vector>& ra_idx, const dim_vector& dimensions,
+	      int resize_ok)
+{
+  dim_vector retval;
+
+  int n = ra_idx.length ();
+
+  int n_dims = dimensions.length ();
+
+  if (n == n_dims)
+    {
+      retval = freeze (ra_idx, dimensions, resize_ok);
+    }
+  else if (n < n_dims)
+    {
+      retval.resize (n);
+      
+      for (int i = 0; i < n - 1; i++)
+        retval(i) = ra_idx(i).freeze (dimensions(i), "dimension", resize_ok);
+
+      int size_left = 1;
+
+      for (int i = n - 1; i < n_dims; i++)
+        size_left *= dimensions(i); 
+ 
+      if (ra_idx(n-1).is_colon())
+        {
+	  retval(n-1) = size_left;
+	}
+      else
+	{
+	  int last_ra_idx = ra_idx(n-1)(0);
+
+	  if (last_ra_idx < dimensions(n - 1))
+            {
+              retval(n - 1) = ra_idx(n - 1).freeze (dimensions(n-1),
+						    "dimension", resize_ok);
+            }
+          else
+            {
+              if (size_left <= last_ra_idx)
+                {
+         	  // Make it larger than it should be to get an error
+         	  // later.
+
+                  retval.resize(n_dims + 1);
+
+                  (*current_liboctave_error_handler)
+                    ("index exceeds N-d array dimensions");
+                }
+              else
+                {
+                  retval(n-1) = 1;
+                }
+	    }
+	}
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/