Module: MyMathGem::ODESolver
- Defined in:
- lib/my_math_gem/ode_solver.rb
Class Method Summary collapse
-
.euler(t0:, y0:, t_end:, steps:, f:, callback: nil, return_separate: false) ⇒ Object
Metode Euler untuk ODE y’ = f(t, y).
-
.heun(t0:, y0:, t_end:, steps:, f:, callback: nil, return_separate: false) ⇒ Object
Metode Heun (Improved Euler).
-
.runge_kutta4(t0:, y0:, t_end:, steps:, f:, callback: nil, return_separate: false) ⇒ Object
Metode Runge-Kutta orde 4 (RK4).
Class Method Details
.euler(t0:, y0:, t_end:, steps:, f:, callback: nil, return_separate: false) ⇒ Object
Metode Euler untuk ODE y’ = f(t, y)
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/my_math_gem/ode_solver.rb', line 4 def self.euler(t0:, y0:, t_end:, steps:, f:, callback: nil, return_separate: false) validate_params!(t0, y0, t_end, steps, f) dt = (t_end - t0).to_f / steps ts = [t0] ys = [deep_copy(y0)] steps.times do |i| t, y = ts[-1], ys[-1] dy = f.call(t, y) y_next = vector_add(y, scalar_multiply(dy, dt)) t_next = t + dt ts << t_next ys << y_next callback.call(t_next, y_next) if callback.is_a?(Proc) end return_separate ? { times: ts, values: ys } : ts.zip(ys) end |
.heun(t0:, y0:, t_end:, steps:, f:, callback: nil, return_separate: false) ⇒ Object
Metode Heun (Improved Euler)
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/my_math_gem/ode_solver.rb', line 62 def self.heun(t0:, y0:, t_end:, steps:, f:, callback: nil, return_separate: false) validate_params!(t0, y0, t_end, steps, f) dt = (t_end - t0).to_f / steps ts = [t0] ys = [deep_copy(y0)] steps.times do t, y = ts[-1], ys[-1] k1 = f.call(t, y) y_predict = vector_add(y, scalar_multiply(k1, dt)) k2 = f.call(t + dt, y_predict) increment = scalar_multiply(vector_add(k1, k2), dt / 2.0) y_next = vector_add(y, increment) t_next = t + dt ts << t_next ys << y_next callback.call(t_next, y_next) if callback.is_a?(Proc) end return_separate ? { times: ts, values: ys } : ts.zip(ys) end |
.runge_kutta4(t0:, y0:, t_end:, steps:, f:, callback: nil, return_separate: false) ⇒ Object
Metode Runge-Kutta orde 4 (RK4)
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/my_math_gem/ode_solver.rb', line 27 def self.runge_kutta4(t0:, y0:, t_end:, steps:, f:, callback: nil, return_separate: false) validate_params!(t0, y0, t_end, steps, f) dt = (t_end - t0).to_f / steps ts = [t0] ys = [deep_copy(y0)] steps.times do t, y = ts[-1], ys[-1] k1 = f.call(t, y) k2 = f.call(t + dt/2.0, vector_add(y, scalar_multiply(k1, dt/2.0))) k3 = f.call(t + dt/2.0, vector_add(y, scalar_multiply(k2, dt/2.0))) k4 = f.call(t + dt, vector_add(y, scalar_multiply(k3, dt))) increment = scalar_multiply( vector_add( vector_add(k1, scalar_multiply(k2, 2)), vector_add(scalar_multiply(k3, 2), k4) ), dt / 6.0 ) y_next = vector_add(y, increment) t_next = t + dt ts << t_next ys << y_next callback.call(t_next, y_next) if callback.is_a?(Proc) end return_separate ? { times: ts, values: ys } : ts.zip(ys) end |