MFC矩阵运算

1,对话框文件

2,图形


3,源码

// 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;  

// 用于应用程序“关于”菜单项的 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++)
		{
			mean[j]+=prow[i][j];
		}
		mean[j]/=row;
	}
	int i ,k,j;
	for( i=0;i<column;i++) //第一个变量
	{
		for(j=i; j<column;j++) //第二个变量
		{
			for(k=0; k<row;k++) //计算
			{
				cov[i*column+j] += ( prow[k][i]-mean[i] )*( prow[k][j]-mean[j] );

			}
			cov[i*column+j]/=(row);
			/*temp.Format("cov=%f,column=%d mean(%d)=%f,mean(%d)=%f",cov[i*column+j],row,i,mean[i],j,mean[j]);
			MessageBox(temp);*/
		}	
	}
	for( i=0;i<column;i++) //补全对应面
	{
		for(j=0; j<i;j++) 
		{
			cov[i*column+j]=cov[j*column+i];
		}
	}
	m_output="均值向量:\r\n";
	for(int j=0;j<column;j++) //mean
	{
		temp.Format("%g   ",mean[j]);
		m_output+=temp;
	}		
	temp.Format("\r\n ");
	m_output+=temp;
	m_output+="\r\n协方差阵D:\r\n";
	for( i=0;i<column;i++) //print
	{
		for(j=0; j<column;j++)
		{
			temp.Format("%g    ",cov[i*column+j]);
			m_output+=temp;
		} 
		temp.Format("\r\n");
		m_output+=temp;
	}
	UpdateData(FALSE);   //print
}


void CVarianceDlg::OnBnClicked_S()//样本协方差阵
{
	//row 样本数,column 变量数

	if(row<2)
	{
		MessageBox("row<2,不能计算");
		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++)
		{
			mean[j]+=prow[i][j];
		}
		mean[j]/=row;
	}

	int i ,k,j;
	for( i=0;i<column;i++) //第一个变量
	{
		for(j=i; j<column;j++) //第二个变量
		{
			for(k=0; k<row;k++) //计算
			{
				cov[i*column+j] += ( prow[k][i]-mean[i] )*( prow[k][j]-mean[j] );

			}
			cov[i*column+j]/=(row-1);
			/*temp.Format("cov=%f,column=%d mean(%d)=%f,mean(%d)=%f",cov[i*column+j],row,i,mean[i],j,mean[j]);
			MessageBox(temp);*/
		}

	}

	for( i=0;i<column;i++) //补全对应面
	{
		for(j=0; j<i;j++) 
		{
			cov[i*column+j]=cov[j*column+i];
		}
	}
	m_output="均值向量:\r\n";
	for(int j=0;j<column;j++) //mean
	{
		temp.Format("%g   ",mean[j]);
		m_output+=temp;
	}
	temp.Format("\r\n ");
	m_output+=temp;
	m_output+="\r\n样本协方差阵S:\r\n";
	for( i=0;i<column;i++) //print
	{
		for(j=0; j<column;j++)
		{
			temp.Format("%g    ",cov[i*column+j]);
			m_output+=temp;
		} 		
		m_output+="\r\n";
	}
	UpdateData(FALSE);   //print
}

void CVarianceDlg::OnBnClicked_R()
{
	//row 样本数,column 变量数
	if(column==0)
	{
		MessageBox("先检查数据");
		return;
	}
	double *mean=new double[column];
	cov=new double[column*column];
	double *rr=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++)
		{
			mean[j]+=prow[i][j];
		}
		mean[j]/=row;
	}
	int i ,k,j;
	for( i=0;i<column;i++) //第一个变量
	{
		for(j=i; j<column;j++) //第二个变量
		{
			for(k=0; k<row;k++) //计算
			{
				cov[i*column+j] += ( prow[k][i]-mean[i] )*( prow[k][j]-mean[j] );
			}
			cov[i*column+j]/=(row);
		}	
	}
	for( i=0;i<column;i++) //补全对应面
	{
		for(j=0; j<i;j++) 
		{
			cov[i*column+j]=cov[j*column+i];
		}
	}
	for( i=0;i<column;i++) //第一个变量
	{
		for(j=0; j<column;j++) //第二个变量
		{
			rr[i*column+j]=cov[i*column+j]/sqrt(cov[i*column+i]*cov[j*column+j]);		
		}	
	}
	m_output+="\r\n相关系数阵R:\r\n";
	for( i=0;i<column;i++) //print
	{
		for(j=0; j<column;j++)
		{
			temp.Format("%g    ",rr[i*column+j]);
			m_output+=temp;
		} 		
		m_output+="\r\n";
	}
	UpdateData(FALSE);   //print
	delete []rr;
}


