PageRenderTime 49ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/polan02/runtime/CBucks.Common/ArrOps.cs

#
C# | 833 lines | 443 code | 45 blank | 345 comment | 184 complexity | f0539b4c6581bdc2d2fe76f71177d9f2 MD5 | raw file
Possible License(s): AGPL-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Wintellect.PowerCollections;
  5. namespace CBucks.Common {
  6. public delegate bool DoublePred<T1, T2>(T1 a, T2 b);
  7. public delegate T3 Transform<T1, T2, T3>(T1 a, T2 b);
  8. /// <summary>
  9. /// Contains common array operations
  10. /// </summary>
  11. public static class ArrOps {
  12. /// <summary>
  13. /// Checks whether the specified arrays are equal, i.e., contain equal
  14. /// components and are of same length.
  15. /// </summary>
  16. /// <typeparam name="T"> The first array </typeparam>
  17. /// <param name="a"> The first array </param>
  18. /// <param name="b"> The second array </param>
  19. /// <returns> True if they are equal and false if not </returns>
  20. public static bool equal<T>(T[] a, T[] b) {
  21. if(null == a || null == b)
  22. return null == a && null == b;
  23. if(a.Length != b.Length)
  24. return false;
  25. int n = a.Length;
  26. for(int i = 0; i < n; i++)
  27. if(!object.Equals(a[i], b[i]))
  28. return false;
  29. return true;
  30. } // end of equal<T>
  31. /// <summary>
  32. /// Checks whether the specified arrays contain all their references
  33. /// equal
  34. /// </summary>
  35. /// <typeparam name="T"> The array type </typeparam>
  36. /// <param name="a"> The first array </param>
  37. /// <param name="b"> The second array </param>
  38. /// <returns> True if they do and false if not </returns>
  39. public static bool equalRef<T>(T[] a, T[] b) where T : class {
  40. if(null == a || null == b)
  41. return null == a && null == b;
  42. if(a.Length != b.Length)
  43. return false;
  44. int n = a.Length;
  45. for(int i = 0; i < n; i++)
  46. if(a[i] != b[i])
  47. return false;
  48. return true;
  49. } // end of equalRef<T>
  50. /// <summary>
  51. /// Gets whether all elements of the specified array are equal to
  52. /// the specified value
  53. /// </summary>
  54. /// <typeparam name="T"> The element type </typeparam>
  55. /// <param name="a"> The array </param>
  56. /// <param name="b"> The value </param>
  57. /// <returns> True if it is and false if not </returns>
  58. public static bool allEqual<T>(T[] a, T b) {
  59. if(null == a || a.Length == 0)
  60. return true;
  61. for(int i = 0; i < a.Length; i++)
  62. if(!object.Equals(a[i], b))
  63. return false;
  64. return true;
  65. } // end of allEqual<T>()
  66. /// <summary>
  67. /// Gets whether all elements of the specified array are reference equal to
  68. /// the specified value
  69. /// </summary>
  70. /// <typeparam name="T"> The element type </typeparam>
  71. /// <param name="a"> The array </param>
  72. /// <param name="b"> The value </param>
  73. /// <returns> True if it is and false if not </returns>
  74. public static bool allEqualRef<T>(T[] a, T b) where T: class {
  75. if(null == a || a.Length == 0)
  76. return true;
  77. for(int i = 0; i < a.Length; i++)
  78. if(b != a[i])
  79. return false;
  80. return true;
  81. } // end of allEqual<T>()
  82. /// <summary>
  83. /// Gets whether all elements of the array are the same
  84. /// </summary>
  85. /// <typeparam name="T"> The array element type </typeparam>
  86. /// <param name="a"> The array </param>
  87. /// <returns> True if it is and false if not </returns>
  88. public static bool allSame<T>(T[] a) {
  89. if(null == a || a.Length <= 1)
  90. return true;
  91. return allEqual<T>(a, a[0]);
  92. } // end of allSame<T>()
  93. /// <summary>
  94. /// Gets whether all array elemetns are the same references
  95. /// </summary>
  96. /// <typeparam name="T"> The array element type </typeparam>
  97. /// <param name="a"> The array to check </param>
  98. /// <returns> True if it is and false if not </returns>
  99. public static bool allSameRef<T>(T[] a) where T : class {
  100. if(null == a || a.Length <= 1)
  101. return true;
  102. return allEqualRef<T>(a, a[0]);
  103. } // end of allSameRef<T>()
  104. /// <summary>
  105. /// Creates an alternative iterator of two arrays of the same length.
  106. /// If n is the length of both arrays, returns an iterator over a
  107. /// sequence of 2^n values.
  108. /// </summary>
  109. /// <typeparam name="T"> The element type of the array </typeparam>
  110. /// <param name="a"> The first array </param>
  111. /// <param name="b"> The second array </param>
  112. /// <returns> The resulting iterator </returns>
  113. /// <remarks> The resulting arrays should not be modified </remarks>
  114. public static IEnumerable<T[]> alterIter<T>(T[] a, T[] b) {
  115. if(null == a || null == b)
  116. throw new ArgumentNullException();
  117. if(a.Length != b.Length)
  118. throw new ArgumentException();
  119. int n = a.Length;
  120. T[] res = new T[n];
  121. int[] iis = idarr<int>(-1, n); // -1 - no value, 0 - first array,
  122. // 1 - second array
  123. int i = 0;
  124. while(i > -1) {
  125. if(i < n) {
  126. switch(iis[i]) {
  127. case -1: iis[i]++; res[i] = a[i]; i++; break;
  128. case 0: iis[i]++; res[i] = b[i]; i++; break;
  129. case 1: iis[i] = -1; i--; break;
  130. } // end of switch()
  131. } else {
  132. i--;
  133. yield return res;
  134. } // end of while()
  135. } // end of while()
  136. } // end of alterIter<T>()
  137. /// <summary>
  138. /// Gets the product of all array values and 1 if the array is empty
  139. /// </summary>
  140. /// <param name="arr"> The array </param>
  141. /// <returns> The resulting product </returns>
  142. public static int prod(params int[] arr) {
  143. int p = 1;
  144. foreach(int i in arr)
  145. p *= i;
  146. return p;
  147. } // end of prod()
  148. /// <summary>
  149. /// Negates the array component-wise
  150. /// </summary>
  151. /// <param name="arr"> The array to negate </param>
  152. /// <returns> The negated array </returns>
  153. public static int[] neg(params int[] arr) {
  154. int n = arr.Length;
  155. int[] r = new int[n];
  156. for(int i = 0; i < n; i++)
  157. r[i] = -arr[i];
  158. return r;
  159. } // end of neg()
  160. /// <summary>
  161. /// Transforms an array into a 2D array of the specified size,
  162. /// </summary>
  163. /// <typeparam name="T"> The type of the array to transform </typeparam>
  164. /// <param name="arr"> The source array </param>
  165. /// <param name="s"> The size of the resulting 2D array </param>
  166. /// <returns> The resulting array </returns>
  167. public static T[,] to2DArray<T>(Array arr, int s) {
  168. T[,] arr2 = new T[s, s];
  169. // copy array values
  170. int i = 0, j = 0;
  171. foreach(T v in arr) {
  172. arr2[i, j++] = v;
  173. if(j == s) {
  174. i++;
  175. j = 0;
  176. } // end of if()
  177. } // end of foreach()
  178. return arr2;
  179. } // end of to2DArray()
  180. /// <summary>
  181. /// Reads the data from a 2D array into the specified array
  182. /// </summary>
  183. /// <typeparam name="T"> The array element type </typeparam>
  184. /// <param name="arr"> The source 2D array </param>
  185. /// <param name="s"> The size of the 2D square array </param>
  186. /// <param name="sizes"> The size of the resulting array </param>
  187. /// <returns> The resulting array </returns>
  188. public static Array from2DArray<T>(T[,] arr, int s, int[] sizes) {
  189. switch(sizes.Length) {
  190. case 1:
  191. return from2DArrayTo1D<T>(arr, s, sizes);
  192. case 2:
  193. return arr;
  194. case 3:
  195. return from2DArrayTo3D<T>(arr, s, sizes);
  196. case 4:
  197. return from2DArrayTo4D<T>(arr, s, sizes);
  198. default:
  199. return from2DArrayToND<T>(arr, s, sizes);
  200. } // end of switch()
  201. } // end of from2DArray<T>()
  202. /// <summary>
  203. /// Reads the data from the 2D array into a 1D array
  204. /// </summary>
  205. /// <typeparam name="T"> The element type </typeparam>
  206. /// <param name="arr"> The 2D array </param>
  207. /// <param name="s"> The size of the 2D array </param>
  208. /// <param name="sizes"> The sizes of the 1D array </param>
  209. /// <returns> The resulting 1D array </returns>
  210. public static T[] from2DArrayTo1D<T>(T[,] arr, int s, int[] sizes) {
  211. int n = sizes[0];
  212. T[] arr2 = new T[n];
  213. int i = 0, j = 0;
  214. for(int p = 0; p < n; p++) {
  215. arr2[p] = arr[i, j++];
  216. if(j == s) {
  217. i++;
  218. j = 0;
  219. } // end of if()
  220. } // end of for()
  221. return arr2;
  222. } // end of from2DArrayTo1D()
  223. /// <summary>
  224. /// Converts a 2D array representation into a 3D array
  225. /// </summary>
  226. /// <typeparam name="T"> The array type </typeparam>
  227. /// <param name="arr"> The array to convert </param>
  228. /// <param name="s"> The size of the 2D array along one
  229. /// of the dimensions </param>
  230. /// <param name="sizes"> The sizes of the 3D array </param>
  231. /// <returns> The 3D array created </returns>
  232. public static T[, ,] from2DArrayTo3D<T>(T[,] arr, int s, int[] sizes) {
  233. int n0 = sizes[0], n1 = sizes[1], n2 = sizes[2];
  234. T[,,] arr2 = new T[n0, n1, n2];
  235. int i = 0, j = 0;
  236. for(int p0 = 0; p0 < n0; p0++)
  237. for(int p1 = 0; p1 < n1; p1++)
  238. for(int p2 = 0; p2 < n2; p2++) {
  239. arr2[p0, p1, p2] = arr[i, j++];
  240. if(j == s) {
  241. i++;
  242. j = 0;
  243. } // end of if()
  244. } // end of for()
  245. return arr2;
  246. } // end of from2DArrayTo3D<T>()
  247. /// <summary>
  248. /// Converts a 2D array representation into a 4D array
  249. /// </summary>
  250. /// <typeparam name="T"> The array type </typeparam>
  251. /// <param name="arr"> The array to convert </param>
  252. /// <param name="s"> The size of the 2D array along one
  253. /// of the dimensions </param>
  254. /// <param name="sizes"> The sizes of the 4D array </param>
  255. /// <returns> The 4D array created </returns>
  256. public static T[,, ,] from2DArrayTo4D<T>(T[,] arr, int s, int[] sizes) {
  257. int n0 = sizes[0], n1 = sizes[1], n2 = sizes[2], n3 = sizes[3];
  258. T[, , ,] arr2 = new T[n0, n1, n2, n3];
  259. int i = 0, j = 0;
  260. for(int p0 = 0; p0 < n0; p0++)
  261. for(int p1 = 0; p1 < n1; p1++)
  262. for(int p2 = 0; p2 < n2; p2++)
  263. for(int p3 = 0; p3 < n3; p3++) {
  264. arr2[p0, p1, p2, p3] = arr[i, j++];
  265. if(j == s) {
  266. i++;
  267. j = 0;
  268. } // end of if()
  269. } // end of for()
  270. return arr2;
  271. } // end of from2DArrayTo4D<T>()
  272. /// <summary>
  273. /// Reads the data from the 2D array into an ND array
  274. /// </summary>
  275. /// <typeparam name="T"> The element type </typeparam>
  276. /// <param name="arr"> The 2D array </param>
  277. /// <param name="s"> The size of the 2D array </param>
  278. /// <param name="sizes"> The sizes of the ND array </param>
  279. /// <returns> The resulting ND array </returns>
  280. public static Array from2DArrayToND<T>(T[,] arr, int s, int[] sizes) {
  281. int n = sizes[0];
  282. Array arr2 = Array.CreateInstance(typeof(T), sizes);
  283. int i = 0, j = 0;
  284. foreach(int[] p in pointIter(sizes)) {
  285. arr2.SetValue(arr[i, j++], p);
  286. if(j == s) {
  287. i++;
  288. j = 0;
  289. } // end of if()
  290. } // end of for()
  291. return arr2;
  292. } // end of from2DArrayToND()
  293. /// <summary>
  294. /// Checks whether the arrays have equal length and whether the predicate
  295. /// is valid for both of them
  296. /// </summary>
  297. /// <typeparam name="T1"> The type of the first array </typeparam>
  298. /// <typeparam name="T2"> The type of the second array </typeparam>
  299. /// <param name="arr1"> The first array </param>
  300. /// <param name="arr2"> The second array </param>
  301. /// <param name="prd"> The predicate to check </param>
  302. /// <returns> True iff either both <paramref name="arr1"/>
  303. /// and <paramref name="arr2"/> are null or both of them have equal length
  304. /// and for each pair of their respective elements the predicate
  305. /// <paramref name="prd"/> holds, i.e., returns true </returns>
  306. public static bool allTrue<T1, T2>(T1[] arr1, T2[] arr2, DoublePred<T1, T2> prd) {
  307. // check for null
  308. if(arr1 == null || arr2 == null) {
  309. return arr1 == null && arr2 == null;
  310. }
  311. if(prd == null)
  312. throw new ArgumentNullException();
  313. if(arr1.Length != arr2.Length)
  314. return false;
  315. int n = arr1.Length;
  316. for(int i = 0; i < n; i++)
  317. if(!prd(arr1[i], arr2[i]))
  318. return false;
  319. return true;
  320. }
  321. /// <summary>
  322. /// Concatenates the first array with the second array
  323. /// </summary>
  324. /// <typeparam name="T"> The type of the arrays being concatenated </typeparam>
  325. /// <param name="arr1"> The first array to be concatenated </param>
  326. /// <param name="arr2"> The second array to be concatenated </param>
  327. /// <returns> The result of concatenation </returns>
  328. public static T[] con<T>(T[] arr1, T[] arr2) {
  329. if(arr1 == null)
  330. return arr2;
  331. if(arr2 == null)
  332. return arr1;
  333. int l1 = arr1.Length, l2 = arr2.Length;
  334. int l = l1 + l2;
  335. T[] res = new T[l];
  336. int i = 0;
  337. for(; i < l1; i++)
  338. res[i] = arr1[i];
  339. for(; i < l; i++)
  340. res[i] = arr2[i - l1];
  341. return res;
  342. }
  343. /// <summary>
  344. /// Concatenates any number of arrays of the same type specified
  345. /// </summary>
  346. /// <typeparam name="T"> The element type of the arrays to concatenate </typeparam>
  347. /// <param name="arrs"> The arrays to concatenate </param>
  348. /// <returns> The result of concatenation </returns>
  349. public static T[] con<T>(params T[][] arrs) {
  350. if(arrs == null)
  351. return null;
  352. if(arrs.Length == 0)
  353. return new T[] { };
  354. //if(Array.TrueForAll<T[]>(arrs, delegate(T[] a) { return a == null; }))
  355. // return null;
  356. if(null == arrs[0] && allEqualRef<T[]>(arrs, null))
  357. return null;
  358. int n = 0;
  359. for(int i = 0; i < arrs.Length; i++)
  360. n += arrs[i].Length;
  361. T[] res = new T[n];
  362. int k = 0;
  363. for(int i = 0; i < arrs.Length; i++)
  364. for(int j = 0; j < arrs[i].Length; j++)
  365. res[k++] = arrs[i][j];
  366. return res;
  367. } // end of con<T>()
  368. /// <summary>
  369. /// Adds an element to the end of the array
  370. /// </summary>
  371. /// <typeparam name="T"> The type of the array element </typeparam>
  372. /// <param name="arr"> The array to concatenate </param>
  373. /// <param name="el"> The element to concatenate </param>
  374. /// <returns> The resulting array </returns>
  375. public static T[] con<T>(T[] arr, T el) {
  376. return con<T>(arr, new T[] { el });
  377. } // end of con<T>
  378. /// <summary>
  379. /// Adds an element to the beginning of the array
  380. /// </summary>
  381. /// <typeparam name="T"> The type of the array element </typeparam>
  382. /// <param name="el"> The element to concatenate </param>
  383. /// <param name="arr"> The array to concatenate </param>
  384. /// <returns> The resulting array </returns>
  385. public static T[] con<T>(T el, T[] arr) {
  386. return con<T>(new T[] { el }, arr);
  387. } // end of con<T>
  388. /// <summary>
  389. /// Indexes the array with an array of indices and returns the result of the
  390. /// indexing
  391. /// </summary>
  392. /// <typeparam name="T"> The type of the array to index </typeparam>
  393. /// <param name="arr"> The array to index </param>
  394. /// <param name="inds"> The indices of the elements to retrieve </param>
  395. /// <returns> The list of indices for indexing </returns>
  396. public static T[] index<T>(T[] arr, params int[] inds) {
  397. List<T> l = new List<T>();
  398. if(inds == null)
  399. return l.ToArray();
  400. if(arr == null) {
  401. if(inds == null || inds.Length == 0)
  402. return l.ToArray();
  403. throw new ArgumentNullException();
  404. }
  405. foreach(int i in inds)
  406. l.Add(arr[i]);
  407. return l.ToArray();
  408. } // end of index()
  409. /// <summary>
  410. /// Creates a new array which contains original values except
  411. /// those specified in <paramref name="inds"/>; they are removed
  412. /// </summary>
  413. /// <typeparam name="T"> The type of the array element </typeparam>
  414. /// <param name="arr"> The source array </param>
  415. /// <param name="inds"> The indices to be except </param>
  416. /// <returns> The resulting array </returns>
  417. public static T[] indexExcept<T>(T[] arr, params int[] inds) {
  418. int rn = arr.Length - inds.Length;
  419. T[] ra = new T[rn];
  420. // current index to inds array
  421. int k = 0;
  422. // current index to resulting array
  423. int j = 0;
  424. for(int i = 0; i < arr.Length; i++) {
  425. if(k >= inds.Length || inds[k] != i)
  426. ra[j++] = arr[i];
  427. else
  428. k++;
  429. } // end of for()
  430. return ra;
  431. } // end of indexExcept<T>()
  432. /// <summary>
  433. /// Gets the indices of the array given the single cumulative index.
  434. /// </summary>
  435. /// <param name="index"> The cumulative index of the array </param>
  436. /// <param name="cumSizes"> The cumulative sizes of the array. The
  437. /// last of it equals to 1, the next-to-last to cumSizes[cumSizes.Length - 1] *
  438. /// sizes[cumSizes.length - 1], etc. </param>
  439. /// <returns> The resulting set of indices </returns>
  440. public static int[] indices(int index, int[] cumSizes) {
  441. int n = cumSizes.Length;
  442. int[] inds = new int[n];
  443. int j = index;
  444. for(int i = 0; i < n; i++) {
  445. inds[i] = j / cumSizes[i];
  446. j %= cumSizes[i];
  447. }
  448. return inds;
  449. } // end of indices()
  450. /// <summary>
  451. /// Creates the array of cumulative sizes from the array of sizes
  452. /// </summary>
  453. /// <param name="sizes"> The array of sizes </param>
  454. /// <returns> The array of cumulative sizes </returns>
  455. /// <remarks> When it is created, it is assumed that the first index in
  456. /// the array changes the slowest </remarks>
  457. public static int[] cumSizes(int[] sizes) {
  458. int n = sizes.Length;
  459. int[] cs = new int[n];
  460. cs[n - 1] = 1;
  461. for(int i = n - 2; i >= 0; i--)
  462. cs[i] = cs[i + 1] * sizes[i + 1];
  463. return cs;
  464. }
  465. /// <summary>
  466. /// Creates a tail from an array starting from the specified element
  467. /// </summary>
  468. /// <typeparam name="T"> The type of the array element </typeparam>
  469. /// <param name="arr"> The array from which to create a tail </param>
  470. /// <param name="start"> The start element of the tail </param>
  471. /// <returns> The tail created </returns>
  472. public static T[] tail<T>(T[] arr, int start) {
  473. if(start <= 0)
  474. return arr;
  475. if(start >= arr.Length)
  476. throw new IndexOutOfRangeException();
  477. int nl = arr.Length - start;
  478. T[] res = new T[nl];
  479. for(int i = 0; i < nl; i++)
  480. res[i] = arr[start + i];
  481. return res;
  482. }
  483. /// <summary>
  484. /// Gets the array of sizes of the array.
  485. /// </summary>
  486. /// <param name="arr"> The array for which to get the sizes. </param>
  487. /// <returns> The array of sizes of the array, staring from the one
  488. /// along which changes the slowest (i.e., the first). Returns null for
  489. /// null arrays. </returns>
  490. public static int[] sizes(Array arr) {
  491. if(null == arr)
  492. return null;
  493. int n = arr.Rank;
  494. int[] sz = new int[n];
  495. for(int i = 0; i < n; i++)
  496. sz[i] = arr.GetLength(i);
  497. return sz;
  498. }
  499. /// <summary>
  500. /// Creates a 1D array of the specified type and of specified size with all
  501. /// elements equal to a specified value
  502. /// </summary>
  503. /// <typeparam name="T"> The type of the array to create </typeparam>
  504. /// <param name="val"> The value of the array element </param>
  505. /// <param name="size"> The length of the array to create </param>
  506. /// <returns> The array created </returns>
  507. public static T[] idarr<T>(T val, int size) {
  508. if(size < 0)
  509. throw new ArgumentOutOfRangeException();
  510. T[] arr = new T[size];
  511. for(int i = 0; i < arr.Length; i++)
  512. arr[i] = val;
  513. return arr;
  514. }
  515. /// <summary>
  516. /// Transforms two arrays of values into a single array of values
  517. /// </summary>
  518. /// <typeparam name="T1"> The type of the first array of values </typeparam>
  519. /// <typeparam name="T2"> The type of the second array of values </typeparam>
  520. /// <typeparam name="T3"> The type of the resulting array of values </typeparam>
  521. /// <param name="arr1"> The first array of values </param>
  522. /// <param name="arr2"> The second array of values </param>
  523. /// <param name="trs"> The transform to apply </param>
  524. /// <returns> The resulting array of values </returns>
  525. public static T3[] map2<T1, T2, T3>(T1[] arr1, T2[] arr2, Transform<T1, T2, T3>
  526. trs) {
  527. // check for nulls
  528. if(arr1 == null || arr2 == null) {
  529. if(arr1 == null && arr2 == null)
  530. return null;
  531. else
  532. throw new ArgumentNullException();
  533. }
  534. if(trs == null)
  535. throw new ArgumentNullException();
  536. if(arr1.Length != arr2.Length)
  537. throw new ArgumentException();
  538. int n = arr1.Length;
  539. T3[] res = new T3[n];
  540. for(int i = 0; i < n; i++)
  541. res[i] = trs(arr1[i], arr2[i]);
  542. return res;
  543. }
  544. /// <summary>
  545. /// Performs the reduction of the specified array by the specified function
  546. /// </summary>
  547. /// <typeparam name="T"> The type of the array to reduce </typeparam>
  548. /// <param name="arr"> The array being reduced </param>
  549. /// <param name="red"> The reducing function </param>
  550. /// <returns> The result of the reduciton </returns>
  551. public static T reduce<T>(T[] arr, Transform<T, T, T> red) {
  552. if(null == arr || null == red)
  553. throw new ArgumentNullException();
  554. if(arr.Length == 0)
  555. return default(T);
  556. if(arr.Length == 1)
  557. return arr[0];
  558. T res = arr[0];
  559. for(int i = 1; i < arr.Length; i++)
  560. res = red(res, arr[i]);
  561. return res;
  562. }
  563. /// <summary>
  564. /// Gets the head of the specified array
  565. /// </summary>
  566. /// <param name="arr"> The array from which to get the head </param>
  567. /// <param name="end"> The index of the last element to be included in
  568. /// the head array </param>
  569. /// <returns> The head of the array </returns>
  570. public static T[] head<T>(T[] arr, int end) {
  571. if(null == arr)
  572. return null;
  573. if(end < 0)
  574. throw new IndexOutOfRangeException();
  575. if(end >= arr.Length)
  576. return arr;
  577. T[] res = new T[end + 1];
  578. for(int i = 0; i <= end; i++)
  579. res[i] = arr[i];
  580. return res;
  581. }
  582. /// <summary>
  583. /// Accepts the list of arrays and returns
  584. /// their union
  585. /// </summary>
  586. /// <typeparam name="T"> The type of the arrays to unite </typeparam>
  587. /// <param name="arr"> The arrays to unite </param>
  588. /// <returns> The union of the arrays </returns>
  589. /// <remarks> The result does not have any repeating elements; that is,
  590. /// even if a single array is passed, it has its repeating elements
  591. /// removed </remarks>
  592. public static T[] union<T>(params T[][] arr) {
  593. if(null == arr || arr.Length == 0)
  594. return new T[] { };
  595. //List<T> l = new List<T>();
  596. //Set<T> s = new Set<T>();
  597. //foreach(T[] a in arr) {
  598. // if(null == a)
  599. // continue;
  600. // foreach(T el in a)
  601. // if(!s.Contains(el)) {
  602. // s.Add(el);
  603. // l.Add(el);
  604. // }
  605. //}
  606. //return l.ToArray();
  607. List<T> l = new List<T>(arr.Length * arr[0].Length);
  608. for(int i = 0; i < arr[0].Length; i++)
  609. l.Add(arr[0][i]);
  610. for(int i = 1; i < arr.Length; i++)
  611. for(int j = 0; j < arr[i].Length; j++) {
  612. T v = arr[i][j];
  613. if(l.IndexOf(v) == -1)
  614. l.Add(v);
  615. } // end of for()
  616. return l.ToArray();
  617. } // end of union()
  618. /// <summary>
  619. /// Accepts two arrays and returns their difference
  620. /// </summary>
  621. /// <typeparam name="T"> The type of the array </typeparam>
  622. /// <param name="arr1"> The first array </param>
  623. /// <param name="arr2"> The second array </param>
  624. /// <returns> The difference of the first and second arrays </returns>
  625. public static T[] diff<T>(T[] arr1, T[] arr2) {
  626. //if(null == arr1 || null == arr2)
  627. // throw new ArgumentNullException();
  628. //List<T> l = new List<T>();
  629. //Set<T> s = new Set<T>(arr1).Difference(new Set<T>(arr2));
  630. //Set<T> s1 = new Set<T>(); // for there be no identical elements
  631. //foreach(T el in arr1)
  632. // if(s.Contains(el) && !s1.Contains(el)) {
  633. // s1.Add(el);
  634. // l.Add(el);
  635. // }
  636. //return l.ToArray();
  637. int n = arr1.Length;
  638. List<T> l = new List<T>(n);
  639. for(int i = 0; i < arr1.Length; i++) {
  640. T val = arr1[i];
  641. if(Array.IndexOf<T>(arr2, val) == -1)
  642. l.Add(val);
  643. } // end of for()
  644. return l.ToArray();
  645. } // end of diff();
  646. /// <summary>
  647. /// Gets the array containing integer span of data between a and b
  648. /// </summary>
  649. /// <param name="a"> The start of the span </param>
  650. /// <param name="b"> The end of the span </param>
  651. /// <returns> The span created or null if none </returns>
  652. public static int[] span(int a, int b) {
  653. if(b < a) return null;
  654. int n = b - a + 1;
  655. int[] arr = new int[n];
  656. for(int i = a; i <= b; i++) arr[i - a] = i;
  657. return arr;
  658. } // end of span()
  659. /// <summary>
  660. /// Iterates over a rectangular set of integer points, starting from
  661. /// (0, ..., 0) and ending with (sizes[0]-1, ..., sizes[n-1]-1), with
  662. /// first index chaning the slowest. In case null or zero-length array
  663. /// is passed, returns a single zero-length array
  664. /// </summary>
  665. /// <param name="sizes"> The limits of the domain over which to
  666. /// iterate </param>
  667. /// <returns> The iterator over the point domain </returns>
  668. public static IEnumerable<int[]> pointIter(int[] sizes) {
  669. if(null == sizes || sizes.Length == 0) {
  670. yield return new int[0];
  671. yield break;
  672. } else {
  673. int n = sizes.Length;
  674. int[] vals = idarr<int>(-1, n);
  675. int ptr = 0;
  676. while(ptr != -1) {
  677. if(ptr == n) {
  678. yield return (int[])vals.Clone();
  679. ptr--;
  680. } else {
  681. vals[ptr]++;
  682. if(vals[ptr] == sizes[ptr]) {
  683. vals[ptr] = -1;
  684. ptr--;
  685. } else {
  686. ptr++;
  687. } // end of if()-else
  688. } // end of if()-else
  689. } // end of while()
  690. } // end of if()-else
  691. } // end of pointIter()
  692. /// <summary>
  693. /// Creates an array of <paramref name="size"/> elements, all of
  694. /// which are equal to <paramref name="val"/>, except for element
  695. /// with index <paramref name="pos"/>, which is equal to
  696. /// <paramref name="diffVal"/>
  697. /// </summary>
  698. /// <typeparam name="T"> The type of the element & array </typeparam>
  699. /// <param name="size"> The size of the resulting array </param>
  700. /// <param name="pos"> The position in the array which shall differ </param>
  701. /// <param name="val"> The value of the array element </param>
  702. /// <param name="diffVal"> The different value of the single element </param>
  703. /// <returns> The array created </returns>
  704. public static T[] singleDiff<T>(int size, int pos, T val, T diffVal) {
  705. T[] a = idarr<T>(val, size);
  706. a[pos] = diffVal;
  707. return a;
  708. } // end of singleDiff<T>()
  709. /// <summary>
  710. /// Evaluates the dot product of two integer arrays
  711. /// </summary>
  712. /// <param name="a1"> The first array </param>
  713. /// <param name="a2"> The second array </param>
  714. /// <returns> The dot product of two arrays </returns>
  715. public static int dot(int[] a1, int[] a2) {
  716. int n = a1.Length;
  717. if(a2.Length != n)
  718. throw new ArgumentException();
  719. int r = 0;
  720. for(int i = 0; i < n; i++)
  721. r += a1[i] * a2[i];
  722. return r;
  723. } // end of dot()
  724. /// <summary>
  725. /// Assigns values of <paramref name="src"/> to <paramref name="tgt"/>,
  726. /// so that each element of <paramref name="src"/> is assigned to the
  727. /// <paramref name="inds"/> position with respective index of
  728. /// <paramref name="tgt"/>. If there are several candidates to the
  729. /// same position, any of them can be assigned.
  730. /// </summary>
  731. /// <typeparam name="T"> The type of the array </typeparam>
  732. /// <param name="tgt"> The target array </param>
  733. /// <param name="src"> The source array </param>
  734. /// <param name="inds"> The indices at which to assign </param>
  735. public static void arrass<T>(T[] tgt, T[] src, int[] inds) {
  736. int n = src.Length;
  737. if(inds.Length != n)
  738. throw new ArgumentException("Source and indices lengths do not match");
  739. for(int i = 0; i < n; i++) tgt[inds[i]] = src[i];
  740. } // end of arrass<T>
  741. /// <summary>
  742. /// Removes duplicates in the array
  743. /// </summary>
  744. /// <param name="arr"> The array from which to remove duplicates </param>
  745. /// <returns> The array with all duplicates removed </returns>
  746. public static T[] removeDups<T>(T[] arr) {
  747. List<T> l = new List<T>();
  748. Set<T> s = new Set<T>();
  749. foreach(T t in arr)
  750. if(!s.Contains(t)) {
  751. s.Add(t);
  752. l.Add(t);
  753. } // end of if()
  754. return l.ToArray();
  755. } // end of removeDups()
  756. /// <summary>
  757. /// Gets the indices of objects of <paramref name="arr2"/> with which
  758. /// they are present in <paramref name="arr1"/>
  759. /// </summary>
  760. /// <typeparam name="T"> The array type </typeparam>
  761. /// <param name="arr1"> The first array </param>
  762. /// <param name="arr2"> The second array </param>
  763. /// <returns> The array of indices </returns>
  764. public static int[] indicesOf<T>(T[] arr1, T[] arr2) {
  765. int n = arr2.Length;
  766. int[] inds = new int[n];
  767. for(int i = 0; i < n; i++)
  768. inds[i] = Array.IndexOf<T>(arr1, arr2[i]);
  769. return inds;
  770. } // end of indicesOf<T>
  771. /// <summary>
  772. /// Reverses the given array
  773. /// </summary>
  774. /// <typeparam name="T"> The type of the array to reverse </typeparam>
  775. /// <param name="arr"> The array to reverse </param>
  776. /// <returns> The reversed array </returns>
  777. /// <remarks> Reversing a null array returns null. </remarks>
  778. public static T[] reverse<T>(T[] arr) {
  779. if(null == arr)
  780. return null;
  781. int n = arr.Length;
  782. T[] arr2 = new T[n];
  783. for(int i = 0; i < n; i++)
  784. arr2[i] = arr[n - i - 1];
  785. return arr2;
  786. } // end of reverse<T>()
  787. } // end of class ArrOps
  788. }