Module: Mathpack::DifferentialEquations
- Defined in:
- lib/mathpack/differential_equations.rb
Class Method Summary collapse
- .generate_result(params, step, u) ⇒ Object
- .runge_kutta_4(params = {}) ⇒ Object
- .solve_cauchie_system(params = {}) ⇒ Object
Class Method Details
.generate_result(params, step, u) ⇒ Object
66 67 68 69 70 |
# File 'lib/mathpack/differential_equations.rb', line 66 def self.generate_result(params, step, u) result = { x: Mathpack::Approximation.generate_nodes(from: params[:from], to: params[:to], step: step) } u.each_index { |i| result[:"u#{i + 1}"] = u[i] } result end |
.runge_kutta_4(params = {}) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/mathpack/differential_equations.rb', line 5 def self.runge_kutta_4(params = {}) nodes = Mathpack::Approximation.generate_nodes(from: params[:from], to: params[:to], step: params[:step]) y = Array.new(params[:system].length) { Array.new(nodes.length) } y.each_index do |i| y[i][0] = params[:y0][i] end fi0 = Array.new(y.length) fi1 = Array.new(y.length) fi2 = Array.new(y.length) fi3 = Array.new(y.length) for i in 0...nodes.length-1 do column = y.transpose[i] y_volna = Array.new(y.length) y.each_index do |j| fi0[j] = params[:system][j].call(nodes[i], *column) end y.each_index do |j| y_volna.each_index { |k| y_volna[k] = column[k] + 0.5 * params[:step] * fi0[k] } fi1[j] = params[:system][j].call(nodes[i] + 0.5 * params[:step], *y_volna) end y.each_index do |j| y_volna.each_index { |k| y_volna[k] = column[k] + 0.5 * params[:step] * fi1[k] } fi2[j] = params[:system][j].call(nodes[i] + 0.5 * params[:step], *y_volna) end y.each_index do |j| y_volna.each_index { |k| y_volna[k] = column[k] + params[:step] * fi2[k] } fi3[j] = params[:system][j].call(nodes[i + 1], *y_volna) end y.each_index do |j| y[j][i + 1] = y[j][i] + params[:step]/6.0 * (fi0[j] + 2.0 * fi1[j] + 2.0 * fi2[j] + fi3[j]) y[j][i + 1] = y[j][i] + params[:step]/6.0 * (fi0[j] + 2.0 * fi1[j] + 2.0 * fi2[j] + fi3[j]) end end y end |
.solve_cauchie_system(params = {}) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/mathpack/differential_equations.rb', line 41 def self.solve_cauchie_system(params = {}) params[:method] ||= :runge_kutta_4 params[:m] = 2 step = (params[:to] - params[:from]) / 2.0 result = Mathpack::DifferentialEquations.send(params[:method], from: params[:from], to: params[:to], step: step, y0: params[:y0], system: params[:system], eps: params[:eps]) u_next = Array.new(params[:system].length) { |i| result[i] } loop do u_prev = Array.new(u_next.length) { |i| u_next[i].dup } step /= 2.0 result = Mathpack::DifferentialEquations.send(params[:method], from: params[:from], to: params[:to], step: step, y0: params[:y0], system: params[:system], eps: params[:eps]) u_next.each_index do |i| u_next[i] = result[i] end is_finished = true u_next.each_index do |i| if Mathpack::IO.count_diff(u_next[i], u_prev[i]) / (2**params[:m] - 1) > params[:eps] is_finished = false break end end break if is_finished end generate_result(params, step, u_next) end |