Server IP : 195.201.23.43 / Your IP : 18.219.89.207 Web Server : Apache System : Linux webserver2.vercom.be 5.4.0-192-generic #212-Ubuntu SMP Fri Jul 5 09:47:39 UTC 2024 x86_64 User : kdecoratie ( 1041) PHP Version : 7.1.33-63+ubuntu20.04.1+deb.sury.org+1 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals, MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /lib/ruby/2.7.0/bigdecimal/ |
Upload File : |
# frozen_string_literal: false require "bigdecimal/ludcmp" require "bigdecimal/jacobian" # # newton.rb # # Solves the nonlinear algebraic equation system f = 0 by Newton's method. # This program is not dependent on BigDecimal. # # To call: # n = nlsolve(f,x) # where n is the number of iterations required, # x is the initial value vector # f is an Object which is used to compute the values of the equations to be solved. # It must provide the following methods: # # f.values(x):: returns the values of all functions at x # # f.zero:: returns 0.0 # f.one:: returns 1.0 # f.two:: returns 2.0 # f.ten:: returns 10.0 # # f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. # # On exit, x is the solution vector. # module Newton include LUSolve include Jacobian module_function def norm(fv,zero=0.0) # :nodoc: s = zero n = fv.size for i in 0...n do s += fv[i]*fv[i] end s end # See also Newton def nlsolve(f,x) nRetry = 0 n = x.size f0 = f.values(x) zero = f.zero one = f.one two = f.two p5 = one/two d = norm(f0,zero) minfact = f.ten*f.ten*f.ten minfact = one/minfact e = f.eps while d >= e do nRetry += 1 # Not yet converged. => Compute Jacobian matrix dfdx = jacobian(f,f0,x) # Solve dfdx*dx = -f0 to estimate dx dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero) fact = two xs = x.dup begin fact *= p5 if fact < minfact then raise "Failed to reduce function values." end for i in 0...n do x[i] = xs[i] - dx[i]*fact end f0 = f.values(x) dn = norm(f0,zero) end while(dn>=d) d = dn end nRetry end endPrivate