scoringrules 0.2.0__tar.gz → 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.
Files changed (25) hide show
  1. {scoringrules-0.2.0 → scoringrules-0.3.0}/PKG-INFO +1 -1
  2. {scoringrules-0.2.0 → scoringrules-0.3.0}/pyproject.toml +6 -2
  3. scoringrules-0.3.0/scoringrules/__init__.py +35 -0
  4. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/_crps.py +41 -0
  5. scoringrules-0.3.0/scoringrules/_logs.py +43 -0
  6. scoringrules-0.3.0/scoringrules/_wcrps.py +187 -0
  7. scoringrules-0.3.0/scoringrules/_wenergy.py +182 -0
  8. scoringrules-0.3.0/scoringrules/_wvariogram.py +193 -0
  9. scoringrules-0.3.0/scoringrules/backend/array.py +531 -0
  10. scoringrules-0.3.0/scoringrules/backend/base.py +156 -0
  11. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/gufuncs.py +235 -8
  12. scoringrules-0.3.0/scoringrules/backend/numba.py +324 -0
  13. scoringrules-0.2.0/scoringrules/__init__.py +0 -20
  14. scoringrules-0.2.0/scoringrules/backend/array.py +0 -191
  15. scoringrules-0.2.0/scoringrules/backend/base.py +0 -54
  16. scoringrules-0.2.0/scoringrules/backend/numba.py +0 -115
  17. {scoringrules-0.2.0 → scoringrules-0.3.0}/LICENSE +0 -0
  18. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/_brier.py +0 -0
  19. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/_energy.py +0 -0
  20. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/_variogram.py +0 -0
  21. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/__init__.py +0 -0
  22. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/arrayapi/__init__.py +0 -0
  23. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/arrayapi/array_type.py +0 -0
  24. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/arrayapi/functions.py +0 -0
  25. {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/registry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scoringrules
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Scoring rules for probabilistic forecast evaluation.
5
5
  Home-page: https://github.com/frazane/scoringrules
6
6
  Keywords: probabilistic,forecasting,verification
@@ -1,8 +1,11 @@
1
1
  [tool.poetry]
2
2
  name = "scoringrules"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "Scoring rules for probabilistic forecast evaluation."
5
- authors = ["Francesco Zanetta <zanetta.francesco@gmail.com>"]
5
+ authors = [
6
+ "Francesco Zanetta <zanetta.francesco@gmail.com>",
7
+ "Sam Allen <sam.allen@unibe.ch>",
8
+ ]
6
9
  homepage = "https://github.com/frazane/scoringrules"
7
10
  documentation = "https://frazane.github.io/scoringrules/"
8
11
  keywords = ["probabilistic", "forecasting", "verification"]
@@ -35,6 +38,7 @@ pre-commit = "^3.3.1"
35
38
  pytest = "^7.3.1"
36
39
  mypy = "^1.3.0"
37
40
  jax = { extras = ["cpu"], version = "^0.4.10" }
41
+ dask = "^2023.7.1"
38
42
 
39
43
  [build-system]
40
44
  requires = ["poetry-core>=1.0.0"]
@@ -0,0 +1,35 @@
1
+ from importlib.metadata import version
2
+
3
+ from scoringrules._brier import brier_score
4
+ from scoringrules._crps import crps_ensemble, crps_lognormal, crps_normal, crps_logistic
5
+ from scoringrules._wcrps import owcrps_ensemble, twcrps_ensemble, vrcrps_ensemble
6
+ from scoringrules._energy import energy_score
7
+ from scoringrules._wenergy import owenergy_score, twenergy_score, vrenergy_score
8
+ from scoringrules._logs import logs_normal
9
+ from scoringrules._variogram import variogram_score
10
+ from scoringrules._wvariogram import owvariogram_score, twvariogram_score, vrvariogram_score
11
+ from scoringrules.backend import register_backend
12
+
13
+ __version__ = version("scoringrules")
14
+
15
+
16
+ __all__ = [
17
+ "register_backend",
18
+ "crps_ensemble",
19
+ "crps_normal",
20
+ "crps_lognormal",
21
+ "crps_logistic",
22
+ "owcrps_ensemble",
23
+ "twcrps_ensemble",
24
+ "vrcrps_ensemble",
25
+ "logs_normal",
26
+ "brier_score",
27
+ "energy_score",
28
+ "owenergy_score",
29
+ "twenergy_score",
30
+ "vrenergy_score",
31
+ "variogram_score",
32
+ "owvariogram_score",
33
+ "twvariogram_score",
34
+ "vrvariogram_score",
35
+ ]
@@ -138,8 +138,49 @@ def crps_lognormal(
138
138
  return srb[backend].crps_lognormal(mulog, sigmalog, observation)
139
139
 
140
140
 
141
+ def crps_logistic(
142
+ mu: ArrayLike,
143
+ sigma: ArrayLike,
144
+ observation: ArrayLike,
145
+ /,
146
+ *,
147
+ backend: str = "numpy",
148
+ ) -> ArrayLike:
149
+ r"""Compute the closed form of the CRPS for the logistic distribution.
150
+
151
+ It is based on the following formulation from
152
+ [Jordan et al. (2019)](https://www.jstatsoft.org/article/view/v090i12):
153
+
154
+ $$ \mathrm{CRPS}(\mathcal{L}(\mu, \sigma), y) = \sigma \left\{ \omega - 2 \log F(\omega) - 1 \right\}, $$
155
+
156
+ where $F(\omega)$ is the CDF of the standard logistic distribution at the
157
+ normalized prediction error $\omega = \frac{y - \mu}{\sigma}$.
158
+
159
+ Parameters
160
+ ----------
161
+ mu: ArrayLike
162
+ Location parameter of the forecast logistic distribution.
163
+ sigma: ArrayLike
164
+ Scale parameter of the forecast logistic distribution.
165
+ observation: ArrayLike
166
+ Observed values.
167
+
168
+ Returns
169
+ -------
170
+ crps: array_like
171
+ The CRPS for the Logistic(mu, sigma) forecasts given the observations.
172
+
173
+ Examples
174
+ --------
175
+ >>> from scoringrules import crps
176
+ >>> crps.logistic(0.1, 0.4, 0.0)
177
+ """
178
+ return srb[backend].crps_logistic(mu, sigma, observation)
179
+
180
+
141
181
  __all__ = [
142
182
  "crps_ensemble",
143
183
  "crps_normal",
144
184
  "crps_lognormal",
185
+ "crps_logistic",
145
186
  ]
@@ -0,0 +1,43 @@
1
+ import typing as tp
2
+
3
+ from scoringrules.backend import backends as srb
4
+ from scoringrules.backend.arrayapi import Array
5
+
6
+ ArrayLike = tp.TypeVar("ArrayLike", Array, float)
7
+
8
+
9
+ def logs_normal(
10
+ mu: ArrayLike,
11
+ sigma: ArrayLike,
12
+ observation: ArrayLike,
13
+ /,
14
+ *,
15
+ backend: tp.Literal["numba", "numpy", "jax"] = "numpy",
16
+ ) -> Array:
17
+ r"""Compute the logarithmic score (LS) for the normal distribution.
18
+
19
+ This score is equivalent to the negative log likelihood.
20
+
21
+ Parameters
22
+ ----------
23
+ mu: ArrayLike
24
+ Mean of the forecast normal distribution.
25
+ sigma: ArrayLike
26
+ Standard deviation of the forecast normal distribution.
27
+ observation: ArrayLike
28
+ The observed values.
29
+ backend: str, optional
30
+ The backend used for computations.
31
+
32
+ Returns
33
+ -------
34
+ ls: array_like
35
+ The LS between Normal(mu, sigma) and obs.
36
+
37
+ Examples
38
+ --------
39
+ >>> import scoringrules as sr
40
+ >>> sr.logs_normal(0.1, 0.4, 0.0)
41
+ >>> 0.033898
42
+ """
43
+ return srb[backend].logs_normal(mu, sigma, observation)
@@ -0,0 +1,187 @@
1
+ import numpy as np
2
+ import typing as tp
3
+
4
+ from scoringrules.backend import backends as srb
5
+ from scoringrules.backend.arrayapi import Array
6
+
7
+ ArrayLike = tp.TypeVar("ArrayLike", Array, float)
8
+
9
+
10
+ def twcrps_ensemble(
11
+ forecasts: Array,
12
+ observations: ArrayLike,
13
+ /,
14
+ v_func: tp.Callable = lambda x, *args: x,
15
+ v_funcargs: tuple = (),
16
+ *,
17
+ axis: int = -1,
18
+ backend: str = "numba",
19
+ ) -> Array:
20
+ r"""Estimate the Threshold-Weighted Continuous Ranked Probability Score (twCRPS) for a finite ensemble.
21
+
22
+ Computation is performed using the ensemble representation of the twCRPS in
23
+ [Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
24
+
25
+ $$ \mathrm{twCRPS}(F_{ens}, y) = \frac{1}{M} \sum_{m = 1}^{M} |v(x_{m}) - v(y)| - \frac{1}{2 M^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} |v(x_{m}) - v(x_{j})|,$$
26
+
27
+ where $F_{ens}(x) = \sum_{m=1}^{M} 1 \{ x_{m} \leq x \}/M$ is the empirical
28
+ distribution function associated with an ensemble forecast $x_{1}, \dots, x_{M}$ with
29
+ $M$ members, and $v$ is the chaining function used to target particular outcomes.
30
+
31
+ Parameters
32
+ ----------
33
+ forecasts: ArrayLike
34
+ The predicted forecast ensemble, where the ensemble dimension is by default
35
+ represented by the last axis.
36
+ observations: ArrayLike
37
+ The observed values.
38
+ v_func: tp.Callable
39
+ Chaining function used to emphasise particular outcomes.
40
+ v_funcargs: tuple
41
+ Additional arguments to the chaining function.
42
+ axis: int
43
+ The axis corresponding to the ensemble. Default is the last axis.
44
+ backend: str
45
+ The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
46
+
47
+ Returns
48
+ -------
49
+ twcrps: ArrayLike
50
+ The twCRPS between the forecast ensemble and obs for the chosen chaining function.
51
+
52
+ Examples
53
+ --------
54
+ >>> from scoringrules import crps
55
+ >>> twcrps.ensemble(pred, obs)
56
+ """
57
+ return srb[backend].twcrps_ensemble(
58
+ forecasts,
59
+ observations,
60
+ v_func,
61
+ v_funcargs,
62
+ axis=axis,
63
+ )
64
+
65
+
66
+ def owcrps_ensemble(
67
+ forecasts: Array,
68
+ observations: ArrayLike,
69
+ /,
70
+ w_func: tp.Callable = lambda x, *args: np.ones_like(x),
71
+ w_funcargs: tuple = (),
72
+ *,
73
+ axis: int = -1,
74
+ backend: str = "numba",
75
+ ) -> Array:
76
+ r"""Estimate the Outcome-Weighted Continuous Ranked Probability Score (owCRPS) for a finite ensemble.
77
+
78
+ Computation is performed using the ensemble representation of the owCRPS in
79
+ [Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
80
+
81
+ $$ \mathrm{owCRPS}(F_{ens}, y) = \frac{1}{M \bar{w}} \sum_{m = 1}^{M} |x_{m} - y|w(x_{m})w(y) - \frac{1}{2 M^{2} \bar{w}^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} |x_{m} - x_{j}|w(x_{m})w(x_{j})w(y),$$
82
+
83
+ where $F_{ens}(x) = \sum_{m=1}^{M} 1\{ x_{m} \leq x \}/M$ is the empirical
84
+ distribution function associated with an ensemble forecast $x_{1}, \dots, x_{M}$ with
85
+ $M$ members, $w$ is the chosen weight function, and $\bar{w} = \sum_{m=1}^{M}w(x_{m})/M$.
86
+
87
+ Parameters
88
+ ----------
89
+ forecasts: ArrayLike
90
+ The predicted forecast ensemble, where the ensemble dimension is by default
91
+ represented by the last axis.
92
+ observations: ArrayLike
93
+ The observed values.
94
+ w_func: tp.Callable
95
+ Weight function used to emphasise particular outcomes.
96
+ w_funcargs: tuple
97
+ Additional arguments to the weight function.
98
+ axis: int
99
+ The axis corresponding to the ensemble. Default is the last axis.
100
+ backend: str
101
+ The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
102
+
103
+ Returns
104
+ -------
105
+ owcrps: ArrayLike
106
+ The owCRPS between the forecast ensemble and obs for the chosen weight function.
107
+
108
+ Examples
109
+ --------
110
+ >>> from scoringrules import crps
111
+ >>> owcrps.ensemble(pred, obs)
112
+ """
113
+ return srb[backend].owcrps_ensemble(
114
+ forecasts,
115
+ observations,
116
+ w_func,
117
+ w_funcargs,
118
+ axis=axis,
119
+ )
120
+
121
+
122
+ def vrcrps_ensemble(
123
+ forecasts: Array,
124
+ observations: ArrayLike,
125
+ /,
126
+ w_func: tp.Callable = lambda x, *args: np.ones_like(x),
127
+ w_funcargs: tuple = (),
128
+ *,
129
+ axis: int = -1,
130
+ backend: str = "numba",
131
+ ) -> Array:
132
+ r"""Estimate the Vertically Re-scaled Continuous Ranked Probability Score (vrCRPS) for a finite ensemble.
133
+
134
+ Computation is performed using the ensemble representation of the vrCRPS in
135
+ [Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
136
+
137
+ \[
138
+ \begin{split}
139
+ \mathrm{vrCRPS}(F_{ens}, y) = & \frac{1}{M} \sum_{m = 1}^{M} |x_{m} - y|w(x_{m})w(y) - \frac{1}{2 M^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} |x_{m} - x_{j}|w(x_{m})w(x_{j}) \\
140
+ & + \left( \frac{1}{M} \sum_{m = 1}^{M} |x_{m}| w(x_{m}) - |y| w(y) \right) \left( \frac{1}{M} \sum_{m = 1}^{M} w(x_{m}) - w(y) \right),
141
+ \end{split}
142
+ \]
143
+
144
+ where $F_{ens}(x) = \sum_{m=1}^{M} 1 \{ x_{m} \leq x \}/M$ is the empirical
145
+ distribution function associated with an ensemble forecast $x_{1}, \dots, x_{M}$ with
146
+ $M$ members, $w$ is the chosen weight function, and $\bar{w} = \sum_{m=1}^{M}w(x_{m})/M$.
147
+
148
+ Parameters
149
+ ----------
150
+ forecasts: ArrayLike
151
+ The predicted forecast ensemble, where the ensemble dimension is by default
152
+ represented by the last axis.
153
+ observations: ArrayLike
154
+ The observed values.
155
+ w_func: tp.Callable
156
+ Weight function used to emphasise particular outcomes.
157
+ w_funcargs: tuple
158
+ Additional arguments to the weight function.
159
+ axis: int
160
+ The axis corresponding to the ensemble. Default is the last axis.
161
+ backend: str
162
+ The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
163
+
164
+ Returns
165
+ -------
166
+ vrcrps: ArrayLike
167
+ The vrCRPS between the forecast ensemble and obs for the chosen weight function.
168
+
169
+ Examples
170
+ --------
171
+ >>> from scoringrules import crps
172
+ >>> vrcrps.ensemble(pred, obs)
173
+ """
174
+ return srb[backend].vrcrps_ensemble(
175
+ forecasts,
176
+ observations,
177
+ w_func,
178
+ w_funcargs,
179
+ axis=axis,
180
+ )
181
+
182
+
183
+ __all__ = [
184
+ "twcrps_ensemble",
185
+ "owcrps_ensemble",
186
+ "vrcrps_ensemble",
187
+ ]
@@ -0,0 +1,182 @@
1
+ import typing as tp
2
+
3
+ from scoringrules.backend import backends as srb
4
+ from scoringrules.backend.arrayapi import Array
5
+
6
+ ArrayLike = tp.TypeVar("ArrayLike", Array, float)
7
+
8
+
9
+ def owenergy_score(
10
+ forecasts: Array,
11
+ observations: Array,
12
+ /,
13
+ w_func: tp.Callable = lambda x, *args: 1.0,
14
+ w_funcargs: tuple = (),
15
+ *,
16
+ m_axis: int = -2,
17
+ v_axis: int = -1,
18
+ backend="numba",
19
+ ) -> Array:
20
+ r"""Compute the Outcome-Weighted Energy Score (owES) for a finite multivariate ensemble.
21
+
22
+ Computation is performed using the ensemble representation of the owES in
23
+ [Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
24
+
25
+ \[
26
+ \mathrm{owES}(F_{ens}, \mathbf{y}) = \frac{1}{M \bar{w}} \sum_{m = 1}^{M} \| \mathbf{x}_{m} - \mathbf{y} \| w(\mathbf{x}_{m}) w(\mathbf{y}) - \frac{1}{2 M^{2} \bar{w}^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} \| \mathbf{x}_{m} - \mathbf{x}_{j} \| w(\mathbf{x}_{m}) w(\mathbf{x}_{j}) w(\mathbf{y}),
27
+ \]
28
+
29
+ where $F_{ens}$ is the ensemble forecast $\mathbf{x}_{1}, \dots, \mathbf{x}_{M}$ with
30
+ $M$ members, $\| \cdotp \|$ is the Euclidean distance, $w$ is the chosen weight function,
31
+ and $\bar{w} = \sum_{m=1}^{M}w(\mathbf{x}_{m})/M$.
32
+
33
+
34
+ Parameters
35
+ ----------
36
+ forecasts: ArrayLike of shape (..., M, D)
37
+ The predicted forecast ensemble, where the ensemble dimension is by default
38
+ represented by the second last axis and the variables dimension by the last axis.
39
+ observations: ArrayLike of shape (...,D)
40
+ The observed values, where the variables dimension is by default the last axis.
41
+ w_func: tp.Callable
42
+ Weight function used to emphasise particular outcomes.
43
+ w_funcargs: tuple
44
+ Additional arguments to the weight function.
45
+ m_axis: int
46
+ The axis corresponding to the ensemble dimension. Defaults to -2.
47
+ v_axis: int or tuple(int)
48
+ The axis corresponding to the variables dimension. Defaults to -1.
49
+ backend: str
50
+ The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
51
+
52
+ Returns
53
+ -------
54
+ owenergy_score: ArrayLike of shape (...)
55
+ The computed Outcome-Weighted Energy Score.
56
+ """
57
+ return srb[backend].owenergy_score(
58
+ forecasts,
59
+ observations,
60
+ w_func,
61
+ w_funcargs,
62
+ m_axis=m_axis,
63
+ v_axis=v_axis
64
+ )
65
+
66
+
67
+ def twenergy_score(
68
+ forecasts: Array,
69
+ observations: Array,
70
+ /,
71
+ v_func: tp.Callable = lambda x, *args: x,
72
+ v_funcargs: tuple = (),
73
+ *,
74
+ m_axis: int = -2,
75
+ v_axis: int = -1,
76
+ backend="numba",
77
+ ) -> Array:
78
+ r"""Compute the Threshold-Weighted Energy Score (twES) for a finite multivariate ensemble.
79
+
80
+ Computation is performed using the ensemble representation of the twES in
81
+ [Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
82
+
83
+ \[
84
+ \mathrm{twES}(F_{ens}, \mathbf{y}) = \frac{1}{M} \sum_{m = 1}^{M} \| v(\mathbf{x}_{m}) - v(\mathbf{y}) \| - \frac{1}{2 M^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} \| v(\mathbf{x}_{m}) - v(\mathbf{x}_{j}) \|,
85
+ \]
86
+
87
+ where $F_{ens}$ is the ensemble forecast $\mathbf{x}_{1}, \dots, \mathbf{x}_{M}$ with
88
+ $M$ members, $\| \cdotp \|$ is the Euclidean distance, and $v$ is the chaining function
89
+ used to target particular outcomes.
90
+
91
+
92
+ Parameters
93
+ ----------
94
+ forecasts: ArrayLike of shape (..., M, D)
95
+ The predicted forecast ensemble, where the ensemble dimension is by default
96
+ represented by the second last axis and the variables dimension by the last axis.
97
+ observations: ArrayLike of shape (...,D)
98
+ The observed values, where the variables dimension is by default the last axis.
99
+ v_func: tp.Callable
100
+ Chaining function used to emphasise particular outcomes.
101
+ v_funcargs: tuple
102
+ Additional arguments to the chaining function.
103
+ m_axis: int
104
+ The axis corresponding to the ensemble dimension. Defaults to -2.
105
+ v_axis: int or tuple(int)
106
+ The axis corresponding to the variables dimension. Defaults to -1.
107
+ backend: str
108
+ The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
109
+
110
+ Returns
111
+ -------
112
+ twenergy_score: ArrayLike of shape (...)
113
+ The computed Threshold-Weighted Energy Score.
114
+ """
115
+ return srb[backend].twenergy_score(
116
+ forecasts,
117
+ observations,
118
+ v_func,
119
+ v_funcargs,
120
+ m_axis=m_axis,
121
+ v_axis=v_axis
122
+ )
123
+
124
+
125
+ def vrenergy_score(
126
+ forecasts: Array,
127
+ observations: Array,
128
+ /,
129
+ w_func: tp.Callable = lambda x, *args: 1.0,
130
+ w_funcargs: tuple = (),
131
+ *,
132
+ m_axis: int = -2,
133
+ v_axis: int = -1,
134
+ backend="numba",
135
+ ) -> Array:
136
+ r"""Compute the Vertically Re-scaled Energy Score (vrES) for a finite multivariate ensemble.
137
+
138
+ Computation is performed using the ensemble representation of the twES in
139
+ [Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
140
+
141
+ \[
142
+ \begin{split}
143
+ \mathrm{vrES}(F_{ens}, \mathbf{y}) = & \frac{1}{M} \sum_{m = 1}^{M} \| \mathbf{x}_{m} - \mathbf{y} \| w(\mathbf{x}_{m}) w(\mathbf{y}) - \frac{1}{2 M^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} \| \mathbf{x}_{m} - \mathbf{x}_{j} \| w(\mathbf{x}_{m}) w(\mathbf{x_{j}}) \\
144
+ & + \left( \frac{1}{M} \sum_{m = 1}^{M} \| \mathbf{x}_{m} \| w(\mathbf{x}_{m}) - \| \mathbf{y} \| w(\mathbf{y}) \right) \left( \frac{1}{M} \sum_{m = 1}^{M} w(\mathbf{x}_{m}) - w(\mathbf{y}) \right),
145
+ \end{split}
146
+ \]
147
+
148
+ where $F_{ens}$ is the ensemble forecast $\mathbf{x}_{1}, \dots, \mathbf{x}_{M}$ with
149
+ $M$ members, and $v$ is the chaining function used to target particular outcomes.
150
+
151
+
152
+ Parameters
153
+ ----------
154
+ forecasts: ArrayLike of shape (..., M, D)
155
+ The predicted forecast ensemble, where the ensemble dimension is by default
156
+ represented by the second last axis and the variables dimension by the last axis.
157
+ observations: ArrayLike of shape (...,D)
158
+ The observed values, where the variables dimension is by default the last axis.
159
+ w_func: tp.Callable
160
+ Weight function used to emphasise particular outcomes.
161
+ w_funcargs: tuple
162
+ Additional arguments to the weight function.
163
+ m_axis: int
164
+ The axis corresponding to the ensemble dimension. Defaults to -2.
165
+ v_axis: int or tuple(int)
166
+ The axis corresponding to the variables dimension. Defaults to -1.
167
+ backend: str
168
+ The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
169
+
170
+ Returns
171
+ -------
172
+ vrenergy_score: ArrayLike of shape (...)
173
+ The computed Vertically Re-scaled Energy Score.
174
+ """
175
+ return srb[backend].vrenergy_score(
176
+ forecasts,
177
+ observations,
178
+ w_func,
179
+ w_funcargs,
180
+ m_axis=m_axis,
181
+ v_axis=v_axis
182
+ )