KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > lists > GeneralArray


1 // Copyright (c) 2001, 2002 Per M.A. Bothner and Brainfood Inc.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.lists;
5
6 /** A class to handle general multi-dimensional arrays.
7  * This class is <strong>unfinished</strong>.
8  * If the number of dimensions (the "rank") is one, should use
9  * a class that implements Sequence.
10  * GeneralArray uses a SimpleVector 'base' to store the actual data, and
11  * provides general linear mapping from the array indexes to an
12  * element index in the 'base' SimpleVector. Thus such uperations as
13  * transposing an array can be implement as just creating a simple
14  * re-mapping of the indexes. */

15
16 public class GeneralArray extends AbstractSequence
17 implements Array //, Consumable
18
// Should implement Collection?
19
// Note this intentionally does not implement Sequence.
20
{
21   SimpleVector base;
22   int[] dimensions;
23   int[] strides;
24   int[] lowBounds;
25   static final int[] zeros = new int[8];
26   int offset;
27   boolean simple = true;
28
29   public static Array makeSimple(int[] lowBounds, int[] dimensions,
30                  SimpleVector base)
31   {
32     int d = dimensions.length;
33     if (lowBounds == null)
34       {
35     lowBounds = zeros;
36     if (d > lowBounds.length)
37       lowBounds = new int[d];
38       }
39     if (d == 1 && lowBounds[0] == 0)
40       return base;
41     GeneralArray array = new GeneralArray();
42     int[] strides = new int[d];
43     int n = 1;
44     for (int i = d; --i >= 0; )
45       {
46     strides[i] = n;
47     n *= dimensions[i];
48       }
49     array.strides = strides;
50     array.dimensions = dimensions;
51     array.lowBounds = lowBounds;
52     array.base = base;
53     return array;
54   }
55
56   public GeneralArray()
57   {
58   }
59
60   public GeneralArray(int[] dimensions)
61   {
62     int total = 1;
63     int rank = dimensions.length;
64     if (rank <= zeros.length)
65       lowBounds = zeros;
66     else
67       lowBounds = new int[rank];
68     int[] strides = new int[rank];
69     for (int i = rank; --i >= 0; )
70       {
71     strides[i] = total;
72     total *= dimensions[i];
73       }
74     base = new FVector(total);
75     this.dimensions = dimensions;
76     this.offset = 0;
77   }
78
79   public int rank() { return dimensions.length; }
80
81   /** Calculate corresponding index in base array. */
82   public int getEffectiveIndex(int[] indexes)
83   {
84     int result = offset;
85     for (int i = dimensions.length; --i >= 0; )
86       {
87     int index = indexes[i];
88     int low = lowBounds[i];
89     if (index < low || (index -= low) >= dimensions[i])
90       throw new IndexOutOfBoundsException JavaDoc();
91     result += strides[i] * index;
92       }
93     return result;
94   }
95
96   public Object JavaDoc get (int index)
97   {
98     return getRowMajor(index);
99   }
100
101   public int createPos(int index, boolean isAfter)
102   {
103     int total = offset;
104     for (int i = dimensions.length; --i >= 0; )
105       {
106     int dim = dimensions[i];
107     int cur = index % dim;
108     index = index / dim;
109     total = total + strides[i] * cur;
110       }
111     return (total << 1) | (isAfter ? 1 : 0);
112   }
113
114   public Object JavaDoc getRowMajor(int index)
115   {
116     if (simple)
117       return base.get(index);
118     int total = offset;
119     for (int i = dimensions.length; --i >= 0; )
120       {
121     int dim = dimensions[i];
122     int cur = index % dim;
123     index = index / dim;
124     total = total + strides[i] * cur;
125       }
126     return base.get(total);
127   }
128
129   public Object JavaDoc get(int[] indexes)
130   {
131     return base.get(getEffectiveIndex(indexes));
132   }
133
134   public Object JavaDoc set(int[] indexes, Object JavaDoc value)
135   {
136     return base.set(getEffectiveIndex(indexes), value);
137   }
138
139   /** See java.util.Collection. */
140   public int size()
141   {
142     int total = 1;
143     for (int i = dimensions.length; --i >= 0; )
144       total *= dimensions[i];
145     return total;
146   }
147
148   public int getLowBound(int dim)
149   {
150     return lowBounds[dim];
151   }
152
153   public int getSize(int dim)
154   {
155     return dimensions[dim];
156   }
157
158   public Array transpose(int[] lowBounds, int[] dimensions,
159              int offset0, int[] factors)
160   {
161     GeneralArray array =
162       dimensions.length == 1 && lowBounds[0] == 0 ? new GeneralArray1()
163       : new GeneralArray();
164     array.offset = offset0;
165     array.strides = factors;
166     array.dimensions = dimensions;
167     array.lowBounds = lowBounds;
168     array.base = base;
169     array.simple = false;
170     return array;
171   }
172
173   public static void toString (Array array, StringBuffer JavaDoc sbuf)
174   {
175     sbuf.append("#<array");
176     int r = array.rank();
177     for (int i = 0; i < r; i++)
178       {
179     sbuf.append(' ');
180     int lo = array.getLowBound(i);
181     int sz = array.getSize(i);
182     if (lo != 0)
183       {
184         sbuf.append(lo);
185         sbuf.append(':');
186       }
187     sbuf.append(lo+sz);
188       }
189     sbuf.append('>');
190   }
191
192   public String JavaDoc toString ()
193   {
194     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
195     toString(this, sbuf);
196     return sbuf.toString();
197   }
198 }
199
Popular Tags