博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 简单的矩阵运算
阅读量:4096 次
发布时间:2019-05-25

本文共 25776 字,大约阅读时间需要 85 分钟。

软件界面图

这里写图片描述

代码文件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
temp_list = new List
(); //临时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
temp_list = new List
(); //临时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))"); } }}
你可能感兴趣的文章
Java编程基础:static的用法
查看>>
Java编程基础:抽象类和接口
查看>>
Java编程基础:异常处理
查看>>
Java编程基础:了解面向对象
查看>>
新一代Java模板引擎Thymeleaf
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
Spring Boot构建简单的微博应用
查看>>
Spring处理表单提交
查看>>
Spring MVC异常处理
查看>>
Leetcode 1180. Count Substrings with Only One Distinct Letter [Python]
查看>>
PHP 7 的五大新特性
查看>>
php使用 memcache 来存储 session
查看>>
php实现socket(转)
查看>>
PHP底层的运行机制与原理
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
PHP7新特性 What will be in PHP 7/PHPNG
查看>>
比较strtr, str_replace和preg_replace三个函数的效率
查看>>
ubuntu 下编译PHP5.5.7问题:configure: error: freetype.h not found.
查看>>