线性代数之行列式的C#研究实现

最近学习机器学习 才发现以前数学没有学好 开始从线性代数开始学起 读完行列式一章写了些C#的代码学习一下。

直接上C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;

namespace LYF.Math
{
    /// <summary>
    /// 行列式 Determinant
    /// </summary>
    [SerializableAttribute]
    [ComVisibleAttribute(true)]
    public class Determinant<T> where T : IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
    {
        T[,] tarr = null;
        public Determinant(int n)
        {
            tarr = new T[n, n];
        }

        public Determinant(T[,] arrT)
        {
            if (arrT == null || arrT.GetLength(0) != arrT.GetLength(1) || arrT.GetLength(0) < 1)
            {
                throw new MathException("不正确的数组(数组必须行列数相同且大于1)");
            }
            else
            {
                tarr=new T[arrT.GetLength(0),arrT.GetLength(0)];
                SetItem(arrT);
            }
        }

        /// <summary>
        /// 获取元素值
        /// </summary>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <returns></returns>
        public T this[int i, int j]
        {
            //实现索引器的get方法
            get
            {
                return GetItem(i, j);
            }

            //实现索引器的set方法
            set
            {
                SetItem(i, j, value);
            }
        }

        /// <summary>
        /// 获取元素的余子式
        /// </summary>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <returns></returns>
        public Determinant<T> A(int i, int j)
        {
            if (N == 1)
            {
                return null;
            }
            else if (i>N||j>N)
            {
                return null;
            }
            else
            {
                Determinant<T> a = new Determinant<T>(N - 1);
                for (int m = 1; m <= N - 1; m++)
                {
                    for (int n = 1; n <= N - 1; n++)
                    {
                        int p = m, q = n;
                        if (p >= i)
                        {
                            p = m + 1;
                        }
                        if (q >= j)
                        {
                            q = n + 1;
                        }
                        a[m, n] = this[p,q];
                    }
                }
                return a;
            }
        }

        /// <summary>
        /// 设置行列式的值
        /// </summary>
        /// <param name="i">行数(从1开始)</param>
        /// <param name="j">列数(从1开始)</param>
        /// <param name="value">值</param>
        public void SetItem(int i, int j, T value)
        {
            if (tarr == null)
            {
                throw new MathException("行列式未正确初始化");
            }
            else if (i > N || j > N)
            {
                throw new MathException("超出行列式索引范围");
            }
            else
            {
                tarr[i - 1, j - 1] = value;
            }
        }

        public void SetItem(T[,] arrT)
        {
            if (arrT == null || tarr == null)
            {
                throw new MathException("不能为空");
            }
            else if (arrT.GetLength(0) != N || arrT.GetLength(1) != N)
            {
                throw new MathException("传入阶数不同");
            }
            else
            {
                for (int m = 0; m <=N-1; m++)
                {
                    for (int n = 0; n <= N- 1; n++)
                    {
                        this[m + 1, n + 1] = arrT[m, n];
                    }
                }
            }
        }

        /// <summary>
        /// 设置行列式的值
        /// </summary>
        /// <param name="i">行数(从1开始)</param>
        /// <param name="j">列数(从1开始)</param>
        /// <param name="value">值</param>
        public T GetItem(int i, int j)
        {
            if (tarr == null)
            {
                throw new MathException("行列式未正确初始化");
            }
            else if (i > N || j > N)
            {
                throw new MathException("超出行列式索引范围");
            }
            else
            {
                return tarr[i-1, j-1];
            }
        }

        /// <summary>
        /// 输出行列式信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder sbRs = new StringBuilder();
            if(tarr!=null)
            {
                for (int m = 0; m <= N - 1; m++)
                {
                    for (int n = 0; n <= N - 1; n++)
                    {
                        sbRs.Append(string.Format("{0}\t", tarr[m, n]));
                    }
                    sbRs.Append("\n");
                }

            }
            return sbRs.ToString();
        }

        /// <summary>
        /// 获取行列式的阶数
        /// </summary>
        public int N
        {
            get{
                if (tarr != null)
                {
                    return tarr.GetLength(0);
                }
                else
                {
                    return 0;
                }
            }

        }

        private string typeName = string.Empty;
        private string GetType()
        {
            if (string.IsNullOrEmpty(typeName))
            {
                typeName=typeof(T).Name;
                File.AppendAllText("E:\\op.txt", typeName);
            }
            return typeName;

        }

