Buckets:
| import numpy as np | |
| class Parameters(object): | |
| def __init__(self): | |
| """ | |
| Subclasses must initialize self.prm with | |
| parameters and default values, self.type with | |
| the corresponding types, and self.help with | |
| the corresponding descriptions of parameters. | |
| self.type and self.help are optional, but | |
| self.prms must be complete and contain all parameters. | |
| """ | |
| pass | |
| def ok(self): | |
| """Check if attr. prm, type, and help are defined.""" | |
| if hasattr(self, 'prm') and \ | |
| isinstance(self.prm, dict) and \ | |
| hasattr(self, 'type') and \ | |
| isinstance(self.type, dict) and \ | |
| hasattr(self, 'help') and \ | |
| isinstance(self.help, dict): | |
| return True | |
| else: | |
| raise ValueError( | |
| 'The constructor in class %s does not '\ | |
| 'initialize the\ndictionaries '\ | |
| 'self.prm, self.type, self.help!' % | |
| self.__class__.__name__) | |
| def _illegal_parameter(self, name): | |
| """Raise exception about illegal parameter name.""" | |
| raise ValueError( | |
| 'parameter "%s" is not registered.\nLegal '\ | |
| 'parameters are\n%s' % | |
| (name, ' '.join(list(self.prm.keys())))) | |
| def set(self, **parameters): | |
| """Set one or more parameters.""" | |
| for name in parameters: | |
| if name in self.prm: | |
| self.prm[name] = parameters[name] | |
| else: | |
| self._illegal_parameter(name) | |
| def get(self, name): | |
| """Get one or more parameter values.""" | |
| if isinstance(name, (list,tuple)): # get many? | |
| for n in name: | |
| if n not in self.prm: | |
| self._illegal_parameter(name) | |
| return [self.prm[n] for n in name] | |
| else: | |
| if name not in self.prm: | |
| self._illegal_parameter(name) | |
| return self.prm[name] | |
| def __getitem__(self, name): | |
| """Allow obj[name] indexing to look up a parameter.""" | |
| return self.get(name) | |
| def __setitem__(self, name, value): | |
| """Allow obj[name] = valye syntax to assign a parameter's value.""" | |
| return self.set(name=value) | |
| def define_command_line_options(self, parser=None): | |
| self.ok() | |
| if parser is None: | |
| import argparse | |
| parser = argparse.ArgumentParser() | |
| for name in self.prm: | |
| tp = self.type[name] if name in self.type else str | |
| help = self.help[name] if name in self.help else None | |
| parser.add_argument( | |
| '--' + name, default=self.get(name), metavar=name, | |
| type=tp, help=help) | |
| return parser | |
| def init_from_command_line(self, args): | |
| for name in self.prm: | |
| self.prm[name] = getattr(args, name) | |
| class Problem(Parameters): | |
| """ | |
| Physical parameters for the problem u'=-a*u, u(0)=I, | |
| with t in [0,T]. | |
| """ | |
| def __init__(self): | |
| self.prm = dict(I=1, a=1, T=10) | |
| self.type = dict(I=float, a=float, T=float) | |
| self.help = dict(I='initial condition, u(0)', | |
| a='coefficient in ODE', | |
| T='end time of simulation') | |
| def u_exact(self, t): | |
| I, a = self['I a'.split()] | |
| return I*np.exp(-a*t) | |
| class Solver(Parameters): | |
| """ | |
| Numerical parameters and algorithm for solving u'=-au by the | |
| theta rule. | |
| """ | |
| def __init__(self, problem): | |
| self.problem = problem | |
| self.prm = dict(dt=0.5, theta=0.5) | |
| self.type = dict(dt=float, theta=float) | |
| self.help = dict(dt='time step value', | |
| theta='time discretization parameter') | |
| def solve(self): | |
| from decay import solver | |
| I, a, T = self.problem['I a T'.split()] | |
| dt, theta = self['dt theta'.split()] | |
| self.u, self.t = solver(I, a, T, dt, theta) | |
| def error(self): | |
| try: | |
| u_e = self.problem.u_exact(self.t) | |
| e = u_e - self.u | |
| E = np.sqrt(self.get('dt')*np.sum(e**2)) | |
| except AttributeError: | |
| E = None | |
| return E | |
| def experiment_classes(): | |
| problem = Problem() | |
| solver = Solver(problem) | |
| # Read input from the command line | |
| parser = problem.define_command_line_options() | |
| parser = solver. define_command_line_options(parser) | |
| args = parser.parse_args() | |
| problem.init_from_command_line(args) | |
| solver. init_from_command_line(args) | |
| # Solve and plot | |
| solver.solve() | |
| u, t = solver.u, solver.t | |
| print 'Error norm:', solver.error() | |
| import matplotlib.pyplot as plt | |
| t_e = np.linspace(0, problem['T'], 1001) # very fine mesh for u_e | |
| u_e = problem.u_exact(t_e) | |
| plt.plot(t, u, 'r--o') # dashed red line with circles | |
| plt.plot(t_e, u_e, 'b-') # blue line for u_e | |
| plt.legend(['numerical, theta=%g' % solver['theta'], 'exact']) | |
| plt.xlabel('t') | |
| plt.ylabel('u') | |
| plotfile = 'tmp' | |
| plt.savefig(plotfile + '.png'); plt.savefig(plotfile + '.pdf') | |
| plt.show() | |
| if __name__ == '__main__': | |
| experiment_classes() | |
Xet Storage Details
- Size:
- 5.17 kB
- Xet hash:
- 6a77d1d480d131df9821faefa59a4a601c7c9b1ef9fc407323d3879a0f4c65a4
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.