vc计算矩阵的转置,矩阵的点乘,矩阵的逆矩阵,参考网上的例子
矩阵点乘的例子:
矩阵逆矩阵计算例子:
#include "stdafx.h"
#include <math.h>
//#include<complex.h>
#include <iostream>
#include <complex>
#include <cstdlib> // 包含rand()和srand()
#include <ctime> // 包含time()
using namespace std;
///计算 两个矩阵的点乘
void dotMatrix(float *a, float *b, float c[][50],int rowsa, int colsa,int colsb, int n) {///rowsa 前面矩阵的行数,colsa前面矩阵的列数,colsb后面矩阵的列数,n最大维数
for (int i = 0; i < rowsa; i++)
{
for (int j = 0; j < colsb; j++)
{
int sum = 0;
for (int k = 0; k < colsa; k++)
{
sum += a[i*n+k] * b[k*n+j];
}
c[i][j] = sum;
}
}
}
// 函数定义:计算矩阵的转置
void transposeMatrix(float *source, float *dest, int rows, int cols,int n) {///rows 原始矩阵的行数,cols原始矩阵的列数
// 对于每一个元素,将其放到dest数组的相应位置(行变列,列变行) ,n最大维数
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
float *p = (float *)&source[i*n + j];
float *dp = (float *)&dest[j*n + i];
**&dp = *p; // 注意这里的行列索引交换
}
}
}
计算矩阵的逆矩阵
float** Matrix_inver(float** src, int row, int col,int nn)//原始矩阵的行与列,nn最大的维数
{
//step 1
//判断指针是否为空
if (src == NULL)exit(-1);
int i, j, k, n,principal;
float** res, ** res2, tmp;//res为增广矩阵,res为输出的逆矩阵
float Max;
//判断矩阵维数
//row = (double)_msize(src) / (double)sizeof(double*);
//col = (double)_msize(*src) / (double)sizeof(double);
if (row != col)exit(-1);
//step 2
res = (float**)malloc(sizeof(float*) * row);
res2 = (float**)malloc(sizeof(float*) * row);
n = 2 * row;
for (i = 0; i < row; i++)
{
res[i] = (float*)malloc(sizeof(float) * n);
res2[i] = (float*)malloc(sizeof(float) * col);
memset(res[i], 0, sizeof(res[0][0]) * n);//初始化
memset(res2[i], 0, sizeof(res2[0][0]) * col);
}
//step 3
//进行数据拷贝
for (i = 0; i < row; i++)
{
//此处源代码中的n已改为col,当然方阵的row和col相等,这里用col为了整体逻辑更加清晰
memcpy(res[i], &src[i*nn], sizeof(res[0][0]) * col);
}
//将增广矩阵右侧变为单位阵
for (i = 0; i < row; i++)
{
for (j = col; j < n; j++)
{
if (i == (j - row))
res[i][j] = 1.0;
}
}
for (j = 0; j < col; j++)
{
//step 4
//整理增广矩阵,选主元
principal = j;
Max = fabs(res[principal][j]); // 用绝对值比较
// 默认第一行的数最大
// 主元只选主对角线下方
for (i = j; i < row; i++)
{
if (fabs(res[i][j]) > Max)
{
principal = i;
Max = fabs(res[i][j]);
}
}
if (j != principal)
{
for (k = 0; k < n; k++)
{
tmp = res[principal][k];
res[principal][k] = res[j][k];
res[j][k] = tmp;
}
}
//step 5
//将每列其他元素化0
for (i = 0; i < row; i++)
{
if (i == j || res[i][j] == 0)continue;
float b = res[i][j] / res[j][j];
for (k = 0; k < n; k++)
{
res[i][k] += b * res[j][k] * (-1);
}
}
//阶梯处化成1
float a = 1.0 / res[j][j];
for (i = 0; i < n; i++)
{
res[j][i] *= a;
}
}
//step 6
//将逆矩阵部分拷贝到res2中
for (i = 0; i < row; i++)
{
memcpy(res2[i], res[i] + row, sizeof(res[0][0]) * row);
}
//必须释放res内存!
for (i = 0; i < row; i++)
{
free(res[i]);
}
free(res);
return res2;
}
int _tmain(int argc, _TCHAR* argv[])
{
float q[50] = { 0 };///保存视电阻率值
float r[10] = { 0 };
float h[10] = { 0 };
r[0] = 100;
r[1] = 1000;
r[2] = 500;
r[3] = 3000;
// r[4] = 400;
h[0] = 500;
h[1] = 1000;
h[2] = 2000;
// h[3] = 2000;
for (int i = 0; i < 50; i++)///计算模型的正演值,为模拟退火计算做准备
{
//q[i]=calcR(r, h, 3, f[i]);
q[i] = calcR(r, h, 4, f[i]);
}
// 假设我们有一个3x3的矩阵
float matrix[50][50] = {
{ 1, 2,3 },
{ 4, 5,6},
{ 7, 8 ,9}
};
// 用于存储转置后的矩阵的数组
float transposed[50][50] = { 0 };
// 调用函数计算转置
transposeMatrix((float *)&matrix[0], (float *)&transposed[0], 3, 2,50);
//矩阵点乘计算
float a[50][50] = { { 1, 2, 4 }, { 2, 0, 3 } };
float b[50][50] = { { 1, 2 }, { 3, 2 }, { 0, 5 } };
/ 7,26
/ 2,19
dotMatrix((float *)&a, (float *)&b, transposed, 2, 3, 2, 50);
///下面计算点乘的结果
printf("%f,%f,\n%f,%f\n", transposed[0][0], transposed[0][1], transposed[1][0], transposed[1][1]);
下面计算矩阵aa的逆矩阵
float aa[50][50] = {
{1,0,0},
{1,1,0},
{1,1,1}
};
float **ret = Matrix_inver((float **)aa, 3, 3, 50);
printf("下面计算矩阵aa的逆矩阵\n");
printf("%f,%f,%f,\n%f,%f,%f,\n%f,%f,%f\n", ret[0][0], ret[0][1], ret[0][2], ret[1][0], ret[1][1], ret[1][2], ret[2][0], ret[2][1], ret[2][2]);
下面计算矩阵aa与它的逆矩阵bb的点乘
float bb[50][50] = { 0 };
bb[0][0] = ret[0][0];
bb[0][1] = ret[0][1];
bb[0][2] = ret[0][2];
bb[1][0] = ret[1][0];
bb[1][1] = ret[1][1];
bb[1][2] = ret[1][2];
bb[2][0] = ret[2][0];
bb[2][1] = ret[2][1];
bb[2][2] = ret[2][2];
dotMatrix((float *)&aa, (float *)&bb, transposed, 3, 3, 3, 50);
///下面计算点乘的结果
printf("下面计算矩阵aa与它的逆矩阵bb的点乘结果\n");
printf("%f,%f,%f,\n%f,%f,%f,\n%f,%f,%f", transposed[0][0], transposed[0][1], transposed[0][2], transposed[1][0], transposed[1][1], transposed[1][2], transposed[2][0], transposed[2][1], transposed[2][2]);
return 0;
}
最终显示结果