佛萨奇2.0系统开发源码搭建

62 阅读3分钟

DApp基于区块链的底层开发平台,18I链上合约-259l开发系统3365能够理解为App的升级版。用白话说明一下:DAPP和底层链(Ethereum、EOS、星云链等)的瓜葛,就像App和iOS以及安卓系统之间的差别同样。以是现阶段不少做法都是复制现有的APP,扔在区块链,加之一顶“去中心化”的帽子,成为Dapp。

using System;

namespace NumNet { ///

/// 矩阵 /// public class Matrix { #region 保护成员 /// /// 存储矩阵数据的二维数组 /// protected double[,] _data; #endregion

    #region 公有属性
    /// <summary>
    /// 矩阵行数
    /// </summary>
    public int RowCount => _data.GetLength(0);

    /// <summary>
    /// 矩阵列数
    /// </summary>
    public int ColumnCount => _data.GetLength(1);
    #endregion

    #region 构造方法
    /// <summary>
    /// 构造一个空矩阵
    /// </summary>
    public Matrix()
    {
        _data = new double[0, 0];
    }

    /// <summary>
    /// 构造rowCount行的方阵,默认元素均为0;
    /// fillOne为true时,元素均为1
    /// </summary>
    /// <param name="rowCount"></param>
    /// <param name="fillOne"></param>
    public Matrix(int rowCount, bool fillOne = false)
        : this(rowCount, rowCount, fillOne)
    {

    }

    /// <summary>
    /// 构造rowCount行、colCount列的矩阵,默认元素均为0;
    /// fillOne为true时,元素均为1
    /// </summary>
    /// <param name="rowCount"></param>
    /// <param name="colCount"></param>
    /// <param name="fillOne"></param>
    public Matrix(int rowCount, int colCount, bool fillOne = false)
    {
        _data = new double[rowCount, colCount];
        if (fillOne)
        {
            for (int i = 0; i < rowCount; i++)
            {
                for (int j = 0; j < colCount; j++)
                {
                    _data[i, j] = 1;
                }
            }
        }
    }

    /// <summary>
    /// 根据二维数组构造矩阵
    /// </summary>
    /// <param name="data"></param>
    public Matrix(double[,] data)
    {
        _data = new double[data.GetLength(0), data.GetLength(1)];
        Array.Copy(data, _data, data.Length);
    }

    /// <summary>
    /// 根据一系列行向量构造新矩阵,这些向量具有相同的长度;
    /// 若要作为列向量构造,请对得到的矩阵进行转置
    /// </summary>
    /// <param name="rows"></param>
    /// <exception cref="Exception"></exception>
    public Matrix(params Vector[] rows)
    {
        int rowCount = rows.Length;
        if (rowCount == 0)
        {
            _data = new double[0, 0];
            return;
        }
        int colCount = rows[0].Length;
        for (int i = 1; i < rowCount; i++)
        {
            if (rows[i].Length != colCount)
                throw new Exception("各行向量的长度不同,无法组成矩阵!");
        }
        _data = new double[rowCount, colCount];
        for (int i = 0; i < rowCount; i++)
        {
            rows[i].CopyTo(_data, i * colCount);
        }
    }
    #endregion

    #region 公共方法
    /// <summary>
    /// 返回size行size列的单位矩阵
    /// </summary>
    /// <param name="size"></param>
    /// <returns></returns>
    public static Matrix Identity(int size)
    {
        Matrix m = new Matrix(size, size);
        for (int i = 0; i < size; i++)
        {
            m[i, i] = 1;
        }
        return m;
    }

    /// <summary>
    /// 返回size行size列的Hilbert矩阵
    /// </summary>
    /// <param name="size"></param>
    /// <returns></returns>
    public static Matrix Hilbert(int size)
    {
        Matrix m = new Matrix(size);
        for (int i = 0; i < size; i++)
        {
            for (int j = 0; j < size; j++)
            {
                m[i, j] = 1.0 / (i + j + 1);
            }
        }
        return m;
    }

    /// <summary>
    /// 根据对角线元素构造对角方阵
    /// </summary>
    /// <param name="diag"></param>
    /// <returns></returns>
    public static Matrix Diagonal(Vector diag)
    {
        Matrix m = new Matrix(diag.Length, diag.Length);
        for (int i = 0; i < diag.Length; i++)
        {
            m[i, i] = diag[i];
        }
        return m;
    }

    /// <summary>
    /// 获取矩阵中第rowDex行,第colDex列的元素
    /// </summary>
    /// <param name="rowDex"></param>
    /// <param name="colDex"></param>
    /// <returns></returns>
    public double this[int rowDex, int colDex]
    {
        get => _data[rowDex, colDex];
        set => _data[rowDex, colDex] = value;
    }

    /// <summary>
    /// 获取矩阵中的第rowDex行,作为向量返回;
    /// 对向量元素的修改不会反映到矩阵中
    /// </summary>
    /// <param name="rowDex"></param>
    /// <returns></returns>
    public Vector GetRow(int rowDex)
    {
        double[] data = new double[ColumnCount];
        Buffer.BlockCopy(_data, rowDex * ColumnCount * sizeof(double),
            data, 0, ColumnCount * sizeof(double));
        return new Vector(data);
    }

    /// <summary>
    /// 设置矩阵的第rowDex行,其中row的长度与矩阵列数相同
    /// </summary>
    /// <param name="rowDex"></param>
    /// <param name="row"></param>
    /// <exception cref="Exception"></exception>
    public void SetRow(int rowDex, Vector row)
    {
        if (row.Length != ColumnCount)
            throw new Exception("行向量长度与矩阵列数不同,不能设置!");
        row.CopyTo(_data, rowDex * ColumnCount);
    }

    /// <summary>
    /// 获取矩阵中的第colDex列,作为向量返回;
    /// 对向量元素的修改不会反映到矩阵中
    /// </summary>
    /// <param name="colDex"></param>
    /// <returns></returns>
    public Vector GetColumn(int colDex)
    {
        Vector v = new Vector(RowCount);
        for (int i = 0; i < RowCount; i++)
        {
            v[i] = this[i, colDex];
        }
        return v;
    }

    /// <summary>
    /// 设置矩阵的第colDex列,其中col的长度与矩阵行数相同
    /// </summary>
    /// <param name="colDex"></param>
    /// <param name="col"></param>
    /// <exception cref="Exception"></exception>
    public void SetColumn(int colDex, Vector col)
    {
        if (col.Length != RowCount)
            throw new Exception("列向量长度与矩阵行数不同,不能设置!");
        for (int i = 0; i < RowCount; i++)
        {
            this[i, colDex] = col[i];
        }
    }

    /// <summary>
    /// 获取矩阵对角线元素组成的向量;
    /// 返回向量的长度为行数与列数的较小值
    /// </summary>
    /// <returns></returns>
    public Vector GetDiagonal()
    {
        Vector v = new Vector(Math.Min(RowCount, ColumnCount));
        for (int i = 0; i < v.Length; i++)
        {
            v[i] = this[i, i];
        }
        return v;
    }

    /// <summary>
    /// 正号,返回m1的拷贝
    /// </summary>
    /// <param name="m1"></param>
    /// <returns></returns>
    public static Matrix operator +(Matrix m1)
    {
        return m1.Copy();
    }

    /// <summary>
    /// 负号,返回m1的相反矩阵
    /// </summary>
    /// <param name="m1"></param>
    /// <returns></returns>
    public static Matrix operator -(Matrix m1)
    {
        Matrix m = new Matrix(m1.RowCount, m1.ColumnCount);
        for (int i = 0; i < m1.RowCount; i++)
        {
            for (int j = 0; j < m1.ColumnCount; j++)
            {
                m[i, j] = -m1[i, j];
            }
        }
        return m;
    }

    /// <summary>
    /// 矩阵加法
    /// </summary>
    /// <param name="m1"></param>
    /// <param name="m2"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public static Matrix operator +(Matrix m1, Matrix m2)
    {
        if (m1.RowCount != m2.RowCount || m1.ColumnCount != m2.ColumnCount)
            throw new Exception("两矩阵形状不同,不能相加!");
        Matrix m = new Matrix(m1.RowCount, m1.ColumnCount);
        for (int i = 0; i < m1.RowCount; i++)
        {
            for (int j = 0; j < m1.ColumnCount; j++)
            {
                m[i, j] = m1[i, j] + m2[i, j];
            }
        }
        return m;
    }

    /// <summary>
    /// 矩阵减法
    /// </summary>
    /// <param name="m1"></param>
    /// <param name="m2"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public static Matrix operator -(Matrix m1, Matrix m2)
    {
        if (m1.RowCount != m2.RowCount || m1.ColumnCount != m2.ColumnCount)
            throw new Exception("两矩阵形状不同,不能相减!");
        Matrix m = new Matrix(m1.RowCount, m1.ColumnCount);
        for (int i = 0; i < m1.RowCount; i++)
        {
            for (int j = 0; j < m1.ColumnCount; j++)
            {
                m[i, j] = m1[i, j] - m2[i, j];
            }
        }
        return m;
    }

    /// <summary>
    /// 矩阵乘法
    /// </summary>
    /// <param name="m1"></param>
    /// <param name="m2"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public static Matrix operator *(Matrix m1, Matrix m2)
    {
        if (m1.ColumnCount != m2.RowCount)
            throw new Exception("左矩阵列数与右矩阵行数不同,不能相乘!");
        Matrix m = new Matrix(m1.RowCount, m2.ColumnCount);
        for (int i = 0; i < m.RowCount; i++)
        {
            for (int j = 0; j < m.ColumnCount; j++)
            {
                for (int k = 0; k < m1.ColumnCount; k++)
                {
                    m[i, j] += m1[i, k] * m2[k, j];
                }
            }
        }
        return m;
    }