        /// <summary>
        /// 获取行列式的值
        /// </summary>
        public T Value
        {
            get
            {
                if (N == 1)
                {
                    return tarr[0, 0];
                }
                else if (N == 2)
                {
                    return Minus(MUL(tarr[0, 0], tarr[1, 1]), MUL(tarr[0, 1], tarr[1, 0]));
                }
                else
                {
                    T sum = default(T);
                    for (int i = 1; i <= N; i++)
                    {
                        if ((1+i) % 2 == 0)
                        {
                            //余子式正值
                            sum = Add(sum, MUL(this[1, i], this.A(1, i).Value));
                        }
                        else
                        {
                            //余子式负值
                            sum = Minus(sum, MUL(this[1, i], this.A(1, i).Value));
                        }
                    }
                    return sum;
                }

            }
        }

        /// <summary>
        /// 加法
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        private T Add(T left, T right)
        {
            switch (GetType())
            {
                case "Int16":
                    return ((T)(object)((short)(object)left + (short)(object)right));
                case "Int32":
                    return ((T)(object)((int)(object)left + (int)(object)right));
                case "Int64":
                    return ((T)(object)((long)(object)left + (long)(object)right));
                case "Single":
                    return ((T)(object)((float)(object)left + (float)(object)right));
                case "Double":
                    return ((T)(object)((double)(object)left + (double)(object)right));
                case "Decimal":
                    return ((T)(object)((decimal)(object)left + (decimal)(object)right));
            }
            throw new MathException("不支持的操作类型");
        }

        /// <summary>
        /// 减法
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        private T Minus(T left, T right)
        {
            switch (GetType())
            {
                case "Int16":
                    return ((T)(object)((short)(object)left - (short)(object)right));
                case "Int32":
                    return ((T)(object)((int)(object)left - (int)(object)right));
                case "Int64":
                    return ((T)(object)((long)(object)left - (long)(object)right));
                case "Single":
                    return ((T)(object)((float)(object)left - (float)(object)right));
                case "Double":
                    return ((T)(object)((double)(object)left - (double)(object)right));
                case "Decimal":
                    return ((T)(object)((decimal)(object)left - (decimal)(object)right));
            }
            throw new MathException("不支持的操作类型");
        }

        /// <summary>
        /// 乘法
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        private T MUL(T left, T right)
        {
            switch (GetType())
            {
                case "Int16":
                    return ((T)(object)((short)(object)left * (short)(object)right));
                case "Int32":
                    return ((T)(object)((int)(object)left * (int)(object)right));
                case "Int64":
                    return ((T)(object)((long)(object)left * (long)(object)right));
                case "Single":
                    return ((T)(object)((float)(object)left * (float)(object)right));
                case "Double":
                    return ((T)(object)((double)(object)left * (double)(object)right));
                case "Decimal":
                    return ((T)(object)((decimal)(object)left * (decimal)(object)right));
            }
            throw new MathException("不支持的操作类型");
        }

    }
}

  以上代码就是对行列式的封装 可以求值获得余子式 很基本的东西 求值的话主要用了递归的方式 因为泛型的原因导致计算过程重复拆箱装箱 不过目前好像也没有什么太好的方法了。反正就是学习 所以性能无所谓了。

然后就是调用了直接上调用代码:

            int[,] aaa = new int[4, 4]{{1,2,3,6},
                                        {4,5,7,8},
                                        {7,8,9,10},
                                        {3,8,4,3}};

            //LYF.Math.Determinant<int> d = new Determinant<int>(4);
            LYF.Math.Determinant<int> d = new Determinant<int>(aaa);
            d.SetItem(aaa);
            Console.WriteLine("当前行列式:");
            Console.WriteLine(d.ToString());
            Console.WriteLine("余子式M11:");
            Console.WriteLine(d.A(1, 1).ToString());
            Console.WriteLine("余子式M12:");
            Console.WriteLine(d.A(1, 2).ToString());
            Console.WriteLine("余子式M22:");
            Console.WriteLine(d.A(2, 2).ToString());
            Console.WriteLine("N="+d.N);
            Console.WriteLine("行列式的值为:"+d.Value.ToString());
            Console.Read();
  

  执行结果如下:

时间: 2024-10-08 23:10:30

线性代数之行列式的C#研究实现的相关文章

线性代数 - 01 行列式

线性代数 - 01 行列式 一.行列式的概念与性质 1.二阶.三阶行列式 2.n阶行列式的全面展开 3.行列式的性质 二.行列式的降阶算法 1.代数余子式 2.特殊行列式的计算公式 3.行列式的降阶算法 三.克莱姆法则 1.行列式的按行(列)展开 2.代数余子式组合定理 3.克莱姆法则 线性代数 - 01 行列式,码迷,mamicode.com

