public static void Write(this BinaryWriter writer, Poly val) { writer.Write(val.Degrees); writer.Write(val.InChannels); writer.Write(val.OutChannels); writer.Write(val.Ceofs.GetLength(1)); for (int c = 0; c < val.Ceofs.GetLength(0); ++c) { for (int i = 0; i < val.Ceofs.GetLength(1); ++i) { writer.Write(val.Ceofs[c, i]); } } writer.Write(val.MaxError); writer.Write(val.MeanError); }
public static Poly Fit(int degrees, int channels, Matrix <float> x, Matrix <float> y) { var nItems = GetItemCount(degrees, channels); Debug.Assert(x.NRows == y.NRows && x.NRows >= GetItemCount(degrees, channels)); var nSamples = x.NRows; /* ********【预声明phy超定矩阵】************************/ /* 多项式拟合的函数为多项幂函数 * f(x)=a0*x^2 + a1*y^2 + a2*xy + a3*x + a4*y + a5 * * 超定矩阵phy=x1^2 y1^2 x1y1 x1 y1 1 * x2^2 y2^2 x2y2 x2 y2 1 * ... ... ... ... * ... ... ... ... * xn^2 yn^2 xnyn xn yn 1 * * *************************************************/ var phy = new Matrix <float> (nSamples, nItems); for (var i = 0; i < nSamples; i++) { var items = GetItems(degrees, x.GetRow(i)); for (var j = 0; j < items.Length; ++j) { phy[i, j] = items[j]; } } var a = new float[channels, nItems]; for (var c = 0; c < channels; ++c) { var yc = y.GetColumn(c); var ac = new Matrix <float> (nItems, 1); Solver.SolveLinear(phy, yc, ac, (int)Solver.DecompTypes.DECOMP_NORMAL); for (var i = 0; i < nItems; ++i) { a[c, i] = ac[i, 0]; } } // 构造PolyFunc对象 var f = new Poly(degrees, channels, a, 0.0f, 0.0f); // 计算Max Error和RMSE for (var i = 0; i < nSamples; ++i) { var evalValue = f.Evaluate(x.GetRow(i)); var sqrErr = 0.0f; for (var j = 0; j < evalValue.Length; ++j) { sqrErr = (evalValue[j] - y[i, j]) * (evalValue[j] - y[i, j]); } var err = Mathf.Sqrt(sqrErr); f.MaxError = Mathf.Max(err, f.MaxError); f.MeanError += sqrErr; } f.MeanError = Mathf.Sqrt(f.MeanError / nSamples); return(f); }