mfc如何做矩阵的除法
1、 计算矩阵的除法,先将被除的矩阵先转化为它的逆矩阵,再将前面的矩阵和后面的矩阵的逆矩阵相乘。
2、先把一个单位矩阵放在目的矩阵的右边,然后把左边的矩阵通过初等行变换转换为单位矩阵,此时右边的矩阵就是我们要求的逆矩阵。
3、那么MFC矩阵下面给出程序代码参考
图形如下
4、源码如下
// VarianceDlg.cpp : 实现文件
#include "stdafx.h"
#include "Variance.h"
#include "VarianceDlg.h"
#include "afxdialogex.h"
#include <string.h>
#include <math.h>
#include "Eigen/Eigenvalues"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include <iostream>
#include <sstream>
using namespace Eigen;
5、
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CVarianceDlg 对话框
CVarianceDlg::CVarianceDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CVarianceDlg::IDD, pParent)
, m_input(_T(""))
, m_output(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
}
void CVarianceDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT4, m_input);
DDX_Text(pDX, IDC_EDIT3, m_output);
}
BEGIN_MESSAGE_MAP(CVarianceDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CVarianceDlg::OnBnClicked_save_A)
ON_BN_CLICKED(IDC_BUTTON2, &CVarianceDlg::OnBnClicked_Cov)
ON_BN_CLICKED(IDC_BUTTON3, &CVarianceDlg::OnBnClicked_S)
ON_BN_CLICKED(IDC_BUTTON4, &CVarianceDlg::OnBnClickeddet)
ON_BN_CLICKED(IDC_BUTTON5, &CVarianceDlg::OnBnClickedButton_dets)
ON_BN_CLICKED(IDC_BUTTON6, &CVarianceDlg::OnBnClicked_adjoint)
ON_BN_CLICKED(IDC_BUTTON7, &CVarianceDlg::OnBnClicked_inverse)
ON_BN_CLICKED(IDC_BUTTON8, &CVarianceDlg::OnBnClicked_R)
ON_BN_CLICKED(IDC_BUTTON9, &CVarianceDlg::OnBnClicked_save_B)
ON_BN_CLICKED(IDC_BUTTON10, &CVarianceDlg::OnBnClicked_AB)
ON_BN_CLICKED(IDC_BUTTON11, &CVarianceDlg::OnBnClicked_Cramer)
ON_BN_CLICKED(IDC_BUTTON12, &CVarianceDlg::OnBnClicked_Jacobi)
ON_BN_CLICKED(IDC_BUTTON13, &CVarianceDlg::OnBnClicked_Clear_out)
ON_BN_CLICKED(IDC_BUTTON14, &CVarianceDlg::OnBnClicked_Gauss_Seidel)
ON_BN_CLICKED(IDC_BUTTON15, &CVarianceDlg::OnBn_Eigen)
ON_COMMAND(ID_32771, &CVarianceDlg::Onmenu_data)
ON_COMMAND(ID_AX_DATA, &CVarianceDlg::OnAx_B_data)
ON_COMMAND(ID_ABOUT_ABOUT, &CVarianceDlg::OnAboutAbout)
ON_BN_CLICKED(IDC_BUTTON16, &CVarianceDlg::but_PCA)
ON_COMMAND(ID_PCA_DATA, &CVarianceDlg::Menu_PcaData)
END_MESSAGE_MAP()
// CVarianceDlg 消息处理程序
BOOL CVarianceDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
row=0;
column=0;
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CVarianceDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CVarianceDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CVarianceDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
// TODO: 在此添加控件通知处理程序代码#####################################
//文件变量定义
void CVarianceDlg::OnBnClicked_Clear_out()
{
m_output="";
UpdateData(FALSE); //print
}
void CVarianceDlg::OnBnClicked_save_A()
{
UpdateData(TRUE); //READ
row=0;
column=0;
int max=0;
m_input.Replace("\r\n", " # "); //回车换成字符#
char *p = strtok((LPSTR)(LPCSTR)m_input," \t\n"); //使用' '和'\t'来分割字符串 line,当前 p 的值为类别
if(p != NULL)
column++;
else {
MessageBox(" Please input matrix_A ! ");
return;
}
bool flag=true;
while(1)
{
p = strtok(NULL," \t");
if( p == NULL) //最后一行
{
if(column>0&&flag==true)//1 行 且没遇到换行
{
row=1;
max=column;
MessageBox("only one line ");
break;
}
else if(max==column&&flag==false) //最后一个数量合适
{
row++;
break;
}
else if(column==0&&flag==false) //column==0说明回车后面是空行,此时停止读数
{
break;
MessageBox("last line ");//
}
else if(flag==false&&max!=column)
{
temp.Format("wrong in %d row",row+1);
MessageBox(temp);
return;
}
}
if( *p == '#') // 换行
{
if(max>0&&column==0)//空行
{
break;
}
if(max>0&&max!=column)
{
temp.Format("wrong in %d row",row+1);
MessageBox(temp);
return;
}
if(flag)
max=column;
flag=false;
row++;
column=0;
}
else
{
column++; //非空列加1
}
}
column=max;
save();
}
void CVarianceDlg::save()
{
UpdateData(TRUE); //READ
char *endptr;
int i=0, j=0;
CString str;
matrix_A= new double[row*column]; //yiwei
prow= new double*[row]; /////二维数据
//m_output=m_input;
/* temp.Format("r=%d,c=%d ",row,column);
MessageBox(temp);*/
m_input.Replace("\r\n", " # ");
bool flag =true;
for(i=0;i<row;i++)
{
prow[i]=matrix_A+column*i;
for(j=0;j<column;j++)
{
if(flag)
{
str = strtok((LPSTR)(LPCSTR)m_input," \t");
matrix_A[i*column+j]=strtod(str,&endptr); // STR TO double
}
else
{
str= strtok(NULL," \t");
if( str == '#')
{
str= strtok(NULL," \t");
matrix_A[i*column+j]=strtod(str,&endptr);
}
else{
matrix_A[i*column+j]=strtod(str,&endptr);
}
}
flag=false;
}
}
CString output;
m_input="";
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
output.Format("%g ",prow[i][j]);
m_input+=output;
}
if(i<row-1)
{
output.Format("\r\n");
m_input+=output;}
}
temp.Format("row=%d,column=%d ",row,column);
m_output=temp;
UpdateData(FALSE); //print
}
void CVarianceDlg::OnBnClicked_save_B()
{
UpdateData(TRUE); //READ
row_b=0;
column_b=0;
int max=0;
m_input.Replace("\r\n", " # "); //回车换成字符#
char *p = strtok((LPSTR)(LPCSTR)m_input," \t\n"); //使用' '和'\t'来分割字符串 line,当前 p 的值为类别
if(p != NULL)
column_b++;
else {
MessageBox(" Please input matrix_B ! ");
return;
}
bool flag=true;
while(1)
{
p = strtok(NULL," \t");
if( p == NULL) //最后一行
{
if(column_b>0&&flag==true)//1 行 且没遇到换行
{
row_b=1;
max=column_b;
MessageBox("only one line ");
break;
}
else if(max==column_b&&flag==false) //最后一个数量合适
{
row_b++;
break;
}
else if(column_b==0&&flag==false) //column==0说明回车后面是空行,此时停止读数
{
break;
MessageBox("last line ");//
}
else if(flag==false&&max!=column_b)
{
temp.Format("wrong in %d row_b",row_b+1);
MessageBox(temp);
return;
}
}
if( *p == '#') // 换行
{
if(max>0&&column_b==0)//空行
{
break;
}
if(max>0&&max!=column_b)
{
temp.Format("wrong in %d row_b",row_b+1);
MessageBox(temp);
return;
}
if(flag)
max=column_b;
flag=false;
row_b++;
column_b=0;
}
else
{
column_b++; //非空列加1
}
}
column_b=max;
save_B();
}
void CVarianceDlg::save_B()
{
UpdateData(TRUE); //READ
char *endptr;
int i=0, j=0;
CString str;
matrix_B= new double[row_b*column_b];
prow_b= new double*[row_b];
//m_output=m_input;
/* temp.Format("r=%d,c=%d ",row_b,column_b);
MessageBox(temp);*/
m_input.Replace("\r\n", " # ");
bool flag =true;
for(i=0;i<row_b;i++)
{
prow_b[i]=matrix_B+column_b*i;
for(j=0;j<column_b;j++)
{
if(flag)
{
str = strtok((LPSTR)(LPCSTR)m_input," \t");
matrix_B[i*column_b+j]=strtod(str,&endptr); // STR TO double
}
else
{
str= strtok(NULL," \t");
if( str == '#')
{
str= strtok(NULL," \t");
matrix_B[i*column_b+j]=strtod(str,&endptr);
}
else{
matrix_B[i*column_b+j]=strtod(str,&endptr);
}
}
flag=false;
}
}
CString output;
m_input="";
for(i=0;i<row_b;i++)
{
for(j=0;j<column_b;j++)
{
output.Format("%g ",prow_b[i][j]);
m_input+=output;
}
if(i<row_b-1)
{
output.Format("\r\n");
m_input+=output;}
}
temp.Format("row_b=%d,column_b=%d ",row_b,column_b);
m_output=temp;
UpdateData(FALSE); //print
}
void CVarianceDlg::OnBnClicked_Cov()//协方差阵
{
//row 样本数,column 变量数
if(column==0)
{
MessageBox("先检查数据");
return;
}
double *mean=new double[column]; //均值向量
cov=new double[column*column];
for(int j=0;j<column;j++) //init
{
mean[j]=0.0;
}
for(int j=0;j<column*column;j++) //init
{
cov[j]=0.0;
}
for(int j=0;j<column;j++) //mean
{
for(int i=0; i<row;i++)
{
6、void CVarianceDlg::Menu_PcaData()
{
// TODO: 在此添加命令处理程序代码
m_input="37.115 33.069 24.631 12.364 2.695 11.155 7.367 12.597\r\n\
33.069 31.314 22.624 11.506 2.593 11.177 7.075 11.911\r\n\
24.631 22.624 19.739 7.119 1.217 6.163 4.030 9.322\r\n\
12.364 11.506 7.119 7.131 1.575 5.334 3.229 3.573\r\n\
2.695 2.593 1.217 1.575 4.437 7.013 2.084 0.577\r\n\
11.155 11.177 6.163 5.334 7.013 30.784 7.472 4.049\r\n\
7.367 7.075 4.030 3.229 2.084 7.472 7.554 2.340\r\n\
12.597 11.911 9.322 3.573 0.577 4.049 2.340 9.246\r\n";
UpdateData(FALSE); //print
}