1#!/usr/bin/env python
2
3import polypy
4import polypy_test
5
6def check_binary(op, op_name, p, q, expected):
7    result = op(p, q)
8    ok = result == expected
9    if (not ok):
10        print("p = {0}".format(p))
11        print("q = {0}".format(q))
12        print("{0} = {1}".format(op_name, result))
13        print("expected = {0}".format(expected))
14    polypy_test.check(ok)
15
16def check_unary(op, op_name, p, expected):
17    result = op(p)
18    ok = result == expected
19    if (not ok):
20        print("p = {0}".format(p))
21        print("{0} = {1}".format(op_name, result))
22        print("expected = {0}".format(expected))
23    polypy_test.check(ok)
24
25polypy_test.init()
26
27polypy_test.start("Addition")
28
29x = polypy.Variable("x");
30y = polypy.Variable("y");
31z = polypy.Variable("z");
32
33polypy.variable_order.set([z, y, x])
34
35# polypy.trace_enable("polynomial")
36# polypy.trace_enable("coefficient")
37# polypy.trace_enable("coefficient::reduce")
38
39def poly_plus(p, q):
40    return p + q
41
42p = x**2 + 2*x + 1
43q = y**2 + 2*y + 1
44expected = x**2 + y**2 + 2*x + 2*y + 2
45check_binary(poly_plus, "plus", p, q, expected)
46
47p = x**2
48q = 1
49expected = x**2 + 1
50check_binary(poly_plus, "plus", p, q, expected)
51check_binary(poly_plus, "plus", q, p, expected)
52
53p = x**2
54q = x
55expected = x**2 + x
56check_binary(poly_plus, "plus", p, q, expected)
57check_binary(poly_plus, "plus", q, p, expected)
58
59polypy_test.start("Negation")
60
61def poly_neg(p):
62    return -p
63
64p = x**2 + 2*x + 1
65expected = -x**2 -2*x - 1
66check_unary(poly_neg, "neg", p, expected)
67
68q = y**2 + 2*y + 1
69expected = -y**2 -2*y - 1
70check_unary(poly_neg, "neg", q, expected)
71
72polypy_test.start("Subtraction")
73
74def poly_sub(p, q):
75    return p - q
76
77p = x**2 + 2*x + 1
78q = y**2 + 2*y + 1
79expected = x**2 + 2*x - y**2 - 2*y
80check_binary(poly_sub, "sub", p, q, expected)
81
82polypy_test.start("Multiplication")
83
84def poly_mul(p, q):
85    return p*q
86
87p = 3*y + (-3*z)
88q = 1*y - 3
89expected = 3*y**2 + (-3*z - 9)*y + 9*z
90check_binary(poly_mul, "mul", p, q, expected)
91
92p = (1*y + (-1*z))*x**2 + (2*y + (-2*z))*x + (3*y + (-3*z))
93q = (1*y - 3)*x
94expected = (y**2 + (-z - 3)*y + 3*z)*x**3 + (2*y**2 + (-2*z - 6)*y + 6*z)*x**2 + (3*y**2 + (-3*z - 9)*y + 9*z)*x
95check_binary(poly_mul, "mul", p, q, expected)
96
97p = x + 1
98q = y + 1
99expected = x*y + x + y + 1
100check_binary(poly_mul, "mul", p, q, expected)
101
102expected = 3*x + 3
103check_binary(poly_mul, "mul", 3, p, expected)
104check_binary(poly_mul, "mul", p, 3, expected)
105
106expected = x*z + z
107check_binary(poly_mul, "mul", p, z, expected)
108
109expected = x*y*z + x*z + y*z + z;
110check_binary(poly_mul, "mul", (p*q), z, expected)
111
112p = (1*y - 3)*x**3 + (1*y - 2)*x**2 + (1*y - 1)*x + (1*y)
113q = 1*y + (-1*z)
114expected = (y**2 + (-z - 3)*y + 3*z)*x**3 + (y**2 + (-z - 2)*y + 2*z)*x**2 + (y**2 + (-z - 1)*y + z)*x + y**2 - z*y
115check_binary(poly_mul, "mul", p, q, expected)
116
117polypy_test.start("Power")
118
119def poly_pow(p, k):
120    return p**k
121
122p = (x + y)
123expected = x**2 + 2*x*y + y**2
124check_binary(poly_pow, "pow", p, 2, expected)
125
126expected = [1,
127            x + 1,
128            x**2 + 2*x + 1,
129            x**3 + 3*x**2 + 3*x + 1,
130            x**4 + 4*x**3 + 6*x**2 + 4*x + 1,
131            x**5 + 5*x**4 + 10*x**3 + 10*x**2 + 5*x + 1,
132            x**6 + 6*x**5 + 15*x**4 + 20*x**3 + 15*x**2 + 6*x + 1,
133            x**7 + 7*x**6 + 21*x**5 + 35*x**4 + 35*x**3 + 21*x**2 + 7*x + 1,
134            x**8 + 8*x**7 + 28*x**6 + 56*x**5 + 70*x**4 + 56*x**3 + 28*x**2 + 8*x + 1,
135            x**9 + 9*x**8 + 36*x**7 + 84*x**6 + 126*x**5 + 126*x**4 + 84*x**3 + 36*x**2 + 9*x + 1,
136            x**10 + 10*x**9 + 45*x**8 + 120*x**7 + 210*x**6 + 252*x**5 + 210*x**4 + 120*x**3 + 45*x**2 + 10*x + 1,
137            x**11 + 11*x**10 + 55*x**9 + 165*x**8 + 330*x**7 + 462*x**6 + 462*x**5 + 330*x**4 + 165*x**3 + 55*x**2 + 11*x + 1,
138            x**12 + 12*x**11 + 66*x**10 + 220*x**9 + 495*x**8 + 792*x**7 + 924*x**6 + 792*x**5 + 495*x**4 + 220*x**3 + 66*x**2 + 12*x + 1,
139            x**13 + 13*x**12 + 78*x**11 + 286*x**10 + 715*x**9 + 1287*x**8 + 1716*x**7 + 1716*x**6 + 1287*x**5 + 715*x**4 + 286*x**3 + 78*x**2 + 13*x + 1,
140            x**14 + 14*x**13 + 91*x**12 + 364*x**11 + 1001*x**10 + 2002*x**9 + 3003*x**8 + 3432*x**7 + 3003*x**6 + 2002*x**5 + 1001*x**4 + 364*x**3 + 91*x**2 + 14*x + 1,
141            x**15 + 15*x**14 + 105*x**13 + 455*x**12 + 1365*x**11 + 3003*x**10 + 5005*x**9 + 6435*x**8 + 6435*x**7 + 5005*x**6 + 3003*x**5 + 1365*x**4 + 455*x**3 + 105*x**2 + 15*x + 1]
142
143for k in range(0, 16):
144    check_binary(poly_pow, "pow", (x + 1), k, expected[k])
145
146polypy_test.start("Derivative");
147
148def poly_d(p):
149    return p.derivative()
150
151polypy.variable_order.set([z, y, x]);
152
153p = (x + y + z + 1)**3
154expected = 3*x**2 + 6*x*y + 3*y**2 + 6*x*z + 6*y*z + 3*z**2 + 6*x + 6*y + 6*z + 3
155check_unary(poly_d, "derivative", p, expected)
156
157polypy_test.start("Division")
158
159polypy.variable_order.set([z, y, x]);
160
161def poly_div(p, q):
162    return p / q
163
164def poly_rem(p, q):
165    return p % q
166
167p = 2*x + 2
168q = 2
169expected = x + 1
170check_binary(poly_div, "div", p, q, expected)
171
172p = x**2 - 1
173q = x - 1
174expected = x + 1
175check_binary(poly_div, "div", p, q, expected)
176
177p = x**2 - 1
178q = x - 1
179expected = 0
180check_binary(poly_rem, "rem", p, q, expected)
181
182p = (1*z**11 - 1*z**5)
183q = (z**5)
184expected = z**6 - 1
185check_binary(poly_div, "div", p, q, expected)
186
187p = x*y*z
188q = (x*y)
189expected = z
190check_binary(poly_div, "div", p, q, expected)
191
192p = 6*y*(x + 1)
193q = (2*y)
194expected = 3*(x + 1)
195check_binary(poly_div, "div", p, q, expected)
196
197p = 6*y*(x + 1)
198q = 3*(x+1)
199expected = 2*y
200check_binary(poly_div, "div", p, q, expected)
201
202q = x + 1
203expected = 6*y
204check_binary(poly_div, "div", p, q, expected)
205
206p = 2*x**2 + 4*x + 6
207q = 2
208expected = x**2 + 2*x + 3
209check_binary(poly_div, "div", p, q, expected)
210
211p = 2*x**2 + 4*x + 6
212q = (x + 2) - x
213expected = x**2 + 2*x + 3
214check_binary(poly_div, "div", p, q, expected)
215
216p = (x + 6) - x
217q = (x + 3) - x
218expected = 2
219check_binary(poly_div, "div", p, q, expected)
220