skinoptics 0.0.1b8__py3-none-any.whl → 0.0.2__py3-none-any.whl

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.
skinoptics/utils.py CHANGED
@@ -1,420 +1,419 @@
1
- '''
2
- | SkinOptics
3
- | Copyright (C) 2024-2025 Victor Lima
4
-
5
- | This program is free software: you can redistribute it and/or modify
6
- | it under the terms of the GNU General Public License as published by
7
- | the Free Software Foundation, either version 3 of the License, or
8
- | (at your option) any later version.
9
-
10
- | This program is distributed in the hope that it will be useful,
11
- | but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- | GNU General Public License for more details.
14
-
15
- | You should have received a copy of the GNU General Public License
16
- | along with this program. If not, see <https://www.gnu.org/licenses/>.
17
-
18
- | Victor Lima
19
- | victorporto\@ifsc.usp.br
20
- | victor.lima\@ufscar.br
21
- | victorportog.github.io
22
-
23
- | Release date:
24
- | October 2024
25
- | Last modification:
26
- | October 2024
27
-
28
- | References:
29
-
30
- | [WSS13] Wyman, Sloan & Shirley 2013.
31
- | Simple Analytic Approximations to the CIE XYZ Color Matching Functions
32
- | https://jcgt.org/published/0002/02/01/
33
- '''
34
-
35
- import numpy as np
36
-
37
- def dict_from_arrays(array_keys, array_values):
38
- r'''
39
- Construct a dictionary from two arrays.
40
-
41
- :param array_keys: array with the dictionary keys
42
- :type array_keys: np.ndarray
43
-
44
- :param array_values: array with the dictionary values
45
- :type array_values: np.ndarray
46
-
47
- :return: - **dict** (*dictionary*) – dictionary constructed with the two arrays
48
- '''
49
-
50
- return {array_keys[i]: array_values[i] for i in range(len(array_keys))}
51
-
52
- def circle(r, xc, yc, theta_i = 0., theta_f = 360., n_points = 1000):
53
- r'''
54
- The points that compose a circle.
55
-
56
- :math:`\left \{ \begin{matrix}
57
- x = r \cos \theta + x_c\\
58
- y = r \sin \theta + y_c
59
- \end{matrix} \right.`
60
-
61
- :param r: radius
62
- :type r: float
63
-
64
- :param xc: center x-coordinate
65
- :type xc: float
66
-
67
- :param yc: center y-coordinate
68
- :type yc: float
69
-
70
- :param theta_i: initial angle [degrees] (default to 0.)
71
- :type theta_i: float
72
-
73
- :param theta_f: final angle [degrees] (default to 360.)
74
- :type theta_f: float
75
-
76
- :param n_points: number of points (default to 1000)
77
- :type n_points: int
78
-
79
- :return: - **x** (*np.ndarray*) – x-coordinantes of a circle
80
-
81
- - **y** (*np.ndarray*) – y-coordinantes of a circle
82
- '''
83
-
84
- theta = np.linspace(theta_i*np.pi/180., theta_f*np.pi/180., n_points)
85
- x = r*np.cos(theta) + xc
86
- y = r*np.sin(theta) + yc
87
-
88
- return x, y
89
-
90
- def linear(x, a, b):
91
- r'''
92
- The linear function.
93
-
94
- :math:`f(x) = ax + b`
95
-
96
- :param x: function variable
97
- :type x: float or np.ndarray
98
-
99
- :param a: slope
100
- :type a: float
101
-
102
- :param b: y-intercept
103
- :type b: float
104
-
105
- :return: - **f** (*float or np.ndarray*) – evaluated linear function
106
- '''
107
-
108
- return a*x + b
109
-
110
- def quadratic(x, a, b, c):
111
- r'''
112
- The quadratic function.
113
-
114
- :math:`f(x) = ax^2 + bx + c`
115
-
116
- :param x: function variable
117
- :type x: float or np.ndarray
118
-
119
- :param a: function constant
120
- :type a: float
121
-
122
- :param b: function constant
123
- :type b: float
124
-
125
- :param c: function constant
126
- :type c: float
127
-
128
- :return: - **f** (*float or np.ndarray*) – evaluated quadratic function
129
- '''
130
-
131
- return a*np.power(x, 2, dtype = 'float64') + b*x + c
132
-
133
- def cubic(x, a, b, c, d):
134
- r'''
135
- The cubic function.
136
-
137
- :math:`f(x) = ax^3 + bx^2 + cx + d`
138
-
139
- :param x: function variable
140
- :type x: float or np.ndarray
141
-
142
- :param a: function constant
143
- :type a: float
144
-
145
- :param b: function constant
146
- :type b: float
147
-
148
- :param c: function constant
149
- :type c: float
150
-
151
- :param d: function constant
152
- :type d: float
153
-
154
- :return: - **f** (*float or np.ndarray*) – evaluated cubic function
155
- '''
156
-
157
- return a*np.power(x, 3, dtype = 'float64') + b*np.power(x, 2, dtype = 'float64') + c*x + d
158
-
159
- def exp_decay(x, a, b, c):
160
- r'''
161
- The exponential decay function.
162
-
163
- :math:`f(x) = a \mbox{ exp}(-|b|x) + c`
164
-
165
- :param x: function variable
166
- :type x: float or np.ndarray
167
-
168
- :param a: function constant
169
- :type a: float
170
-
171
- :param b: function constant
172
- :type b: float
173
-
174
- :param c: function constant
175
- :type c: float
176
-
177
- :return: - **f** (*float or np.ndarray*) – evaluated exponential decay function
178
- '''
179
-
180
- return a*np.exp(-np.abs(b)*x) + c
181
-
182
- def biexp_decay(x, a, b, c, d, e):
183
- r'''
184
- The biexponential decay function.
185
-
186
- :math:`f(x) = a\mbox{ exp}(-|b|x) + c \mbox{ exp}(-|d|x) + e`
187
-
188
- :param x: function variable
189
- :type x: float or np.ndarray
190
-
191
- :param a: function constant
192
- :type a: float
193
-
194
- :param b: function constant
195
- :type b: float
196
-
197
- :param c: function constant
198
- :type c: float
199
-
200
- :param d: function constant
201
- :type d: float
202
-
203
- :param e: function constant
204
- :type e: float
205
-
206
- :return: - **f** (*float or np.ndarray*) – evaluated biexponential decay function
207
- '''
208
-
209
- return a*np.exp(-np.abs(b)*x) + c*np.exp(-np.abs(d)*x) + e
210
-
211
- def exp_decay_inc_form(x, a, b, c):
212
- r'''
213
- The increasing form of the exponential decay function.
214
-
215
- :math:`f(x) = a \mbox{ [}1 - \mbox{exp}(-|b|x)] + c`
216
-
217
- :param x: function variable
218
- :type x: float or np.ndarray
219
-
220
- :param a: function constant
221
- :type a: float
222
-
223
- :param b: function constant
224
- :type b: float
225
-
226
- :param c: function constant
227
- :type c: float
228
-
229
- :return: - **f** (*float or np.ndarray*) – evaluated exponential decay (increasing form) function
230
- '''
231
-
232
- return a*(1 - np.exp(-np.abs(b)*x)) + c
233
-
234
- def natural_log(x, a, b, c):
235
- r'''
236
- The natural logarithm function.
237
-
238
- :math:`f(x) = a \mbox{ ln}(x + b) + c`
239
-
240
- :param x: function variable
241
- :type x: float or np.ndarray
242
-
243
- :param a: function constant
244
- :type a: float
245
-
246
- :param b: function constant
247
- :type b: float
248
-
249
- :param c: function constant
250
- :type c: float
251
-
252
- :return: - **f** (*float or np.ndarray*) – evaluated natural logarithm function
253
- '''
254
-
255
- return a*np.log(x + b) + c
256
-
257
- def gaussian(x, a, b, c):
258
- r'''
259
- The Gaussian function.
260
-
261
- :math:`f(x) = a \mbox{ exp}\left[-\frac{1}{2}\frac{(x - b)^2}{c^2}\right]`
262
-
263
- :param x: function variable
264
- :type x: float or np.ndarray
265
-
266
- :param a: function constant
267
- :type a: float
268
-
269
- :param b: function constant
270
- :type b: float
271
-
272
- :param c: function constant
273
- :type c: float
274
-
275
- :return: - **f** (*float or np.ndarray*) – evaluated Gaussian function
276
- '''
277
-
278
- return a*np.exp(-1./2.*(x - b)**2/c**2)
279
-
280
- def heaviside(x):
281
- r'''
282
- The Heaviside step function.
283
-
284
- :math:`H(x) =
285
- \left \{ \begin{matrix}
286
- 0, & \mbox{if } g < 0 \\
287
- \frac{1}{2}, & \mbox{if } g = 0 \\
288
- 1, & \mbox{if } g > 0 \\
289
- \end{matrix} \right.`
290
-
291
- :param x: function variable
292
- :type x: float or np.ndarray
293
-
294
- :return: - **H** (*float or np.ndarray*) – evaluated Heaviside step function
295
- '''
296
-
297
- if isinstance(x, np.ndarray) == True:
298
- H = np.zeros(len(x))
299
- for i in range(len(x)):
300
- if x[i] < 0.:
301
- H[i] = 0.
302
- elif x[i] == 0.:
303
- H[i] = 1./2.
304
- else:
305
- H[i] = 1.
306
- elif isinstance(x, (int, float)) == True:
307
- if x < 0.:
308
- H = 0.
309
- elif x == 0.:
310
- H = 1./2.
311
- else:
312
- H = 1.
313
- else:
314
- msg = 'x must be int, float or np.ndarray.'
315
- raise Exception(msg)
316
-
317
- return H
318
-
319
- def mod_gaussian_Wyman(x, a, b, c, d):
320
- r'''
321
- | The modified Gaussian function needed to calculate some analytical functions
322
- | from Wyman, Sloan & Shirley 2013 [WSS13] (see function :meth:`skinoptics.colors.cmfs`).
323
-
324
- :math:`f(x) = a \mbox{ exp}\left\{-d \mbox{ } \left[\mbox{ ln}\left(\frac{x - b}{c}\right)\right]^2\right\}`
325
-
326
- :param x: function variable
327
- :type x: float or np.ndarray
328
-
329
- :param a: function constant
330
- :type a: float
331
-
332
- :param b: function constant
333
- :type b: float
334
-
335
- :param c: function constant
336
- :type c: float
337
-
338
- :param d: function constant
339
- :type d: float
340
-
341
- :return: - **f** (*float or np.ndarray*) – evaluated function
342
- '''
343
-
344
- return a*np.exp(-d*(np.log((x - b)/c))**2)
345
-
346
- def selector_function_Wyman(x, y, z):
347
- r'''
348
- | The selector function needed to calculate some analytical functions
349
- | from Wyman, Sloan & Shirley 2013 [WSS13] (see function :meth:`skinoptics.colors.cmfs`).
350
-
351
- :math:`S(x,y,z) = y \mbox{ } (1 - H(x)) + z \mbox{ } H(x)`
352
-
353
- in which :math:`H(x)` is the Heaviside step function :meth:`skinoptics.utils.heaviside`.
354
-
355
- :param x: function variable
356
- :type x: float or np.ndarray
357
-
358
- :param y: function variable
359
- :type y: float or np.ndarray
360
-
361
- :param z: function variable
362
- :type z: float or np.ndarray
363
-
364
- :return: - **S** (*float or np.ndarray*) – evaluated selector function
365
- '''
366
-
367
- return y*(1 - heaviside(x)) + z*heaviside(x)
368
-
369
- def piecewise_gaussian_Wyman(x, a, b, c, d):
370
- r'''
371
- | The piecewise Gaussian function needed to calculate some analytical functions
372
- | from Wyman, Sloan & Shirley 2013 [WSS13] (see function :meth:`skinoptics.colors.cmfs`).
373
-
374
- :math:`f(x) = a \mbox{ exp}\left\{-\frac{1}{2}[(x - b)\mbox{ }S(x - b \mbox{, }c \mbox{, }d)]^2\right\}`
375
-
376
- :param x: function variable
377
- :type x: float or np.ndarray
378
-
379
- :param a: function constant
380
- :type a: float
381
-
382
- :param b: function constant
383
- :type b: float
384
-
385
- :param c: function constant
386
- :type c: float
387
-
388
- :param d: function constant
389
- :type d: float
390
-
391
- :return: - **f** (*float or np.ndarray*) – evaluated function
392
- '''
393
-
394
- return a*np.exp(-1./2.*((x - b)*selector_function_Wyman(x - b, c, d))**2)
395
-
396
- def hyperbolic_cossine(x, a, b, c, d):
397
- r'''
398
- The hyperbolic cossine function (with four parameters).
399
-
400
- :math:`f(x) = a \mbox{ cosh}\left[\frac{(x - b)}{c}\right] + d`
401
-
402
- :param x: function variable
403
- :type x: float or np.ndarray
404
-
405
- :param a: function constant
406
- :type a: float
407
-
408
- :param b: function constant
409
- :type b: float
410
-
411
- :param c: function constant
412
- :type c: float
413
-
414
- :param d: function constant
415
- :type d: float
416
-
417
- :return: - **f** (*float or np.ndarray*) – evaluated hyperbolic cossine function
418
- '''
419
-
420
- return a*np.cosh((x - b)/c) + d
1
+ '''
2
+ | SkinOptics
3
+ | Copyright (C) 2024-2025 Victor Lima
4
+
5
+ | This program is free software: you can redistribute it and/or modify
6
+ | it under the terms of the GNU General Public License as published by
7
+ | the Free Software Foundation, either version 3 of the License, or
8
+ | (at your option) any later version.
9
+
10
+ | This program is distributed in the hope that it will be useful,
11
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ | GNU General Public License for more details.
14
+
15
+ | You should have received a copy of the GNU General Public License
16
+ | along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ | Victor Lima
19
+ | victor.lima\@ufscar.br
20
+ | victorportog.github.io
21
+
22
+ | Release date:
23
+ | October 2024
24
+ | Last modification:
25
+ | October 2024
26
+
27
+ | References:
28
+
29
+ | [WSS13] Wyman, Sloan & Shirley 2013.
30
+ | Simple Analytic Approximations to the CIE XYZ Color Matching Functions
31
+ | https://jcgt.org/published/0002/02/01/
32
+ '''
33
+
34
+ import numpy as np
35
+
36
+ def dict_from_arrays(array_keys, array_values):
37
+ r'''
38
+ Construct a dictionary from two arrays.
39
+
40
+ :param array_keys: array with the dictionary keys
41
+ :type array_keys: np.ndarray
42
+
43
+ :param array_values: array with the dictionary values
44
+ :type array_values: np.ndarray
45
+
46
+ :return: - **dict** (*dictionary*) – dictionary constructed with the two arrays
47
+ '''
48
+
49
+ return {array_keys[i]: array_values[i] for i in range(len(array_keys))}
50
+
51
+ def circle(r, xc, yc, theta_i = 0., theta_f = 360., n_points = 1000):
52
+ r'''
53
+ The points that compose a circle.
54
+
55
+ :math:`\left \{ \begin{matrix}
56
+ x = r \cos \theta + x_c\\
57
+ y = r \sin \theta + y_c
58
+ \end{matrix} \right.`
59
+
60
+ :param r: radius
61
+ :type r: float
62
+
63
+ :param xc: center x-coordinate
64
+ :type xc: float
65
+
66
+ :param yc: center y-coordinate
67
+ :type yc: float
68
+
69
+ :param theta_i: initial angle [degrees] (default to 0.)
70
+ :type theta_i: float
71
+
72
+ :param theta_f: final angle [degrees] (default to 360.)
73
+ :type theta_f: float
74
+
75
+ :param n_points: number of points (default to 1000)
76
+ :type n_points: int
77
+
78
+ :return: - **x** (*np.ndarray*) – x-coordinantes of a circle
79
+
80
+ - **y** (*np.ndarray*) – y-coordinantes of a circle
81
+ '''
82
+
83
+ theta = np.linspace(theta_i*np.pi/180., theta_f*np.pi/180., n_points)
84
+ x = r*np.cos(theta) + xc
85
+ y = r*np.sin(theta) + yc
86
+
87
+ return x, y
88
+
89
+ def linear(x, a, b):
90
+ r'''
91
+ The linear function.
92
+
93
+ :math:`f(x) = ax + b`
94
+
95
+ :param x: function variable
96
+ :type x: float or np.ndarray
97
+
98
+ :param a: slope
99
+ :type a: float
100
+
101
+ :param b: y-intercept
102
+ :type b: float
103
+
104
+ :return: - **f** (*float or np.ndarray*) – evaluated linear function
105
+ '''
106
+
107
+ return a*x + b
108
+
109
+ def quadratic(x, a, b, c):
110
+ r'''
111
+ The quadratic function.
112
+
113
+ :math:`f(x) = ax^2 + bx + c`
114
+
115
+ :param x: function variable
116
+ :type x: float or np.ndarray
117
+
118
+ :param a: function constant
119
+ :type a: float
120
+
121
+ :param b: function constant
122
+ :type b: float
123
+
124
+ :param c: function constant
125
+ :type c: float
126
+
127
+ :return: - **f** (*float or np.ndarray*) – evaluated quadratic function
128
+ '''
129
+
130
+ return a*np.power(x, 2, dtype = 'float64') + b*x + c
131
+
132
+ def cubic(x, a, b, c, d):
133
+ r'''
134
+ The cubic function.
135
+
136
+ :math:`f(x) = ax^3 + bx^2 + cx + d`
137
+
138
+ :param x: function variable
139
+ :type x: float or np.ndarray
140
+
141
+ :param a: function constant
142
+ :type a: float
143
+
144
+ :param b: function constant
145
+ :type b: float
146
+
147
+ :param c: function constant
148
+ :type c: float
149
+
150
+ :param d: function constant
151
+ :type d: float
152
+
153
+ :return: - **f** (*float or np.ndarray*) – evaluated cubic function
154
+ '''
155
+
156
+ return a*np.power(x, 3, dtype = 'float64') + b*np.power(x, 2, dtype = 'float64') + c*x + d
157
+
158
+ def exp_decay(x, a, b, c):
159
+ r'''
160
+ The exponential decay function.
161
+
162
+ :math:`f(x) = a \mbox{ exp}(-|b|x) + c`
163
+
164
+ :param x: function variable
165
+ :type x: float or np.ndarray
166
+
167
+ :param a: function constant
168
+ :type a: float
169
+
170
+ :param b: function constant
171
+ :type b: float
172
+
173
+ :param c: function constant
174
+ :type c: float
175
+
176
+ :return: - **f** (*float or np.ndarray*) – evaluated exponential decay function
177
+ '''
178
+
179
+ return a*np.exp(-np.abs(b)*x) + c
180
+
181
+ def biexp_decay(x, a, b, c, d, e):
182
+ r'''
183
+ The biexponential decay function.
184
+
185
+ :math:`f(x) = a\mbox{ exp}(-|b|x) + c \mbox{ exp}(-|d|x) + e`
186
+
187
+ :param x: function variable
188
+ :type x: float or np.ndarray
189
+
190
+ :param a: function constant
191
+ :type a: float
192
+
193
+ :param b: function constant
194
+ :type b: float
195
+
196
+ :param c: function constant
197
+ :type c: float
198
+
199
+ :param d: function constant
200
+ :type d: float
201
+
202
+ :param e: function constant
203
+ :type e: float
204
+
205
+ :return: - **f** (*float or np.ndarray*) – evaluated biexponential decay function
206
+ '''
207
+
208
+ return a*np.exp(-np.abs(b)*x) + c*np.exp(-np.abs(d)*x) + e
209
+
210
+ def exp_decay_inc_form(x, a, b, c):
211
+ r'''
212
+ The increasing form of the exponential decay function.
213
+
214
+ :math:`f(x) = a \mbox{ [}1 - \mbox{exp}(-|b|x)] + c`
215
+
216
+ :param x: function variable
217
+ :type x: float or np.ndarray
218
+
219
+ :param a: function constant
220
+ :type a: float
221
+
222
+ :param b: function constant
223
+ :type b: float
224
+
225
+ :param c: function constant
226
+ :type c: float
227
+
228
+ :return: - **f** (*float or np.ndarray*) – evaluated exponential decay (increasing form) function
229
+ '''
230
+
231
+ return a*(1 - np.exp(-np.abs(b)*x)) + c
232
+
233
+ def natural_log(x, a, b, c):
234
+ r'''
235
+ The natural logarithm function.
236
+
237
+ :math:`f(x) = a \mbox{ ln}(x + b) + c`
238
+
239
+ :param x: function variable
240
+ :type x: float or np.ndarray
241
+
242
+ :param a: function constant
243
+ :type a: float
244
+
245
+ :param b: function constant
246
+ :type b: float
247
+
248
+ :param c: function constant
249
+ :type c: float
250
+
251
+ :return: - **f** (*float or np.ndarray*) – evaluated natural logarithm function
252
+ '''
253
+
254
+ return a*np.log(x + b) + c
255
+
256
+ def gaussian(x, a, b, c):
257
+ r'''
258
+ The Gaussian function.
259
+
260
+ :math:`f(x) = a \mbox{ exp}\left[-\frac{1}{2}\frac{(x - b)^2}{c^2}\right]`
261
+
262
+ :param x: function variable
263
+ :type x: float or np.ndarray
264
+
265
+ :param a: function constant
266
+ :type a: float
267
+
268
+ :param b: function constant
269
+ :type b: float
270
+
271
+ :param c: function constant
272
+ :type c: float
273
+
274
+ :return: - **f** (*float or np.ndarray*) – evaluated Gaussian function
275
+ '''
276
+
277
+ return a*np.exp(-1./2.*(x - b)**2/c**2)
278
+
279
+ def heaviside(x):
280
+ r'''
281
+ The Heaviside step function.
282
+
283
+ :math:`H(x) =
284
+ \left \{ \begin{matrix}
285
+ 0, & \mbox{if } g < 0 \\
286
+ \frac{1}{2}, & \mbox{if } g = 0 \\
287
+ 1, & \mbox{if } g > 0 \\
288
+ \end{matrix} \right.`
289
+
290
+ :param x: function variable
291
+ :type x: float or np.ndarray
292
+
293
+ :return: - **H** (*float or np.ndarray*) – evaluated Heaviside step function
294
+ '''
295
+
296
+ if isinstance(x, np.ndarray) == True:
297
+ H = np.zeros(len(x))
298
+ for i in range(len(x)):
299
+ if x[i] < 0.:
300
+ H[i] = 0.
301
+ elif x[i] == 0.:
302
+ H[i] = 1./2.
303
+ else:
304
+ H[i] = 1.
305
+ elif isinstance(x, (int, float)) == True:
306
+ if x < 0.:
307
+ H = 0.
308
+ elif x == 0.:
309
+ H = 1./2.
310
+ else:
311
+ H = 1.
312
+ else:
313
+ msg = 'x must be int, float or np.ndarray.'
314
+ raise Exception(msg)
315
+
316
+ return H
317
+
318
+ def mod_gaussian_Wyman(x, a, b, c, d):
319
+ r'''
320
+ | The modified Gaussian function needed to calculate some analytical functions
321
+ | from Wyman, Sloan & Shirley 2013 [WSS13] (see function :meth:`skinoptics.colors.cmfs`).
322
+
323
+ :math:`f(x) = a \mbox{ exp}\left\{-d \mbox{ } \left[\mbox{ ln}\left(\frac{x - b}{c}\right)\right]^2\right\}`
324
+
325
+ :param x: function variable
326
+ :type x: float or np.ndarray
327
+
328
+ :param a: function constant
329
+ :type a: float
330
+
331
+ :param b: function constant
332
+ :type b: float
333
+
334
+ :param c: function constant
335
+ :type c: float
336
+
337
+ :param d: function constant
338
+ :type d: float
339
+
340
+ :return: - **f** (*float or np.ndarray*) – evaluated function
341
+ '''
342
+
343
+ return a*np.exp(-d*(np.log((x - b)/c))**2)
344
+
345
+ def selector_function_Wyman(x, y, z):
346
+ r'''
347
+ | The selector function needed to calculate some analytical functions
348
+ | from Wyman, Sloan & Shirley 2013 [WSS13] (see function :meth:`skinoptics.colors.cmfs`).
349
+
350
+ :math:`S(x,y,z) = y \mbox{ } (1 - H(x)) + z \mbox{ } H(x)`
351
+
352
+ in which :math:`H(x)` is the Heaviside step function :meth:`skinoptics.utils.heaviside`.
353
+
354
+ :param x: function variable
355
+ :type x: float or np.ndarray
356
+
357
+ :param y: function variable
358
+ :type y: float or np.ndarray
359
+
360
+ :param z: function variable
361
+ :type z: float or np.ndarray
362
+
363
+ :return: - **S** (*float or np.ndarray*) – evaluated selector function
364
+ '''
365
+
366
+ return y*(1 - heaviside(x)) + z*heaviside(x)
367
+
368
+ def piecewise_gaussian_Wyman(x, a, b, c, d):
369
+ r'''
370
+ | The piecewise Gaussian function needed to calculate some analytical functions
371
+ | from Wyman, Sloan & Shirley 2013 [WSS13] (see function :meth:`skinoptics.colors.cmfs`).
372
+
373
+ :math:`f(x) = a \mbox{ exp}\left\{-\frac{1}{2}[(x - b)\mbox{ }S(x - b \mbox{, }c \mbox{, }d)]^2\right\}`
374
+
375
+ :param x: function variable
376
+ :type x: float or np.ndarray
377
+
378
+ :param a: function constant
379
+ :type a: float
380
+
381
+ :param b: function constant
382
+ :type b: float
383
+
384
+ :param c: function constant
385
+ :type c: float
386
+
387
+ :param d: function constant
388
+ :type d: float
389
+
390
+ :return: - **f** (*float or np.ndarray*) – evaluated function
391
+ '''
392
+
393
+ return a*np.exp(-1./2.*((x - b)*selector_function_Wyman(x - b, c, d))**2)
394
+
395
+ def hyperbolic_cossine(x, a, b, c, d):
396
+ r'''
397
+ The hyperbolic cossine function (with four parameters).
398
+
399
+ :math:`f(x) = a \mbox{ cosh}\left[\frac{(x - b)}{c}\right] + d`
400
+
401
+ :param x: function variable
402
+ :type x: float or np.ndarray
403
+
404
+ :param a: function constant
405
+ :type a: float
406
+
407
+ :param b: function constant
408
+ :type b: float
409
+
410
+ :param c: function constant
411
+ :type c: float
412
+
413
+ :param d: function constant
414
+ :type d: float
415
+
416
+ :return: - **f** (*float or np.ndarray*) – evaluated hyperbolic cossine function
417
+ '''
418
+
419
+ return a*np.cosh((x - b)/c) + d