We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Optimizer creates candidate from out of bounds args
## Steps to reproduce

**Note:** I don't know if this is properly handled (doesn't cause the optimizer to mis-behave) but here is my observation:
  1. Define a bounded instrumentation variable (ex. instru.var.Array(1).asfloat().bounded(0,5))
  2. Create a candidate from out of space args (ex. 10)
  3. Optimizer.tell(candidate, arbitrary value)

## Observed Results

the candidate is created normally and the optimizer accepts it.

## Expected Results

throwing an exception due to output of bounds args.





--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nevergrad/instrumentation/transforms.py`
Content:
```
1 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
2 #
3 # This source code is licensed under the MIT license found in the
4 # LICENSE file in the root directory of this source tree.
5 
6 import numpy as np
7 from scipy import stats
8 
9 
10 class Transform:
11     """Base class for transforms implementing a forward and a backward (inverse)
12     method.
13     This provide a default representation, and a short representation should be implemented
14     for each transform.
15     """
16 
17     def forward(self, x: np.ndarray) -> np.ndarray:
18         raise NotImplementedError
19 
20     def backward(self, y: np.ndarray) -> np.ndarray:
21         raise NotImplementedError
22 
23     def reverted(self) -> 'Transform':
24         return Reverted(self)
25 
26     def _short_repr(self) -> str:
27         raise NotImplementedError
28 
29     def __repr__(self) -> str:
30         args = ", ".join(f"{x}={y}" for x, y in sorted(self.__dict__.items()) if not x.startswith("_"))
31         return f"{self.__class__.__name__}({args})"
32 
33     def __format__(self, format_spec: str) -> str:
34         if format_spec == "short":
35             return self._short_repr()
36         return repr(self)
37 
38 
39 class Reverted(Transform):
40     """Inverse of a transform.
41 
42     Parameters
43     ----------
44     transform: Transform
45     """
46 
47     def __init__(self, transform: Transform) -> None:
48         self.transform = transform
49 
50     def forward(self, x: np.ndarray) -> np.ndarray:
51         return self.transform.backward(x)
52 
53     def backward(self, y: np.ndarray) -> np.ndarray:
54         return self.transform.forward(y)
55 
56     def _short_repr(self) -> str:
57         return f'Rv({self.transform:short})'
58 
59 
60 class Affine(Transform):
61     """Affine transform a * x + b
62 
63     Parameters
64     ----------
65     a: float
66     b: float
67     """
68 
69     def __init__(self, a: float, b: float) -> None:
70         self.a = a
71         self.b = b
72 
73     def forward(self, x: np.ndarray) -> np.ndarray:
74         return self.a * x + self.b  # type: ignore
75 
76     def backward(self, y: np.ndarray) -> np.ndarray:
77         return (y - self.b) / self.a  # type: ignore
78 
79     def _short_repr(self) -> str:
80         return f"Af({self.a},{self.b})"
81 
82 
83 class Exponentiate(Transform):
84     """Exponentiation transform base ** (coeff * x)
85     This can for instance be used for to get a logarithmicly distruted values 10**(-[1, 2, 3]).
86 
87     Parameters
88     ----------
89     base: float
90     coeff: float
91     """
92 
93     def __init__(self, base: float = 10., coeff: float = 1.) -> None:
94         self.base = base
95         self.coeff = coeff
96 
97     def forward(self, x: np.ndarray) -> np.ndarray:
98         return self.base ** (float(self.coeff) * x)  # type: ignore
99 
100     def backward(self, y: np.ndarray) -> np.ndarray:
101         return np.log(y) / (float(self.coeff) * np.log(self.base))  # type: ignore
102 
103     def _short_repr(self) -> str:
104         return f"Ex({self.base},{self.coeff})"
105 
106 
107 class TanhBound(Transform):
108     """Bounds all real values into [min_val, max_val] using a tanh transform.
109     Beware, tanh goes very fast to its limits.
110 
111     Parameters
112     ----------
113     min_val: float
114     max_val: float
115     """
116 
117     def __init__(self, min_val: float, max_val: float) -> None:
118         assert min_val < max_val
119         self.min_val = min_val
120         self.max_val = max_val
121         self._b = .5 * (self.max_val + self.min_val)
122         self._a = .5 * (self.max_val - self.min_val)
123 
124     def forward(self, x: np.ndarray) -> np.ndarray:
125         return self._b + self._a * np.tanh(x)  # type: ignore
126 
127     def backward(self, y: np.ndarray) -> np.ndarray:
128         return np.arctanh((y - self._b) / self._a)  # type: ignore
129 
130     def _short_repr(self) -> str:
131         return f"Th({self.min_val},{self.max_val})"
132 
133 
134 class ArctanBound(Transform):
135     """Bounds all real values into [min_val, max_val] using an arctan transform.
136     This is a much softer approach compared to tanh.
137 
138     Parameters
139     ----------
140     min_val: float
141     max_val: float
142     """
143 
144     def __init__(self, min_val: float, max_val: float) -> None:
145         assert min_val < max_val
146         self.min_val = min_val
147         self.max_val = max_val
148         self._b = .5 * (self.max_val + self.min_val)
149         self._a = (self.max_val - self.min_val) / np.pi
150 
151     def forward(self, x: np.ndarray) -> np.ndarray:
152         return self._b + self._a * np.arctan(x)  # type: ignore
153 
154     def backward(self, y: np.ndarray) -> np.ndarray:
155         return np.tan((y - self._b) / self._a)  # type: ignore
156 
157     def _short_repr(self) -> str:
158         return f"At({self.min_val},{self.max_val})"
159 
160 
161 class CumulativeDensity(Transform):
162     """Bounds all real values into [0, 1] using a gaussian cumulative density function (cdf)
163     Beware, cdf goes very fast to its limits.
164     """
165 
166     def forward(self, x: np.ndarray) -> np.ndarray:
167         return stats.norm.cdf(x)  # type: ignore
168 
169     def backward(self, y: np.ndarray) -> np.ndarray:
170         return stats.norm.ppf(y)  # type: ignore
171 
172     def _short_repr(self) -> str:
173         return f"Cd()"
174
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nevergrad/instrumentation/transforms.py b/nevergrad/instrumentation/transforms.py
--- a/nevergrad/instrumentation/transforms.py
+++ b/nevergrad/instrumentation/transforms.py
@@ -125,6 +125,9 @@
         return self._b + self._a * np.tanh(x)  # type: ignore
 
     def backward(self, y: np.ndarray) -> np.ndarray:
