PageRenderTime 47ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

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

#
C# | 1382 lines | 710 code | 73 blank | 599 comment | 276 complexity | 038b134747acd51fdab07e68a898f6d0 MD5 | raw file
Possible License(s): AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Wintellect.PowerCollections;
  5. using System.Diagnostics;
  6. namespace CBucks.Common {
  7. public delegate bool DoublePred<T1, T2>(T1 a, T2 b);
  8. public delegate T3 Transform<T1, T2, T3>(T1 a, T2 b);
  9. /// <summary>
  10. /// Contains common array operations
  11. /// </summary>
  12. public static class ArrOps {
  13. /// <summary>
  14. /// Gets whether any element of the array is equal to the
  15. /// specified value
  16. /// </summary>
  17. /// <typeparam name="T"> The value of the element </typeparam>
  18. /// <param name="a"> The array to check </param>
  19. /// <param name="val"> The value to compare with </param>
  20. /// <returns> True if it contains the value and false if not </returns>
  21. public static bool contains<T>(T[] a, T val) {
  22. if(null == a)
  23. return false;
  24. for(int i = 0; i < a.Length; i++) {
  25. if(object.Equals(a[i], val))
  26. return true;
  27. } // end of for()
  28. return false;
  29. } // end of contains<T>()
  30. /// <summary>
  31. /// Gets the last element of the array.
  32. /// </summary>
  33. /// <typeparam name="T"> The type of the array element </typeparam>
  34. /// <param name="a"> The array from which to get the last element </param>
  35. /// <returns> The last element of the array </returns>
  36. /// <exception cref="System.IndexOutOfRangeException"> The array length
  37. /// is zero </exception>
  38. /// <exception cref="System.NullReferenceException"> The <paramref name="a"/>
  39. /// is null </exception>
  40. public static T last<T>(T[] a) {
  41. return a[a.Length - 1];
  42. } // end of last()
  43. /// <summary>
  44. /// Removes all null entries from the array.
  45. /// </summary>
  46. /// <typeparam name="T"> The array type. </typeparam>
  47. /// <param name="a"> The array to remove nulls from. </param>
  48. /// <returns> The resulting array. </returns>
  49. public static T[] removeNulls<T>(T[] a) where T : class {
  50. List<T> l = new List<T>();
  51. for(int i = 0; i < a.Length; i++)
  52. if(null != a[i])
  53. l.Add(a[i]);
  54. return l.ToArray();
  55. } // end of removeNulls<T>()
  56. /// <summary>
  57. /// Performs a stable in-place sort of the specified array using one of
  58. /// stable sort algorithms
  59. /// </summary>
  60. /// <typeparam name="T"> The type of the array element </typeparam>
  61. /// <param name="a"> The array to be sorted in-place </param>
  62. /// <param name="c"> The comparison delegate </param>
  63. public static void stableSort<T>(T[] a, Comparison<T> c) {
  64. bubbleSort(a, c);
  65. } // end of stableSort()
  66. /// <summary>
  67. /// Performs in-place bubble sort of the specified array
  68. /// </summary>
  69. /// <typeparam name="T"> The type of the array element </typeparam>
  70. /// <param name="a"> The array to sort </param>
  71. /// <param name="c"> The comparison delegate </param>
  72. public static void bubbleSort<T>(T[] a, Comparison<T> c) {
  73. int n = a.Length;
  74. for(int i = 0; i < n; i++) {
  75. for(int j = i - 1; j > -1; j--)
  76. if(c(a[j], a[j + 1]) > 0) {
  77. T t = a[j];
  78. a[j] = a[j + 1];
  79. a[j + 1] = t;
  80. } // end of if()
  81. } // end of for()
  82. } // end of bubbleSort()
  83. /// <summary>
  84. /// Checks whether the <paramref name="a"/> ordered array includes
  85. /// the <paramref name="b"/> ordered array, i.e., contains at least
  86. /// all elements contained in <paramref name="b"/>
  87. /// </summary>
  88. /// <typeparam name="T"> The type of the array to check for
  89. /// inclusion </typeparam>
  90. /// <param name="a"> The first array </param>
  91. /// <param name="b"> The second array </param>
  92. /// <returns> True if the first array fully includes the second and
  93. /// false otherwise </returns>
  94. public static bool ordIncludes<T>(T[] a, T[] b) where T
  95. : IComparable<T> {
  96. if(null == b || b.Length == 0)
  97. return true;
  98. if(null == a || a.Length == 0)
  99. return false;
  100. if(a.Length < b.Length)
  101. return false;
  102. int ia = 0, ib = 0;
  103. while(true) {
  104. if(ib == b.Length)
  105. return true;
  106. if(ia == a.Length)
  107. return false;
  108. T aa = a[ia], bb = b[ib];
  109. int r = aa.CompareTo(bb);
  110. if(r < 0)
  111. ia++;
  112. else if(r == 0) {
  113. ia++; ib++;
  114. } else
  115. return false;
  116. } // end of while()
  117. } // end of ordIncludes<T>()
  118. /// <summary>
  119. /// Checks whether the array contains a null value
  120. /// </summary>
  121. /// <typeparam name="T"> The type of the array </typeparam>
  122. /// <param name="a"> The array to check </param>
  123. /// <returns> True if the array contains a null value and
  124. /// false if not </returns>
  125. public static bool hasNull<T>(T[] a) where T : class {
  126. if(null == a)
  127. return false;
  128. return contains<T>(a, null);
  129. } // end of hasNull<T>()
  130. /// <summary>
  131. /// Gets the sum of the elements of the array
  132. /// </summary>
  133. /// <param name="a"> The array whose elements to sum </param>
  134. /// <returns> The sum of the array elements </returns>
  135. public static double sum(double[] a) {
  136. double r = 0;
  137. for(int i = 0; i < a.Length; i++)
  138. r += a[i];
  139. return r;
  140. } // end of sum()
  141. /// <summary>
  142. /// Creates a value mask for the array
  143. /// </summary>
  144. /// <typeparam name="T"> The type of the array </typeparam>
  145. /// <param name="a"> The array for which to create a value
  146. /// mask </param>
  147. /// <param name="val"> The value </param>
  148. /// <returns> The mask which contains 0's in the position
  149. /// where the element of <paramref name="a"/> equals to the
  150. /// <paramref name="val"/> and 1's in all other positions.
  151. /// If the length of the array is less than sizeof(int) * 8, then
  152. /// remaining positions are set to 0 </returns>
  153. public static int valueMask<T>(T[] a, T val) {
  154. int i = 0;
  155. int n = Math.Min(32, a.Length);
  156. for(int j = 0; j < n; j++)
  157. if(!object.Equals(a[j], val))
  158. i |= 1 << j;
  159. return i;
  160. } // end of valueMask<T>()
  161. /// <summary>
  162. /// Checks whether the specified arrays are equal, i.e., contain equal
  163. /// components and are of same length.
  164. /// </summary>
  165. /// <typeparam name="T"> The first array </typeparam>
  166. /// <param name="a"> The first array </param>
  167. /// <param name="b"> The second array </param>
  168. /// <returns> True if they are equal and false if not </returns>
  169. public static bool equal<T>(T[] a, T[] b) {
  170. if(null == a || null == b)
  171. return null == a && null == b;
  172. if(a.Length != b.Length)
  173. return false;
  174. int n = a.Length;
  175. for(int i = 0; i < n; i++)
  176. if(!object.Equals(a[i], b[i]))
  177. return false;
  178. return true;
  179. } // end of equal<T>
  180. /// <summary>
  181. /// Checks whether specified arrays are component-wise equal.
  182. /// </summary>
  183. /// <param name="a"> The first array. </param>
  184. /// <param name="b"> The second array. </param>
  185. /// <returns> True if they are equal and false if not. </returns>
  186. /// <remarks> Arrays are equal if either both are null, or both
  187. /// are non-null, have same rank and sizes, and for all valid indices
  188. /// elements with the same indices are equal. </remarks>
  189. public static bool equal(Array a, Array b) {
  190. if(null == a || null == b)
  191. return null == a && null == b;
  192. int[] sza = sizes(a), szb = sizes(b);
  193. if(!equal(sza, szb))
  194. return false;
  195. foreach(int[] p in pointIter(sza)) {
  196. if(!object.Equals(a.GetValue(p), b.GetValue(p)))
  197. return false;
  198. } // end of foreach()
  199. return true;
  200. } // end of equal()
  201. /// <summary>
  202. /// Checks whether the specified arrays contain all their references
  203. /// equal
  204. /// </summary>
  205. /// <typeparam name="T"> The array type </typeparam>
  206. /// <param name="a"> The first array </param>
  207. /// <param name="b"> The second array </param>
  208. /// <returns> True if they do and false if not </returns>
  209. public static bool equalRef<T>(T[] a, T[] b) where T : class {
  210. if(null == a || null == b)
  211. return null == a && null == b;
  212. if(a.Length != b.Length)
  213. return false;
  214. int n = a.Length;
  215. for(int i = 0; i < n; i++)
  216. if(a[i] != b[i])
  217. return false;
  218. return true;
  219. } // end of equalRef<T>
  220. /// <summary>
  221. /// Gets whether all elements of the specified array are equal to
  222. /// the specified value
  223. /// </summary>
  224. /// <typeparam name="T"> The element type </typeparam>
  225. /// <param name="a"> The array </param>
  226. /// <param name="b"> The value </param>
  227. /// <returns> True if it is and false if not </returns>
  228. public static bool allEqual<T>(T[] a, T b) {
  229. if(null == a || a.Length == 0)
  230. return true;
  231. for(int i = 0; i < a.Length; i++)
  232. if(!object.Equals(a[i], b))
  233. return false;
  234. return true;
  235. } // end of allEqual<T>()
  236. /// <summary>
  237. /// Gets whether all elements of the specified array are reference equal to
  238. /// the specified value
  239. /// </summary>
  240. /// <typeparam name="T"> The element type </typeparam>
  241. /// <param name="a"> The array </param>
  242. /// <param name="b"> The value </param>
  243. /// <returns> True if it is and false if not </returns>
  244. public static bool allEqualRef<T>(T[] a, T b) where T: class {
  245. if(null == a || a.Length == 0)
  246. return true;
  247. for(int i = 0; i < a.Length; i++)
  248. if(b != a[i])
  249. return false;
  250. return true;
  251. } // end of allEqual<T>()
  252. /// <summary>
  253. /// Checks whether any of the two elements of the array are the same.
  254. /// </summary>
  255. /// <typeparam name="T"> The array type. </typeparam>
  256. /// <param name="a"> The array. </param>
  257. /// <returns> True if any two elements of the array are same and
  258. /// false if not. False is also returned for null and empty arrays as
  259. /// well as for arrays of one element. Null elements are considered
  260. /// the same. The equality procedure is considered to be symmetric,
  261. /// i.e. it is assumed that a[i] equals a[j] iff a[j] equals a[i],
  262. /// so only one of the checks is performed. </returns>
  263. public static bool anySame<T>(T[] a) {
  264. if(null == a || a.Length < 2)
  265. return false;
  266. int n = a.Length;
  267. for(int i = 0; i < n; i++)
  268. for(int j = i + 1; j < n; j++)
  269. if(object.Equals(a[i], a[j]))
  270. return true;
  271. return false;
  272. } // end of anySame<T>()
  273. /// <summary>
  274. /// Gets whether all elements of the array are the same
  275. /// </summary>
  276. /// <typeparam name="T"> The array element type </typeparam>
  277. /// <param name="a"> The array </param>
  278. /// <returns> True if it is and false if not </returns>
  279. public static bool allSame<T>(T[] a) {
  280. if(null == a || a.Length <= 1)
  281. return true;
  282. return allEqual<T>(a, a[0]);
  283. } // end of allSame<T>()
  284. /// <summary>
  285. /// Gets whether all array elemetns are the same references
  286. /// </summary>
  287. /// <typeparam name="T"> The array element type </typeparam>
  288. /// <param name="a"> The array to check </param>
  289. /// <returns> True if it is and false if not </returns>
  290. public static bool allSameRef<T>(T[] a) where T : class {
  291. if(null == a || a.Length <= 1)
  292. return true;
  293. return allEqualRef<T>(a, a[0]);
  294. } // end of allSameRef<T>()
  295. /// <summary>
  296. /// Creates an alternative iterator of two arrays of the same length.
  297. /// If n is the length of both arrays, returns an iterator over a
  298. /// sequence of 2^n values.
  299. /// </summary>
  300. /// <typeparam name="T"> The element type of the array </typeparam>
  301. /// <param name="a"> The first array </param>
  302. /// <param name="b"> The second array </param>
  303. /// <returns> The resulting iterator </returns>
  304. /// <remarks> The resulting arrays should not be modified </remarks>
  305. public static IEnumerable<T[]> alterIter<T>(T[] a, T[] b) {
  306. if(null == a || null == b)
  307. throw new ArgumentNullException();
  308. if(a.Length != b.Length)
  309. throw new ArgumentException();
  310. int n = a.Length;
  311. T[] res = new T[n];
  312. int[] iis = idarr<int>(-1, n); // -1 - no value, 0 - first array,
  313. // 1 - second array
  314. int i = 0;
  315. while(i > -1) {
  316. if(i < n) {
  317. switch(iis[i]) {
  318. case -1: iis[i]++; res[i] = a[i]; i++; break;
  319. case 0: iis[i]++; res[i] = b[i]; i++; break;
  320. case 1: iis[i] = -1; i--; break;
  321. } // end of switch()
  322. } else {
  323. i--;
  324. yield return res;
  325. } // end of while()
  326. } // end of while()
  327. } // end of alterIter<T>()
  328. /// <summary>
  329. /// Gets the product of all array values and 1 if the array is empty
  330. /// </summary>
  331. /// <param name="arr"> The array </param>
  332. /// <returns> The resulting product </returns>
  333. public static int prod(params int[] arr) {
  334. int p = 1;
  335. foreach(int i in arr)
  336. p *= i;
  337. return p;
  338. } // end of prod()
  339. /// <summary>
  340. /// Gets the product of all array values and 1 if the array is empty
  341. /// </summary>
  342. /// <param name="arr"> The array </param>
  343. /// <returns> The resulting product </returns>
  344. public static long prod(params long[] arr) {
  345. long p = 1;
  346. foreach(long i in arr)
  347. p *= i;
  348. return p;
  349. } // end of prod()
  350. /// <summary>
  351. /// Generates a permutation of values which contains
  352. /// <paramref name="dims"/> dimensions in the beginning,
  353. /// if <paramref name="last"/> is false, or end, if
  354. /// <paramref name="last"/> is true, and all other dimensions in other
  355. /// places
  356. /// </summary>
  357. /// <param name="n"> The full rank </param>
  358. /// <param name="dims"> The numbers of dimensions in question,
  359. /// in ascending order </param>
  360. /// <param name="last"> Whether or not to place the dimensions in
  361. /// question to the end </param>
  362. /// <returns> The permutation created </returns>
  363. public static int[] genPermute(int n, int[] dims, bool last) {
  364. int[] prm = new int[n];
  365. if(last) {
  366. for(int i = n - dims.Length; i < n; i++)
  367. prm[i] = dims[i - n + dims.Length];
  368. } else {
  369. for(int i = 0; i < dims.Length; i++)
  370. prm[i] = dims[i];
  371. } // end of if()
  372. // non-dim dimensions
  373. int j1 = 0, j2 = last ? 0 : dims.Length;
  374. for(int i = 0; i < n; i++) {
  375. if(j1 < dims.Length) {
  376. if(i == dims[j1])
  377. j1++;
  378. else
  379. prm[j2++] = i;
  380. } else
  381. prm[j2++] = i;
  382. } // end of for()
  383. return prm;
  384. } // end of genPermute()
  385. /// <summary>
  386. /// Negates the array component-wise
  387. /// </summary>
  388. /// <param name="arr"> The array to negate </param>
  389. /// <returns> The negated array </returns>
  390. public static int[] neg(params int[] arr) {
  391. int n = arr.Length;
  392. int[] r = new int[n];
  393. for(int i = 0; i < n; i++)
  394. r[i] = -arr[i];
  395. return r;
  396. } // end of neg()
  397. /// <summary>
  398. /// Transforms an array into a 2D array of the specified size,
  399. /// </summary>
  400. /// <typeparam name="T"> The type of the array to transform </typeparam>
  401. /// <param name="arr"> The source array </param>
  402. /// <param name="s"> The size of the resulting 2D array </param>
  403. /// <returns> The resulting array </returns>
  404. public static T[,] to2DArray<T>(Array arr, int s) {
  405. T[,] arr2 = new T[s, s];
  406. if(arr.Rank == 2) {
  407. T[,] arr3 = (T[,])arr;
  408. for(int i0 = 0; i0 < arr.GetLength(0); i0++)
  409. for(int i1 = 0; i1 < arr.GetLength(1); i1++)
  410. arr2[i0, i1] = arr3[i0, i1];
  411. return arr2;
  412. } // end of if()
  413. // copy array values
  414. int i = 0, j = 0;
  415. foreach(T v in arr) {
  416. arr2[i, j++] = v;
  417. if(j == s) {
  418. i++;
  419. j = 0;
  420. } // end of if()
  421. } // end of foreach()
  422. return arr2;
  423. } // end of to2DArray()
  424. /// <summary>
  425. /// Transforms an array into an m-D array of the specified size
  426. /// </summary>
  427. /// <typeparam name="T"> The type of the array to transform </typeparam>
  428. /// <param name="arr"> The source array </param>
  429. /// <param name="s"> The sizes of the resulting m-D array </param>
  430. /// <returns> The resulting array </returns>
  431. /// <remarks> Only 1 and 2-rank resulting arrays supported.
  432. /// Also, only square 2d arrays are supported, with first
  433. /// element of <paramref name="s"/> specifying square dimension
  434. /// size </remarks>
  435. public static Array toMDArray<T>(Array arr, int[] s) {
  436. switch(s.Length) {
  437. case 1:
  438. return to1DArray<T>(arr, s[0]);
  439. case 2:
  440. return to2DArray<T>(arr, s[0]);
  441. default:
  442. throw new NotSupportedException("Only ranks 1 and 2 are supported");
  443. } // end of switch()
  444. } // end of toMDArray()
  445. /// <summary>
  446. /// Linearizes the 2d array and returns it as a linearized 1d array.
  447. /// All 1d arrays which are elements of the array <paramref name="a"/>
  448. /// shall be of the same length.
  449. /// </summary>
  450. /// <typeparam name="T"> The type of the array element. </typeparam>
  451. /// <param name="a"> The array to linearize. </param>
  452. /// <returns> The resulting transposed and linearized array.
  453. /// res[i * n + j] = a[j][i]</returns>
  454. public static T[] linearize<T>(T[][] a) {
  455. int n = a.Length, m = a[0].Length;
  456. T[] res = new T[m * n];
  457. for(int j = 0; j < n; j++)
  458. for(int i = 0; i < m; i++)
  459. res[i * n + j] = a[j][i];
  460. return res;
  461. } // end of transpose<T>()
  462. /// <summary>
  463. /// Converts from the array of specific dimensionality (only 1 and
  464. /// 2 are currently supported) to the array of arbitrary number of
  465. /// dimensions
  466. /// </summary>
  467. /// <typeparam name="T"> The array element type </typeparam>
  468. /// <param name="arr"> The array of 1 or 2 rank </param>
  469. /// <param name="s"> The size of the first dimension of the
  470. /// array (only square 2D arrays are supported) </param>
  471. /// <param name="sizes"> The sizes of the desired array </param>
  472. /// <returns> The array of desired sizes and rank </returns>
  473. public static Array fromMDArray<T>(Array arr, int s, int[] sizes) {
  474. switch(arr.Rank) {
  475. case 1:
  476. return from1DArray<T>((T[]) arr, s, sizes);
  477. case 2:
  478. return from2DArray<T>((T[,]) arr, s, sizes);
  479. default:
  480. throw new NotSupportedException("Only ranks 1 and 2 are supported");
  481. } // end of switch()
  482. } // end of fromMDArray()
  483. /// <summary>
  484. /// Converts the array specified into a 1D array
  485. /// </summary>
  486. /// <typeparam name="T"> The type of the array to convert </typeparam>
  487. /// <param name="arr"> The array to convert </param>
  488. /// <param name="s"> The desired 1D array size </param>
  489. /// <returns> The resulting array created </returns>
  490. public static T[] to1DArray<T>(Array arr, int s) {
  491. T[] res = new T[s];
  492. int j = 0;
  493. foreach(T v in arr)
  494. res[j++] = v;
  495. return res;
  496. } // end of to1DArray<T>()
  497. /// <summary>
  498. /// Converts the array specified into a 1D array. The size is
  499. /// supposed equal to the total size of the array being converted.
  500. /// </summary>
  501. /// <typeparam name="T"> The type of the array to convert </typeparam>
  502. /// <param name="arr"> The array to convert </param>
  503. /// <returns> The resulting array created </returns>
  504. public static T[] to1DArray<T>(Array arr) {
  505. return to1DArray<T>(arr, arr.Length);
  506. } // end of to1DArray<T>()
  507. /// <summary>
  508. /// Creates a multi-dimensional array from a given 1-dimensional
  509. /// and returns the array created
  510. /// </summary>
  511. /// <typeparam name="T"> The type of the array being transformed </typeparam>
  512. /// <param name="arr"> The array to transform </param>
  513. /// <param name="s"> The size of the 1d array (can differ from
  514. /// the actual size of the array) </param>
  515. /// <param name="sizes"> The sizes of the resulting array </param>
  516. /// <returns> The resulting array created </returns>
  517. public static Array from1DArray<T>(T[] arr, int s, int[] sizes) {
  518. switch(sizes.Length) {
  519. case 1: return arr;
  520. case 2:
  521. return from1DArrayTo2D<T>(arr, s, sizes);
  522. case 3:
  523. return from1DArrayTo3D<T>(arr, s, sizes);
  524. case 4:
  525. return from1DArrayTo4D<T>(arr, s, sizes);
  526. default:
  527. return from1DArrayToND<T>(arr, s, sizes);
  528. } // end of switch()
  529. } // end of from1DArray<T>()
  530. /// <summary>
  531. /// Creates a 2-dimensional array from a given 1-dimensional
  532. /// and returns the array created.
  533. /// </summary>
  534. /// <typeparam name="T"> The type of the array being transformed </typeparam>
  535. /// <param name="arr"> The array to transform </param>
  536. /// <param name="s"> The size of the 1d array (can differ from
  537. /// the actual size of the array) </param>
  538. /// <param name="sizes"> The sizes of the resulting array </param>
  539. /// <returns> The resulting array created </returns>
  540. public static T[,] from1DArrayTo2D<T>(T[] arr, int s, int[] sizes) {
  541. int s0 = sizes[0], s1 = sizes[1];
  542. T[,] res = new T[s0, s1];
  543. int j = 0;
  544. for(int i0 = 0; i0 < s0; i0++)
  545. for(int i1 = 0; i1 < s1; i1++)
  546. res[i0, i1] = arr[j++];
  547. return res;
  548. } // end of from1DArrayTo2D()
  549. /// <summary>
  550. /// Creates a 3-dimensional array from a given 1-dimensional
  551. /// and returns the array created.
  552. /// </summary>
  553. /// <typeparam name="T"> The type of the array being transformed </typeparam>
  554. /// <param name="arr"> The array to transform </param>
  555. /// <param name="s"> The size of the 1d array (can differ from
  556. /// the actual size of the array) </param>
  557. /// <param name="sizes"> The sizes of the resulting array </param>
  558. /// <returns> The resulting array created </returns>
  559. public static T[,,] from1DArrayTo3D<T>(T[] arr, int s, int[] sizes) {
  560. int s0 = sizes[0], s1 = sizes[1], s2 = sizes[2];
  561. T[,,] res = new T[s0, s1, s2];
  562. int j = 0;
  563. for(int i0 = 0; i0 < s0; i0++)
  564. for(int i1 = 0; i1 < s1; i1++)
  565. for(int i2 = 0; i2 < s2; i2++)
  566. res[i0, i1, i2] = arr[j++];
  567. return res;
  568. } // end of from1DArrayTo3D()
  569. /// <summary>
  570. /// Creates a 4-dimensional array from a given 1-dimensional
  571. /// and returns the array created.
  572. /// </summary>
  573. /// <typeparam name="T"> The type of the array being transformed </typeparam>
  574. /// <param name="arr"> The array to transform </param>
  575. /// <param name="s"> The size of the 1d array (can differ from
  576. /// the actual size of the array) </param>
  577. /// <param name="sizes"> The sizes of the resulting array </param>
  578. /// <returns> The resulting array created </returns>
  579. public static T[,,,] from1DArrayTo4D<T>(T[] arr, int s, int[] sizes) {
  580. int s0 = sizes[0], s1 = sizes[1], s2 = sizes[2], s3 = sizes[3];
  581. T[,,,] res = new T[s0, s1, s2, s3];
  582. int j = 0;
  583. for(int i0 = 0; i0 < s0; i0++)
  584. for(int i1 = 0; i1 < s1; i1++)
  585. for(int i2 = 0; i2 < s2; i2++)
  586. for(int i3 = 0; i3 < s3; i3++)
  587. res[i0, i1, i2, i3] = arr[j++];
  588. return res;
  589. } // end of from1DArrayTo4D()
  590. /// <summary>
  591. /// Creates a multi-dimensional array from a given 1-dimensional
  592. /// and returns the array created. This is a generic and most
  593. /// inefficient implementation. For smaller arrays, more efficient
  594. /// implementations are provided.
  595. /// </summary>
  596. /// <typeparam name="T"> The type of the array being transformed </typeparam>
  597. /// <param name="arr"> The array to transform </param>
  598. /// <param name="s"> The size of the 1d array (can differ from
  599. /// the actual size of the array) </param>
  600. /// <param name="sizes"> The sizes of the resulting array </param>
  601. /// <returns> The resulting array created </returns>
  602. public static Array from1DArrayToND<T>(T[] arr, int s, int[] sizes) {
  603. Array arr2 = Array.CreateInstance(typeof(T), sizes);
  604. int i = 0;
  605. foreach(int[] p in pointIter(sizes))
  606. arr2.SetValue(arr[i++], p);
  607. return arr2;
  608. } // end of from1DArrayToND<T>()
  609. /// <summary>
  610. /// Reads the data from a 2D array into the specified array
  611. /// </summary>
  612. /// <typeparam name="T"> The array element type </typeparam>
  613. /// <param name="arr"> The source 2D array </param>
  614. /// <param name="s"> The size of the 2D square array </param>
  615. /// <param name="sizes"> The size of the resulting array </param>
  616. /// <returns> The resulting array </returns>
  617. public static Array from2DArray<T>(T[,] arr, int s, int[] sizes) {
  618. switch(sizes.Length) {
  619. case 1:
  620. return from2DArrayTo1D<T>(arr, s, sizes);
  621. case 2:
  622. return arr;
  623. case 3:
  624. return from2DArrayTo3D<T>(arr, s, sizes);
  625. case 4:
  626. return from2DArrayTo4D<T>(arr, s, sizes);
  627. default:
  628. return from2DArrayToND<T>(arr, s, sizes);
  629. } // end of switch()
  630. } // end of from2DArray<T>()
  631. /// <summary>
  632. /// Reads the data from the 2D array into a 1D array
  633. /// </summary>
  634. /// <typeparam name="T"> The element type </typeparam>
  635. /// <param name="arr"> The 2D array </param>
  636. /// <param name="s"> The size of the 2D array </param>
  637. /// <param name="sizes"> The sizes of the 1D array </param>
  638. /// <returns> The resulting 1D array </returns>
  639. public static T[] from2DArrayTo1D<T>(T[,] arr, int s, int[] sizes) {
  640. int n = sizes[0];
  641. T[] arr2 = new T[n];
  642. int i = 0, j = 0;
  643. for(int p = 0; p < n; p++) {
  644. arr2[p] = arr[i, j++];
  645. if(j == s) {
  646. i++;
  647. j = 0;
  648. } // end of if()
  649. } // end of for()
  650. return arr2;
  651. } // end of from2DArrayTo1D()
  652. /// <summary>
  653. /// Converts a 2D array representation into a 3D array
  654. /// </summary>
  655. /// <typeparam name="T"> The array type </typeparam>
  656. /// <param name="arr"> The array to convert </param>
  657. /// <param name="s"> The size of the 2D array along one
  658. /// of the dimensions </param>
  659. /// <param name="sizes"> The sizes of the 3D array </param>
  660. /// <returns> The 3D array created </returns>
  661. public static T[, ,] from2DArrayTo3D<T>(T[,] arr, int s, int[] sizes) {
  662. int n0 = sizes[0], n1 = sizes[1], n2 = sizes[2];
  663. T[,,] arr2 = new T[n0, n1, n2];
  664. int i = 0, j = 0;
  665. for(int p0 = 0; p0 < n0; p0++)
  666. for(int p1 = 0; p1 < n1; p1++)
  667. for(int p2 = 0; p2 < n2; p2++) {
  668. arr2[p0, p1, p2] = arr[i, j++];
  669. if(j == s) {
  670. i++;
  671. j = 0;
  672. } // end of if()
  673. } // end of for()
  674. return arr2;
  675. } // end of from2DArrayTo3D<T>()
  676. /// <summary>
  677. /// Converts a 2D array representation into a 4D array
  678. /// </summary>
  679. /// <typeparam name="T"> The array type </typeparam>
  680. /// <param name="arr"> The array to convert </param>
  681. /// <param name="s"> The size of the 2D array along one
  682. /// of the dimensions </param>
  683. /// <param name="sizes"> The sizes of the 4D array </param>
  684. /// <returns> The 4D array created </returns>
  685. public static T[,, ,] from2DArrayTo4D<T>(T[,] arr, int s, int[] sizes) {
  686. int n0 = sizes[0], n1 = sizes[1], n2 = sizes[2], n3 = sizes[3];
  687. T[, , ,] arr2 = new T[n0, n1, n2, n3];
  688. int i = 0, j = 0;
  689. for(int p0 = 0; p0 < n0; p0++)
  690. for(int p1 = 0; p1 < n1; p1++)
  691. for(int p2 = 0; p2 < n2; p2++)
  692. for(int p3 = 0; p3 < n3; p3++) {
  693. arr2[p0, p1, p2, p3] = arr[i, j++];
  694. if(j == s) {
  695. i++;
  696. j = 0;
  697. } // end of if()
  698. } // end of for()
  699. return arr2;
  700. } // end of from2DArrayTo4D<T>()
  701. /// <summary>
  702. /// Reads the data from the 2D array into an ND array
  703. /// </summary>
  704. /// <typeparam name="T"> The element type </typeparam>
  705. /// <param name="arr"> The 2D array </param>
  706. /// <param name="s"> The size of the 2D array </param>
  707. /// <param name="sizes"> The sizes of the ND array </param>
  708. /// <returns> The resulting ND array </returns>
  709. public static Array from2DArrayToND<T>(T[,] arr, int s, int[] sizes) {
  710. Array arr2 = Array.CreateInstance(typeof(T), sizes);
  711. int i = 0, j = 0;
  712. foreach(int[] p in pointIter(sizes)) {
  713. arr2.SetValue(arr[i, j++], p);
  714. if(j == s) {
  715. i++;
  716. j = 0;
  717. } // end of if()
  718. } // end of for()
  719. return arr2;
  720. } // end of from2DArrayToND()
  721. /// <summary>
  722. /// Checks whether the arrays have equal length and whether the predicate
  723. /// is valid for both of them
  724. /// </summary>
  725. /// <typeparam name="T1"> The type of the first array </typeparam>
  726. /// <typeparam name="T2"> The type of the second array </typeparam>
  727. /// <param name="arr1"> The first array </param>
  728. /// <param name="arr2"> The second array </param>
  729. /// <param name="prd"> The predicate to check </param>
  730. /// <returns> True iff either both <paramref name="arr1"/>
  731. /// and <paramref name="arr2"/> are null or both of them have equal length
  732. /// and for each pair of their respective elements the predicate
  733. /// <paramref name="prd"/> holds, i.e., returns true </returns>
  734. public static bool allTrue<T1, T2>(T1[] arr1, T2[] arr2, DoublePred<T1, T2> prd) {
  735. // check for null
  736. if(arr1 == null || arr2 == null) {
  737. return arr1 == null && arr2 == null;
  738. }
  739. if(prd == null)
  740. throw new ArgumentNullException();
  741. if(arr1.Length != arr2.Length)
  742. return false;
  743. int n = arr1.Length;
  744. for(int i = 0; i < n; i++)
  745. if(!prd(arr1[i], arr2[i]))
  746. return false;
  747. return true;
  748. } // end of allTrue<T1, T2>
  749. /// <summary>
  750. /// Checks whether the array are compatible and the predicate is true
  751. /// for each pair of elements in the arrays.
  752. /// </summary>
  753. /// <typeparam name="T1"> The type of the first array element. </typeparam>
  754. /// <typeparam name="T2"> The type of the second array element. </typeparam>
  755. /// <param name="a"> The first array. </param>
  756. /// <param name="b"> The second array. </param>
  757. /// <param name="prd"> The predicate to check. </param>
  758. /// <returns> True if either both arrays are null, or they are non-null,
  759. /// have equal ranks and sizes, and for each pair of corresponding elements,
  760. /// the predicate holds. Otherwise, returns false. </returns>
  761. public static bool allTrue<T1, T2>(Array a, Array b,
  762. DoublePred<T1, T2> prd) {
  763. if(null == a || null == b)
  764. return null == a && null == b;
  765. int[] sza = sizes(a), szb = sizes(b);
  766. if(!equal(sza, szb))
  767. return false;
  768. foreach(int[] p in pointIter(sza)) {
  769. if(!prd((T1)a.GetValue(p), (T2)b.GetValue(p)))
  770. return false;
  771. } // end of foreach()
  772. return true;
  773. } // end of allTrue<T1, T2>()
  774. /// <summary>
  775. /// Concatenates the first array with the second array
  776. /// </summary>
  777. /// <typeparam name="T"> The type of the arrays being concatenated </typeparam>
  778. /// <param name="arr1"> The first array to be concatenated </param>
  779. /// <param name="arr2"> The second array to be concatenated </param>
  780. /// <returns> The result of concatenation </returns>
  781. public static T[] con<T>(T[] arr1, T[] arr2) {
  782. if(arr1 == null)
  783. return arr2;
  784. if(arr2 == null)
  785. return arr1;
  786. int l1 = arr1.Length, l2 = arr2.Length;
  787. int l = l1 + l2;
  788. T[] res = new T[l];
  789. int i = 0;
  790. for(; i < l1; i++)
  791. res[i] = arr1[i];
  792. for(; i < l; i++)
  793. res[i] = arr2[i - l1];
  794. return res;
  795. }
  796. /// <summary>
  797. /// Concatenates any number of arrays of the same type specified
  798. /// </summary>
  799. /// <typeparam name="T"> The element type of the arrays to concatenate </typeparam>
  800. /// <param name="arrs"> The arrays to concatenate </param>
  801. /// <returns> The result of concatenation </returns>
  802. public static T[] con<T>(params T[][] arrs) {
  803. if(arrs == null)
  804. return null;
  805. if(arrs.Length == 0)
  806. return new T[] { };
  807. //if(Array.TrueForAll<T[]>(arrs, delegate(T[] a) { return a == null; }))
  808. // return null;
  809. if(null == arrs[0] && allEqualRef<T[]>(arrs, null))
  810. return null;
  811. int n = 0;
  812. for(int i = 0; i < arrs.Length; i++)
  813. n += arrs[i].Length;
  814. T[] res = new T[n];
  815. int k = 0;
  816. for(int i = 0; i < arrs.Length; i++)
  817. for(int j = 0; j < arrs[i].Length; j++)
  818. res[k++] = arrs[i][j];
  819. return res;
  820. } // end of con<T>()
  821. /// <summary>
  822. /// Adds an element to the end of the array
  823. /// </summary>
  824. /// <typeparam name="T"> The type of the array element </typeparam>
  825. /// <param name="arr"> The array to concatenate </param>
  826. /// <param name="el"> The element to concatenate </param>
  827. /// <returns> The resulting array </returns>
  828. public static T[] con<T>(T[] arr, T el) {
  829. return con<T>(arr, new T[] { el });
  830. } // end of con<T>
  831. /// <summary>
  832. /// Adds an element to the beginning of the array
  833. /// </summary>
  834. /// <typeparam name="T"> The type of the array element </typeparam>
  835. /// <param name="el"> The element to concatenate </param>
  836. /// <param name="arr"> The array to concatenate </param>
  837. /// <returns> The resulting array </returns>
  838. public static T[] con<T>(T el, T[] arr) {
  839. return con<T>(new T[] { el }, arr);
  840. } // end of con<T>
  841. /// <summary>
  842. /// Indexes the array with an array of indices and returns the result of the
  843. /// indexing
  844. /// </summary>
  845. /// <typeparam name="T"> The type of the array to index </typeparam>
  846. /// <param name="arr"> The array to index </param>
  847. /// <param name="inds"> The indices of the elements to retrieve </param>
  848. /// <returns> The list of indices for indexing </returns>
  849. public static T[] index<T>(T[] arr, params int[] inds) {
  850. List<T> l = new List<T>();
  851. if(inds == null)
  852. return l.ToArray();
  853. if(arr == null) {
  854. if(inds == null || inds.Length == 0)
  855. return l.ToArray();
  856. throw new ArgumentNullException();
  857. }
  858. foreach(int i in inds)
  859. l.Add(arr[i]);
  860. return l.ToArray();
  861. } // end of index()
  862. /// <summary>
  863. /// Creates a new array which contains original values except
  864. /// those specified in <paramref name="inds"/>; they are removed
  865. /// </summary>
  866. /// <typeparam name="T"> The type of the array element </typeparam>
  867. /// <param name="arr"> The source array </param>
  868. /// <param name="inds"> The indices to be except </param>
  869. /// <returns> The resulting array </returns>
  870. public static T[] indexExcept<T>(T[] arr, params int[] inds) {
  871. int rn = arr.Length - inds.Length;
  872. T[] ra = new T[rn];
  873. // current index to inds array
  874. int k = 0;
  875. // current index to resulting array
  876. int j = 0;
  877. for(int i = 0; i < arr.Length; i++) {
  878. if(k >= inds.Length || inds[k] != i)
  879. ra[j++] = arr[i];
  880. else
  881. k++;
  882. } // end of for()
  883. return ra;
  884. } // end of indexExcept<T>()
  885. /// <summary>
  886. /// Gets the indices of the array given the single cumulative index.
  887. /// </summary>
  888. /// <param name="index"> The cumulative index of the array </param>
  889. /// <param name="cumSizes"> The cumulative sizes of the array. The
  890. /// last of it equals to 1, the next-to-last to cumSizes[cumSizes.Length - 1] *
  891. /// sizes[cumSizes.length - 1], etc. </param>
  892. /// <returns> The resulting set of indices </returns>
  893. public static int[] indices(int index, int[] cumSizes) {
  894. int n = cumSizes.Length;
  895. int[] inds = new int[n];
  896. int j = index;
  897. for(int i = 0; i < n; i++) {
  898. inds[i] = j / cumSizes[i];
  899. j %= cumSizes[i];
  900. }
  901. return inds;
  902. } // end of indices()
  903. /// <summary>
  904. /// Creates the array of cumulative sizes from the array of sizes
  905. /// </summary>
  906. /// <param name="sizes"> The array of sizes </param>
  907. /// <returns> The array of cumulative sizes </returns>
  908. /// <remarks> When it is created, it is assumed that the first index in
  909. /// the array changes the slowest </remarks>
  910. public static int[] cumSizes(int[] sizes) {
  911. int n = sizes.Length;
  912. int[] cs = new int[n];
  913. cs[n - 1] = 1;
  914. for(int i = n - 2; i >= 0; i--)
  915. cs[i] = cs[i + 1] * sizes[i + 1];
  916. return cs;
  917. }
  918. /// <summary>
  919. /// Creates a tail from an array starting from the specified element
  920. /// </summary>
  921. /// <typeparam name="T"> The type of the array element </typeparam>
  922. /// <param name="arr"> The array from which to create a tail </param>
  923. /// <param name="start"> The start element of the tail </param>
  924. /// <returns> The tail created </returns>
  925. public static T[] tail<T>(T[] arr, int start) {
  926. if(start <= 0)
  927. return arr;
  928. if(start >= arr.Length)
  929. throw new IndexOutOfRangeException();
  930. int nl = arr.Length - start;
  931. T[] res = new T[nl];
  932. for(int i = 0; i < nl; i++)
  933. res[i] = arr[start + i];
  934. return res;
  935. }
  936. /// <summary>
  937. /// Gets the array of sizes of the array.
  938. /// </summary>
  939. /// <param name="arr"> The array for which to get the sizes. </param>
  940. /// <returns> The array of sizes of the array, staring from the one
  941. /// along which changes the slowest (i.e., the first). Returns null for
  942. /// null arrays. </returns>
  943. public static int[] sizes(Array arr) {
  944. if(null == arr)
  945. return null;
  946. int n = arr.Rank;
  947. int[] sz = new int[n];
  948. for(int i = 0; i < n; i++)
  949. sz[i] = arr.GetLength(i);
  950. return sz;
  951. }
  952. /// <summary>
  953. /// Creates a 1D array of the specified type and of specified size with all
  954. /// elements equal to a specified value
  955. /// </summary>
  956. /// <typeparam name="T"> The type of the array to create </typeparam>
  957. /// <param name="val"> The value of the array element </param>
  958. /// <param name="size"> The length of the array to create </param>
  959. /// <returns> The array created </returns>
  960. public static T[] idarr<T>(T val, int size) {
  961. if(size < 0)
  962. throw new ArgumentOutOfRangeException();
  963. T[] arr = new T[size];
  964. for(int i = 0; i < arr.Length; i++)
  965. arr[i] = val;
  966. return arr;
  967. }
  968. /// <summary>
  969. /// Transforms two arrays of values into a single array of values
  970. /// </summary>
  971. /// <typeparam name="T1"> The type of the first array of values </typeparam>
  972. /// <typeparam name="T2"> The type of the second array of values </typeparam>
  973. /// <typeparam name="T3"> The type of the resulting array of values </typeparam>
  974. /// <param name="arr1"> The first array of values </param>
  975. /// <param name="arr2"> The second array of values </param>
  976. /// <param name="trs"> The transform to apply </param>
  977. /// <returns> The resulting array of values </returns>
  978. public static T3[] map2<T1, T2, T3>(T1[] arr1, T2[] arr2, Transform<T1, T2, T3>
  979. trs) {
  980. // check for nulls
  981. if(arr1 == null || arr2 == null) {
  982. if(arr1 == null && arr2 == null)
  983. return null;
  984. else
  985. throw new ArgumentNullException();
  986. }
  987. if(trs == null)
  988. throw new ArgumentNullException();
  989. if(arr1.Length != arr2.Length)
  990. throw new ArgumentException();
  991. int n = arr1.Length;
  992. T3[] res = new T3[n];
  993. for(int i = 0; i < n; i++)
  994. res[i] = trs(arr1[i], arr2[i]);
  995. return res;
  996. }
  997. /// <summary>
  998. /// Performs the reduction of the specified array by the specified function
  999. /// </summary>
  1000. /// <typeparam name="T"> The type of the array to reduce </typeparam>
  1001. /// <param name="arr"> The array being reduced </param>
  1002. /// <param name="red"> The reducing function </param>
  1003. /// <returns> The result of the reduciton </returns>
  1004. public static T reduce<T>(T[] arr, Transform<T, T, T> red) {
  1005. if(null == arr || null == red)
  1006. throw new ArgumentNullException();
  1007. if(arr.Length == 0)
  1008. return default(T);
  1009. if(arr.Length == 1)
  1010. return arr[0];
  1011. T res = arr[0];
  1012. for(int i = 1; i < arr.Length; i++)
  1013. res = red(res, arr[i]);
  1014. return res;
  1015. }
  1016. /// <summary>
  1017. /// Converts an array of arbitrary rank from one type to another.
  1018. /// </summary>
  1019. /// <typeparam name="TI"> The input type of the array. </typeparam>
  1020. /// <typeparam name="TO"> The output type of the array. </typeparam>
  1021. /// <param name="a"> The array to convert. </param>
  1022. /// <param name="conv"> The converter delegate. </param>
  1023. /// <returns> The resulting array. </returns>
  1024. public static Array map<TI, TO>(Array a, Converter<TI, TO> conv) {
  1025. if(a.Rank == 1)
  1026. return Array.ConvertAll<TI, TO>((TI[])a, conv);
  1027. int[] sz = sizes(a);
  1028. Array newa = Array.CreateInstance(typeof(TO), sz);
  1029. foreach(int[] p in pointIter(sz))
  1030. newa.SetValue(conv((TI)a.GetValue(p)), p);
  1031. return newa;
  1032. } // end of map()
  1033. /// <summary>
  1034. /// Gets the head of the specified array
  1035. /// </summary>
  1036. /// <param name="arr"> The array from which to get the head </param>
  1037. /// <param name="end"> The index of the last element to be included in
  1038. /// the head array </param>
  1039. /// <returns> The head of the array </returns>
  1040. public static T[] head<T>(T[] arr, int end) {
  1041. if(null == arr)
  1042. return null;
  1043. if(end < 0)
  1044. throw new IndexOutOfRangeException();
  1045. if(end >= arr.Length)
  1046. return arr;
  1047. T[] res = new T[end + 1];
  1048. for(int i = 0; i <= end; i++)
  1049. res[i] = arr[i];
  1050. return res;
  1051. }
  1052. /// <summary>
  1053. /// Accepts the list of arrays and returns
  1054. /// their union
  1055. /// </summary>
  1056. /// <typeparam name="T"> The type of the arrays to unite </typeparam>
  1057. /// <param name="arr"> The arrays to unite </param>
  1058. /// <returns> The union of the arrays </returns>
  1059. /// <remarks> The result does not have any repeating elements; that is,
  1060. /// even if a single array is passed, it has its repeating elements
  1061. /// removed </remarks>
  1062. public static T[] union<T>(params T[][] arr) {
  1063. if(null == arr || arr.Length == 0)
  1064. return new T[] { };
  1065. //List<T> l = new List<T>();
  1066. //Set<T> s = new Set<T>();
  1067. //foreach(T[] a in arr) {
  1068. // if(null == a)
  1069. // continue;
  1070. // foreach(T el in a)
  1071. // if(!s.Contains(el)) {
  1072. // s.Add(el);
  1073. // l.Add(el);
  1074. // }
  1075. //}
  1076. //return l.ToArray();
  1077. List<T> l = new List<T>(arr.Length * arr[0].Length);
  1078. for(int i = 0; i < arr[0].Length; i++) {
  1079. T v = arr[0][i];
  1080. if(l.IndexOf(v) == -1)
  1081. l.Add(v);
  1082. } // end of for()
  1083. for(int i = 1; i < arr.Length; i++)
  1084. for(int j = 0; j < arr[i].Length; j++) {
  1085. T v = arr[i][j];
  1086. if(l.IndexOf(v) == -1)
  1087. l.Add(v);
  1088. } // end of for()
  1089. return l.ToArray();
  1090. } // end of union()
  1091. /// <summary>
  1092. /// Accepts two arrays and returns their difference
  1093. /// </summary>
  1094. /// <typeparam name="T"> The type of the array </typeparam>
  1095. /// <param name="arr1"> The first array </param>
  1096. /// <param name="arr2"> The second array </param>
  1097. /// <returns> The difference of the first and second arrays </returns>
  1098. public static T[] diff<T>(T[] arr1, T[] arr2) {
  1099. //if(null == arr1 || null == arr2)
  1100. // throw new ArgumentNullException();
  1101. //List<T> l = new List<T>();
  1102. //Set<T> s = new Set<T>(arr1).Difference(new Set<T>(arr2));
  1103. //Set<T> s1 = new Set<T>(); // for there be no identical elements
  1104. //foreach(T el in arr1)
  1105. // if(s.Contains(el) && !s1.Contains(el)) {
  1106. // s1.Add(el);
  1107. // l.Add(el);
  1108. // }
  1109. //return l.ToArray();
  1110. int n = arr1.Length;
  1111. List<T> l = new List<T>(n);
  1112. for(int i = 0; i < arr1.Length; i++) {
  1113. T val = arr1[i];
  1114. if(Array.IndexOf(arr2, val) == -1 && l.IndexOf(val) == -1)
  1115. l.Add(val);
  1116. } // end of for()
  1117. return l.ToArray();
  1118. } // end of diff();
  1119. /// <summary>
  1120. /// Gets the array containing integer span of data between a and b
  1121. /// </summary>
  1122. /// <param name="a"> The start of the span </param>
  1123. /// <param name="b"> The end of the span </param>
  1124. /// <returns> The span created or null if none </returns>
  1125. public static int[] span(int a, int b) {
  1126. if(b < a) return null;
  1127. int n = b - a + 1;
  1128. int[] arr = new int[n];
  1129. for(int i = a; i <= b; i++) arr[i - a] = i;
  1130. return arr;
  1131. } // end of span()
  1132. /// <summary>
  1133. /// Gets the floating-point
  1134. /// array containing integer span of data between a and b
  1135. /// </summary>
  1136. /// <param name="a"> The start of the span </param>
  1137. /// <param name="b"> The end of the span </param>
  1138. /// <returns> The span created or null if none </returns>
  1139. public static float[] spanFloat(int a, int b) {
  1140. if(b < a) return null;
  1141. int n = b - a + 1;
  1142. float[] arr = new float[n];
  1143. for(int i = a; i <= b; i++) arr[i - a] = i;
  1144. return arr;
  1145. } // end of spanFloat()
  1146. /// <summary>
  1147. /// Iterates over a rectangular set of integer points, starting from
  1148. /// (0, ..., 0) and ending with (sizes[0]-1, ..., sizes[n-1]-1), with
  1149. /// first index chaning the slowest. In case null or zero-length array
  1150. /// is passed, returns a single zero-length array
  1151. /// </summary>
  1152. /// <param name="sizes"> The limits of the domain over which to
  1153. /// iterate </param>
  1154. /// <returns> The iterator over the point domain </returns>
  1155. public static IEnumerable<int[]> pointIter(int[] sizes) {
  1156. if(null == sizes || sizes.Length == 0) {
  1157. yield return new int[0];
  1158. yield break;
  1159. } else {
  1160. int n = sizes.Length;
  1161. int[] vals = idarr<int>(-1, n);
  1162. int ptr = 0;
  1163. while(ptr != -1) {
  1164. if(ptr == n) {
  1165. yield return (int[])vals.Clone();
  1166. ptr--;
  1167. } else {
  1168. vals[ptr]++;
  1169. if(vals[ptr] == sizes[ptr]) {
  1170. vals[ptr] = -1;
  1171. ptr--;
  1172. } else {
  1173. ptr++;
  1174. } // end of if()-else
  1175. } // end of if()-else
  1176. } // end of while()
  1177. } // end of if()-else
  1178. } // end of pointIter()
  1179. /// <summary>
  1180. /// Creates an array of <paramref name="size"/> elements, all of
  1181. /// which are equal to <paramref name="val"/>, except for element
  1182. /// with index <paramref name="pos"/>, which is equal to
  1183. /// <paramref name="diffVal"/>
  1184. /// </summary>
  1185. /// <typeparam name="T"> The type of the element & array </typeparam>
  1186. /// <param name="size"> The size of the resulting array </param>
  1187. /// <param name="pos"> The position in the array which shall differ </param>
  1188. /// <param name="val"> The value of the array element </param>
  1189. /// <param name="diffVal"> The different value of the single element </param>
  1190. /// <returns> The array created </returns>
  1191. public static T[] singleDiff<T>(int size, int pos, T val, T diffVal) {
  1192. T[] a = idarr<T>(val, size);
  1193. a[pos] = diffVal;
  1194. return a;
  1195. } // end of singleDiff<T>()
  1196. /// <summary>
  1197. /// Evaluates the dot product of two integer arrays
  1198. /// </summary>
  1199. /// <param name="a1"> The first array </param>
  1200. /// <param name="a2"> The second array </param>
  1201. /// <returns> The dot product of two arrays </returns>
  1202. public static int dot(int[] a1, int[] a2) {
  1203. int n = a1.Length;
  1204. if(a2.Length != n)
  1205. throw new ArgumentException();
  1206. int r = 0;
  1207. for(int i = 0; i < n; i++)
  1208. r += a1[i] * a2[i];
  1209. return r;
  1210. } // end of dot()
  1211. /// <summary>
  1212. /// Assigns values of <paramref name="src"/> to <paramref name="tgt"/>,
  1213. /// so that each element of <paramref name="src"/> is assigned to the
  1214. /// <paramref name="inds"/> position with respective index of
  1215. /// <paramref name="tgt"/>. If there are several candidates to the
  1216. /// same position, any of them can be assigned.
  1217. /// </summary>
  1218. /// <typeparam name="T"> The type of the array </typeparam>
  1219. /// <param name="tgt"> The target array </param>
  1220. /// <param name="src"> The source array </param>
  1221. /// <param name="inds"> The indices at which to assign </param>
  1222. public static void arrass<T>(T[] tgt, T[] src, int[] inds) {
  1223. int n = src.Length;
  1224. if(inds.Length != n)
  1225. throw new ArgumentException("Source and indices lengths do not match");
  1226. for(int i = 0; i < n; i++) tgt[inds[i]] = src[i];
  1227. } // end of arrass<T>
  1228. /// <summary>
  1229. /// Removes duplicates in the array
  1230. /// </summary>
  1231. /// <param name="arr"> The array from which to remove duplicates </param>
  1232. /// <returns> The array with all duplicates removed </returns>
  1233. public static T[] removeDups<T>(T[] arr) {
  1234. List<T> l = new List<T>();
  1235. Set<T> s = new Set<T>();
  1236. foreach(T t in arr)
  1237. if(!s.Contains(t)) {
  1238. s.Add(t);
  1239. l.Add(t);
  1240. } // end of if()
  1241. return l.ToArray();
  1242. } // end of removeDups()
  1243. /// <summary>
  1244. /// Gets the indices of objects of <paramref name="arr2"/> with which
  1245. /// they are present in <paramref name="arr1"/>
  1246. /// </summary>
  1247. /// <typeparam name="T"> The array type </typeparam>
  1248. /// <param name="arr1"> The first array </param>
  1249. /// <param name="arr2"> The second array </param>
  1250. /// <returns> The array of indices </returns>
  1251. public static int[] indicesOf<T>(T[] arr1, T[] arr2) {
  1252. int n = arr2.Length;
  1253. int[] inds = new int[n];
  1254. for(int i = 0; i < n; i++)
  1255. inds[i] = Array.IndexOf<T>(arr1, arr2[i]);
  1256. return inds;
  1257. } // end of indicesOf<T>
  1258. /// <summary>
  1259. /// Given an array and a predicate, finds indices of all elements for
  1260. /// which the predicate evaluates to true
  1261. /// </summary>
  1262. /// <typeparam name="T"> The type of the array element </typeparam>
  1263. /// <param name="arr1"> The array </param>
  1264. /// <param name="p"> The predicate </param>
  1265. /// <returns> The array of indices for which the predicate evaluates
  1266. /// to true </returns>
  1267. public static int[] indicesOf<T>(T[] arr1, Predicate<T> p) {
  1268. List<int> l = new List<int>();
  1269. for(int i = 0; i < arr1.Length; i++)
  1270. if(p(arr1[i])) l.Add(i);
  1271. return l.ToArray();
  1272. } // end of indicesOf()
  1273. /// <summary>
  1274. /// Reverses the given array
  1275. /// </summary>
  1276. /// <typeparam name="T"> The type of the array to reverse </typeparam>
  1277. /// <param name="arr"> The array to reverse </param>
  1278. /// <returns> The reversed array </returns>
  1279. /// <remarks> Reversing a null array returns null. </remarks>
  1280. public static T[] reverse<T>(T[] arr) {
  1281. if(null == arr)
  1282. return null;
  1283. int n = arr.Length;
  1284. T[] arr2 = new T[n];
  1285. for(int i = 0; i < n; i++)
  1286. arr2[i] = arr[n - i - 1];
  1287. return arr2;
  1288. } // end of reverse<T>()
  1289. /// <summary>
  1290. /// Given the keys and values, makes a map. The number of keys
  1291. /// shall be the same as the number of values, and the keys shall not
  1292. /// duplicate itself
  1293. /// </summary>
  1294. /// <typeparam name="TK"> The type of the key </typeparam>
  1295. /// <typeparam name="TV"> The type of the value </typeparam>
  1296. /// <param name="keys"> The keys </param>
  1297. /// <param name="vals"> The values </param>
  1298. /// <returns> The dictionary created </returns>
  1299. public static Dictionary<TK, TV> makeMap<TK, TV>(TK[] keys, TV[] vals) {
  1300. if(keys.Length != vals.Length)
  1301. throw new ArgumentException("Length of keys and values " +
  1302. "must be the same");
  1303. Di

Large files files are truncated, but you can click here to view the full file