/// <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); }
// 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); }