Module: Mathpack::IntegralEquations
- Defined in:
- lib/mathpack/integral_equations.rb
Class Method Summary collapse
- .solve_fredholm_2(params = {}) ⇒ Object
- .solve_freedholm_with_step(step, params = {}) ⇒ Object
- .solve_volter_2(params = {}) ⇒ Object
- .solve_volter_with_step(step, params = {}) ⇒ Object
Class Method Details
.solve_fredholm_2(params = {}) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 |
# File 'lib/mathpack/integral_equations.rb', line 3 def self.solve_fredholm_2(params = {}) step = (params[:to] - params[:from]) / 2.0 y_next = solve_freedholm_with_step(step, params) loop do y_prev = y_next step /= 2.0 y_next = solve_freedholm_with_step(step, params) break if Mathpack::IO.count_diff(y_next, y_prev) / (2**4 - 1) <= params[:eps] end { x: Mathpack::Approximation.generate_nodes(from: params[:from], to: params[:to], step: step), f: y_next } end |
.solve_freedholm_with_step(step, params = {}) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/mathpack/integral_equations.rb', line 15 def self.solve_freedholm_with_step(step, params = {}) nodes = Mathpack::Approximation.generate_nodes(from: params[:from], to: params[:to], step: step) a = Array.new(nodes.length) do |i| i % 2 == 1 ? 4.0 * step / 3.0 : 2.0 * step / 3.0 end a[0], a[-1] = 1.0 / 3.0 * step, 1.0 / 3.0 * step matrix = Array.new(nodes.length) { Array.new nodes.length } for i in 0...matrix.length do for j in 0...matrix[i].length do matrix[i][j] = i == j ? 1.0 - params[:lambda] * a[i] * params[:k].call(nodes[i], nodes[i]) : - params[:lambda] * a[j] * params[:k].call(nodes[i], nodes[j]) end end f = Array.new(nodes.length){ |i| params[:f].call(nodes[i]) } Mathpack::SLE.solve(matrix: matrix, f: f) end |
.solve_volter_2(params = {}) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/mathpack/integral_equations.rb', line 31 def self.solve_volter_2(params = {}) step = (params[:to] - params[:from]) / 2.0 y_next = solve_volter_with_step(step, params) loop do y_prev = y_next step /= 2.0 y_next = solve_volter_with_step(step, params) break if Mathpack::IO.count_diff(y_next, y_prev) / (2**2 - 1) <= params[:eps] end { x: Mathpack::Approximation.generate_nodes(from: params[:from], to: params[:to], step: step), f: y_next } end |
.solve_volter_with_step(step, params = {}) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/mathpack/integral_equations.rb', line 43 def self.solve_volter_with_step(step, params = {}) y = [] nodes = Mathpack::Approximation.generate_nodes(from: params[:from], to: params[:to], step: step) y[0] = params[:f].call(nodes[0]) y[1] = (params[:f].call(nodes[1]) + 0.5 * params[:lambda] * step * params[:k].call(nodes[1], nodes[0]) * y[0]) / (1.0 - 0.5 * params[:lambda] * step * params[:k].call(nodes[1], nodes[1])) for i in 2...nodes.length do sum = 0.0 for j in 1..(i-1) do sum += params[:k].call(nodes[i], nodes[j]) * y[j] end sum *= step y[i] = (0.5 * params[:lambda] * step * params[:k].call(nodes[i], nodes[0]) * y[0] + params[:lambda] * sum + params[:f].call(nodes[i])) / (1.0 - 0.5 * params[:lambda] * step * params[:k].call(nodes[i], nodes[i])) end y end |