fastcmb 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fastcmb-0.3.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Salih Yeşil
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
fastcmb-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,264 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastcmb
3
+ Version: 0.3.0
4
+ Summary: An online emulator of Boltzmann codes: CMB spectra in milliseconds, with the code as the fallback.
5
+ Author: Salih Yeşil
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/salihyesil59/fastcmb
8
+ Project-URL: Source, https://github.com/salihyesil59/fastcmb
9
+ Project-URL: Issues, https://github.com/salihyesil59/fastcmb/issues
10
+ Keywords: cosmology,CMB,emulator,Gaussian process,CAMB,MCMC,Boltzmann code
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
19
+ Classifier: Topic :: Scientific/Engineering :: Physics
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: numpy>=2.0
24
+ Requires-Dist: scipy
25
+ Provides-Extra: camb
26
+ Requires-Dist: camb>=1.5; extra == "camb"
27
+ Provides-Extra: cobaya
28
+ Requires-Dist: cobaya>=3.5; extra == "cobaya"
29
+ Requires-Dist: camb>=1.5; extra == "cobaya"
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest; extra == "dev"
32
+ Requires-Dist: camb>=1.5; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # fastcmb
36
+
37
+ fastcmb is an online emulator for Boltzmann codes, aimed at CMB analyses.
38
+ It sits in front of CAMB, or any other code, and works one point at a
39
+ time:
40
+
41
+ - It predicts the spectra together with the error of that prediction,
42
+ measured in units of `ln L`.
43
+ - If the predicted error is below the tolerance, it returns the
44
+ prediction. This takes about 6 ms.
45
+ - Otherwise it runs the code and adds the point to its training set.
46
+
47
+ There is nothing to train in advance: the emulator learns while the
48
+ chain runs.
49
+
50
+ The package itself depends only on numpy and scipy. Three integrations
51
+ are available:
52
+
53
+ | Where | How |
54
+ |---|---|
55
+ | **CosmoFit** | `theory: {background: ..., fastcmb: ...}` in place of `camb` (built in, with `pip install "cosmofit[fast]"`) |
56
+ | **cobaya** | the theory `fastcmb.cobaya.FastCAMB` in place of `camb` |
57
+ | **anything else** | call a `CMBEmulator` |
58
+
59
+ ## Install
60
+
61
+ ```bash
62
+ pip install "fastcmb[camb]" # with CAMB as the oracle
63
+ pip install "fastcmb[cobaya]" # and the cobaya theory
64
+ pip install "cosmofit[fast]" # CosmoFit, with fastcmb and CAMB
65
+ ```
66
+
67
+ The emulator alone (`pip install fastcmb`) needs only numpy and scipy;
68
+ the oracle is then a code of your own. From a clone, `pip install -e ".[dev]"`
69
+ installs the tests' dependencies as well.
70
+
71
+ ## Use
72
+
73
+ ### Python
74
+
75
+ ```python
76
+ from fastcmb import CAMBOracle, CMBEmulator
77
+
78
+ emulator = CMBEmulator(CAMBOracle(lmax=2508, lens_potential_accuracy=4),
79
+ tolerance=0.05, training_file="emu/lcdm")
80
+
81
+ result = emulator({"H0": 67.4, "ombh2": 0.0224, "omch2": 0.120,
82
+ "ln1e10As": 3.044, "ns": 0.965, "tau": 0.054})
83
+
84
+ result.Cl["tt"], result.Cl["pp"], result.sigma8, result.emulated
85
+ ```
86
+
87
+ `result` contains the following:
88
+
89
+ - `Cl` holds `ell`, `tt`, `te`, `ee` and `bb`, starting at `l = 0`. These
90
+ are `C_l` in muK².
91
+ - `pp` is `[L(L+1)]² C_L / 2π`.
92
+
93
+ Any code can serve as the oracle. It is a function that takes a
94
+ parameter dict and returns `{"Cl": ..., "sigma8": ..., "sigma8_cb": ...}`
95
+ in these conventions, or `None` when the point cannot be computed.
96
+ `CAMBOracle` takes the parameters as cobaya names them (`H0` or
97
+ `cosmomc_theta`, `ombh2`, `omch2`, `ln1e10As`/`logA` or `As`, `ns`, `tau`,
98
+ and optionally `mnu`, `nnu`, `omk`, `w`, `wa`).
99
+
100
+ `emulator(params, loose_tolerance=1.0)` also answers with a prediction
101
+ whose error is above the tolerance but below 1, marked
102
+ `result.approximate`. A sampler can use it to reject a proposal that is
103
+ clearly worse than the current point without running the code, and ask
104
+ again without `loose_tolerance` for one it might accept. CosmoFit's MCMC
105
+ does this with `screen: true`.
106
+
107
+ ### cobaya
108
+
109
+ ```yaml
110
+ theory:
111
+ fastcmb.cobaya.FastCAMB:
112
+ tolerance: 0.05
113
+ lens_potential_accuracy: 4
114
+ training_file: chains/emu/lcdm
115
+ params:
116
+ logA: ... # or As
117
+ ns: ...
118
+ H0: ... # or cosmomc_theta
119
+ ombh2: ...
120
+ omch2: ...
121
+ tau: ...
122
+ sigma8: # derived
123
+ ```
124
+
125
+ The theory provides `Cl` in cobaya's units and `ell_factor` conventions,
126
+ so cobaya's CMB likelihoods read it as they would read `camb`.
127
+
128
+ ### CosmoFit
129
+
130
+ ```yaml
131
+ theory:
132
+ background:
133
+ fastcmb:
134
+ tolerance: 0.05
135
+ training_file: chains/emu/lcdm
136
+ ```
137
+
138
+ The theory takes every `camb` option and parameter, and dark sectors
139
+ beyond ΛCDM: CPL and other dark energies, early dark energy, and
140
+ Hu–Sawicki f(R) when CAMB is MGCAMB. Their parameters become inputs of
141
+ the emulator, together with the distance to last scattering, along which
142
+ they trade off against `h`.
143
+
144
+ ## Options
145
+
146
+ | | default | |
147
+ |---|---|---|
148
+ | `tolerance` | 0.05 | largest predicted `ln L` error the emulator answers with |
149
+ | `sigma8_tolerance` | 1e-3 | largest predicted relative error of `sigma8` |
150
+ | `min_train` | 30 | points computed by the code before the first fit |
151
+ | `retrain_fraction` | 0.1 | refit once the new points are this fraction of those fitted on |
152
+ | `max_train` | 800 | most points fitted on (the latest) |
153
+ | `training_file` | none | keeps the points, so parallel chains and later runs share them |
154
+ | `check_every` | 200 | after N predictions the code runs as well, to measure the error; the interval doubles while checks pass, up to 10 N |
155
+
156
+ ## How it works
157
+
158
+ 1. **Transformation.**
159
+ - `tt`, `ee`, `bb` and `pp` are emulated as `ln C_l`.
160
+ - `te` is emulated as the correlation `C_TE / sqrt(C_TT C_EE)`.
161
+ 2. **Compression.** Each block is reduced with PCA. The number of
162
+ components is chosen so that the PCA error in `ln L` stays below 0.01
163
+ (`compress.py`).
164
+ 3. **Gaussian process.**
165
+ - The mean is quadratic in the inputs.
166
+ - The four components that carry the most likelihood each get their
167
+ own kernel, and the remaining components share one (`gp.py`).
168
+ - Hyperparameters are fitted by maximum likelihood on 200 of the
169
+ points. Each refit tries both the previous values and a fresh
170
+ start, and it reruns whenever half the training set is new.
171
+ 4. **Error.**
172
+ - Each kernel's predictive variance is projected onto `ln L` with an
173
+ idealized Planck Fisher weight (`metric.py`).
174
+ - Variances are computed in order of their bound and only while they
175
+ can still change the decision. This keeps the result an upper
176
+ bound (`online.py`).
177
+ 5. **Decision.** The prediction is used, or the code runs and the point
178
+ is learned (`emulator.py`).
179
+
180
+ ## Benchmarks
181
+
182
+ The test case is ΛCDM on Planck 2018 lite + lowE + lensing, with
183
+ CosmoFit's MCMC running 4 chains in one process:
184
+
185
+ ```bash
186
+ python benchmarks/chain.py --max-time 3600 --output chains/lcdm
187
+ python benchmarks/validate_chain.py chains/lcdm # chain points re-checked with CAMB
188
+ ```
189
+
190
+ One hour, starting with no training points, on an idle machine (CAMB
191
+ 0.45 s per point):
192
+
193
+ | | v0.2 |
194
+ |---|---|
195
+ | evaluations | 131 203 |
196
+ | CAMB calls | 1 545 (897 learned, 648 checks) |
197
+ | emulated | 98.8% |
198
+ | equivalent with CAMB alone | 16.5 h |
199
+ | speed-up | 16.5× |
200
+ | `R - 1` after the hour | 0.36 |
201
+
202
+ Accuracy against CAMB, on 60 points drawn from the chain:
203
+
204
+ - `|Δ ln L|` has a median of 0.004 and a maximum of 0.02.
205
+ - The posterior agrees with Planck's: `H0` = 67.39 ± 0.51 and
206
+ `n_s` = 0.9639 ± 0.0041.
207
+
208
+ Compared with v0.1 on the same machine:
209
+
210
+ - Evaluations in the first hour went from 54 000 to 131 000.
211
+ - A prediction takes 6 ms instead of 16 ms.
212
+ - A refit takes 4–7 s instead of 58 s.
213
+
214
+ The speed-up grows with the length of the run, because CAMB runs less
215
+ and less often once the emulator has learned the posterior.
216
+
217
+ Starting from a trained emulator (the hour above), 20 minutes:
218
+
219
+ | | 1 process | 4 processes (`processes: 4`) |
220
+ |---|---|---|
221
+ | MCMC steps | 10 080 | 26 880 |
222
+ | CAMB calls (first process) | 93 | 40 |
223
+ | `R - 1` | 13.9 | **0.026** |
224
+ | `\|Δ ln L\|` vs CAMB, max | 0.016 | 0.011 |
225
+
226
+ Several processes share their points through `training_file`, so give
227
+ it whenever a run has more than one.
228
+
229
+ ### Beyond ΛCDM
230
+
231
+ The same chain with a dark sector, through CosmoFit (`--dark-energy`
232
+ `cpl`, `ede` or `hu_sawicki`; `--bao` adds DESI BAO), 4 processes sharing
233
+ a training file, run until `R - 1 < 0.02`:
234
+
235
+ | | CPL + DESI BAO | EDE | Hu–Sawicki f(R) |
236
+ |---|---|---|---|
237
+ | sampled beyond ΛCDM | `w0`, `wa` | `f_ede`, `log10 z_c` | `log10 \|f_R0\|` |
238
+ | wall time | 33 min | 39 min | 59 min |
239
+ | `R - 1` | 0.019 | 0.019 | 0.016 |
240
+ | code calls / evaluations, per process | 133 / 18 044 | 426 / 20 201 | 157 / 5 688 |
241
+ | `\|Δ ln L\|` vs the code, median / max | — | 0.015 / 0.10 | 0.003 / 0.032 |
242
+ | speed-up | — | 8.6× | 8.3× |
243
+
244
+ f(R) runs through MGCAMB, roughly ten times slower than CAMB per point.
245
+ The CPL run was not re-checked against CAMB point by point; the analysis
246
+ below does that for CPL with more data.
247
+
248
+ ## Analyses
249
+
250
+ [`analysis/cpl_vs_lcdm/`](https://github.com/salihyesil59/fastcmb/tree/main/analysis/cpl_vs_lcdm) fits ΛCDM and CPL
251
+ (`w0`, `wa`) with CosmoFit to the full Planck 2018 likelihoods (plik_lite,
252
+ lowE, lensing), DESI DR2 BAO, cosmic chronometers and, in turn, Pantheon+,
253
+ Union3 and DES-SN5YR: six runs to `R - 1 < 0.01`, all six ΛCDM parameters
254
+ sampled. The notebook compares the models (Δχ², AIC, BIC), shows which data
255
+ carry the signal, and checks the emulator against CAMB.
256
+
257
+ | | Pantheon+ | Union3 | DES-SN5YR (Dovekie) |
258
+ |---|---|---|---|
259
+ | `w0` | −0.843 ± 0.054 | −0.677 ± 0.090 | −0.809 ± 0.056 |
260
+ | `wa` | −0.59 ± 0.20 | −1.04 ± 0.30 | −0.70 ± 0.22 |
261
+ | preference for CPL | 2.6σ | 3.5σ | 3.1σ |
262
+
263
+ Each run took 15–52 min. CAMB ran at 272 (ΛCDM) and 642 (CPL) points
264
+ over all six runs, and `|Δ ln L|` against CAMB is at most 0.015.
@@ -0,0 +1,230 @@
1
+ # fastcmb
2
+
3
+ fastcmb is an online emulator for Boltzmann codes, aimed at CMB analyses.
4
+ It sits in front of CAMB, or any other code, and works one point at a
5
+ time:
6
+
7
+ - It predicts the spectra together with the error of that prediction,
8
+ measured in units of `ln L`.
9
+ - If the predicted error is below the tolerance, it returns the
10
+ prediction. This takes about 6 ms.
11
+ - Otherwise it runs the code and adds the point to its training set.
12
+
13
+ There is nothing to train in advance: the emulator learns while the
14
+ chain runs.
15
+
16
+ The package itself depends only on numpy and scipy. Three integrations
17
+ are available:
18
+
19
+ | Where | How |
20
+ |---|---|
21
+ | **CosmoFit** | `theory: {background: ..., fastcmb: ...}` in place of `camb` (built in, with `pip install "cosmofit[fast]"`) |
22
+ | **cobaya** | the theory `fastcmb.cobaya.FastCAMB` in place of `camb` |
23
+ | **anything else** | call a `CMBEmulator` |
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ pip install "fastcmb[camb]" # with CAMB as the oracle
29
+ pip install "fastcmb[cobaya]" # and the cobaya theory
30
+ pip install "cosmofit[fast]" # CosmoFit, with fastcmb and CAMB
31
+ ```
32
+
33
+ The emulator alone (`pip install fastcmb`) needs only numpy and scipy;
34
+ the oracle is then a code of your own. From a clone, `pip install -e ".[dev]"`
35
+ installs the tests' dependencies as well.
36
+
37
+ ## Use
38
+
39
+ ### Python
40
+
41
+ ```python
42
+ from fastcmb import CAMBOracle, CMBEmulator
43
+
44
+ emulator = CMBEmulator(CAMBOracle(lmax=2508, lens_potential_accuracy=4),
45
+ tolerance=0.05, training_file="emu/lcdm")
46
+
47
+ result = emulator({"H0": 67.4, "ombh2": 0.0224, "omch2": 0.120,
48
+ "ln1e10As": 3.044, "ns": 0.965, "tau": 0.054})
49
+
50
+ result.Cl["tt"], result.Cl["pp"], result.sigma8, result.emulated
51
+ ```
52
+
53
+ `result` contains the following:
54
+
55
+ - `Cl` holds `ell`, `tt`, `te`, `ee` and `bb`, starting at `l = 0`. These
56
+ are `C_l` in muK².
57
+ - `pp` is `[L(L+1)]² C_L / 2π`.
58
+
59
+ Any code can serve as the oracle. It is a function that takes a
60
+ parameter dict and returns `{"Cl": ..., "sigma8": ..., "sigma8_cb": ...}`
61
+ in these conventions, or `None` when the point cannot be computed.
62
+ `CAMBOracle` takes the parameters as cobaya names them (`H0` or
63
+ `cosmomc_theta`, `ombh2`, `omch2`, `ln1e10As`/`logA` or `As`, `ns`, `tau`,
64
+ and optionally `mnu`, `nnu`, `omk`, `w`, `wa`).
65
+
66
+ `emulator(params, loose_tolerance=1.0)` also answers with a prediction
67
+ whose error is above the tolerance but below 1, marked
68
+ `result.approximate`. A sampler can use it to reject a proposal that is
69
+ clearly worse than the current point without running the code, and ask
70
+ again without `loose_tolerance` for one it might accept. CosmoFit's MCMC
71
+ does this with `screen: true`.
72
+
73
+ ### cobaya
74
+
75
+ ```yaml
76
+ theory:
77
+ fastcmb.cobaya.FastCAMB:
78
+ tolerance: 0.05
79
+ lens_potential_accuracy: 4
80
+ training_file: chains/emu/lcdm
81
+ params:
82
+ logA: ... # or As
83
+ ns: ...
84
+ H0: ... # or cosmomc_theta
85
+ ombh2: ...
86
+ omch2: ...
87
+ tau: ...
88
+ sigma8: # derived
89
+ ```
90
+
91
+ The theory provides `Cl` in cobaya's units and `ell_factor` conventions,
92
+ so cobaya's CMB likelihoods read it as they would read `camb`.
93
+
94
+ ### CosmoFit
95
+
96
+ ```yaml
97
+ theory:
98
+ background:
99
+ fastcmb:
100
+ tolerance: 0.05
101
+ training_file: chains/emu/lcdm
102
+ ```
103
+
104
+ The theory takes every `camb` option and parameter, and dark sectors
105
+ beyond ΛCDM: CPL and other dark energies, early dark energy, and
106
+ Hu–Sawicki f(R) when CAMB is MGCAMB. Their parameters become inputs of
107
+ the emulator, together with the distance to last scattering, along which
108
+ they trade off against `h`.
109
+
110
+ ## Options
111
+
112
+ | | default | |
113
+ |---|---|---|
114
+ | `tolerance` | 0.05 | largest predicted `ln L` error the emulator answers with |
115
+ | `sigma8_tolerance` | 1e-3 | largest predicted relative error of `sigma8` |
116
+ | `min_train` | 30 | points computed by the code before the first fit |
117
+ | `retrain_fraction` | 0.1 | refit once the new points are this fraction of those fitted on |
118
+ | `max_train` | 800 | most points fitted on (the latest) |
119
+ | `training_file` | none | keeps the points, so parallel chains and later runs share them |
120
+ | `check_every` | 200 | after N predictions the code runs as well, to measure the error; the interval doubles while checks pass, up to 10 N |
121
+
122
+ ## How it works
123
+
124
+ 1. **Transformation.**
125
+ - `tt`, `ee`, `bb` and `pp` are emulated as `ln C_l`.
126
+ - `te` is emulated as the correlation `C_TE / sqrt(C_TT C_EE)`.
127
+ 2. **Compression.** Each block is reduced with PCA. The number of
128
+ components is chosen so that the PCA error in `ln L` stays below 0.01
129
+ (`compress.py`).
130
+ 3. **Gaussian process.**
131
+ - The mean is quadratic in the inputs.
132
+ - The four components that carry the most likelihood each get their
133
+ own kernel, and the remaining components share one (`gp.py`).
134
+ - Hyperparameters are fitted by maximum likelihood on 200 of the
135
+ points. Each refit tries both the previous values and a fresh
136
+ start, and it reruns whenever half the training set is new.
137
+ 4. **Error.**
138
+ - Each kernel's predictive variance is projected onto `ln L` with an
139
+ idealized Planck Fisher weight (`metric.py`).
140
+ - Variances are computed in order of their bound and only while they
141
+ can still change the decision. This keeps the result an upper
142
+ bound (`online.py`).
143
+ 5. **Decision.** The prediction is used, or the code runs and the point
144
+ is learned (`emulator.py`).
145
+
146
+ ## Benchmarks
147
+
148
+ The test case is ΛCDM on Planck 2018 lite + lowE + lensing, with
149
+ CosmoFit's MCMC running 4 chains in one process:
150
+
151
+ ```bash
152
+ python benchmarks/chain.py --max-time 3600 --output chains/lcdm
153
+ python benchmarks/validate_chain.py chains/lcdm # chain points re-checked with CAMB
154
+ ```
155
+
156
+ One hour, starting with no training points, on an idle machine (CAMB
157
+ 0.45 s per point):
158
+
159
+ | | v0.2 |
160
+ |---|---|
161
+ | evaluations | 131 203 |
162
+ | CAMB calls | 1 545 (897 learned, 648 checks) |
163
+ | emulated | 98.8% |
164
+ | equivalent with CAMB alone | 16.5 h |
165
+ | speed-up | 16.5× |
166
+ | `R - 1` after the hour | 0.36 |
167
+
168
+ Accuracy against CAMB, on 60 points drawn from the chain:
169
+
170
+ - `|Δ ln L|` has a median of 0.004 and a maximum of 0.02.
171
+ - The posterior agrees with Planck's: `H0` = 67.39 ± 0.51 and
172
+ `n_s` = 0.9639 ± 0.0041.
173
+
174
+ Compared with v0.1 on the same machine:
175
+
176
+ - Evaluations in the first hour went from 54 000 to 131 000.
177
+ - A prediction takes 6 ms instead of 16 ms.
178
+ - A refit takes 4–7 s instead of 58 s.
179
+
180
+ The speed-up grows with the length of the run, because CAMB runs less
181
+ and less often once the emulator has learned the posterior.
182
+
183
+ Starting from a trained emulator (the hour above), 20 minutes:
184
+
185
+ | | 1 process | 4 processes (`processes: 4`) |
186
+ |---|---|---|
187
+ | MCMC steps | 10 080 | 26 880 |
188
+ | CAMB calls (first process) | 93 | 40 |
189
+ | `R - 1` | 13.9 | **0.026** |
190
+ | `\|Δ ln L\|` vs CAMB, max | 0.016 | 0.011 |
191
+
192
+ Several processes share their points through `training_file`, so give
193
+ it whenever a run has more than one.
194
+
195
+ ### Beyond ΛCDM
196
+
197
+ The same chain with a dark sector, through CosmoFit (`--dark-energy`
198
+ `cpl`, `ede` or `hu_sawicki`; `--bao` adds DESI BAO), 4 processes sharing
199
+ a training file, run until `R - 1 < 0.02`:
200
+
201
+ | | CPL + DESI BAO | EDE | Hu–Sawicki f(R) |
202
+ |---|---|---|---|
203
+ | sampled beyond ΛCDM | `w0`, `wa` | `f_ede`, `log10 z_c` | `log10 \|f_R0\|` |
204
+ | wall time | 33 min | 39 min | 59 min |
205
+ | `R - 1` | 0.019 | 0.019 | 0.016 |
206
+ | code calls / evaluations, per process | 133 / 18 044 | 426 / 20 201 | 157 / 5 688 |
207
+ | `\|Δ ln L\|` vs the code, median / max | — | 0.015 / 0.10 | 0.003 / 0.032 |
208
+ | speed-up | — | 8.6× | 8.3× |
209
+
210
+ f(R) runs through MGCAMB, roughly ten times slower than CAMB per point.
211
+ The CPL run was not re-checked against CAMB point by point; the analysis
212
+ below does that for CPL with more data.
213
+
214
+ ## Analyses
215
+
216
+ [`analysis/cpl_vs_lcdm/`](https://github.com/salihyesil59/fastcmb/tree/main/analysis/cpl_vs_lcdm) fits ΛCDM and CPL
217
+ (`w0`, `wa`) with CosmoFit to the full Planck 2018 likelihoods (plik_lite,
218
+ lowE, lensing), DESI DR2 BAO, cosmic chronometers and, in turn, Pantheon+,
219
+ Union3 and DES-SN5YR: six runs to `R - 1 < 0.01`, all six ΛCDM parameters
220
+ sampled. The notebook compares the models (Δχ², AIC, BIC), shows which data
221
+ carry the signal, and checks the emulator against CAMB.
222
+
223
+ | | Pantheon+ | Union3 | DES-SN5YR (Dovekie) |
224
+ |---|---|---|---|
225
+ | `w0` | −0.843 ± 0.054 | −0.677 ± 0.090 | −0.809 ± 0.056 |
226
+ | `wa` | −0.59 ± 0.20 | −1.04 ± 0.30 | −0.70 ± 0.22 |
227
+ | preference for CPL | 2.6σ | 3.5σ | 3.1σ |
228
+
229
+ Each run took 15–52 min. CAMB ran at 272 (ΛCDM) and 642 (CPL) points
230
+ over all six runs, and `|Δ ln L|` against CAMB is at most 0.015.
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "fastcmb"
7
+ dynamic = ["version"]
8
+ description = "An online emulator of Boltzmann codes: CMB spectra in milliseconds, with the code as the fallback."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Salih Yeşil" }]
14
+ keywords = ["cosmology", "CMB", "emulator", "Gaussian process", "CAMB", "MCMC", "Boltzmann code"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Science/Research",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Scientific/Engineering :: Astronomy",
24
+ "Topic :: Scientific/Engineering :: Physics",
25
+ ]
26
+ dependencies = [
27
+ "numpy>=2.0",
28
+ "scipy",
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/salihyesil59/fastcmb"
33
+ Source = "https://github.com/salihyesil59/fastcmb"
34
+ Issues = "https://github.com/salihyesil59/fastcmb/issues"
35
+
36
+ [project.optional-dependencies]
37
+ camb = ["camb>=1.5"]
38
+ cobaya = ["cobaya>=3.5", "camb>=1.5"]
39
+ dev = ["pytest", "camb>=1.5"]
40
+
41
+ [tool.setuptools.dynamic]
42
+ version = { attr = "fastcmb.__version__" }
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,23 @@
1
+ """
2
+ fastcmb: an online emulator of Boltzmann codes for CMB analyses.
3
+
4
+ :class:`CMBEmulator` wraps a Boltzmann code -- an *oracle*, such as
5
+ :class:`CAMBOracle` -- and answers with a Gaussian-process prediction
6
+ wherever its error, in units of the log-likelihood, is below a
7
+ tolerance; elsewhere the code runs, and the point is learned. It needs
8
+ only numpy and scipy, and fits in any analysis code:
9
+
10
+ * CosmoFit: ``theory: {background: ..., fastcmb: ...}`` in place of
11
+ ``camb`` (built into CosmoFit, with ``fastcmb`` installed);
12
+ * cobaya: the theory ``fastcmb.cobaya.FastCAMB`` in place of ``camb``;
13
+ * anything else: call a :class:`CMBEmulator`.
14
+ """
15
+
16
+ from .camb_oracle import CAMBOracle
17
+ from .emulator import CMBEmulator, Result
18
+ from .gp import GP
19
+ from .online import OnlineEmulator
20
+
21
+ __all__ = ["GP", "CAMBOracle", "CMBEmulator", "OnlineEmulator", "Result", "__version__"]
22
+
23
+ __version__ = "0.3.0"