double det(int n,double *&aa)
{
	double *bb = new double[(n-1)*(n-1)];//创建n-1阶的代数余子式阵bb 	
	int p=0,//判断行是否移动
		q=0;//代数余子式
	if(n == 1) 
	{
		return aa[0]; 
	}
	double sum=0.0;//sum为行列式的值
	for(int ai=0;ai<n;ai++) // a的行数把矩阵a(nn)赋值到b(n-1)
	{
		for(int bi=0;bi<n-1;bi++)//把元素aa[ai][0]代数余子式存到bb[][]
		{
			if(ai>bi)    //ai行的代数余子式是:小于ai的行,aa与bb阵,同行赋值
				p=0;
			else         
				p=1;     //大于等于ai的行,取aa阵的ai+1行赋值给阵bb的bi行
			for(int j=0;j<n-1;j++)  //从aa的第二列赋值到第n列
			{
				bb[bi*(n-1)+j]=aa[(bi+p)*n+j+1];
			}
		}
		if(ai%2==0)  q=1;//因为列数为0,所以行数是偶数时候,代数余子式为-1.
		else  q=(-1);
		sum+= q* aa[ai*n] *det(n-1,bb);
	}
	return sum;
	delete []bb;
}

void CVarianceDlg::OnBnClickeddet()
{
	// TODO: 在此添加控件通知处理程序代码
	if(column==row)
	{
		temp.Format("det=%g",det(row,matrix_A ));
		MessageBox(temp);
	}
	else
	{
		MessageBox("行列不相等无法计算");
	}

}

void CVarianceDlg::OnBnClickedButton_dets()
{

	temp.Format("det=%f",det(column,cov ));
	MessageBox(temp);
}

void CVarianceDlg::adjoint(int n ,double *aa)
{
	//调动之前,检查时候方阵,这里默认为aa为方阵
	//确定本函数是否修改传入的数据 :no
	//调用函数内删除内存delete []padjoint;

	padjoint=new double[n*n];
	double *bb = new double[(n-1)*(n-1)];//创建n-1阶的代数余子式阵bb 

	int pi,pj, q;
	for(int ai=0;ai<n;ai++) // a的行数把矩阵a(nn)赋值到b(n-1)
	{
		for(int aj=0;aj<n;aj++)
		{
			for(int bi=0;bi<n-1;bi++)//把元素aa[ai][0]余子式存到bb[][]
			{
				for(int bj=0;bj<n-1;bj++)//把元素aa[ai][0]代数余子式存到bb[][]
				{
					if(ai>bi)    //ai行的代数余子式是:小于ai的行,aa与bb阵,同行赋值
						pi=0;
					else         
						pi=1;     //大于等于ai的行,取aa阵的ai+1行赋值给阵bb的bi行
					if(aj>bj)    //ai行的代数余子式是:小于ai的行,aa与bb阵,同行赋值
						pj=0;
					else         
						pj=1;     //大于等于ai的行,取aa阵的ai+1行赋值给阵bb的bi行
					bb[bi*(n-1)+bj]=aa[(bi+pi)*n+bj+pj];
				}
			}
			if((ai+aj)%2==0)  q=1;//因为列数为0,所以行数是偶数时候,代数余子式为-1.
			else  q=(-1);
			padjoint[ai*n+aj]=q*det(n-1,bb);  //加符号变为代数余子式
		}
	}
	delete []bb;
}
void CVarianceDlg::OnBnClicked_adjoint()
{
	if(column!=row)
	{	
		MessageBox("行列不相等,无法计算");
		return ;
	}
	adjoint(row,matrix_A);  ////计算

	m_output+="\r\n伴随阵: \r\n";
	for(int ai=0;ai<row;ai++) 
	{
		for(int aj=0;aj<row;aj++)
		{
			temp.Format("%g    ",padjoint[ai*row+aj]);
			m_output+=temp;
		}
		m_output+="\r\n";
	}
	UpdateData(FALSE);   //print
	delete []padjoint;
}

