[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/arrayfire/arrayfire/feature/optional-graphics/src/api/cpp/fft.cpp [Back]  [Original]

/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include 
#include 
#include 
#include "error.hpp"

using af::array;
using af::dim4;

namespace af {
array fftNorm(const array& in, const double norm_factor, const dim_t odim0) {
    af_array out = 0;
    AF_THROW(af_fft(&out, in.get(), norm_factor, odim0));
    return array(out);
}

array fft2Norm(const array& in, const double norm_factor, const dim_t odim0,
               const dim_t odim1) {
    af_array out = 0;
    AF_THROW(af_fft2(&out, in.get(), norm_factor, odim0, odim1));
    return array(out);
}

array fft3Norm(const array& in, const double norm_factor, const dim_t odim0,
               const dim_t odim1, const dim_t odim2) {
    af_array out = 0;
    AF_THROW(af_fft3(&out, in.get(), norm_factor, odim0, odim1, odim2));
    return array(out);
}

array fft(const array& in, const dim_t odim0) {
    return fftNorm(in, 1.0, odim0);
}

array fft2(const array& in, const dim_t odim0, const dim_t odim1) {
    return fft2Norm(in, 1.0, odim0, odim1);
}

array fft3(const array& in, const dim_t odim0, const dim_t odim1,
           const dim_t odim2) {
    return fft3Norm(in, 1.0, odim0, odim1, odim2);
}

// NOLINTNEXTLINE(performance-unnecessary-value-param)
array dft(const array& in, const double norm_factor, const dim4 outDims) {
    array temp;
    switch (in.dims().ndims()) {
        case 1: temp = fftNorm(in, norm_factor, outDims[0]); break;
        case 2: temp = fft2Norm(in, norm_factor, outDims[0], outDims[1]); break;
        case 3:
            temp =
                fft3Norm(in, norm_factor, outDims[0], outDims[1], outDims[2]);
            break;
        default: AF_THROW(AF_ERR_NOT_SUPPORTED);
    }
    return temp;
}

// NOLINTNEXTLINE(performance-unnecessary-value-param)
array dft(const array& in, const dim4 outDims) { return dft(in, 1.0, outDims); }

array dft(const array& in) { return dft(in, 1.0, dim4(0, 0, 0, 0)); }

array ifftNorm(const array& in, const double norm_factor, const dim_t odim0) {
    af_array out = 0;
    AF_THROW(af_ifft(&out, in.get(), norm_factor, odim0));
    return array(out);
}

array ifft2Norm(const array& in, const double norm_factor, const dim_t odim0,
                const dim_t odim1) {
    af_array out = 0;
    AF_THROW(af_ifft2(&out, in.get(), norm_factor, odim0, odim1));
    return array(out);
}

array ifft3Norm(const array& in, const double norm_factor, const dim_t odim0,
                const dim_t odim1, const dim_t odim2) {
    af_array out = 0;
    AF_THROW(af_ifft3(&out, in.get(), norm_factor, odim0, odim1, odim2));
    return array(out);
}

array ifft(const array& in, const dim_t odim0) {
    const dim4 dims    = in.dims();
    dim_t dim0         = odim0 == 0 ? dims[0] : odim0;
    double norm_factor = 1.0 / static_cast(dim0);
    return ifftNorm(in, norm_factor, odim0);
}

array ifft2(const array& in, const dim_t odim0, const dim_t odim1) {
    const dim4 dims    = in.dims();
    dim_t dim0         = odim0 == 0 ? dims[0] : odim0;
    dim_t dim1         = odim1 == 0 ? dims[1] : odim1;
    double norm_factor = 1.0 / static_cast(dim0 * dim1);
    return ifft2Norm(in, norm_factor, odim0, odim1);
}

array ifft3(const array& in, const dim_t odim0, const dim_t odim1,
            const dim_t odim2) {
    const dim4 dims    = in.dims();
    dim_t dim0         = odim0 == 0 ? dims[0] : odim0;
    dim_t dim1         = odim1 == 0 ? dims[1] : odim1;
    dim_t dim2         = odim2 == 0 ? dims[2] : odim2;
    double norm_factor = 1.0 / static_cast(dim0 * dim1 * dim2);
    return ifft3Norm(in, norm_factor, odim0, odim1, odim2);
}

// NOLINTNEXTLINE(performance-unnecessary-value-param)
array idft(const array& in, const double norm_factor, const dim4 outDims) {
    array temp;
    switch (in.dims().ndims()) {
        case 1: temp = ifftNorm(in, norm_factor, outDims[0]); break;
        case 2:
            temp = ifft2Norm(in, norm_factor, outDims[0], outDims[1]);
            break;
        case 3:
            temp =
                ifft3Norm(in, norm_factor, outDims[0], outDims[1], outDims[2]);
            break;
        default: AF_THROW(AF_ERR_NOT_SUPPORTED);
    }
    return temp;
}

// NOLINTNEXTLINE(performance-unnecessary-value-param)
array idft(const array& in, const dim4 outDims) {
    return idft(in, 1.0, outDims);
}

array idft(const array& in) { return idft(in, 1.0, dim4(0, 0, 0, 0)); }

void fftInPlace(array& in, const double norm_factor) {
    AF_THROW(af_fft_inplace(in.get(), norm_factor));
}

void fft2InPlace(array& in, const double norm_factor) {
    AF_THROW(af_fft2_inplace(in.get(), norm_factor));
}

void fft3InPlace(array& in, const double norm_factor) {
    AF_THROW(af_fft3_inplace(in.get(), norm_factor));
}

void ifftInPlace(array& in, const double norm_factor) {
    const dim4 dims = in.dims();
    double norm     = norm_factor * (1.0 / static_cast(dims[0]));
    AF_THROW(af_ifft_inplace(in.get(), norm));
}

void ifft2InPlace(array& in, const double norm_factor) {
    const dim4 dims = in.dims();
    double norm = norm_factor * (1.0 / static_cast(dims[0] * dims[1]));
    AF_THROW(af_ifft2_inplace(in.get(), norm));
}

void ifft3InPlace(array& in, const double norm_factor) {
    const dim4 dims = in.dims();
    double norm =
        norm_factor * (1.0 / static_cast(dims[0] * dims[1] * dims[2]));
    AF_THROW(af_ifft3_inplace(in.get(), norm));
}

template
AFAPI array fftR2C(const array& in, const dim4& dims,
                      const double norm_factor) {
    af_array res;
    AF_THROW(af_fft_r2c(&res, in.get(), norm_factor == 0 ? 1.0 : norm_factor,
                        dims[0]));
    return array(res);
}

template
AFAPI array fftR2C(const array& in, const dim4& dims,
                      const double norm_factor) {
    af_array res;
    AF_THROW(af_fft2_r2c(&res, in.get(), norm_factor == 0 ? 1.0 : norm_factor,
                         dims[0], dims[1]));
    return array(res);
}

template
AFAPI array fftR2C(const array& in, const dim4& dims,
                      const double norm_factor) {
    af_array res;
    AF_THROW(af_fft3_r2c(&res, in.get(), norm_factor == 0 ? 1.0 : norm_factor,
                         dims[0], dims[1], dims[2]));
    return array(res);
}

inline dim_t getOrigDim(dim_t d, bool is_odd) {
    return 2 * (d - 1) + (is_odd ? 1 : 0);
}

template
AFAPI array fftC2R(const array& in, const bool is_odd,
                      const double norm_factor) {
    double norm = norm_factor;

    if (norm == 0) {
        dim4 idims = in.dims();
        dim_t dim0 = getOrigDim(idims[0], is_odd);
        norm       = 1.0 / static_cast(dim0);
    }

    af_array res;
    AF_THROW(af_fft_c2r(&res, in.get(), norm, is_odd));
    return array(res);
}

template
AFAPI array fftC2R(const array& in, const bool is_odd,
                      const double norm_factor) {
    double norm = norm_factor;

    if (norm == 0) {
        dim4 idims = in.dims();
        dim_t dim0 = getOrigDim(idims[0], is_odd);
        dim_t dim1 = idims[1];
        norm       = 1.0 / static_cast(dim0 * dim1);
    }

    af_array res;
    AF_THROW(af_fft2_c2r(&res, in.get(), norm, is_odd));
    return array(res);
}

template
AFAPI array fftC2R(const array& in, const bool is_odd,
                      const double norm_factor) {
    double norm = norm_factor;

    if (norm == 0) {
        dim4 idims = in.dims();
        dim_t dim0 = getOrigDim(idims[0], is_odd);
        dim_t dim1 = idims[1];
        dim_t dim2 = idims[2];
        norm       = 1.0 / static_cast(dim0 * dim1 * dim2);
    }

    af_array res;
    AF_THROW(af_fft3_c2r(&res, in.get(), norm, is_odd));
    return array(res);
}

#define FFT_REAL(rank)                                                    \
    template                                                            \
    AFAPI array fftR2C(const array& in, const double norm_factor) { \
        return fftR2C(in, in.dims(), norm_factor);                  \
    }

FFT_REAL(1)
FFT_REAL(2)
FFT_REAL(3)

void setFFTPlanCacheSize(size_t cacheSize) {
    AF_THROW(af_set_fft_plan_cache_size(cacheSize));
}
}  // namespace af

Web Proxy Viewer  |  New URL  |  Original Page