1 4 package gnu.lists; 5 6 15 16 public class GeneralArray extends AbstractSequence 17 implements Array { 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 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 (); 91 result += strides[i] * index; 92 } 93 return result; 94 } 95 96 public Object 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 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 get(int[] indexes) 130 { 131 return base.get(getEffectiveIndex(indexes)); 132 } 133 134 public Object set(int[] indexes, Object value) 135 { 136 return base.set(getEffectiveIndex(indexes), value); 137 } 138 139 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 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 toString () 193 { 194 StringBuffer sbuf = new StringBuffer (); 195 toString(this, sbuf); 196 return sbuf.toString(); 197 } 198 } 199 | Popular Tags |