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