1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
from JXGServerModule import JXGServerModule
import JXG
import numpy
import os
# Should be changed to something more persistent but must be writable by
# the webserver (usually user www-data)
if not 'MPLCONFIGDIR' in os.environ:
os.environ['MPLCONFIGDIR'] = '/tmp/'
# os.environ['MPLCONFIGDIR'] = 'C:/xampp/tmp'
import matplotlib
matplotlib.use('Agg')
from matplotlib.pyplot import *
from matplotlib.contour import *
import subprocess
import signal
import time
import re
import zlib
import base64
import cStringIO
import cgi
import math
class JXGGeoLociModule(JXGServerModule):
def __init__(self):
############################
#
# Config lines
#
############################
# Command to start cocoa
self.cmd_cocoa = "/share8/opt/cocoa/cocoa"
# If you're using Windows
#cmd_cocoa = r"C:\cocoa\cocoa.bat"
# Shouldn't be changed, except you know what you're doing
self.debug = False
############################
self.debugOutput = cStringIO.StringIO()
JXGServerModule.__init__(self)
return
def init(self, resp):
resp.addHandler(self.lociCoCoA, 'function(data) { }')
return
def lociCoCoA(self, resp, xs, xe, ys, ye, number, polys, sf, rot, transx, transy):
self.output = ''
self.cococa_process = None
cinput = ""
c = math.cos(rot)
s = math.sin(rot)
tx = 0;
# Variable code begins here
# Here indeterminates of polynomial ring have to be adjusted
if number > 0:
cinput += "Use R ::= QQ[u[1..%s],x,y], Xel;" % number
else:
cinput += "Use R ::= QQ[x,y];"
# Of course the polynomials generating the ideal must be adjusted
cinput += "I := Ideal(%s);" % polys
# So have to be the indeterminates to be eliminated
if number > 0:
cinput += "J := Elim(u[1]..u[%s], I); J;" % number
else:
cinput += "J := I; J;"
# and ends here
# Fixed code which hasn't to be adjusted on each run of this script
cinput += "G := ReducedGBasis(J);"
cinput += "Print \"resultsbegin\", NewLine;"
cinput += "For N := 1 To Len(G) Do\n"
cinput += " B := Factor(G[N]);\n"
cinput += " For M := 1 To Len(B) Do\n"
cinput += " StarPrintFold(B[M][1], -1);"
cinput += " Print NewLine;"
cinput += " EndFor;\n"
cinput += "EndFor;\n"
cinput += "Print \"resultsend\", NewLine;"
#cinput = "Ciao;"
if self.debug:
print >>self.debugOutput, "Starting CoCoA with input<br />"
print >>self.debugOutput, cinput + '<br />'
# The suicide pill for the CoCoA process:
# If not done within the following amount
# of seconds, the subprocess will be terminated
time_left = 30
class TimeoutException(Exception): pass
def time_limit(seconds):
def signal_handler(signum, frame):
raise Exception(TimeoutException, "Timed out!")
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(seconds)
#global cocoa_process
#global output
def callCoCoA():
# Global variables aren't that nice, but this time they're useful
#global cocoa_process, output
self.cocoa_process = subprocess.Popen([self.cmd_cocoa], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
self.output = self.cocoa_process.communicate(cinput)[0]
calc_time = time.time()
try:
time_limit(time_left)
callCoCoA()
except TimeoutException as msg:
# This is only tested with linux/unix
# and works ONLY if the cocoa script cd-ing
# to the cocoa dir and starting cocoa executes
# it with
# $ exec ./cocoa_text
# This is NOT YET TESTED WITH WINDOWS! (though
# sharing tests would be nice).
self.cocoa_process.kill()
if self.debug:
print >>self.debugOutput, "Timed out!"
resp.error("Timeout, maybe the system of polynomial is too big or there's an error in it.")
return
calc_time = time.time() - calc_time
resp.addData('exectime', calc_time)
if self.debug:
print >>self.debugOutput, "Reading and Parsing CoCoA output" + '<br />'
print >>self.debugOutput, self.output + '<br />'
# Extract results
if re.search('resultsbegin', self.output) is None:
return
result = re.split('resultsend', re.split('resultsbegin', self.output)[1])[0]
result = re.split('-------------------------------', re.split('-------------------------------', result)[1])[0]
result = result.replace("^", "**")
result = result.replace("\r", "")
polynomials = re.split('\n', result)
if self.debug:
print >>self.debugOutput, "Found the following polynomials:" + '<br />'
for i in range(0,len(polynomials)):
print >>self.debugOutput, "Polynomial ", i+1, ": " + polynomials[i] + '<br />'
datax = []
datay = []
polynomialsReturn = []
for i in range(0,len(polynomials)):
if len(polynomials[i]) == 0:
continue
if ((not "x" in polynomials[i]) and (not "y" in polynomials[i])) or ("W" in polynomials[i]):
continue
polynomialsReturn.append(polynomials[i])
x, y = numpy.meshgrid(numpy.linspace(xs, xe, 500), numpy.linspace(ys, ye, 500))
z = eval(polynomials[i])
C = contour(x, y, z, [0])
if self.debug:
savefig('/tmp/test%s.png' % i)
for i in range(0, len(C.collections[0].get_paths())):
pa = C.collections[0].get_paths()[i].to_polygons()[0]
for i in range(0,len(pa)):
tx = pa[i, 0]
pa[i, 0] = c*pa[i,0] - s*pa[i,1]
pa[i, 1] = s*tx + c*pa[i,1]
datax.append(sf*pa[i,0] + transx)
datay.append(sf*pa[i,1] + transy)
datax.append('null')
datay.append('null')
resp.addData('datax', datax)
resp.addData('datay', datay)
resp.addData('polynomial', polynomialsReturn)
if self.debug:
print (", ".join(map(str, datax)) + '<br />', file=self.debugOutput)
print (", ".join(map(str, datay)) + '<br />', file=self.debugOutput)
print ("Content-Type: text/plain\n\n")
print()
print()
print (self.debugOutput.getvalue())
self.debugOutput.close()
return
|