行列式求值 (取模)

typedef __int64 lld; lld a[205][205]; int sign; lld N,MOD; void solved() { lld ans=1; for(int i=0;i<N;i++)//当前行 { for(int j=i+1;j<N;j++)//当前之后的每一行,因为每一行的当前第一个数要转化成0(想想线性代数中行列式的计算) { int x=i,y=j; while(a[y][i])//利用gcd的方法,不停地进行辗转相除 { lld t=a[x][i]/a[y

线性代数知识

https://zhidao.baidu.com/question/2140241988539998868.html 线性代数,行列式交换任意两行行列式变号一次,那么这两行一定要相邻吗?如果是矩阵呢?矩阵用变号吗,为什么? 行列式行行之间.列列之间交换不必相邻.矩阵行列互换不用变号,互换后相当于左乘或右乘一个初等矩阵,不再是原先的矩阵,但是和原先的矩阵相似,拥有相同的特征值. 追问 乘上得这个初等矩阵是? 还有一个,矩阵某行直接除以二,结果的矩阵还是等于原来的矩阵? 追答 如果交换行,那么左乘一

省选板块

部分摘抄自网络 同样的,加粗是重点,星号是选学 图论 网络流(dinic,ISAP选一个,费用流写EK就行.*zkw费用流),二分图 点分治,边分治,*动态点分治 树链剖分,动态树,树分块 虚树,*prufer编码 *仙人掌算法 数据结构 带权并查集 Splay(作为平衡树和维护区间),Treap,替罪羊树 线段树(权值线段树),树状数组,*线段树合并 树套树 主席树,可持久化trie,*其它可持久化数据结构 二维线段树,*KDtree *舞蹈链,*二进制分组,*左偏树,*超哥线段树,*后缀平衡

[3D数学]向量

<1>向量与标量: 向量:有方向有长度(非负,比如(1,0,0) 方向指向X+,长度为1.normalize向量规范化,向量方向不变,但是长度为1,计算向量夹角一般规范化向量,求出cosa的值,acos反余弦求夹角) 标量:只有长度(强调的是数值) <2>向量的维度: 2维(0,1)  3维(0,0,1)  4维(0,1,1,0)  4维在CG语言中:比如color就有4个维度rgba  _Time也有四个维度:值得注意的是:2维用x,y表示 3维用x,y,z表示 4维用x,y,z

图像处理学习过程——网站,视频,书籍(长期更新)

网站: http://www.linuxgraphics.cn/home/index.html 图像处理编程相关的网站,也讲到了一些基础知识.特点是比较全,关于图形处理各方面的知识都有涉及到,但是比较粗浅.可以从这里延伸深入研究某个领域. http://pippin.gimp.org/image_processing/ 图像处理位图和矢量图相关基础知识介绍,英文网站,决定以翻译的形式放到博客中来. 视频: http://v.163.com/special/opencourse/daishu.ht

wenbao与高斯消元

消元  高斯消元 1 typedef double Matrix[maxn][maxn]; 2 void gauss_elimination(Matrix A, int n){ 3 int i, j, k, r; 4 //消元过程 5 for(i = 0; i < n; ++i){ 6 //选一行r并与i行交换 7 r = i; 8 for(j = i+1; j < n; ++j){ 9 if(fabs(A[j][i]) > fabs(A[r][i])) r = j; 10 } 11 i

[线性代数] 1、行列式

第一章  行列式 §1  二阶与三阶行列式------------------>行列式的概念    §2  全排列及其逆序数    §3  n 阶行列式的定义    §4  对换------------------------------>行列式的性质及计算    §5  行列式的性质    §6  行列式按行(列)展开    §7  克拉默法则------------------------>线性方程组的求解. 1.1.二元线性方程组与二阶行列式 PS:对角线相乘[二阶行列式] 1.2

【线性代数】 03 - 行列式

1. 行列式的定义 线性方程组中比较常见的是\(m=n\)的情况,我们想知道这种方程组什么时候有唯一解?并且如何用系数表示这个唯一解?对于元数较少的方程,可以直接用消元法得到解的具体公式,比如(1)式就是二元方程组的公式解.公式中重复出现了模式\(ab-cd\),这个模式不仅能判断方程组是否有唯一解,还能直接表示解的公式. \[x_1=\dfrac{b_1a_{22}-b_2a_{21}}{a_{11}a_{22}-a_{12}a_{21}};\quad x_2=\dfrac{a_{11}b_2