C_Sharp 板


LINE

今天临时需要用到解方程式,牛顿法 找不到C#的类别。 python的 sympy又跑太慢了, 只好自己硬干了一个能跑牛顿法的。 请问C#有这类的lib吗? // 用法 // 定义变数 Furmula x = new Furmula("x"); Furmula y = new Furmula("y"); Furmula z = new Furmula("z"); // 定义方程式 Furmula f = x*x + y*y+z*z + x*y*z; // 变数代入 double v =f.subs(x,3).subs(y,2).subs(z,1).Value; // 微分 Furmula df = f.Diff(x); // -- source code -- class Furmula { // Furmula public String mName = ""; public bool mIsValue = false; public double mValue = 0; // public OPERATORS mOperator = OPERATORS.NULL; public Furmula mLeftChild = null; public Furmula mRightChild = null; public enum OPERATORS { ADD, SUB, MUL, DIV, SIN, COS, TAN, POW, NULL }; public Furmula(String name) { mName = name; } public Furmula(double value) { mValue = value; mIsValue = true; } public Furmula(Furmula b) { mName = b.mName; mIsValue = b.mIsValue; mValue = b.mValue; mOperator = b.mOperator; mLeftChild = b.mLeftChild; mRightChild = b.mRightChild; } public Furmula(OPERATORS oper, Furmula LeftChild, Furmula RightChild) { mOperator = oper; mLeftChild = LeftChild; mRightChild = RightChild; } public static Furmula operator +(Furmula a, Furmula b) { if (a.mIsValue && b.mIsValue) return a.mValue + b.mValue; else if (a == 0) return new Furmula(b); else if (b == 0) return new Furmula(a); return new Furmula(OPERATORS.ADD, a, b); } public static Furmula operator -(Furmula a, Furmula b) { if (a.mIsValue && b.mIsValue) return a.mValue - b.mValue; else if (a == 0) return -1 * new Furmula(b); else if (b == 0) return new Furmula(a); return new Furmula(OPERATORS.SUB, a, b); } public static Furmula operator *(Furmula a, Furmula b) { if (a.mIsValue && b.mIsValue) return a.mValue * b.mValue; else if (a == 0) return 0; else if (b == 0) return 0; else if (a == 1) return new Furmula(b); else if (b == 1) return new Furmula(a); if (a.mIsValue && b.mIsValue) return a.mValue * b.mValue; return new Furmula(OPERATORS.MUL, a, b); } public static Furmula operator /(Furmula a, Furmula b) { if (a.mIsValue && b.mIsValue) return a.mValue / b.mValue; else if (b == 0) throw new Exception(); else if (a == 0) return 0; else if (b == 1) return new Furmula(a); return new Furmula(OPERATORS.DIV, a, b); } public static Furmula Pow(Furmula a, Furmula b) { if (a.mIsValue && b.mIsValue) return Math.Pow(a.mValue, b.mValue); else if (b == 0) return 1; else if (a == 0) return 0; else if (a == 1) return 1; return new Furmula(OPERATORS.POW, a, b); } public static Furmula Sin(Furmula a) { if (a.mIsValue) return Math.Sin(a.mValue); return new Furmula(OPERATORS.SIN, a, null); } public static Furmula Cos(Furmula a) { if (a.mIsValue) return Math.Cos(a.mValue); return new Furmula(OPERATORS.COS, a, null); } public static Furmula Tan(Furmula a) { if (a.mIsValue) return Math.Tan(a.mValue); return new Furmula(OPERATORS.TAN, a, null); } public static bool operator ==(Furmula a, double b) { if (a.mIsValue && a.mValue == b) return true; return false; } public static bool operator !=(Furmula a, double b) { return !(a == b); } public static implicit operator Furmula(double v) { return new Furmula(v); } public double Value { get { if (mIsValue) { return mValue; } throw new Exception(); } } public Furmula Subs(Dictionary<Furmula, double> values) { if (mOperator == OPERATORS.NULL) { foreach (var v in values) { if (mName == v.Key.mName) { return new Furmula(v.Value); } } return new Furmula(this); } else { Furmula NewLeft = null, NewRight = null; if (mLeftChild != null) { NewLeft = mLeftChild.Subs(values); } if (mRightChild != null) { NewRight= mRightChild.Subs(values); } switch (mOperator) { case OPERATORS.ADD: return NewLeft + NewRight; case OPERATORS.SUB: return NewLeft - NewRight; case OPERATORS.MUL: return NewLeft * NewRight; case OPERATORS.DIV: return NewLeft / NewRight; case OPERATORS.SIN: return Sin(NewLeft); case OPERATORS.COS: return Cos(NewLeft); case OPERATORS.TAN: return Tan(NewLeft); case OPERATORS.POW: return Pow(NewLeft, NewRight); } throw new Exception(); } } public Furmula Subs(String name, double value) { if (mOperator == OPERATORS.NULL) { if (mName == name) { return new Furmula(value); } else { return new Furmula(this); } } else { Furmula NewLeft = null, NewRight = null; if (mLeftChild != null) { NewLeft= mLeftChild.Subs(name, value); } if (mRightChild != null) { NewRight= mRightChild.Subs(name, value); } switch (mOperator) { case OPERATORS.ADD: return NewLeft + NewRight; case OPERATORS.SUB: return NewLeft - NewRight; case OPERATORS.MUL: return NewLeft * NewRight; case OPERATORS.DIV: return NewLeft / NewRight; case OPERATORS.SIN: return Sin(NewLeft); case OPERATORS.COS: return Cos(NewLeft); case OPERATORS.TAN: return Tan(NewLeft); case OPERATORS.POW: return Pow(NewLeft, NewRight); } throw new Exception(); } } public Furmula Diff(Furmula furmula) { return Diff(furmula.mName); } public Furmula Diff(String name) { if (mOperator == OPERATORS.NULL) { if (mName == name) { return new Furmula(1); } else { return new Furmula(0); } } else { switch (mOperator) { case OPERATORS.ADD: return mLeftChild.Diff(name) + mRightChild.Diff(name); case OPERATORS.SUB: return mLeftChild.Diff(name) - mRightChild.Diff(name); case OPERATORS.MUL: return mLeftChild.Diff(name) * mRightChild + mLeftChild * mRightChild.Diff(name); case OPERATORS.DIV: return ((mLeftChild.Diff(name) * mRightChild) - (mLeftChild * mRightChild.Diff(name))) / Pow(mRightChild, 2); case OPERATORS.SIN: return Cos(mLeftChild) * mLeftChild.Diff(name); case OPERATORS.COS: return -1 * Sin(mLeftChild) * mLeftChild.Diff(name); case OPERATORS.TAN: return mLeftChild.Diff(name) / Pow(Cos(mLeftChild), 2); case OPERATORS.POW: return mRightChild * Pow(mLeftChild, mRightChild - 1) * mLeftChild.Diff(name); } } throw new Exception(); } public override string ToString() { switch(mOperator){ case OPERATORS.NULL: if (mIsValue) return mValue.ToString(); else return mName; case OPERATORS.ADD: return String.Format("({0}+{1})", mLeftChild, mRightChild); case OPERATORS.SUB: return String.Format("({0}-{1})", mLeftChild, mRightChild); case OPERATORS.MUL: return String.Format("({0}*{1})", mLeftChild, mRightChild); case OPERATORS.DIV: return String.Format("({0}/{1})", mLeftChild, mRightChild); case OPERATORS.POW: return String.Format("({0}**{1})", mLeftChild, mRightChild); case OPERATORS.SIN: return String.Format("Sin({0})", mLeftChild); case OPERATORS.COS: return String.Format("Cos({0})", mLeftChild); case OPERATORS.TAN: return String.Format("Tan({0})", mLeftChild); } throw new Exception(); } public static Dictionary<Furmula, double> Newton(Furmula f, Dictionary<Furmula, double> Guass) { List<Furmula> vars = new List<Furmula>(Guass.Keys); int K = vars.Count; Furmula[] Gradient = new Furmula[K]; Furmula[,] Hessian = new Furmula[K, K]; for (int i = 0; i < K; i++) Gradient[i] = f.Diff(vars[i]); for (int i = 0; i < K; i++) { for (int j = 0; j < K; j++) { Hessian[i, j] = f.Diff(vars[i]).Diff(vars[j]); } } CSML.Matrix Xn = new CSML.Matrix(K, 1); CSML.Matrix Fn = new CSML.Matrix(K, 1); CSML.Matrix Hn = new CSML.Matrix(K, K); System.IO.StreamWriter writer = new System.IO.StreamWriter("iter.log"); for (int iter = 0; iter < 100; iter++) { writer.WriteLine("{0} {1}", iter, f.Subs(Guass)); writer.Flush(); for (int i = 0; i < K; i++) { Xn[i + 1, 1] = new Complex(Guass[vars[i]]); } for (int i = 0; i < K; i++) { Fn[i + 1, 1] = new Complex(Gradient[i].Subs(Guass).Value); } for (int i = 0; i < K; i++) { for (int j = 0; j < K; j++) { Hn[i + 1, j + 1] = new Complex(Hessian[i, j].Subs(Guass).Value); } } Xn = Xn - Hn.Inverse() * Fn; for (int i = 0; i < K; i++) { Guass[vars[i]] = Xn[i + 1, 1].Re; } } return Guass; } } --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 154.20.172.64
1F:推 Steven0422:IMSL for .Net 07/16 16:34
2F:推 pyrochlore:Open Source的有Math.Net 07/17 14:08
3F:→ Lucemia:感谢 07/18 00:32







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP