Skip to content

Commit d1e6bc9

Browse files
committed
Add "power" fitting code.
1 parent 05926bd commit d1e6bc9

File tree

1 file changed

+141
-10
lines changed

1 file changed

+141
-10
lines changed

notebooks/gamut_mapping_compression_functions_01.ipynb

Lines changed: 141 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"import matplotlib.pyplot as plt\n",
6464
"import numpy as np\n",
6565
"import os\n",
66-
"from scipy.optimize import fsolve\n",
66+
"import scipy\n",
6767
"\n",
6868
"COLOUR_STYLE = colour.plotting.colour_style()\n",
6969
"COLOUR_STYLE.update({\n",
@@ -101,7 +101,7 @@
101101
"def tanh_compression_function(x, a=0.8, b=1 - 0.8):\n",
102102
" x = colour.utilities.as_float_array(x)\n",
103103
"\n",
104-
" return np.where(x > a, (a + b * np.tanh((x - a) / b)), x)\n",
104+
" return np.where(x > a, a + b * np.tanh((x - a) / b), x)\n",
105105
"\n",
106106
"\n",
107107
"def atan_compression_function(x, a=0.8, b=1 - 0.8):\n",
@@ -110,6 +110,12 @@
110110
" return np.where(x > a, a + b * 2 / np.pi * np.arctan(((np.pi / 2) * (x - a)) / b), x)\n",
111111
"\n",
112112
"\n",
113+
"def power_compression_function(x, a=0.8, b=1 - 0.8, p=2.0):\n",
114+
" x = colour.utilities.as_float_array(x)\n",
115+
"\n",
116+
" return np.where(x > a, a + (((x - a) / b) / np.power(1 + np.power((x - a) / b, p), 1.0/p)) * b, x)\n",
117+
"\n",
118+
"\n",
113119
"def simple_compression_function(x, a=0.8, b=1 - 0.8):\n",
114120
" x = colour.utilities.as_float_array(x)\n",
115121
"\n",
@@ -128,7 +134,7 @@
128134
{
129135
"data": {
130136
"application/vnd.jupyter.widget-view+json": {
131-
"model_id": "0682438225404555bcfc31ffbf717986",
137+
"model_id": "ec62041dbc1b4fa1968fe8f0116534f8",
132138
"version_major": 2,
133139
"version_minor": 0
134140
},
@@ -147,6 +153,8 @@
147153
" 'd/dx(tanh)': lambda x: derivative(x, tanh_compression_function),\n",
148154
" 'atan': atan_compression_function,\n",
149155
" 'd/dx(atan)': lambda x: derivative(x, atan_compression_function),\n",
156+
" 'power': power_compression_function,\n",
157+
" 'd/dx(power)': lambda x: derivative(x, power_compression_function),\n",
150158
" 'simple': simple_compression_function,\n",
151159
" 'd/dx(simple)': lambda x: derivative(x, simple_compression_function),\n",
152160
" },\n",
@@ -177,6 +185,13 @@
177185
" {\n",
178186
" 'c': 'b'\n",
179187
" },\n",
188+
" {\n",
189+
" 'c': 'y',\n",
190+
" 'linestyle': 'dashdot'\n",
191+
" },\n",
192+
" {\n",
193+
" 'c': 'y'\n",
194+
" },\n",
180195
" ]\n",
181196
" },\n",
182197
");"
@@ -186,18 +201,26 @@
186201
"cell_type": "markdown",
187202
"metadata": {},
188203
"source": [
189-
"## Solving Intersection with Y = 1"
204+
"## TANH - Power Fitting"
190205
]
191206
},
192207
{
193208
"cell_type": "code",
194209
"execution_count": 5,
195210
"metadata": {},
196211
"outputs": [
212+
{
213+
"name": "stdout",
214+
"output_type": "stream",
215+
"text": [
216+
"[ 0.65953861 0.34051662 4.6993435 ]\n",
217+
"7.53150995846e-08\n"
218+
]
219+
},
197220
{
198221
"data": {
199222
"application/vnd.jupyter.widget-view+json": {
200-
"model_id": "5026406f51784d0887ab0f01eeec1781",
223+
"model_id": "906062bed9f244d1892820a200f3e4c2",
201224
"version_major": 2,
202225
"version_minor": 0
203226
},
@@ -210,14 +233,115 @@
210233
}
211234
],
212235
"source": [
213-
"X, A, I = 65504, 0.8, 1\n",
236+
"SAMPLES = np.linspace(0, 8, 1000)\n",
237+
"TANH_SAMPLES = tanh_compression_function(SAMPLES)\n",
238+
"\n",
239+
"POPT, PCOV = scipy.optimize.curve_fit(\n",
240+
" power_compression_function, SAMPLES, TANH_SAMPLES, maxfev=50000)\n",
241+
"\n",
242+
"print(POPT)\n",
243+
"print(\n",
244+
" colour.utilities.metric_mse(TANH_SAMPLES,\n",
245+
" power_compression_function(SAMPLES, *POPT)))\n",
246+
"\n",
247+
"colour.plotting.artist()\n",
248+
"plt.plot(SAMPLES, TANH_SAMPLES, 'r', label='tanh')\n",
249+
"plt.plot(SAMPLES, power_compression_function(SAMPLES, *POPT), 'g', label='power')\n",
250+
"plt.legend()\n",
251+
"plt.show()"
252+
]
253+
},
254+
{
255+
"cell_type": "markdown",
256+
"metadata": {},
257+
"source": [
258+
"## ATAN - Power Fitting"
259+
]
260+
},
261+
{
262+
"cell_type": "code",
263+
"execution_count": 6,
264+
"metadata": {},
265+
"outputs": [
266+
{
267+
"name": "stdout",
268+
"output_type": "stream",
269+
"text": [
270+
"[ 0.83715264 0.16187046 1.18238345]\n",
271+
"9.2282913999e-08\n"
272+
]
273+
},
274+
{
275+
"data": {
276+
"application/vnd.jupyter.widget-view+json": {
277+
"model_id": "c323d4940f444fc392aa7e131e2d658a",
278+
"version_major": 2,
279+
"version_minor": 0
280+
},
281+
"text/plain": [
282+
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
283+
]
284+
},
285+
"metadata": {},
286+
"output_type": "display_data"
287+
}
288+
],
289+
"source": [
290+
"ATAN_SAMPLES = atan_compression_function(SAMPLES)\n",
291+
"\n",
292+
"POPT, PCOV = scipy.optimize.curve_fit(\n",
293+
" power_compression_function, SAMPLES, ATAN_SAMPLES, maxfev=50000)\n",
294+
"\n",
295+
"print(POPT)\n",
296+
"print(\n",
297+
" colour.utilities.metric_mse(ATAN_SAMPLES,\n",
298+
" power_compression_function(SAMPLES, *POPT)))\n",
299+
"\n",
300+
"colour.plotting.artist()\n",
301+
"plt.plot(SAMPLES, ATAN_SAMPLES, 'r', label='atan')\n",
302+
"plt.plot(SAMPLES, power_compression_function(SAMPLES, *POPT), 'g', label='power')\n",
303+
"plt.legend()\n",
304+
"plt.show()"
305+
]
306+
},
307+
{
308+
"cell_type": "markdown",
309+
"metadata": {},
310+
"source": [
311+
"## Solving Intersection with Y = 1"
312+
]
313+
},
314+
{
315+
"cell_type": "code",
316+
"execution_count": 7,
317+
"metadata": {},
318+
"outputs": [
319+
{
320+
"data": {
321+
"application/vnd.jupyter.widget-view+json": {
322+
"model_id": "f1e84e0006c64a139d748773fd8be653",
323+
"version_major": 2,
324+
"version_minor": 0
325+
},
326+
"text/plain": [
327+
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
328+
]
329+
},
330+
"metadata": {},
331+
"output_type": "display_data"
332+
}
333+
],
334+
"source": [
335+
"X, A, I = 1.2, 0.8, 1\n",
214336
"\n",
215337
"figure, axes = colour.plotting.plot_multi_functions(\n",
216338
" {\n",
217339
" 'tanh': lambda x: tanh_compression_function(\n",
218-
" x, A, fsolve(lambda x: tanh_compression_function(X, A, x) - I, 0.5)),\n",
340+
" x, A, scipy.optimize.fsolve(\n",
341+
" lambda x: tanh_compression_function(X, A, x) - I, 0.5)),\n",
219342
" 'simple': lambda x: simple_compression_function(\n",
220-
" x, A, fsolve(lambda x: simple_compression_function(X, A, x) - I, 0.5)),\n",
343+
" x, A, scipy.optimize.fsolve(\n",
344+
" lambda x: simple_compression_function(X, A, x) - I, 0.5)),\n",
221345
" },\n",
222346
" **{\n",
223347
" 'standalone': False,\n",
@@ -238,9 +362,16 @@
238362
"axes.scatter(X, I, c='b', s=50, zorder=4);"
239363
]
240364
},
365+
{
366+
"cell_type": "markdown",
367+
"metadata": {},
368+
"source": [
369+
"## Maximum Representable Value"
370+
]
371+
},
241372
{
242373
"cell_type": "code",
243-
"execution_count": 6,
374+
"execution_count": 8,
244375
"metadata": {},
245376
"outputs": [
246377
{
@@ -264,7 +395,7 @@
264395
},
265396
{
266397
"cell_type": "code",
267-
"execution_count": 7,
398+
"execution_count": 9,
268399
"metadata": {},
269400
"outputs": [
270401
{

0 commit comments

Comments
 (0)