Repository: facebookresearch/nevergrad

Issue:
Suggesting a point breaks when one of the parameters is a constant numpy array
## Steps to reproduce
```
import nevergrad as ng
import numpy as np


constant_param = np.zeros(3, dtype=int)
param = ng.p.Instrumentation(ng.p.Choice(["a", "b", "c"]), constant_param)
optim = ng.optimizers.OnePlusOne(parametrization=param, budget=100)
optim.suggest("c", constant_param)
```


## Observed Results

Traceback (most recent call last):
  in <module>
    optim.suggest("c", constant_param)
  File "C:\Program Files\Python37\lib\site-packages\nevergrad\optimization\base.py", line 219, in suggest
    self._suggestions.append(self.parametrization.spawn_child(new_value=new_value))
  File "C:\Program Files\Python37\lib\site-packages\nevergrad\parametrization\core.py", line 332, in spawn_child
    child.value = new_value
  File "C:\Program Files\Python37\lib\site-packages\nevergrad\parametrization\container.py", line 52, in value
    core.as_parameter(self[k]).value = val
  File "C:\Program Files\Python37\lib\site-packages\nevergrad\parametrization\container.py", line 52, in value
    core.as_parameter(self[k]).value = val
  File "C:\Program Files\Python37\lib\site-packages\nevergrad\parametrization\core.py", line 405, in value
    if not (value == self._value or value is self._value):
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

## Expected Results

I did not expect the insertion of a constant numpy array (i.e., constant_param) to throw an exception.

## Relevant Code
I believe the problem lies in line 405 of file *nevergrad\parametrization\core.py*, which currently looks like this:
  ```
  if not (value == self._value or value is self._value):
  ```

The equality only works for basic types, but throws an exception if value is a numpy ndarray.



<!--- In any case, don't hesitate to join and ask questions if you need on Nevergrad users Facebook group https://www.facebook.com/groups/nevergradusers/ -->



Discussion:
Hi,
Thanks for the bug report. I thought this had already beenn solved but I was obviously wrong :s I'll try a fix asap (a bit busy these days, if you want to give it a try, you're welcome to it ;) I think you pinned down the correct line)


Resolving patch:
diff --git a/nevergrad/parametrization/core.py b/nevergrad/parametrization/core.py
--- a/nevergrad/parametrization/core.py
+++ b/nevergrad/parametrization/core.py
@@ -402,7 +402,13 @@ def value(self) -> tp.Any:
 
     @value.setter
     def value(self, value: tp.Any) -> None:
-        if not (value == self._value or value is self._value):
+        different = False
+        if isinstance(value, np.ndarray):
+            if not np.equal(value, self._value).all():
+                different = True
+        elif not (value == self._value or value is self._value):
+            different = True
+        if different:
             raise ValueError(f'Constant value can only be updated to the same value (in this case "{self._value}")')
 
     def get_standardized_data(self: P, *, reference: tp.Optional[P] = None) -> np.ndarray:  # pylint: disable=unused-argument


Test patch:
diff --git a/nevergrad/parametrization/test_parameter.py b/nevergrad/parametrization/test_parameter.py
--- a/nevergrad/parametrization/test_parameter.py
+++ b/nevergrad/parametrization/test_parameter.py
@@ -53,6 +53,7 @@ def _true(*args: tp.Any, **kwargs: tp.Any) -> bool:  # pylint: disable=unused-ar
                                    par.Scalar(),
                                    par.Scalar(1.0).set_mutation(exponent=2.),
                                    par.Dict(blublu=par.Array(shape=(2, 3)), truc=12),
+                                   par.Dict(scalar=par.Scalar(), const_array=np.array([12.0, 12.0]), const_list=[3, 3]),
                                    par.Tuple(par.Array(shape=(2, 3)), 12),
                                    par.Instrumentation(par.Array(shape=(2,)), nonhash=[1, 2], truc=par.Array(shape=(1, 3))),
                                    par.Choice([par.Array(shape=(2,)), "blublu"]),