/*!HC:TYPELIST: * <hycalper> * <type> * <source locate="after"> * inArr1 * </source> * <destination>byte</destination> * <destination>complex</destination> * <destination>complex</destination> * <destination>double</destination> * </type> * <type> * <source locate="after"> * inCls1 * </source> * <destination><![CDATA[ILArray<byte>]]></destination> * <destination><![CDATA[ILArray<complex>]]></destination> * <destination><![CDATA[ILArray<complex>]]></destination> * <destination><![CDATA[ILArray<double>]]></destination> * </type> * <type> * <source locate="after"> * outCls1 * </source> * <destination><![CDATA[ILArray<byte>]]></destination> * <destination><![CDATA[ILArray<complex>]]></destination> * <destination><![CDATA[ILArray<double>]]></destination> * <destination><![CDATA[ILArray<complex>]]></destination> * </type> * <type> * <source locate="after"> * outArr1 * </source> * <destination>byte</destination> * <destination>complex</destination> * <destination>double</destination> * <destination>complex</destination> * </type> * <type> * <source locate="after"> * delegate_unary * </source> * <destination>ILByteFunctionByte</destination> * <destination>ILComplexFunctionComplex</destination> * <destination>ILDoubleFunctionComplex</destination> * <destination>ILComplexFunctionDouble</destination> * </type> * <type> * <source locate="after"> * unaryop * </source> * <destination>ByteOperatorByte</destination> * <destination>ComplexOperatorComplex</destination> * <destination>DoubleOperatorComplex</destination> * <destination>ComplexOperatorDouble</destination> * </type> * </hycalper> */ /// <summary> /// Applys the function (delegate) given to all elements of the storage /// </summary> /// <param name="inArray">storage array to apply the function to</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns>new <![CDATA[ /*!HC:outCls1*/ ILArray<double> ]]> with result of operation</returns> /// <remarks> the values of inArray will not be altered.</remarks> private static /*!HC:outCls1*/ ILArray <double> /*!HC:unaryop*/ DoubleOperatorDouble(/*!HC:inCls1*/ ILArray <double> inArray, /*!HC:delegate_unary*/ ILDoubleFunctionDouble operation) { ILDimension inDim = inArray.Dimensions; /*!HC:outArr1*/ double [] retDblArr; // build ILDimension int newLength = inDim.NumberOfElements; retDblArr = new /*!HC:outArr1*/ double [newLength]; int leadDimLen = inDim [0]; unsafe { fixed(/*!HC:outArr1*/ double *pOutArr = retDblArr) fixed(/*!HC:inArr1*/ double *pInArr = inArray.m_data) { /*!HC:outArr1*/ double *lastElement = pOutArr + retDblArr.Length; /*!HC:outArr1*/ double *tmpOut = pOutArr; /*!HC:inArr1*/ double * tmpIn = pInArr; while (tmpOut < lastElement) { *tmpOut++ = operation(*tmpIn++); } } } return(new /*!HC:outCls1*/ ILArray <double> (retDblArr, inDim.ToIntArray())); }
/// <summary> /// imaginary part of complex array elements /// </summary> /// <param name="X">complex input array</param> /// <returns>imaginary part of complex array</returns> public static /*!HC:outCls1*/ ILArray<double> imag (/*!HC:inCls1*/ ILArray<complex> X) { int nrX = X.m_dimensions.NumberOfElements; /*!HC:outArr1*/ double [] retArr = new /*!HC:outArr1*/ double [nrX]; /*!HC:outCls1*/ ILArray<double> ret = new /*!HC:outCls1*/ ILArray<double> (retArr,X.m_dimensions); for (int i= 0; i < nrX; i++) { retArr[i] = X.GetValue(i).imag; } return ret; }
/// <summary> /// real part of complex array /// </summary> /// <param name="X">complex input array</param> /// <returns>real part of complex array</returns> public static /*!HC:outCls1*/ ILArray<double> real (/*!HC:inCls1*/ ILArray<complex> X) { int nrX = X.m_dimensions.NumberOfElements; /*!HC:outArr1*/ double [] retArr = new /*!HC:outArr1*/ double [nrX]; /*!HC:outCls1*/ ILArray<double> ret = new /*!HC:outCls1*/ ILArray<double> (retArr,X.m_dimensions); ILIterator</*!HC:inArr1*/ complex > it = X.CreateIterator(ILIteratorPositions.ILEnd,0); for (int i= 0; i < nrX; i++) { retArr[i] = it.Increment().real; } return ret; }
/// <summary> /// imaginary part of complex array elements /// </summary> /// <param name="X">complex input array</param> /// <returns>imaginary part of complex array</returns> public static /*!HC:outCls1*/ ILArray <double> imag(/*!HC:inCls1*/ ILArray <complex> X) { int nrX = X.m_dimensions.NumberOfElements; /*!HC:outArr1*/ double [] retArr = new /*!HC:outArr1*/ double [nrX]; /*!HC:outCls1*/ ILArray <double> ret = new /*!HC:outCls1*/ ILArray <double> (retArr, X.m_dimensions); for (int i = 0; i < nrX; i++) { retArr[i] = X.GetValue(i).imag; } return(ret); }
/// <summary> /// real part of complex array /// </summary> /// <param name="X">complex input array</param> /// <returns>real part of complex array</returns> public static /*!HC:outCls1*/ ILArray <double> real(/*!HC:inCls1*/ ILArray <complex> X) { int nrX = X.m_dimensions.NumberOfElements; /*!HC:outArr1*/ double [] retArr = new /*!HC:outArr1*/ double [nrX]; /*!HC:outCls1*/ ILArray <double> ret = new /*!HC:outCls1*/ ILArray <double> (retArr, X.m_dimensions); ILIterator </*!HC:inArr1*/ complex> it = X.CreateIterator(ILIteratorPositions.ILEnd, 0); for (int i = 0; i < nrX; i++) { retArr[i] = it.Increment().real; } return(ret); }
/*!HC:TYPELIST: * <hycalper> * <type> * <source locate="after"> * inArr1 * </source> * <destination>byte</destination> * <destination>complex</destination> * </type> * <type> * <source locate="after"> * inArr2 * </source> * <destination>byte</destination> * <destination>complex</destination> * </type> * <type> * <source locate="after"> * inCls1 * </source> * <destination><![CDATA[ILArray<byte>]]></destination> * <destination><![CDATA[ILArray<complex>]]></destination> * </type> * <type> * <source locate="after"> * inCls2 * </source> * <destination><![CDATA[ILArray<byte>]]></destination> * <destination><![CDATA[ILArray<complex>]]></destination> * </type> * <type> * <source locate="after"> * outCls1 * </source> * <destination><![CDATA[ILArray<byte>]]></destination> * <destination><![CDATA[ILArray<complex>]]></destination> * </type> * <type> * <source locate="after"> * outArr1 * </source> * <destination>byte</destination> * <destination>complex</destination> * </type> * <type> * <source locate="after"> * delegate_binary * </source> * <destination>ILByteFunctionByteByte</destination> * <destination>ILComplexFunctionComplexComplex</destination> * </type> * <type> * <source locate="after"> * hcfunctionName * </source> * <destination>ByteOperatorByteByte</destination> * <destination>ComplexOperatorComplexComplex</destination> * </type> * </hycalper> */ /// <summary> /// operate on elements of both storages by the given function -> relational operations /// </summary> /// <param name="inArray1">First storage array</param> /// <param name="inArray2">Second storage array</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns><![CDATA[ /*!HC:outCls1*/ ILArray<double> ]]> with result of operation for corresponding /// elements of both arrays.</returns> /// <remarks>The values of inArray1 nor inArray2 will not be altered.The dimensions /// of both arrays must match.</remarks> private static /*!HC:outCls1*/ ILArray <double> /*!HC:hcfunctionName*/ DoubleOperatorDoubleDouble(/*!HC:inCls1*/ ILArray <double> inArray1, /*!HC:inCls2*/ ILArray <double> inArray2, /*!HC:delegate_binary*/ ILDoubleFunctionDoubleDouble operation) { ILDimension inDim = inArray1.Dimensions; if (!inDim.IsSameSize(inArray2.Dimensions)) { throw new ILDimensionMismatchException(); } /*!HC:outArr1*/ double [] retSystemArr; // build ILDimension int newLength = inDim.NumberOfElements; retSystemArr = new /*!HC:outArr1*/ double [newLength]; int leadDimLen = inDim [0]; // physical -> pointer arithmetic unsafe { fixed(/*!HC:inArr1*/ double *pInArr1 = inArray1.m_data) fixed(/*!HC:inArr2*/ double *pInArr2 = inArray2.m_data) fixed(/*!HC:outArr1*/ double *pOutArr = retSystemArr) { /*!HC:outArr1*/ double *poutarr = pOutArr; /*!HC:outArr1*/ double *poutend = poutarr + newLength; /*!HC:inArr1*/ double * pIn1 = pInArr1; /*!HC:inArr2*/ double * pIn2 = pInArr2; while (poutarr < poutend) { *poutarr++ = operation(*pIn1++, *pIn2++); } } } return(new /*!HC:outCls1*/ ILArray <double> (retSystemArr, inDim.ToIntArray())); }
// DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! #endregion HYCALPER AUTO GENERATED CODE #region HYCALPER LOOPSTART Matrix_multiply /*!HC:TYPELIST: * <hycalper> * <type> * <source locate="after"> * inArr1 * </source> * <destination>complex</destination> * </type> * <type> * <source locate="after"> * inArr2 * </source> * <destination>complex</destination> * </type> * <type> * <source locate="after"> * outArr1 * </source> * <destination>complex</destination> * </type> * <type> * <source locate="after"> * inCls1 * </source> * <destination><![CDATA[ILArray<complex>]]></destination> * </type> * <type> * <source locate="after"> * inCls2 * </source> * <destination><![CDATA[ILArray<complex>]]></destination> * </type> * <type> * <source locate="after"> * outCls1 * </source> * <destination><![CDATA[ILArray<complex>]]></destination> * </type> * <type> * <source locate="after"> * lapackfunc * </source> * <destination>Lapack.zgemm</destination> * </type> * </hycalper> */ /// <summary> /// GEneral Matrix Multiply this array /// </summary> /// <overloads>General Matrix Multiply for double, float, complex and fcomplex arrays</overloads> /// <param name="A"><![CDATA[ILArray<>]]> matrix A</param> /// <param name="B"><![CDATA[ILArray<>]]> matrix B</param> /// <returns><![CDATA[ILArray<double>]]> new array - result of matrix multiplication</returns> /// <remarks>Both arrays must be matrices. The matrix will be multiplied only /// if dimensions match accordingly. Therefore B's number of rows must /// equal A's number of columns. An Exception will be thrown otherwise. /// The multiplication will carried out on BLAS libraries, if availiable and the /// storage memory structure meets BLAS's requirements. If not it will be done inside .NET's /// framework 'by hand'. This is especially true for referencing storages with /// irregular dimensions. However, even GEMM on those reference storages linking into /// a physical storage can (an will) be carried out via BLAS dll's, if the spacing /// into dimensions matches the requirements of BLAS. Those are: /// <list> /// <item>the elements of one dimension will be adjecently layed out, and</item> /// <item>the elements of the second dimension must be regular (evenly) spaced</item> /// </list> /// <para>For reference arrays where the spacing between adjecent elements do not meet the /// requirements above, the matrix multiplication will be made without optimization and /// therefore suffer from low performance in relation to solid arrays. See <a href="http://ilnumerics.net?site=5142">online documentation: referencing for ILNumerics.Net</a></para> /// </remarks> /// <exception cref="ILNumerics.Exceptions.ILArgumentSizeException">if at least one arrays is not a matrix</exception> /// <exception cref="ILNumerics.Exceptions.ILDimensionMismatchException">if the size of both matrices do not match</exception> public static /*!HC:outCls1*/ ILArray <double> multiply(/*!HC:inCls1*/ ILArray <double> A, /*!HC:inCls2*/ ILArray <double> B) { /*!HC:outCls1*/ ILArray <double> ret = null; if (A.Dimensions.NumberOfDimensions != 2 || B.Dimensions.NumberOfDimensions != 2) { throw new ILArgumentSizeException("Matrix multiply: arguments must be 2-d."); } if (A.Dimensions[1] != B.Dimensions[0]) { throw new ILDimensionMismatchException("Matrix multiply: inner matrix dimensions must match."); } // decide wich method to use // test auf Regelmigkeit der Dimensionen int spacingA0; int spacingA1; int spacingB0; int spacingB1; char transA, transB; /*!HC:inArr1*/ double [] retArr = null; isSuitableForLapack(A, B, out spacingA0, out spacingA1, out spacingB0, out spacingB1, out transA, out transB); if (A.m_dimensions.NumberOfElements > ILAtlasMinimumElementSize || B.m_dimensions.NumberOfElements > ILAtlasMinimumElementSize) { // do BLAS GEMM retArr = new /*!HC:inArr1*/ double [A.m_dimensions[0] * B.m_dimensions[1]]; if (((spacingA0 == 1 && spacingA1 > int.MinValue) || (spacingA1 == 1 && spacingA0 > int.MinValue)) && ((spacingB0 == 1 && spacingB1 > int.MinValue) || (spacingB1 == 1 && spacingB0 > int.MinValue))) { ret = new /*!HC:outCls1*/ ILArray <double> (retArr, new ILDimension(A.m_dimensions[0], B.m_dimensions[1])); if (transA == 't') { spacingA1 = spacingA0; } if (transB == 't') { spacingB1 = spacingB0; } unsafe { fixed(/*!HC:outArr1*/ double *ptrC = retArr) fixed(/*!HC:inArr1*/ double *pA = A.m_data) fixed(/*!HC:inArr2*/ double *pB = B.m_data) { /*!HC:inArr1*/ double *ptrA = pA + A.getBaseIndex(0); /*!HC:inArr2*/ double *ptrB = pB + B.getBaseIndex(0); if (transA == 't') { spacingA1 = spacingA0; } if (transB == 't') { spacingB1 = spacingB0; } /*!HC:lapackfunc*/ Lapack.dgemm(transA, transB, A.m_dimensions[0], B.m_dimensions[1], A.m_dimensions[1], (/*!HC:inArr1*/ double )1.0, (IntPtr)ptrA, spacingA1, (IntPtr)ptrB, spacingB1, (/*!HC:inArr1*/ double )1.0, retArr, A.m_dimensions[0]); } } return(ret); } } // do GEMM by hand retArr = new /*!HC:outArr1*/ double [A.m_dimensions[0] * B.m_dimensions[1]]; ret = new /*!HC:outCls1*/ ILArray <double> (retArr, A.m_dimensions[0], B.m_dimensions[1]); unsafe { int in2Len1 = B.m_dimensions[1]; int in1Len0 = A.m_dimensions[0]; int in1Len1 = A.m_dimensions[1]; fixed(/*!HC:outArr1*/ double *ptrC = retArr) { /*!HC:outArr1*/ double *pC = ptrC; for (int c = 0; c < in2Len1; c++) { for (int r = 0; r < in1Len0; r++) { for (int n = 0; n < in1Len1; n++) { *pC += A.GetValue(r, n) * B.GetValue(n, c); } pC++; } } } } return(ret); }
/*!HC:TYPELIST: <hycalper> <type> <source locate="after"> inArr1 </source> <destination>byte</destination> <destination>char</destination> <destination>complex</destination> <destination>fcomplex</destination> <destination>float</destination> <destination>Int16</destination> <destination>Int32</destination> <destination>Int64</destination> <destination>UInt16</destination> <destination>UInt32</destination> <destination>UInt64</destination> </type> <type> <source locate="after"> inArr2 </source> <destination>byte</destination> <destination>char</destination> <destination>complex</destination> <destination>fcomplex</destination> <destination>float</destination> <destination>Int16</destination> <destination>Int32</destination> <destination>Int64</destination> <destination>UInt16</destination> <destination>UInt32</destination> <destination>UInt64</destination> </type> <type> <source locate="after"> inCls1 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<char>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<fcomplex>]]></destination> <destination><![CDATA[ILArray<float>]]></destination> <destination><![CDATA[ILArray<Int16>]]></destination> <destination><![CDATA[ILArray<Int32>]]></destination> <destination><![CDATA[ILArray<Int64>]]></destination> <destination><![CDATA[ILArray<UInt16>]]></destination> <destination><![CDATA[ILArray<UInt32>]]></destination> <destination><![CDATA[ILArray<UInt64>]]></destination> </type> <type> <source locate="after"> inCls2 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<char>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<fcomplex>]]></destination> <destination><![CDATA[ILArray<float>]]></destination> <destination><![CDATA[ILArray<Int16>]]></destination> <destination><![CDATA[ILArray<Int32>]]></destination> <destination><![CDATA[ILArray<Int64>]]></destination> <destination><![CDATA[ILArray<UInt16>]]></destination> <destination><![CDATA[ILArray<UInt32>]]></destination> <destination><![CDATA[ILArray<UInt64>]]></destination> </type> <type> <source locate="after"> outCls1 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<char>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<fcomplex>]]></destination> <destination><![CDATA[ILArray<float>]]></destination> <destination><![CDATA[ILArray<Int16>]]></destination> <destination><![CDATA[ILArray<Int32>]]></destination> <destination><![CDATA[ILArray<Int64>]]></destination> <destination><![CDATA[ILArray<UInt16>]]></destination> <destination><![CDATA[ILArray<UInt32>]]></destination> <destination><![CDATA[ILArray<UInt64>]]></destination> </type> <type> <source locate="after"> outArr1 </source> <destination>byte</destination> <destination>char</destination> <destination>complex</destination> <destination>fcomplex</destination> <destination>float</destination> <destination>Int16</destination> <destination>Int32</destination> <destination>Int64</destination> <destination>UInt16</destination> <destination>UInt32</destination> <destination>UInt64</destination> </type> <type> <source locate="after"> delegate_binary </source> <destination>ILByteFunctionByteByte</destination> <destination>ILCharFunctionCharChar</destination> <destination>ILComplexFunctionComplexComplex</destination> <destination>ILFcomplexFunctionFcomplexFcomplex</destination> <destination>ILFloatFunctionFloatFloat</destination> <destination>ILInt16FunctionInt16Int16</destination> <destination>ILInt32FunctionInt32Int32</destination> <destination>ILInt64FunctionInt64Int64</destination> <destination>ILUInt16FunctionUInt16UInt16</destination> <destination>ILUInt32FunctionUInt32UInt32</destination> <destination>ILUInt64FunctionUInt64UInt64</destination> </type> <type> <source locate="after"> hcfunctionName </source> <destination>ByteOperatorByteByte</destination> <destination>CharOperatorCharChar</destination> <destination>ComplexOperatorComplexComplex</destination> <destination>FcomplexOperatorFcomplexFcomplex</destination> <destination>FloatOperatorFloatFloat</destination> <destination>Int16OperatorInt16Int16</destination> <destination>Int32OperatorInt32Int32</destination> <destination>Int64OperatorInt64Int64</destination> <destination>UInt16OperatorUInt16UInt16</destination> <destination>UInt32OperatorUInt32UInt32</destination> <destination>UInt64OperatorUInt64UInt64</destination> </type> </hycalper> */ /// <summary> /// operate on elements of both storages by the given function -> relational operations /// </summary> /// <param name="inArray1">First storage array</param> /// <param name="inArray2">Second storage array</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns><![CDATA[ /*!HC:outCls1*/ ILArray<double> ]]> with result of operation for corresponding /// elements of both arrays.</returns> /// <remarks>The values of inArray1 nor inArray2 will not be altered.The dimensions /// of both arrays must match.</remarks> private static /*!HC:outCls1*/ ILArray<double> /*!HC:hcfunctionName*/ DoubleOperatorDoubleDouble (/*!HC:inCls1*/ ILArray<double> inArray1,/*!HC:inCls2*/ ILArray<double> inArray2, /*!HC:delegate_binary*/ ILDoubleFunctionDoubleDouble operation) { ILDimension inDim = inArray1.Dimensions; if (!inDim.IsSameSize ( inArray2.Dimensions )) throw new ILDimensionMismatchException (); /*!HC:outArr1*/ double [] retSystemArr; // build ILDimension int newLength = inDim.NumberOfElements; retSystemArr = new /*!HC:outArr1*/ double [newLength]; int leadDim = 0; int leadDimLen = inDim [0]; if (inArray1.IsReference || inArray2.IsReference) { // this will most probably be not very fast, but .... :| #region Reference storage // walk along the longest dimension (for performance reasons) for (int i = 1; i < inDim.NumberOfDimensions; i++) { if (leadDimLen < inDim [i]) { leadDimLen = inDim [i]; leadDim = i; } } unsafe { fixed (/*!HC:outArr1*/ double * pOutArr = retSystemArr) fixed (/*!HC:inArr1*/ double * inA1 = inArray1.m_data) fixed (/*!HC:inArr2*/ double * inA2 = inArray2.m_data) { /*!HC:inArr1*/ double * pInA1 = inA1; /*!HC:inArr2*/ double * pInA2 = inA2; int c = 0; /*!HC:outArr1*/ double * poutarr = pOutArr; /*!HC:outArr1*/ double * outEnd = poutarr + newLength; if (inArray1.IsReference && !inArray2.IsReference) while (poutarr < outEnd) { *poutarr++ = operation ( *(pInA1 + inArray1.getBaseIndex(c++)), *pInA2++); } else if (!inArray1.IsReference && inArray2.IsReference) while (poutarr < outEnd) { *poutarr++ = operation ( *pInA1++, *(pInA2 + inArray2.getBaseIndex(c++))); } else if (!inArray1.IsReference && !inArray2.IsReference) while (poutarr < outEnd) { *poutarr++ = operation ( *pInA1++, *pInA2++); } else if (inArray1.IsReference && inArray2.IsReference) if (inArray1.Dimensions.NumberOfDimensions < 3 && inArray2.Dimensions.NumberOfDimensions < 3) { fixed (int * pA1idx0 = inArray1.m_indexOffset[0]) fixed (int * pA1idx1 = inArray1.m_indexOffset[1]) fixed (int * pA2idx0 = inArray2.m_indexOffset[0]) fixed (int * pA2idx1 = inArray2.m_indexOffset[1]) { int r = 0, rLen = inArray1.m_dimensions[0]; int cLen = inArray1.m_dimensions[1]; while (poutarr < outEnd) { *poutarr++ = operation ( *(pInA1 + *(pA1idx0 + r) + *(pA1idx1 + c)), *(pInA2+ *(pA2idx0 + r) + *(pA2idx1 + c))); if (++r == rLen) { r = 0; c++; } } } } else { while (poutarr < outEnd) { *poutarr++ = operation ( *(pInA1 + inArray1.getBaseIndex(c)), *(pInA2+inArray2.getBaseIndex(c++))); } } } } // ============================================================== #endregion } else { // physical -> pointer arithmetic #region physical storage unsafe { fixed (/*!HC:inArr1*/ double * pInArr1 = inArray1.m_data) fixed (/*!HC:inArr2*/ double * pInArr2 = inArray2.m_data) fixed (/*!HC:outArr1*/ double * pOutArr = retSystemArr) { /*!HC:outArr1*/ double * poutarr = pOutArr; /*!HC:outArr1*/ double * poutend = poutarr + newLength; /*!HC:inArr1*/ double * pIn1 = pInArr1; /*!HC:inArr2*/ double * pIn2 = pInArr2; while (poutarr < poutend) *poutarr++ = operation ( *pIn1++, *pIn2++ ); } } #endregion } return new /*!HC:outCls1*/ ILArray<double> ( retSystemArr, inDim.ToIntArray () ); }
/*!HC:TYPELIST: <hycalper> <type> <source locate="after"> inArr1 </source> <destination>byte</destination> <destination>char</destination> <destination>complex</destination> <destination>fcomplex</destination> <destination>float</destination> <destination>Int16</destination> <destination>Int32</destination> <destination>Int64</destination> <destination>UInt16</destination> <destination>UInt32</destination> <destination>UInt64</destination> <destination>complex</destination> <destination>fcomplex</destination> <destination>double</destination> <destination>float</destination> </type> <type> <source locate="after"> inCls1 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<char>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<fcomplex>]]></destination> <destination><![CDATA[ILArray<float>]]></destination> <destination><![CDATA[ILArray<Int16>]]></destination> <destination><![CDATA[ILArray<Int32>]]></destination> <destination><![CDATA[ILArray<Int64>]]></destination> <destination><![CDATA[ILArray<UInt16>]]></destination> <destination><![CDATA[ILArray<UInt32>]]></destination> <destination><![CDATA[ILArray<UInt64>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<fcomplex>]]></destination> <destination><![CDATA[ILArray<double>]]></destination> <destination><![CDATA[ILArray<float>]]></destination> </type> <type> <source locate="after"> outCls1 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<char>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<fcomplex>]]></destination> <destination><![CDATA[ILArray<float>]]></destination> <destination><![CDATA[ILArray<Int16>]]></destination> <destination><![CDATA[ILArray<Int32>]]></destination> <destination><![CDATA[ILArray<Int64>]]></destination> <destination><![CDATA[ILArray<UInt16>]]></destination> <destination><![CDATA[ILArray<UInt32>]]></destination> <destination><![CDATA[ILArray<UInt64>]]></destination> <destination><![CDATA[ILArray<double>]]></destination> <destination><![CDATA[ILArray<float>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<fcomplex>]]></destination> </type> <type> <source locate="after"> outArr1 </source> <destination>byte</destination> <destination>char</destination> <destination>complex</destination> <destination>fcomplex</destination> <destination>float</destination> <destination>Int16</destination> <destination>Int32</destination> <destination>Int64</destination> <destination>UInt16</destination> <destination>UInt32</destination> <destination>UInt64</destination> <destination>double</destination> <destination>float</destination> <destination>complex</destination> <destination>fcomplex</destination> </type> <type> <source locate="after"> delegate_unary </source> <destination>ILByteFunctionByte</destination> <destination>ILCharFunctionChar</destination> <destination>ILComplexFunctionComplex</destination> <destination>ILFcomplexFunctionFcomplex</destination> <destination>ILFloatFunctionFloat</destination> <destination>ILInt16FunctionInt16</destination> <destination>ILInt32FunctionInt32</destination> <destination>ILInt64FunctionInt64</destination> <destination>ILUInt16FunctionUInt16</destination> <destination>ILUInt32FunctionUInt32</destination> <destination>ILUInt64FunctionUInt64</destination> <destination>ILDoubleFunctionComplex</destination> <destination>ILFloatFunctionFcomplex</destination> <destination>ILComplexFunctionDouble</destination> <destination>ILFcomplexFunctionFloat</destination> </type> <type> <source locate="after"> unaryop </source> <destination>ByteOperatorByte</destination> <destination>CharOperatorChar</destination> <destination>ComplexOperatorComplex</destination> <destination>FcomplexOperatorFcomplex</destination> <destination>FloatOperatorFloat</destination> <destination>Int16OperatorInt16</destination> <destination>Int32OperatorInt32</destination> <destination>Int64OperatorInt64</destination> <destination>UInt16OperatorUInt16</destination> <destination>UInt32OperatorUInt32</destination> <destination>UInt64OperatorUInt64</destination> <destination>DoubleOperatorComplex</destination> <destination>FloatOperatorFcomplex</destination> <destination>ComplexOperatorDouble</destination> <destination>FcomplexOperatorFloat</destination> </type> </hycalper> */ /// <summary> /// Applys the function (delegate) given to all elements of the storage /// </summary> /// <param name="inArray">storage array to apply the function to</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns>new <![CDATA[ /*!HC:outCls1*/ ILArray<double> ]]> with result of operation</returns> /// <remarks> the values of inArray will not be altered.</remarks> private static /*!HC:outCls1*/ ILArray<double> /*!HC:unaryop*/ DoubleOperatorDouble (/*!HC:inCls1*/ ILArray<double> inArray, /*!HC:delegate_unary*/ ILDoubleFunctionDouble operation) { ILDimension inDim = inArray.Dimensions; /*!HC:outArr1*/ double [] retDblArr; // build ILDimension int newLength = inDim.NumberOfElements; retDblArr = new /*!HC:outArr1*/ double [newLength]; int leadDim = 0; int leadDimLen = inDim [0]; if (inArray.IsReference) { #region Reference storage // walk along the longest dimension (for performance reasons) for (int i = 1; i < inDim.NumberOfDimensions; i++) { if (leadDimLen < inDim [i]) { leadDimLen = inDim [i]; leadDim = i; } } ILIndexOffset idxOffset = inArray.m_indexOffset; int incOut = inDim.SequentialIndexDistance ( leadDim ); // ======================== REFERENCE double Storage =========== System.Diagnostics.Debug.Assert(!inArray.IsVector,"Reference arrays of vector size should not exist!"); if (inArray.IsMatrix) { #region Matrix //////////////////////////// MATRIX //////////////////// int secDim = ( leadDim + 1 ) % 2; unsafe { fixed (int* leadDimStart = idxOffset [leadDim], secDimStart = idxOffset [secDim]) { fixed (/*!HC:outArr1*/ double * pOutArr = retDblArr) fixed (/*!HC:inArr1*/ double * pInArr = inArray.m_data) { /*!HC:outArr1*/ double * tmpOut = pOutArr; /*!HC:inArr1*/ double * tmpIn = pInArr; /*!HC:outArr1*/ double * tmpOutEnd = pOutArr + inDim.NumberOfElements - 1; int* secDimEnd = secDimStart + idxOffset [secDim].Length; int* secDimIdx = secDimStart; int* leadDimIdx = leadDimStart; int* leadDimEnd = leadDimStart + leadDimLen; while (secDimIdx < secDimEnd) { if (tmpOut > tmpOutEnd) tmpOut = pOutArr + ( tmpOut - tmpOutEnd); tmpIn = pInArr + *secDimIdx++; leadDimIdx = leadDimStart; while (leadDimIdx < leadDimEnd) { *tmpOut = operation ( *( tmpIn + *leadDimIdx++ ) ); tmpOut += incOut; } } } } } #endregion } else { ///////////////////////////// ARBITRARY DIMENSIONS ////////// #region arbitrary size unsafe { int [] curPosition = new int [inArray.Dimensions.NumberOfDimensions]; fixed (int* leadDimStart = idxOffset [leadDim]) { fixed (/*!HC:outArr1*/ double * pOutArr = retDblArr) fixed (/*!HC:inArr1*/ double * pInArr = inArray.m_data) { /*!HC:outArr1*/ double * tmpOut = pOutArr; /*!HC:outArr1*/ double * tmpOutEnd = tmpOut + retDblArr.Length; // init lesezeiger: add alle Dimensionen mit 0 (auer leadDim) /*!HC:inArr1*/ double * tmpIn = pInArr + inArray.getBaseIndex ( 0, 0 ); tmpIn -= idxOffset [leadDim, 0]; int* leadDimIdx = leadDimStart; int* leadDimEnd = leadDimStart + leadDimLen; int dimLen = curPosition.Length; int d, curD; // start at first element while (tmpOut < tmpOutEnd) { leadDimIdx = leadDimStart; while (leadDimIdx < leadDimEnd) { *tmpOut = operation ( *( tmpIn + *leadDimIdx++ ) ); tmpOut += incOut; } if (tmpOut > tmpOutEnd) tmpOut = pOutArr + ( tmpOutEnd - tmpOut ); // increment higher dimensions d = 1; while (d < dimLen) { curD = ( d + leadDim ) % dimLen; tmpIn -= idxOffset [curD, curPosition [curD]]; curPosition [curD]++; if (curPosition [curD] < idxOffset [curD].Length) { tmpIn += idxOffset [curD, curPosition [curD]]; break; } curPosition [curD] = 0; tmpIn += idxOffset [curD, 0]; d++; } } } } } #endregion } // ============================================================== #endregion } else { // physical -> pointer arithmetic #region physical storage unsafe { fixed (/*!HC:outArr1*/ double * pOutArr = retDblArr) fixed (/*!HC:inArr1*/ double * pInArr = inArray.m_data) { /*!HC:outArr1*/ double * lastElement = pOutArr + retDblArr.Length; /*!HC:outArr1*/ double * tmpOut = pOutArr; /*!HC:inArr1*/ double * tmpIn = pInArr; while (tmpOut < lastElement) *tmpOut++ = operation ( *tmpIn++ ); } } #endregion } return new /*!HC:outCls1*/ ILArray<double> ( retDblArr, inDim.ToIntArray () ); }
/*!HC:TYPELIST: <hycalper> <type> <source locate="after"> inArr1 </source> <destination>byte</destination> <destination>complex</destination> <destination>complex</destination> <destination>double</destination> </type> <type> <source locate="after"> inCls1 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<double>]]></destination> </type> <type> <source locate="after"> outCls1 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> <destination><![CDATA[ILArray<double>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> </type> <type> <source locate="after"> outArr1 </source> <destination>byte</destination> <destination>complex</destination> <destination>double</destination> <destination>complex</destination> </type> <type> <source locate="after"> delegate_unary </source> <destination>ILByteFunctionByte</destination> <destination>ILComplexFunctionComplex</destination> <destination>ILDoubleFunctionComplex</destination> <destination>ILComplexFunctionDouble</destination> </type> <type> <source locate="after"> unaryop </source> <destination>ByteOperatorByte</destination> <destination>ComplexOperatorComplex</destination> <destination>DoubleOperatorComplex</destination> <destination>ComplexOperatorDouble</destination> </type> </hycalper> */ /// <summary> /// Applys the function (delegate) given to all elements of the storage /// </summary> /// <param name="inArray">storage array to apply the function to</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns>new <![CDATA[ /*!HC:outCls1*/ ILArray<double> ]]> with result of operation</returns> /// <remarks> the values of inArray will not be altered.</remarks> private static /*!HC:outCls1*/ ILArray<double> /*!HC:unaryop*/ DoubleOperatorDouble (/*!HC:inCls1*/ ILArray<double> inArray, /*!HC:delegate_unary*/ ILDoubleFunctionDouble operation) { ILDimension inDim = inArray.Dimensions; /*!HC:outArr1*/ double [] retDblArr; // build ILDimension int newLength = inDim.NumberOfElements; retDblArr = new /*!HC:outArr1*/ double [newLength]; int leadDimLen = inDim [0]; unsafe { fixed (/*!HC:outArr1*/ double * pOutArr = retDblArr) fixed (/*!HC:inArr1*/ double * pInArr = inArray.m_data) { /*!HC:outArr1*/ double * lastElement = pOutArr + retDblArr.Length; /*!HC:outArr1*/ double * tmpOut = pOutArr; /*!HC:inArr1*/ double * tmpIn = pInArr; while (tmpOut < lastElement) *tmpOut++ = operation ( *tmpIn++ ); } } return new /*!HC:outCls1*/ ILArray<double> ( retDblArr, inDim.ToIntArray () ); }
/*!HC:TYPELIST: <hycalper> <type> <source locate="after"> inArr1 </source> <destination>byte</destination> <destination>complex</destination> </type> <type> <source locate="after"> inArr2 </source> <destination>byte</destination> <destination>complex</destination> </type> <type> <source locate="after"> inCls1 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> </type> <type> <source locate="after"> inCls2 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> </type> <type> <source locate="after"> outCls1 </source> <destination><![CDATA[ILArray<byte>]]></destination> <destination><![CDATA[ILArray<complex>]]></destination> </type> <type> <source locate="after"> outArr1 </source> <destination>byte</destination> <destination>complex</destination> </type> <type> <source locate="after"> delegate_binary </source> <destination>ILByteFunctionByteByte</destination> <destination>ILComplexFunctionComplexComplex</destination> </type> <type> <source locate="after"> hcfunctionName </source> <destination>ByteOperatorByteByte</destination> <destination>ComplexOperatorComplexComplex</destination> </type> </hycalper> */ /// <summary> /// operate on elements of both storages by the given function -> relational operations /// </summary> /// <param name="inArray1">First storage array</param> /// <param name="inArray2">Second storage array</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns><![CDATA[ /*!HC:outCls1*/ ILArray<double> ]]> with result of operation for corresponding /// elements of both arrays.</returns> /// <remarks>The values of inArray1 nor inArray2 will not be altered.The dimensions /// of both arrays must match.</remarks> private static /*!HC:outCls1*/ ILArray<double> /*!HC:hcfunctionName*/ DoubleOperatorDoubleDouble (/*!HC:inCls1*/ ILArray<double> inArray1,/*!HC:inCls2*/ ILArray<double> inArray2, /*!HC:delegate_binary*/ ILDoubleFunctionDoubleDouble operation) { ILDimension inDim = inArray1.Dimensions; if (!inDim.IsSameSize ( inArray2.Dimensions )) throw new ILDimensionMismatchException (); /*!HC:outArr1*/ double [] retSystemArr; // build ILDimension int newLength = inDim.NumberOfElements; retSystemArr = new /*!HC:outArr1*/ double [newLength]; int leadDimLen = inDim [0]; // physical -> pointer arithmetic unsafe { fixed (/*!HC:inArr1*/ double * pInArr1 = inArray1.m_data) fixed (/*!HC:inArr2*/ double * pInArr2 = inArray2.m_data) fixed (/*!HC:outArr1*/ double * pOutArr = retSystemArr) { /*!HC:outArr1*/ double * poutarr = pOutArr; /*!HC:outArr1*/ double * poutend = poutarr + newLength; /*!HC:inArr1*/ double * pIn1 = pInArr1; /*!HC:inArr2*/ double * pIn2 = pInArr2; while (poutarr < poutend) *poutarr++ = operation ( *pIn1++, *pIn2++ ); } } return new /*!HC:outCls1*/ ILArray<double> ( retSystemArr, inDim.ToIntArray () ); }