#ifndef __FUNCTION2D_CUDA__
#define __FUNCTION2D_CUDA__
#include "CudaMatrix.h"
#include "AuroraDefs.h"

namespace Aurora
{
    CudaMatrix max(const CudaMatrix &aMatrix, FunctionDirection direction = Column);
    CudaMatrix max(const CudaMatrix &aMatrix, FunctionDirection direction, long& rowIdx, long& colIdx);
    CudaMatrix max(const CudaMatrix &aMatrix, const float aValue);
    CudaMatrix max(const CudaMatrix &aMatrix, const CudaMatrix &aOther);

    CudaMatrix min(const CudaMatrix &aMatrix, FunctionDirection direction = Column);
    CudaMatrix min(const CudaMatrix &aMatrix, FunctionDirection direction, long& rowIdx, long& colIdx);
    CudaMatrix min(const CudaMatrix &aMatrix, const float aValue);
    CudaMatrix min(const CudaMatrix &aMatrix, const CudaMatrix &aOther);

    CudaMatrix sum(const CudaMatrix &aMatrix, FunctionDirection direction = Column);

    /**
     * @brief 平均值，注意不支持复数
     * 
     * @param aMatrix 需要处理的矩阵
     * @param direction 方向
     * @return CudaMatrix 
     */
    CudaMatrix mean(const CudaMatrix &aMatrix, FunctionDirection direction = Column);

    /**
     * @brief 标准差，只支持列方向
     * 
     * @param aMatrix 
     * @return CudaMatrix 
     */
    CudaMatrix std(const CudaMatrix &aMatrix);

    CudaMatrix sort(const CudaMatrix &aMatrix,FunctionDirection direction = Column);
    CudaMatrix sort(CudaMatrix &&aMatrix,FunctionDirection direction = Column);

    float immse(const CudaMatrix &aImageA, const CudaMatrix &aImageB);

    /**
     * 基于第一列中的元素按升序对矩阵行进行排序。
     * 当第一列包含重复的元素时，sortrows 会根据下一列中的值进行排序，并对后续的相等值重复此行为。
     * @attention 目前不支持三维，不支持复数
     * @param aMatrix 目标矩阵
     * @param indexMatrix 排序后各行的原索引矩阵指针，非必须
     * @return 排序后矩阵
     */
    CudaMatrix sortrows(const CudaMatrix &aMatrix, CudaMatrix& indexMatrix);

    CudaMatrix inv(const CudaMatrix &aMatrix);

    CudaMatrix inv(CudaMatrix &&aMatrix);

    CudaMatrix dot(const CudaMatrix &aMatrix, const CudaMatrix &aOther, FunctionDirection direction = Column);

    /**
     * prod，支持到2维
     * @param aMatrix
     * @return
     */
    CudaMatrix prod(const CudaMatrix &aMatrix);

    CudaMatrix fft(const CudaMatrix &aMatrix, long aFFTSize = -1);
    CudaMatrix ifft(const CudaMatrix &aMatrix, long aFFTSize = -1);

    CudaMatrix hilbert(const CudaMatrix &aMatrix);

    void fftshift(CudaMatrix &aMatrix);
    void ifftshift(CudaMatrix &aMatrix);

    /**
     * 转换下标为索引值
     * @attention 索引值按照其实为1与matlab对应，在C++中使用需要-1
     * @param aVMatrixSize
     * @param aSliceIdxs
     * @return
     */
    CudaMatrix sub2ind(const CudaMatrix &aVMatrixSize, std::vector<CudaMatrix> aSliceIdxs);

    /**
     * Symmetric逆fft，支持到2维，输入必须是复数，输出必是实数
     * @param aMatrix
     * @return ifft后的实数矩阵
     */
    CudaMatrix ifft_symmetric(const CudaMatrix &aMatrix,long aLength);

}

#endif // __FUNCTION2D_CUDA_H__