/*
 * @Description: 电量采集模块-svc层-矩阵计算子模块
 * @Author: yangsw
 * @Date: 2021-06-08 09:42:17
 * @LastEditTime: 2021-06-25 09:36:13
 * @LastEditors: yangsw
 * @Reference: 
 */
#include "svc_bat_matrix.h"
#include "stdio.h"
#include "../../log/svc/svc_log.h"


/**
 * @brief: 按第一行展开计算A的行列式|A|
 * @return {double} A的行列式
 * @note: 
 * @see: 
 * @param {double} arcs 待求矩阵，DEGREE为矩阵阶数
 * @param {matInt32} n 待求矩阵阶数
 */
double getA(double arcs[DEGREE][DEGREE],matInt32 n)//按第一行展开计算|A|
{
    if(n==1)
    {
        return arcs[0][0];
    }
    double ans = 0;
    double temp[DEGREE][DEGREE];
    matInt32 i,j,k;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n-1;j++)
        {
            for(k=0;k<n-1;k++)
            {
                temp[j][k] = arcs[j+1][(k>=i)?k+1:k];

            }
        }
        double t = getA(temp,n-1);
        if(i%2==0)
        {
            ans += arcs[0][i]*t;
        }
        else
        {
            ans -=  arcs[0][i]*t;
        }
    }
    return ans;
}


/**
 * @brief: 计算每一行每一列的每个元素所对应的代数余子式，组成伴随矩阵A*
 * @return {void}
 * @note: 
 * @see: 
 * @param {double} arcs 输入矩阵
 * @param {int} n   矩阵阶数
 * @param {double} ans 输出伴随矩阵A*
 */
void getAStart(double arcs[DEGREE][DEGREE],int n,double ans[DEGREE][DEGREE])
{
    if(n==1)
    {
        ans[0][0] = 1;
        return;
    }
    matInt32 i,j,k,t;
    double temp[DEGREE][DEGREE];
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            for(k=0;k<n-1;k++)
            {
                for(t=0;t<n-1;t++)
                {
                    temp[k][t] = arcs[k>=i?k+1:k][t>=j?t+1:t];
                }
            }


            ans[j][i]  =  getA(temp,n-1);
            if((i+j)%2 == 1)
            {
                ans[j][i] = - ans[j][i];
            }
        }
    }
}

/**
 * @brief: 计算A的逆矩阵
 * @return {void}
 * @note: A-1=A*除于|A|     A的逆矩阵=A的伴随矩阵/A的行列式
 * 由于怕精度丢失，这里的所求的逆矩阵并没有除于A的行列式|A|，所以实际输出的是伴随矩阵A*
 * @see: 
 * @param {double} arcs 输入矩阵A
 * @param {double} astar A的逆矩阵A-1
 * @param {matInt32} n 矩阵阶数
 */
double getInverseMatrix(double arcs[DEGREE][DEGREE],double astar[DEGREE][DEGREE],matInt32 n)      //
{
  matInt32 i,j;
  double a = getA(arcs,n);
  if(a==0)
  {
    Svc_Log_Printf(LOG_ERROR,"can not transform!\n");
  }
  else
  {
    getAStart(arcs,n,astar);
//     Svc_Log_Printf(LOG_DEBUG,">>para:");
//     for(i=0;i<n;i++)
//     {
//       for(j=0;j<n;j++)
//       {
//         Svc_Log_Printf(LOG_DEBUG,"%f ",(double)astar[i][j]/a);
//       }
//       Svc_Log_Printf(LOG_DEBUG,"\r\n");
//     }
   }
//   Svc_Log_Printf(LOG_DEBUG,"\n");
  return a;
}