############################################################################
#
# File: polystuf.icn
#
# Subject: Procedures for manipulating polynomials
#
# Author: Erik Eid
#
# Date: May 23, 1994
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# These procedures are for creating and performing operations on single-
# variable polynomials (like ax^2 + bx + c).
#
# poly (c1, e1, c2, e2, ...) - creates a polynomial from the parameters
# given as coefficient-exponent pairs:
# c1x^e1 + c2x^e2 + ...
# is_zero (n) - determines if n = 0
# is_zero_poly (p) - determines if a given polynomial is 0x^0
# poly_add (p1, p2) - returns the sum of two polynomials
# poly_sub (p1, p2) - returns the difference of p1 - p2
# poly_mul (p1, p2) - returns the product of two polynomials
# poly_eval (p, x) - finds the value of polynomial p when
# evaluated at the given x.
# term2string (c, e) - converts one coefficient-exponent pair
# into a string.
# poly_string (p) - returns the string representation of an
# entire polynomial.
#
############################################################################
procedure poly (terms[])
local p, coef, expn
if *terms % 2 = 1 then fail # Odd number of terms means the
# list does not contain all
# coefficient-exponent pairs.
p := table()
while *terms > 0 do { # A polynomial is stored as a
coef := get(terms) # table in which the keys are
expn := get(terms) # exponents and the elements are
# coefficients.
if numeric(coef) then if numeric(expn)
then p[real(expn)] := coef # If any part of pair is invalid,
# discard it. Otherwise, save
# term with a real key (necessary
# for consistency in sorting).
}
return p
end
procedure is_zero (n)
if ((n = integer(n)) & (n = 0)) then return else fail
end
procedure is_zero_poly (p)
if ((*p = 1) & is_zero(p[real(0)])) then return else fail
end
procedure poly_add (p1, p2)
local p3, z
p3 := copy(p1) # Make a copy to start with.
if is_zero_poly (p3) then delete (p3, real(0))
# If first is zero, don't include
# the 0x^0 term.
every z := key(p2) do { # For every term in the second
if member (p3, z) then p3[z] +:= p2[z] # polynomial, if one of its
else p3[z] := p2[z] # exponent is in the third,
# increment its coefficient.
# Otherwise, create a new term.
if is_zero(p3[z]) then delete (p3, z)
# Remove any term with coefficient
# zero, since the term equals 0.
}
if *p3 = 0 then p3[real(0)] := 0 # Empty poly table indicates a
# zero polynomial.
return p3
end
procedure poly_sub (p1, p2)
local p3, z
p3 := copy(p1) # Similar process to poly_add.
if is_zero_poly (p3) then delete (p3, real(0))
every z := key(p2) do {
if member (p3, z) then p3[z] -:= p2[z]
else p3[z] := -p2[z]
if is_zero(p3[z]) then delete (p3, z)
}
if *p3 = 0 then p3[real(0)] := 0
return p3
end
procedure poly_mul (p1, p2)
local p3, c, e, y, z
p3 := table()
every y := key(p1) do # Multiply every term in p1 by
every z := key(p2) do { # every term in p2 and add those
c := p1[y] * p2[z] # results into p3 as in poly_add.
e := y + z
if member (p3, e) then p3[e] +:= c
else p3[e] := c
if is_zero(p3[e]) then delete (p3, e)
}
if *p3 = 0 then p3[real(0)] := 0
return p3
end
procedure poly_eval (p, x)
local e, sum
sum := 0
every e := key(p) do # Increase sum by coef * x ^ exp.
sum +:= p[e] * (x ^ e) # Note: this procedure does not
# check in advance if x^e will
# result in an error.
return sum
end
procedure term2string (c, e)
local t
t := ""
if e = integer(e) then e := integer(e) # Removes unnecessary ".0"
if c ~= 1 then {
if c = -1 then t ||:= "-" else t ||:= c
} # Use "-x" or "x," not "-1x" or
# "1x."
else if e = 0 then t ||:= c # Make sure to include a
# constant term.
if e ~= 0 then {
t ||:= "x"
if e ~= 1 then t ||:= ("^" || e) # Use "x," not "x^1."
}
return t
end
procedure poly_string (p)
local pstr, plist, c, e
pstr := ""
plist := sort(p, 3) # Sort table into key-value pairs.
while *plist > 0 do {
c := pull(plist) # Since sort is nondecreasing,
e := pull(plist) # take terms in reverse order.
pstr ||:= (term2string (c, e) || " + ")
}
pstr := pstr[1:-3] # Remove last " + " from end
return pstr
end
This page produced by UniDoc on 2021/04/15 @ 23:59:45.