Skip to content

Commit aad7439

Browse files
committed
...
1 parent 6ac07fb commit aad7439

File tree

2 files changed

+51
-70
lines changed

2 files changed

+51
-70
lines changed

examples/cad/cad.py

+40-55
Original file line numberDiff line numberDiff line change
@@ -41,53 +41,38 @@ def cylinder_notify(self, cylinder, assignment):
4141
print "Cylinder:\n", cylinder
4242
pass
4343

44+
45+
# Get all the reductums (including the polynomial itself), but not the constant
46+
def get_reductums(f, x):
47+
R = []
48+
while f.var() == x:
49+
R.append(f)
50+
f = f.reductum()
51+
return R
52+
53+
# Polynomials with sign conditions are considered a conjunction
54+
CONJUNCTIVE = 0
55+
# Polynomials with sign conditions are considered a disjunction
56+
DISJUNCTIVE = 1
4457

4558
# Do cylindrical algebraic decomposition (CAD)
4659
class CAD:
47-
48-
# Map from variables to polynomials
49-
projection_map = {}
50-
51-
# Signs of relevant polynomials, mapping top variables to polynomials (for lifting)
52-
sign_condition_map = {}
53-
54-
# Set of variables we're working with
55-
variables = []
56-
57-
# Notification
58-
cylinder_notify = CylinderNotify()
59-
60-
# Polynomials with sign conditions are considered a conjunction
61-
CONJUCTIVE = 0
62-
# Polynomials with sign conditions are considered a disjunction
63-
DISJUNCTIVE = 1
64-
65-
# Type of CAD
66-
type = CONJUCTIVE
67-
60+
6861
# Initialize
69-
def __init__(self, variable_list):
70-
# Set the variable order
71-
polypy.variable_order.set(variable_list)
72-
# Map from variables to sets of polynomials
62+
def __init__(self, variable_list, type = CONJUNCTIVE):
63+
# Init variables
7364
self.projection_map = {}
7465
self.sign_condition_map = {}
66+
self.variables = variable_list
67+
self.cylinder_notify = CylinderNotify()
68+
self.type = type
69+
# Initialize the maps
7570
for x in variable_list:
7671
self.projection_map[x] = set()
7772
self.sign_condition_map[x] = set()
78-
79-
# Variables
80-
self.variables = variable_list
81-
82-
# Get all the reductums (including the polynomial itself), but not the constant
83-
@staticmethod
84-
def get_reductums(f, x):
85-
R = []
86-
while f.var() == x:
87-
R.append(f)
88-
f = f.reductum()
89-
return R
90-
73+
# Set the variable order
74+
polypy.variable_order.set(variable_list)
75+
9176
# Add a polynomial to CAD
9277
def add_polynomial(self, f, sign_condition = None):
9378
# Factor the polynomial
@@ -104,7 +89,7 @@ def add_polynomial(self, f, sign_condition = None):
10489

10590
# Check if the assignment respects the polynomials with top variable x
10691
def check_assignment(self, x, assignment):
107-
if self.type == CAD.CONJUCTIVE:
92+
if self.type == CONJUNCTIVE:
10893
for p, sgn_condition in self.sign_condition_map[x]:
10994
if not p.sgn_check(assignment, sgn_condition):
11095
return False
@@ -121,29 +106,26 @@ def add_polynomials(self, polynomials):
121106
self.add_polynomial(f)
122107

123108
# Project. Go down the variable stack and project:
124-
# [1] coeff(f) for f in poly[x]
125-
# [2] psc(g, g') for f in poly[x], g in R(f, x)
126-
# [3] psc(g1, g2) for f1, f2 in poly[x], g1 in R(f1, x), g2 in R(f2, x)
127109
def project(self):
128110
for x in reversed(self.variables):
129111
# Project variable x
130112
x_poly_set = self.projection_map[x]
131113
# [1] coeff(f) for f in poly[x]
132-
for f in self.projection_map[x]:
114+
for f in x_poly_set:
133115
self.add_polynomials(f.coefficients())
134116
# [2] psc(g, g') for f in poly[x], g in R(f, x)
135-
for f in self.projection_map[x]:
136-
for g in CAD.get_reductums(f, x):
117+
for f in x_poly_set:
118+
for g in get_reductums(f, x):
137119
g_d = f.derivative()
138120
if (g_d.var() == x):
139121
self.add_polynomials(g.psc(g_d))
140122
# [3] psc(g1, g2) for f1, f2 in poly[x], g1 in R(f1, x), g2 in R(f2, x)
141-
for (f1, f2) in itertools.combinations(self.projection_map[x], 2):
142-
f1_R = CAD.get_reductums(f1, x)
143-
f2_R = CAD.get_reductums(f2, x)
123+
for (f1, f2) in itertools.combinations(x_poly_set, 2):
124+
f1_R = get_reductums(f1, x)
125+
f2_R = get_reductums(f2, x)
144126
for (g1, g2) in itertools.product(f1_R, f2_R):
145-
self.add_polynomials(g1.psc(g2))
146-
127+
self.add_polynomial(g1.psc(g2))
128+
147129
# Lift the first variable, update the assignment and lift recursively
148130
def lift_first_var(self, variables, assignment, cylinder):
149131
# We've tried all variables, this assignment checks out
@@ -190,7 +172,12 @@ def lift(self):
190172
assignment = polypy.Assignment()
191173
cylinder = Cylinder()
192174
self.lift_first_var(self.variables, assignment, cylinder)
193-
175+
176+
# Run the CAD construction
177+
def run(self):
178+
self.project()
179+
self.lift()
180+
194181
# Print internal state
195182
def print_state(self):
196183
print "Variables:", self.variables
@@ -208,7 +195,5 @@ def print_state(self):
208195
# Setup CAD
209196
cad = CAD([x, y])
210197
cad.add_polynomial(x**2 + y**2 - 1, polypy.SGN_GE_0)
211-
# Project
212-
cad.project()
213-
# Lift
214-
cad.lift()
198+
# Run CAD
199+
cad.run()

examples/cad/plot.py

+11-15
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,33 @@
66
import matplotlib.pyplot as plt
77

88
# 2D plotting of polynomials
9-
class PolyPlot2D(CylinderNotify):
10-
11-
# The variables
12-
x = None
13-
y = None
14-
15-
# List of polynomials with sign conditions
16-
polynomials = None
17-
9+
class PolyPlot2D(cad.CylinderNotify):
10+
1811
# Initialize
1912
def __init__(self, x, y):
2013
self.x = x
2114
self.y = y
2215
self.cad = cad.CAD([x, y])
2316
self.polynomials = []
17+
self.cylinders = []
2418

2519
# Add a polynomial
2620
def add_polynomial(self, f, sign_condition):
2721
self.polynomials.append((f, sign_condition))
28-
self.cad.add_polynomial(f, sign_condition)
2922

3023
# Show the plot
3124
def show(self):
32-
# Do CAD
25+
# Run the CAD and collect cyllinders
3326
mycad = cad.CAD([x, y])
34-
mycad.project()
35-
mycad.lift()
27+
mycad.cylinder_notify = self
28+
for (f, sign_condition) in self.polynomials:
29+
mycad.add_polynomial(f, sign_condition)
30+
mycad.run()
3631

3732
# Notifications on sylinders
38-
def cylinder_notify(self, cylinder):
39-
pass
33+
def cylinder_notify(self, cylinder, assignment):
34+
self.cylinders.append(cylinder)
35+
print "Cylinder:\n", cylinder
4036

4137
if __name__ == "__main__":
4238
# Some variables

0 commit comments

Comments
 (0)