public void GaussianOpMean() { Gaussian result = new Gaussian(); Gaussian X0 = Gaussian.FromMeanAndVariance(7, 1.0 / 3); Gaussian Mean0 = Gaussian.FromMeanAndVariance(3, 0.5); Gamma Precision0 = Gamma.FromShapeAndScale(3, 3); // Unknown precision Gamma Precision = Gamma.FromShapeAndScale(3, 3); Gaussian X = X0; Gaussian Mean = Mean0; // in matlab: test_t_msg result = GaussianOp.MeanAverageConditional_slow(X, Mean, Precision); Console.WriteLine(result); Assert.True(GaussianOp.MeanAverageConditional_slow(X, Mean, Precision).MaxDiff(new Gaussian(-9.9121, -4.5998)) < 1e-0); X = Gaussian.FromMeanAndVariance(1, 2); Mean = Gaussian.PointMass(0); Precision = Gamma.FromShapeAndRate(3, 1); Gaussian xPostExpected = Gaussian.FromMeanAndVariance(0.178378819440295, 0.365796599498963); Console.WriteLine(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision) * X); Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(xPostExpected / X) < 5e-7); Console.WriteLine(GaussianOp_Slow.SampleAverageConditional(X, Mean, Precision) * X); Assert.True(GaussianOp_Slow.SampleAverageConditional(X, Mean, Precision).MaxDiff(xPostExpected / X) < 5e-7); }
private void GaussianOpX2(Gaussian mean, Gamma precision) { Gaussian sample, result, result2; sample = Gaussian.PointMass(2); result = GaussianOp.SampleAverageConditional_slow(sample, mean, precision); result2 = GaussianOp_Slow.SampleAverageConditional(sample, mean, precision); Console.WriteLine("{0}: {1} {2}", sample, result, result2); Assert.True(result.MaxDiff(result2) < 1e-8); double prevDiff = double.PositiveInfinity; for (int i = 8; i < 30; i++) { double v = System.Math.Pow(0.1, i); sample = Gaussian.FromMeanAndVariance(2, v); result2 = GaussianOp_Slow.SampleAverageConditional(sample, mean, precision); double diff = result.MaxDiff(result2); Console.WriteLine("{0}: {1} diff={2}", sample, result2, diff.ToString("g4")); Assert.True(diff <= prevDiff || diff < 1e-6); result2 = GaussianOp.SampleAverageConditional_slow(sample, mean, precision); diff = result.MaxDiff(result2); Console.WriteLine("{0}: {1} diff={2}", sample, result2, diff.ToString("g4")); Assert.True(diff <= prevDiff || diff < 1e-6); prevDiff = diff; } }
public static Gaussian FindxB(Gaussian xB, Gaussian meanPrior, Gamma precPrior, Gaussian xF) { Gaussian xB3 = IsPositiveOp.XAverageConditional(true, xF); Func <Vector, double> func = delegate(Vector x2) { Gaussian xB2 = Gaussian.FromMeanAndPrecision(x2[0], System.Math.Exp(x2[1])); //Gaussian xF2 = GaussianOp.SampleAverageConditional_slow(xB2, meanPrior, precPrior); Gaussian xF2 = GaussianOp_Slow.SampleAverageConditional(xB2, meanPrior, precPrior); //Assert.True(xF2.MaxDiff(xF3) < 1e-10); //return Math.Pow((xF*xB2).GetMean() - (xF2*xB2).GetMean(), 2) + Math.Pow((xF*xB2).GetVariance() - (xF2*xB2).GetVariance(), 2); //return KlDiv(xF2*xB2, xF*xB2) + KlDiv(xF*xB3, xF*xB2); //return KlDiv(xF2*xB2, xF*xB2) + Math.Pow((xF*xB3).GetMean() - (xF*xB2).GetMean(),2); return(MeanError(xF2 * xB2, xF * xB2) + KlDiv(xF * xB3, xF * xB2)); //return xF.MaxDiff(xF2); //Gaussian q = new Gaussian(0, 0.1); //return Math.Pow((xF*q).GetMean() - (xF2*q).GetMean(), 2) + Math.Pow((xF*q).GetVariance() - (xF2*q).GetVariance(), 2); }; double m = xB.GetMean(); double p = xB.Precision; Vector x = Vector.FromArray(m, System.Math.Log(p)); Minimize2(func, x); return(Gaussian.FromMeanAndPrecision(x[0], System.Math.Exp(x[1]))); }
public static Gaussian FindxF2(Gaussian meanPrior, Gamma precPrior, Gaussian xF) { Func <Vector, double> func = delegate(Vector x2) { Gaussian xFt = Gaussian.FromMeanAndPrecision(x2[0], System.Math.Exp(x2[1])); Gaussian xB = IsPositiveOp.XAverageConditional(true, xFt); Gaussian xF2 = GaussianOp_Slow.SampleAverageConditional(xB, meanPrior, precPrior); return(xFt.MaxDiff(xF2)); }; double m = xF.GetMean(); double p = xF.Precision; Vector x = Vector.FromArray(m, System.Math.Log(p)); Minimize2(func, x); return(Gaussian.FromMeanAndPrecision(x[0], System.Math.Exp(x[1]))); }
public static Gaussian FindxF(Gaussian xB, Gaussian meanPrior, Gamma precPrior, Gaussian xF) { Gaussian xF3 = GaussianOp_Slow.SampleAverageConditional(xB, meanPrior, precPrior); Func <Vector, double> func = delegate(Vector x2) { Gaussian xF2 = Gaussian.FromMeanAndPrecision(x2[0], System.Math.Exp(x2[1])); Gaussian xB2 = IsPositiveOp.XAverageConditional(true, xF2); //return (xF2*xB2).MaxDiff(xF2*xB) + (xF3*xB).MaxDiff(xF2*xB); //return KlDiv(xF2*xB2, xF2*xB) + KlDiv(xF3*xB, xF2*xB); //return KlDiv(xF3*xB, xF2*xB) + Math.Pow((xF2*xB2).GetMean() - (xF2*xB).GetMean(),2); return(KlDiv(xF2 * xB2, xF2 * xB) + MeanError(xF3 * xB, xF2 * xB)); }; double m = xF.GetMean(); double p = xF.Precision; Vector x = Vector.FromArray(m, System.Math.Log(p)); Minimize2(func, x); //MinimizePowell(func, x); return(Gaussian.FromMeanAndPrecision(x[0], System.Math.Exp(x[1]))); }
public static Gaussian FindxF0(Gaussian xB, Gaussian meanPrior, Gamma precPrior, Gaussian xF) { Gaussian xF3 = GaussianOp_Slow.SampleAverageConditional(xB, meanPrior, precPrior); Func <double, double> func = delegate(double tau2) { Gaussian xF2 = Gaussian.FromNatural(tau2, 0); if (tau2 >= 0) { return(double.PositiveInfinity); } Gaussian xB2 = IsPositiveOp.XAverageConditional(true, xF2); //return (xF2*xB2).MaxDiff(xF2*xB) + (xF3*xB).MaxDiff(xF2*xB); //return KlDiv(xF2*xB2, xF2*xB) + KlDiv(xF3*xB, xF2*xB); //return KlDiv(xF3*xB, xF2*xB) + Math.Pow((xF2*xB2).GetMean() - (xF2*xB).GetMean(), 2); return(KlDiv(xF2 * xB2, xF2 * xB) + MeanError(xF3 * xB, xF2 * xB)); }; double tau = xF.MeanTimesPrecision; double fmin; tau = Minimize(func, tau, out fmin); //MinimizePowell(func, x); return(Gaussian.FromNatural(tau, 0)); }
public void GaussianOpX() { Gaussian uniform = Gaussian.Uniform(); Gaussian X0 = Gaussian.FromMeanAndVariance(3, 0.5); Gaussian Mean0 = Gaussian.FromMeanAndVariance(7, 1.0 / 3); double Precision0 = 3; Gaussian X, Mean; Gamma Precision, to_precision; Gaussian xActual, xExpected; bool testImproper = false; if (testImproper) { // Test the case where precisionIsBetween = false X = Gaussian.FromNatural(1, 2); Mean = Gaussian.FromNatural(3, -1); Precision = Gamma.FromShapeAndRate(4, 5); to_precision = Gamma.FromShapeAndRate(6, 7); xActual = GaussianOp.SampleAverageConditional(X, Mean, Precision, to_precision); } X = Gaussian.FromNatural(-2.7793306963303595, 0.050822473645365768); Mean = Gaussian.FromNatural(-5.9447032851878134E-09, 3.2975231004586637E-204); Precision = Gamma.FromShapeAndRate(318.50907574398883, 9.6226982361933746E+205); to_precision = Gamma.PointMass(0); xActual = GaussianOp.SampleAverageConditional(X, Mean, Precision, to_precision); X = Gaussian.FromNatural(0.1559599323109816, 8.5162535450918462); Mean = Gaussian.PointMass(0.57957597647840942); Precision = Gamma.FromShapeAndRate(7.8308812008325587E+30, 8.2854255911709925E+30); to_precision = Gamma.FromShapeAndRate(1.4709139487775529, 0.14968339171493822); xActual = GaussianOp.SampleAverageConditional(X, Mean, Precision, to_precision); X = Gaussian.FromNatural(0.15595993233964134, 8.5162535466550349); Mean = Gaussian.PointMass(0.57957597647840942); Precision = Gamma.FromShapeAndRate(3.9206259406339067E+20, 4.1481991194547565E+20); to_precision = Gamma.FromShapeAndRate(1.4709139487806249, 0.14968339171413536); xActual = GaussianOp.SampleAverageConditional(X, Mean, Precision, to_precision); X = Gaussian.FromNatural(0.15595993261634511, 8.5162535617468418); Mean = Gaussian.PointMass(0.57957597647840942); Precision = Gamma.FromShapeAndRate(1.825759224425317E+19, 1.9317356258150703E+19); to_precision = Gamma.FromShapeAndRate(1.4709139487887679, 0.14968339176002607); xActual = GaussianOp.SampleAverageConditional(X, Mean, Precision, to_precision); X = Gaussian.FromNatural(0.16501264432785923, 9.01); Mean = Gaussian.PointMass(0.57957597647840942); Precision = Gamma.FromShapeAndRate(1.6965139612477539E+21, 1.6965139612889427E+21); to_precision = Gamma.FromShapeAndRate(1.4695136363119978, 0.14707291154227081); xActual = GaussianOp.SampleAverageConditional(X, Mean, Precision, to_precision); // initialized in a bad place, gets stuck in a flat region X = Gaussian.FromNatural(3.9112579392580757, 11.631097473681082); Mean = Gaussian.FromNatural(10.449696977834144, 5.5617978202886995); Precision = Gamma.FromShapeAndRate(1.0112702817305146, 0.026480506235719053); to_precision = Gamma.FromShapeAndRate(1, 0.029622790537514355); xActual = GaussianOp.SampleAverageConditional(X, Mean, Precision, to_precision); X = Gaussian.FromNatural(57788.170908674481, 50207.150004827061); Mean = Gaussian.PointMass(0); Precision = Gamma.FromShapeAndRate(19764.051194189466, 0.97190264412377791); xActual = GaussianOp.SampleAverageConditional_slow(X, Mean, Precision); // integration bounds should be [-36,4] X = Gaussian.FromNatural(1.696828485456396, 0.71980672726406147); Mean = Gaussian.PointMass(-1); Precision = new Gamma(1, 1); xActual = GaussianOp.SampleAverageConditional_slow(X, Mean, Precision); xExpected = GaussianOp_Slow.SampleAverageConditional(X, Mean, Precision); Assert.True(xExpected.MaxDiff(xActual) < 1e-4); X = new Gaussian(-1.565, 0.8466); Mean = new Gaussian(0.0682, 0.3629); Precision = new Gamma(103.2, 0.009786); xActual = GaussianOp.SampleAverageConditional_slow(X, Mean, Precision); xExpected = GaussianOp_Slow.SampleAverageConditional(X, Mean, Precision); Assert.True(xExpected.MaxDiff(xActual) < 1e-4); // Fixed precision X = X0; Mean = uniform; Assert.True(GaussianOp.SampleAverageConditional(Mean, Precision0).MaxDiff(uniform) < 1e-10); Mean = Mean0; Assert.True(GaussianOp.SampleAverageConditional(Mean, Precision0).MaxDiff(new Gaussian(Mean.GetMean(), Mean.GetVariance() + 1 / Precision0)) < 1e-10); Mean = Gaussian.PointMass(Mean0.GetMean()); Assert.True(GaussianOp.SampleAverageConditional(Mean, Precision0).MaxDiff(new Gaussian(Mean.GetMean(), 1 / Precision0)) < 1e-10); // Uniform precision // the answer should always be uniform Precision = Gamma.Uniform(); Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(uniform) < 1e-10); // Unknown precision Precision = Gamma.FromShapeAndScale(3, 3); // Known X X = Gaussian.PointMass(X0.GetMean()); Mean = uniform; Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(uniform) < 1e-10); // Unknown X X = X0; Mean = uniform; //Console.WriteLine(XAverageConditional2(result)); Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(uniform) < 1e-10); X = X0; Mean = Mean0; // converge the precision message. (only matters if KeepLastMessage is set). //for (int i = 0; i < 10; i++) GaussianOp.PrecisionAverageConditional(X, Mean, Precision, precisionMessage); // in matlab: test_t_msg if (GaussianOp.ForceProper) { Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(Gaussian.FromNatural(3.1495, 0)) < 1e-4); } else { Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(new Gaussian(-9.9121, -4.5998)) < 1e-4); } X = X0; Mean = Gaussian.PointMass(Mean0.GetMean()); // converge the precision message. (only matters if KeepLastMessage is set). //for (int i = 0; i < 10; i++) GaussianOp.PrecisionAverageConditional(X, Mean, Precision, precisionMessage); // in matlab: test_t_msg if (GaussianOp.ForceProper) { Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(Gaussian.FromNatural(2.443, 0)) < 1e-4); } else { Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(new Gaussian(0.81394, -1.3948)) < 1e-4); } // Uniform X X = uniform; Mean = Mean0; // converge the precision message. (only matters if KeepLastMessage is set). //for (int i = 0; i < 10; i++) GaussianOp.PrecisionAverageConditional(X, Mean, Precision, precisionMessage); Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(new Gaussian(7, 0.5)) < 1e-10); X = uniform; Mean = Gaussian.PointMass(Mean0.GetMean()); // converge the precision message. (only matters if KeepLastMessage is set). //for (int i = 0; i < 10; i++) GaussianOp.PrecisionAverageConditional(X, Mean, Precision, precisionMessage); Assert.True(GaussianOp.SampleAverageConditional_slow(X, Mean, Precision).MaxDiff(new Gaussian(7, 1.0 / 6)) < 1e-10); }
internal void StudentIsPositiveTest2() { GaussianOp.ForceProper = false; double shape = 1; double mean = -1; Gamma precPrior = Gamma.FromShapeAndRate(shape, shape); Gaussian meanPrior = Gaussian.PointMass(mean); double evExpected; Gaussian xExpected = StudentIsPositiveExact(mean, precPrior, out evExpected); Gaussian xF2 = Gaussian.FromMeanAndVariance(-1, 1); // the energy has a stationary point here (min in both dimensions), even though xF0 is improper Gaussian xB0 = new Gaussian(2, 1); xF2 = Gaussian.FromMeanAndVariance(-4.552, 6.484); //xB0 = new Gaussian(1.832, 0.9502); //xB0 = new Gaussian(1.792, 1.558); //xB0 = new Gaussian(1.71, 1.558); //xB0 = new Gaussian(1.792, 1.5); Gaussian xF0 = GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior); //Console.WriteLine("xB0 = {0} xF0 = {1}", xB0, xF0); //Console.WriteLine(xF0*xB0); //Console.WriteLine(xF2*xB0); xF2 = new Gaussian(0.8651, 1.173); xB0 = new Gaussian(-4, 2); xB0 = new Gaussian(7, 7); if (false) { xF2 = new Gaussian(mean, 1); double[] xs = EpTests.linspace(0, 100, 1000); double[] logTrue = Util.ArrayInit(xs.Length, i => GaussianOp.LogAverageFactor(xs[i], mean, precPrior)); Normalize(logTrue); xF2 = FindxF4(xs, logTrue, xF2); xF2 = Gaussian.FromNatural(-0.85, 0); xB0 = IsPositiveOp.XAverageConditional(true, xF2); Console.WriteLine("xF = {0} xB = {1}", xF2, xB0); Console.WriteLine("x = {0} should be {1}", xF2 * xB0, xExpected); Console.WriteLine("proj[T*xB] = {0}", GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior) * xB0); double ev = System.Math.Exp(IsPositiveOp.LogAverageFactor(true, xF2) + GaussianOp_Slow.LogAverageFactor(xB0, meanPrior, precPrior) - xF2.GetLogAverageOf(xB0)); Console.WriteLine("evidence = {0} should be {1}", ev, evExpected); return; } if (false) { xF2 = new Gaussian(mean, 1); xF2 = FindxF3(xExpected, evExpected, meanPrior, precPrior, xF2); xB0 = IsPositiveOp.XAverageConditional(true, xF2); Console.WriteLine("xF = {0} xB = {1}", xF2, xB0); Console.WriteLine("x = {0} should be {1}", xF2 * xB0, xExpected); //double ev = Math.Exp(IsPositiveOp.LogAverageFactor(true, xF2) + GaussianOp.LogAverageFactor_slow(xB0, meanPrior, precPrior) - xF2.GetLogAverageOf(xB0)); //Console.WriteLine("evidence = {0} should be {1}", ev, evExpected); return; } if (false) { xF2 = new Gaussian(-2, 10); xF2 = FindxF2(meanPrior, precPrior, xF2); xB0 = IsPositiveOp.XAverageConditional(true, xF2); xF0 = GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior); Console.WriteLine("xB = {0}", xB0); Console.WriteLine("xF = {0} should be {1}", xF0, xF2); return; } if (false) { xF2 = new Gaussian(-3998, 4000); xF2 = new Gaussian(0.8651, 1.173); xB0 = new Gaussian(-4, 2); xB0 = new Gaussian(2000, 1e-5); xB0 = FindxB(xB0, meanPrior, precPrior, xF2); xF0 = GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior); Console.WriteLine("xB = {0}", xB0); Console.WriteLine("xF = {0} should be {1}", xF0, xF2); return; } if (false) { //xF2 = new Gaussian(-7, 10); //xF2 = new Gaussian(-50, 52); xB0 = new Gaussian(-1.966, 5.506e-08); //xF2 = new Gaussian(-3998, 4000); xF0 = FindxF(xB0, meanPrior, precPrior, xF2); Gaussian xB2 = IsPositiveOp.XAverageConditional(true, xF0); Console.WriteLine("xF = {0}", xF0); Console.WriteLine("xB = {0} should be {1}", xB2, xB0); return; } if (true) { xF0 = new Gaussian(-3.397e+08, 5.64e+08); xF0 = new Gaussian(-2.373e+04, 2.8e+04); xB0 = new Gaussian(2.359, 1.392); xF0 = Gaussian.FromNatural(-0.84, 0); //xF0 = Gaussian.FromNatural(-0.7, 0); for (int iter = 0; iter < 10; iter++) { xB0 = FindxB(xB0, meanPrior, precPrior, xF0); Gaussian xFt = GaussianOp_Slow.SampleAverageConditional(xB0, meanPrior, precPrior); Console.WriteLine("xB = {0}", xB0); Console.WriteLine("xF = {0} should be {1}", xFt, xF0); xF0 = FindxF0(xB0, meanPrior, precPrior, xF0); Gaussian xBt = IsPositiveOp.XAverageConditional(true, xF0); Console.WriteLine("xF = {0}", xF0); Console.WriteLine("xB = {0} should be {1}", xBt, xB0); } Console.WriteLine("x = {0} should be {1}", xF0 * xB0, xExpected); double ev = System.Math.Exp(IsPositiveOp.LogAverageFactor(true, xF0) + GaussianOp_Slow.LogAverageFactor(xB0, meanPrior, precPrior) - xF0.GetLogAverageOf(xB0)); Console.WriteLine("evidence = {0} should be {1}", ev, evExpected); return; } //var precs = EpTests.linspace(1e-6, 1e-5, 200); var precs = EpTests.linspace(xB0.Precision / 11, xB0.Precision, 100); //var precs = EpTests.linspace(xF0.Precision/20, xF0.Precision/3, 100); precs = EpTests.linspace(1e-9, 1e-5, 100); //precs = new double[] { xB0.Precision }; var ms = EpTests.linspace(xB0.GetMean() - 1, xB0.GetMean() + 1, 100); //var ms = EpTests.linspace(xF0.GetMean()-1, xF0.GetMean()+1, 100); //precs = EpTests.linspace(1.0/10, 1.0/8, 200); ms = EpTests.linspace(2000, 4000, 100); //ms = new double[] { xB0.GetMean() }; Matrix result = new Matrix(precs.Length, ms.Length); Matrix result2 = new Matrix(precs.Length, ms.Length); //ms = new double[] { 0.7 }; for (int j = 0; j < ms.Length; j++) { double maxZ = double.NegativeInfinity; double minZ = double.PositiveInfinity; Gaussian maxxF = Gaussian.Uniform(); Gaussian minxF = Gaussian.Uniform(); Gaussian maxxB = Gaussian.Uniform(); Gaussian minxB = Gaussian.Uniform(); Vector v = Vector.Zero(3); for (int i = 0; i < precs.Length; i++) { Gaussian xF = Gaussian.FromMeanAndPrecision(ms[j], precs[i]); xF = xF2; Gaussian xB = IsPositiveOp.XAverageConditional(true, xF); xB = Gaussian.FromMeanAndPrecision(ms[j], precs[i]); //xB = xB0; v[0] = IsPositiveOp.LogAverageFactor(true, xF); v[1] = GaussianOp.LogAverageFactor_slow(xB, meanPrior, precPrior); //v[1] = GaussianOp_Slow.LogAverageFactor(xB, meanPrior, precPrior); v[2] = -xF.GetLogAverageOf(xB); double logZ = v.Sum(); double Z = logZ; if (Z > maxZ) { maxZ = Z; maxxF = xF; maxxB = xB; } if (Z < minZ) { minZ = Z; minxF = xF; minxB = xB; } result[i, j] = Z; result2[i, j] = IsPositiveOp.LogAverageFactor(true, xF) + xF0.GetLogAverageOf(xB) - xF.GetLogAverageOf(xB); //Gaussian xF3 = GaussianOp.SampleAverageConditional_slower(xB, meanPrior, precPrior); //result[i, j] = Math.Pow(xF3.Precision - xF.Precision, 2); //result2[i, j] = Math.Pow((xF2*xB).Precision - (xF*xB).Precision, 2); //result2[i, j] = -xF.GetLogAverageOf(xB); //Gaussian xF2 = GaussianOp.SampleAverageConditional_slow(xB, Gaussian.PointMass(0), precPrior); Gaussian xMarginal = xF * xB; //Console.WriteLine("xF = {0} Z = {1} x = {2}", xF, Z.ToString("g4"), xMarginal); } double delta = v[1] - v[2]; //Console.WriteLine("xF = {0} xB = {1} maxZ = {2} x = {3}", maxxF, maxxB, maxZ.ToString("g4"), maxxF*maxxB); //Console.WriteLine("xF = {0} maxZ = {1} delta = {2}", maxxF, maxZ.ToString("g4"), delta.ToString("g4")); Console.WriteLine("xF = {0} xB = {1} minZ = {2} x = {3}", minxF, minxB, minZ.ToString("g4"), minxF * minxB); } //TODO: change path for cross platform using using (var writer = new MatlabWriter(@"..\..\..\Tests\student.mat")) { writer.Write("z", result); writer.Write("z2", result2); writer.Write("precs", precs); writer.Write("ms", ms); } }