#ifndef AURORA_CUDA_FUNCTION1D_H
#define AURORA_CUDA_FUNCTION1D_H

#include "CudaMatrix.h"
#include "Function1D.h"

namespace Aurora
{
    CudaMatrix complex(const CudaMatrix& aMatrix);

    CudaMatrix complex(const CudaMatrix& aReal, const CudaMatrix& aImag);

    CudaMatrix real(const CudaMatrix& aMatrix);

    CudaMatrix imag(const CudaMatrix& aMatrix);

    CudaMatrix ceil(const CudaMatrix& aMatrix);

    CudaMatrix ceil(const CudaMatrix&& aMatrix);

    CudaMatrix round(const CudaMatrix& aMatrix);

    CudaMatrix round(const CudaMatrix&& aMatrix);

    CudaMatrix floor(const CudaMatrix& aMatrix);

    CudaMatrix floor(const CudaMatrix&& aMatrix);

    /**
     * 开根号，暂时只支持正整数
     * @param matrix
     * @return
     */
    CudaMatrix sqrt(const CudaMatrix& aMatrix);

    CudaMatrix sqrt(const CudaMatrix&& aMatrix);

    CudaMatrix abs(const CudaMatrix& aMatrix);
    CudaMatrix abs2(const CudaMatrix& aMatrix);


    CudaMatrix abs(const CudaMatrix&& aMatrix);

    CudaMatrix sign(const CudaMatrix& aMatrix);

    CudaMatrix sign(const CudaMatrix&& aMatrix);

    CudaMatrix repmat(const CudaMatrix& aMatrix,int aRowTimes, int aColumnTimes);

    CudaMatrix repmat(const CudaMatrix& aMatrix,int aRowTimes, int aColumnTimes, int aSliceTimes);

    CudaMatrix repmat3d(const CudaMatrix& aMatrix,int aRowTimes, int aColumnTimes, int aSliceTimes);

    CudaMatrix log(const CudaMatrix& aMatrix, int aBaseNum = -1);

    CudaMatrix exp(const CudaMatrix& aMatrix);

    CudaMatrix mod(const CudaMatrix& aMatrix, float aValue);

    CudaMatrix acos(const CudaMatrix& aMatrix);

    CudaMatrix acosd(const CudaMatrix& aMatrix);

    CudaMatrix conj(const CudaMatrix& aMatrix);

    float norm(const CudaMatrix& aMatrix, NormMethod aNormMethod);

    CudaMatrix transpose(const CudaMatrix& aMatrix);

    CudaMatrix horzcat(const CudaMatrix& aMatrix1, const CudaMatrix& aMatrix2);

    CudaMatrix vertcat(const CudaMatrix& aMatrix1, const CudaMatrix& aMatrix2);

    CudaMatrix vecnorm(const CudaMatrix& aMatrix, NormMethod aNormMethod, int aDim);

    CudaMatrix linspaceCuda(float aStart, float aEnd, int aNum);

    CudaMatrix auroraUnion(const CudaMatrix& aMatrix1, const CudaMatrix& aMatrix2);

    CudaMatrix intersect(const CudaMatrix& aMatrix1, const CudaMatrix& aMatrix2);

    CudaMatrix intersect(const CudaMatrix& aMatrix1, const CudaMatrix& aMatrix2, CudaMatrix& aIa);

    CudaMatrix reshape(const CudaMatrix& aMatrix, int aRows, int aColumns, int aSlices);

    CudaMatrix xcorr(const CudaMatrix& aMatrix1, const CudaMatrix& aMatrix2);
     
    CudaMatrix deleteColumn(const CudaMatrix& aMatrix, int aColumnIndex);

    CudaMatrix createCudaVectorMatrix(float aStartValue, float aStepValue, float aEndValue);

    CudaMatrix uniqueByRows(const CudaMatrix& aMatrix, CudaMatrix& aIndexResult);

     /**
     * 将所有nan值设置为特定值
     * @attention 直接在原数据上进行修改！
     * @param aMatrix 向量
     * @param val 指定值
     */
    void nantoval(CudaMatrix& aMatrix,float val);

    CudaMatrix isnan(const CudaMatrix& aMatrix);

    CudaMatrix isfinite(const CudaMatrix& aMatrix);

    /**
     * 使用特定值补齐矩阵，默认为设置原数据矩阵数据到制定长度索引的所有值为制定值
     * @attention 直接在原数据上进行修改！不支持复数！
     * @param aMatrix 向量
     * @param aIndex 长度索引
     * @param aValue 指定值
     */
    void padding(CudaMatrix& aMatrix, int aIndex, float aValue);

    CudaMatrix auroraNot(const CudaMatrix& aMatrix);

    CudaMatrix auroraNot(CudaMatrix&& aMatrix);

    CudaMatrix convertfp16tofloatCuda(short* aData, int aRows, int aColumns);

    // ------compareSet----------------------------------------------------
    void compareSet(CudaMatrix& aValueMatrix,float compareValue, float newValue,CompareOp op);
    void compareSet(CudaMatrix& aValueMatrix,CudaMatrix& aCompareMatrix,float compareValue, float newValue,CompareOp op);
    void compareSet(CudaMatrix& aDesAndCompareMatrix,CudaMatrix& aOtherCompareMatrix, float newValue,CompareOp op);
    void compareSet(CudaMatrix& aCompareMatrix,float compareValue, CudaMatrix& aNewValueMatrix,CompareOp op);
}

#endif //AURORA_CUDA_FUNCTION1D_H