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

来源:互联网 发布:sass mac 编辑:程序博客网 时间:2024/04/29 01:53

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

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyMathLib{    /// <summary>    /// 主要用于一元多项式计算,目标是为了求矩阵特征值。    /// </summary>    public abstract class TExp    {        /// <summary>        /// 获取A/B的系数比.        /// </summary>        /// <param name="A"></param>        /// <param name="B"></param>        /// <returns></returns>        public static double GetRelativRation(TExp A, TExp B)        {            if (A is TSymbolExp && B is TSymbolExp)            {                var theA = (TSymbolExp)A;                var theB = (TSymbolExp)B;                if (theA.IsZero || theB.IsZero)                {                    return 0;                }                if (theA.Power == theB.Power)                {                    return theA.Ratio / theB.Ratio;                }                return 0;            }            if (A is TSymbolExp && B is TListExp)            {                var theA = (TSymbolExp)A;                var theB = (TListExp)B;                if (theB.Operands.Count != 1)                {                    return 0;                }                if (theA.IsZero || theB.IsZero)                {                    return 0;                }                if (theA.Power == theB.Operands[0].Power)                {                    return theA.Ratio / theB.Operands[0].Ratio;                }                return 0;            }            if (A is TListExp && B is TSymbolExp)            {                var theB = (TListExp)A;                var theA = (TSymbolExp)B;                if (theB.Operands.Count != 1)                {                    return 0;                }                if (theA.IsZero || theB.IsZero)                {                    return 0;                }                if (theA.Power == theB.Operands[0].Power)                {                    return theB.Operands[0].Ratio / theA.Ratio;                }                return 0;            }            var theA1 = (TListExp)A;            var theB1 = (TListExp)B;            if (theA1.Operands.Count != theB1.Operands.Count)            {                return 0;            }            var thePreRate = 0.0;            for (int i = 0; i < theA1.Operands.Count; i++)            {                var theA = theA1.Operands[i];                var theB = theB1.Operands[i];                if (theA.IsZero || theB.IsZero)                {                    return 0;                }                if (theA.Power == theB.Power)                {                    var theRate = theA.Ratio / theB.Ratio;                    if (thePreRate.IsEqualTo(0))                    {                        thePreRate = theRate;                    }                    else                    {                        if (!(thePreRate -theRate).IsEqualTo(0))                        {                            return 0;                        }                    }                }                else                {                    return 0;                }            }            return thePreRate;        }        /// <summary>        /// 获取最高次项的系数        /// </summary>        /// <returns></returns>        public abstract double GetMaxPowerItemRatio();        public abstract bool IsConstance{get;}        public abstract bool IsNotZeroConst { get; }        public abstract bool IsZero{get;}         public TSymbolExp GetMaxPowerExp()        {            if (this is TSymbolExp)            {                return (TSymbolExp)this;            }            TListExp theExp= (TListExp)this;            if (theExp.Operands.Count > 0)            {                return theExp.Operands[theExp.Operands.Count-1];            }            return 0;        }        public abstract string GetExpString();        public static TExp NewSymbolElement(string Symbol)        {            return new TSymbolExp() { Power = 1, Ratio = 1, Symbol = Symbol };        }        public static TExp operator *(TExp A, TExp B)        {            if (A is TSymbolExp && B is TSymbolExp)            {                var theA = (TSymbolExp)A;                var theB = (TSymbolExp)B;                return theA * theB;            }            if (A is TSymbolExp && B is TListExp)            {                var theA = (TSymbolExp)A;                var theB = (TListExp)B;                return theA * theB;            }            if (B is TSymbolExp && A is TListExp)            {                var theA = (TListExp)A;                var theB = (TSymbolExp)B;                return theA * theB;            }            var theA1 = (TListExp)A;            var theB1 = (TListExp)B;            return theA1 * theB1;        }        public static TExp operator +(TExp A, TExp B)        {            if (A is TSymbolExp && B is TSymbolExp)            {                var theA = (TSymbolExp)A;                var theB = (TSymbolExp)B;                return theA + theB;            }            if (A is TSymbolExp && B is TListExp)            {                var theA = (TSymbolExp)A;                var theB = (TListExp)B;                return theA + theB;            }            if (B is TSymbolExp && A is TListExp)            {                var theA = (TListExp)A;                var theB = (TSymbolExp)B;                return theB + theA;            }            var theA1 = (TListExp)A;            var theB1 = (TListExp)B;            return theA1 + theB1;        }        public static TExp operator -(TExp B)        {            return -1 * B;        }        public static TExp operator -(TExp A, TExp B)        {            var theB = -B;            return A + theB;        }        public static bool operator ==(TExp A, TExp B)        {            if (A is TSymbolExp && B is TSymbolExp)            {                var theA = (TSymbolExp)A;                var theB = (TSymbolExp)B;                return theA == theB;            }            if (A is TSymbolExp && B is TListExp)            {                var theA = (TSymbolExp)A;                var theB = (TListExp)B;                return theA == theB;            }            if (B is TSymbolExp && A is TListExp)            {                var theA = (TListExp)A;                var theB = (TSymbolExp)B;                return theA == theB;            }            var theA1 = (TListExp)A;            var theB1 = (TListExp)B;            return theA1 == theB1;        }        public static bool operator !=(TExp A, TExp B)        {            return !(A == B);        }        public static bool operator ==(TExp A, double B)        {            if (A is TSymbolExp)            {                return A == B;            }            if (A is TListExp)            {                return A == B;            }            return false;        }        public static bool operator !=(TExp A, double B)        {            return !(A == B);        }        public static bool operator ==(double A, TExp B)        {            return B == A;        }        public static bool operator !=(double A, TExp B)        {            return !(B == A);        }        public static implicit operator TExp(double A)        {            return (TSymbolExp)A;        }        public override bool Equals(object obj)        {            if (obj == null)            {                return false;            }            if (obj is TExp)            {                return this == (TExp)obj;            }            return false;        }        public override int GetHashCode()        {            return base.GetHashCode();        }    }    /// <summary>    /// 符号项,也是基本项,Power=0,就是普通数值项。    /// </summary>    public class TSymbolExp : TExp    {               public UInt32 Power { get; set; }        public string Symbol { get; set; }        public double Ratio { get; set; }        public override string GetExpString()        {            return GetExpString(true);        }        public string GetExpString(bool IsSingle)        {            if (Ratio.IsEqualTo(0))            {                if (IsSingle)                {                    return "0";                }                return "";            }            var theSign = "-";            var theRatio = Math.Abs(this.Ratio).ToString("0.######");            var theSymbol = Symbol;            var thePower = "^" + Power;            if (Ratio > 0)            {                if (IsSingle)                {                    theSign = "";                }                else                {                    theSign = "+";                }            }            if (Math.Abs(this.Ratio).IsEqualTo(1))            {                theRatio = "";            }            if (Power == 0)            {                theSymbol = "";                thePower = "";                theRatio = Math.Abs(this.Ratio).ToString();            }            else if (Power == 1)            {                thePower = "";            }            return theSign + theRatio + theSymbol + thePower;        }        public static TSymbolExp operator *(TSymbolExp A, TSymbolExp B)        {            var theNewExp = new TSymbolExp();            theNewExp.Symbol = A.Symbol;            if(string.IsNullOrEmpty(theNewExp.Symbol))            {                theNewExp.Symbol = B.Symbol;            }            if (A.Ratio.IsEqualTo(0) || B.Ratio.IsEqualTo(0))            {                theNewExp.Ratio = 0;                theNewExp.Power = 0;                theNewExp.Symbol = "";                return theNewExp;            }            theNewExp.Ratio = A.Ratio * B.Ratio;            theNewExp.Power = A.Power + B.Power;            if (theNewExp.Ratio.IsEqualTo(0))            {                theNewExp.Ratio = 0;                theNewExp.Power = 0;                theNewExp.Symbol = "";            }            return theNewExp;        }        public static TSymbolExp operator *(TSymbolExp A, double B)        {            if (B.IsEqualTo(0))            {                return new TSymbolExp() { Ratio = 0, Power = 0, Symbol = "" };            }            return new TSymbolExp() { Ratio = B * A.Ratio, Power = A.Power, Symbol = A.Symbol };        }        public static TSymbolExp operator *(double A, TSymbolExp B)        {            return B * A;        }        public static TExp operator +(TSymbolExp A, double B)        {            if (B.IsEqualTo(0))            {                return A;            }            var theB = new TSymbolExp() { Ratio = B, Power = 0,Symbol=""};            return A + theB;        }        public static TExp operator +(double A, TSymbolExp B)        {            if (A.IsEqualTo(0))            {                return B;            }            return B + A;        }        public static TExp operator +(TSymbolExp A, TSymbolExp B)        {            if (A.Power == B.Power && (A.Symbol == B.Symbol                 || string.IsNullOrEmpty(A.Symbol) == string.IsNullOrEmpty(B.Symbol)))            {                var theNewExp = new TSymbolExp();                theNewExp.Symbol = A.Symbol ?? B.Symbol;                theNewExp.Ratio = A.Ratio + B.Ratio;                theNewExp.Power = A.Power;                if (theNewExp.Ratio.IsEqualTo(0))                {                    theNewExp.Ratio = 0;                    theNewExp.Power = 0;                    theNewExp.Symbol = "";                }                return theNewExp;            }            else            {                var theNewExp = new TListExp();                if (A.Power < B.Power)                {                    theNewExp.Operands.Add(A);                    theNewExp.Operands.Add(B);                }                else                {                    theNewExp.Operands.Add(B);                    theNewExp.Operands.Add(A);                }                return theNewExp;            }        }        public static bool operator ==(TSymbolExp A, TSymbolExp B)        {            return (A.Ratio == B.Ratio && A.Power == B.Power && (A.Symbol == B.Symbol                || string.IsNullOrEmpty(A.Symbol) == string.IsNullOrEmpty(B.Symbol)));        }        public static bool operator !=(TSymbolExp A, TSymbolExp B)        {            return !(A == B);        }        public static bool operator ==(TSymbolExp A, double B)        {            return (A.Ratio == B && A.Power == 0);        }        public static bool operator !=(TSymbolExp A, double B)        {            return !(A == B);        }        public static bool operator !=(double A, TSymbolExp B)        {            return !(B == A);        }        public static bool operator ==(double A, TSymbolExp B)        {            return (B == A);        }        public static implicit operator double(TSymbolExp A)        {            if (A.Power == 0)            {                return A.Ratio;            }            throw new Exception("非常数项,不能转换!");        }        public static implicit operator TSymbolExp(double A)        {            return new TSymbolExp() { Ratio = A, Power = 0 };        }               public TSymbolExp Clone()        {            return new TSymbolExp() { Power = this.Power, Ratio = this.Ratio, Symbol = this.Symbol };        }        public override bool Equals(object obj)        {            if (obj == null)            {                return false;            }            if (obj is TSymbolExp)            {                return ((TSymbolExp)obj == this);            }            return false;        }        public override int GetHashCode()        {            return (this.GetType().Name + this.Power.ToString()                + this.Ratio.ToString()                + this.Symbol.ToString()).GetHashCode();        }        public override string ToString()        {            return GetExpString();        }        public override bool IsConstance        {            get            {                return this.Power == 0;            }        }        public override bool IsZero        {            get {                return this.Ratio.IsEqualTo(0);            }        }        public override bool IsNotZeroConst        {            get {                return this.Power == 0 && this.Ratio != 0;            }        }        public override double GetMaxPowerItemRatio()        {            return this.Ratio;        }    }    /// <summary>    /// 项积,因为任何符号表达式都可以表达成项积的和.    /// </summary>    public class TListExp : TExp    {        public List<TSymbolExp> Operands { get; set; }        public TListExp()        {            Operands = new List<TSymbolExp>();        }        public override string GetExpString()        {            var theRet = "";            if (Operands.Count == 0)            {                return "0";            }            if (Operands.Count == 1)            {                return Operands[0].GetExpString(true);             }            for (int i = Operands.Count - 1; i >= 0; i--)            {                theRet = theRet + Operands[i].GetExpString(false);            }            if (theRet.Length > 0)            {                if (theRet[0] == '+')                {                    theRet = theRet.Substring(1);                }            }            return theRet;        }        public static TExp operator +(TListExp A, TSymbolExp B)        {            var theRet = new TListExp();            if (B.Ratio.IsEqualTo(0))            {                theRet.Operands.AddRange(A.Operands);                return theRet;            }            var theHasInserted = false;            for (int i = 0; i < A.Operands.Count; i++)            {                if (B.Power == A.Operands[i].Power)                {                    var theNewExp = (TSymbolExp)(B + A.Operands[i]);                    if (!theNewExp.Ratio.IsEqualTo(0))                    {                        theRet.Operands.Add(theNewExp);                    }                    continue;                }                if (B.Power > A.Operands[i].Power)                {                    if (theHasInserted == false)                    {                        A.Operands.Add(B);                        theHasInserted = true;                    }                }                theRet.Operands.Add(A.Operands[i]);            }            return theRet;        }        public static TExp operator +(TSymbolExp A, TListExp B)        {            return B + A;        }        public static TListExp operator +(TListExp A, TListExp B)        {            TListExp theRet = new TListExp();            int theAi = 0;            int theBi = 0;            while (theAi < A.Operands.Count && theBi < B.Operands.Count)            {                if (A.Operands[theAi].Power == B.Operands[theBi].Power)                {                    var theTemp = (TSymbolExp)(A.Operands[theAi] + B.Operands[theBi]);                    if (!theTemp.Ratio.IsEqualTo(0))                    {                        theRet.Operands.Add(theTemp);                    }                    theAi++;                    theBi++;                    continue;                }                if (A.Operands[theAi].Power < B.Operands[theBi].Power)                {                    theRet.Operands.Add(A.Operands[theAi]);                    theAi++;                    continue;                }                theRet.Operands.Add(B.Operands[theBi]);                theBi++;            }            for (int i = theAi; i < A.Operands.Count; i++)            {                theRet.Operands.Add(A.Operands[i]);            }            for (int i = theBi; i < B.Operands.Count; i++)            {                theRet.Operands.Add(B.Operands[i]);            }            return theRet;        }        public static TListExp operator *(TListExp A, TSymbolExp B)        {            var theRet = new TListExp();            for (int i = 0; i < A.Operands.Count; i++)            {                var theTmp = A.Operands[i] * B;                if (!theTmp.Ratio.IsEqualTo(0))                {                    theRet.Operands.Add(theTmp);                }            }            return theRet;        }        public static TListExp operator *(TSymbolExp A, TListExp B)        {            return B * A;        }        public static TListExp operator *(TListExp A, TListExp B)        {            var theRet = new TListExp();            for (int i = 0; i < A.Operands.Count; i++)            {               var theTmp = A.Operands[i] * B;               theRet = theRet + theTmp;            }            return theRet;        }        public static TListExp operator *(TListExp A, double B)        {            if (B.IsEqualTo(0))            {                return A;            }            var theB = new TSymbolExp() { Ratio = B, Power = 0 };            return A * theB;        }        public static TListExp operator *(double A, TListExp B)        {            return B * A;        }        public static TExp operator +(TListExp A, double B)        {            if (B.IsEqualTo(0))            {                return A;            }            var theB = new TSymbolExp() { Ratio = B, Power = 0 };            return A + theB;        }        public static TExp operator +(double A, TListExp B)        {            if (A.IsEqualTo(0))            {                return B;            }            return B + A;        }        public static bool operator ==(TListExp A, TListExp B)        {            bool theRet = true;            for (int i = 0; i < A.Operands.Count && i < B.Operands.Count; i++)            {                if (A.Operands[i] != B.Operands[i])                {                    theRet = false;                    break;                }            }            return theRet;        }        public static bool operator !=(TListExp A, TListExp B)        {            return !(A == B);        }        public static bool operator ==(TListExp A, TSymbolExp B)        {            switch (A.Operands.Count)            {                case 0:                    return B == (TSymbolExp)0;                case 1:                    return A.Operands[0] == B;            }            return false;        }        public static bool operator !=(TListExp A, TSymbolExp B)        {            return !(A == B);        }        public static bool operator ==(TSymbolExp A, TListExp B)        {            return (B == A);        }        public static bool operator !=(TSymbolExp A, TListExp B)        {            return !(B == A);        }        public static bool operator ==(TListExp A, double B)        {            bool theRet = true;            if (A.Operands.Count > 1)            {                theRet = false;            }            else            {                theRet = A.Operands[0] == B;            }            return theRet;        }        public static bool operator !=(TListExp A, double B)        {            return !(A == B);        }        public static bool operator ==(double A, TListExp B)        {            return (B == A);        }        public static bool operator !=(double A, TListExp B)        {            return !(B == A);        }        public static implicit operator double(TListExp A)        {            if (A.Operands.Count == 1)            {                return A.Operands[0];            }            throw new Exception("不能转换!");        }        public static implicit operator TListExp(double A)        {            TSymbolExp theA = A;            var theRet = new TListExp();            theRet.Operands.Add(theA);            return theRet;        }        public override bool Equals(object obj)        {            if (obj == null)            {                return false;            }            return this == (TListExp)obj;        }        public override int GetHashCode()        {            return base.GetHashCode();        }        public override string ToString()        {            return GetExpString();        }        /// <summary>        /// 是否是数值        /// </summary>        public override bool IsConstance        {            get {                return this.Operands.Count == 1 && this.Operands[0].Power == 0 || this.Operands.Count == 0;            }        }        public override bool IsZero        {            get {                return this.Operands.Count == 0;            }        }        public override bool IsNotZeroConst        {            get {                return this.Operands.Count == 1 && this.Operands[0].Power == 0 && this.Operands[0].Ratio != 0;            }        }        /// <summary>        /// 获取最高次项的系数        /// </summary>        /// <returns></returns>        public override double GetMaxPowerItemRatio()        {            if (this.Operands.Count==0)            {                return 0;            }            return this.Operands[this.Operands.Count - 1].Ratio;        }    }}


简单的用法:

TExp x = new TSymbolExp() { Power = 1, Ratio = 1, Symbol = "x" }; var theA = (x - 7) * (x - 7) * (x - 1);

答案可以自己测试。显示的时候只要调用GetExpString().ToString()也可以.

0 0
原创粉丝点击