/// <summary>Get a element of the table.</summary> /// <param name="row">The row desired.</param> /// <param name="col">The column desired.</param> /// <returns> A primitive array containing the information. Note /// that an array will be returned even if the element /// is a scalar.</returns> public virtual Object GetElement(int row, int col) { Array x = ArrayFuncs.NewInstance(bases[col], sizes[col]); Array.Copy((Array)arrays[col], sizes[col] * row, x, 0, sizes[col]); return(x); }
/// <summary>Add a row to the table. This method is very inefficient /// for adding multiple rows and should be avoided if possible. /// </summary> public virtual void AddRow(Object[] row) { if (arrays.Length == 0) { for (int i = 0; i < row.Length; i += 1) { AddColumn((Array)row[i], ((Array)row[i]).Length); } } else { if (row.Length != arrays.Length) { throw new TableException("Row length mismatch"); } for (int i = 0; i < row.Length; i += 1) { if (row[i].GetType() != arrays[i].GetType() || ((Array)row[i]).Length != sizes[i]) { throw new TableException("Row column mismatch at column:" + i); } Object xarray = ArrayFuncs.NewInstance(bases[i], (nrow + 1) * sizes[i]); Array.Copy((Array)arrays[i], 0, (Array)xarray, 0, nrow * sizes[i]); Array.Copy((Array)row[i], 0, (Array)xarray, nrow * sizes[i], sizes[i]); arrays[i] = xarray; } InitializePointers(); nrow += 1; } }
// suggested in .99.1 version: /// Delete a contiguous set of rows from the table. /// <param name="row">The row (0-indexed) to be deleted.</param> /// <param name="length">The number of rows to be deleted.</param> /// <exception cref="TableException"> TableException Thrown when the new data /// is not of the same type as the data it replaces.</exception> public void DeleteRows(int row, int length) { if (row < 0 || length < 0 || row + length > nrow) { throw new TableException("Invalid request to delete rows start: " + row + " length:" + length + " for table with " + nrow + " rows."); } if (length == 0) { return; } for (int col = 0; col < arrays.Length; col += 1) { int sz = sizes[col]; int newSize = sz * (nrow - length); Object newArr = ArrayFuncs.NewInstance(bases[col], newSize); // Copy whatever comes before the deletion Array.Copy((System.Array)arrays[col], 0, (System.Array)newArr, 0, row * sz); // Copy whatever comes after the deletion Array.Copy((System.Array)arrays[col], (row + length) * sz, (System.Array)newArr, row * sz, (nrow - row - length) * sz); arrays[col] = newArr; } nrow -= length; InitializePointers(); }
/// <summary>Create an array of a type given by new type with /// the dimensionality given in array.</summary> /// <param name="array">A possibly multidimensional array to be converted.</param> /// <param name="newType">The desired output type. This should be one of the /// class descriptors for primitive numeric data, e.g., double.type.</param> public static System.Object MimicArray(System.Object array, System.Type newType) { if (array == null || !array.GetType().IsArray) { return(null); } int dims = array.GetType().GetArrayRank(); Object mimic; if (dims > 1) { Object[] xarray = (Object[])array; int[] dimens = new int[dims]; dimens[0] = xarray.Length; // Leave other dimensions at 0. mimic = ArrayFuncs.NewInstance(newType, dimens); for (int i = 0; i < xarray.Length; i += 1) { System.Object temp = MimicArray(xarray[i], newType); ((System.Object[])mimic)[i] = temp; } } else { mimic = ArrayFuncs.NewInstance(newType, GetDimensions(array)); } return(mimic); }
/// <summary>Try to create a deep clone of an Array or a standard clone of a scalar. /// The object may comprise arrays of any primitive type or any Object type which /// implements Cloneable. However, if the Object is some kind of collection, /// e.g., a Vector then only a shallow copy of that object is made. I.e., deep /// refers only to arrays. /// </summary> /// <param name="o">The object to be copied.</param> /*TODO: If multidimension array is passed as an input, it is getting flattened out * TODO: For normal multidimension, we get an error because NewInstance always returns Jagged array.*/ public static System.Object DeepClone(System.Object o) { if (o == null) { return(null); } if (!o.GetType().IsArray) { return(GenericClone(o)); } Array a = (Array)o; if (ArrayFuncs.IsArrayOfArrays(o)) { Array result = NewInstance(o.GetType().GetElementType(), a.Length); for (int i = 0; i < result.Length; ++i) { result.SetValue(DeepClone(a.GetValue(i)), i); } return(result); } else { int[] lengths = new int[a.Rank]; for (int i = 0; i < lengths.Length; ++i) { lengths[i] = a.GetLength(i); } Array result = ArrayFuncs.NewInstance(o.GetType().GetElementType(), lengths); Array.Copy(a, result, a.Length); return(result); } return(null); }
public void TestArrayFuncs() { // Check GetBaseClass(), GetBaseLength() and ComputeSize() methods int[,,] test1 = new int[10, 9, 8]; bool[][] test2 = new bool[4][]; test2[0] = new bool[5]; test2[1] = new bool[4]; test2[2] = new bool[3]; test2[3] = new bool[2]; double[,] test3 = new double[10, 20]; System.Text.StringBuilder[,] test4 = new System.Text.StringBuilder[3, 2]; Assert.AreEqual(typeof(int), ArrayFuncs.GetBaseClass(test1)); Assert.AreEqual(4, ArrayFuncs.GetBaseLength(test1)); Assert.AreEqual(4 * 8 * 9 * 10, ArrayFuncs.ComputeSize(test1)); Assert.AreEqual(typeof(bool), ArrayFuncs.GetBaseClass(test2)); Assert.AreEqual(1, ArrayFuncs.GetBaseLength(test2)); Assert.AreEqual(1 * (2 + 3 + 4 + 5), ArrayFuncs.ComputeSize(test2)); Assert.AreEqual(typeof(double), ArrayFuncs.GetBaseClass(test3)); Assert.AreEqual(8, ArrayFuncs.GetBaseLength(test3)); Assert.AreEqual(8 * 10 * 20, ArrayFuncs.ComputeSize(test3)); Assert.AreEqual(typeof(System.Text.StringBuilder), ArrayFuncs.GetBaseClass(test4)); Assert.AreEqual(-1, ArrayFuncs.GetBaseLength(test4)); Assert.AreEqual(0, ArrayFuncs.ComputeSize(test4)); Object[] agg = new Object[4]; agg[0] = test1; agg[1] = test2; agg[2] = test3; agg[3] = test4; Assert.AreEqual(typeof(Object), ArrayFuncs.GetBaseClass(agg)); Assert.AreEqual(-1, ArrayFuncs.GetBaseLength(agg)); // Add up all the primitive arrays and ignore the objects. Assert.AreEqual(2880 + 14 + 1600 + 0, ArrayFuncs.ComputeSize(agg)); for (int i = 0; i < ((Array)test1).GetLength(0); i += 1) { for (int j = 0; j < ((Array)test1).GetLength(1); j += 1) { for (int k = 0; k < ((Array)test1).GetLength(2); k += 1) { test1[i, j, k] = i + j + k; } } } /* * // Check DeepClone() method: Does not work for multi-dimension Array. * int[,,] test5 = (int[,,]) ArrayFuncs.DeepClone(test1); * * Assert.AreEqual("deepClone()", true, ArrayFuncs.ArrayEquals(test1, test5)); * test5[1,1,1] = -3; * Assert.AreEqual("arrayEquals()", false, ArrayFuncs.ArrayEquals(test1, test5)); */ // Check Flatten() method int[] dimsOrig = ArrayFuncs.GetDimensions(test1); int[] test6 = (int[])ArrayFuncs.Flatten(test1); int[] dims = ArrayFuncs.GetDimensions(test6); Assert.AreEqual(3, dimsOrig.Length); Assert.AreEqual(10, dimsOrig[0]); Assert.AreEqual(9, dimsOrig[1]); Assert.AreEqual(8, dimsOrig[2]); Assert.AreEqual(1, dims.Length); // Check Curl method int[] newdims = { 8, 9, 10 }; Array[] test7 = (Array[])ArrayFuncs.Curl(test6, newdims); int[] dimsAfter = ArrayFuncs.GetDimensions(test7); Assert.AreEqual(3, dimsAfter.Length); Assert.AreEqual(8, dimsAfter[0]); Assert.AreEqual(9, dimsAfter[1]); Assert.AreEqual(10, dimsAfter[2]); /* * // Check Convert Array method: Implemented in Java Package * byte[,,] xtest1 = (byte[,,]) ArrayFuncs.convertArray(test1, typeof(byte)); * * Assert.AreEqual("convertArray(toByte)", typeof(byte), ArrayFuncs.GetBaseClass(xtest1)); * Assert.AreEqual("convertArray(tobyte)", test1[3,3,3], (int)xtest1[3,3,3]); * * double[,,] xtest2 = (double[,,]) ArrayFuncs.convertArray(test1, typeof(double)); * Assert.AreEqual("convertArray(toByte)", typeof(double), ArrayFuncs.GetBaseClass(xtest2)); * Assert.AreEqual("convertArray(tobyte)", test1[3,3,3], (int)xtest2[3,3,3]); */ // Check NewInstance method int[] xtest3 = (int[])ArrayFuncs.NewInstance(typeof(int), 20); int[] xtd = ArrayFuncs.GetDimensions(xtest3); Assert.AreEqual(1, xtd.Length); Assert.AreEqual(20, xtd[0]); Array[] xtest4 = (Array[])ArrayFuncs.NewInstance(typeof(double), new int[] { 5, 4, 3, 2 }); xtd = ArrayFuncs.GetDimensions(xtest4); Assert.AreEqual(4, xtd.Length); Assert.AreEqual(5, xtd[0]); Assert.AreEqual(4, xtd[1]); Assert.AreEqual(3, xtd[2]); Assert.AreEqual(2, xtd[3]); Assert.AreEqual(120, ArrayFuncs.CountElements(xtest4)); /* * // Check TestPattern method: Implemented in Java package, not in C#. * ArrayFuncs.TestPattern(xtest4, (byte)-1); * * Assert.AreEqual("testPattern()", (double) -1, xtest4[0,0,0,0]); * Assert.AreEqual("testPattern()", (double) 118, xtest4[4,3,2,1]); * double[] xtest4x = (double[])ArrayFuncs.GetBaseArray(xtest4); * * Assert.AreEqual("getBaseArray()", 2, xtest4x.Length); */ // Check ArrayEquals method double[] x = { 1, 2, 3, 4, 5 }; double[] y = new double[x.Length]; for (int i = 0; i < y.Length; i += 1) { y[i] = x[i] + 1E-10; } Assert.AreEqual(false, ArrayFuncs.ArrayEquals(x, y)); Assert.AreEqual(true, ArrayFuncs.ArrayEquals(x, y, 0d, 1e-9)); Assert.AreEqual(true, ArrayFuncs.ArrayEquals(x, y, 1E-5, 1e-9)); Assert.AreEqual(false, ArrayFuncs.ArrayEquals(x, y, 0d, 1e-11)); Assert.AreEqual(false, ArrayFuncs.ArrayEquals(x, y, 1E-5, 0d)); float[] fx = { 1, 2, 3, 4, 5 }; float[] fy = new float[fx.Length]; for (int i = 0; i < fy.Length; i += 1) { fy[i] = fx[i] + 1E-5F; } Assert.AreEqual(false, ArrayFuncs.ArrayEquals(fx, fy)); Assert.AreEqual(true, ArrayFuncs.ArrayEquals(fx, fy, 1E-4, 0d)); Assert.AreEqual(false, ArrayFuncs.ArrayEquals(fx, fy, 1E-6, 0d)); Assert.AreEqual(false, ArrayFuncs.ArrayEquals(fx, fy, 0d, 0d)); Assert.AreEqual(false, ArrayFuncs.ArrayEquals(fx, fy, 0d, 1E-4)); }