void CVarianceDlg::inverse(int n ,double *aa)
{
	//调动之前,检查时候方阵,这里默认为aa为方阵
	//确定本函数是否修改传入的数据 :no
	//调用函数内删除内存delete []pinverse;

	double det_aa=det(n,aa);
	if(det_aa==0)
	{
		MessageBox("行列式为0 ,不能计算逆矩阵。\n");
		return;
	}
	pinverse = new double[n*n]; //为成员变量分配内存

	adjoint(n,aa); //计算

	for( int i=0;i<n;i++) //print
	{
		for(int j=0; j<n;j++)
		{
			pinverse[i*n+j]=padjoint[i*n+j]/det_aa;
		} 	
	}
	delete []padjoint;
}

void CVarianceDlg::OnBnClicked_inverse()
{
	//计算A的逆
	if(column!=row)
	{	
		MessageBox("行列不相等,无法计算");
		return ;
	}
	double det_aa=det(row ,matrix_A);
	if(det_aa==0)
	{
		MessageBox("行列式为0 ,不能计算逆矩阵。\n");
		return;
	}
	inverse(row ,matrix_A);  //计算函数

	m_output+="\r\n逆矩阵:\r\n";
	for( int i=0;i<row;i++) //print
	{
		for(int j=0; j<row;j++)
		{
			temp.Format("%g    ",pinverse[i*row+j]);
			m_output+=temp;
		} 	
		m_output+="\r\n";
	}
	delete []pinverse;
	UpdateData(FALSE);   //print
}
void CVarianceDlg::AB(int ai ,int aj,int bj,double *aa,double *bb )
{
	//	调用函数内加上delete []pab;
	//  默认aj=bi
	if(ai==0||aj==0||bj==0)
	{	
		MessageBox("先输入A、B");
		return ;
	}
	pab = new double[ai*bj];
	for(int j=0;j<ai*bj;j++) //init
	{
		pab[j]=0.0;
	}
	for( int i=0;i<ai;i++) //print
	{
		for(int j=0; j<bj;j++)
		{
			for(int k=0; k<aj;k++)
			{

				pab[i*bj+j]+= aa[i*aj+k] * bb[k*bj+j];
				/*temp.Format("ab=%f  ,a=%f,b=%f  ",pab[i*bj+j],aa[i*aj+k] ,bb[k*bj+j]);
				MessageBox(temp);*/
			}
		} 	
	}

}
void CVarianceDlg::OnBnClicked_AB()
{
	// TODO: 在此添加控件通知处理程序代码
	if(column==0||row==0||column_b==0||row_b==0)
	{	
		MessageBox("先输入A、B");
		return ;
	}
	if(column!=row_b)
	{	
		MessageBox("A的列与B的行不相等,无法计算");
		return ;
	}
	AB(row ,column,column_b,matrix_A,matrix_B ); ///计算

	m_output+="\r\nA*B矩阵:   \r\n";
	for( int i=0;i<row;i++) //print
	{
		for(int j=0; j<column_b;j++)
		{
			temp.Format("%g    ",pab[i*column_b+j]);
			m_output+=temp;
		} 	
		m_output+="\r\n";
	}
	delete []pab;
	UpdateData(FALSE);   //print
}


void CVarianceDlg::OnBnClicked_Cramer()
{
	// TODO: 在此添加控件通知处理程序代码
	if(column==0||row==0)
	{	
		MessageBox("先输入 A");
		return ;
	}
	if(column!=row+1)
	{	
		MessageBox("column!=row+1");
		return ;
	}

	double *Dx = new double[row*row];
	for( int i=0; i<row;i++) 
	{
		for(int j=0; j<row;j++)
		{
			Dx[i*row+j]=matrix_A[i*column+j]; 
		} 	
	}
	double D=det(row,Dx);
	if(D==0)
	{
		MessageBox("Cramer法则只能计算系数矩阵为满秩的矩阵");
		return;
	}

	CString xx="\r\n x=";
	m_output+=xx;
	for( int j=0; j<row;j++) 
	{
		for( int i=0; i<row;i++) 
		{
			for(int j=0; j<row;j++)
			{
				Dx[i*row+j]=matrix_A[i*column+j]; 
			} 	
		}
		for(int i=0; i<row;i++)
		{
			Dx[i*row+j]=matrix_A[(i+1)*column-1]; //A的最后一列赋值给第j列
		} 	

		//m_output+="\r\n Dx矩阵: \r\n";

		//for( int i=0;i<row;i++) //print
		//{
		//	for(int j=0; j<row;j++)
		//	{
		//		temp.Format("A =%f   ",Dx[i*row+j]);
		//		m_output+=temp;
		//	} 	
		//	m_output+="\r\n";
		//}
		xx.Format("%g , ",det(row,Dx)/D);
		m_output+=xx;
	}

	m_output+="\r\n";
	delete []Dx;
	UpdateData(FALSE);   //print

}


