We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
BUG `scattering3d_qm7.py` crashes on GPU
The input is on the GPU, but the scattering object has not been put in GPU mode, see https://github.com/kymatio/kymatio/blob/master/examples/3d/scattering3d_qm7.py#L212.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `examples/3d/scattering3d_qm7.py`
Content:
```
1 """
2 3D scattering quantum chemistry regression
3 ==========================================
4 This uses the 3D scattering on a standard dataset.
5 """
6 
7 import numpy as np
8 import time
9 import torch
10 import os
11 
12 from sklearn import linear_model, model_selection, preprocessing, pipeline
13 from kymatio.scattering3d import HarmonicScattering3D
14 from kymatio.scattering3d.utils import compute_integrals, generate_weighted_sum_of_gaussians
15 from kymatio.datasets import fetch_qm7
16 from kymatio.caching import get_cache_dir
17 from scipy.spatial.distance import pdist
18 
19 
20 def evaluate_linear_regression(X, y, n_folds=5):
21     """
22     Evaluates linear ridge regression predictions of y using X.
23 
24     Parameters
25     ----------
26     X:  numpy array
27         input features, shape (N, D)
28     y: numpy array
29         target value, shape (N, 1)
30 
31     """
32     n_datapoints = X.shape[0]
33     P = np.random.permutation(n_datapoints).reshape((n_folds, -1))
34     cross_val_folds = []
35 
36     for i_fold in range(n_folds):
37         fold = (np.concatenate(P[np.arange(n_folds) != i_fold], axis=0), P[i_fold])
38         cross_val_folds.append(fold)
39 
40     alphas = 10.**(-np.arange(0, 10))
41     for i, alpha in enumerate(alphas):
42         regressor = pipeline.make_pipeline(
43             preprocessing.StandardScaler(), linear_model.Ridge(alpha=alpha))
44         y_prediction = model_selection.cross_val_predict(
45             regressor, X=X, y=y, cv=cross_val_folds)
46         MAE = np.mean(np.abs(y_prediction - y))
47         RMSE = np.sqrt(np.mean((y_prediction - y)**2))
48         print('Ridge regression, alpha: {}, MAE: {}, RMSE: {}'.format(
49             alpha, MAE, RMSE))
50 
51 
52 def get_valence(charges):
53     """
54         Returns the number valence electrons of a particle given the
55         nuclear charge.
56 
57         Parameters
58         ----------
59         charges: numpy array
60             array containing the nuclear charges, arbitrary size
61 
62         Returns
63         -------
64         valence_charges : numpy array
65             same size as the input
66     """
67     return (
68         charges * (charges <= 2) +
69         (charges - 2) * np.logical_and(charges > 2, charges <= 10) +
70         (charges - 10) * np.logical_and(charges > 10, charges <= 18))
71 
72 
73 def get_qm7_energies():
74     """
75         Loads the energies of the molecules of the QM7 dataset.
76 
77         Returns
78         -------
79         energies: numpy array
80             array containing the energies of the molecules
81     """
82     qm7 = fetch_qm7()
83     return qm7['energies']
84 
85 
86 
87 def get_qm7_positions_and_charges(sigma, overlapping_precision=1e-1):
88     """
89         Loads the positions and charges of the molecules of the QM7 dataset.
90         QM7 is a dataset of 7165 organic molecules with up to 7 non-hydrogen
91         atoms, whose energies were computed with a quantun chemistry
92         computational method named Density Functional Theory.
93         This dataset has been made available to train machine learning models
94         to predict these energies.
95 
96         Parameters
97         ----------
98         sigma : float
99             width parameter of the Gaussian that represents a particle
100 
101         overlapping_precision : float, optional
102             affects the scaling of the positions. The positions are re-scaled
103             such that two Gaussian functions of width sigma centerd at the qm7
104             positions overlapp with amplitude <= the overlapping_precision
105 
106         Returns
107         -------
108         positions, charges, valence_charges: torch arrays
109             array containing the positions, charges and valence charges
110             of the QM7 database molecules
111     """
112     qm7 = fetch_qm7(align=True)
113     positions = qm7['positions']
114     charges = qm7['charges'].astype('float32')
115     valence_charges = get_valence(charges)
116 
117     # normalize positions
118     min_dist = np.inf
119     for i in range(positions.shape[0]):
120         n_atoms = np.sum(charges[i] != 0)
121         pos = positions[i, :n_atoms, :]
122         min_dist = min(min_dist, pdist(pos).min())
123     delta = sigma * np.sqrt(-8 * np.log(overlapping_precision))
124     positions = positions * delta / min_dist
125 
126     return (torch.from_numpy(positions),
127             torch.from_numpy(charges),
128             torch.from_numpy(valence_charges))
129 
130 
131 def compute_qm7_solid_harmonic_scattering_coefficients(
132         M=192, N=128, O=96, sigma=2., J=2, L=3,
133         integral_powers=(0.5, 1., 2., 3.), batch_size=16):
134     """
135         Computes the scattering coefficients of the molecules of the
136         QM7 database. Channels used are full charges, valence charges
137         and core charges. Linear regression of the qm7 energies with
138         the given values gives MAE 2.75, RMSE 4.18 (kcal.mol-1).
139 
140         Parameters
141         ----------
142         M, N, O: int
143             dimensions of the numerical grid
144         sigma : float
145             width parameter of the Gaussian that represents a particle
146         J: int
147             maximal scale of the solid harmonic wavelets
148         L: int
149             maximal first order of the solid harmonic wavelets
150         integral_powers: list of int
151             powers for the integrals
152         batch_size: int
153             size of the batch for computations
154 
155         Returns
156         -------
157         order_0: torch tensor
158             array containing zeroth-order scattering coefficients
159         orders_1_and_2: torch tensor
160             array containing first- and second-order scattering coefficients
161     """
162     cuda = torch.cuda.is_available()
163     grid = torch.from_numpy(
164         np.fft.ifftshift(
165             np.mgrid[-M//2:-M//2+M, -N//2:-N//2+N, -O//2:-O//2+O].astype('float32'),
166             axes=(1, 2, 3)))
167     pos, full_charges, valence_charges = get_qm7_positions_and_charges(sigma)
168 
169     if cuda:
170         grid = grid.cuda()
171         pos = pos.cuda()
172         full_charges = full_charges.cuda()
173         valence_charges = valence_charges.cuda()
174 
175     n_molecules = pos.size(0)
176     n_batches = np.ceil(n_molecules / batch_size).astype(int)
177 
178     scattering = HarmonicScattering3D(J=J, shape=(M, N, O), L=L, sigma_0=sigma)
179 
180     order_0, order_1, order_2 = [], [], []
181     print('Computing solid harmonic scattering coefficients of {} molecules '
182         'of QM7 database on {}'.format(pos.size(0), 'GPU' if cuda else 'CPU'))
183     print('sigma: {}, L: {}, J: {}, integral powers: {}'.format(sigma, L, J, integral_powers))
184 
185     this_time = None
186     last_time = None
187     for i in range(n_batches):
188         this_time = time.time()
189         if last_time is not None:
190             dt = this_time - last_time
191             print("Iteration {} ETA: [{:02}:{:02}:{:02}]".format(
192                         i + 1, int(((n_batches - i - 1) * dt) // 3600),
193                         int((((n_batches - i - 1) * dt) // 60) % 60),
194                         int(((n_batches - i - 1) * dt) % 60)), end='\r')
195         else:
196             print("Iteration {} ETA: {}".format(i + 1,'-'),end='\r')
197         last_time = this_time
198         time.sleep(1)
199 
200         start, end = i * batch_size, min((i + 1) * batch_size, n_molecules)
201 
202         pos_batch = pos[start:end]
203         full_batch = full_charges[start:end]
204         val_batch = valence_charges[start:end]
205 
206         full_density_batch = generate_weighted_sum_of_gaussians(
207                 grid, pos_batch, full_batch, sigma, cuda=cuda)
208         full_order_0 = compute_integrals(full_density_batch, integral_powers)
209         scattering.max_order = 2
210         scattering.method = 'integral'
211         scattering.integral_powers = integral_powers
212         full_scattering = scattering(full_density_batch)
213 
214         val_density_batch = generate_weighted_sum_of_gaussians(
215                 grid, pos_batch, val_batch, sigma, cuda=cuda)
216         val_order_0 = compute_integrals(val_density_batch, integral_powers)
217         val_scattering= scattering(val_density_batch)
218 
219         core_density_batch = full_density_batch - val_density_batch
220         core_order_0 = compute_integrals(core_density_batch, integral_powers)
221         core_scattering = scattering(core_density_batch)
222 
223 
224         order_0.append(
225             torch.stack([full_order_0, val_order_0, core_order_0], dim=-1))
226         orders_1_and_2.append(
227             torch.stack(
228                 [full_scattering, val_scattering, core_scattering], dim=-1))
229 
230     order_0 = torch.cat(order_0, dim=0)
231     orders_1_and_2 = torch.cat(orders_1_and_2, dim=0)
232 
233     return order_0, orders_1_and_2
234 
235 M, N, O, J, L = 192, 128, 96, 2, 3
236 integral_powers = [0.5,  1., 2., 3.]
237 sigma = 2.
238 
239 order_0, orders_1_and_2 = compute_qm7_solid_harmonic_scattering_coefficients(
240     M=M, N=N, O=O, J=J, L=L, integral_powers=integral_powers,
241     sigma=sigma, batch_size=8)
242 
243 n_molecules = order_0.size(0)
244 
245 np_order_0 = order_0.numpy().reshape((n_molecules, -1))
246 np_orders_1_and_2 = orders_1_and_2.numpy().reshape((n_molecules, -1))
247 
248 basename = 'qm7_L_{}_J_{}_sigma_{}_MNO_{}_powers_{}.npy'.format(
249         L, J, sigma, (M, N, O), integral_powers)
250 cachedir = get_cache_dir("qm7/experiments")
251 np.save(os.path.join(cachedir, 'order_0_' + basename), np_order_0)
252 np.save(os.path.join(
253     cachedir, 'orders_1_and_2_' + basename), np_orders_1_and_2)
254 
255 scattering_coef = np.concatenate([np_order_0, np_orders_1_and_2], axis=1)
256 target = get_qm7_energies()
257 
258 evaluate_linear_regression(scattering_coef, target)
259
```
--- 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/examples/3d/scattering3d_qm7.py b/examples/3d/scattering3d_qm7.py
--- a/examples/3d/scattering3d_qm7.py
+++ b/examples/3d/scattering3d_qm7.py
@@ -166,16 +166,17 @@
             axes=(1, 2, 3)))
     pos, full_charges, valence_charges = get_qm7_positions_and_charges(sigma)
 
