Announcing Tengolo, an open-source library for agent-based modeling in python and matplotlib! Tengolo is open source, and currently hosted at github. Preliminary documentation is here.
Tengolo is designed to allow users to
- Quickly express their ideas in code,
- Get immediate feedback from the python shell, matplotlib GUI, and logs, AND
- Scale up the scope of their experiments with batches for repeated trials, parameter sweeps, etc.
For the most part, the advantages of Tengolo are the advantages of python and matplotlib:
- Clean, object-oriented code for
- Quick learning
- Rapid prototyping
- Easy debugging
- Great maintainability
- An enormous codebase of snippets and outside libraries.
- An active and supportive user community
- Powerful, professional graphs and plots with a minimum of hassle
- An intuitive GUI that lets you interact with your model in real time
Development so far
I've just begun development -- about 8 hours of work -- but the advantages are already starting to show. As a proof of concept, here's a screen shot and the script for a model I'm building in Tengolo. All told, the script is only 80 lines long, and does not contain a single turtle.
#!/usr/bin/python """ P-A model simulator for mixed motives paper Abe Gong - Feb 2102 """ import numpy import scipy.optimize from tengolo.core import TengoloModel, TengoloView from tengolo.widgets import contour, slider class M4Model(TengoloModel): def __init__(self): self.beta = .5 self.x_bar = 2 self.a = 0 self.b = 1 self.alpha = .5 self.c = .1 delta = 0.025 self.v = numpy.arange(0.025, 10, delta) self.w = numpy.arange(0.025, 10, delta) self.V, self.W = numpy.meshgrid(self.v,self.w) self.update() def update(self): self.U = self.calc_utility( self.V, self.W, self.linear_rate ) (self.v_star, self.w_star) = self.calc_optimal_workload( self.linear_rate ) (self.v_bar, self.w_bar) = self.calc_optimal_workload( self.flat_rate ) print (self.v_star, self.w_star) def calc_utility(self, v, w, x_func): z = (v**(self.beta))*(w**(1-self.beta)) x = x_func(z) u = self.alpha*numpy.log(v) + (1-self.alpha)*numpy.log(x) - self.c*(w+v) return u def calc_optimal_workload(self, x_func): # return scipy.optimize.fmin( lambda args : -1*self.calc_utility( args[0], args[1], x_func ), [2,2], disp=False ) result = scipy.optimize.fmin_tnc( lambda args : -1*self.calc_utility( args[0], args[1], x_func ), [2,2], bounds = [(0,None),(0,None)], approx_grad=True, disp=False, ) return result[0] def flat_rate(self, z): return self.x_bar def linear_rate(self, z): return self.x_bar + self.a + self.b*z #Initialize model my_model = M4Model() #Initialize viewer my_view = TengoloView(my_model) #Attach controls and observers my_view.add_observer( contour, [0.15, 0.30, 0.70, 0.60], args={ "title":"Utility isoquants", "xlabel":"v (hrs)", "ylabel":"w (hrs)", "x":"V", "y":"W", "z":"U", }) my_view.add_control( slider, "alpha", [0.15, 0.15, 0.70, 0.03], args={"range_min":0, "range_max":1} ) my_view.add_control( slider, "beta", [0.15, 0.10, 0.70, 0.03], args={"range_min":0, "range_max":1} ) #Render the view my_view.render()
This particular model is game-theoretic, not agent-based, but the process of model design is essentially the same. I want to be able to build and edit the model, and get results as quickly as possible. The process should be creative, not bogged down with debugging. Along the way, I need to experiment with model parameters, and quickly see their impact on the behavior of the system as a whole.
As I said earlier, I've only just started down this road, but there's no turning back. If you have a model you'd like to port to Tenlogo, let me know. Cheers!
Thanks for doing this!
ReplyDeleteHi,
ReplyDeleteI was thinking... since NetLogo is written in Java, instead of rewriting all this in Python, why not do it in Jython? This way you can access all the NetLogo .java classes directly.
Then you just need to superimpose a JTextBox (or similar) on top of the NetLogo editor window, and be done.
(Or, you could capture the Jython code (or any code, for that matter) from the JTextBox superimposed window, map it (through a Lex/Yacc module) to the NetLogo language, and paste it to the underlying (hidden) editor window.)
Some thoughts to save you re-implementing the whole NetLogo system in CPython.
I agree - thank you for thinking/doing this.