class Algebra::MPolynomial
Public Class Methods
[](*x)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 191 def self.[](*x) new(Hash[*x]) end
const(x)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 177 def self.const(x) new({Algebra::MIndex::Unity => x}) end
create(ground, *vars)
click to toggle source
Calls superclass method
# File lib/algebra/m-polynomial.rb, line 119 def self.create(ground, *vars) klass = super(ground) klass.sysvar(:order, nil) klass.sysvar(:v_order, nil) klass.set_ord(:lex) klass.sysvar(:variables, vars) klass.sysvar(:display_type, :norm) klass end
euclidian?()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 195 def self.euclidian? ground.euclidian? && variables.size <= 1 end
get_ord()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 297 def self.get_ord order end
get_v_ord()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 305 def self.get_v_ord v_order end
indeterminate(obj)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 145 def self.indeterminate(obj) ind = if i = variables.index(obj) [0] * i + [1] # Algebra::MIndex.monomial(i) else variables.push obj # [0] * (variables.size-1) + [1] Algebra::MIndex.monomial(variables.size-1) end monomial(ind) end
method_cash_clear(*m)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 342 def self.method_cash_clear(*m) # $stderr.puts "method_cash_clear is given no parameter" if m.empty? m.each do |x| x.method_cash_clear end end
monomial(ind = [1], c = ground.unity)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 169 def self.monomial(ind = [1], c = ground.unity) new({Algebra::MIndex[*ind] => c}) end
mvar(*array)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 161 def self.mvar(*array) if array.empty? variables.collect{|var| indeterminate(var) } else array.collect{|var| indeterminate(var)} end end
new(ha = {})
click to toggle source
# File lib/algebra/m-polynomial.rb, line 114 def initialize(ha = {}) @bone = ha method_cash_clear end
ord()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 301 def self.ord get_ord end
ord=(ord)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 293 def self.ord=(ord) self.set_ord(ord, nil) end
regulate(x)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 181 def self.regulate(x) if x.is_a? self x elsif y = ground.regulate(x) const(y) else nil end end
set_ord(ord = nil, v_ord = nil)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 267 def self.set_ord(ord = nil, v_ord = nil) # @@order = MonomialOrder.new(ord, v_ord) if ord.is_a? String ord = ord.intern elsif ord.is_a?(Symbol) || ord.nil? else raise "#{ord} must be String or Symbol" end if v_ord.is_a? String v_ord = v_ord.intern elsif v_ord.is_a?(Symbol) || v_ord.nil? else raise "#{v_ord} must be String or Symbol" end if ord.nil? ord = get_ord end # self.order = MonomialOrder.new(ord, v_ord) #o self.order = ord if ord #n self.v_order = v_ord if v_ord #n MIndex.set_ord(ord) if ord #n MIndex.set_v_ord(v_ord) if v_ord #n end
to_ary()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 141 def self.to_ary [self, *vars] end
ufd?()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 199 def self.ufd? euclidian? || ground.field? end
unity()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 263 def self.unity; const(ground.unity); end
var(obj)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 157 def self.var(obj) indeterminate(obj) end
vars(*vs)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 132 def self.vars(*vs) if vs.size > 0 vs = vs[0].scan(/[a-zA-Z]_?\d*/) if vs.size == 1 && vs[0].is_a?(String) vs.collect{|var| indeterminate(var)} else variables.collect{|var| indeterminate(var) } end end
with_ord(ord = nil, v_ord = nil, methods = []) { || ... }
click to toggle source
# File lib/algebra/m-polynomial.rb, line 322 def self.with_ord(ord = nil, v_ord = nil, methods = []) method_cash_clear(*methods) o_ord, o_v_ord = get_ord, get_v_ord ord = o_ord unless ord result = nil if v_ord MIndex.set_v_ord(ord, v_ord) MIndex.import_module(MIndex.get_module(ord || self.order, v_ord)) do result = yield end MIndex.set_v_ord(o_ord, o_v_ord) else MIndex.import_module(MIndex.get_module(ord || self.order)) do result = yield end end result end
with_ord_old(ord = nil, v_ord = nil, methods = []) { || ... }
click to toggle source
# File lib/algebra/m-polynomial.rb, line 309 def self.with_ord_old(ord = nil, v_ord = nil, methods = []) method_cash_clear(*methods) o_ord, o_v_ord = get_ord, get_v_ord result = nil begin set_ord(ord, v_ord) result = yield ensure set_ord(o_ord, o_v_ord) end result end
zero()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 261 def self.zero; new; end
Public Instance Methods
%(others)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 539 def %(others) divmod(*others).last end
*(other)
click to toggle source
Calls superclass method
Algebra::AlgebraBase#*
# File lib/algebra/m-polynomial.rb, line 450 def *(other) super{ |other| a = zero each do |m0, c0| other.each do |m1, c1| a[m0 + m1] += c0 * c1 end end # a.compact! a } end
+(other)
click to toggle source
Calls superclass method
Algebra::AlgebraBase#+
# File lib/algebra/m-polynomial.rb, line 419 def +(other) super{ |other| a = zero each do |m, c| a[m] = c + other[m] end other.each do |m, c| if !include? m a[m] = self[m] + c # a[m] = c + self[m] end end a } end
-(other)
click to toggle source
Calls superclass method
Algebra::AlgebraBase#-
# File lib/algebra/m-polynomial.rb, line 435 def -(other) super{ |other| a = zero each do |m, c| a[m] = c - other[m] end other.each do |m, c| if !include? m a[m] = self[m] - c end end a } end
/(other)
click to toggle source
Calls superclass method
Algebra::AlgebraBase#/
# File lib/algebra/m-polynomial.rb, line 463 def /(other) # other asume to be scalar # if (o = regulate(other)) super{ |o| if o.constant? # self * (ground.unity / o.constant_coeff) project{|c, ind| c/o.constant_coeff } else a, r = divmod(other) if r.zero? a.first else raise "#{other} not divides #{self}" end end } # else # raise "other(#{o}, #{o.class}) must be monomial" # end end
<=>(other)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 407 def <=>(other) if o = regulate(other) # THIS IS RATHER VAGUE # lm.ind <=> o.lm.ind # self.class.order.cmp(lm.ind, o.lm.ind) #o lm.ind <=> o.lm.ind #n else x , y = other.coerce(self) x <=> y end end
==(other)
click to toggle source
Calls superclass method
Algebra::AlgebraBase#==
# File lib/algebra/m-polynomial.rb, line 393 def ==(other) super{ |other| each do |m, c| return false unless c == other[m] end other.each do |m, c| if !include? m return false unless c.zero? end end true } end
[](ind)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 209 def [](ind) @bone[ind] || 0 end
[]=(ind, c)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 213 def []=(ind, c) @bone[ind] = c end
annihilate_away_from(n, e = 0)
click to toggle source
# File lib/algebra/m-polynomial-factor.rb, line 211 def annihilate_away_from(n, e = 0) # n = 0, e = 2 # x*y*z + x*y**2*z + x*y*z + y*z + z**3 #=> x*y*z + y*z + z**3 project(self.class) do |c, ind| ind.totdeg - ind[n] > e ? ground.zero : c end end
coeffs_at(an)
click to toggle source
# File lib/algebra/m-polynomial-factor.rb, line 251 def coeffs_at(an) ss = (0..deg_at(an)).collect { zero } each do |ind, c| next if c.zero? md = ind.annihilate(an) ss[ind[an]] += monomial(md, c) end ss end
collect_away_from(n, ps)
click to toggle source
# File lib/algebra/m-polynomial-factor.rb, line 271 def collect_away_from(n, ps) # 2*x*y*z + x**2*y*z + x*y #=> [y*z=>(2*x + x**2), y=>x] h_alpha = {} each do |ind, c| next if c.zero? i = ind[n] ind0 = ind.annihilate(n) v = ps.var h_alpha[ind0] = h_alpha[ind0] ? h_alpha[ind0] + c * v**i : c * v**i end h_alpha end
compact!()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 353 def compact! a = {} each do |m, c| a[m.compact] = c unless c.zero? end @bone = a self end
constant?()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 231 def constant? each do |m, c| if m.totdeg > 0 && !c.zero? return false end end true end
constant_coeff()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 244 def constant_coeff # we assume {[]=>2, [0]=>3} is not appeared. # it must be reduced to {[]=>6}. @bone[Algebra::MIndex::Unity] # k = ground.unity # @bone.each do |ind, c| # unless c.zero? # k *= c if ind.totdeg == 0 # end # end # k end
convert_to(ring)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 645 def convert_to(ring) project(ring){|c, ind| c} end
deg()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 391 def deg; multideg; end
deg_at(an)
click to toggle source
# File lib/algebra/m-polynomial-factor.rb, line 219 def deg_at(an) if zero? -1 else max = 0 each do |ind, c| unless c.zero? t = ind[an] max = t if t > max end end max end end
derivate(v)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 616 def derivate(v) if an = self.class.variables.index(v) || vars.index(v) derivate_at(an) else raise "#{var} is not a variable" end end
derivate_at(an)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 624 def derivate_at(an) ary = vars project0 {|c, ind| if ind[an] < 1 zero else ind0 = ind - Algebra::MIndex.monomial(an) index_eval(self.class, ary, ind0) * ind[an] * c end } end
divmod(*f)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 485 def divmod(*f) g = clone # not dup f_lts = f.collect{|x| x.lt} a = (0...f.size).collect{zero} r = zero until g.zero? flag = false f_lts.each_with_index do |f_lt, i| g_lt = g.lt if f_lt.divide? g_lt d = g_lt / f_lt if d == 0 then exit; end a[i] += d g = g.rt - (d * f[i]).rt g.compact! flag = true break end end unless flag r += g.lt g = g.rt #g.rt! g.compact! end end [a, r] end
divmod_variant(*f)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 513 def divmod_variant(*f) g = clone # not dup f_lts = f.collect{|x| x.lt} a = (0...f.size).collect{zero} r = zero until g.zero? flag = false f_lts.each_with_index do |f_lt, i| g_lt = g.lt if f_lt.divide? g_lt d = g_lt / f_lt a[i] += d g = g.rt - (d * f[i]).rt g.compact! flag = true g.zero? ? break : redo end end unless flag r += g.lt g = g.rt #g.rt! end end [a, r] end
each(&b)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 203 def each(&b); @bone.each(&b); end
evaluate(*ary)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 598 def evaluate(*ary) project(ground, ary){|c, ind| c} # project(self.class, ary){|c, ind| c} end
Also aliased as: call
factorize()
click to toggle source
# File lib/algebra/m-polynomial-factor.rb, line 188 def factorize return Algebra::Factors.new([[zero, 1]]) if zero? fact = if ground <= Integer factorize_int elsif defined?(Rational) && ground <= Rational || defined?(LocalizedRing) && ground <= LocalizedRing factorize_rational elsif defined?(ResidueClassRing) && ground <= ResidueClassRing && ground.ground <= Integer factorize_modp else factorize_alg end fact.normalize! end
gcd(other)
click to toggle source
# File lib/algebra/annihilate.rb, line 25 def gcd(other) (self * other).divmod(lcm(other)).first.first end
gcd_all(*a)
click to toggle source
# File lib/algebra/annihilate.rb, line 29 def gcd_all(*a) t = self a.each do |x| break if t.constant? t = t.gcd(x) end t end
include?(k)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 257 def include?(k) @bone.include?(k) end
index_eval(ring, ary, ind)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 572 def index_eval(ring, ary, ind) e = ring.unity ind.each_with_index do |n, i| e *= ary[i]**n if n > 0 end e end
indice_of_constant()
click to toggle source
# File lib/algebra/m-polynomial-factor.rb, line 234 def indice_of_constant (0...vars.size).find_all { |an| deg_at(an) <= 0 } end
keys()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 205 def keys; @bone.keys; end
lc()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 548 def lc @lc ||= self[multideg] end
lc_at(an)
click to toggle source
# File lib/algebra/m-polynomial-factor.rb, line 238 def lc_at(an) d = deg_at(an) s = zero each do |ind, c| next if c.zero? if ind[an] == d md = ind.annihilate(an) s += monomial(md, c) end end s end
lcm(other)
click to toggle source
# File lib/algebra/annihilate.rb, line 6 def lcm(other) vars0 = vars mp = MPolynomial.create(ground) mp.vars('t', *vars) t = mp.vars.first mpvars = mp.vars f = project0(mp) do |c, ind| c * index_eval(mp, mpvars, [0] + ind.to_a) end g = other.project0(mp) do |c, ind| c * index_eval(mp, mpvars, [0] + ind.to_a) end gb = Groebner.basis([t * f, (1 - t) * g]) lcm0 = gb.last lcm0.project0(self.class) do |c, ind| c * index_eval(self.class, vars0, ind.empty? ? [] : ind[1..-1]) end end
lm()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 552 def lm #@lm ||= monomial(multideg).extend(Monomial) monomial(multideg).extend(Monomial) end
lt()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 557 def lt md = multideg @lt ||= monomial(md, self[md]).extend(Monomial) end
method_cash_clear()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 349 def method_cash_clear @lc = @lm = @lt = @rt = @multideg = nil end
monomial(ind = [1], c = ground.unity)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 173 def monomial(ind = [1], c = ground.unity) self.class.monomial(ind, c) end
monomial?()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 217 def monomial? flag = false each do |m, c| unless c.zero? if flag return false else flag = true end end end flag end
move_const(pb, coef = ground.unity)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 636 def move_const(pb, coef = ground.unity) vs = self.class.vars.dup a = [] vs.each_with_index do |x, i| a << x + pb[i]*coef end evaluate(*a) end
multideg()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 362 def multideg if @multideg @multideg else d = Algebra::MIndex::Unity each do |m, c| # d = m if !c.zero? && m > d # d = m if !c.zero? && self.class.order.cmp(m, d) > 0 #o d = m if !c.zero? && (m <=> d) > 0 #n end @multideg = d end end
need_paren_in_coeff?()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 649 def need_paren_in_coeff? if constant? c = constant_coeff if c.respond_to?(:need_paren_in_coeff?) c.need_paren_in_coeff? elsif c.is_a?(Numeric) false else true end elsif !monomial? true else false end end
project(ring = self.class, ary = ring.vars) { |c, ind| ... }
click to toggle source
# File lib/algebra/m-polynomial.rb, line 590 def project(ring = self.class, ary = ring.vars) e = ring.zero each do |ind, c| e += index_eval(ring, ary, ind) * yield(c, ind) end e end
project0(ring = self.class, ary = ring.vars) { |c, ind| ... }
click to toggle source
# File lib/algebra/m-polynomial.rb, line 580 def project0(ring = self.class, ary = ring.vars) e = ring.zero each do |ind, c| e += yield(c, ind) end e end
Also aliased as: map_to
reduce2onevar(pring, n)
click to toggle source
# File lib/algebra/m-polynomial-factor.rb, line 203 def reduce2onevar(pring, n) evar = [] self.class.vars.each_with_index do |_v, i| evar.push i == n ? pring.var : pring.zero end project(pring, evar) { |c, _ind| c } end
rt()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 562 def rt @rt ||= self - lt end
rt!()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 566 def rt! # deepy destructive, do NOT use @bone.delete(multideg) method_cash_clear self end
sub(var, value)
click to toggle source
# File lib/algebra/m-polynomial.rb, line 603 def sub(var, value) vs = self.class.vars if i = vs.index(var) vs = vs.dup vs[i] = value evaluate(*vs) else raise "#{var} is not a variable" end end
to_s()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 666 def to_s case self.class.display_type when :code pr, po = "*", "**" when :tex pr, po = "", "}^" else pr, po = "", "^" end a = [] # (k = keys).sort! # k = keys.sort{|x, y| self.class.order.cmp(x, y)} #o k = keys.sort{|x, y| x <=> y} #n k.each do |m| c = self[m] next if c.zero? s = if m.unity? c.to_s else case c when Numeric c = c == 1 ? "" : c == -1 ? "-" : c.to_s when self.class c = "(#{c})" else c = if c == 1 "" elsif c == -1 "-" elsif c.respond_to?(:need_paren_in_coeff?) if c.need_paren_in_coeff? "(#{c})" else c.to_s end elsif c.is_a?(Numeric) c.to_s else "(#{c})" end end ms = m.to_s(variables, pr, po) c.empty? ? ms : c + pr + ms end a.unshift s end a.unshift "0" if a.empty? a.join(" + ").gsub(/\+ -/, "- ") end
Also aliased as: inspect
totdeg()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 376 def totdeg if zero? -1 else max = 0 each do |ind, c| unless c.zero? t = ind.totdeg max = t if t > max end end max end end
totdeg_away_from(n)
click to toggle source
# File lib/algebra/m-polynomial-factor.rb, line 261 def totdeg_away_from(n) max = 0 each do |ind, c| next if c.zero? m = ind.totdeg - ind[n] max = m if m > max end max end
unit?()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 240 def unit? constant? && lc.unit? end
values()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 207 def values; @bone.values; end
variables()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 129 def variables; self.class.variables; end
vars()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 130 def vars; self.class.vars; end
zero?()
click to toggle source
# File lib/algebra/m-polynomial.rb, line 265 def zero?; !find{|m, c| !c.zero?}; end