示例#1
0
        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);
        }
示例#2
0
        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);
        }