+        if np.max(y) > self.max_val or np.min(y) < self.min_val:
+            raise ValueError(f"Only data between {self.min_val} and {self.max_val} "
+                             "can be transformed back (bounds lead to infinity).")
         return np.arctanh((y - self._b) / self._a)  # type: ignore
 
     def _short_repr(self) -> str:
@@ -152,6 +155,8 @@
         return self._b + self._a * np.arctan(x)  # type: ignore
 
     def backward(self, y: np.ndarray) -> np.ndarray:
+        if np.max(y) > self.max_val or np.min(y) < self.min_val:
+            raise ValueError(f"Only data between {self.min_val} and {self.max_val} can be transformed back.")
         return np.tan((y - self._b) / self._a)  # type: ignore
 
     def _short_repr(self) -> str:
@@ -167,6 +172,8 @@
         return stats.norm.cdf(x)  # type: ignore
 
     def backward(self, y: np.ndarray) -> np.ndarray:
+        if np.max(y) > 1 or np.min(y) < 0:
+            raise ValueError("Only data between 0 and 1 can be transformed back (bounds lead to infinity).")
         return stats.norm.ppf(y)  # type: ignore
 
     def _short_repr(self) -> str:

{"golden_diff": "diff --git a/nevergrad/instrumentation/transforms.py b/nevergrad/instrumentation/transforms.py\n--- a/nevergrad/instrumentation/transforms.py\n+++ b/nevergrad/instrumentation/transforms.py\n@@ -125,6 +125,9 @@\n         return self._b + self._a * np.tanh(x)  # type: ignore\n \n     def backward(self, y: np.ndarray) -> np.ndarray:\n+        if np.max(y) > self.max_val or np.min(y) < self.min_val:\n+            raise ValueError(f\"Only data between {self.min_val} and {self.max_val} \"\n+                             \"can be transformed back (bounds lead to infinity).\")\n         return np.arctanh((y - self._b) / self._a)  # type: ignore\n \n     def _short_repr(self) -> str:\n@@ -152,6 +155,8 @@\n         return self._b + self._a * np.arctan(x)  # type: ignore\n \n     def backward(self, y: np.ndarray) -> np.ndarray:\n+        if np.max(y) > self.max_val or np.min(y) < self.min_val:\n+            raise ValueError(f\"Only data between {self.min_val} and {self.max_val} can be transformed back.\")\n         return np.tan((y - self._b) / self._a)  # type: ignore\n \n     def _short_repr(self) -> str:\n@@ -167,6 +172,8 @@\n         return stats.norm.cdf(x)  # type: ignore\n \n     def backward(self, y: np.ndarray) -> np.ndarray:\n+        if np.max(y) > 1 or np.min(y) < 0:\n+            raise ValueError(\"Only data between 0 and 1 can be transformed back (bounds lead to infinity).\")\n         return stats.norm.ppf(y)  # type: ignore\n \n     def _short_repr(self) -> str:\n", "issue": "Optimizer creates candidate from out of bounds args\n## Steps to reproduce\r\n\r\n**Note:** I don't know if this is properly handled (doesn't cause the optimizer to mis-behave) but here is my observation:\r\n  1. Define a bounded instrumentation variable (ex. instru.var.Array(1).asfloat().bounded(0,5))\r\n  2. Create a candidate from out of space args (ex. 10)\r\n  3. Optimizer.tell(candidate, arbitrary value)\r\n\r\n## Observed Results\r\n\r\nthe candidate is created normally and the optimizer accepts it.\r\n\r\n## Expected Results\r\n\r\nthrowing an exception due to output of bounds args.\r\n\r\n\r\n\r\n\n", "before_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.\n#\n# This source code is licensed under the MIT license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport numpy as np\nfrom scipy import stats\n\n\nclass Transform:\n    \"\"\"Base class for transforms implementing a forward and a backward (inverse)\n    method.\n    This provide a default representation, and a short representation should be implemented\n    for each transform.\n    \"\"\"\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        raise NotImplementedError\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        raise NotImplementedError\n\n    def reverted(self) -> 'Transform':\n        return Reverted(self)\n\n    def _short_repr(self) -> str:\n        raise NotImplementedError\n\n    def __repr__(self) -> str:\n        args = \", \".join(f\"{x}={y}\" for x, y in sorted(self.__dict__.items()) if not x.startswith(\"_\"))\n        return f\"{self.__class__.__name__}({args})\"\n\n    def __format__(self, format_spec: str) -> str:\n        if format_spec == \"short\":\n            return self._short_repr()\n        return repr(self)\n\n\nclass Reverted(Transform):\n    \"\"\"Inverse of a transform.\n\n    Parameters\n    ----------\n    transform: Transform\n    \"\"\"\n\n    def __init__(self, transform: Transform) -> None:\n        self.transform = transform\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self.transform.backward(x)\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        return self.transform.forward(y)\n\n    def _short_repr(self) -> str:\n        return f'Rv({self.transform:short})'\n\n\nclass Affine(Transform):\n    \"\"\"Affine transform a * x + b\n\n    Parameters\n    ----------\n    a: float\n    b: float\n    \"\"\"\n\n    def __init__(self, a: float, b: float) -> None:\n        self.a = a\n        self.b = b\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self.a * x + self.b  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        return (y - self.b) / self.a  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"Af({self.a},{self.b})\"\n\n\nclass Exponentiate(Transform):\n    \"\"\"Exponentiation transform base ** (coeff * x)\n    This can for instance be used for to get a logarithmicly distruted values 10**(-[1, 2, 3]).\n\n    Parameters\n    ----------\n    base: float\n    coeff: float\n    \"\"\"\n\n    def __init__(self, base: float = 10., coeff: float = 1.) -> None:\n        self.base = base\n        self.coeff = coeff\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self.base ** (float(self.coeff) * x)  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        return np.log(y) / (float(self.coeff) * np.log(self.base))  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"Ex({self.base},{self.coeff})\"\n\n\nclass TanhBound(Transform):\n    \"\"\"Bounds all real values into [min_val, max_val] using a tanh transform.\n    Beware, tanh goes very fast to its limits.\n\n    Parameters\n    ----------\n    min_val: float\n    max_val: float\n    \"\"\"\n\n    def __init__(self, min_val: float, max_val: float) -> None:\n        assert min_val < max_val\n        self.min_val = min_val\n        self.max_val = max_val\n        self._b = .5 * (self.max_val + self.min_val)\n        self._a = .5 * (self.max_val - self.min_val)\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self._b + self._a * np.tanh(x)  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        return np.arctanh((y - self._b) / self._a)  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"Th({self.min_val},{self.max_val})\"\n\n\nclass ArctanBound(Transform):\n    \"\"\"Bounds all real values into [min_val, max_val] using an arctan transform.\n    This is a much softer approach compared to tanh.\n\n    Parameters\n    ----------\n    min_val: float\n    max_val: float\n    \"\"\"\n\n    def __init__(self, min_val: float, max_val: float) -> None:\n        assert min_val < max_val\n        self.min_val = min_val\n        self.max_val = max_val\n        self._b = .5 * (self.max_val + self.min_val)\n        self._a = (self.max_val - self.min_val) / np.pi\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self._b + self._a * np.arctan(x)  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        return np.tan((y - self._b) / self._a)  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"At({self.min_val},{self.max_val})\"\n\n\nclass CumulativeDensity(Transform):\n    \"\"\"Bounds all real values into [0, 1] using a gaussian cumulative density function (cdf)\n    Beware, cdf goes very fast to its limits.\n    \"\"\"\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return stats.norm.cdf(x)  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        return stats.norm.ppf(y)  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"Cd()\"\n", "path": "nevergrad/instrumentation/transforms.py"}], "after_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.\n#\n# This source code is licensed under the MIT license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport numpy as np\nfrom scipy import stats\n\n\nclass Transform:\n    \"\"\"Base class for transforms implementing a forward and a backward (inverse)\n    method.\n    This provide a default representation, and a short representation should be implemented\n    for each transform.\n    \"\"\"\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        raise NotImplementedError\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        raise NotImplementedError\n\n    def reverted(self) -> 'Transform':\n        return Reverted(self)\n\n    def _short_repr(self) -> str:\n        raise NotImplementedError\n\n    def __repr__(self) -> str:\n        args = \", \".join(f\"{x}={y}\" for x, y in sorted(self.__dict__.items()) if not x.startswith(\"_\"))\n        return f\"{self.__class__.__name__}({args})\"\n\n    def __format__(self, format_spec: str) -> str:\n        if format_spec == \"short\":\n            return self._short_repr()\n        return repr(self)\n\n\nclass Reverted(Transform):\n    \"\"\"Inverse of a transform.\n\n    Parameters\n    ----------\n    transform: Transform\n    \"\"\"\n\n    def __init__(self, transform: Transform) -> None:\n        self.transform = transform\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self.transform.backward(x)\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        return self.transform.forward(y)\n\n    def _short_repr(self) -> str:\n        return f'Rv({self.transform:short})'\n\n\nclass Affine(Transform):\n    \"\"\"Affine transform a * x + b\n\n    Parameters\n    ----------\n    a: float\n    b: float\n    \"\"\"\n\n    def __init__(self, a: float, b: float) -> None:\n        self.a = a\n        self.b = b\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self.a * x + self.b  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        return (y - self.b) / self.a  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"Af({self.a},{self.b})\"\n\n\nclass Exponentiate(Transform):\n    \"\"\"Exponentiation transform base ** (coeff * x)\n    This can for instance be used for to get a logarithmicly distruted values 10**(-[1, 2, 3]).\n\n    Parameters\n    ----------\n    base: float\n    coeff: float\n    \"\"\"\n\n    def __init__(self, base: float = 10., coeff: float = 1.) -> None:\n        self.base = base\n        self.coeff = coeff\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self.base ** (float(self.coeff) * x)  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        return np.log(y) / (float(self.coeff) * np.log(self.base))  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"Ex({self.base},{self.coeff})\"\n\n\nclass TanhBound(Transform):\n    \"\"\"Bounds all real values into [min_val, max_val] using a tanh transform.\n    Beware, tanh goes very fast to its limits.\n\n    Parameters\n    ----------\n    min_val: float\n    max_val: float\n    \"\"\"\n\n    def __init__(self, min_val: float, max_val: float) -> None:\n        assert min_val < max_val\n        self.min_val = min_val\n        self.max_val = max_val\n        self._b = .5 * (self.max_val + self.min_val)\n        self._a = .5 * (self.max_val - self.min_val)\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self._b + self._a * np.tanh(x)  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        if np.max(y) > self.max_val or np.min(y) < self.min_val:\n            raise ValueError(f\"Only data between {self.min_val} and {self.max_val} \"\n                             \"can be transformed back (bounds lead to infinity).\")\n        return np.arctanh((y - self._b) / self._a)  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"Th({self.min_val},{self.max_val})\"\n\n\nclass ArctanBound(Transform):\n    \"\"\"Bounds all real values into [min_val, max_val] using an arctan transform.\n    This is a much softer approach compared to tanh.\n\n    Parameters\n    ----------\n    min_val: float\n    max_val: float\n    \"\"\"\n\n    def __init__(self, min_val: float, max_val: float) -> None:\n        assert min_val < max_val\n        self.min_val = min_val\n        self.max_val = max_val\n        self._b = .5 * (self.max_val + self.min_val)\n        self._a = (self.max_val - self.min_val) / np.pi\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return self._b + self._a * np.arctan(x)  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        if np.max(y) > self.max_val or np.min(y) < self.min_val:\n            raise ValueError(f\"Only data between {self.min_val} and {self.max_val} can be transformed back.\")\n        return np.tan((y - self._b) / self._a)  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"At({self.min_val},{self.max_val})\"\n\n\nclass CumulativeDensity(Transform):\n    \"\"\"Bounds all real values into [0, 1] using a gaussian cumulative density function (cdf)\n    Beware, cdf goes very fast to its limits.\n    \"\"\"\n\n    def forward(self, x: np.ndarray) -> np.ndarray:\n        return stats.norm.cdf(x)  # type: ignore\n\n    def backward(self, y: np.ndarray) -> np.ndarray:\n        if np.max(y) > 1 or np.min(y) < 0:\n            raise ValueError(\"Only data between 0 and 1 can be transformed back (bounds lead to infinity).\")\n        return stats.norm.ppf(y)  # type: ignore\n\n    def _short_repr(self) -> str:\n        return f\"Cd()\"\n", "path": "nevergrad/instrumentation/transforms.py"}]}