dimanche 3 mai 2015

Design heuristics for writing Python classes that interact with `scipy.integrate.odeint`?

Introduction

scipy.integrate.odeint requires as its first argument, a function that computes the derivatives of the variables we want to integrate over (which I'll refer to as d_func, for "derivative function" from now on).

d_func has to be written by the user, in Python code. A great way to get a boost of performance using Numba is to @jit the d_func (because d_func is called many times during integration).

I have questions about how to write performant code when d_func is complicated enough that it needs a Python class object behind it.

Code setup

Here is a "cartoon" of my code:

  • there is a module called DynamicBox.py
  • inside this module is a Python class, DynamicBox
  • DynamicBox has a bunch of attributes
  • some of these attributes are "phase variables" -- that is, they are the quantities I am interested in integrating
  • some of these attributes are "parameters" -- that is, I use them to calculate the derivatives of the phase variables

I will have a bunch of functions that will take DynamixBox phase variable or parameter attributes, in order to calculate relevant terms in the derivatives. That is:

  • I will have a d_func
  • d_func itself will call lots of little helper functions to calculate relevant terms in the derivative, using DynamixBox attributes

Design choices

I have to make a choice, with the following options:

  1. either I can make d_func and all its helper functions methods of DynamicBox;
  2. or I can make only d_func a method of DynamicBox, and all of its helper functions are in the same module as DynamicBox, but not methods of DynamicBox;
  3. or only the helper functions are methods of DynamicBox, but d_func is just in the same module (DynamicBox.py), and not a method of DynamicBox;
  4. or neither the helper functions, nor d_func, are methods of DynamicBox.

Question

I do not know enough about Python to figure out which choice is best. The following questions I think would need answering.

  • Is it expensive to make instance attribute calls to get attributes or is it expensive only if you are in a function that is not a method of the class?

  • What if Numba is in play? For instance, will Numba like it better if I am @jit-ting normal functions instead of class methods?

Aucun commentaire:

Enregistrer un commentaire