MyMathLib系列(向量运算--1)

主要是线性代数的第2章的算法,由于本章的大部分都是概念性的,而且后面还有矩阵,因此算法较少:

/*Vector.cs
 * Albert.Tian on 20141225
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMathLib
{
    /// <summary>
    /// 向量相关运算,这里没有给出向量的基本变换。因为
    /// 向量组可以用矩阵表达,因此很多向量的运算最终都归于矩阵运算。
    /// 本算法中的求极大线性无关组,是根据课本算法得出,不是最简单的一种方法,
    /// 在矩阵表达中,可以根据矩阵的初等变换,很容易求到极大线性无关组.
    /// 这个类在后面被重新定义.
    /// </summary>
    public class Vectors
    {
        /// <summary>
        /// 判断从0到指定结束位的元素是否全是0.
        /// </summary>
        /// <param name="CurrVector">当前向量</param>
        /// <param name="EndIndex">结束索引</param>
        /// <returns></returns>
        public static bool IsZeroVector(double[] CurrVector, int EndIndex = 0)
        {
            int theEndIndex = EndIndex;
            if (theEndIndex == 0)
            {
                theEndIndex = CurrVector.Length;
            }

            var theIsZeroVector = true;
            for (int i = 0; i < theEndIndex; i++)
            {
                if (CurrVector[i] != 0)
                {
                    theIsZeroVector = false;
                    break;
                }
            }
            return theIsZeroVector;
        }
        /// <summary>
        /// 判断当前向量是否与前面的向量线性相关,采用的是消元化
        /// </summary>
        /// <param name="CurrVector">当前向量</param>
        /// <param name="PrevMaxLIVectors">已有的线性无关的向量组</param>
        /// <returns></returns>
        private static bool IsLinearCorrelation(double[] CurrVector, List<double[]> PrevMaxLIVectors)
        {
            //零向量必是线性相关
            var theIsZeroVector = IsZeroVector(CurrVector);
            if (theIsZeroVector)
            {
                return true;
            }
            //如果前面没有向量,则当前非零向量必是线性无关的.
            if (PrevMaxLIVectors.Count <= 0)
            {
                return false;
            }
            //构造方程式,判断是否线性相关
            var theECount = CurrVector.Length;
            var theVCount = PrevMaxLIVectors.Count;

            //加入当前向量为常量向量,因此方程组的列为theVCount+1.
            var theEquealGroup = new double[theECount, theVCount + 1];
            //导入PrevMaxLIVectors
            for (int i = 0; i < theVCount; i++)
            {
                for (int j = 0; j < theECount; j++)
                {
                    theEquealGroup[j, i] = PrevMaxLIVectors[i][j];
                }
            }

            //加入当前向量作为常量向量
            for (int j = 0; j < theECount; j++)
            {
                theEquealGroup[j, theVCount] = CurrVector[j];
            }
            //消元,这里的消元法变成了求矩阵秩的基本算法.
            LinearAlgebra.EquationsElimination(theEquealGroup);
            //如果theRA<theRA1,则有矛盾方程,必然线性无关,如果theRA>=theRA1,则至少有一个非零解。
            //这里如此判断,主要是因为消元的方法。当然,这在矩阵有证。
            var theRA = 0;
            var theRA1 = 0;
            for (int i = 0; i < theECount; i++)
            {
                if (!IsZeroVector(theEquealGroup.GetVectorRow(i), theVCount))
                {
                    theRA++;
                }
                if (!IsZeroVector(theEquealGroup.GetVectorRow(i)))
                {
                    theRA1++;
                }
            }
            return (theRA >= theRA1);
        }
        /// <summary>
        /// 这个函数暂时无用,判断两个向量的等价性
        /// </summary>
        /// <param name="V1"></param>
        /// <param name="V2"></param>
        /// <returns></returns>
        private static bool IsEquivalent(double[] V1, double[] V2)
        {
            var theV1IsZeroVector = IsZeroVector(V1);
            var theV2IsZeroVector = IsZeroVector(V2);
            //两个都是0向量
            if (theV1IsZeroVector && theV2IsZeroVector)
            {
                return true;
            }
            //其中一个零向量,另一个是非零向量
            if (theV1IsZeroVector || theV2IsZeroVector)
            {
                return false;
            }
            //一个分量肯定成比例
            if (V1.Length <= 1)
            {
                return true;
            }

            double thePreRate = 0;
            var theCount = V1.Length;
            var theIndex = 0;
            for (int i = 0; i < theCount; i++)
            {
                //如果都等于0,则不比较
                if (V1[i] == V2[i] && V2[i] == 0)
                {
                    continue;
                }
                //如果其中一个是0,则必然不成比例,不等价
                if (V1[i] == 0 || V2[i] == 0)
                {
                    return false;
                }
                if (theIndex == 0)
                {
                    thePreRate = V1[i] / V2[i];
                    theIndex++;
                }
                else
                {

                    if (thePreRate != V1[i] / V2[i])
                    {
                        return false;
                    }

                }
            }
            return true;
        }
        /// <summary>
        /// 获取向量组的极大线性无关组,方法是依照教科书写的。
        /// 这个方法的效率比较低,后面的矩阵方法会比较好.
        /// </summary>
        /// <param name="Vectors">向量组</param>
        /// <returns></returns>
        public static List<double[]> GetMaxLinearIndependentGroup(double[,] Vectors)
        {
            //向量个数
            var theVCount = Vectors.GetLength(0);
            //元数个数
            var theECount = Vectors.GetLength(1);
            List<double[]> theTempVectors = new List<double[]>();
            for (int i = 0; i < theVCount; i++)
            {
                var theTempVector = Vectors.GetVectorRow(i);
                //如果当前向量不能被前面的向量线性表出,则加入到极大组
                //能不能线性表出,实际上就是求当前向量加入前面的向量组后,
                //还是不是线性相关
                if (!IsLinearCorrelation(theTempVector, theTempVectors))
                {
                    theTempVectors.Add(theTempVector);
                }
            }
            return theTempVectors;
        }

    }
}
时间: 2024-12-31 04:01:02

MyMathLib系列(向量运算--1)的相关文章

MyMathLib系列(一元多项式运算求初等因子等)

利用TExp类的运算来求矩阵的特征值,初等因子等: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyMathLib { /// <summary> /// 一元多项式计算 /// </summary> public class PolynomialOfOneBasic { /// <summary> /// 化成对阶梯矩阵

MyMathLib系列(向量及矩阵--准备工作)

因为向量和矩阵的计算工作量比较大,为了更好的书写代码,这里增加了几个定义类,这些定义或者扩展方法将在以后的代码中应用到:1.公共枚举类型 /* 文件:PublicEnums.cs * 目的:定义公共枚举类型. */ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyMathLib { /// <summary> /// 初等变换类型(课本上是加,这里

3D数学读书笔记——向量运算及在c++上的实现

本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24782661 开始之前:接上上篇说的,张宇老师说过线性代数研究的就是向量.其实严谨的说,数学中专门研究向量的分之称作线性代数,线性代数是一个非常有趣并且应用广泛的研究 领域,但它与3D数学关注的领域并不相同.3D数学主要关心向量和向量运算的几何意义. 零向量:任何集合,都存在 the additive identity el

MyMathLib系列(行列式计算4--向量部分)

1)将向量组进行消元,变换成阶梯矩阵,这是求向量组的极大线性无关组的基本算法.这个方法在前面曾经给出过,但在这里做了改进,目的是为了可以判断是否线性相关: /// <summary> /// 方程组消元,最后一列为系数,结果就在CoefficientDeterminant里. /// 本算法也可以用来求矩阵的秩. /// </summary> /// <param name="CoefficientDeterminant">方程组系数数组</p

