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

# · C# · 707 lines · 392 code · 39 blank · 276 comment · 156 complexity · 09d23c0bbf3f399235dc6635cbcd024e MD5 · raw file

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