Repository: facebookresearch/nevergrad

Issue:
How to use `Scalar` as an int?
According to the [documentation](https://facebookresearch.github.io/nevergrad/parametrization.html?highlight=scalar). `Scalar(dtype): describes a float (the default) or an int. and all Array methods are therefore available.`

However, nowhere else in the documentation it is explained how to use it as a `int`. It seems like the constructor exposed above also does not match the one in the source code. A naive approach, calling `x1 = Scalar(int)` does not work.

In light of issue #1, My current approach is to use `TransitionChoice` instead. However, the documentation makes me unsure which is the natural choice for integral values.

## Steps to reproduce

  1. Run code below

## Observed Results

  ```
  File "main.py", line 19, in <module>
    optimizer = ng.optimizers.OnePlusOne(parametrization=instru, budget=100)
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/optimization/base.py", line 80, in _deprecated_init_wrapper
    return func(self, parametrization, budget, num_workers, **kwargs)
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/optimization/base.py", line 647, in __call__
    run = self._optimizer_class(parametrization, budget, num_workers)
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/optimization/optimizerlib.py", line 51, in __init__
    super().__init__(parametrization, budget=budget, num_workers=num_workers)
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/optimization/base.py", line 80, in _deprecated_init_wrapper
    return func(self, parametrization, budget, num_workers, **kwargs)
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/optimization/base.py", line 138, in __init__
    if not self.dimension:
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/optimization/base.py", line 180, in dimension
    return self.parametrization.dimension
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/core.py", line 85, in dimension
    self._dimension = self.get_standardized_data(reference=self).size
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/core.py", line 145, in get_standardized_data
    return self._internal_get_standardized_data(self if reference is None else reference)
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/core.py", line 496, in _internal_get_standardized_data
    data = {k: self[k].get_standardized_data(reference=p) for k, p in reference._content.items()}
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/core.py", line 496, in <dictcomp>
    data = {k: self[k].get_standardized_data(reference=p) for k, p in reference._content.items()}
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/core.py", line 145, in get_standardized_data
    return self._internal_get_standardized_data(self if reference is None else reference)
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/core.py", line 496, in _internal_get_standardized_data
    data = {k: self[k].get_standardized_data(reference=p) for k, p in reference._content.items()}
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/core.py", line 496, in <dictcomp>
    data = {k: self[k].get_standardized_data(reference=p) for k, p in reference._content.items()}
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/core.py", line 145, in get_standardized_data
    return self._internal_get_standardized_data(self if reference is None else reference)
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/data.py", line 296, in _internal_get_standardized_data
    return reference._to_reduced_space(self._value) - reference._get_ref_data()  # type: ignore
  File "/home/homeGlobal/lcampos/anaconda3/envs/nevergrad_testing/lib/python3.6/site-packages/nevergrad/parametrization/data.py", line 311, in _to_reduced_space
    reduced = distribval / sigma
TypeError: unsupported operand type(s) for /: 'type' and 'float'
```

## Expected Results

  * The code would not crash.

## Relevant Code

```python
import nevergrad as ng

def square(x1, x2, y):
    ¦   return (x1 -3)**2 + (x2-3)**2 + abs(y)

x1 = ng.p.Scalar(int)
x2 = ng.p.Scalar(int)
y = ng.p.Scalar(int)

instru = ng.p.Instrumentation(x1, x2, y)
optimizer = ng.optimizers.OnePlusOne(parametrization=instru, budget=100)
recommendation = optimizer.minimize(square)  # best value
print(recommendation.value)
````


<!--- 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:
Indeed the doc is not up to date, I'll try to update it.
In the meantime you can check the API directly in the documentation website, and in particular the [`set_integer_casting` method](
https://facebookresearch.github.io/nevergrad/parametrization_ref.html#nevergrad.p.Array.set_integer_casting)
An additional thought: just make sure you set the mutation sigma accordingly, by default it is 1 so that you're likely to change from one integer to the next or previous one, but not much farther. You can increase this step, but do avoid setting it lower.

Resolving patch:
diff --git a/nevergrad/parametrization/data.py b/nevergrad/parametrization/data.py
--- a/nevergrad/parametrization/data.py
+++ b/nevergrad/parametrization/data.py
@@ -309,6 +309,12 @@ def set_integer_casting(self: A) -> A:
         Returns
         -------
         self
+
+        Note
+        ----
+        Using integer casting makes the parameter discrete which can make the optimization more
+        difficult. It is especially ill-adviced to use this with a range smaller than 10, or
+        a sigma lower than 1. In those cases, you should rather use a TransitionChoice instead.
         """
         self.integer = True
         return self
@@ -384,7 +390,7 @@ class Scalar(Array):
     - if both lower and upper bounds are provided, sigma will be adapted so that the range spans 6 sigma.
       Also, if init is not provided, it will be set to the middle value.
     - More specific behaviors can be obtained throught the following methods:
-     set_bounds, set_mutation
+     :code:`set_bounds`, :code:`set_mutation`, :code:`set_integer_casting`
     """
 
     def __init__(
@@ -438,7 +444,7 @@ def _a_min_max_deprecation(
 
 
 class Log(Scalar):
-    """Parameter representing a log distributed scalar between 0 and infinity.
+    """Parameter representing a positive variable, mutated by Gaussian mutation in log-scale.
 
     Parameters
     ----------
@@ -457,9 +463,7 @@ class Log(Scalar):
 
     Note
     ----
-    By default this is a positive variable, mutated by Gaussian mutation in log-scale.
-    More specific behaviors can be obtained throught the following methods:
-    set_bounds, set_mutation
+    This class is only a wrapper over :code:`Scalar`.
     """
 
     def __init__(


Test patch: