unit Polynomial;
interface
uses math;
const ZERO = 1e-10;
type TPolynomial = record
deg:integer;
coeff:array of Double
end;
function MakePolynomial(n:integer):TPolynomial;
function Equals(a,b:TPolynomial):boolean;
function AddPolynomials(a,b:TPolynomial):TPolynomial;
function SubtractPolynomials(a,b:TPolynomial):TPolynomial;
function MultiplyPolynomials(a,b:TPolynomial):TPolynomial;
function DividePolynomials(a,b:TPolynomial;var r:TPolynomial):TPolynomial;
function Horner(p:TPolynomial;x:Double):Double;
procedure WritePolynomial(p:TPolynomial;c:char);
implementation
function MakePolynomial(n:integer):TPolynomial;
var p:TPolynomial;
begin
p.deg := n;
SetLength(p.coeff,n+1);
MakePolynomial := p
end;
procedure FindDeg(var p:TPolynomial);
var i:integer;
begin
for i := p.deg downto 0 do
if abs(p.coeff[i]) > ZERO then
begin
p.deg := i;
Exit;
end;
p.deg := 0
end;
function AddPolynomials(a,b:TPolynomial):TPolynomial;
var newDeg,range,i:integer;
n:TPolynomial;
begin
if a.deg > b.deg then
newDeg := a.deg
else
newDeg := b.deg;
range := newDeg - abs(a.deg - b.deg);
n := MakePolynomial(newDeg);
for i := range downto 0 do
n.coeff[i] := a.coeff[i] + b.coeff[i];
if a.deg > b.deg then
for i := newDeg downto range+1 do
n.coeff[i] := a.coeff[i]
else
for i := newDeg downto range+1 do
n.coeff[i] := b.coeff[i];
findDeg(n);
AddPolynomials := n
end;
function SubtractPolynomials(a,b:TPolynomial):TPolynomial;
var newDeg,range,i:integer;
n:TPolynomial;
begin
if a.deg > b.deg then
newDeg := a.deg
else
newDeg := b.deg;
range := newDeg - abs(a.deg - b.deg);
n := MakePolynomial(newDeg);
for i := range downto 0 do
n.coeff[i] := a.coeff[i] - b.coeff[i];
if a.deg > b.deg then
for i := newDeg downto range+1 do
n.coeff[i] := a.coeff[i]
else
for i := newDeg downto range+1 do
n.coeff[i] := -b.coeff[i];
findDeg(n);
SubtractPolynomials := n
end;
function MultiplyPolynomials(a,b:TPolynomial):TPolynomial;
var i,j:integer;
n:TPolynomial;
begin
n := MakePolynomial(a.deg + b.deg);
for i := 0 to n.deg do
n.coeff[i] := 0;
for i := 0 to a.deg do
for j := 0 to b.deg do
n.coeff[i + j] := n.coeff[i + j] + a.coeff[i] * b.coeff[j];
MultiplyPolynomials := n
end;
function DividePolynomials(a,b:TPolynomial;var r:TPolynomial):TPolynomial;
var q,temp:TPolynomial;
i,j,qdeg:integer;
begin
if a.deg < b.deg then
qdeg := 0
else
qdeg := a.deg;
q := MakePolynomial(qdeg);
if q.deg = 0 then
begin
q.coeff[0] := 0;
r.deg := a.deg;
for i :=r.deg downto 0 do
r.coeff[i] := a.coeff[i];
DividePolynomials := q;
Exit
end;
temp := MakePolynomial(a.deg);
for i := 0 to a.deg do
begin
temp.coeff[i] := a.coeff[i];
q.coeff[i] := 0
end;
for i := a.deg - b.deg downto 0 do
begin
q.coeff[i] := temp.coeff[b.deg + i] /b.coeff[b.deg];
for j := b.deg + i - 1 downto i do
temp.coeff[j] := temp.coeff[j] - q.coeff[i] * b.coeff[j - i]
end;
for i := 0 to b.deg - 1 do
r.coeff[i] := temp.coeff[i];
if r.deg < a.deg then
for i := b.deg to r.deg do
r.coeff[i] := 0
else
for i := b.deg to a.deg do
r.coeff[i] := 0;
findDeg(r);
findDeg(q);
DividePolynomials := q
end;
function Equals(a,b:TPolynomial):boolean;
var bool : boolean;
i : integer;
begin
bool := a.deg = b.deg;
i := a.deg;
while bool and (i >= 0) do
begin
bool := bool and (a.coeff[i] = b.coeff[i]);
Dec(i)
end;
Equals := bool
end;
procedure WritePolynomial(p:TPolynomial;c:char);
var i:integer;
begin
for i := p.deg downto 0 do
if p.coeff[i] < 0 then
write(p.coeff[i]:1:12,'*',c,'^',i)
else
write('+',p.coeff[i]:1:12,'*',c,'^',i);
writeln
end;
function Horner(p:TPolynomial;x:Double):Double;
var v:double;
i:integer;
begin
v := p.coeff[p.deg];
for i := p.deg - 1 downto 0 do
v := v * x + p.coeff[i];
Horner := v
end;
begin
end.