#ifndef AURORA_FUNCTION1D_H
#define AURORA_FUNCTION1D_H

#include "Matrix.h"
#include <cmath>

namespace Aurora {

    enum InterpnMethod
    {
        Spline=0,Linear
    };

    enum NormMethod
    {
        Norm1=1,Norm2,NormF
    };

    Matrix complex(const Matrix& matrix);

    Matrix real(const Matrix& matrix);

    Matrix imag(const Matrix& matrix);

    Matrix ceil(const Matrix& matrix);

    Matrix ceil(const Matrix&& matrix);

    Matrix round(const Matrix& matrix);

    Matrix round(const Matrix&& matrix);

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

    Matrix sqrt(Matrix&& matrix);

    Matrix abs(const Matrix& matrix);

    Matrix abs(Matrix&& matrix);

    Matrix sign(const Matrix& matrix);

    Matrix sign(Matrix&& matrix);

    Matrix interp1(const Matrix& aX, const Matrix& aV, const Matrix& aX1, InterpnMethod aMethod);

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

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

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

    Matrix exp(const Matrix& aMatrix);

    Matrix mod(const Matrix& aMatrix, double aValue);

    Matrix acos(const Matrix& aMatrix);

    Matrix acosd(const Matrix& aMatrix);

    Matrix conj(const Matrix& aMatrix);

    double norm(const Matrix& aMatrix, NormMethod aNormMethod);

    Matrix transpose(const Matrix& aMatrix);

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

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

    Matrix linspace(double aStart, double aEnd, int aNum);

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

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

    Matrix reshape(const Matrix& aMatrix, int aRows, int aColumns, int aSlices);
    /**
     * 并集
     * @param aIa, [C,ia,~] = intersect(A,B)用法中ia的返回值
     * @return 并集结果
     */
    Matrix intersect(const Matrix& aMatrix1, const Matrix& aMatrix2, Matrix& aIa);

    /**
     * 多项式计算
     * @brief 例如p[1 0 1],x[3 2 5],代表对多项式 y = x^2 + 1 求(x=3, x=2, x=5)时所有的y
     * @attention 本函数的数据一律视为向量，在计算时会完全忽视维度，值考虑作为数组输入
     * @param aP 多项式系数，指定为向量
     * @param aX 查询点，指定为向量
     * @return 查询结果
     */
    Matrix polyval(const Matrix& aP, const Matrix& aX);

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


    Matrix isnan(const Matrix& aMatrix);

    Matrix isfinite(const Matrix& aMatrix);

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

    Matrix auroraNot(const Matrix& aMatrix);
    Matrix auroraNot(Matrix&& aMatrix);
    
    Matrix convertfp16tofloat(short* aData, int aRows, int aColumns);
};


#endif //AURORA_FUNCTION1D_H
