软件界面图
代码文件Matrix.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Matrix
{
public partial class Matrix : Form
{
public Matrix()
{
InitializeComponent();
}
//成员变量、、、、、、、、、、、、、、、
int row = 0;
int column = 0;
int row_b = 0;
int column_b = 0;
string str;
double[] cov; //协方差矩阵
bool cov_flag = false;
double[] padjoint; //伴随矩阵 的返回数组
double[] pinverse; //逆矩阵 的返回数组
double[] matrix_A;
double[] matrix_B;
double[] pab; //A*B
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void save_A(object sender, EventArgs e)
{
if (text_in.Text.Equals(""))
{
MessageBox.Show(" Please input matrix_A ! ");
return;
}
List<double> temp_list = new List<double>(); //临时list 存数据
row = 0;
column = 0;
int cmax = 0;
str = text_in.Text.Replace("\r\n", " # ");
// MessageBox.Show(str);
str = str.TrimEnd("# ".ToCharArray()); //
//MessageBox.Show(str);
bool row1 = true;
int index = str.IndexOf(" ");
string[] Array = str.Split(new Char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string ii in Array)
{
string ss = ii.ToString();
row++;
//MessageBox.Show( string.Format("row={0}, ", ss));
string[] subArray = ss.Split(new Char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string i in subArray)
{
cmax++;
try
{
temp_list.Add(Convert.ToDouble(i.ToString()));
}
catch
{
MessageBox.Show(string.Format("第{0}行{1}列有非数字字符 ",row ,cmax));
return;
}
}
if (row1 == true)
{
column = cmax;
row1 = false;
}
if (cmax != column)
{
MessageBox.Show("每行元素数量不相等,\r\n修改后再读取!");
return;
}
cmax = 0;
}
///开始存储
matrix_A = new double[row * column]; /* 把list的数据存到数组 matrix_A[] */
text_out.Text = string.Format("row={0} column={1} \r\n\r\n", row.ToString(), column.ToString());
for (int i = 0; i < row ; i++)
{
for (int j = 0; j < column; j++)
{
matrix_A[i * column + j] = temp_list[i * column + j];
text_out.Text += string.Format("{0} ", matrix_A[i * column + j]);
}
text_out.Text += "\r\n";
}
}
private void clear_out(object sender, EventArgs e)
{
text_out.Text = "";
}
private void save_B(object sender, EventArgs e)
{
if (text_in.Text.Equals(""))
{
MessageBox.Show(" Please input matrix_B ! ");
return;
}
row_b = 0;
column_b = 0;
int cmax = 0 ;
List<double> temp_list = new List<double>(); //临时list 存数据
str = text_in.Text.Replace("\r\n", " # ");
// MessageBox.Show(str);
str = str.TrimEnd("# ".ToCharArray()); //
//MessageBox.Show(str);
bool row1 = true;
int index = str.IndexOf(" ");
string[] Array = str.Split(new Char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string ii in Array)
{
string ss = ii.ToString();
row_b++;
//MessageBox.Show( string.Format("row={0}, ", ss));
string[] subArray = ss.Split(new Char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string i in subArray)
{
cmax++;
try
{
temp_list.Add(Convert.ToDouble(i.ToString()));
}
catch
{
MessageBox.Show(string.Format("第{0}行{1}列有非数字字符 ", row_b, cmax));
return;
}
}
if (row1 == true)
{
column_b = cmax;
row1 = false;
}
if (cmax != column_b)
{
MessageBox.Show("每行元素数量不相等,\r\n修改后再读取!");
return;
}
cmax = 0;
}
text_out.Text = string.Format("row_b={0} column_b={1} \r\n\r\n", row_b.ToString(), column_b.ToString());
matrix_B = new double[row_b * column_b]; /* n 是一个带有 10 个整数的数组 */
for (int i = 0; i < row_b; i++)
{
for (int j = 0; j < column_b; j++)
{
matrix_B[i * column_b + j] = temp_list[i * column_b + j];
text_out.Text += string.Format("{0} ", matrix_B[i * column_b + j]);
}
text_out.Text += "\r\n";
}
}
private void cov_A(object sender, EventArgs e)
{
//row 样本数,column 变量数
if (column == 0)
{
MessageBox.Show("先检查数据");
return;
}
double[] mean = new double[column];
cov = new double[column * column];
cov_flag = true; //表示已经创建协方差矩阵
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] += matrix_A[i * column + j];
}
mean[j] /= row;
}
for (int i = 0; i < column; i++) //第一个变量
{
for (int j = i; j < column; j++) //第二个变量
{
for (int k = 0; k < row; k++) //计算
{
cov[i * column + j] += (matrix_A[k * column + i] - mean[i]) * (matrix_A[k * column + 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 (int i = 0; i < column; i++) //补全对应面
{
for (int j = 0; j < i; j++)
{
cov[i * column + j] = cov[j * column + i];
}
}
text_out.Text = "均值向量:\r\n";
for (int j = 0; j < column; j++) //mean
{
// temp.Format("%f ", mean[j]);
text_out.Text += string.Format("{0} ", (float)mean[j]);
}
text_out.Text += "\r\n协方差阵S:\r\n";
for (int i = 0; i < column; i++) //print
{
for (int j = 0; j < column; j++)
{
text_out.Text += string.Format("{0} ", (float)cov[i * column + j]);
}
text_out.Text += "\r\n";
}
}
private void cov_S_A(object sender, EventArgs e)
{
//row 样本数,column 变量数
if (column == 0)
{
MessageBox.Show("先检查数据");
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] += matrix_A[i * column + j];
}
mean[j] /= row;
}
for (int i = 0; i < column; i++) //第一个变量
{
for (int j = i; j < column; j++) //第二个变量
{
for (int k = 0; k < row; k++) //计算
{
cov[i * column + j] += (matrix_A[k * column + i] - mean[i]) * (matrix_A[k * column + j] - mean[j]);
}
cov[i * column + j] /= (row - 1);
}
}
for (int i = 0; i < column; i++) //补全对应面
{
for (int j = 0; j < i; j++)
{
cov[i * column + j] = cov[j * column + i];
}
}
text_out.Text = "均值向量:\r\n";
for (int j = 0; j < column; j++) //mean
{
// temp.Format("%f ", mean[j]);
text_out.Text += string.Format("{0} ", (float)mean[j]);
}
text_out.Text += "\r\n样本方差阵S:\r\n";
for (int i = 0; i < column; i++) //print
{
for (int j = 0; j < column; j++)
{
text_out.Text += string.Format("{0} ", (float)cov[i * column + j]);
}
text_out.Text += "\r\n";
}
}
double det(int n, double[] ab)
{
double[] aa = new double[n * n];
for (int i = 0; i < n * n; i++) /*赋值*/
aa[i] = ab[i];
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;
}
private void det_A(object sender, EventArgs e)
{
if (column == row)
{
text_out.Text =string.Format("|A|={0}", (float)det(row, matrix_A));
}
else
{
MessageBox.Show("行列不相等无法计算");
}
}
private void det_S(object sender, EventArgs e)
{
if (cov_flag == false)
{
MessageBox.Show("先计算协方差,在计算协方差的行列式");
return;
}
else
{
text_out.Text = string.Format("|S|={0}", (float)det(column, cov));
}
}
void adjoint(int n, double[] aa)
{
//调动之前,检查时候方阵,这里默认为aa为方阵
//确定本函数是否修改传入的数据 :no
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); //加符号变为代数余子式
}
}
}
private void Adjoint(object sender, EventArgs e)
{
if (column != row)
{
MessageBox.Show("行列不相等,无法计算");
return;
}
if (column ==0|| row==0)
{
MessageBox.Show("先输入数据");
return;
}
adjoint(row, matrix_A); ////计算
text_out.Text += "\r\n伴随阵: \r\n";
for (int ai = 0; ai < row; ai++)
{
for (int aj = 0; aj < row; aj++)
{
text_out.Text += string.Format("{0} ", padjoint[ai * row + aj]);
}
text_out.Text += "\r\n";
}
}
void inverse(int n, double[] aa)
{
//调动之前,检查时候方阵,这里默认为aa为方阵
//确定本函数是否修改传入的数据 :no
//调用函数内删除内存delete []pinverse;
double det_aa = det(n, aa);
if (det_aa == 0)
{
MessageBox.Show("行列式为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;
}
}
}
private void Inverse(object sender, EventArgs e)
{
//计算A的逆
if (column != row)
{
MessageBox.Show ("行列不相等,无法计算");
return;
}
if (column == 0 || row == 0)
{
MessageBox.Show("先输入数据");
return;
}
inverse(row, matrix_A); //计算函数
text_out.Text += "\r\n逆矩阵:\r\n";
for (int i = 0; i < row; i++) //print
{
for (int j = 0; j < row; j++)
{
text_out.Text += string.Format("{0} ", pinverse[i * row + j]);
}
text_out.Text += "\r\n";
}
}
private void R_A(object sender, EventArgs e)
{
//row 样本数,column 变量数
if (column == 0)
{
MessageBox.Show ("先检查数据");
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] += matrix_A[i*column+j];
}
mean[j] /= row;
}
for (int i = 0; i < column; i++) //第一个变量
{
for (int j = i; j < column; j++) //第二个变量
{
for (int k = 0; k < row; k++) //计算
{
cov[i * column + j] += (matrix_A[k * column + i] - mean[i]) * (matrix_A[k*column+j] - mean[j]);
}
cov[i * column + j] /= (row);
}
}
for (int i = 0; i < column; i++) //补全对应面
{
for (int j = 0; j < i; j++)
{
cov[i * column + j] = cov[j * column + i];
}
}
for (int i = 0; i < column; i++) //第一个变量
{
for (int j = 0; j < column; j++) //第二个变量
{
rr[i * column + j] = cov[i * column + j] / Math.Sqrt(cov[i * column + i] * cov[j * column + j]);
}
}
text_out.Text += "\r\n相关系数阵R:\r\n";
for (int i = 0; i < column; i++) //print
{
for (int j = 0; j < column; j++)
{
text_out.Text += string.Format("{0} ", (float)rr[i * column + j]);
}
text_out.Text += "\r\n";
}
}
void a_b(int ai, int aj, int bj, double[] aa, double[] bb)
{
// 调用函数内加上delete []pab;
// 默认aj=bi
if (ai == 0 || aj == 0 || bj == 0)
{
MessageBox.Show("先输入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);*/
}
}
}
}
private void A_B(object sender, EventArgs e)
{
// TODO: 在此添加控件通知处理程序代码
text_out.Text = "";
if (column == 0 || row == 0 || column_b == 0 || row_b == 0)
{
MessageBox.Show("先输入A、B");
return;
}
if (column != row_b)
{
MessageBox.Show("A的列与B的行不相等,无法计算");
return;
}
a_b(row, column, column_b, matrix_A, matrix_B); ///计算
text_out.Text += "A*B矩阵: \r\n";
for (int i = 0; i < row; i++) //print
{
for (int j = 0; j < column_b; j++)
{
text_out.Text += string.Format("{0} ", (float)pab[i * column_b+j]);
}
text_out.Text += "\r\n";
}
}
private void Gramer(object sender, EventArgs e)
{
// TODO: 在此添加控件通知处理程序代码
if (column == 0 || row == 0)
{
MessageBox.Show("先输入 A");
return;
}
if (column != row + 1)
{
MessageBox.Show("解方程组A*x=b 需要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.Show("Cramer法则只能计算系数矩阵为满秩的矩阵");
return;
}
text_out.Text = "\r\n x=";
for (int k = 0; k < row; k++)
{
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 + k] = matrix_A[(i + 1) * column - 1]; //A的最后一列赋值给第j列
}
text_out.Text += string.Format("{0} ", (float )(det(row, Dx) / D));
}
//text_out.Text += "\r\n";
}
private void Jacobi(object sender, EventArgs e)
{
/*
8 -3 2 20
4 11 -1 33
2 1 4 12
*/
if (column == 0 || row == 0)
{
MessageBox.Show ("先输入 A");
return;
}
if (column != row + 1)
{
MessageBox.Show("解方程组A*x=b 需要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
}
}
text_out.Text = "Jacobi 迭代:\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
}
}
for (int i = 0; i < row; i++) //print
{
x[i] = Bjx[i] + b[i];//b转化为f,
}
text_out.Text += string.Format("x{0}: ",it);
for (int i = 0; i < row; i++) //print
{
text_out.Text += string.Format("{0} ", (float)x[i]);
}
text_out.Text += "\r\n";
}
}
private void Gauss_seidel(object sender, EventArgs e)
{
if (column == 0 || row == 0)
{
MessageBox.Show ("先输入 A");
return;
}
if (column != row + 1)
{
MessageBox.Show("解方程组A*x=b 需要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;
}
}
/*
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
*/
text_out.Text = "Gauss_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];
}
text_out.Text += string.Format("\r\nx{0}: ", it);
for (int i = 0; i < row; i++) //print
{
text_out.Text += string.Format("{0} ", (float)x[i]);
}
}
}
private void 关于ToolStripMenuItem1_Click(object sender, EventArgs e)
{
About form = new About();
form.Show();
}
private void illustration(object sender, EventArgs e)
{
MessageBox.Show("在浅色文本框输入数据,\r\n每个数据以空格和换行分开,\r\n输入完成后点击save_A或save_B,\r\n然后在点击相应的计算。");
}
private void Example(object sender, EventArgs e)
{
text_in.Text = "8 -3 2\r\n4 11 -1\r\n2 1 4";
}
private void explain_Gramer(object sender, EventArgs e)
{
MessageBox.Show("Gramer法则用于计算系数矩阵满秩的齐次方程组");
}
private void example_data(object sender, EventArgs e)
{
text_in.Text = "8 -3 2 20 \r\n4 11 -1 33 \r\n2 1 4 12";
}
private void explain_RA(object sender, EventArgs e)
{
MessageBox.Show("矩阵A的相关系数阵主对角线元素为1,其它为Rij=cov(x,y)/sqrt(D(X)*D(Y))");
}
}
}