/*
 * @Description: 电量采集模块-svc层-最小二乘法子模块
 * @Author: yangsw
 * @Date: 2021-06-08 09:42:17
 * @LastEditTime: 2021-07-12 12:37:16
 * @LastEditors: yangsw
 * @Reference: 
 */
#include "svc_bat_leastSquare.h"



static double paraX[DEGREE][DEGREE]={0};
static double paraY[DEGREE]={0};
static double paraA[DEGREE]={0};


/**
 * @brief: 获取X矩阵和Y矩阵
 * @return {void}
 * @note: X={(1+1+...,x1+x2+...,x1^2+x2^2...),(x1+x2+...,x1^2+x2^2...,x1^3+x2^3...),(x1^2+x2^2...,x1^3+x2^3...,x1^4+x2^4...),...}
 * Y={(y1+y2+...),(x1y1+x2y2+...),(x1^2y1+x2^2y2+...)}
 * @see: 
 * @param {double} x  数据源，此项目中x为环境温度T
 * @param {double} y  数据源，此项目中y为电池总容量PMC
 */
void getMatrixXAndMatrixY(double x,double y)
{
  int i,j,k;
  double sumX,sumY;
  for(i=0;i<DEGREE;i++)
  {
    for(j=0;j<DEGREE;j++)
    {
      sumX=1;
      for(k=DEGREE-j-i;k<DEGREE;k++)
      {
        sumX=sumX*x;
      }
      paraX[i][j]=paraX[i][j]+sumX;
    }
    sumY=1;
    for(k=DEGREE-i;k<DEGREE;k++)
    {
      sumY=sumY*x;
    }
    paraY[i]=paraY[i]+sumY*y;
  }
}


/**
 * @brief: 计算系数矩阵A
 * @return {void}
 * @note: 
 * @see: 
 * @param {double} *paraA 计算结果系数矩阵A放入传人参数
 */
void getParaA(double *paraA)
{
  double paraInverseX[DEGREE][DEGREE];           //逆矩阵
  int i,j;
  double sum;
  double a;
  a=getInverseMatrix(paraX,paraInverseX,DEGREE);        //计算逆矩阵*|X|和|X|
  for(i=0;i<DEGREE;i++)
  {
    sum=0;
    for(j=0;j<DEGREE;j++)
    {
      sum=sum+paraInverseX[i][j]*paraY[j];              //A=X-1*Y/a  系数矩阵=X的逆矩阵*|X|*Y矩阵/|X|
    }
    paraA[i]=(double)sum/a;
  }
}


/**
 * @brief: y=f(x)代入x求y的值
 * @return {double} y的值
 * @note: y=f(x)=a0+a1x+a2x^2+...，代入x求y
 * @see: 
 * @param {double} x 自变量
 * @param {double} *paraA 多项式的系数矩阵
 * @param {int} num 多项式系数个数（多项式阶数+1）
 */
double getYvalue(double x,double *paraA,int num)       
{
  int i,j;
  double sum,sumX;
  sum=0;
  for(i=0;i<num;i++)
  {
    sumX=1;
    for(j=num-i;j<num;j++)
    {
      sumX=sumX*x;
    }
    sum=sum+paraA[i]*sumX;
  }
    return sum;
}
