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 io 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 = io.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("Starting CoCoA with input
", file=self.debugOutput) print(cinput + '
', file=self.debugOutput) # 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 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("Timed out!", file=self.debugOutput) 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("Reading and Parsing CoCoA output" + '
', file=self.debugOutput) print(self.output + '
', file=self.debugOutput) # 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("Found the following polynomials:" + '
', file=self.debugOutput) for i in range(0,len(polynomials)): print("Polynomial ", i+1, ": " + polynomials[i] + '
', file=self.debugOutput) 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)) + '
', file=self.debugOutput) print(", ".join(map(str, datay)) + '
', file=self.debugOutput) print("Content-Type: text/plain\n\n") print() print() print(self.debugOutput.getvalue()) self.debugOutput.close() return