Class: Silicium::Algebra::PolynomialDivision
- Inherits:
-
Object
- Object
- Silicium::Algebra::PolynomialDivision
- Defined in:
- lib/polynomial_division.rb
Overview
TODO: class docs
Constant Summary collapse
- DELTA =
0.01
Instance Method Summary collapse
- #build_polynom_from_coeffs(coefficients) ⇒ Object
- #compare_polynoms(poly1, poly2) ⇒ Object
-
#polynom_division(poly_1, poly_2) ⇒ Object
This function returns array of 2 strings: first is the result of division polynom poly_1 on polynom poly_2 Second - remainder.
-
#polynom_gcd(poly1, poly2, delta = DELTA) ⇒ Object
This function returns a string: greatest common integer divisor of two polynoms.
-
#polynom_parser(str) ⇒ Object
This function returns an array of coefficients obtained by parsing input string in format: “<coeff>x*<degree>+…” Even if in your expression don’t exist x with some degree, you should to write it with 0 coefficient Also free term you should to write with 0 degree Example: “2*x**5-3*x**4+0*x**3+0*x**2-5*x**1-6*x**0”.
- #round_coeffs(coefficients, delta = DELTA) ⇒ Object
-
#str_rem_impl(coeff_1) ⇒ Object
String implementation of remained part.
-
#str_res_impl(coeff_res, sgn_array) ⇒ Object
String implementation of result.
- #zero_coeffs?(polynom, delta = DELTA) ⇒ Boolean
Instance Method Details
#build_polynom_from_coeffs(coefficients) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/polynomial_division.rb', line 96 def build_polynom_from_coeffs(coefficients) "#{coefficients[0]}*x**#{coefficients.size - 1}" + coefficients[1..-1].each_with_index.inject('') do |acc, (coefficient, index)| leading_sign = coefficient >= 0 ? '+' : '' acc + "#{leading_sign}#{coefficient}*x**#{ coefficients.size - index - 2 }" end end |
#compare_polynoms(poly1, poly2) ⇒ Object
82 83 84 |
# File 'lib/polynomial_division.rb', line 82 def compare_polynoms(poly1, poly2) polynom_parser(poly1).size - polynom_parser(poly2).size end |
#polynom_division(poly_1, poly_2) ⇒ Object
This function returns array of 2 strings: first is the result of division polynom poly_1 on polynom poly_2 Second - remainder
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/polynomial_division.rb', line 63 def polynom_division(poly_1, poly_2) coeff_1 = polynom_parser(poly_1) coeff_2 = polynom_parser(poly_2) res_size = coeff_1.size - coeff_2.size + 1 coeff_result = Array.new(res_size) sgn_array = Array.new(res_size + 1,'') (0..res_size-1).each do |i| cur_coeff = coeff_1[i] / coeff_2[0] coeff_result[i] = cur_coeff coeff_result[i] < 0 ? sgn_array[i] = '-' : sgn_array[i] = '+' (0..coeff_2.size-1).each do |j| coeff_1[i+j] -= coeff_2[j]*cur_coeff end end res_exp = str_res_impl(coeff_result, sgn_array) rem_exp = str_rem_impl(coeff_1[coeff_result.size..coeff_1.size-1]) [res_exp, rem_exp] end |
#polynom_gcd(poly1, poly2, delta = DELTA) ⇒ Object
This function returns a string: greatest common integer divisor of two polynoms
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/polynomial_division.rb', line 105 def polynom_gcd(poly1, poly2, delta = DELTA) divisor, remainder = order_gcd_operands(poly1, poly2) until zero_coeffs?(remainder) do division = polynom_division(divisor, remainder) divisor = remainder remainder = division[1] end normalizer = polynom_parser(divisor)[0] temp_result = polynom_division(divisor, normalizer.to_s+'*x**0')[0] coefficients = round_coeffs(polynom_parser(temp_result), delta) build_polynom_from_coeffs(coefficients) end |
#polynom_parser(str) ⇒ Object
This function returns an array of coefficients obtained by parsing input string in format: “<coeff>x*<degree>+…” Even if in your expression don’t exist x with some degree, you should to write it with 0 coefficient Also free term you should to write with 0 degree Example: “2*x**5-3*x**4+0*x**3+0*x**2-5*x**1-6*x**0”
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/polynomial_division.rb', line 15 def polynom_parser(str) copy_str = str.clone sgn_array = [] # Array of signs if copy_str[0] != '-' sgn_array.push('+') else sgn_array.push('-') copy_str[0] = '' end token = copy_str.split(/[-+]/) (0..copy_str.size-1).each do |i| sgn_array.push(copy_str[i]) if copy_str[i] == '-' || copy_str[i] == '+' end size = token.size - 1 coeff = [] # Array of coefficients (0..size).each do |i| degree = token[i].split('*') # Split by '*' to get coefficient and degree degree[0] == 'x' ? coeff[i] = 1.0 : coeff[i] = degree[0].to_f coeff[i] *= -1 if sgn_array[i] == '-' end coeff end |
#round_coeffs(coefficients, delta = DELTA) ⇒ Object
90 91 92 93 94 |
# File 'lib/polynomial_division.rb', line 90 def round_coeffs(coefficients, delta = DELTA) coefficients.map do |element| (element.round - element).abs < delta ? element.round.to_f : element end end |
#str_rem_impl(coeff_1) ⇒ Object
String implementation of remained part
50 51 52 53 54 55 56 57 58 59 |
# File 'lib/polynomial_division.rb', line 50 def str_rem_impl(coeff_1) c = coeff_1.size rem_exp = "" (0..c-1).each do |i| rem_exp += '+' if coeff_1[i] >= 0.0 rem_exp += ((coeff_1[i].ceil(3)).to_s+"*x**"+(c - i - 1).to_s) end rem_exp[0] = '' if rem_exp[0] == '+' rem_exp end |
#str_res_impl(coeff_res, sgn_array) ⇒ Object
String implementation of result
39 40 41 42 43 44 45 46 47 |
# File 'lib/polynomial_division.rb', line 39 def str_res_impl(coeff_res, sgn_array) res_size = coeff_res.size res_exp = "" (0..res_size-1).each do |i| res_exp += ((coeff_res[i].ceil(3)).to_s+"*x**"+(res_size - i - 1).to_s) res_exp += sgn_array[i+1] if sgn_array[i+1] != '-' end res_exp end |
#zero_coeffs?(polynom, delta = DELTA) ⇒ Boolean
86 87 88 |
# File 'lib/polynomial_division.rb', line 86 def zero_coeffs?(polynom, delta = DELTA) polynom_parser(polynom).all?{ |item| item.abs < delta } end |