/branches/polan02/runtime/CBucks.Common/ArrOps.cs
# · C# · 833 lines · 443 code · 45 blank · 345 comment · 184 complexity · f0539b4c6581bdc2d2fe76f71177d9f2 MD5 · raw file
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Wintellect.PowerCollections;
-
- namespace CBucks.Common {
-
- public delegate bool DoublePred<T1, T2>(T1 a, T2 b);
-
- public delegate T3 Transform<T1, T2, T3>(T1 a, T2 b);
-
- /// <summary>
- /// Contains common array operations
- /// </summary>
- public static class ArrOps {
-
- /// <summary>
- /// Checks whether the specified arrays are equal, i.e., contain equal
- /// components and are of same length.
- /// </summary>
- /// <typeparam name="T"> The first array </typeparam>
- /// <param name="a"> The first array </param>
- /// <param name="b"> The second array </param>
- /// <returns> True if they are equal and false if not </returns>
- public static bool equal<T>(T[] a, T[] b) {
- if(null == a || null == b)
- return null == a && null == b;
- if(a.Length != b.Length)
- return false;
- int n = a.Length;
- for(int i = 0; i < n; i++)
- if(!object.Equals(a[i], b[i]))
- return false;
- return true;
- } // end of equal<T>
-
- /// <summary>
- /// Checks whether the specified arrays contain all their references
- /// equal
- /// </summary>
- /// <typeparam name="T"> The array type </typeparam>
- /// <param name="a"> The first array </param>
- /// <param name="b"> The second array </param>
- /// <returns> True if they do and false if not </returns>
- public static bool equalRef<T>(T[] a, T[] b) where T : class {
- if(null == a || null == b)
- return null == a && null == b;
- if(a.Length != b.Length)
- return false;
- int n = a.Length;
- for(int i = 0; i < n; i++)
- if(a[i] != b[i])
- return false;
- return true;
- } // end of equalRef<T>
-
- /// <summary>
- /// Gets whether all elements of the specified array are equal to
- /// the specified value
- /// </summary>
- /// <typeparam name="T"> The element type </typeparam>
- /// <param name="a"> The array </param>
- /// <param name="b"> The value </param>
- /// <returns> True if it is and false if not </returns>
- public static bool allEqual<T>(T[] a, T b) {
- if(null == a || a.Length == 0)
- return true;
- for(int i = 0; i < a.Length; i++)
- if(!object.Equals(a[i], b))
- return false;
- return true;
- } // end of allEqual<T>()
-
- /// <summary>
- /// Gets whether all elements of the specified array are reference equal to
- /// the specified value
- /// </summary>
- /// <typeparam name="T"> The element type </typeparam>
- /// <param name="a"> The array </param>
- /// <param name="b"> The value </param>
- /// <returns> True if it is and false if not </returns>
- public static bool allEqualRef<T>(T[] a, T b) where T: class {
- if(null == a || a.Length == 0)
- return true;
- for(int i = 0; i < a.Length; i++)
- if(b != a[i])
- return false;
- return true;
- } // end of allEqual<T>()
-
- /// <summary>
- /// Gets whether all elements of the array are the same
- /// </summary>
- /// <typeparam name="T"> The array element type </typeparam>
- /// <param name="a"> The array </param>
- /// <returns> True if it is and false if not </returns>
- public static bool allSame<T>(T[] a) {
- if(null == a || a.Length <= 1)
- return true;
- return allEqual<T>(a, a[0]);
- } // end of allSame<T>()
-
- /// <summary>
- /// Gets whether all array elemetns are the same references
- /// </summary>
- /// <typeparam name="T"> The array element type </typeparam>
- /// <param name="a"> The array to check </param>
- /// <returns> True if it is and false if not </returns>
- public static bool allSameRef<T>(T[] a) where T : class {
- if(null == a || a.Length <= 1)
- return true;
- return allEqualRef<T>(a, a[0]);
- } // end of allSameRef<T>()
-
- /// <summary>
- /// Creates an alternative iterator of two arrays of the same length.
- /// If n is the length of both arrays, returns an iterator over a
- /// sequence of 2^n values.
- /// </summary>
- /// <typeparam name="T"> The element type of the array </typeparam>
- /// <param name="a"> The first array </param>
- /// <param name="b"> The second array </param>
- /// <returns> The resulting iterator </returns>
- /// <remarks> The resulting arrays should not be modified </remarks>
- public static IEnumerable<T[]> alterIter<T>(T[] a, T[] b) {
- if(null == a || null == b)
- throw new ArgumentNullException();
- if(a.Length != b.Length)
- throw new ArgumentException();
- int n = a.Length;
- T[] res = new T[n];
- int[] iis = idarr<int>(-1, n); // -1 - no value, 0 - first array,
- // 1 - second array
- int i = 0;
- while(i > -1) {
- if(i < n) {
- switch(iis[i]) {
- case -1: iis[i]++; res[i] = a[i]; i++; break;
- case 0: iis[i]++; res[i] = b[i]; i++; break;
- case 1: iis[i] = -1; i--; break;
- } // end of switch()
- } else {
- i--;
- yield return res;
- } // end of while()
- } // end of while()
- } // end of alterIter<T>()
-
- /// <summary>
- /// Gets the product of all array values and 1 if the array is empty
- /// </summary>
- /// <param name="arr"> The array </param>
- /// <returns> The resulting product </returns>
- public static int prod(params int[] arr) {
- int p = 1;
- foreach(int i in arr)
- p *= i;
- return p;
- } // end of prod()
-
- /// <summary>
- /// Negates the array component-wise
- /// </summary>
- /// <param name="arr"> The array to negate </param>
- /// <returns> The negated array </returns>
- public static int[] neg(params int[] arr) {
- int n = arr.Length;
- int[] r = new int[n];
- for(int i = 0; i < n; i++)
- r[i] = -arr[i];
- return r;
- } // end of neg()
-
- /// <summary>
- /// Transforms an array into a 2D array of the specified size,
- /// </summary>
- /// <typeparam name="T"> The type of the array to transform </typeparam>
- /// <param name="arr"> The source array </param>
- /// <param name="s"> The size of the resulting 2D array </param>
- /// <returns> The resulting array </returns>
- public static T[,] to2DArray<T>(Array arr, int s) {
- T[,] arr2 = new T[s, s];
- // copy array values
- int i = 0, j = 0;
- foreach(T v in arr) {
- arr2[i, j++] = v;
- if(j == s) {
- i++;
- j = 0;
- } // end of if()
- } // end of foreach()
- return arr2;
- } // end of to2DArray()
-
- /// <summary>
- /// Reads the data from a 2D array into the specified array
- /// </summary>
- /// <typeparam name="T"> The array element type </typeparam>
- /// <param name="arr"> The source 2D array </param>
- /// <param name="s"> The size of the 2D square array </param>
- /// <param name="sizes"> The size of the resulting array </param>
- /// <returns> The resulting array </returns>
- public static Array from2DArray<T>(T[,] arr, int s, int[] sizes) {
- switch(sizes.Length) {
- case 1:
- return from2DArrayTo1D<T>(arr, s, sizes);
- case 2:
- return arr;
- case 3:
- return from2DArrayTo3D<T>(arr, s, sizes);
- case 4:
- return from2DArrayTo4D<T>(arr, s, sizes);
- default:
- return from2DArrayToND<T>(arr, s, sizes);
- } // end of switch()
- } // end of from2DArray<T>()
-
- /// <summary>
- /// Reads the data from the 2D array into a 1D array
- /// </summary>
- /// <typeparam name="T"> The element type </typeparam>
- /// <param name="arr"> The 2D array </param>
- /// <param name="s"> The size of the 2D array </param>
- /// <param name="sizes"> The sizes of the 1D array </param>
- /// <returns> The resulting 1D array </returns>
- public static T[] from2DArrayTo1D<T>(T[,] arr, int s, int[] sizes) {
- int n = sizes[0];
- T[] arr2 = new T[n];
- int i = 0, j = 0;
- for(int p = 0; p < n; p++) {
- arr2[p] = arr[i, j++];
- if(j == s) {
- i++;
- j = 0;
- } // end of if()
- } // end of for()
- return arr2;
- } // end of from2DArrayTo1D()
-
- /// <summary>
- /// Converts a 2D array representation into a 3D array
- /// </summary>
- /// <typeparam name="T"> The array type </typeparam>
- /// <param name="arr"> The array to convert </param>
- /// <param name="s"> The size of the 2D array along one
- /// of the dimensions </param>
- /// <param name="sizes"> The sizes of the 3D array </param>
- /// <returns> The 3D array created </returns>
- public static T[, ,] from2DArrayTo3D<T>(T[,] arr, int s, int[] sizes) {
- int n0 = sizes[0], n1 = sizes[1], n2 = sizes[2];
- T[,,] arr2 = new T[n0, n1, n2];
- int i = 0, j = 0;
- for(int p0 = 0; p0 < n0; p0++)
- for(int p1 = 0; p1 < n1; p1++)
- for(int p2 = 0; p2 < n2; p2++) {
- arr2[p0, p1, p2] = arr[i, j++];
- if(j == s) {
- i++;
- j = 0;
- } // end of if()
- } // end of for()
- return arr2;
- } // end of from2DArrayTo3D<T>()
-
- /// <summary>
- /// Converts a 2D array representation into a 4D array
- /// </summary>
- /// <typeparam name="T"> The array type </typeparam>
- /// <param name="arr"> The array to convert </param>
- /// <param name="s"> The size of the 2D array along one
- /// of the dimensions </param>
- /// <param name="sizes"> The sizes of the 4D array </param>
- /// <returns> The 4D array created </returns>
- public static T[,, ,] from2DArrayTo4D<T>(T[,] arr, int s, int[] sizes) {
- int n0 = sizes[0], n1 = sizes[1], n2 = sizes[2], n3 = sizes[3];
- T[, , ,] arr2 = new T[n0, n1, n2, n3];
- int i = 0, j = 0;
- for(int p0 = 0; p0 < n0; p0++)
- for(int p1 = 0; p1 < n1; p1++)
- for(int p2 = 0; p2 < n2; p2++)
- for(int p3 = 0; p3 < n3; p3++) {
- arr2[p0, p1, p2, p3] = arr[i, j++];
- if(j == s) {
- i++;
- j = 0;
- } // end of if()
- } // end of for()
- return arr2;
- } // end of from2DArrayTo4D<T>()
-
- /// <summary>
- /// Reads the data from the 2D array into an ND array
- /// </summary>
- /// <typeparam name="T"> The element type </typeparam>
- /// <param name="arr"> The 2D array </param>
- /// <param name="s"> The size of the 2D array </param>
- /// <param name="sizes"> The sizes of the ND array </param>
- /// <returns> The resulting ND array </returns>
- public static Array from2DArrayToND<T>(T[,] arr, int s, int[] sizes) {
- int n = sizes[0];
- Array arr2 = Array.CreateInstance(typeof(T), sizes);
- int i = 0, j = 0;
- foreach(int[] p in pointIter(sizes)) {
- arr2.SetValue(arr[i, j++], p);
- if(j == s) {
- i++;
- j = 0;
- } // end of if()
- } // end of for()
- return arr2;
- } // end of from2DArrayToND()
-
- /// <summary>
- /// Checks whether the arrays have equal length and whether the predicate
- /// is valid for both of them
- /// </summary>
- /// <typeparam name="T1"> The type of the first array </typeparam>
- /// <typeparam name="T2"> The type of the second array </typeparam>
- /// <param name="arr1"> The first array </param>
- /// <param name="arr2"> The second array </param>
- /// <param name="prd"> The predicate to check </param>
- /// <returns> True iff either both <paramref name="arr1"/>
- /// and <paramref name="arr2"/> are null or both of them have equal length
- /// and for each pair of their respective elements the predicate
- /// <paramref name="prd"/> holds, i.e., returns true </returns>
- public static bool allTrue<T1, T2>(T1[] arr1, T2[] arr2, DoublePred<T1, T2> prd) {
- // check for null
- if(arr1 == null || arr2 == null) {
- return arr1 == null && arr2 == null;
- }
- if(prd == null)
- throw new ArgumentNullException();
- if(arr1.Length != arr2.Length)
- return false;
- int n = arr1.Length;
- for(int i = 0; i < n; i++)
- if(!prd(arr1[i], arr2[i]))
- return false;
- return true;
- }
-
- /// <summary>
- /// Concatenates the first array with the second array
- /// </summary>
- /// <typeparam name="T"> The type of the arrays being concatenated </typeparam>
- /// <param name="arr1"> The first array to be concatenated </param>
- /// <param name="arr2"> The second array to be concatenated </param>
- /// <returns> The result of concatenation </returns>
- public static T[] con<T>(T[] arr1, T[] arr2) {
- if(arr1 == null)
- return arr2;
- if(arr2 == null)
- return arr1;
- int l1 = arr1.Length, l2 = arr2.Length;
- int l = l1 + l2;
- T[] res = new T[l];
- int i = 0;
- for(; i < l1; i++)
- res[i] = arr1[i];
- for(; i < l; i++)
- res[i] = arr2[i - l1];
- return res;
- }
-
- /// <summary>
- /// Concatenates any number of arrays of the same type specified
- /// </summary>
- /// <typeparam name="T"> The element type of the arrays to concatenate </typeparam>
- /// <param name="arrs"> The arrays to concatenate </param>
- /// <returns> The result of concatenation </returns>
- public static T[] con<T>(params T[][] arrs) {
- if(arrs == null)
- return null;
- if(arrs.Length == 0)
- return new T[] { };
- //if(Array.TrueForAll<T[]>(arrs, delegate(T[] a) { return a == null; }))
- // return null;
- if(null == arrs[0] && allEqualRef<T[]>(arrs, null))
- return null;
- int n = 0;
- for(int i = 0; i < arrs.Length; i++)
- n += arrs[i].Length;
- T[] res = new T[n];
- int k = 0;
- for(int i = 0; i < arrs.Length; i++)
- for(int j = 0; j < arrs[i].Length; j++)
- res[k++] = arrs[i][j];
- return res;
- } // end of con<T>()
-
- /// <summary>
- /// Adds an element to the end of the array
- /// </summary>
- /// <typeparam name="T"> The type of the array element </typeparam>
- /// <param name="arr"> The array to concatenate </param>
- /// <param name="el"> The element to concatenate </param>
- /// <returns> The resulting array </returns>
- public static T[] con<T>(T[] arr, T el) {
- return con<T>(arr, new T[] { el });
- } // end of con<T>
-
- /// <summary>
- /// Adds an element to the beginning of the array
- /// </summary>
- /// <typeparam name="T"> The type of the array element </typeparam>
- /// <param name="el"> The element to concatenate </param>
- /// <param name="arr"> The array to concatenate </param>
- /// <returns> The resulting array </returns>
- public static T[] con<T>(T el, T[] arr) {
- return con<T>(new T[] { el }, arr);
- } // end of con<T>
-
- /// <summary>
- /// Indexes the array with an array of indices and returns the result of the
- /// indexing
- /// </summary>
- /// <typeparam name="T"> The type of the array to index </typeparam>
- /// <param name="arr"> The array to index </param>
- /// <param name="inds"> The indices of the elements to retrieve </param>
- /// <returns> The list of indices for indexing </returns>
- public static T[] index<T>(T[] arr, params int[] inds) {
- List<T> l = new List<T>();
- if(inds == null)
- return l.ToArray();
- if(arr == null) {
- if(inds == null || inds.Length == 0)
- return l.ToArray();
- throw new ArgumentNullException();
- }
- foreach(int i in inds)
- l.Add(arr[i]);
- return l.ToArray();
- } // end of index()
-
- /// <summary>
- /// Creates a new array which contains original values except
- /// those specified in <paramref name="inds"/>; they are removed
- /// </summary>
- /// <typeparam name="T"> The type of the array element </typeparam>
- /// <param name="arr"> The source array </param>
- /// <param name="inds"> The indices to be except </param>
- /// <returns> The resulting array </returns>
- public static T[] indexExcept<T>(T[] arr, params int[] inds) {
- int rn = arr.Length - inds.Length;
- T[] ra = new T[rn];
- // current index to inds array
- int k = 0;
- // current index to resulting array
- int j = 0;
- for(int i = 0; i < arr.Length; i++) {
- if(k >= inds.Length || inds[k] != i)
- ra[j++] = arr[i];
- else
- k++;
- } // end of for()
- return ra;
- } // end of indexExcept<T>()
-
- /// <summary>
- /// Gets the indices of the array given the single cumulative index.
- /// </summary>
- /// <param name="index"> The cumulative index of the array </param>
- /// <param name="cumSizes"> The cumulative sizes of the array. The
- /// last of it equals to 1, the next-to-last to cumSizes[cumSizes.Length - 1] *
- /// sizes[cumSizes.length - 1], etc. </param>
- /// <returns> The resulting set of indices </returns>
- public static int[] indices(int index, int[] cumSizes) {
- int n = cumSizes.Length;
- int[] inds = new int[n];
- int j = index;
- for(int i = 0; i < n; i++) {
- inds[i] = j / cumSizes[i];
- j %= cumSizes[i];
- }
- return inds;
- } // end of indices()
-
- /// <summary>
- /// Creates the array of cumulative sizes from the array of sizes
- /// </summary>
- /// <param name="sizes"> The array of sizes </param>
- /// <returns> The array of cumulative sizes </returns>
- /// <remarks> When it is created, it is assumed that the first index in
- /// the array changes the slowest </remarks>
- public static int[] cumSizes(int[] sizes) {
- int n = sizes.Length;
- int[] cs = new int[n];
- cs[n - 1] = 1;
- for(int i = n - 2; i >= 0; i--)
- cs[i] = cs[i + 1] * sizes[i + 1];
- return cs;
- }
-
- /// <summary>
- /// Creates a tail from an array starting from the specified element
- /// </summary>
- /// <typeparam name="T"> The type of the array element </typeparam>
- /// <param name="arr"> The array from which to create a tail </param>
- /// <param name="start"> The start element of the tail </param>
- /// <returns> The tail created </returns>
- public static T[] tail<T>(T[] arr, int start) {
- if(start <= 0)
- return arr;
- if(start >= arr.Length)
- throw new IndexOutOfRangeException();
- int nl = arr.Length - start;
- T[] res = new T[nl];
- for(int i = 0; i < nl; i++)
- res[i] = arr[start + i];
- return res;
- }
-
- /// <summary>
- /// Gets the array of sizes of the array.
- /// </summary>
- /// <param name="arr"> The array for which to get the sizes. </param>
- /// <returns> The array of sizes of the array, staring from the one
- /// along which changes the slowest (i.e., the first). Returns null for
- /// null arrays. </returns>
- public static int[] sizes(Array arr) {
- if(null == arr)
- return null;
- int n = arr.Rank;
- int[] sz = new int[n];
- for(int i = 0; i < n; i++)
- sz[i] = arr.GetLength(i);
- return sz;
- }
-
- /// <summary>
- /// Creates a 1D array of the specified type and of specified size with all
- /// elements equal to a specified value
- /// </summary>
- /// <typeparam name="T"> The type of the array to create </typeparam>
- /// <param name="val"> The value of the array element </param>
- /// <param name="size"> The length of the array to create </param>
- /// <returns> The array created </returns>
- public static T[] idarr<T>(T val, int size) {
- if(size < 0)
- throw new ArgumentOutOfRangeException();
- T[] arr = new T[size];
- for(int i = 0; i < arr.Length; i++)
- arr[i] = val;
- return arr;
- }
-
- /// <summary>
- /// Transforms two arrays of values into a single array of values
- /// </summary>
- /// <typeparam name="T1"> The type of the first array of values </typeparam>
- /// <typeparam name="T2"> The type of the second array of values </typeparam>
- /// <typeparam name="T3"> The type of the resulting array of values </typeparam>
- /// <param name="arr1"> The first array of values </param>
- /// <param name="arr2"> The second array of values </param>
- /// <param name="trs"> The transform to apply </param>
- /// <returns> The resulting array of values </returns>
- public static T3[] map2<T1, T2, T3>(T1[] arr1, T2[] arr2, Transform<T1, T2, T3>
- trs) {
- // check for nulls
- if(arr1 == null || arr2 == null) {
- if(arr1 == null && arr2 == null)
- return null;
- else
- throw new ArgumentNullException();
- }
- if(trs == null)
- throw new ArgumentNullException();
- if(arr1.Length != arr2.Length)
- throw new ArgumentException();
- int n = arr1.Length;
- T3[] res = new T3[n];
- for(int i = 0; i < n; i++)
- res[i] = trs(arr1[i], arr2[i]);
- return res;
- }
-
- /// <summary>
- /// Performs the reduction of the specified array by the specified function
- /// </summary>
- /// <typeparam name="T"> The type of the array to reduce </typeparam>
- /// <param name="arr"> The array being reduced </param>
- /// <param name="red"> The reducing function </param>
- /// <returns> The result of the reduciton </returns>
- public static T reduce<T>(T[] arr, Transform<T, T, T> red) {
- if(null == arr || null == red)
- throw new ArgumentNullException();
- if(arr.Length == 0)
- return default(T);
- if(arr.Length == 1)
- return arr[0];
- T res = arr[0];
- for(int i = 1; i < arr.Length; i++)
- res = red(res, arr[i]);
- return res;
- }
-
- /// <summary>
- /// Gets the head of the specified array
- /// </summary>
- /// <param name="arr"> The array from which to get the head </param>
- /// <param name="end"> The index of the last element to be included in
- /// the head array </param>
- /// <returns> The head of the array </returns>
- public static T[] head<T>(T[] arr, int end) {
- if(null == arr)
- return null;
- if(end < 0)
- throw new IndexOutOfRangeException();
- if(end >= arr.Length)
- return arr;
- T[] res = new T[end + 1];
- for(int i = 0; i <= end; i++)
- res[i] = arr[i];
- return res;
- }
-
- /// <summary>
- /// Accepts the list of arrays and returns
- /// their union
- /// </summary>
- /// <typeparam name="T"> The type of the arrays to unite </typeparam>
- /// <param name="arr"> The arrays to unite </param>
- /// <returns> The union of the arrays </returns>
- /// <remarks> The result does not have any repeating elements; that is,
- /// even if a single array is passed, it has its repeating elements
- /// removed </remarks>
- public static T[] union<T>(params T[][] arr) {
- if(null == arr || arr.Length == 0)
- return new T[] { };
- //List<T> l = new List<T>();
- //Set<T> s = new Set<T>();
- //foreach(T[] a in arr) {
- // if(null == a)
- // continue;
- // foreach(T el in a)
- // if(!s.Contains(el)) {
- // s.Add(el);
- // l.Add(el);
- // }
- //}
- //return l.ToArray();
- List<T> l = new List<T>(arr.Length * arr[0].Length);
- for(int i = 0; i < arr[0].Length; i++)
- l.Add(arr[0][i]);
- for(int i = 1; i < arr.Length; i++)
- for(int j = 0; j < arr[i].Length; j++) {
- T v = arr[i][j];
- if(l.IndexOf(v) == -1)
- l.Add(v);
- } // end of for()
- return l.ToArray();
- } // end of union()
-
- /// <summary>
- /// Accepts two arrays and returns their difference
- /// </summary>
- /// <typeparam name="T"> The type of the array </typeparam>
- /// <param name="arr1"> The first array </param>
- /// <param name="arr2"> The second array </param>
- /// <returns> The difference of the first and second arrays </returns>
- public static T[] diff<T>(T[] arr1, T[] arr2) {
- //if(null == arr1 || null == arr2)
- // throw new ArgumentNullException();
- //List<T> l = new List<T>();
- //Set<T> s = new Set<T>(arr1).Difference(new Set<T>(arr2));
- //Set<T> s1 = new Set<T>(); // for there be no identical elements
- //foreach(T el in arr1)
- // if(s.Contains(el) && !s1.Contains(el)) {
- // s1.Add(el);
- // l.Add(el);
- // }
- //return l.ToArray();
- int n = arr1.Length;
- List<T> l = new List<T>(n);
- for(int i = 0; i < arr1.Length; i++) {
- T val = arr1[i];
- if(Array.IndexOf<T>(arr2, val) == -1)
- l.Add(val);
- } // end of for()
- return l.ToArray();
- } // end of diff();
-
- /// <summary>
- /// Gets the array containing integer span of data between a and b
- /// </summary>
- /// <param name="a"> The start of the span </param>
- /// <param name="b"> The end of the span </param>
- /// <returns> The span created or null if none </returns>
- public static int[] span(int a, int b) {
- if(b < a) return null;
- int n = b - a + 1;
- int[] arr = new int[n];
- for(int i = a; i <= b; i++) arr[i - a] = i;
- return arr;
- } // end of span()
-
- /// <summary>
- /// Iterates over a rectangular set of integer points, starting from
- /// (0, ..., 0) and ending with (sizes[0]-1, ..., sizes[n-1]-1), with
- /// first index chaning the slowest. In case null or zero-length array
- /// is passed, returns a single zero-length array
- /// </summary>
- /// <param name="sizes"> The limits of the domain over which to
- /// iterate </param>
- /// <returns> The iterator over the point domain </returns>
- public static IEnumerable<int[]> pointIter(int[] sizes) {
- if(null == sizes || sizes.Length == 0) {
- yield return new int[0];
- yield break;
- } else {
- int n = sizes.Length;
- int[] vals = idarr<int>(-1, n);
- int ptr = 0;
- while(ptr != -1) {
- if(ptr == n) {
- yield return (int[])vals.Clone();
- ptr--;
- } else {
- vals[ptr]++;
- if(vals[ptr] == sizes[ptr]) {
- vals[ptr] = -1;
- ptr--;
- } else {
- ptr++;
- } // end of if()-else
- } // end of if()-else
- } // end of while()
- } // end of if()-else
- } // end of pointIter()
-
- /// <summary>
- /// Creates an array of <paramref name="size"/> elements, all of
- /// which are equal to <paramref name="val"/>, except for element
- /// with index <paramref name="pos"/>, which is equal to
- /// <paramref name="diffVal"/>
- /// </summary>
- /// <typeparam name="T"> The type of the element & array </typeparam>
- /// <param name="size"> The size of the resulting array </param>
- /// <param name="pos"> The position in the array which shall differ </param>
- /// <param name="val"> The value of the array element </param>
- /// <param name="diffVal"> The different value of the single element </param>
- /// <returns> The array created </returns>
- public static T[] singleDiff<T>(int size, int pos, T val, T diffVal) {
- T[] a = idarr<T>(val, size);
- a[pos] = diffVal;
- return a;
- } // end of singleDiff<T>()
-
- /// <summary>
- /// Evaluates the dot product of two integer arrays
- /// </summary>
- /// <param name="a1"> The first array </param>
- /// <param name="a2"> The second array </param>
- /// <returns> The dot product of two arrays </returns>
- public static int dot(int[] a1, int[] a2) {
- int n = a1.Length;
- if(a2.Length != n)
- throw new ArgumentException();
- int r = 0;
- for(int i = 0; i < n; i++)
- r += a1[i] * a2[i];
- return r;
- } // end of dot()
-
- /// <summary>
- /// Assigns values of <paramref name="src"/> to <paramref name="tgt"/>,
- /// so that each element of <paramref name="src"/> is assigned to the
- /// <paramref name="inds"/> position with respective index of
- /// <paramref name="tgt"/>. If there are several candidates to the
- /// same position, any of them can be assigned.
- /// </summary>
- /// <typeparam name="T"> The type of the array </typeparam>
- /// <param name="tgt"> The target array </param>
- /// <param name="src"> The source array </param>
- /// <param name="inds"> The indices at which to assign </param>
- public static void arrass<T>(T[] tgt, T[] src, int[] inds) {
- int n = src.Length;
- if(inds.Length != n)
- throw new ArgumentException("Source and indices lengths do not match");
- for(int i = 0; i < n; i++) tgt[inds[i]] = src[i];
- } // end of arrass<T>
-
- /// <summary>
- /// Removes duplicates in the array
- /// </summary>
- /// <param name="arr"> The array from which to remove duplicates </param>
- /// <returns> The array with all duplicates removed </returns>
- public static T[] removeDups<T>(T[] arr) {
- List<T> l = new List<T>();
- Set<T> s = new Set<T>();
- foreach(T t in arr)
- if(!s.Contains(t)) {
- s.Add(t);
- l.Add(t);
- } // end of if()
- return l.ToArray();
- } // end of removeDups()
-
- /// <summary>
- /// Gets the indices of objects of <paramref name="arr2"/> with which
- /// they are present in <paramref name="arr1"/>
- /// </summary>
- /// <typeparam name="T"> The array type </typeparam>
- /// <param name="arr1"> The first array </param>
- /// <param name="arr2"> The second array </param>
- /// <returns> The array of indices </returns>
- public static int[] indicesOf<T>(T[] arr1, T[] arr2) {
- int n = arr2.Length;
- int[] inds = new int[n];
- for(int i = 0; i < n; i++)
- inds[i] = Array.IndexOf<T>(arr1, arr2[i]);
- return inds;
- } // end of indicesOf<T>
-
- /// <summary>
- /// Reverses the given array
- /// </summary>
- /// <typeparam name="T"> The type of the array to reverse </typeparam>
- /// <param name="arr"> The array to reverse </param>
- /// <returns> The reversed array </returns>
- /// <remarks> Reversing a null array returns null. </remarks>
- public static T[] reverse<T>(T[] arr) {
- if(null == arr)
- return null;
- int n = arr.Length;
- T[] arr2 = new T[n];
- for(int i = 0; i < n; i++)
- arr2[i] = arr[n - i - 1];
- return arr2;
- } // end of reverse<T>()
-
- } // end of class ArrOps
- }