void CVarianceDlg::OnBnClicked_Jacobi()
{
	/*
	公式:A=D-L-U
	A*x=b
	(D-L-U)*x=b
	D*x=(L+U)*x+b
	x=D^-1*(L+U)*x+b
	Bj=D^-1*(L+U)
	f=D^-1*b
	简写为:x=Bj*x+f
	*/
	/*
	8 -3 2 20
	4 11 -1 33
	2 1 4 12
	*/

	if(column==0||row==0)
	{	
		MessageBox("先输入 A");
		return ;
	}
	if(column!=row+1)
	{	
		MessageBox("column!=row+1");
		return ;
	}
	double *A = new double[row*row];//系数矩阵
	double *b = new double[row];    ///b
	double *x = new double[row];    //x
	double *Bjx = new double[row];  

	for( int i=0; i<row;i++)    
	{
		b[i]=matrix_A[(i+1)*column-1];  //b
		x[i]=0.0;                     //初始化解向量x  
		for(int j=0; j<row;j++)
		{
			A[i*row+j]=matrix_A[i*column+j]; //提取系数矩阵
		} 	
	}

	double aii;
	for( int i=0; i<row;i++)    
	{
		aii =A[i*row+i];   //处理i行对角线元素
		A[i*row+i]=0;
		b[i]=b[i]/aii;     //b转化为f=D^-1*b,at same time assign x[i]
		for(int j=0; j<row;j++)
		{	
			A[i*row+j]=-A[i*row+j]/aii; //A 转化为BJ
		} 	
	}
	//m_output+="\r\n BJ,b矩阵: \r\n";

	//for( int i=0;i<row;i++) //print
	//{
	//	for(int j=0; j<row;j++)
	//	{
	//		temp.Format("%f   ",A[i*row+j]);
	//		m_output+=temp;
	//	} 	
	//	temp.Format("%f   ",b[i]);
	//	m_output+=temp;
	//	m_output+="\r\n";
	//}
	//b用来存放x


	// 已知   Bj=A 和 f=b
	m_output+="\r\nJacobi 迭代:\r\n";
	for( int it=0;it<20;it++) //it 
	{
		for( int i=0; i<row;i++)    
		{
			Bjx[i]=0.0;   //每个循环都要赋0
		}

		for( int i=0;i<row;i++) //print
		{
			for(int k=0; k<row;k++)
			{
				Bjx[i]+= A[i*row+k] * x[k];   //A[i]=BJ*x

				/*	temp.Format("bjx=%f  , A=%f, x=%f  ",Bjx[i],A[i*row+k]  ,x[k]);
				MessageBox(temp);*/

			}

		}

		for( int i=0;i<row;i++) //print
		{
			x[i]=Bjx[i]+b[i];//b转化为f,
		}

		temp.Format("x%d :  ",it);m_output+=temp;
		for( int i=0;i<row;i++) //print
		{

			temp.Format("%g   ",x[i]);
			m_output+=temp;

		}
		m_output+="\r\n";

	}
	delete []Bjx;
	delete []x;
	delete []b;
	delete []A;
	UpdateData(FALSE);   //print
}



