Arrays.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. package gnu.lists;
  2. public class Arrays {
  3. public static int rowMajorToEffectiveIndex(Array arr, int index) {
  4. if (arr instanceof GeneralArray) {
  5. GeneralArray garr = (GeneralArray) arr;
  6. if (garr.simple)
  7. return garr.base.effectiveIndex(index);
  8. }
  9. int r = arr.rank();
  10. switch (r) {
  11. case 0:
  12. return arr.effectiveIndex();
  13. case 1:
  14. return arr.effectiveIndex(index + arr.getLowBound(0));
  15. case 2:
  16. int sz1 = arr.getSize(1);
  17. return arr.effectiveIndex((index / sz1) + arr.getLowBound(0),
  18. (index % sz1) + arr.getLowBound(1));
  19. default:
  20. int[] rest = r == 3 ? AbstractSequence.noInts : new int[r-3];
  21. int p = 1;
  22. int sz;
  23. for (int i = r; --i >= 3; ) {
  24. sz = arr.getSize(i);
  25. rest[i] = (index % sz) + arr.getLowBound(i);
  26. index = index / sz;
  27. }
  28. sz = arr.getSize(2);
  29. int i2 = (index % sz) + arr.getLowBound(2);
  30. index = index / sz;
  31. sz = arr.getSize(1);
  32. int i1 = (index % sz) + arr.getLowBound(1);
  33. index = index / sz;
  34. sz = arr.getSize(0);
  35. int i0 = (index % sz) + arr.getLowBound(0);
  36. return arr.effectiveIndex(i0, i1, i2, rest);
  37. }
  38. }
  39. public static <E> E getRowMajor(Array<E> arr, int index) {
  40. return (E) arr.getRaw(rowMajorToEffectiveIndex(arr, index));
  41. }
  42. public static int hashCode(Array arr) {
  43. int rank = arr.rank();
  44. int[] indexes = new int[rank];
  45. int size = 1;
  46. for (int r = 0; r < rank; r++) {
  47. indexes[r] = arr.getLowBound(r);
  48. size *= arr.getSize(r);
  49. }
  50. int hash = 1;
  51. for (int i = 0; i < size; i++) {
  52. Object element = arr.get(indexes);
  53. hash = 31*hash + (element==null ? 0 : element.hashCode());
  54. gnu.lists.Arrays.incrementIndexes(indexes, arr);
  55. }
  56. return hash;
  57. }
  58. public static Array<Integer> asIntArrayOrNull(Object obj) {
  59. if (obj instanceof Array) {
  60. Array arr = (Array) obj;
  61. int kind = arr.getElementKind();
  62. if (kind >= Sequence.INT_U8_VALUE && kind <= Sequence.INT_S64_VALUE)
  63. return arr;
  64. }
  65. if (obj instanceof Array) {
  66. Array arr = (Array) obj;
  67. int sz = arr.getSize();
  68. int rank = arr.rank();
  69. int[] data = new int[sz];
  70. int[] dims = new int[rank];
  71. int[] lows = null;
  72. int[] work = new int[rank];
  73. for (int i = 0; i < rank; i++) {
  74. dims[i] = arr.getSize(i);
  75. int low = arr.getLowBound(i);
  76. if (low != 0) {
  77. if (lows == null)
  78. lows = new int[rank];
  79. lows[i] = low;
  80. }
  81. work[i] = low;
  82. }
  83. for (int j = 0; j < sz; ) {
  84. Object datum = arr.get(work);
  85. data[j] = ((Number) datum).intValue();
  86. if (++j == sz)
  87. break;
  88. work[rank-1] ++;
  89. for (int i = rank; --i >= 0; ) {
  90. int low = lows == null ? 0 : lows[i];
  91. if (work[i] < low + dims[i])
  92. break;
  93. work[i] = low;
  94. work[i-1]++;
  95. }
  96. }
  97. S32Vector vec = new S32Vector(data);
  98. if (rank == 1 && lows == null)
  99. return vec;
  100. return (Array<Integer>) new GeneralArray(vec, dims, lows);
  101. }
  102. IntSequence is = Sequences.asIntSequenceOrNull(obj);
  103. if (is != null)
  104. return is;
  105. if (obj instanceof Number) {
  106. // FIXME should use an optimized class for this case
  107. int[] iis = new int[] { ((Number) obj).intValue() };
  108. S32Vector vec = new S32Vector(iis);
  109. return (Array<Integer>)
  110. new GeneralArray(vec, AbstractSequence.noInts,
  111. AbstractSequence.noInts);
  112. }
  113. return null;
  114. }
  115. public static void incrementIndexes(int[] indexes, Array<?> arr) {
  116. for (int r = arr.rank(); --r >= 0; ) {
  117. int ind = indexes[r];
  118. ind++;
  119. int low = arr.getLowBound(r);
  120. int dim = arr.getSize(r);
  121. if (ind-low < dim) {
  122. indexes[r] = ind;
  123. break;
  124. }
  125. indexes[r] = low;
  126. }
  127. }
  128. public static int[] getDimensions(Array<?> arr) {
  129. if (arr instanceof GeneralArray<?>)
  130. return ((GeneralArray<?>) arr).dimensions;
  131. int rank = arr.rank();
  132. int[] dims = new int[rank];
  133. for (int i = rank; --i >= 0; )
  134. dims[i] = arr.getSize(i);
  135. return dims;
  136. }
  137. public static int[] getLowBounds(Array<?> arr) {
  138. if (arr instanceof GeneralArray<?>)
  139. return ((GeneralArray<?>) arr).lowBounds;
  140. int rank = arr.rank();
  141. int[] lows = new int[rank];
  142. for (int i = rank; --i >= 0; )
  143. lows[i] = arr.getLowBound(i);
  144. return lows;
  145. }
  146. public static <E> void fill(Array<E> arr, E value) {
  147. int rank = arr.rank();
  148. int[] indexes = new int[rank];
  149. for (int r = rank; --r >= 0; )
  150. indexes[r] = arr.getLowBound(r);
  151. int size = arr.getSize();
  152. for (int i = size; --i >= 0; ) {
  153. arr.set(indexes, value);
  154. incrementIndexes(indexes, arr);
  155. }
  156. }
  157. public static <E> void copy(Array<E> dst, Array<E> src) {
  158. int rank = dst.rank();
  159. if (rank != src.rank())
  160. throw new RuntimeException("incompatible arrays for copy (source rank :"+src.rank()+", destination rank:"+rank+")");
  161. int[] idst = new int[rank];
  162. int[] isrc = new int[rank];
  163. for (int r = rank; --r >= 0; ) {
  164. int ssize = src.getSize(r);
  165. int dsize = dst.getSize(r);
  166. if (ssize != dsize)
  167. throw new RuntimeException("incompatible arrays for copy, dimension "+r+" (source size: "+ssize+"; destination: "+dsize+")");
  168. isrc[r] = src.getLowBound(r);
  169. idst[r] = dst.getLowBound(r);
  170. }
  171. int size = dst.getSize();
  172. for (int i = size; --i >= 0; ) {
  173. E value = src.get(isrc);
  174. dst.set(idst, value);
  175. incrementIndexes(isrc, src);
  176. incrementIndexes(idst, dst);
  177. }
  178. }
  179. public static <E> GeneralArray<E> simpleCopy(Array<E> arr, boolean writable) {
  180. SimpleVector<E> vec = flattenCopy(arr, writable);
  181. return GeneralArray.make(vec, getDimensions(arr),
  182. getLowBounds(arr), null, 0);
  183. }
  184. public static <E> SimpleVector<E> flattenCopy(Array<E> arr, boolean writable) {
  185. int rank = arr.rank();
  186. int[] indexes = new int[rank];
  187. for (int d = rank; --d >= 0; )
  188. indexes[d] = arr.getLowBound(d);
  189. int size = arr.getSize();
  190. int kind = arr.getElementKind();
  191. SimpleVector vec;
  192. switch (kind) {
  193. case Sequence.BOOLEAN_VALUE:
  194. {
  195. boolean[] data = new boolean[size];
  196. for (int i = 0; i < size; i++) {
  197. int effi = arr.effectiveIndex(indexes);
  198. incrementIndexes(indexes, arr);
  199. data[i] = arr.getBooleanRaw(effi);
  200. }
  201. vec = new BitVector(data);
  202. }
  203. break;
  204. case Sequence.CHAR_VALUE:
  205. {
  206. char[] data = new char[size];
  207. for (int i = 0; i < size; i++) {
  208. int effi = arr.effectiveIndex(indexes);
  209. incrementIndexes(indexes, arr);
  210. data[i] = arr.getCharRaw(effi);
  211. }
  212. vec = new CharVector(data);
  213. }
  214. break;
  215. case Sequence.INT_S8_VALUE:
  216. case Sequence.INT_U8_VALUE:
  217. {
  218. byte[] data = new byte[size];
  219. for (int i = 0; i < size; i++) {
  220. int effi = arr.effectiveIndex(indexes);
  221. incrementIndexes(indexes, arr);
  222. data[i] = arr.getByteRaw(effi);
  223. }
  224. vec = kind == Sequence.INT_S8_VALUE ? new S8Vector(data)
  225. : new U8Vector(data);
  226. }
  227. break;
  228. case Sequence.INT_S16_VALUE:
  229. case Sequence.INT_U16_VALUE:
  230. {
  231. short[] data = new short[size];
  232. for (int i = 0; i < size; i++) {
  233. int effi = arr.effectiveIndex(indexes);
  234. incrementIndexes(indexes, arr);
  235. data[i] = arr.getShortRaw(effi);
  236. }
  237. vec = kind == Sequence.INT_S16_VALUE ? new S16Vector(data)
  238. : new U16Vector(data);
  239. }
  240. break;
  241. case Sequence.INT_S32_VALUE:
  242. case Sequence.INT_U32_VALUE:
  243. {
  244. int[] data = new int[size];
  245. for (int i = 0; i < size; i++) {
  246. int effi = arr.effectiveIndex(indexes);
  247. incrementIndexes(indexes, arr);
  248. data[i] = arr.getIntRaw(effi);
  249. }
  250. vec = kind == Sequence.INT_S32_VALUE ? new S32Vector(data)
  251. : new U32Vector(data);
  252. }
  253. break;
  254. case Sequence.INT_S64_VALUE:
  255. case Sequence.INT_U64_VALUE:
  256. {
  257. long[] data = new long[size];
  258. for (int i = 0; i < size; i++) {
  259. int effi = arr.effectiveIndex(indexes);
  260. incrementIndexes(indexes, arr);
  261. data[i] = arr.getLongRaw(effi);
  262. }
  263. vec = kind == Sequence.INT_S64_VALUE ? new S64Vector(data)
  264. : new U64Vector(data);
  265. }
  266. break;
  267. case Sequence.FLOAT_VALUE:
  268. {
  269. float[] data = new float[size];
  270. for (int i = 0; i < size; i++) {
  271. int effi = arr.effectiveIndex(indexes);
  272. incrementIndexes(indexes, arr);
  273. data[i] = arr.getFloatRaw(effi);
  274. }
  275. vec = new F32Vector(data);
  276. }
  277. break;
  278. case Sequence.DOUBLE_VALUE:
  279. {
  280. double[] data = new double[size];
  281. for (int i = 0; i < size; i++) {
  282. int effi = arr.effectiveIndex(indexes);
  283. incrementIndexes(indexes, arr);
  284. data[i] = arr.getDoubleRaw(effi);
  285. }
  286. vec = new F64Vector(data);
  287. }
  288. break;
  289. default:
  290. {
  291. Object[] data = new Object[size];
  292. for (int i = 0; i < size; i++) {
  293. int effi = arr.effectiveIndex(indexes);
  294. incrementIndexes(indexes, arr);
  295. data[i] = arr.getRaw(effi);
  296. }
  297. vec = new FVector(data);
  298. }
  299. break;
  300. }
  301. if (! writable)
  302. vec.info |= SimpleVector.READ_ONLY_FLAG;
  303. return vec;
  304. }
  305. }