diff liboctave/idx-vector.cc @ 1:78fd87e624cb

[project @ 1993-08-08 01:13:40 by jwe] Initial revision
author jwe
date Sun, 08 Aug 1993 01:13:40 +0000
parents
children e2c950dd96d2
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/idx-vector.cc	Sun Aug 08 01:13:40 1993 +0000
@@ -0,0 +1,249 @@
+// Very simple integer vectors for indexing              -*- C++ -*-
+/*
+
+Copyright (C) 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include "idx-vector.h"
+#include "error.h"
+#include "user-prefs.h"
+#include "utils.h"
+
+idx_vector::idx_vector (const idx_vector& a)
+{
+  len = a.len;
+  if (len > 0)
+    {
+      data = new int [len];
+      for (int i = 0; i < len; i++)
+	data[i] = a.data[i];
+
+      num_zeros = a.num_zeros;
+      num_ones = a.num_ones;
+      one_zero = a.one_zero;
+
+      max_val = a.max_val;
+      min_val = a.min_val;
+    }
+  else
+    data = 0;
+}
+
+static inline int
+tree_to_mat_idx (double x)
+{
+  if (x > 0)
+    return ((int) (x + 0.5) - 1);
+  else
+    return ((int) (x - 0.5) - 1);
+}
+
+idx_vector::idx_vector (Matrix& m, int do_ftn_idx, char *rc, int z_len = 0)
+{
+  int nr = m.rows ();
+  int nc = m.columns ();
+
+  if (nr == 0 || nc == 0)
+    {
+      len = 0;
+      data = 0;
+      num_zeros = 0;
+      num_ones = 0;
+      one_zero = 0;
+      return;
+    }
+  else if (nr > 1 && nc > 1 && do_ftn_idx)
+    {
+      double *cop_out = m.fortran_vec ();
+      len = nr * nc;
+      data = new int [len];
+      for (int i = 0; i < len; i++)
+	data[i] = tree_to_mat_idx (*cop_out++);
+    }
+  else if (nr == 1 && nc > 0)
+    {
+      len = nc;
+      data = new int [len];
+      for (int i = 0; i < len; i++)
+	data[i] = tree_to_mat_idx (m.elem (0, i)); 
+    }  
+  else if (nc == 1 && nr > 0)
+    {
+      len = nr;
+      data = new int [len];
+      for (int i = 0; i < len; i++)
+	data[i] = tree_to_mat_idx (m.elem (i, 0));
+    }
+  else
+    {
+      message ((char *) NULL, "invalid matrix index");
+      jump_to_top_level ();
+    }
+
+  init_state (rc, z_len);
+}
+
+idx_vector::idx_vector (const Range& r)
+{
+  len = r.nelem ();
+
+  assert (len != 0);
+
+  double b = r.base ();
+  double step = r.inc ();
+
+  data = new int [len];
+
+  for (int i = 0; i < len; i++)
+    {
+      double val = b + i * step;
+      data[i] = tree_to_mat_idx (val);
+    }
+
+  init_state ();
+}
+
+idx_vector&
+idx_vector::operator = (const idx_vector& a)
+{
+  if (this != &a)
+    {
+      delete [] data;
+      len = a.len;
+      data = new int [len];
+      for (int i = 0; i < len; i++)
+	data[i] = a.data[i];
+
+      num_zeros = a.num_zeros;
+      num_ones = a.num_ones;
+      one_zero = a.one_zero;
+
+      max_val = a.max_val;
+      min_val = a.min_val;
+    }
+  return *this;
+}
+
+void
+idx_vector::init_state (char *rc, int z_len = 0)
+{
+  one_zero = 1;
+  num_zeros = 0;
+  num_ones = 0;
+
+  min_val = max_val = data[0];
+
+  int i = 0;
+  do
+    {
+      if (data[i] == -1)
+	num_zeros++;
+      else if (data[i] == 0)
+	num_ones++;
+
+      if (one_zero && data[i] != -1 && data[i] != 0)
+	one_zero = 0;
+
+      if (data[i] > max_val)
+	max_val = data[i];
+
+      if (data[i] < min_val)
+	min_val = data[i];
+    }
+  while (++i < len);
+
+  if (one_zero && z_len == len)
+    {
+      if (num_zeros == len)
+	{
+	  delete [] data;
+	  len = 0;
+	  data = 0;
+	  num_zeros = 0;
+	  num_ones = 0;
+	  one_zero = 0;
+	}
+      else if (num_ones != len || user_pref.prefer_zero_one_indexing)
+	convert_one_zero_to_idx ();
+    }
+  else if (min_val < 0)
+    {
+      error ("%s index %d out of range", rc, min_val+1);
+      jump_to_top_level ();
+    }
+}
+
+void
+idx_vector::convert_one_zero_to_idx (void)
+{
+  if (num_ones == 0)
+    {
+      len = 0;
+      max_val = 0;
+      min_val = 0;
+      delete [] data;
+    }
+  else
+    {
+      assert (num_ones + num_zeros == len);
+
+      int *new_data = new int [num_ones];
+      int count = 0;
+      for (int i = 0; i < len; i++)
+	if (data[i] == 0)
+	  new_data[count++] = i;
+
+      delete [] data;
+      len = num_ones;
+      data = new_data;
+
+      min_val = max_val = data[0];
+
+      i = 0;
+      do
+	{
+	  if (data[i] > max_val)
+	    max_val = data[i];
+
+	  if (data[i] < min_val)
+	    min_val = data[i];
+	}
+      while (++i < len);
+    }
+}
+
+ostream&
+operator << (ostream& os, const idx_vector& a)
+{
+  for (int i = 0; i < a.len; i++)
+    os << a.data[i] << "\n";
+  return os;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/