void CVarianceDlg::OnBnClicked_Gauss_Seidel()
{
	/*
	公式:A=D-L-U
	A*x=b
	(D-L-U)*x=b
	(D-L)*x[k+1]=U*x[k]+b
	x[k+1]=(D-L)^-1*U*x+ (D-L)^-1b
	Bg=(D-L)^-1*U
	fg=(D-L)^-1b
	简写为:x=Bg*x+fg
	*/
	if(column==0||row==0)
	{	
		MessageBox("先输入 A");
		return ;
	}
	if(column!=row+1)
	{	
		MessageBox("column!=row+1");
		return ;
	}
	double *A = new double[row*row];//系数矩阵
	double *b = new double[row];    ///b 后来存放fg=(D-L)^-1*b
	double *x = new double[row];    //x
   
	for( int i=0; i<row;i++)    
	{
		x[i]=0.0;                     //初始化x  
		b[i]=matrix_A[(i+1)*column-1];  //b		
		for(int j=0; j<row;j++)
		{
			A[i*row+j]=matrix_A[i*column+j]; //提取系数矩阵
		} 	
	}
	////////////BG,fg/////////////////////////
	for( int i=0; i<row;i++)    //除以aii
	{  
		double aii=A[i*row+i];
		A[i*row+i]=0;
		b[i]=b[i]/aii;
		for(int j=0; j<row;j++)
		{	
			A[i*row+j]=A[i*row+j]/aii; 	
		} 	
	}

	//m_output+="\r\nA:\r\n";
	//for( int i=0;i<row;i++) //print
	//{
	//	for(int j=0; j<row;j++)
	//	{
	//		temp.Format("A[%d,%d]=%f   ",i,j,A[i*row+j]);
	//		m_output+=temp;
	//	} 	
	//	temp.Format("b[%d]=%f   ",i,b[i]);
	//	m_output+=temp;
	//	m_output+="\r\n";
	//}
		/*
	8 -3 2 20
	4 11 -1 33
	2 1 4 12
	10.000000  -2.000000  -1.000000  3.000000  
	-2.000000  10.000000  -1.000000  15.000000  
	-1.000000  -2.000000  5.000000  10.000000  
	1 2 3
	*/
	m_output+="\r\nGauss_Seidel 迭代 :";
	for( int it=0; it<20;it++)    
	{
		for( int i=0; i<row;i++)    
		{ 
			double xx=0;
			for( int j=0; j<row;j++)    
			{
				xx-=A[i*row+j]*x[j];
			/*	temp.Format("%f    %f:  ",A[i*row+j ],x[i]);
				MessageBox(temp );*/
			}
			x[i]=xx+b[i];
		}
		temp.Format("\r\n x%d :  ",it);m_output+=temp;
		for( int i=0;i<row;i++) //print
		{
			temp.Format("%g   ",x[i]);
			m_output+=temp;
		}	
	}
    m_output+="\r\n";
	delete []A;
	delete []b;
	delete []x;
	UpdateData(FALSE);   //print
}

void CVarianceDlg::OnBn_Eigen()
{
	// TODO: 在此添加控件通知处理程序代码
	if(column!=row)
	{	
		MessageBox("行列不相等,无法计算");
		return ;
	}
	if(column==0||row==0)
	{	
		MessageBox("先输入 A 并且按save_A");
		return ;
	}
	Eigen::MatrixXd A (row,row);

	for(int i=0; i<row ;i++)
	for(int j=0; j<row ;j++)
		A(i,j)=matrix_A[i*row+j];
	 

	
	//A<< 1, 2, 3,4, 5, 6,   7, 8, 9;
	Eigen::EigenSolver<Eigen::MatrixXd> es(A);

	std::ostringstream os;
	std::string temp;
	os<< "The eigenvalues of A are:\r\n" << es.eigenvalues()  << std::endl;
	temp=os.str();
    m_output=temp.c_str();
	m_output.Replace( "(", "\t"); //回车换成字符#
 

	std::ostringstream os2;
	os2<< "The eigenvectors of A are:\r\n" <<es.eigenvectors() << std::endl;
	temp=os2.str();
    m_output+=temp.c_str();

	m_output.Replace("\n", "\r\n");  
	m_output.Replace( "(" , " " );  
	m_output.Replace(",0)", "\t");  
	//有复数的情况
	m_output.Replace(",-", " - ");  
	m_output.Replace(",", " + ");  
	m_output.Replace(")", " i");  
	UpdateData(FALSE);   //print
}


void CVarianceDlg::Onmenu_data()
{
	// TODO: 在此添加命令处理程序代码
	m_input="1 2 3\r\n4 5 6\r\n7 8 9";
	UpdateData(FALSE);   //print
}


void CVarianceDlg::OnAx_B_data()
{
	// TODO: 在此添加命令处理程序代码
	m_input="8 -3 2 20 \r\n4 11 -1 33 \r\n2 1 4 12";
	UpdateData(FALSE);   //print
}


void CVarianceDlg::OnAboutAbout()
{
	// TODO: 在此添加命令处理程序代码
	CAboutDlg dlg;
	dlg.DoModal(); 
}


void CVarianceDlg::but_PCA()
{
	// TODO: 在此添加控件通知处理程序代码

}


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

}

猜你喜欢

转载自blog.csdn.net/sinat_36219858/article/details/80224789