On Thursday 07 May 2009 23:16:54 Anders Logg wrote:
On Thu, May 07, 2009 at 11:05:49PM +0200, Johan Hake wrote:
On Thursday 07 May 2009 18:54:04 Anders Logg wrote:
I've added some of the requested features to the parameter system,
some pushed and some sitting here in a local repository. But the
current design makes it a pain to add new features. A single change
will make it necessary to add a function in at least 5 different
classes.
So I'm thinking of reimplementing and simplifying the parameter
system. I think I know how to make it simpler.
But before I do that, does anyone have opinions on the
design/implementation? Is there any third-party library that we
could/should use (maybe something in boost)?
It would be nice to have something that easely could be transferable
to Python.
Having a base class let say Parameterized and then let all inherit
this to be able to define parameters will not work well for the
shared_ptr interface we have. We have problems with the Variable
class, which does not work for the derived shared_ptr classes e.g.
Function. I would rather have classes that have a parameter rather
than beeing.
How would that work? Inheritance now provides get/set functions for
subclasses making it possible to do
solver.set("tolerance", 0.1);
Not sure what you ask for here. I know of Parametrized and I agree that
the above syntax is nice. But I prefer to keep the parameters in its own
object and just operate on that. These can then be collected into one
"dict/map" and then form the parameters of an application. This is also
easier to wrap to python.
The shared_ptr argument might not be so relevant as the potential
parametrized classes may not be declared as shared_ptr classes in the
swig interface anyway. However if that will be the case we must declare
Parametrized as a shared_ptr class in swig and then we must declare all
Parametrized sub classes as shared_ptr...
Also by defining a parameter(list/dict) class which can be accessed as
a dict let us make the transition to python smoother.
ParameterDict p = solver.default_params();
p["abs_tol"] = 1e-9;
It would need to be
ParameterDict& p = solver.default_params();
Sure :P
and I'd suggest naming it Parameters:
Parameters& p = solver.parameters();
Fine.
By defining some templated check classes we could controll the
assignment. In the Solver:
...
ParameterDict& default_params(){
if (!_par)
{
_par = new ParameterDict();
_par->add_param("abs_tol",new RangeCheck<double>(1e-15,0,1));
vector<string> * allowed_prec = new Vector<string>();
allowed_prec->push_back("ilu");
allowed_prec->push_back("amg");
allowed_prec->push_back("jacobi");
_par->add_param("prec",new
OptionCheck<string>("ilu"),allowed_prec));
_par->add_param("nonsense","jada"); // No checks
}
}
Well, I admit that the above code is not beautiful, and others can
probably make it cleaner and spot errors. The point is that RangeCheck
and OptionCheck can be derived from a ParCheck class that overloads
the operator=(). This will just call a private set function which is
defined in the derived classes, and which do the check.
I think we can also solve this without excessive templating... ;-)
Good!
The to and from file can be implemented in the ParameterDict body. The
checks do not have to be written or read, as a ParameterDict can only
read in allready predefined parameters, and the check will be done
when the file is read.
The option parser ability can also be implemented in ParameterDict
using boost or other libraries, based on the registered parameters.
I have implemented something like this in Python, and the above is a
try to scetch something similare in c++.
What exactly is needed from the Python side? I think I can make a
fairly simple implementation of this in C++ using a minimal amount of
templates with simple syntax.
Using operator[] to get and set parameters can straightforwardly be
mapped to python, and we can then also implement the map/dict protocol
on top of that. Other get and set methods can also be used, however set
is a built in type in Python and not a good alternative.
Is the main difference that instead of inheriting Parametrized, a
subclass needs to implement a method named parameters() which returns
the parameter "dictionary"?
Yes.