+    n_molecules = pos.size(0)
+    n_batches = np.ceil(n_molecules / batch_size).astype(int)
+
+    scattering = HarmonicScattering3D(J=J, shape=(M, N, O), L=L, sigma_0=sigma)
+
     if cuda:
         grid = grid.cuda()
         pos = pos.cuda()
         full_charges = full_charges.cuda()
         valence_charges = valence_charges.cuda()
-
-    n_molecules = pos.size(0)
-    n_batches = np.ceil(n_molecules / batch_size).astype(int)
-
-    scattering = HarmonicScattering3D(J=J, shape=(M, N, O), L=L, sigma_0=sigma)
+        scattering.cuda()
 
     order_0, order_1, order_2 = [], [], []
     print('Computing solid harmonic scattering coefficients of {} molecules '

{"golden_diff": "diff --git a/examples/3d/scattering3d_qm7.py b/examples/3d/scattering3d_qm7.py\n--- a/examples/3d/scattering3d_qm7.py\n+++ b/examples/3d/scattering3d_qm7.py\n@@ -166,16 +166,17 @@\n             axes=(1, 2, 3)))\n     pos, full_charges, valence_charges = get_qm7_positions_and_charges(sigma)\n \n+    n_molecules = pos.size(0)\n+    n_batches = np.ceil(n_molecules / batch_size).astype(int)\n+\n+    scattering = HarmonicScattering3D(J=J, shape=(M, N, O), L=L, sigma_0=sigma)\n+\n     if cuda:\n         grid = grid.cuda()\n         pos = pos.cuda()\n         full_charges = full_charges.cuda()\n         valence_charges = valence_charges.cuda()\n-\n-    n_molecules = pos.size(0)\n-    n_batches = np.ceil(n_molecules / batch_size).astype(int)\n-\n-    scattering = HarmonicScattering3D(J=J, shape=(M, N, O), L=L, sigma_0=sigma)\n+        scattering.cuda()\n \n     order_0, order_1, order_2 = [], [], []\n     print('Computing solid harmonic scattering coefficients of {} molecules '\n", "issue": "BUG `scattering3d_qm7.py` crashes on GPU\nThe input is on the GPU, but the scattering object has not been put in GPU mode, see https://github.com/kymatio/kymatio/blob/master/examples/3d/scattering3d_qm7.py#L212.\n", "before_files": [{"content": "\"\"\"\n3D scattering quantum chemistry regression\n==========================================\nThis uses the 3D scattering on a standard dataset.\n\"\"\"\n\nimport numpy as np\nimport time\nimport torch\nimport os\n\nfrom sklearn import linear_model, model_selection, preprocessing, pipeline\nfrom kymatio.scattering3d import HarmonicScattering3D\nfrom kymatio.scattering3d.utils import compute_integrals, generate_weighted_sum_of_gaussians\nfrom kymatio.datasets import fetch_qm7\nfrom kymatio.caching import get_cache_dir\nfrom scipy.spatial.distance import pdist\n\n\ndef evaluate_linear_regression(X, y, n_folds=5):\n    \"\"\"\n    Evaluates linear ridge regression predictions of y using X.\n\n    Parameters\n    ----------\n    X:  numpy array\n        input features, shape (N, D)\n    y: numpy array\n        target value, shape (N, 1)\n\n    \"\"\"\n    n_datapoints = X.shape[0]\n    P = np.random.permutation(n_datapoints).reshape((n_folds, -1))\n    cross_val_folds = []\n\n    for i_fold in range(n_folds):\n        fold = (np.concatenate(P[np.arange(n_folds) != i_fold], axis=0), P[i_fold])\n        cross_val_folds.append(fold)\n\n    alphas = 10.**(-np.arange(0, 10))\n    for i, alpha in enumerate(alphas):\n        regressor = pipeline.make_pipeline(\n            preprocessing.StandardScaler(), linear_model.Ridge(alpha=alpha))\n        y_prediction = model_selection.cross_val_predict(\n            regressor, X=X, y=y, cv=cross_val_folds)\n        MAE = np.mean(np.abs(y_prediction - y))\n        RMSE = np.sqrt(np.mean((y_prediction - y)**2))\n        print('Ridge regression, alpha: {}, MAE: {}, RMSE: {}'.format(\n            alpha, MAE, RMSE))\n\n\ndef get_valence(charges):\n    \"\"\"\n        Returns the number valence electrons of a particle given the\n        nuclear charge.\n\n        Parameters\n        ----------\n        charges: numpy array\n            array containing the nuclear charges, arbitrary size\n\n        Returns\n        -------\n        valence_charges : numpy array\n            same size as the input\n    \"\"\"\n    return (\n        charges * (charges <= 2) +\n        (charges - 2) * np.logical_and(charges > 2, charges <= 10) +\n        (charges - 10) * np.logical_and(charges > 10, charges <= 18))\n\n\ndef get_qm7_energies():\n    \"\"\"\n        Loads the energies of the molecules of the QM7 dataset.\n\n        Returns\n        -------\n        energies: numpy array\n            array containing the energies of the molecules\n    \"\"\"\n    qm7 = fetch_qm7()\n    return qm7['energies']\n\n\n\ndef get_qm7_positions_and_charges(sigma, overlapping_precision=1e-1):\n    \"\"\"\n        Loads the positions and charges of the molecules of the QM7 dataset.\n        QM7 is a dataset of 7165 organic molecules with up to 7 non-hydrogen\n        atoms, whose energies were computed with a quantun chemistry\n        computational method named Density Functional Theory.\n        This dataset has been made available to train machine learning models\n        to predict these energies.\n\n        Parameters\n        ----------\n        sigma : float\n            width parameter of the Gaussian that represents a particle\n\n        overlapping_precision : float, optional\n            affects the scaling of the positions. The positions are re-scaled\n            such that two Gaussian functions of width sigma centerd at the qm7\n            positions overlapp with amplitude <= the overlapping_precision\n\n        Returns\n        -------\n        positions, charges, valence_charges: torch arrays\n            array containing the positions, charges and valence charges\n            of the QM7 database molecules\n    \"\"\"\n    qm7 = fetch_qm7(align=True)\n    positions = qm7['positions']\n    charges = qm7['charges'].astype('float32')\n    valence_charges = get_valence(charges)\n\n    # normalize positions\n    min_dist = np.inf\n    for i in range(positions.shape[0]):\n        n_atoms = np.sum(charges[i] != 0)\n        pos = positions[i, :n_atoms, :]\n        min_dist = min(min_dist, pdist(pos).min())\n    delta = sigma * np.sqrt(-8 * np.log(overlapping_precision))\n    positions = positions * delta / min_dist\n\n    return (torch.from_numpy(positions),\n            torch.from_numpy(charges),\n            torch.from_numpy(valence_charges))\n\n\ndef compute_qm7_solid_harmonic_scattering_coefficients(\n        M=192, N=128, O=96, sigma=2., J=2, L=3,\n        integral_powers=(0.5, 1., 2., 3.), batch_size=16):\n    \"\"\"\n        Computes the scattering coefficients of the molecules of the\n        QM7 database. Channels used are full charges, valence charges\n        and core charges. Linear regression of the qm7 energies with\n        the given values gives MAE 2.75, RMSE 4.18 (kcal.mol-1).\n\n        Parameters\n        ----------\n        M, N, O: int\n            dimensions of the numerical grid\n        sigma : float\n            width parameter of the Gaussian that represents a particle\n        J: int\n            maximal scale of the solid harmonic wavelets\n        L: int\n            maximal first order of the solid harmonic wavelets\n        integral_powers: list of int\n            powers for the integrals\n        batch_size: int\n            size of the batch for computations\n\n        Returns\n        -------\n        order_0: torch tensor\n            array containing zeroth-order scattering coefficients\n        orders_1_and_2: torch tensor\n            array containing first- and second-order scattering coefficients\n    \"\"\"\n    cuda = torch.cuda.is_available()\n    grid = torch.from_numpy(\n        np.fft.ifftshift(\n            np.mgrid[-M//2:-M//2+M, -N//2:-N//2+N, -O//2:-O//2+O].astype('float32'),\n            axes=(1, 2, 3)))\n    pos, full_charges, valence_charges = get_qm7_positions_and_charges(sigma)\n\n    if cuda:\n        grid = grid.cuda()\n        pos = pos.cuda()\n        full_charges = full_charges.cuda()\n        valence_charges = valence_charges.cuda()\n\n    n_molecules = pos.size(0)\n    n_batches = np.ceil(n_molecules / batch_size).astype(int)\n\n    scattering = HarmonicScattering3D(J=J, shape=(M, N, O), L=L, sigma_0=sigma)\n\n    order_0, order_1, order_2 = [], [], []\n    print('Computing solid harmonic scattering coefficients of {} molecules '\n        'of QM7 database on {}'.format(pos.size(0), 'GPU' if cuda else 'CPU'))\n    print('sigma: {}, L: {}, J: {}, integral powers: {}'.format(sigma, L, J, integral_powers))\n\n    this_time = None\n    last_time = None\n    for i in range(n_batches):\n        this_time = time.time()\n        if last_time is not None:\n            dt = this_time - last_time\n            print(\"Iteration {} ETA: [{:02}:{:02}:{:02}]\".format(\n                        i + 1, int(((n_batches - i - 1) * dt) // 3600),\n                        int((((n_batches - i - 1) * dt) // 60) % 60),\n                        int(((n_batches - i - 1) * dt) % 60)), end='\\r')\n        else:\n            print(\"Iteration {} ETA: {}\".format(i + 1,'-'),end='\\r')\n        last_time = this_time\n        time.sleep(1)\n\n        start, end = i * batch_size, min((i + 1) * batch_size, n_molecules)\n\n        pos_batch = pos[start:end]\n        full_batch = full_charges[start:end]\n        val_batch = valence_charges[start:end]\n\n        full_density_batch = generate_weighted_sum_of_gaussians(\n                grid, pos_batch, full_batch, sigma, cuda=cuda)\n        full_order_0 = compute_integrals(full_density_batch, integral_powers)\n        scattering.max_order = 2\n        scattering.method = 'integral'\n        scattering.integral_powers = integral_powers\n        full_scattering = scattering(full_density_batch)\n\n        val_density_batch = generate_weighted_sum_of_gaussians(\n                grid, pos_batch, val_batch, sigma, cuda=cuda)\n        val_order_0 = compute_integrals(val_density_batch, integral_powers)\n        val_scattering= scattering(val_density_batch)\n\n        core_density_batch = full_density_batch - val_density_batch\n        core_order_0 = compute_integrals(core_density_batch, integral_powers)\n        core_scattering = scattering(core_density_batch)\n\n\n        order_0.append(\n            torch.stack([full_order_0, val_order_0, core_order_0], dim=-1))\n        orders_1_and_2.append(\n            torch.stack(\n                [full_scattering, val_scattering, core_scattering], dim=-1))\n\n    order_0 = torch.cat(order_0, dim=0)\n    orders_1_and_2 = torch.cat(orders_1_and_2, dim=0)\n\n    return order_0, orders_1_and_2\n\nM, N, O, J, L = 192, 128, 96, 2, 3\nintegral_powers = [0.5,  1., 2., 3.]\nsigma = 2.\n\norder_0, orders_1_and_2 = compute_qm7_solid_harmonic_scattering_coefficients(\n    M=M, N=N, O=O, J=J, L=L, integral_powers=integral_powers,\n    sigma=sigma, batch_size=8)\n\nn_molecules = order_0.size(0)\n\nnp_order_0 = order_0.numpy().reshape((n_molecules, -1))\nnp_orders_1_and_2 = orders_1_and_2.numpy().reshape((n_molecules, -1))\n\nbasename = 'qm7_L_{}_J_{}_sigma_{}_MNO_{}_powers_{}.npy'.format(\n        L, J, sigma, (M, N, O), integral_powers)\ncachedir = get_cache_dir(\"qm7/experiments\")\nnp.save(os.path.join(cachedir, 'order_0_' + basename), np_order_0)\nnp.save(os.path.join(\n    cachedir, 'orders_1_and_2_' + basename), np_orders_1_and_2)\n\nscattering_coef = np.concatenate([np_order_0, np_orders_1_and_2], axis=1)\ntarget = get_qm7_energies()\n\nevaluate_linear_regression(scattering_coef, target)\n", "path": "examples/3d/scattering3d_qm7.py"}], "after_files": [{"content": "\"\"\"\n3D scattering quantum chemistry regression\n==========================================\nThis uses the 3D scattering on a standard dataset.\n\"\"\"\n\nimport numpy as np\nimport time\nimport torch\nimport os\n\nfrom sklearn import linear_model, model_selection, preprocessing, pipeline\nfrom kymatio.scattering3d import HarmonicScattering3D\nfrom kymatio.scattering3d.utils import compute_integrals, generate_weighted_sum_of_gaussians\nfrom kymatio.datasets import fetch_qm7\nfrom kymatio.caching import get_cache_dir\nfrom scipy.spatial.distance import pdist\n\n\ndef evaluate_linear_regression(X, y, n_folds=5):\n    \"\"\"\n    Evaluates linear ridge regression predictions of y using X.\n\n    Parameters\n    ----------\n    X:  numpy array\n        input features, shape (N, D)\n    y: numpy array\n        target value, shape (N, 1)\n\n    \"\"\"\n    n_datapoints = X.shape[0]\n    P = np.random.permutation(n_datapoints).reshape((n_folds, -1))\n    cross_val_folds = []\n\n    for i_fold in range(n_folds):\n        fold = (np.concatenate(P[np.arange(n_folds) != i_fold], axis=0), P[i_fold])\n        cross_val_folds.append(fold)\n\n    alphas = 10.**(-np.arange(0, 10))\n    for i, alpha in enumerate(alphas):\n        regressor = pipeline.make_pipeline(\n            preprocessing.StandardScaler(), linear_model.Ridge(alpha=alpha))\n        y_prediction = model_selection.cross_val_predict(\n            regressor, X=X, y=y, cv=cross_val_folds)\n        MAE = np.mean(np.abs(y_prediction - y))\n        RMSE = np.sqrt(np.mean((y_prediction - y)**2))\n        print('Ridge regression, alpha: {}, MAE: {}, RMSE: {}'.format(\n            alpha, MAE, RMSE))\n\n\ndef get_valence(charges):\n    \"\"\"\n        Returns the number valence electrons of a particle given the\n        nuclear charge.\n\n        Parameters\n        ----------\n        charges: numpy array\n            array containing the nuclear charges, arbitrary size\n\n        Returns\n        -------\n        valence_charges : numpy array\n            same size as the input\n    \"\"\"\n    return (\n        charges * (charges <= 2) +\n        (charges - 2) * np.logical_and(charges > 2, charges <= 10) +\n        (charges - 10) * np.logical_and(charges > 10, charges <= 18))\n\n\ndef get_qm7_energies():\n    \"\"\"\n        Loads the energies of the molecules of the QM7 dataset.\n\n        Returns\n        -------\n        energies: numpy array\n            array containing the energies of the molecules\n    \"\"\"\n    qm7 = fetch_qm7()\n    return qm7['energies']\n\n\n\ndef get_qm7_positions_and_charges(sigma, overlapping_precision=1e-1):\n    \"\"\"\n        Loads the positions and charges of the molecules of the QM7 dataset.\n        QM7 is a dataset of 7165 organic molecules with up to 7 non-hydrogen\n        atoms, whose energies were computed with a quantun chemistry\n        computational method named Density Functional Theory.\n        This dataset has been made available to train machine learning models\n        to predict these energies.\n\n        Parameters\n        ----------\n        sigma : float\n            width parameter of the Gaussian that represents a particle\n\n        overlapping_precision : float, optional\n            affects the scaling of the positions. The positions are re-scaled\n            such that two Gaussian functions of width sigma centerd at the qm7\n            positions overlapp with amplitude <= the overlapping_precision\n\n        Returns\n        -------\n        positions, charges, valence_charges: torch arrays\n            array containing the positions, charges and valence charges\n            of the QM7 database molecules\n    \"\"\"\n    qm7 = fetch_qm7(align=True)\n    positions = qm7['positions']\n    charges = qm7['charges'].astype('float32')\n    valence_charges = get_valence(charges)\n\n    # normalize positions\n    min_dist = np.inf\n    for i in range(positions.shape[0]):\n        n_atoms = np.sum(charges[i] != 0)\n        pos = positions[i, :n_atoms, :]\n        min_dist = min(min_dist, pdist(pos).min())\n    delta = sigma * np.sqrt(-8 * np.log(overlapping_precision))\n    positions = positions * delta / min_dist\n\n    return (torch.from_numpy(positions),\n            torch.from_numpy(charges),\n            torch.from_numpy(valence_charges))\n\n\ndef compute_qm7_solid_harmonic_scattering_coefficients(\n        M=192, N=128, O=96, sigma=2., J=2, L=3,\n        integral_powers=(0.5, 1., 2., 3.), batch_size=16):\n    \"\"\"\n        Computes the scattering coefficients of the molecules of the\n        QM7 database. Channels used are full charges, valence charges\n        and core charges. Linear regression of the qm7 energies with\n        the given values gives MAE 2.75, RMSE 4.18 (kcal.mol-1).\n\n        Parameters\n        ----------\n        M, N, O: int\n            dimensions of the numerical grid\n        sigma : float\n            width parameter of the Gaussian that represents a particle\n        J: int\n            maximal scale of the solid harmonic wavelets\n        L: int\n            maximal first order of the solid harmonic wavelets\n        integral_powers: list of int\n            powers for the integrals\n        batch_size: int\n            size of the batch for computations\n\n        Returns\n        -------\n        order_0: torch tensor\n            array containing zeroth-order scattering coefficients\n        orders_1_and_2: torch tensor\n            array containing first- and second-order scattering coefficients\n    \"\"\"\n    cuda = torch.cuda.is_available()\n    grid = torch.from_numpy(\n        np.fft.ifftshift(\n            np.mgrid[-M//2:-M//2+M, -N//2:-N//2+N, -O//2:-O//2+O].astype('float32'),\n            axes=(1, 2, 3)))\n    pos, full_charges, valence_charges = get_qm7_positions_and_charges(sigma)\n\n    n_molecules = pos.size(0)\n    n_batches = np.ceil(n_molecules / batch_size).astype(int)\n\n    scattering = HarmonicScattering3D(J=J, shape=(M, N, O), L=L, sigma_0=sigma)\n\n    if cuda:\n        grid = grid.cuda()\n        pos = pos.cuda()\n        full_charges = full_charges.cuda()\n        valence_charges = valence_charges.cuda()\n        scattering.cuda()\n\n    order_0, order_1, order_2 = [], [], []\n    print('Computing solid harmonic scattering coefficients of {} molecules '\n        'of QM7 database on {}'.format(pos.size(0), 'GPU' if cuda else 'CPU'))\n    print('sigma: {}, L: {}, J: {}, integral powers: {}'.format(sigma, L, J, integral_powers))\n\n    this_time = None\n    last_time = None\n    for i in range(n_batches):\n        this_time = time.time()\n        if last_time is not None:\n            dt = this_time - last_time\n            print(\"Iteration {} ETA: [{:02}:{:02}:{:02}]\".format(\n                        i + 1, int(((n_batches - i - 1) * dt) // 3600),\n                        int((((n_batches - i - 1) * dt) // 60) % 60),\n                        int(((n_batches - i - 1) * dt) % 60)), end='\\r')\n        else:\n            print(\"Iteration {} ETA: {}\".format(i + 1,'-'),end='\\r')\n        last_time = this_time\n        time.sleep(1)\n\n        start, end = i * batch_size, min((i + 1) * batch_size, n_molecules)\n\n        pos_batch = pos[start:end]\n        full_batch = full_charges[start:end]\n        val_batch = valence_charges[start:end]\n\n        full_density_batch = generate_weighted_sum_of_gaussians(\n                grid, pos_batch, full_batch, sigma, cuda=cuda)\n        full_order_0 = compute_integrals(full_density_batch, integral_powers)\n        scattering.max_order = 2\n        scattering.method = 'integral'\n        scattering.integral_powers = integral_powers\n        full_scattering = scattering(full_density_batch)\n\n        val_density_batch = generate_weighted_sum_of_gaussians(\n                grid, pos_batch, val_batch, sigma, cuda=cuda)\n        val_order_0 = compute_integrals(val_density_batch, integral_powers)\n        val_scattering= scattering(val_density_batch)\n\n        core_density_batch = full_density_batch - val_density_batch\n        core_order_0 = compute_integrals(core_density_batch, integral_powers)\n        core_scattering = scattering(core_density_batch)\n\n\n        order_0.append(\n            torch.stack([full_order_0, val_order_0, core_order_0], dim=-1))\n        orders_1_and_2.append(\n            torch.stack(\n                [full_scattering, val_scattering, core_scattering], dim=-1))\n\n    order_0 = torch.cat(order_0, dim=0)\n    orders_1_and_2 = torch.cat(orders_1_and_2, dim=0)\n\n    return order_0, orders_1_and_2\n\nM, N, O, J, L = 192, 128, 96, 2, 3\nintegral_powers = [0.5,  1., 2., 3.]\nsigma = 2.\n\norder_0, orders_1_and_2 = compute_qm7_solid_harmonic_scattering_coefficients(\n    M=M, N=N, O=O, J=J, L=L, integral_powers=integral_powers,\n    sigma=sigma, batch_size=8)\n\nn_molecules = order_0.size(0)\n\nnp_order_0 = order_0.numpy().reshape((n_molecules, -1))\nnp_orders_1_and_2 = orders_1_and_2.numpy().reshape((n_molecules, -1))\n\nbasename = 'qm7_L_{}_J_{}_sigma_{}_MNO_{}_powers_{}.npy'.format(\n        L, J, sigma, (M, N, O), integral_powers)\ncachedir = get_cache_dir(\"qm7/experiments\")\nnp.save(os.path.join(cachedir, 'order_0_' + basename), np_order_0)\nnp.save(os.path.join(\n    cachedir, 'orders_1_and_2_' + basename), np_orders_1_and_2)\n\nscattering_coef = np.concatenate([np_order_0, np_orders_1_and_2], axis=1)\ntarget = get_qm7_energies()\n\nevaluate_linear_regression(scattering_coef, target)\n", "path": "examples/3d/scattering3d_qm7.py"}]}