private void Test_isConj(ILArray <complex> A, ILArray <complex> conjA) { try { if (A.IsEmpty) { if (!conjA.IsEmpty) { throw new Exception("conj of empty array must be empty!"); } else { Success(); return; } } if (!A.Dimensions.IsSameSize(conjA.Dimensions)) { throw new Exception("dimensions must match!"); } if (ILMath.sumall(ILMath.real(A) != ILMath.real(conjA)) > 0.0) { throw new Exception("real parts must match!"); } if (ILMath.sumall(-ILMath.imag(A) != ILMath.imag(conjA)) > 0.0) { throw new Exception("imag parts must be the inverse of each other!"); } Success(); } catch (Exception exc) { Error(exc.Message); } }
/// <summary> /// Multidimensional scaling/PCoA: transform distances to points in a coordinate system. /// </summary> /// <param name="input">A matrix of pairwise distances. Zero indicates identical objects.</param> /// <returns>A matrix, the columns of which are coordinates in the nth dimension. /// The rows are in the same order as the input.</returns> public static ILArray <double> Scale(ILArray <double> input) { int n = input.Length; ILArray <double> p = ILMath.eye <double>(n, n) - ILMath.repmat(1.0 / n, n, n); ILArray <double> a = -.5 * ILMath.multiplyElem(input, input); ILArray <double> b = ILMath.multiply(p, a, p); ILArray <complex> V = ILMath.empty <complex>(); ILArray <complex> E = ILMath.eig((b + b.T) / 2, V); ILArray <int> i = ILMath.empty <int>(); ILArray <double> e = ILMath.sort(ILMath.diag(ILMath.real(E)), i); e = ILMath.flipud(e); i = ILMath.toint32(ILMath.flipud(ILMath.todouble(i))); ILArray <int> keep = ILMath.empty <int>(); for (int j = 0; j < e.Length; j++) { if (e[j] > 0.000000001) { keep.SetValue(j, keep.Length); } } ILArray <double> Y; if (ILMath.isempty(keep)) { Y = ILMath.zeros(n, 1); } else { Y = ILMath.zeros <double>(V.S[0], keep.Length); for (int j = 0; j < keep.Length; j++) { Y[ILMath.full, j] = ILMath.todouble(-V[ILMath.full, i[keep[j]]]); } Y = ILMath.multiply(Y, ILMath.diag(ILMath.sqrt(e[keep]))); } ILArray <int> maxind = ILMath.empty <int>(); ILMath.max(ILMath.abs(Y), maxind, 0); int d = Y.S[1]; ILArray <int> indices = maxind + ILMath.toint32(ILMath.array <int>(SteppedRange(0, n, (d - 1) * n))); ILArray <double> colsign = ILMath.sign(Y[indices]); for (int j = 0; j < Y.S[1]; j++) { Y[ILMath.full, j] = Y[ILMath.full, j] * colsign[j]; } return(Y); }
/*!HC:TYPELIST: * <hycalper> * <type> * <source locate="after"> * HCretArr * </source> * </type> * <type> * <source locate="after"> * HCinArr * </source> * </type> * <type> * <source locate="after"> * mklPrec * </source> * </type> * </hycalper> */ public ILArray </*!HC:HCretArr*/ double> FFTBackwSym(ILArray </*!HC:HCinArr*/ complex> A, int nDims) { return(ILMath.real(FFTBackward(A, nDims))); }
/*!HC:TYPELIST: * <hycalper> * <type> * <source locate="after"> * HCretArr * </source> * </type> * <type> * <source locate="after"> * inArr * </source> * </type> * </hycalper> */ public ILArray </*!HC:HCretArr*/ double> FFTBackwSym1D(ILArray </*!HC:inArr*/ complex> A, int dim) { return(ILMath.real(FFTBackward1D(A, dim))); }
public ILArray <double> FFTBackwSym(ILArray <complex> A, int nDims) { return(ILMath.real(FFTBackward(A, nDims))); }
public ILArray <double> FFTBackwSym1D(ILArray <complex> A, int dim) { return(ILMath.real(FFTBackward1D(A, dim))); }
/*!HC:TYPELIST: * <hycalper> * <type> * <source locate="after"> * HCretArr * </source> * </type> * <type> * <source locate="after"> * HCinArr * </source> * </type> * <type> * <source locate="after"> * mklPrec * </source> * </type> * </hycalper> */ public ILArray </*!HC:HCretArr*/ double> FFTBackwSym(ILArray </*!HC:HCinArr*/ complex> A, int nDims) { if (A == null || nDims <= 0) { throw new ILArgumentException("invalid argument!"); } if (A.IsEmpty) { return(ILArray </*!HC:HCretArr*/ double> .empty(A.Dimensions)); } if (A.IsScalar || (A.Dimensions[0] == 1 && nDims == 1)) { return(ILMath.real(A)); } if (nDims > A.Dimensions.NumberOfDimensions) { nDims = A.Dimensions.NumberOfDimensions; } // MKL currently does not handle more than 3 dimensions this way if (nDims > 3) { return(ILMath.real(FFTBackward(A, nDims))); } // prepare output array, if we query the memory directly from // memory pool, we prevent from clearing the elements since every // single one will be overwritten by fft anyway /*!HC:HCretArr*/ double [] retArr = ILMemoryPool.Pool.New </*!HC:HCretArr*/ double>(A.Dimensions.NumberOfElements); ILArray </*!HC:HCretArr*/ double> ret = new ILArray </*!HC:HCretArr*/ double>(retArr, A.Dimensions); IntPtr descriptor = IntPtr.Zero; int error = -1; int[] tmpDims = A.Dimensions.ToIntArray(nDims + 1); string hash = hashPlan(/*!HC:mklPrec*/ MKLValues.DOUBLE, MKLValues.REAL, nDims, tmpDims); // try to reuse existing descriptor lock (_lockobject) { if (!m_descriptors.TryGetValue(hash, out descriptor)) { error = MKLImports.DftiCreateDescriptor(ref descriptor, /*!HC:mklPrec*/ MKLValues.DOUBLE, MKLValues.REAL, nDims, tmpDims); if (isMKLError(error)) { throw new ILInvalidOperationException("error creating descriptor: " + MKLImports.DftiErrorMessage(error)); } m_descriptors[hash] = descriptor; } } // how many transformations ? int tmp = A.Dimensions.SequentialIndexDistance(nDims); MKLImports.DftiSetValue(descriptor, MKLParameter.NUMBER_OF_TRANSFORMS, __arglist(A.Dimensions.NumberOfElements / tmp)); MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_DISTANCE, __arglist(tmp)); MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_DISTANCE, __arglist(tmp)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.PLACEMENT, __arglist(MKLValues.NOT_INPLACE)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.REAL_STORAGE, __arglist(MKLValues.REAL_REAL)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.CONJUGATE_EVEN_STORAGE, __arglist(MKLValues.COMPLEX_COMPLEX)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.BACKWARD_SCALE, __arglist(1.0 / tmp)); // spacing between elements tmpDims[0] = 0; for (int i = 0; i < nDims; i++) { tmpDims[i + 1] = A.Dimensions.SequentialIndexDistance(i); } MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_STRIDES, __arglist(tmpDims)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_STRIDES, __arglist(tmpDims)); if (isMKLError(error)) { throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error)); } error = MKLImports.DftiCommitDescriptor(descriptor); if (isMKLError(error)) { throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error)); } // do the transform(s) unsafe { fixed(/*!HC:HCretArr*/ double *retArrP = ret.m_data) fixed(/*!HC:HCinArr*/ complex * inArr = A.m_data) { error = MKLImports.DftiComputeBackward(descriptor, __arglist(inArr, retArrP)); } } if (isMKLError(error)) { throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error)); } return(ret); }
/*!HC:TYPELIST: * <hycalper> * <type> * <source locate="after"> * HCretArr * </source> * </type> * <type> * <source locate="after"> * inArr * </source> * </type> * <type> * <source locate="after"> * mklPrec * </source> * </type> * </hycalper> */ public ILArray </*!HC:HCretArr*/ double> FFTBackwSym1D(ILArray </*!HC:inArr*/ complex> A, int dim) { if (A == null || dim < 0) { throw new ILArgumentException("invalid parameter!"); } if (A.IsEmpty) { return(ILArray </*!HC:HCretArr*/ double> .empty(A.Dimensions)); } if (A.IsScalar || A.Dimensions[dim] == 1) { return(ILMath.real(A)); } // prepare output array, if we query the memory directly from // memory pool, we prevent from clearing the elements since every // single one will be overwritten by fft anyway int error = 0, inDim = A.Dimensions[dim]; /*!HC:HCretArr*/ double [] retArr = ILMemoryPool.Pool.New </*!HC:HCretArr*/ double>(A.Dimensions.NumberOfElements); ILArray </*!HC:HCretArr*/ double> ret = new ILArray </*!HC:HCretArr*/ double>(retArr, A.Dimensions); string hash = hashPlan(/*!HC:mklPrec*/ MKLValues.DOUBLE, MKLValues.REAL, 1, inDim); IntPtr descriptor = IntPtr.Zero; // try to reuse existing descriptor lock (_lockobject) { if (!m_descriptors.TryGetValue(hash, out descriptor)) { error = MKLImports.DftiCreateDescriptor(ref descriptor, /*!HC:mklPrec*/ MKLValues.DOUBLE, MKLValues.REAL, 1, inDim); if (isMKLError(error)) { throw new ILInvalidOperationException("error creating descriptor: " + MKLImports.DftiErrorMessage(error)); } m_descriptors[hash] = descriptor; } } // spacing between elements int tmp = A.Dimensions.SequentialIndexDistance(dim); int[] stride = new int[] { 0, tmp }; MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_STRIDES, __arglist(stride)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_STRIDES, __arglist(stride)); if (isMKLError(error)) { throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error)); } // storage of subsequent transformations tmp = inDim * tmp; MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_DISTANCE, __arglist(tmp)); MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_DISTANCE, __arglist(tmp)); // how many transformations ? tmp = A.Dimensions.NumberOfElements / tmp; MKLImports.DftiSetValue(descriptor, MKLParameter.NUMBER_OF_TRANSFORMS, __arglist(tmp)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.PLACEMENT, __arglist(MKLValues.NOT_INPLACE)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.REAL_STORAGE, __arglist(MKLValues.REAL_REAL)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.CONJUGATE_EVEN_STORAGE, __arglist(MKLValues.COMPLEX_COMPLEX)); error = MKLImports.DftiSetValue(descriptor, MKLParameter.BACKWARD_SCALE, __arglist(1.0 / inDim)); error = MKLImports.DftiCommitDescriptor(descriptor); if (isMKLError(error)) { throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error)); } // do the transform(s) tmp = A.Dimensions.SequentialIndexDistance(dim); unsafe { fixed(/*!HC:HCretArr*/ double *retArrP = ret.m_data) fixed(/*!HC:inArr*/ complex * pA = A.m_data) { for (int i = 0; i < tmp && error == 0; i++) { error = MKLImports.DftiComputeBackward(descriptor, __arglist(pA + i, retArrP + i)); } } } if (isMKLError(error)) { throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error)); } return(ret); }