@@ -173,12 +173,9 @@ def from_step_impf(
173173
174174 """ Step function type impact function.
175175
176- By default, everything is destroyed above the step.
176+ By default, the impact is 100% above the step.
177177 Useful for high resolution modelling.
178178
179- This method modifies self (climada.entity.impact_funcs instance)
180- by assigning an id, intensity, mdd and paa to the impact function.
181-
182179 Parameters
183180 ----------
184181 intensity: tuple(float, float, float)
@@ -226,12 +223,14 @@ def from_sigmoid_impf(
226223 haz_type : str ,
227224 impf_id : int = 1 ,
228225 ** kwargs ):
229- """Sigmoid type impact function hinging on three parameter.
226+ r """Sigmoid type impact function hinging on three parameter.
230227
231228 This type of impact function is very flexible for any sort of study,
232229 hazard and resolution. The sigmoid is defined as:
233230
234- .. math:: f(x) = \\ frac{L}{1+exp^{-k(x-x0)}}
231+ .. math::
232+
233+ f(x) = \frac{L}{1+e^{-k(x-x0)}}
235234
236235 For more information: https://en.wikipedia.org/wiki/Logistic_function
237236
@@ -240,7 +239,7 @@ def from_sigmoid_impf(
240239
241240 Parameters
242241 ----------
243- intensity: tuple(float, float, float)
242+ intensity : tuple(float, float, float)
244243 tuple of 3 intensity numbers along np.arange(min, max, step)
245244 L : float
246245 "top" of sigmoid
@@ -273,3 +272,88 @@ def set_sigmoid_impf(self, *args, **kwargs):
273272 LOGGER .warning ("The use of ImpactFunc.set_sigmoid_impf is deprecated."
274273 "Use ImpactFunc.from_sigmoid_impf instead." )
275274 self .__dict__ = ImpactFunc .from_sigmoid_impf (* args , ** kwargs ).__dict__
275+
276+ @classmethod
277+ def from_poly_s_shape (
278+ cls ,
279+ intensity : tuple [float , float , int ],
280+ threshold : float ,
281+ half_point : float ,
282+ scale : float ,
283+ exponent : float ,
284+ haz_type : str ,
285+ impf_id : int = 1 ,
286+ ** kwargs ):
287+ r"""S-shape polynomial impact function hinging on four parameter.
288+
289+ .. math::
290+
291+ f(I) = \frac{\textrm{luk}(I)^{\textrm{exponent}}}{
292+ 1 + \textrm{luk}(I)^{\textrm{exponent}}
293+ }
294+ \cdot \textrm{scale} \\
295+ \textrm{luk}(I) = \frac{\max[I - \textrm{threshold}, 0]}{
296+ \textrm{half_point} - \textrm{threshold}
297+ }
298+
299+ This function is inspired by Emanuel et al. (2011)
300+ https://doi.org/10.1175/WCAS-D-11-00007.1
301+
302+ This method only specifies mdd, and paa = 1 for all intensities.
303+
304+ Parameters
305+ ----------
306+ intensity : tuple(float, float, float)
307+ tuple of 3 intensity numbers along np.linsapce(min, max, num)
308+ threshold : float
309+ Intensity threshold below which there is no impact.
310+ In general choose threshold > 0 for computational efficiency
311+ of impacts.
312+ half_point : float
313+ Intensity at which 50% of maximum impact is expected.
314+ If half_point <= threshold, mdd = 0 (and f(I)=0) for all
315+ intensities.
316+ scale : float
317+ Multiplicative factor for the whole function. Typically,
318+ this sets the maximum value at large intensities.
319+ exponent: float
320+ Exponent of the polynomial. Value must be exponent >= 0.
321+ Emanuel et al. (2011) uses the value 3.
322+ haz_type: str
323+ Reference string for the hazard (e.g., 'TC', 'RF', 'WS', ...)
324+ impf_id : int, optional, default=1
325+ Impact function id
326+ kwargs :
327+ keyword arguments passed to ImpactFunc()
328+
329+ Raises
330+ ------
331+ ValueError : if exponent <= 0
332+
333+ Returns
334+ -------
335+ impf : climada.entity.impact_funcs.ImpactFunc
336+ s-shaped polynomial impact function
337+ """
338+ if exponent < 0 :
339+ raise ValueError ('Exponent value must larger than 0' )
340+
341+ inten = np .linspace (* intensity )
342+
343+ if threshold >= half_point :
344+ mdd = np .zeros_like (inten )
345+ else :
346+ luk = (inten - threshold ) / (half_point - threshold )
347+ luk [luk < 0 ] = 0
348+ mdd = scale * luk ** exponent / (1 + luk ** exponent )
349+ paa = np .ones_like (inten )
350+
351+ impf = cls (
352+ haz_type = haz_type ,
353+ id = impf_id ,
354+ intensity = inten ,
355+ paa = paa ,
356+ mdd = mdd ,
357+ ** kwargs
358+ )
359+ return impf
0 commit comments