static int Main() { Func <double, double>[] lnexp = new Func <double, double> [2]; lnexp[0] = (x) => 1; lnexp[1] = (x) => - x; double[] t = { 1, 2, 3, 4, 6, 9, 10, 13 }; double[] yt = { 117, 100, 88, 72, 53, 29.5, 25.2, 15.2 }; vector xs = new vector(t); vector ys = new vector(yt); vector lny = new vector(yt.Length); vector yerr = new vector(yt.Length); vector lnerr = new vector(yt.Length); for (int i = 0; i < yt.Length; i++) { lny[i] = Log(yt[i]); yerr[i] = yt[i] / 20; lnerr[i] = yerr[i] / yt[i]; } lsfit fit1 = new lsfit(xs, lny, lnerr, lnexp); vector c = fit1.C; WriteLine("\n Data:"); xs.print("time in days = "); ys.print("y = "); WriteLine("\n Attempting to make fit y=a*Exp(-lambda*t) by using ln(y)=ln(a)-lambda*t"); c.print("c = ln(a) lambda = "); WriteLine("a = {0:f6}", Exp(c[0])); WriteLine("half life = {0:f6}\n", Log(2) * 1 / c[1]); Func <double, double> fit1fun = x => c[0] * lnexp[0](x) + c[1] * lnexp[1](x); var fitwriter = new System.IO.StreamWriter("out.fit.txt"); for (double x = 0; x < 20; x += 0.1) { fitwriter.Write("{0:f16} {1:f16}\n", x, Exp(fit1fun(x))); } fitwriter.Close(); var datwriter = new System.IO.StreamWriter("out.data.txt"); for (int i = 0; i < xs.size; i++) { datwriter.Write("{0:f16} {1:f16} {2:f16}\n", xs[i], yt[i], yerr[i]); } datwriter.Close(); return(0); }
/************************************************************************* Subroutine for nonlinear fitting of linear problem DerAvailable: * 0 when only function value should be used * 1 when we can provide gradient/function * 2 when we can provide Hessian/gradient/function When something which is not permitted by DerAvailable is requested, this function sets NLSErrors to True. *************************************************************************/ private static void fitlinearnonlinear(int m, int deravailable, double[,] xy, lsfit.lsfitstate state, ref bool nlserrors) { int i = 0; int j = 0; double v = 0; int i_ = 0; while( lsfit.lsfititeration(state) ) { // // assume that one and only one of flags is set // test that we didn't request hessian in hessian-free setting // if( deravailable<1 & state.needfg ) { nlserrors = true; } if( deravailable<2 & state.needfgh ) { nlserrors = true; } i = 0; if( state.needf ) { i = i+1; } if( state.needfg ) { i = i+1; } if( state.needfgh ) { i = i+1; } if( i!=1 ) { nlserrors = true; } // // test that PointIndex is consistent with actual point passed // for(i=0; i<=m-1; i++) { nlserrors = nlserrors | (double)(xy[state.pointindex,i])!=(double)(state.x[i]); } // // calculate // if( state.needf ) { v = 0.0; for(i_=0; i_<=m-1;i_++) { v += state.x[i_]*state.c[i_]; } state.f = v; continue; } if( state.needfg ) { v = 0.0; for(i_=0; i_<=m-1;i_++) { v += state.x[i_]*state.c[i_]; } state.f = v; for(i_=0; i_<=m-1;i_++) { state.g[i_] = state.x[i_]; } continue; } if( state.needfgh ) { v = 0.0; for(i_=0; i_<=m-1;i_++) { v += state.x[i_]*state.c[i_]; } state.f = v; for(i_=0; i_<=m-1;i_++) { state.g[i_] = state.x[i_]; } for(i=0; i<=m-1; i++) { for(j=0; j<=m-1; j++) { state.h[i,j] = 0; } } continue; } } }
static int Main() { Func <double, double>[] lnexp = new Func <double, double> [2]; lnexp[0] = (x) => 1; lnexp[1] = (x) => - x; double[] t = { 1, 2, 3, 4, 6, 9, 10, 13 }; double[] yt = { 117, 100, 88, 72, 53, 29.5, 25.2, 15.2 }; vector xs = new vector(t); vector lny = new vector(yt.Length); vector yerr = new vector(yt.Length); vector lnerr = new vector(yt.Length); for (int i = 0; i < yt.Length; i++) { lny[i] = Log(yt[i]); yerr[i] = yt[i] / 20; lnerr[i] = yerr[i] / yt[i]; } lsfit fit1 = new lsfit(xs, lny, lnerr, lnexp); WriteLine("Trying to fit y=a*Exp(-lambda*x) on log form ln(y) = ln(a)-lambda*x \n"); vector c = fit1.C; vector cerr = fit1.Cerr; matrix covar = fit1.Covar; c.print("c = ln(a) lambda = "); covar.print("covariance matrix = "); double a = Exp(c[0]); double aerr = Exp(c[0]) * cerr[0]; double ml = 1 / c[1]; double hlerr = cerr[1] * Log(2) / ((-c[1]) * (-c[1])); double hl = Log(2) * ml; WriteLine("a = {0:f6} +- {1:f6}", a, aerr); WriteLine("lambda = {0:f6} +- {1:f6}\n", c[1], cerr[1]); WriteLine("Lambda converted to half life, error found by simplified propagation formula"); WriteLine("half life = {0:f6} +- {1:f6}", hl, hlerr); Func <double, double> expfun = x => a *Exp(-c[1] *x); Func <double, double> expu = x => (a + aerr) * Exp(-(c[1] - cerr[1]) * x); Func <double, double> expl = x => (a - aerr) * Exp(-(c[1] + cerr[1]) * x); vector x_eval = new vector(200); for (int i = 0; i < x_eval.size; i++) { x_eval[i] = (double)i / 10; } var fitwriter = new System.IO.StreamWriter("out.fit.txt"); var fitupwriter = new System.IO.StreamWriter("out.fitu.txt"); var fitlowriter = new System.IO.StreamWriter("out.fitl.txt"); for (int i = 0; i < x_eval.size; i++) { fitwriter.Write("{0:f16} {1:f16}\n", x_eval[i], expfun(x_eval[i])); fitupwriter.Write("{0:f16} {1:f16}\n", x_eval[i], expu(x_eval[i])); fitlowriter.Write("{0:f16} {1:f16}\n", x_eval[i], expl(x_eval[i])); } fitwriter.Close(); fitupwriter.Close(); fitlowriter.Close(); var datwriter = new System.IO.StreamWriter("out.data.txt"); for (int i = 0; i < xs.size; i++) { datwriter.Write("{0:f16} {1:f16} {2:f16}\n", xs[i], yt[i], yerr[i]); } datwriter.Close(); return(0); }
static void Main() { /* A */ var t0 = new vector(new double[] { 1, 2, 3, 4, 6, 9, 10, 13, 15 }); var y0 = new vector(new double[] { 117, 100, 88, 72, 53, 29.5, 25.2, 15.2, 11.1 }); var dy0 = 0.05 * y0; var f = new Func <double, double>[] { x => 1, x => x }; int n = t0.size; var t = new vector(n); var y = new vector(n); var dy = new vector(n); for (int i = 0; i < n; i++) { t[i] = t0[i]; y[i] = Log(y0[i]); dy[i] = dy0[i] / y0[i]; } var fit = new lsfit(t, y, dy, f); for (int i = 0; i < t.size; i++) { WriteLine($"{t0[i]} {y0[i]} {dy0[i]}"); } int k, N = 100; double z, step = (t[t.size - 1] - t[0]) / (N - 1); WriteLine("\n\n"); for (z = t[0], k = 0; k < N; z = t[0] + (++k) * step) { WriteLine($"{z} {Exp(fit.eval(z))}"); } double lambda = fit.c[1]; double dlambda = Sqrt(fit.sigma[1, 1]); // Error.WriteLine($"lambda={lambda:f5}, dlambda={dlambda:f5}"); double T = -Log(2.0) / lambda; // half-life double dT = Abs(dlambda / lambda / lambda); // half-life uncertainty Error.WriteLine("A)"); Error.WriteLine($"ThX half-life from fit = {T:f1} +/- {dT:f1} days"); Error.WriteLine($"The modern value for the half-life of 224-Rn = {3.619} +/- {0.023} days"); Error.WriteLine("The value obtained from the fit agrees with the modern value within the uncertainties of the fit"); Error.WriteLine("(Source: https://en.wikipedia.org/wiki/Isotopes_of_radium)\n"); /* B) */ matrix sigma = fit.sigma; Error.WriteLine("B)"); Error.WriteLine($"The covariance matrix, Σ: \n {sigma[0,0]:f6} {sigma[0,1]:f6} \n {sigma[1,0]:f6} {sigma[1,1]:f6}"); Error.WriteLine("\nThe fitting parameters with uncertainties are:"); vector unc = new vector(sigma.size1); for (int i = 0; i < sigma.size1; i++) { unc[i] = Sqrt(sigma[i, i]); Error.WriteLine($"c[{i}]: {fit.c[i]:f6} +/- {unc[i]:f6}"); } /* C) */ WriteLine("\n\n"); fit.c[0] += Sqrt(fit.sigma[0, 0]); for (z = t[0], k = 0; k < N; z = t[0] + (++k) * step) { WriteLine($"{z} {Exp(fit.eval(z))}"); } WriteLine("\n\n"); fit.c[0] -= 2 * Sqrt(fit.sigma[0, 0]); for (z = t[0], k = 0; k < N; z = t[0] + (++k) * step) { WriteLine($"{z} {Exp(fit.eval(z))}"); } fit.c[0] += Sqrt(fit.sigma[0, 0]); WriteLine("\n\n"); fit.c[1] += Sqrt(fit.sigma[1, 1]); for (z = t[0], k = 0; k < N; z = t[0] + (++k) * step) { WriteLine($"{z} {Exp(fit.eval(z))}"); } WriteLine("\n\n"); fit.c[1] -= 2 * Sqrt(fit.sigma[1, 1]); for (z = t[0], k = 0; k < N; z = t[0] + (++k) * step) { WriteLine($"{z} {Exp(fit.eval(z))}"); } }
public lsfitstate(lsfit.lsfitstate obj) { _innerobj = obj; }
public lsfitreport(lsfit.lsfitreport obj) { _innerobj = obj; }
public spline1dfitreport(lsfit.spline1dfitreport obj) { _innerobj = obj; }
public barycentricfitreport(lsfit.barycentricfitreport obj) { _innerobj = obj; }
public polynomialfitreport(lsfit.polynomialfitreport obj) { _innerobj = obj; }
static void Main() { //Original coordinates vector xo = new vector(new double[] { 1, 2, 3, 4, 6, 9, 10, 13, 15 }); vector yo = new vector(new double[] { 117, 100, 88, 72, 53, 29.5, 25.2, 15.2, 11.1 }); vector dyo = yo / 20; var f = new Func <double, double>[] { t => 1, t => t }; for (int i = 0; i < xo.size; i++) { WriteLine($"{xo[i]}\t{yo[i]}\t{dyo[i]}"); } WriteLine(); WriteLine(); //Linebreak vector x = xo.copy(); vector y = new vector(x.size); vector dy = new vector(x.size); for (int i = 0; i < x.size; i++) { y[i] = Log(yo[i]); dy[i] = dyo[i] / yo[i]; } var fit = new lsfit(x, y, dy, f); vector c = fit.c; //Coefficients vector delta_c = fit.delta_c; //Uncertienties of the coefficients double lambda = c[1]; double dlambda = delta_c[1]; Error.WriteLine($"lambda={lambda:f5} ± {dlambda:f5} "); double T = Log(0.5) / lambda; double dT = Abs(dlambda / lambda / lambda); Error.WriteLine($"Halvlife= {T:f1} ± {dT:f1} days"); if (T + dT >= 3.6 && (T - dT) <= 3.6) { Error.WriteLine("Halvlife matches modern value of 3.6 days"); } else { Error.WriteLine("Halvlife does not match modern value of 3.6 days"); } int N = 1000; double x_lnmin = x[0]; double x_lnmax = x[x.size - 1]; vector x_fit = new vector(N + 1); vector y_lnfit = new vector(N + 1); vector y_fit = new vector(N + 1); double xi; for (int i = 0; i <= N; i++) { xi = (x_lnmax - x_lnmin) / 1000 * i + x_lnmin; x_fit[i] = xi; y_lnfit[i] = fit.eval(xi); y_fit[i] = Exp(y_lnfit[i]); WriteLine($"{x_fit[i]:f5} {y_fit[i]:f5} "); } WriteLine(); WriteLine(); fit.c[0] += fit.delta_c[0]; for (int i = 0; i <= N; i++) { y_fit[i] = Exp(fit.eval(x_fit[i])); WriteLine($"{x_fit[i]:f5} {y_fit[i]:f5} "); } WriteLine(); WriteLine(); fit.c[0] -= 2 * fit.delta_c[0]; for (int i = 0; i <= N; i++) { y_fit[i] = Exp(fit.eval(x_fit[i])); WriteLine($"{x_fit[i]:f5} {y_fit[i]:f5} "); } WriteLine(); WriteLine(); fit.c[0] += fit.delta_c[0]; fit.c[1] += fit.delta_c[1]; for (int i = 0; i <= N; i++) { y_fit[i] = Exp(fit.eval(x_fit[i])); WriteLine($"{x_fit[i]:f5} {y_fit[i]:f5} "); } WriteLine(); WriteLine(); fit.c[1] -= 2 * fit.delta_c[1]; for (int i = 0; i <= N; i++) { y_fit[i] = Exp(fit.eval(x_fit[i])); WriteLine($"{x_fit[i]:f5} {y_fit[i]:f5} "); } }
static void B1() { WriteLine("\n Problem B1: Test Jacobi cycle time \n"); int n = 50; WriteLine("Symmetric random test matrix A of size {0}", n); Stopwatch sw = new Stopwatch(); double time_avg = 0; int k = 15; vector times = new vector(k); for (int i = 0; i < k; i++) { sw.Reset(); matrix A = rand_sym_mat(n); matrix B = A.copy(); sw.Start(); jcbi_cycl test = new jcbi_cycl(B); sw.Stop(); times[i] = sw.Elapsed.TotalMilliseconds; time_avg += times[i]; } time_avg = time_avg / times.size; WriteLine("Average Jacobi diagonalisation time"); WriteLine("time_avg = {0} ms\n", time_avg); WriteLine("Perform calculation for different matrix sizes"); var timewriter = new System.IO.StreamWriter("out.time.txt"); k = 5; // number of tries for each avg int l = 30; // upper range of matrix sizes; vector tavgs = new vector(l - 5); vector xs = new vector(l - 5); vector terr = new vector(l - 5); for (int i = 5; i < l; i++) { xs[i - 5] = i * 1.0; tavgs[i - 5] = 0; for (int j = 0; j < k; j++) { matrix A = rand_sym_mat(i); sw.Reset(); matrix B = A.copy(); sw.Start(); jcbi_cycl test = new jcbi_cycl(B); sw.Stop(); tavgs[i - 5] += sw.Elapsed.TotalMilliseconds; } tavgs[i - 5] = tavgs[i - 5] / k; terr[i - 5] = tavgs[i - 5] * 0.025; timewriter.WriteLine($"{i} {tavgs[i-5]}"); } timewriter.Close(); Func <double, double>[] tfun = new Func <double, double> [2]; tfun[0] = (x) => 1; tfun[1] = (x) => x * x * x; //tfun[0] = (x) => 1; tfun[1] = (x) => x; tfun[2] = (x) => x*x; tfun[3] = (x) => x*x*x; lsfit tfit = new lsfit(xs, tavgs, terr, tfun); WriteLine("exec time fit params {0} {1}", tfit.C[0], tfit.C[1]); vector fiteval = tfit.evaluate(xs); var tfunw = new System.IO.StreamWriter("out.tfun.txt"); for (int i = 0; i < xs.size; i++) { tfunw.WriteLine($"{xs[i]} {fiteval[i]}"); } tfunw.Close(); WriteLine("See PlotB1.svg for execution time calculation and a+b*x^3 fit"); }
static void Main() { // Note: Contains problem A, B and C, since they are so interrelated, that splitting // it up in several files and folders would be quite an unneccesary hassle. // Arrays with the measured data points vector x = new vector(new double[] { 1, 2, 3, 4, 6, 9, 10, 13, 15 }); vector y = new vector(new double[] { 117, 100, 88, 72, 53, 29.5, 25.2, 15.2, 11.1 }); // The uncertainty of the data points is 5% of the values vector dy = y / 20; int n = x.size; StreamWriter writeData = new StreamWriter("originalData.txt"); for (int i = 0; i < x.size; i++) { writeData.WriteLine("{0}\t{1}\t{2}", x[i], y[i], dy[i]); } writeData.Close(); vector yln = new vector(n); vector dyln = new vector(n); // Take the logarithm of the data for (int i = 0; i < n; i++) { yln[i] = Log(y[i]); dyln[i] = dy[i] / y[i]; } // Fit the data // We fit with a linear equation with a constant var f = new Func <double, double>[] { t => 1, t => t }; var fit = new lsfit(x, yln, dyln, f); // The lambda coefficient is now stored in the c[1] entry of the c-vector // The uncertainty of lambda can be found from the covariance matrix double lna = fit.c[0]; double dlna = Sqrt(fit.sigma[0, 0]); double lambda = fit.c[1]; double dlambda = Sqrt(fit.sigma[1, 1]); // The half-life is then double T = -Log(2.0) / lambda; // Write out the found half-life and lambda+-dlambda StreamWriter writeFitResult = new StreamWriter("outA-B.txt"); writeFitResult.WriteLine("The least squares fit gave the results:"); writeFitResult.WriteLine("lambda = {0:f5} +/- {1:f5}", lambda, dlambda); writeFitResult.WriteLine("ln(a) = {0:f5} +/- {1:f5}", lna, dlna); writeFitResult.WriteLine("The half-life is thus estimated to be {0:f2} days", T); writeFitResult.WriteLine("The table value half-life is 3.66 days"); // Generate data for the fitted curve StreamWriter writeFitData = new StreamWriter("fitData.txt"); double delta = 0.02; for (double i = x[0]; i <= x[n - 1]; i += delta) { writeFitData.WriteLine("{0:f2}\t{1}", i, Exp(fit.eval(i))); } // Part B // The uncertainty of the half-life value for ThX is calculated via the usual formula // for the uncertainty of a function with one variable: dq = dx*|dq/dx| double dT = Log(2.0) * 1 / (lambda * lambda) * dlambda; writeFitResult.WriteLine("\nThe uncertainty in the estimated halflife is {0:f2} days", dT); writeFitResult.WriteLine("The estimated value does thus not match the modern value" + " within the estimated uncertainty, but it is close."); writeFitResult.Close(); // Part C // We generate data for plots where the fit coefficients are changed by the estimated // uncertainties. First they are changed one at time, and at last they are changed // together for the upper and lower boundaries of the uncertainty writeFitData.WriteLine(); writeFitData.WriteLine(); // ln(a) + dln(a) fit.c[0] += dlna; for (double i = x[0]; i <= x[n - 1]; i += delta) { writeFitData.WriteLine("{0:f2}\t{1}", i, Exp(fit.eval(i))); } writeFitData.WriteLine(); writeFitData.WriteLine(); // ln(a) - dln(a) fit.c[0] -= 2 * dlna; for (double i = x[0]; i <= x[n - 1]; i += delta) { writeFitData.WriteLine("{0:f2}\t{1}", i, Exp(fit.eval(i))); } // Restore ln(a) to the original value from the fit fit.c[0] += dlna; writeFitData.WriteLine(); writeFitData.WriteLine(); // lambda + dlambda fit.c[1] += dlambda; for (double i = x[0]; i <= x[n - 1]; i += delta) { writeFitData.WriteLine("{0:f2}\t{1}", i, Exp(fit.eval(i))); } writeFitData.WriteLine(); writeFitData.WriteLine(); // lambda - dlambda fit.c[1] -= 2 * dlambda; for (double i = x[0]; i <= x[n - 1]; i += delta) { writeFitData.WriteLine("{0:f2}\t{1}", i, Exp(fit.eval(i))); } // Restore lambda to original value fit.c[1] += dlambda; // Lower boundary - lowest constant with fastest decay writeFitData.WriteLine(); writeFitData.WriteLine(); fit.c[0] += dlna; fit.c[1] += dlambda; for (double i = x[0]; i <= x[n - 1]; i += delta) { writeFitData.WriteLine("{0:f2}\t{1}", i, Exp(fit.eval(i))); } // Upper boundary - highest constant with slowest decay writeFitData.WriteLine(); writeFitData.WriteLine(); fit.c[0] -= 2 * dlna; fit.c[1] -= 2 * dlambda; for (double i = x[0]; i <= x[n - 1]; i += delta) { writeFitData.WriteLine("{0:f2}\t{1}", i, Exp(fit.eval(i))); } writeFitData.Close(); }