向量运算

1.零向量 加性单位元:满足y+x=y n维向量集合的加性单位元就是n维零向量 运算法则:例如3d零向量表示为:[0,0,0] 几何解释:没有位移 2.负向量 运算法则: 每个分量都变负 数学表达: 几何解释: 向量变负,将得到一个和原来向量大小相等,方向相反的向量. 3.向量的大小(长度和模) 运算法则: n维向量大小计算公式为 几何解释: 2d中任意向量v能构造一个以v为斜边的直角三角形如下图所示 4.标量与向量乘法 运算法则: 几何解释: 效果是以因子|k|缩放向量的长度,例如想让向量长度

MyMathLib系列(行列式计算3)

到今天,行列式和线性方程组部分就完成了. using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyMathLib { /// <summary> /// 行列式计算,本程序属于MyMathLib的一部分,欢迎使用,参考,提意见. /// 有时间用函数语言改写,做自己得MathLib,里面的算法经过验证,但没经过 /// 严格测试,如需参考,请慎重. ///

第五章:向量运算

第1节:零向量 1.零向量的概念 对于任意向量x,都有x+y=x,则x被称为零向量.例如,3D零向量为[0 0 0].零向量非常特殊,因为它是唯一大小为零的向量,并且唯一一个没有方向的向量. 第2节:负向量 1.负向量的概念 对于向量x,如果x+(-x)=0,则-x就是负向量. 2.负向量的运算法则 将此法则应用到2D,3D,4D中,则 -[x y] = [-x -y] -[x y z] = [-x -y -z] -[w x y z] = [-w -x -y -z] 3.负向量的几何解释 向量为

R简单算术操作符&lt;函数和+-*/&gt;,缺失值,正则向量,向量运算&lt;索引&gt;(二)

赋值操作 x <- c(1,2,3); x = c(1,2,3); c(1,2,3) -> x; assign("x", c(1,2,3)); 这四种形式在大部分时候都能达到一致的效果.推荐使用第一种 1:向量的定义 一串有序数值构成的数值向量(vector) ,创建一个向量我们使用c(num1,num2,num3); 在 R 环境里面,单个的数值也是被看作长度为1的向量. 1.1 向量的基本运算 在算术表达式中使用向量将会对该向量的每一个元素都进行同样算术运算.出现 在同

MyMathLib系列(一元多项式-准备)

这里定义的类TExp是基本的计算项,这里的表达式与C#自带的表达式有很大的区别,这里定义这个类主要是为了进行矩阵运算,当然本身也支持普通的运算,但目前不支持除法.这个类目前的用途主要是为了计算矩阵的特征值,特征向量,有时间,再扩展成支持常见的复数域类的数值和符号运算.代码有点长,需要有点耐心: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyMath