C#中矩阵运算方法实例分析

本文实例讲述了C#中矩阵运算方法。分享给大家供大家参考。具体分析如下:

一、测试环境:

主机:XP

开发环境:VS2008

二、功能:

在C#中实现矩阵运算

三、源代码:

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;
//矩阵数据结构
//二维矩阵
class _Matrix
{
 public int m;
 public int n;
 public float[] arr;
 //初始化
 public _Matrix()
 {
  m = 0;
  n = 0;
 }
 public _Matrix(int mm,int nn)
 {
  m = mm;
  n = nn;
 }
 //设置m
 public void set_mn(int mm,int nn)
 {
  m = mm;
  n = nn;
 } 

 //设置m
 public void set_m(int mm)
 {
  m = mm;
 }
 //设置n
 public void set_n(int nn)
 {
  n = nn;
 }
 //初始化
 public void init_matrix()
 {
  arr = new float[m * n];
 }
 //释放
 public void free_matrix()
 {
  //delete [] arr;
 }
 //读取i,j坐标的数据
 //失败返回-31415,成功返回值
 public float read(int i,int j)
 {
  if (i >= m || j >= n)
  {
   return -31415;
  }
  //return *(arr + i * n + j);
  return arr[i * n + j];
 }
 //写入i,j坐标的数据
 //失败返回-1,成功返回1
 public int write(int i,int j,float val)
 {
  if (i >= m || j >= n)
  {
   return -1;
  }
  arr[i * n + j] = val;
  return 1;
 }
};
//二维运算类
class _Matrix_Calc
{
 //初始化
 public _Matrix_Calc()
 {
 }
 //C = A + B
 //成功返回1,失败返回-1
 public int add(ref _Matrix A,ref _Matrix B,ref _Matrix C)
 {
  int i = 0;
  int j = 0;
  //判断是否可以运算
  if (A.m != B.m || A.n != B.n ||
   A.m != C.m || A.n != C.n)
  {
   return -1;
  }
  //运算
  for (i = 0;i < C.m;i++)
  {
   for (j = 0;j < C.n;j++)
   {
    C.write(i,j,A.read(i,j) + B.read(i,j));
   }
  }
  return 1;
 }
 //C = A - B
 //成功返回1,失败返回-1
 public int subtract(ref _Matrix A,ref _Matrix B, ref _Matrix C)
 {
  int i = 0;
  int j = 0;
  //判断是否可以运算
  if (A.m != B.m || A.n != B.n ||
   A.m != C.m || A.n != C.n)
  {
   return -1;
  }
  //运算
  for (i = 0;i < C.m;i++)
  {
   for (j = 0;j < C.n;j++)
   {
    C.write(i,j,A.read(i,j) - B.read(i,j));
   }
  }
  return 1;
 }
 //C = A * B
 //成功返回1,失败返回-1
 public int multiply(ref _Matrix A, ref _Matrix B, ref _Matrix C)
 {
  int i = 0;
  int j = 0;
  int k = 0;
  float temp = 0;
  //判断是否可以运算
  if (A.m != C.m || B.n != C.n ||
   A.n != B.m)
  {
   return -1;
  }
  //运算
  for (i = 0;i < C.m;i++)
  {
   for (j = 0;j < C.n;j++)
   {
    temp = 0;
    for (k = 0;k < A.n;k++)
    {
     temp += A.read(i,k) * B.read(k,j);
    }
    C.write(i,j,temp);
   }
  }
  return 1;
 }
 //行列式的值,只能计算2 * 2,3 * 3
 //失败返回-31415,成功返回值
 public float det(ref _Matrix A)
 {
  float value = 0;
  //判断是否可以运算
  if (A.m != A.n || (A.m != 2 && A.m != 3))
  {
   return -31415;
  }
  //运算
  if (A.m == 2)
  {
   value = A.read(0,0) * A.read(1,1) - A.read(0,1) * A.read(1,0);
  }
  else
  {
   value = A.read(0,0) * A.read(1,1) * A.read(2,2) +
     A.read(0,1) * A.read(1,2) * A.read(2,0) +
     A.read(0,2) * A.read(1,0) * A.read(2,1) -
     A.read(0,0) * A.read(1,2) * A.read(2,1) -
     A.read(0,1) * A.read(1,0) * A.read(2,2) -
     A.read(0,2) * A.read(1,1) * A.read(2,0);
  }
  return value;
 }
 //求转置矩阵,B = AT
 //成功返回1,失败返回-1
 public int transpos(ref _Matrix A,ref _Matrix B)
 {
  int i = 0;
  int j = 0;
  //判断是否可以运算
  if (A.m != B.n || A.n != B.m)
  {
   return -1;
  }
  //运算
  for (i = 0;i < B.m;i++)
  {
   for (j = 0;j < B.n;j++)
   {
    B.write(i,j,A.read(j,i));
   }
  }
  return 1;
 }
 //求逆矩阵,B = A^(-1)
 //成功返回1,失败返回-1
 public int inverse(ref _Matrix A, ref _Matrix B)
 {
  int i = 0;
  int j = 0;
  int k = 0;
  _Matrix m = new _Matrix(A.m,2 * A.m);
  float temp = 0;
  float b = 0;
  //判断是否可以运算
  if (A.m != A.n || B.m != B.n || A.m != B.m)
  {
   return -1;
  }
  /*
  //如果是2维或者3维求行列式判断是否可逆
  if (A.m == 2 || A.m == 3)
  {
   if (det(A) == 0)
   {
    return -1;
   }
  }
  */
  //增广矩阵m = A | B初始化
  m.init_matrix();
  for (i = 0;i < m.m;i++)
  {
   for (j = 0;j < m.n;j++)
   {
    if (j <= A.n - 1)
    {
     m.write(i,j,A.read(i,j));
    }
    else
    {
     if (i == j - A.n)
     {
      m.write(i,j,1);
     }
     else
     {
      m.write(i,j,0);
     }
    }
   }
  }
  //高斯消元
  //变换下三角
  for (k = 0;k < m.m - 1;k++)
  {
   //如果坐标为k,k的数为0,则行变换
   if (m.read(k,k) == 0)
   {
    for (i = k + 1;i < m.m;i++)
    {
     if (m.read(i,k) != 0)
     {
      break;
     }
    }
    if (i >= m.m)
    {
     return -1;
    }
    else
    {
     //交换行
     for (j = 0;j < m.n;j++)
     {
      temp = m.read(k,j);
      m.write(k,j,m.read(k + 1,j));
      m.write(k + 1,j,temp);
     }
    }
   }
   //消元
   for (i = k + 1;i < m.m;i++)
   {
    //获得倍数
    b = m.read(i,k) / m.read(k,k);
    //行变换
    for (j = 0;j < m.n;j++)
    {
     temp = m.read(i,j) - b * m.read(k,j);
     m.write(i,j,temp);
    }
   }
  }
  //变换上三角
  for (k = m.m - 1;k > 0;k--)
  {
   //如果坐标为k,k的数为0,则行变换
   if (m.read(k,k) == 0)
   {
    for (i = k + 1;i < m.m;i++)
    {
     if (m.read(i,k) != 0)
     {
      break;
     }
    }
    if (i >= m.m)
    {
     return -1;
    }
    else
    {
     //交换行
     for (j = 0;j < m.n;j++)
     {
      temp = m.read(k,j);
      m.write(k,j,m.read(k + 1,j));
      m.write(k + 1,j,temp);
     }
    }
   }
   //消元
   for (i = k - 1;i >= 0;i--)
   {
    //获得倍数
    b = m.read(i,k) / m.read(k,k);
    //行变换
    for (j = 0;j < m.n;j++)
    {
     temp = m.read(i,j) - b * m.read(k,j);
     m.write(i,j,temp);
    }
   }
  }
  //将左边方阵化为单位矩阵
  for (i = 0;i < m.m;i++)
  {
   if (m.read(i,i) != 1)
   {
    //获得倍数
    b = 1 / m.read(i,i);
    //行变换
    for (j = 0;j < m.n;j++)
    {
     temp = m.read(i,j) * b;
     m.write(i,j,temp);
    }
   }
  }
  //求得逆矩阵
  for (i = 0;i < B.m;i++)
  {
   for (j = 0;j < B.m;j++)
   {
    B.write(i,j,m.read(i,j + m.m));
   }
  }
  //释放增广矩阵
  m.free_matrix();
  return 1;
 }
};
namespace test
{
 public partial class Form1 : Form
 {
  double zk;
  double xkg, pkg, kk, xk, pk, q, r;
  public Form1()
  {
   InitializeComponent();
   xk = 0;
   pk = 0;
   q = 0.00001;
   r = 0.0001;

   int i = 0;
   int j = 0;
   int k = 0;
   _Matrix_Calc m_c = new _Matrix_Calc();
   //_Matrix m1 = new _Matrix(3,3);
   //_Matrix m2 = new _Matrix(3,3);
   //_Matrix m3 = new _Matrix(3,3);
   _Matrix m1 = new _Matrix(2, 2);
   _Matrix m2 = new _Matrix(2, 2);
   _Matrix m3 = new _Matrix(2, 2);
   //初始化内存
   m1.init_matrix();
   m2.init_matrix();
   m3.init_matrix();
   //初始化数据
   k = 1;
   for (i = 0;i < m1.m;i++)
   {
    for (j = 0;j < m1.n;j++)
    {
     m1.write(i,j,k++);
    }
   }
   for (i = 0;i < m2.m;i++)
   {
    for (j = 0;j < m2.n;j++)
    {
     m2.write(i,j,k++);
    }
   }
   m_c.multiply(ref m1,ref m2, ref m3);
   //output.Text = Convert.ToString(m3.read(1,1));
   output.Text = Convert.ToString(m_c.det(ref m1));
  }
  /*
  private void button1_Click(object sender, EventArgs e)
  {
   zk = Convert.ToDouble(input.Text);
   //时间方程
   xkg = xk;
   pkg = pk + q;
   //状态方程
   kk = pkg / (pkg + r);
   xk = xkg + kk * (zk - xkg);
   pk = (1 - kk) * pkg;
   //输出
   output.Text = Convert.ToString(xk);
  }
  private void textBox1_TextChanged(object sender, EventArgs e)
  {
  }
   * */
 }
}

