The Gauss-Legendre methods are implicit, so in general they cannot be applied exactly. Instead one makes an educated guess of k_i , and then uses
Newton's method to converge arbitrarily close to the true solution. Below is a
Matlab function which implements the Gauss-Legendre method of order four. % starting point x = [ 10.5440; 4.1124; 35.8233]; dt = 0.01; N = 10000; x_series = [x]; for i = 1:N x = gauss_step(x, @lorenz_dynamics, dt, 1e-7, 1, 100); x_series = [x_series x]; end plot3( x_series(1,:), x_series(2,:), x_series(3,:) ); set(gca,'xtick',[],'ytick',[],'ztick',[]); title('Lorenz Attractor'); return; function [td, j] = lorenz_dynamics(state) % return a time derivative and a Jacobian of that time derivative x = state(1); y = state(2); z = state(3); sigma = 10; beta = 8/3; rho = 28; td = [sigma*(y-x); x*(rho-z)-y; x*y-beta*z]; j = [-sigma, sigma, 0; rho-z, -1, -x; y, x, -beta]; end function x_next = gauss_step( x, dynamics, dt, threshold, damping, max_iterations ) [d,~] = size(x); sq3 = sqrt(3); if damping > 1 || damping threshold && iteration threshold error('Newton did not converge by %d iterations.', max_iterations); end x_next = x + dt / 2 * (k1 + k2); end This algorithm is surprisingly cheap. The error in k_i can fall below 10^{-12} in as few as 2 Newton steps. The only extra work compared to explicit Runge-Kutta methods is the computation of the Jacobian. == Time-symmetric variants ==