C语言矩阵实现库运算, 简单的数组直接运算两种方式

C语言需要实现矩阵的加和相乘,发现网上很多实现方法运行使用都有些问题,参考了一位博主的,基于C语言的矩阵实现库简单修改了,在此感谢;由于每次malloc()free()占用资源太浪费,对于我这种工程上反复调用矩阵的特别不合适,后面又简单的实现了矩阵的调用;

1.实现库运算

matrix.h

typedef struct
{
    int row;
    int column;
    float** data;
}MATRIX_T;

matrix.c

static int16_t SizeMatrix(MATRIX_T* matrix)
{
    return matrix->row * matrix->column;
}


/*
set all datas in matrix to zero
*/
void ClearMatrix(MATRIX_T* mat)
{
    uint16_t i, j;
    for (i = 0; i < mat->row; i++)
    {
        for (j = 0; j < mat->column; j++)
        {
            mat->data[i][j] = 0;
        }
    }
}


/*
create a matrix with 0
*/
MATRIX_T CreateMatrix(uint16_t row, uint16_t column)
{
    MATRIX_T mat;
    if (row <= 0 || column <= 0)
    {
        printf("error, in create_mat: row <= 0||column<=0\n");
        exit(1);
    }
    if (row > 0 && column > 0)
    {
        mat.row = row;
        mat.column = column;
        mat.data = (float**)malloc(row * sizeof(float*));//先指针的指针
        if (mat.data == NULL)
        {
            printf("error, in create_mat: mat.data==NULL");
            exit(1);
        }
        uint16_t i;
        for (i = 0; i < row; i++)
        {
            *(mat.data + i) = (float*)malloc(column * sizeof(float));//再分配每行的指针
            if (mat.data[i] == NULL)
            {
                printf("error, in create_mat: mat.data==NULL");
                exit(1);
            }
        }
        ClearMatrix(&mat);
    }
    return mat;
}

/*
free a matrix
*/
void FreeMatrix(MATRIX_T* mat)
{
    uint16_t i;
    for (i = 0; i < mat->row; i++)
        free(mat->data[i]);/*释放行*/
    free(mat->data);/*释放头指针*/
}

void PrintMatrixData(MATRIX_T* mat)
{
    uint16_t i, j;
    printf("row:%d col %d\n", mat->row, mat->column);
    for (i = 0; i < mat->row; i++)
    {
        for (j = 0; j < mat->column; j++)
        {
            printf("%d ", (int)(mat->data[i][j]*1000));
        }
    }

}

/*
set datas to the matrix
*/
void InitMatrix(MATRIX_T* mat, const float* data)
{
    uint16_t i, j;
    for (i = 0; i < mat->row; i++)
    {
        for (j = 0; j < mat->column; j++)
        {
            mat->data[i][j] = data[i * mat->column + j];
        }
    }
}

/*
mat=mat1+mat2
*/
MATRIX_T AddMatrix(const MATRIX_T* mat1, const MATRIX_T* mat2)
{
    if (mat1->row != mat2->row)
    {
        printf("error, in add_mat: mat1->row != mat2->row\n");
        exit(1);
    }
    if (mat1->column != mat2->column)
    {
        printf("error, in add_mat: mat1->column != mat2->column\n");
        exit(1);
    }
    MATRIX_T mat;
    uint16_t i, j;
    mat = CreateMatrix(mat1->row, mat1->column);
    for (i = 0; i < mat1->row; i++)
    {
        for (j = 0; j < mat1->column; j++)
            mat.data[i][j] = mat1->data[i][j] + mat2->data[i][j];
    }
    return mat;
}


/*
mat = mat1 * mat2
*/
MATRIX_T MultMatrix(const MATRIX_T * mat1, const MATRIX_T * mat2)
{
    MATRIX_T mat;
    if (mat1->column != mat2->row)
    {
        printf("error,In mult_mat: mat1->column != mat2->row\n");
        exit(1);
    }
    else
    {
        mat = CreateMatrix(mat1->row, mat2->column);
        ClearMatrix(&mat);
        uint16_t i, j;
        for (i = 0; i < mat1->row; i++)
        {
            for (j = 0; j < mat2->column; j++)
            {
                uint16_t m;
                for (m = 0; m < mat1->column; m++)
                {
                    mat.data[i][j] += mat1->data[i][m] * mat2->data[m][j];
                }
            }
        }
    }
    return mat;
}




main.c

void Main(void)
{
    MATRIX_T mat = CreateMatrix(4, 4);
    float data[16] = { 1, 2, 3, 4,
                        2, 1, 4, 5,
                        5, 4, 3, 5,
                        7, 6, 5, 4 };
    InitMatrix(&mat, data);
    PrintMatrixData(&mat);
    FreeMatrix(&mat);
}

可行

2.矩阵的简单实现

一些矩阵是固定的,但是每次运行都要用到,传到的参数是一个一维的数组

int8_t GetStrokeFromNN(float* fv, uint8_t fv_len, double *pro)
{
    MultipyMatrix(fv,layer_2, m_y_2, LAYER_1_LEN, LAYER_2_LEN);
    AddTwoMatirx(m_y_2, b_2, m_re_2,LAYER_2_LEN);
}

其中用到的固定矩阵和函数

#define LAYER_1_LEN 5
#define LAYER_2_LEN 4

static float  m_y_2[LAYER_2_LEN],m_re_2[LAYER_2_LEN];

/* three layer 5*4 */
const static float layer_2[5][4] = { {-0.61686844,  0.20468698, -0.466563  , 0.78789},//
{-0.75650525, -0.6165384 , -0.05637943, -0.9151292},//
{-0.12878262,  0.6718534 ,  0.14261276, -1.1444305},//
{0.3381382 , -0.5655513 , -0.9225061 , -0.26553082},//
{1.0406455 ,  0.03688743, -0.55733025, -0.35481057} };

const static float b_2[4] = { -0.30565912,  0.6395876 , -0.693441  ,  0.23737375 };

void MultipyMatrix(float *mat1, float *mat2, float *re, uint8_t col_len, uint8_t len)
{
    if ((mat1==NULL)||(mat2 == NULL))
    {
        return;
    }

    uint8_t row, colu;
    float* p;
    float tem1, tem2, tem;

    for (row=0;row<len;row++) // 10
    {
        re[row] = 0;
        p = mat1;

        for (colu=0;colu<col_len;colu++)  // 18
        {
            //re[row] += (*(p + colu)) * (mat2[colu *len+row]);
            tem1 = *(p + colu);
            tem2 = mat2[colu * len + row];
            re[row] += tem1 * tem2;
        }        
    }
}


/******************************************************************************/
/** add two matrix
* @param[in]
*
* @return
*
* History        :
* 1.Date         : 2020/9/30
*   Author       : 
*   Modification : Created function

*******************************************************************************/
void AddTwoMatirx(float *mat1, float *mat2,float *re, uint8_t len)
{
    if ((mat1==NULL)||(mat2==NULL)||(re==NULL))
    {
        return;
    }

    uint8_t i = 0;

    for (i=0; i<len;i++)
    {
        re[i] = mat1[i] + mat2[i];        
    }
}

后面这个矩阵运算虽然没有用到库,直接将数组带入进来运算,对于反反复复调用来说,节省资源,避免内存泄漏问题。

...

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值