Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python API missing a cmasols.print() ? #146

Open
fl2o opened this issue Sep 23, 2016 · 5 comments
Open

Python API missing a cmasols.print() ? #146

fl2o opened this issue Sep 23, 2016 · 5 comments

Comments

@fl2o
Copy link

fl2o commented Sep 23, 2016

LINKED with #135 issue.

Hi @beniz,

I am working with python, using bounded parameters and linear scaling, however the best_candidate parameters are not rescaled with the lcmaes.get_candidate_x(bcand) and I can't find the 'cmasols.print()' function in the python API, neither use the genopheno object.

I struggle implementing it in the python/libcmaes.cc file.
Would be grateful for a code snippet or a merge :)
thanks in advance!

Florian

@beniz
Copy link
Collaborator

beniz commented Sep 23, 2016

Maybe sharing your code would help, first what you are trying to execute, in Python if that's what you are using, along with your attempt to add the print function to the Python bindings.

@fl2o
Copy link
Author

fl2o commented Sep 23, 2016

Here is the code I am running

    x = [2]*dimension #defaut param lies in [0,10]
    olambda = 50 # lambda is a reserved keyword in python, using olambda instead.
    success = 0
    seed = 0 # 0 for seed auto-generated within the lib.
    sigma = 0.01 #[0.001, 0.1]
    #lower_boundaries equals something like [0.756, 0.251, 0.686, ...]
    gp = lcmaes.make_genopheno_pwqb_ls(lower_boundaries.tolist(), upper_boundaries.tolist(), dimension)
    p = lcmaes.make_parameters_pwqb_ls(x, sigma, gp, olambda, seed)
    p.set_max_iter(1000)
    # objective function.
    p.set_str_algo('sepacmaes')
    # generate a function object
    objfunc = lcmaes.fitfunc_pbf.from_callable(pythonFunc);
    # pass the function and parameter to cmaes, run optimization and collect solution object.
    cmasols = lcmaes.pcmaes_pwqb_ls(objfunc,p)
    bcand = cmasols.best_candidate()
    bx = lcmaes.get_candidate_x(bcand)
    print "best value=", bcand.get_fvalue()
    print "best x=",bx

I am getting correct best fitness value but the parameters associated with it are not rescaled

this is the function i am trying to implement:

  template <class TGenoPheno>
  std::ostream& CMASolutions::print(std::ostream &out,
                    const int &verb_level,
const TGenoPheno &gp) const

I tried to implement it the naive way:

 class_<CMASolutions>("CMASolutions","Object for holding results and intermediate evolving solutions from a running optimizer")
    .def(init<Parameters<GenoPheno<NoBoundStrategy>>&>())
    ...
    ...
    ...
    .def("print", &CMASolutions::print, "rescale bcand parameters")

but I get an error

note : template argument deduction/substitution failed

when executing the make command line.

@beniz
Copy link
Collaborator

beniz commented Sep 23, 2016

OK thanks, I see. It's possible that the difficulty is a bit more global, and that access to the solution parameters in original (non distorted) space is not made available easily enough. I just took a quick look at it and can't seriously dig into this immediately.

@fl2o
Copy link
Author

fl2o commented Sep 23, 2016

Thank you for your quick answer!

Unfortunately, I don't have the skills to make the patch by myself...

Keep me updated when you have the solution or any alternative trick that I could use!
Have a good week-end.

@nikohansen
Copy link
Collaborator

One option is to do all transformations on the python side.

import numpy as np
class LinearScaling(object):
    """define a scaling of variables.

    Example:

    >>> fun = lambda x: sum(np.asarray(x)**2)
    >>> dim = 8
    >>> s = LinearScaling(range(1, dim + 1))
    >>> fun_scaled_in_fixed_dim = lambda x: fun(s(x))
    >>> print(s(dim * [1]))
    [1 2 3 4 5 6 7 8]

    """
    def __init__(self, scaling_factors):
        self.scaling = np.array(scaling_factors, copy=True)
    def __call__(self, x):
        return self.scaling * x
    def inverse(self, x):
        return self.scaling**-1 * x

For a transformation into boundaries you might consider cma.BoundTransform.repair. The cma package is available on The Python Package Index, using pip install cma.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants