public ILArray <complex> FFTForward(ILArray <complex> A, int nDims) { if (A == null || nDims <= 0) { throw new ILArgumentException("invalid argument!"); } if (A.IsEmpty) { return(ILArray <complex> .empty(A.Dimensions)); } if (A.IsScalar || (A.Dimensions[0] == 1 && nDims == 1)) { return(A.C); } if (nDims > A.Dimensions.NumberOfDimensions) { nDims = A.Dimensions.NumberOfDimensions; } // prepare output array ILArray <complex> ret = A.C; IntPtr descriptor = IntPtr.Zero; int error = -1; int[] tmpDims = A.Dimensions.ToIntArray(nDims + 1); string hash = hashPlan(MKLValues.DOUBLE, MKLValues.COMPLEX, nDims, tmpDims); lock (_lockobject) { // try to reuse existing descriptor if (!m_descriptors.TryGetValue(hash, out descriptor)) { error = MKLImports.DftiCreateDescriptor(ref descriptor, MKLValues.DOUBLE, MKLValues.COMPLEX, 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)); //error = MKLImports.DftiSetValue(descriptor,MKLParameter.PLACEMENT,MKLValues.NOT_INPLACE); //error = MKLImports.DftiSetValue(descriptor,MKLParameter.REAL_STORAGE, MKLValues.REAL_COMPLEX); // storage of subsequent transformations MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_DISTANCE, __arglist(tmp)); MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_DISTANCE, __arglist(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(complex *retArr = ret.m_data) { error = MKLImports.DftiComputeForward(descriptor, __arglist(retArr)); } } if (isMKLError(error)) { throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error)); } return(ret); }
public ILArray <complex> FFTForward1D(ILArray <complex> A, int dim) { if (object.Equals(A, null) || dim < 0) { throw new ILArgumentException("invalid parameter!"); } if (A.IsEmpty) { return(ILArray <complex> .empty(A.Dimensions)); } if (dim >= A.Dimensions.NumberOfDimensions || A.Dimensions[dim] == 1) { return(A.C); } // prepare output array ILArray <complex> ret = A.C; string hash = hashPlan(MKLValues.DOUBLE, MKLValues.COMPLEX, 1, A.Dimensions[dim]); IntPtr descriptor = IntPtr.Zero; int error, inDim = A.Dimensions[dim]; // try to reuse existing descriptor lock (_lockobject) { if (!m_descriptors.TryGetValue(hash, out descriptor)) { error = MKLImports.DftiCreateDescriptor(ref descriptor, MKLValues.DOUBLE, MKLValues.COMPLEX, 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,MKLValues.NOT_INPLACE); error = MKLImports.DftiCommitDescriptor(descriptor); if (isMKLError(error)) { throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error)); } // do the transform(s) unsafe { tmp = A.Dimensions.SequentialIndexDistance(dim); fixed(complex *retArr = ret.m_data) { for (int i = 0; i < tmp && error == 0; i++) { error = MKLImports.DftiComputeForward(descriptor, __arglist(retArr + i)); } } } if (isMKLError(error)) { throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error)); } return(ret); }