summaryrefslogtreecommitdiff
path: root/diffeq.py
diff options
context:
space:
mode:
authorJoe Anderson <jandew+dev@gmail.com>2011-11-13 11:48:15 -0600
committerJoe Anderson <jandew+dev@gmail.com>2011-11-13 11:48:15 -0600
commitb756b1a28ba6686a0ed1fb9eeb366dee4b24e6dc (patch)
tree0a1c3706f3e62dea6aa7739ac00d642cb3a44cac /diffeq.py
parentba07fedc7d60fed2147e68a2c76ce69a62de9efd (diff)
downloadtoss-b756b1a28ba6686a0ed1fb9eeb366dee4b24e6dc.tar.gz
toss-b756b1a28ba6686a0ed1fb9eeb366dee4b24e6dc.zip
moved data output
Diffstat (limited to 'diffeq.py')
-rw-r--r--diffeq.py106
1 files changed, 106 insertions, 0 deletions
diff --git a/diffeq.py b/diffeq.py
new file mode 100644
index 0000000..1ecc705
--- /dev/null
+++ b/diffeq.py
@@ -0,0 +1,106 @@
+import time, types, itertools
+from scipy.interpolate import interp1d
+from scipy.integrate import odeint
+from scipy.optimize import fmin
+
+class DiffEq(object):
+ """designed to make numerically solving diff eqs more readable
+
+ setattr and getattr have been modified to provide the following effects:
+ >>> self._foo=2 #setting an _under var makes it still callable by...
+ >>> self.foo
+ 2
+
+ >>> # Now suppose foo is a class method and bar is in _flags.
+ >>> self.foo #finding the object having not found it before
+ #self.foo() is called and stored to self.__foo
+ #self.__foo is returned
+
+ >>> self.foo #finding the object having asked for it before
+ #self.__foo is returned
+
+ >>> self.bar=2 #setting bar resets all self.__foos
+
+ >>> self.foo #self.foo() is called again, self.__foo returned
+
+ Note that with this behavior you should treat all variable names, be they
+ normal, _under, or __dunder, as in the same namespace. Don't even try to
+ differentiate variable names by underscores.
+
+ The benefit of this system is that every normal float will be optimized,
+ while every _under float will be ignored completely, and flagging a var
+ with _under will not change the behavior of any functions using it.
+ Additionally, if you suddenly realize that foo should be dependent on
+ bar and baz, you simply define:
+ def foo(self):
+ return do_stuff(self.bar, self.baz)
+ and bar and baz will be optimized while foo will be ignored -- and no
+ function code using foo needs to be rewritten.
+ """
+ def __init__(self):
+ self._time = time.time()
+
+ # All floats lacking an initial _underscore will be optimized.
+ self.opt_vars = {}
+ for key, value in vars(self).items():
+ if key[0] == "_": continue
+ if type(value) != float: continue
+ self.opt_vars[key] = value
+ def time(self): return time.time() - self.time
+
+ def __getattribute__(self, attr):
+ """Provides a few getattr psuedonyms:
+
+ allows self.foo to return:
+ self._foo if self.foo DNE
+ self.foo() if self.foo is a method
+ (be very wary of storing variables under these conditions!)
+ """
+ sgetattr = super(DiffEq, self).__getattribute__
+ try:
+ value = sgetattr(attr)
+ if type(value) == types.MethodType:
+ try: value = sgetattr("__" + attr)
+ except AttributeError:
+ value = value()
+ setattr(self, "__" + attr, value)
+ except AttributeError as err:
+ if attr[0] == "_": raise err
+ else: value = sgetattr("_" + attr)
+ return value
+
+ _flags = []
+ def __setattribute__(self, attr):
+ """Clears dunder updates when phi or phi1 are changed."""
+ sgetattr = super(DiffEq, self).__getattribute__
+ ssetattr = super(DiffEq, self).__setattribute__
+ if attr in self.flags:
+ for key, value in vars(self).items():
+ if key[:2] != "__": continue
+ if type(sgetattr(key[2:])) != types.MethodType: continue
+ vars(self).remove(key)
+ ssetattr(attr)
+
+ def check_in(self, variables):
+ """Usage is as follows.
+
+ def method(self, var0=None, var1=None, ...):
+ self.check_in(vars())
+ return do_stuff_with_vars()
+ """
+ for key, var in variables.items():
+ if var == None:
+ variables[key] = getattr(self, key)
+
+ def solve_fun(self, func=None, init_vars=None, timespace=None):
+ """wrapper for odeint"""
+ check_in(vars())
+ time0 = current_time()
+ time = numpy.linspace(*timespace)
+ soln = odeint(func, init_vars, time)
+ print " :: took %s seconds" % (current_time() - time0)
+ return time, soln
+
+ #in optimize(): vars().update(self.opt_vars)
+
+