public static void Main(){ // for(int n=2;n<50;n+=5){ for(int n=2;n<50;n+=10){ vector e=new vector(n); matrix V=new matrix(n,n); var rnd = new Random(1); matrix A = new matrix(n,n); for(int i=0;i<n;i++){ for(int j=i;j<n;j++){ A[i,j]=(rnd.NextDouble()); A[j,i]=A[i,j]; } } matrix Alow=A.copy(); matrix Ahigh=A.copy(); matrix Vlow=V.copy(); matrix Vhigh=V.copy(); vector elow=e.copy(); vector ehigh=e.copy(); //for plotting: // matrix B=A.copy(); var sweeps=jacobi.cyclic(A,e,V); // matrix VTAV = V.T*B*V; // VTAV.printfloat("Should be diagional:"); var lowest=jacobi.lowest(Alow,elow,1,Vlow); //only the one lowest eigenvalue // matrix VTAVlow = Vlow.T*B*Vlow; // VTAVlow.printfloat("Should be diagional:"); var highest=jacobi.highest(Ahigh,ehigh,1,Vhigh); //only the one highest eigenvalue // matrix VTAVhigh = Vhigh.T*B*Vhigh; // VTAVhigh.printfloat("Should be diagional:"); WriteLine($"{n} {sweeps} {lowest} {highest}"); } }//Main
public static (double, double) recStratifMC(Func <vector, double> f, vector a, vector b, int N, double acc = 1e-4) { //WriteLine("Recursive MC called!"); // Sample N points from plain MC double plainRes, plainError; (plainRes, plainError) = plainMC(f, a, b, N); // If error is good, we return plain MC if (plainError < acc) { return(plainRes, plainError); } else { int n = a.size; // # of dimensions int k = 0; // while going over dimensions, we search for the dimension with biggest subvariance double maxSoFar = 0; double res1, res2, error1, error2, V = 1; for (int i = 0; i < n; i++) { V *= b[i] - a[i]; // Calculate volume } // For each dimension for (int i = 0; i < n; i++) { // Supdivide the volume in 2 along the dimension // first volume vector mid = b.copy(); mid[i] = a[i] + (b[i] - a[i]) / 2; // Estimate sub-variances along these 2 dimensions; (res1, error1) = plainMC(f, a, mid, N / 2); double variance1 = error1 * error1 * N / 2 / V / V / 4; // From central limit theorem (eq 3) // Second volume mid = a.copy(); mid[i] = a[i] + (b[i] - a[i]) / 2; (res2, error2) = plainMC(f, mid, b, N / 2); double variance2 = error2 * error2 * N / 2 / V / V / 4; // From central limit theorem (eq 3) // Check only largest of the 2 variances double maxForI = Max(variance1, variance2); if (maxForI > maxSoFar) { k = i; } } // We now know the dimension with largest sub-variance vector midk = b.copy(); midk[k] = a[k] + (b[k] - a[k]) / 2; // Subdivide volume along this dimension // and make 2 recursive calls to these divisions (res1, error1) = recStratifMC(f, a, midk, N / 2); midk = a.copy(); midk[k] = a[k] + (b[k] - a[k]) / 2; (res2, error2) = recStratifMC(f, midk, b, N / 2); // Estimate grand error and grand average // This is from Wiki(MISER M-C) double gRes = (res1 + res2) / 2; double gErr = (error1 + error2) / 4 / N; return(gRes, gErr); } }
// uses the upper bounds of the fit parameters to evaluate t public double upper(double t) { vector p_up = p.copy(); for (int i = 0; i < p_up.size; i++) { p_up[i] += Sqrt(cov[i, i]); } return(eval(t, p_up)); }
public static Tuple <vector, int> qnewton(Func <vector, double> f, vector x0, double acc = 1e-3, double eps = 1.0 / 4194304) { vector x = x0.copy(); double fx = f(x); matrix B = new matrix(x.size, x.size); B.set_unity(); int n = 0; vector gx = gradient(f, x, eps); while (n < 1000) { vector Dx = -B * gx; n++; if (gx.norm() < acc || Dx.norm() < eps * x.norm()) { break; } double lam = 1.0; // Commence backtracking vector z; double fz; do { z = x + Dx * lam; fz = f(z); if (fz < fx) { break; // Defines a good step } if (lam < eps) // Here we just don't care { B.set_unity(); break; } lam /= 2; }while(true); vector s = z - x; vector gz = gradient(f, z, eps); vector y = gz - gx; vector u = s - B * y; double uTy = u.dot(y); // Updating B if (Abs(uTy) > 1e-6) { for (int i = 0; i < B.size1; i++) { for (int j = 0; j < B.size2; j++) { B[i, j] += u[i] * u[j] * (1 / uTy); } } } x = z; gx = gz; fx = fz; } return(Tuple.Create(x, n)); }
// --- Constructor public AdaptOdeSolver( Func <double, vector, vector> f, double a, vector y, double b, double h, double absAcc, double relAcc ) { this.f = f; this.a = a; this.b = b; this.h = h; this.absAcc = absAcc; this.relAcc = relAcc; this.y = y; this.ys = new List <vector> { y.copy() }; this.xs = new List <double> { a }; drive(); }
static void Main() { for (int n = 200; n < 1001; n += 100) { matrix A = rand_matrix(n); vector v = rand_vector(n); vector b = v.copy(); Stopwatch cd_time = new Stopwatch(); cd_time.Start(); var cd = new cholesky(A); vector x_cd = cd.solve(v); cd_time.Stop(); Stopwatch qr_time = new Stopwatch(); qr_time.Start(); var qr = new gs(A); var x_qr = qr.solve(b); qr_time.Stop(); ///// matrix dimension n*n cd_runtime qr_runtime WriteLine($"{n} \t {cd_time.ElapsedMilliseconds} \t {qr_time.ElapsedMilliseconds}"); } } //Method: Main
static void Main(String[] args) { // Make model of the SIR for Covid-19 in Denmark double Tc = Double.Parse(args[0]); // Time between contacts // -- Setup double N = 5600000; // Pop of Denmark double Tr = 10; // recovery time double h = 1; int tEnd = 250; // Interval vector y = new vector(N - 1, 1, 0); // S,I,R at t = 0 days vector yh = new vector(0, 0, 0); vector dy = new vector(0, 0, 0); Func <double, vector, vector> dydt = (t, yt) => new vector(-(yt[0] * yt[1]) / N / Tc, yt[0] * yt[1] / N / Tc - yt[1] / Tr, yt[1] / Tr); for (int t = 0; t < tEnd; t++) { // Advance 1 day // Format: t, I, dI WriteLine($"{t} {y[1]} {dy[1]}"); rkStep12(dydt, t, y, h, yh, dy); y = yh.copy(); } WriteLine($"{tEnd - 1} {y[1]} {dy[1]}"); }
static void Main(){ // Inintial conditions: vector r1_0= new vector(0.97000436, -0.24308753); vector r2_0= -r1_0.copy(); vector r3_0= new vector(0,0); vector v3_0= new vector(-0.93240737, -0.86473146); vector v2_0= v3_0.copy()/(-2.0); vector v1_0= v2_0.copy(); vector ya = new vector(new double[] {r1_0[0], r1_0[1], r2_0[0], r2_0[1], r3_0[0], r3_0[1], v1_0[0], v1_0[1], v2_0[0], v2_0[1], v3_0[0], v3_0[1]}); double ta = 0; double tb = 7.5; //newton3body()(ta,ya).print($"y at t={ta}: "); double h=1e-3, acc=1e-5, eps=1e-5; var ts=new List<double>(); var ys=new List<vector>(); vector yb=ode.rk23(newton3body(),ta,ya,tb,acc:acc,eps:eps,h:h,xlist:ts,ylist:ys); Error.WriteLine($"acc={acc} eps={eps}"); Error.WriteLine($"npoints={ts.Count}"); Error.WriteLine($"Solve the ODE up to t={tb}"); for(int i=0;i<ts.Count;i++) WriteLine($"{ts[i]}\t{ys[i][0]}\t{ys[i][1]}\t{ys[i][2]}\t{ys[i][3]}\t{ys[i][4]}\t{ys[i][5]}"); } // Method:Main
public vector solve(vector b) { vector bcopy = b.copy(); // Apply G (via many small subsequent rotations) to b to get Rx, since G = Q^T // so Gb = GAx = GQRx = Q^T*QRx = Rx for (int q = 0; q < m; q++) { for (int p = q + 1; p < n; p++) { double theta = R[p, q]; double bq = bcopy[q]; double bp = bcopy[p]; bcopy[q] = bq * Cos(theta) + bp * Sin(theta); bcopy[p] = -bq *Sin(theta) + bp * Cos(theta); } } // bcopy now holds R*x. // Solve for x via back substitution, // R contains both the upper triagonal matrix known from QR factorization // and the Givens angle in the lower triagonal matrix. Here we use the upper // triagonal part for the back substitution. for (int i = bcopy.size - 1; i >= 0; i--) { double sum = 0; for (int k = i + 1; k < bcopy.size; k++) { sum += R[i, k] * bcopy[k]; } bcopy[i] = (bcopy[i] - sum) / R[i, i]; } // bcopy now just holds the x-vector return(bcopy); }
static void Main() { double m = 1.0; // all three masses should me equal, here they are all set to 1.0 double G = 1.0; // the gravitational constant is approximated as 1 vector r1_0 = new vector(new double[] { 0.97000436, -0.24308753 }); // initial conditions (given in figure 1 of the article) vector r2_0 = -r1_0.copy(); vector r3_0 = new vector(new double[] { 0, 0 }); vector dr3_0 = new vector(new double[] { -0.93240737, -0.86473146 }); vector dr2_0 = -dr3_0.copy() / 2; vector dr1_0 = dr2_0.copy(); vector y0 = new vector(new double[] { r1_0[0], r1_0[1], r2_0[0], r2_0[1], r3_0[0], r3_0[1], dr1_0[0], dr1_0[1], dr2_0[0], dr2_0[1], dr3_0[0], dr3_0[1] }); // initial values of y double t0 = 0; // "start value" double tb = 10; // "end value" double acc = 1e-5; // precision double eps = 1e-5; // precision double h = 1e-2; // step size var ts = new List <double>(); var ys = new List <vector>(); ode.rk45(threebody(m, G), t0, y0, tb, h, acc, eps, ts, ys); StreamWriter output = new System.IO.StreamWriter("out.txt"); for (int i = 0; i < ys.Count; i++) { output.WriteLine($"{ts[i]} {ys[i][0]} {ys[i][1]} {ys[i][2]} {ys[i][3]} {ys[i][4]} {ys[i][5]}"); } output.Close(); }
} /* apply the network to input parameter x */ public void train(vector x, vector y) { for (int i = 0; i < n; i++) { double ai = x[0] + (x[-1] - x[0]) * i / (x.size - 1); double bi = 5; double wi = 1; param[3 * i + 0] = ai; param[3 * i + 1] = bi; param[3 * i + 2] = wi; } Func <vector, double> cost = (p) => { param = p; double costSum = 0; for (int i = 0; i < x.size; i++) { double ypred = feedforwad(x[i]); costSum += Pow(ypred - y[i], 2); } // for(int i=0;i<n;i++) // costSum += 0.001*(Pow(1/param[i*3+1],2) + Pow(param[i*3+2],2)); //Weight decay (makes sure the varibels don't go crazy) return(costSum); }; double eps = 1e-7; vector pa = param.copy(); qnewton(cost, ref pa, eps); param = pa; } /* train to interpolate the given table {x,y} */
}//solve public vector givensB(vector b) { vector x = b.copy(); double theta; double c; double s; double x_p; double x_q; for (int q = 0; q < G.size2; q++) { for (int p = q + 1; p < G.size1; p++) { theta = G[p, q]; c = Cos(theta); s = Sin(theta); x_p = c * x[q] + s * x[p]; x_q = -s * x[q] + c * x[p]; x[q] = x_p; x[p] = x_q; } } return(x); }
public static vector newton(Func<vector, vector> f, vector x, double eps = 1e-3, double dx = 1e-7){ int n = x.size; matrix J = new matrix(n,n); vector root = x.copy(); vector f_r = f(root); vector z,fz; while(f_r.norm()>eps){ for(int i = 0; i<n; i++){ root[i] = root[i]+dx; vector df = f(root)-f_r; for(int j=0; j<n; j++){ J[i,j] = df[j]/dx; } // for root[i] -= dx; } // for QRdecompositionGS qr = new QRdecompositionGS(J); vector dr = qr.solve(-1*f_r); double lambda = 1.0; z = root+lambda*dr; fz = f(z); while(fz.norm()>(1-lambda/2)*f_r.norm()){ double lambda_min = 1/64.0; if(lambda>lambda_min){ lambda = lambda/2; fz = f(root+lambda*dr); } // if else{Error.WriteLine($"Bad step: lambda = {lambda_min}"); break; } // else } // while root += lambda*dr; f_r = f(root); } // while return root; } // newton
public vector solve(vector rhs) { vector b = rhs.copy(); for (int q = 0; q < data.size2; q++) { for (int p = q + 1; p < data.size1; p++) { double theta = data[p, q]; double xq = b[q], xp = b[p]; b[q] = +xq *Cos(theta) + xp * Sin(theta); b[p] = -xq *Sin(theta) + xp * Cos(theta); } } vector x = new vector(data.size2); for (int i = data.size2 - 1; i >= 0; i--) { double s = 0; for (int k = i + 1; k < data.size2; k++) { s += data[i, k] * x[k]; } x[i] = (b[i] - s) / data[i, i]; } return(x); }//solve
public vector solve(vector b) { double theta, xp, xq; vector x = b.copy(); // start by applying the rotations to b for (int p = 0; p < m; p++) { for (int q = p + 1; q < n; q++) { theta = G[q, p]; xp = Cos(theta) * x[p] + Sin(theta) * x[q]; xq = Cos(theta) * x[q] - Sin(theta) * x[p]; x[p] = xp; x[q] = xq; } } // then make a back substitution to actually solve it for (int i = m - 1; i >= 0; i--) { for (int j = i + 1; j < m; j++) { x[i] -= G[i, j] * x[j]; } x[i] /= G[i, i]; } return(x); }
public vector solve(vector r) { vector b = r.copy(); for (int q = 0; q < QR.size2; q++) { for (int p = q + 1; p < QR.size1; p++) { double theta = QR[p, q]; double c = Cos(theta), s = Sin(theta); double xq = b[q], xp = b[p]; b[q] = +xq * c + xp * s; b[p] = -xq * s + xp * c; } } vector x = new vector(QR.size2); for (int i = QR.size2 - 1; i >= 0; i--) { double s = 0; for (int k = i + 1; k < QR.size2; k++) { s += QR[i, k] * x[k]; } x[i] = (b[i] - s) / QR[i, i]; } return(x); } //solve
public static vector newton(Func <vector, vector> f, vector p, double eps = 1e-3, double dx = 1e-7) { vector x = p.copy(); // Find a root of 'f', starting at point x matrix J = new matrix(x.size, x.size); while (f(x).norm() > eps) { // Generate J makeJacobian(f, x, J, dx); // Solve J dx = -f(x) for dx vector deltax = qr_givens_solve(J, -1 * f(x)); double lambda = 1; while (Sqrt(f(x + lambda * deltax).dot(f(x + lambda * deltax))) > (1 - lambda / 2) * f(x).norm() && lambda > 1.0 / 64) { lambda /= 2; } for (int i = 0; i < x.size; i++) { x[i] = x[i] + lambda * deltax[i]; } } return(x); }
// In place application of the operation Q^(T) using the givens angles // stored in _G on the vector x. public vector applyQT(vector b) { vector x = b.copy(); double theta; double c; double s; double x_p; double x_q; // Two loops to itterate over all theta: for (int j = 0; j < _G.size2; j++) { for (int i = j + 1; i < _G.size1; i++) { theta = _G[i, j]; c = cos(theta); s = sin(theta); x_p = c * x[j] + s * x[i]; x_q = -s * x[j] + c * x[i]; x[j] = x_p; x[i] = x_q; } } return(x); }
public static vector newton( Func <vector, vector> f, vector x, double epsilon = 1e-3, double dx = 1e-7) { vector x_temp, f_res, delta_x, dfdx; double lam; x = x.copy(); int n = x.size; matrix J = new matrix(n, n); matrix R; f_res = f(x); delta_x = new vector(n); delta_x[0] = 10 + dx * 2; while (f_res.norm() > epsilon && max(abs(delta_x)) > dx) { for (int k = 0; k < n; k++) { x_temp = x.copy(); x_temp[k] += dx; dfdx = (f(x_temp) - f_res) / dx; // J[k] = dfdx; for (int i = 0; i < n; i++) { J[i, k] = dfdx[i]; } } R = new matrix(n, n); qr_gs_decomp(J, R); delta_x = qr_gs_solve(J, R, -1.0 * f_res); lam = 1.0; while (f(x + lam * delta_x).norm() > (1 - lam / 2) * f_res.norm() && lam > 1.0 / 64) { lam /= 2; } x = x + lam * delta_x; f_res = f(x); } return(x); }
public static vector newton(Func <vector, vector> f, vector x_start, double eps = 1e-3, double dx = 1e-7) { vector x = x_start.copy(); int n = x.size; matrix J = new matrix(n, n); vector fx = new vector(n); vector df = new vector(n); vector y = new vector(n); vector fy = new vector(n); vector Dx = new vector(n); bool bool1 = true; do { bool bool2 = true; fx = f(x); for (int j = 0; j < n; j++) { x[j] += dx; df = f(x) - fx; for (int i = 0; i < n; i++) { J[i, j] = df[i] / dx; } x[j] -= dx; } qrDecomp.qr_givens_decomp(J); Dx = qrDecomp.qr_givens_solve(J, fx * (-1)); double s = 2; do { s /= 2; y = x + Dx * s; fy = f(y); if (fy.norm() < (1 - s / 2) * fx.norm()) { bool2 = false; } if (s < 0.02) { bool2 = false; } }while(bool2); x = y; fx = fy; if (Dx.norm() < dx) { bool1 = false; } if (fx.norm() < eps) { bool1 = false; } }while(bool1); return(x); }
public static (vector, int) qnewton( Func <vector, double> f, /* objective function */ vector xstart, /* starting point */ double acc = 1e-3, /* accuracy */ double eps = 1e-7 /* small number epsilon */ ) { vector x = xstart.copy(); double fx = f(x); vector gx = gradient(f, x); matrix B = matrix.id(x.size); int nsteps = 0; while (nsteps < 999) { nsteps++; vector Dx = -B * gx; if (Dx.norm() < eps * x.norm()) { break; } if (gx.norm() < acc) { break; } vector z; double fz, lambda = 1; while (true) // backtracking linesearch { z = x + Dx * lambda; fz = f(z); if (fz < fx) { break; } if (lambda < eps) { B.setid(); break; } lambda /= 2; } vector s = z - x; vector gz = gradient(f, z); vector y = gz - gx; vector u = s - B * y; double uTy = u % y; if (Abs(uTy) > 1e-6) { B.update(u, u, 1 / uTy); // rank-1 update } x = z; gx = gz; fx = fz; } return(x, nsteps); }
} //end plainmc //Stratified sampling mc public static vector SSmc(Func <vector, double> f, vector a, vector b, int N, double acc = 1e-4) { //sample N random points with plainmc: vector samp = plainmc(f, a, b, N); //check error: if (samp[1] <= acc) { //accept average and error: return(samp); } //end if else { int ih = 0; //index for highest sub-var double hvar = 0; //highest sub-var //subdivide the volume: for (int i = 0; i < a.size; i++) { vector vol2 = b.copy(); vol2[i] = vol2[i] - 0.5 * (b[i] - a[i]); //estimate the sub varians vector sam1 = plainmc(f, a, vol2, N / (a.size * 2)); vector sam2 = plainmc(f, vol2, b, N / (a.size * 2)); //calculating the total sub-var: double subvar = (Pow(sam1[1], 2) + Pow(sam2[1], 2)); //check if the sub-var is larger: if (subvar > hvar) { ih = i; //update index hvar = subvar; //update value } //end if } //end for //make recursive call vector svol = b.copy(); svol[ih] = svol[ih] - 0.5 * (b[ih] - a[ih]); vector svol2 = a.copy(); svol2[ih] = svol2[ih] + 0.5 * (b[ih] - a[ih]); vector re1 = SSmc(f, a, svol, N / 2, acc * Sqrt(N / 2)); vector re2 = SSmc(f, svol2, b, N / 2, acc * Sqrt(N / 2)); vector re = re1 + re2; //System.Console.Error.WriteLine($"{re1[0]} {re2[0]} {ih}"); return(new vector(re[0], Pow(re[1], 2) / (N * 4))); } //end else } //end SSmc
// Quadratic interpolate a point z public cspline(vector xtable, vector ytable) { int n = xtable.size; x = xtable.copy(); y = ytable.copy(); b = new vector(n); c = new vector(n - 1); d = new vector(n - 1); vector p = new vector(n - 1); vector h = new vector(n - 1); for (int i = 0; i < n - 1; i++) { h[i] = x[i + 1] - x[i]; Debug.Assert(h[i] > 0); p[i] = (y[i + 1] - y[i]) / h[i]; } vector D = new vector(n); vector Q = new vector(n - 1); vector B = new vector(n); D[0] = 2; D[n - 1] = 2; Q[0] = 1; B[0] = 3 * p[0]; B[n - 1] = 3 * p[n - 2]; for (int i = 0; i < n - 2; i++) { D[i + 1] = 2 * h[i] / h[i + 1] + 2; Q[i + 1] = h[i] / h[i + 1]; B[i + 1] = 3 * (p[i] + p[i + 1] * h[i] / h[i + 1]); } for (int i = 1; i < n; i++) { D[i] = D[i] - Q[i - 1] / D[i - 1]; B[i] = B[i] - B[i - 1] / D[i - 1]; } b[n - 1] = B[n - 1] / D[n - 1]; for (int i = n - 2; i >= 0; i--) { b[i] = (B[i] - Q[i] * b[i + 1]) / D[i]; } for (int i = 0; i < n - 1; i++) { c[i] = (-2 * b[i] - b[i + 1] + 3 * p[i]) / h[i]; d[i] = (b[i] + b[i + 1] - 2 * p[i]) / h[i] / h[i]; } }
// Use rk 45 steps to solve ordinary differential equation // All steps in the calculation is saved to the lists ts and ys public static void driver( Func <double, vector, vector> f, /* right-hand-side of dydt=f(t,y) */ double a, /* the start-point a */ vector y, /* y(a) */ double b, /* the end-point of the integration */ List <double> ts, /*List for used t values*/ List <vector> ys, /*List for found y values*/ double h = 1e-1, /* initial step-size */ double acc = 1e-2, /* absolute accuracy goal */ double eps = 1e-2 /* relative accuracy goal */ ) { vector tau = new vector(y.size); vector err = new vector(y.size); vector yt = y.copy(); vector yh = new vector(y.size); double t = a; double tol; ts.Add(t); ys.Add(yt.copy()); while (t < b) { if (b < t + h) // if next step exeeds limit { h = b - t; // makes sure last step hits limit } rkstep45(f, t, yt, h, yh, err); // make step err = abs(err); //Elementwise abs tau = (eps * abs(yh) + acc) * Sqrt(h / (b - a)); //sice of tollerated error (/ means Elementwise division) tol = min(tau / err); // (/ means Elementwise division) if (tol > 1) //acceptable step { yt = yh.copy(); t += h; ts.Add(t); ys.Add(yt.copy()); } double factor = Min(Pow(tol, 0.25) * 0.95, 2); //factor to change stepsize h *= factor; } }
public static (vector, int) qNewton( Func <vector, double> f, // Function phi vector x0, // Starting point double eps // Desired accuracy ) { int steps = 0; vector x = x0.copy(); matrix B = resetB(x.size); vector dfdx = gradient(f, x); while (dfdx.norm() > eps) { steps++; // Calc dx vector dx = -1 * B * dfdx; // Backtracking search double lambda = 1; matrix dxT = new matrix(1, dx.size); for (int i = 0; i < dx.size; i++) { dxT[0, i] = dx[i]; } double armijo = (dxT * dfdx)[0]; // Armijo condition while (f(x + lambda * dx) > f(x) + lambda * armijo / 10000) { if (lambda < 1.0 / 64) { B = resetB(x.size); break; } lambda /= 2; } // SR1 update of B vector y = gradient(f, x + lambda * dx) - dfdx; vector u = lambda * dx - B * y; matrix uT = new matrix(1, u.size); for (int i = 0; i < u.size; i++) { uT[0, i] = u[i]; } double uTy = (uT * y)[0]; if (Abs(uTy) > 1e-6) { B.update(u, u, 1 / uTy); } // Update x, dfdx x = x + lambda * dx; dfdx = gradient(f, x); } return(x, steps); }
public static vector newton ( Func <vector, vector> f, //takes the input vector x and retrun f(x) vector xstart, //Starting point double eps = 1e-3, //The accuracy goal, ||f(x)||< epsilon double dx = 1e-6 //finite difference ) { vector x = xstart.copy(); int n = xstart.size; vector fx = f(x); vector y; vector fy; do { matrix J = new matrix(n, n); for (int j = 0; j < n; j++) { x[j] += dx; vector df = f(x) - fx; for (int i = 0; i < n; i++) { J[i, j] = df[i] / dx; } x[j] -= dx; } var JQR = new qrdecompositionGS(J); matrix B = JQR.inverse(); vector Dx = -B * fx; double s = 1; do { y = x + Dx * s; fy = f(y); if (fy.norm() < (1 - s / 2) * fx.norm()) { break; } if (s < 1.0 / 32) { break; } s /= 2; } while (true); x = y; fx = fy; if (fx.norm() < eps) { break; } } while (true); return(x); }
public static void randomx(vector x, vector a, vector b, Random RND, lattice RNDL, halton RNDH, bool print_points, bool Lattice = false, bool Halton = false) { int dim = a.size; if (Lattice) { vector y = x.copy(); RNDL.next(y); for (int i = 0; i < dim; i++) { x[i] = a[i] + y[i] * (b[i] - a[i]); } } if (Halton) { vector y = x.copy(); RNDH.next(y); for (int i = 0; i < dim; i++) { x[i] = a[i] + y[i] * (b[i] - a[i]); } } if (!Lattice && !Halton) { for (int i = 0; i < dim; i++) { x[i] = a[i] + RND.NextDouble() * (b[i] - a[i]); } } if (print_points) { StreamWriter pointWriter = new StreamWriter("sample_points.txt", true); for (int i = 0; i < x.size; i++) { pointWriter.Write($"{x[i]} "); } pointWriter.Write("\n"); pointWriter.Close(); } }
// Quadratic interpolate a point z public lspline(vector xtable, vector ytable) { int n = xtable.size; x = xtable.copy(); y = ytable.copy(); a = new vector(n - 1); for (int i = 0; i < n - 1; i++) { a[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]); } }
// Driver private void drive() { // Setup first step int k = 0, n = y.size; double x, s, err, normy, tol; vector yh = new vector(n); vector dy = new vector(n); // Drive while (xs[k] < b) { x = xs[k]; y = ys[k]; if (x + h > b) { h = b - x; } // Take step rkStep12(f, x, y, h, yh, dy); // Calculate error s = 0; for (int i = 0; i < n; i++) { s += dy[i] * dy[i]; } err = Sqrt(s); s = 0; for (int i = 0; i < n; i++) { s += yh[i] * yh[i]; } normy = Sqrt(s); tol = (normy * relAcc + absAcc) * Sqrt(h / (b - a)); //Write($"x: {x} \n"); //y.print("y: "); //yh.print("yh: "); // Check if step is good enough to continue if (err < tol) { k++; xs.Add(x + h); ys.Add(yh.copy()); } // Update Step size if (err > 0) { h *= Pow(tol / err, 0.25) * 0.95; } else { h *= 2; } } }
static void Main(){ // The problem at hand is a 2-dimensional problem. Each body in our 3-body simulation // has 2 coordinates x and y. This gives a total of 6 coordinates to account for. // It is assumed that all 3 bodies have the same mass, i.e. 1, and the gravitational constant is set to 1. // The setting parameters double t_0 = 0; // starting time double MG = 1; // Mass // The following initial conditions can be found in the Chenciner & Montgomery article (Figure text 1) // Initial conditions for position: vector r1_0 = new vector(new double[] {0.97000436,-0.24308753}); vector r2_0 = -1*r1_0.copy(); vector r3_0 = new vector(new double[] {0,0}); // Initial conditions for velocities: vector v3_0 = new vector(new double[] {-0.93240737, -0.86473146}); vector v2_0 = -0.5*v3_0.copy(); vector v1_0 = -0.5*v3_0.copy(); // Collecting all the vectors in one (one to rule them all): vector y0 = new vector(new double[] {r1_0[0],r1_0[1],r2_0[0],r2_0[1],r3_0[0],r3_0[1], v1_0[0],v1_0[1],v2_0[0],v2_0[1],v3_0[0],v3_0[1]}); // Accuracy and timespan double acc = 1e-5; double eps = 1e-5; double h = 1e-3; double t_f = 10; var xs = new List<double>(); var ys = new List<vector>(); ode.rk45(EOM(MG), t_0, y0, t_f, acc, eps, h, xs, ys); var results = new StreamWriter("outC.data.txt"); for(int i=0; i<xs.Count; i++){ results.WriteLine($"{xs[i]} {ys[i][0]} {ys[i][1]} {ys[i][2]} {ys[i][3]} {ys[i][4]} {ys[i][5]}"); } results.Close(); } // Main