频道栏目
首页 > 资讯 > C# > 正文

C#实现基本的矩阵数学库教程

17-11-20        来源:[db:作者]  
收藏   我要投稿

先给出SimpleMatrix.cs的开头,定义总行数、总列数、所有数据(double类型)

using System;
using System.IO;

namespace NeuralDefs.Matrix
{
    public class SimpleMatrix : IMatrix
    {
        public int Row { get; set; }
        public int Column { get; set; }
        public double[,] Data { get; set; }

其中用了IMatrix矩阵来组织,因为我还写了稀疏矩阵的。关于这个接口在介绍稀疏矩阵时候再写

1、首先实现简单矩阵的最基本功能——赋值和输出

我经常用csv格式的文件,用自然方式存储和查看矩阵

public SimpleMatrix(int row, int col)
        {
            // init matrix
            Row = row;
            Column = col;
            Data = new double[row, col];

            for (var i = 0; i < row; i++)
            {
                for (var j = 0; j < col; j++)
                {
                    Data[i, j] = 0;
                }
            }
        }

        public SimpleMatrix(string fileName)
        {
            //var splitUnit = '\t';
            var splitUnit = ',';

            // count columns
            var srCol = new StreamReader(fileName);
            var firstLine = srCol.ReadLine();
            if (firstLine != null)
            {
                var firstArray = firstLine.Split(splitUnit);
                Column = firstArray.Length;
            }
            srCol.Close();

            // count rows
            Row = 0;
            var srRow = new StreamReader(fileName);
            while (srRow.ReadLine() != null)
            {
                Row++;
            }
            srRow.Close();

            // init matrix
            Data = new double[Row, Column];

            // fill matrix
            var srData = new StreamReader(fileName);
            var curRow = 0;
            string line;
            while ((line = srData.ReadLine()) != null)
            {
                var lineArray = line.Split(splitUnit);
                for (var i = 0; i < lineArray.Length; i++)
                {
                    Data[curRow, i] = double.Parse(lineArray[i]);
                }
                curRow++;
            }
            srData.Close();
        }

        public void WriteTo(string path)
        {
            var fs = new FileStream(path, FileMode.Create);
            var sw = new StreamWriter(fs);

            for (var i = 0; i < Row; i++)
            {
                sw.WriteLine(this.RowVector(i).ToSingleLineRow());
            }

            sw.Close();
            fs.Close();
        }

2、用索引器取下标

public double this[int row, int column]
        {
            get { return Data[row, column]; }
            set { Data[row, column] = value; }
        }

3、随机化(用于神经网络赋初值等用途)

public void Randomize()
        {
            var rm = new Random();

            for (var i = 0; i < Row; i++)
            {
                for (var j = 0; j < Column; j++)
                {
                    Data[i, j] = rm.Next(-100, 100) / 1000.0;
                }
            }
        }

4、取某行

public SimpleMatrix RowVector(int row)
        {
            var result = new SimpleMatrix(1, Column);

            for (var i = 0; i < Column; i++)
            {
                result[0, i] = Data[row, i];
            }

            return result;
        }

5、减法

public static SimpleMatrix operator -(SimpleMatrix a, SimpleMatrix b)
        {
            var minus = new SimpleMatrix(a.Row, a.Column);

            for (var i = 0; i < minus.Row; i++)
            {
                for (var j = 0; j < minus.Column; j++)
                {
                    minus[i, j] = a[i, j] - b[i, j];
                }
            }
            return minus;
        }

6、范数

public static double Norm2(SimpleMatrix a)
        {
            var norm = 0.0;
            for (var i = 0; i < a.Row; i++)
            {
                for (var j = 0; j < a.Column; j++)
                {
                    norm += a[i, j] * a[i, j];
                }
            }
            return Math.Sqrt(norm);
        }

7、连接两个向量

public static SimpleMatrix Link(SimpleMatrix vector1, SimpleMatrix vector2)
        {
            // check is vector
            if (vector1.Column != 1 || vector2.Column != 1)
                return null;

            var newRow = vector1.Row + vector2.Row;
            var result = new SimpleMatrix(newRow, 1);

            for (var i = 0; i < vector1.Row; i++)
            {
                result[i, 0] = vector1[i, 0];
            }

            for (var i = 0; i < vector2.Row; i++)
            {
                result[vector1.Row + i, 0] = vector2[i, 0];
            }

            return result;
        }

8、单元素矩阵

 public static SimpleMatrix SingleValueMatrix(double val)
        {
            return new SimpleMatrix(1, 1) { Data = { [0, 0] = val } };
        }

9、绝对值最大元

public static double MaxAbsMember(SimpleMatrix a)
        {
            var max = -1.0;
            foreach (var d in a.Data)
            {
                if (Math.Abs(d) > max)
                    max = Math.Abs(d);
            }
            return max;
        }

10、矩阵转置

public static SimpleMatrix Transpose(SimpleMatrix a)
        {
            var result = new SimpleMatrix(a.Column, a.Row);

            for (var i = 0; i < result.Row; i++)
            {
                for (var j = 0; j < result.Column; j++)
                {
                    result[i, j] = a[j, i];
                }
            }

            return result;
        }
相关TAG标签
上一篇:MVC框架与三层有什么区别?蕴含了什么思想?
下一篇:Spark SQL 的Thrift Server服务不稳定解决办法
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站