希望本文所述对大家的C#程序设计有所帮助。

(0)

相关推荐

  • C#编写的windows计算器的实例代码

    复制代码 代码如下: using System; using System.Drawing; using System.Windows; using System.Windows.Forms; using System.Collections; using System.ComponentModel; using System.Data; namespace comput {     /// <summary>     /// 这是一个计算器的简单实现.     /// </summar

  • c#数学表示法(后缀表示法)详解

    在笔试中有这么一道题目,写出一个表达式的后缀表示形式,当时就迷茫了,什么是后缀表达式,还真没听过.后来查了下原来是一种比较特殊的数学表达式,因为在日常生活中用的不多,不太了解.有三种表达式:前缀表达式.中缀表达式和后缀表达式.一般用的是中缀,比如1+1,前后缀就是把操作符移到前面和后面,下面我就来介绍一下这三种表达式. 1.前缀表示法 前缀表示法又叫波兰表示法,他的操作符置于操作数的前面(例:+ 1 2),是波兰数学家扬·武卡谢维奇1920年代引入的,用于简化命题逻辑.因为我们一般认为操作符是在

  • C#日历样式的下拉式计算器实例讲解

    本文介绍了如何在Visual Studio中创建用户控件来显示下拉式计算器,弹出效果类似于日历控件. 介绍 如果我们正在做一个类似于库存控制和计费系统的项目,有些部分可能必须手动计算数值.因此,用户就不得不使用计算器得到结果,再填入到输入字段中,或者在工作窗口上单独打开一个计算器窗口.总之,各种不便和麻烦. 这篇文章主要描述的是如何添加下拉式计算器到DataGridView单元格中,如下图: 使用代码 第一步,我们必须先创建一个函数计算器,并且能够使用控件.因此,不妨先创建一个Visual St

  • c#入门之实现简易存款利息计算器示例

    本想把练习题做了的结果放上来,不过发现附录是有答案的,就算了吧,自己做了没问题就行了哈.之前提到过,要是有朋友有想法,需要做小工具我可以帮忙实现,不过貌似大家都很忙.SO,自己学完第4章后,决定做一个工具:简易存款利息计算器,可以更好地复习前面学过的知识. 原理介绍为啥叫简易呢,因为现在只能计算整存整取(只有1.2.3.5四种年限哈)的利息,并且没有启用自动转存(俗称利滚利,就是把本年和上年的利息之和,作为下年利息计算时的本金)功能,方便和网上已有的工具对比计算结果,判断自己的程序算出来正不正确

  • C#中math类的全部运算方法(总结)

    如下所示: Abs 返回指定数字的绝对值. Acos 返回余弦值为指定数字的角度. Asin 返回正弦值为指定数字的角度. Atan 返回正切值为指定数字的角度. Atan2 返回正切值为两个指定数字的商的角度. BigMul 生成两个 32 位数字的完整乘积. Ceiling 返回大于或等于指定数字的最小整数. Cos 返回指定角度的余弦值. Cosh 返回指定角度的双曲余弦值. DivRem 计算两个数字的商,并在输出参数中返回余数. Exp 返回 e 的指定次幂. Floor 返回小于或等

  • C#计算器编写代码

    利用C#编写一个计算器.如下图,能够完成基本的四则运算. 当然这个程序甚至还不上Windows附件那个自带的多功能计算器.  不过这个程序的逻辑还是非常值得思考的,首先你要考虑好用户按+ - * / =等运算符号.数字键之后计算器的状态记录问题.  然后要防止多次按某一个键的问题.比如小数点.就不应该让用户在输入一个数的时候键入两次.  最后,还要弄两个数组,一个存放用户在输入的数字,另一个存放用户输入的符号.  制作过程如下,  1.布局如下,同时可以参考<简单实现C#窗体程序判断是否闰年 >

  • C#基于纯数学方法递归实现货币数字转换中文功能详解

    本文实例讲述了C#基于纯数学方法递归实现货币数字转换中文功能.分享给大家供大家参考,具体如下: 最近由于项目的原因,需要写一个货币数字转换中文的算法,先在网了找了一下,结果发现无一列外都是用(Replace)替换的方式来实现的,所以想写个另外的算法:因为本人是学数学出身的,所以用纯数学的方法实现. 注意:本文中的算法支持小于1023 (也就是9999亿兆)货币数字转化. 货币中文说明: 在说明代码之前,首先让我们回顾一下货币的读法. 10020002.23  读为 壹仟零贰万零贰元贰角叁分 10

  • C#编程自学之运算符和表达式

    我们了解完C#数据类型与变量之后,还会遇到变量之间的运算,例如计算两个数的和等等运算.那么,C#中都有那些常用的运算符呢?那么,往下看吧! 一.算数运算符 1.基本算数运算符 说到算数运算符,我们首先就应该可以想到我们数学中一些常用的运算符例如:加 减 乘 除 求余! 那么在C# 这些运算符都是如何表示的呢? 知道C#基本运算符的表示之后我们该如何去使用呢?那么我们来看段代码来看下什么是表达式. int a = 10; //定义一个整形变量a 值为10 int b = 20; //定义一个整形变

  • C#实现简单的计算器功能完整实例

    本文实例讲述了C#实现简单的计算器功能.分享给大家供大家参考,具体如下: 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; using System.Collections; usi

  • C#实现Winform版计算器

    本文实例为大家分享Winform版计算器的具体实现方法,供大家参考,具体内容如下 前台页面设计 后台代码实现 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 计

随机推荐

其他