{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Spectral Signal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Implementation" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [], "source": [ "import numpy as np\n", "from contextlib import contextmanager\n", "from copy import deepcopy\n", "from collections import OrderedDict\n", "from operator import (\n", " add, div, mul, pow, sub, iadd, idiv, imul, ipow, isub)\n", "from pandas import Series\n", "\n", "from colour import (\n", " CaseInsensitiveMapping,\n", " CubicSplineInterpolator,\n", " Extrapolator,\n", " LinearInterpolator,\n", " PchipInterpolator,\n", " SpragueInterpolator,\n", " as_numeric,\n", " is_numeric,\n", " tsplit,\n", " tstack,\n", " warning)\n", "\n", "OPERATORS = CaseInsensitiveMapping({\n", " 'Add': (add, iadd),\n", " 'Sub': (sub, isub),\n", " 'Mul' : (mul, imul),\n", " 'Div': (div, idiv),\n", " 'Pow': (pow, ipow)})\n", "\n", "# TODO: Is this the right name for the interpolator? Should we call the default\n", "# null value `default`?\n", "class NullInterpolator(object):\n", " \"\"\" \n", "\n", " Parameters\n", " ----------\n", " x : ndarray\n", " Independent :math:`x` variable values corresponding with :math:`y`\n", " variable.\n", " y : ndarray\n", " Dependent and already known :math:`y` variable values to\n", " interpolate.\n", "\n", " Methods\n", " -------\n", " __call__\n", "\n", "\n", " Examples\n", " --------\n", " \"\"\"\n", "\n", " def __init__(self,\n", " x=None,\n", " y=None,\n", " absolute_tolerance=10e-7,\n", " relative_tolerance=10e-7,\n", " default=np.nan):\n", " self.__x = None\n", " self.x = x\n", " self.__y = None\n", " self.y = y\n", " self.__absolute_tolerance = None\n", " self.absolute_tolerance = absolute_tolerance\n", " self.__relative_tolerance = None\n", " self.relative_tolerance = relative_tolerance\n", " self.__default = None\n", " self.default = default\n", "\n", " self.__validate_dimensions()\n", "\n", " @property\n", " def x(self):\n", " \"\"\"\n", " Property for **self.__x** private attribute.\n", "\n", " Returns\n", " -------\n", " array_like\n", " self.__x\n", " \"\"\"\n", "\n", " return self.__x\n", "\n", " @x.setter\n", " def x(self, value):\n", " \"\"\"\n", " Setter for **self.__x** private attribute.\n", "\n", " Parameters\n", " ----------\n", " value : array_like\n", " Attribute value.\n", " \"\"\"\n", "\n", " if value is not None:\n", " value = np.atleast_1d(value).astype(np.float_)\n", "\n", " assert value.ndim == 1, (\n", " '\"x\" independent variable must have exactly one dimension!')\n", "\n", " self.__x = value\n", "\n", " @property\n", " def y(self):\n", " \"\"\"\n", " Property for **self.__y** private attribute.\n", "\n", " Returns\n", " -------\n", " array_like\n", " self.__y\n", " \"\"\"\n", "\n", " return self.__y\n", "\n", " @y.setter\n", " def y(self, value):\n", " \"\"\"\n", " Setter for **self.__y** private attribute.\n", "\n", " Parameters\n", " ----------\n", " value : array_like\n", " Attribute value.\n", " \"\"\"\n", "\n", " if value is not None:\n", " value = np.atleast_1d(value).astype(np.float_)\n", "\n", " assert value.ndim == 1, (\n", " '\"y\" dependent variable must have exactly one dimension!')\n", "\n", " self.__y = value\n", "\n", " @property\n", " def relative_tolerance(self):\n", " \"\"\"\n", " Property for **self.__relative_tolerance** private attribute.\n", "\n", " Returns\n", " -------\n", " numeric\n", " self.__relative_tolerance\n", " \"\"\"\n", "\n", " return self.__relative_tolerance\n", "\n", " @relative_tolerance.setter\n", " def relative_tolerance(self, value):\n", " \"\"\"\n", " Setter for **self.__relative_tolerance** private attribute.\n", "\n", " Parameters\n", " ----------\n", " value : numeric\n", " Attribute value.\n", " \"\"\"\n", "\n", " if value is not None:\n", " assert is_numeric(value), (\n", " '\"relative_tolerance\" variable must be a \"numeric\"!')\n", "\n", " self.__relative_tolerance = value\n", "\n", " @property\n", " def absolute_tolerance(self):\n", " \"\"\"\n", " Property for **self.__absolute_tolerance** private attribute.\n", "\n", " Returns\n", " -------\n", " numeric\n", " self.__absolute_tolerance\n", " \"\"\"\n", "\n", " return self.__absolute_tolerance\n", "\n", " @absolute_tolerance.setter\n", " def absolute_tolerance(self, value):\n", " \"\"\"\n", " Setter for **self.__absolute_tolerance** private attribute.\n", "\n", " Parameters\n", " ----------\n", " value : numeric\n", " Attribute value.\n", " \"\"\"\n", "\n", " if value is not None:\n", " assert is_numeric(value), (\n", " '\"absolute_tolerance\" variable must be a \"numeric\"!')\n", "\n", " self.__absolute_tolerance = value\n", "\n", " @property\n", " def default(self):\n", " \"\"\"\n", " Property for **self.__default** private attribute.\n", "\n", " Returns\n", " -------\n", " numeric\n", " self.__default\n", " \"\"\"\n", "\n", " return self.__default\n", "\n", " @default.setter\n", " def default(self, value):\n", " \"\"\"\n", " Setter for **self.__default** private attribute.\n", "\n", " Parameters\n", " ----------\n", " value : numeric\n", " Attribute value.\n", " \"\"\"\n", "\n", " if value is not None:\n", " assert is_numeric(value), (\n", " '\"default\" variable must be a \"numeric\"!')\n", "\n", " self.__default = value\n", "\n", " def __call__(self, x):\n", " \"\"\"\n", " Evaluates the interpolatior at given point(s).\n", "\n", "\n", " Parameters\n", " ----------\n", " x : numeric or array_like\n", " Point(s) to evaluate the interpolant at.\n", "\n", " Returns\n", " -------\n", " float or ndarray\n", " Interpolated value(s).\n", " \"\"\"\n", "\n", " x = np.atleast_1d(x).astype(np.float_)\n", "\n", " xi = as_numeric(self.__evaluate(x))\n", "\n", " return xi\n", "\n", " def __evaluate(self, x):\n", " \"\"\"\n", " Performs the interpolator evaluation at given points.\n", "\n", " Parameters\n", " ----------\n", " x : ndarray\n", " Points to evaluate the interpolant at.\n", "\n", " Returns\n", " -------\n", " ndarray\n", " Interpolated points values.\n", " \"\"\"\n", "\n", " self.__validate_dimensions()\n", " self.__validate_interpolation_range(x)\n", "\n", " index = nearest_index(self.__x, x)\n", " values = self.__y[index]\n", " values[~np.isclose(self.__x[index],\n", " x,\n", " rtol=self.__absolute_tolerance,\n", " atol=self.__relative_tolerance)] = self.__default\n", "\n", " return values\n", "\n", " def __validate_dimensions(self):\n", " \"\"\"\n", " Validates variables dimensions to be the same.\n", " \"\"\"\n", "\n", " if len(self.__x) != len(self.__y):\n", " raise ValueError(\n", " ('\"x\" independent and \"y\" dependent variables have different '\n", " 'dimensions: \"{0}\", \"{1}\"').format(len(self.__x),\n", " len(self.__y)))\n", "\n", " def __validate_interpolation_range(self, x):\n", " \"\"\"\n", " Validates given point to be in interpolation range.\n", " \"\"\"\n", "\n", " below_interpolation_range = x < self.__x[0]\n", " above_interpolation_range = x > self.__x[-1]\n", "\n", " if below_interpolation_range.any():\n", " raise ValueError('\"{0}\" is below interpolation range.'.format(x))\n", "\n", " if above_interpolation_range.any():\n", " raise ValueError('\"{0}\" is above interpolation range.'.format(x))\n", "\n", "\n", "INTERPOLATORS = CaseInsensitiveMapping({\n", " 'Cubic Spline': CubicSplineInterpolator,\n", " 'Linear': LinearInterpolator,\n", " 'Null' : NullInterpolator,\n", " 'Pchip': PchipInterpolator,\n", " 'Sprague': SpragueInterpolator})\n", "\n", "\n", "def nearest_index(a, b):\n", " index = np.searchsorted(a, b)\n", "\n", " return np.where(np.abs(b - a[index-1]) < np.fabs(b - a[index]),\n", " index - 1,\n", " index)\n", "\n", "def nearest(a, b):\n", " a = np.asarray(a)\n", "\n", " return a[nearest_index(a, b)]\n", "\n", "\n", "@contextmanager\n", "def ndarray_write(a):\n", " a.setflags(write=True)\n", "\n", " yield a\n", "\n", " a.setflags(write=False)\n", "\n", "\n", "def fill_nan(a, method='Interpolation', default=np.nan):\n", " mask = np.isnan(a)\n", "\n", " if method.lower() == 'interpolation':\n", " a[mask] = np.interp(\n", " np.flatnonzero(mask),\n", " np.flatnonzero(~mask),\n", " a[~mask])\n", " elif method.lower() == 'constant':\n", " a[mask] = default\n", "\n", " return a\n", "\n", "\n", "def is_pandas_installed():\n", " try:\n", " import pandas\n", "\n", " return True\n", " except ImportError:\n", " return False\n", "\n", "\n", "def unpack_data(data=None, domain=None):\n", " domain_f, range_f, name_f = None, None, None\n", " if isinstance(data, Signal):\n", " domain_f = data.domain\n", " range_f = data.range\n", " if (isinstance(data, tuple) or\n", " isinstance(data, list) or\n", " isinstance(data, np.ndarray)):\n", " data = np.asarray(data)\n", " if data.ndim == 1:\n", " range_f = data\n", " elif data.ndim == 2:\n", " domain_f, range_f = tsplit(data)\n", " else:\n", " raise ValueError('\"data\" must be a 1d or 2d array-like variable!')\n", " elif (isinstance(data, dict) or\n", " isinstance(data, OrderedDict)):\n", " domain_f, range_f = tsplit(sorted(data.items()))\n", " elif is_pandas_installed():\n", " if isinstance(data, Series):\n", " domain_f = data.index.values\n", " range_f = data.values\n", " name_f = data.name\n", "\n", " domain_f = domain_f if domain is None else domain\n", "\n", " return domain_f, range_f, name_f\n", "\n", "\n", "class Signal(object):\n", " def __init__(self,\n", " data=None,\n", " domain=None,\n", " interpolation_method=None,\n", " interpolation_options=None,\n", " extrapolation_method=None,\n", " extrapolation_options=None,\n", " name=None):\n", "\n", " self.__domain = None\n", " self.__range = None\n", " self.__interpolation_method = 'Linear'\n", " self.__interpolation_options = {}\n", " self.__extrapolation_method = 'Constant'\n", " self.__extrapolation_options = {'left': np.nan, 'right': np.nan}\n", " self.__name = '{0} ({1})'.format(self.__class__.__name__, id(self))\n", "\n", " domain_f, range_f, name_f = unpack_data(data, domain)\n", " name_f = name_f if name is None else name\n", "\n", " self.domain = domain_f\n", " self.range = range_f\n", " self.interpolation_method = interpolation_method\n", " self.interpolation_options = interpolation_options\n", " self.extrapolation_method = extrapolation_method\n", " self.extrapolation_options = extrapolation_options\n", " self.name = name_f\n", "\n", " self.__create_function()\n", "\n", " @property\n", " def domain(self):\n", " return self.__domain\n", "\n", " @domain.setter\n", " def domain(self, value):\n", " if value is not None:\n", " if not np.all(np.isfinite(value)):\n", " warning('\"domain\" variable is not finite, '\n", " 'unpredictable results may occur!\\n{0}'.format(value))\n", "\n", " # TODO: `self.domain` is a copy of `value` to avoid side effects,\n", " # Is it a smart way to avoid them?\n", " value = np.copy(np.asarray(value))\n", "\n", " if self.__range is not None:\n", " assert value.size == self.__range.size, (\n", " '\"domain\" and \"range\" variables must have same size!')\n", "\n", " value.setflags(write=False)\n", " self.__domain = value\n", " self.__create_function()\n", "\n", " @property\n", " def range(self):\n", " return self.__range\n", "\n", " @range.setter\n", " def range(self, value):\n", " if value is not None:\n", " if not np.all(np.isfinite(value)):\n", " warning('\"range\" variable is not finite, '\n", " 'unpredictable results may occur!\\n{0}'.format(value))\n", "\n", " # TODO: `self.range` is a copy of `value` to avoid side effects,\n", " # Is it a smart way to avoid them?\n", " value = np.copy(np.asarray(value))\n", "\n", " if self.__domain is not None:\n", " assert value.size == self.__domain.size, (\n", " '\"domain\" and \"range\" variables must have same size!')\n", "\n", " value.setflags(write=False)\n", " self.__range = value\n", " self.__create_function()\n", "\n", " @property\n", " def interpolation_method(self):\n", " return self.__interpolation_method\n", "\n", " @interpolation_method.setter\n", " def interpolation_method(self, value):\n", " if value is not None:\n", " assert type(value) in (str, unicode), ( # noqa\n", " ('\"{0}\" attribute: \"{1}\" type is not '\n", " '\"str\" or \"unicode\"!').format('interpolation_method', value))\n", "\n", " assert value in INTERPOLATORS, (\n", " ('\"{0}\" attribute: \"{1}\" interpolation method is not defined! '\n", " 'Available methods: \"{2}\".').format(\n", " 'interpolation_method',\n", " value,\n", " sorted(INTERPOLATORS.keys())))\n", "\n", " self.__interpolation_method = value\n", " self.__create_function()\n", "\n", " @property\n", " def interpolation_options(self):\n", " return self.__interpolation_options\n", "\n", " @interpolation_options.setter\n", " def interpolation_options(self, value):\n", " if value is not None:\n", " assert type(value) in (dict, OrderedDict), (\n", " ('\"{0}\" attribute: \"{1}\" type is not '\n", " '\"dict\" or \"OrderedDict\"!').format(\n", " 'interpolation_options', value))\n", "\n", " self.__interpolation_options = value\n", " self.__create_function()\n", "\n", " @property\n", " def extrapolation_method(self):\n", " return self.__extrapolation_method\n", "\n", " @extrapolation_method.setter\n", " def extrapolation_method(self, value):\n", " if value is not None:\n", " assert type(value) in (str, unicode), ( # noqa\n", " ('\"{0}\" attribute: \"{1}\" type is not '\n", " '\"str\" or \"unicode\"!').format('extrapolation_method', value))\n", "\n", " assert value in ('Constant', 'Linear'), (\n", " ('\"{0}\" attribute: \"{1}\" extrapolation method is not defined! '\n", " 'Available methods: \"[\\'Constant\\', \\'Linear\\']\".').format(\n", " 'interpolation_method', value))\n", "\n", " self.__extrapolation_method = value\n", " self.__create_function()\n", "\n", " @property\n", " def extrapolation_options(self):\n", " return self.__extrapolation_options\n", "\n", " @extrapolation_options.setter\n", " def extrapolation_options(self, value):\n", " if value is not None:\n", " assert type(value) in (dict, OrderedDict), (\n", " ('\"{0}\" attribute: \"{1}\" type is not '\n", " '\"dict\" or \"OrderedDict\"!').format(\n", " 'extrapolation_options',value))\n", "\n", " self.__extrapolation_options = value\n", " self.__create_function()\n", "\n", " @property\n", " def name(self):\n", " return self.__name\n", "\n", " @name.setter\n", " def name(self, value):\n", " if value is not None:\n", " assert type(value) in (str, unicode), ( # noqa\n", " ('\"{0}\" attribute: \"{1}\" type is not '\n", " '\"str\" or \"unicode\"!').format('name', value))\n", " self.__name = value\n", "\n", " @property\n", " def function(self):\n", " return self.__function\n", "\n", " @function.setter\n", " def function(self, value):\n", " raise AttributeError(\n", " '\"{0}\" attribute is read only!'.format('function'))\n", "\n", " def __create_function(self):\n", " if self.__domain is not None and self.__range is not None:\n", " with ndarray_write(self.__domain), ndarray_write(self.__range):\n", " # TODO: Providing a writeable copy of both `self.domain` and `\n", " # self.range` to the interpolator to avoid issue regarding `MemoryView`\n", " # being read-only. https://mail.python.org/pipermail/cython-devel/2013-February/003384.html\n", " self.__function = Extrapolator(\n", " INTERPOLATORS[self.__interpolation_method](\n", " np.copy(self.__domain),\n", " np.copy(self.__range),\n", " **self.__interpolation_options),\n", " method=self.__extrapolation_method,\n", " **self.__extrapolation_options)\n", " else:\n", " def __undefined_signal_interpolator_function(*args, **kwargs):\n", " raise RuntimeError(\n", " 'Underlying signal interpolator function does not exists, '\n", " 'please ensure you defined both '\n", " '\"domain\" and \"range\" variables!')\n", "\n", " self.__function = __undefined_signal_interpolator_function\n", "\n", " def __str__(self):\n", " try:\n", " return str(tstack((self.domain, self.range)))\n", " except TypeError:\n", " return super(Signal, self).__str__()\n", "\n", " def __repr__(self):\n", " try:\n", " representation = repr(tstack((self.domain, self.range)))\n", " representation = representation.replace('array', self.__class__.__name__)\n", " representation = representation.replace(' [', \n", " '{0}['.format(' ' * (len(self.__class__.__name__) + 2)))\n", "\n", " return representation\n", " except TypeError:\n", " return super(Signal, self).__repr__()\n", " \n", " def __getitem__(self, x):\n", " if type(x) is slice:\n", " return self.__range[x]\n", " else:\n", " return self.__function(x)\n", "\n", " def __setitem__(self, x, value):\n", " if type(x) is slice:\n", " with ndarray_write(self.__range):\n", " self.__range[x] = value\n", " else:\n", " with ndarray_write(self.__domain), ndarray_write(self.__range):\n", " x = np.atleast_1d(x)\n", " value = np.resize(value, self.__domain.shape)\n", "\n", " # Matching domain, replacing existing `self.range`.\n", " mask = np.in1d(x, self.__domain)\n", " x_m = x[mask]\n", " indexes = np.searchsorted(self.__domain, x_m)\n", " self.__range[indexes] = value[mask]\n", "\n", " # Non matching domain, inserting into existing `self.domain`\n", " # and `self.range`.\n", " x_nm = x[~mask]\n", " indexes = np.searchsorted(self.__domain, x_nm)\n", "\n", " self.__domain = np.insert(self.__domain, indexes, x_nm)\n", " self.__range = np.insert(self.__range, indexes, value[~mask])\n", "\n", " self.__create_function\n", "\n", " def __contains__(self, x):\n", " return np.all(np.where(np.logical_and(x >= np.min(self.__domain), \n", " x <= np.max(self.__domain)),\n", " True,\n", " False))\n", "\n", " def __eq__(self, x):\n", " if isinstance(x, self.__class__):\n", " if all((np.array_equal(self.__domain, x.domain),\n", " np.array_equal(self.__range, x.range),\n", " self.__interpolation_method == x.interpolation_method,\n", " self.__interpolation_options == x.interpolation_options,\n", " self.__extrapolation_method == x.extrapolation_method,\n", " self.__extrapolation_options == x.extrapolation_options)):\n", " return True\n", "\n", " return False\n", " \n", " def __neq__(self, x):\n", " return not (self == x)\n", " \n", " def __fill_domain_nan(self, method='Interpolation', default=0):\n", " with ndarray_write(self.__domain):\n", " self.__domain = fill_nan(self.__domain, method, default)\n", " self.__create_function()\n", " \n", " def __fill_range_nan(self, method='Interpolation', default=0):\n", " with ndarray_write(self.__range):\n", " self.__range = fill_nan(self.__range, method, default)\n", " self.__create_function()\n", "\n", " def __arithmetical_ioperation(self, x, operator):\n", " operator, ioperator = OPERATORS[operator]\n", " \n", " if isinstance(x, self.__class__):\n", " with ndarray_write(self.__domain), ndarray_write(self.__range):\n", " # Operation from `self` domain and range.\n", " self[self.__domain] = operator(self.__range, x[self.__domain])\n", "\n", " # Operation from `x` domain and range.\n", " self[x.domain] = operator(self[x.domain], x.range)\n", " else:\n", " with ndarray_write(self.__range):\n", " self.range = ioperator(self.range, x)\n", "\n", " return self \n", "\n", " def __arithmetical_operation(self, x, operator):\n", " _operator, ioperator = OPERATORS[operator]\n", " \n", " copy = ioperator(self.copy(), x)\n", "\n", " return copy\n", "\n", " def __iadd__(self, x):\n", " return self.__arithmetical_ioperation(x, 'Add')\n", "\n", " def __add__(self, x):\n", " return self.__arithmetical_operation(x, 'Add')\n", "\n", " def __isub__(self, x):\n", " return self.__arithmetical_ioperation(x, 'Sub')\n", "\n", " def __sub__(self, x):\n", " return self.__arithmetical_operation(x, 'Sub')\n", "\n", " def __imul__(self, x):\n", " return self.__arithmetical_ioperation(x, 'Mul')\n", "\n", " def __mul__(self, x):\n", " return self.__arithmetical_operation(x, 'Mul')\n", "\n", " def __idiv__(self, x):\n", " return self.__arithmetical_ioperation(x, 'Div')\n", "\n", " def __div__(self, x):\n", " return self.__arithmetical_operation(x, 'Div')\n", "\n", " __itruediv__ = __idiv__\n", " __truediv__ = __div__\n", "\n", " def __ipow__(self, x):\n", " return self.__arithmetical_ioperation(x, 'Pow')\n", "\n", " def __pow__(self, x):\n", " return self.__arithmetical_operation(x, 'Pow')\n", " \n", " def copy(self):\n", " return deepcopy(self)\n", "\n", " def fill_nan(self, method='Interpolation', default=0):\n", " self.__fill_domain_nan(method, default)\n", " self.__fill_range_nan(method, default)\n", "\n", " def uncertainty(self, x):\n", " n = nearest(self.__domain, x)\n", "\n", " return np.abs(x - n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Empty Object Initialisation" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) cs1[0]\n", "Underlying signal interpolator function does not exists, please ensure you defined both \"domain\" and \"range\" variables!\n", "\n", "\n", "2) cs1[0]\n", "Underlying signal interpolator function does not exists, please ensure you defined both \"domain\" and \"range\" variables!\n", "\n", "\n", "3) cs1[0]\n", "1.0\n", "\n", "\n", "4) cs1 = Signal(range, [])\n", "\"domain\" and \"range\" variables must have same size!\n" ] } ], "source": [ "cs1 = Signal()\n", "\n", "print('1) cs1[0]')\n", "try:\n", " print(cs1[0])\n", "except RuntimeError as error:\n", " print(error)\n", "\n", "print('\\n')\n", "\n", "domain = np.arange(0, 1000, 100)\n", "cs1 = Signal(domain=domain)\n", "print('2) cs1[0]')\n", "try:\n", " print(cs1[0])\n", "except RuntimeError as error:\n", " print(error)\n", "\n", "print('\\n')\n", "\n", "range = np.linspace(1, 10, domain.size)\n", "cs1 = Signal(range, domain)\n", "print('3) cs1[0]')\n", "print(cs1[0])\n", "\n", "print('\\n')\n", "\n", "print('4) cs1 = Signal(range, [])')\n", "try:\n", " cs1 = Signal(range, [])\n", "except AssertionError as error:\n", " print(error)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Object Initialisation" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) cs1 = Signal(range, domain)\n", "Signal (139872258696208)\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "2) cs1 = Signal(data)\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "3) cs1 = Signal(data, domain_a)\n", "[[ 0. 1. ]\n", " [ 0.11111111 2. ]\n", " [ 0.22222222 3. ]\n", " [ 0.33333333 4. ]\n", " [ 0.44444444 5. ]\n", " [ 0.55555556 6. ]\n", " [ 0.66666667 7. ]\n", " [ 0.77777778 8. ]\n", " [ 0.88888889 9. ]\n", " [ 1. 10. ]]\n", "\n", "\n", "4) cs1 = Signal(Signal(data))\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "5) cs1 = Signal(Series(range, domain))\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "6) cs1 = Signal(Series(range, domain, name=\"D65\"))\n", "D65\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n" ] } ], "source": [ "domain = np.arange(0, 1000, 100)\n", "domain_a = np.linspace(0, 1, 10)\n", "range = np.linspace(1, 10, domain.size)\n", "\n", "data = zip(domain, range)\n", "\n", "print('1) cs1 = Signal(range, domain)')\n", "cs1 = Signal(range, domain)\n", "\n", "print(cs1.name)\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('2) cs1 = Signal(data)')\n", "cs1 = Signal(data)\n", "\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('3) cs1 = Signal(data, domain_a)')\n", "cs1 = Signal(data, domain_a)\n", "\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('4) cs1 = Signal(Signal(data))')\n", "cs1 = Signal(Signal(data))\n", "\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('5) cs1 = Signal(Series(range, domain))')\n", "cs1 = Signal(Series(range, domain))\n", "\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('6) cs1 = Signal(Series(range, domain, name=\"D65\"))')\n", "cs1 = Signal(Series(range, domain, name=\"D65\"))\n", "\n", "print(cs1.name)\n", "print(cs1)\n", "\n", "print('\\n')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Copy Operations" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) id(cs1)\n", "139872194502224\n", "\n", "\n", "\n", "2) id(cs2)\n", "139872194602512\n", "\n" ] } ], "source": [ "domain = np.arange(0, 1000, 100)\n", "range = np.linspace(1, 10, domain.size)\n", "\n", "cs1 = Signal(range, domain)\n", "\n", "print('1) id(cs1)')\n", "print(id(cs1))\n", "print(cs1.function)\n", "\n", "print('\\n')\n", "\n", "cs2 = cs1.copy()\n", "print('2) id(cs2)')\n", "print(id(cs2))\n", "print(cs2.function)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Item Operations" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) cs1\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "2) cs1[150.25]\n", "2.5025\n", "\n", "\n", "3) cs1[np.linspace(100, 400, 10)]\n", "[ 2. 2.33333333 2.66666667 3. 3.33333333 3.66666667\n", " 4. 4.33333333 4.66666667 5. ]\n", "\n", "\n", "4) cs1[0:3]\n", "[ 1. 2. 3.]\n", "\n", "\n", "5) cs1[10] = np.pi\n", "[[ 0. 1. ]\n", " [ 10. 3.14159265]\n", " [ 100. 2. ]\n", " [ 200. 3. ]\n", " [ 300. 4. ]\n", " [ 400. 5. ]\n", " [ 500. 6. ]\n", " [ 600. 7. ]\n", " [ 700. 8. ]\n", " [ 800. 9. ]\n", " [ 900. 10. ]]\n", "\n", "\n", "6) cs1[(200, 300)] = np.pi\n", "[[ 0. 1. ]\n", " [ 10. 3.14159265]\n", " [ 100. 2. ]\n", " [ 200. 3.14159265]\n", " [ 300. 3.14159265]\n", " [ 400. 5. ]\n", " [ 500. 6. ]\n", " [ 600. 7. ]\n", " [ 700. 8. ]\n", " [ 800. 9. ]\n", " [ 900. 10. ]]\n", "\n", "\n", "7) cs1[(0, 850)] = np.pi\n", "[[ 0. 3.14159265]\n", " [ 10. 3.14159265]\n", " [ 100. 2. ]\n", " [ 200. 3.14159265]\n", " [ 300. 3.14159265]\n", " [ 400. 5. ]\n", " [ 500. 6. ]\n", " [ 600. 7. ]\n", " [ 700. 8. ]\n", " [ 800. 9. ]\n", " [ 850. 3.14159265]\n", " [ 900. 10. ]]\n", "\n", "\n", "8) cs1[0:9] = np.pi\n", "[[ 0. 3.14159265]\n", " [ 10. 3.14159265]\n", " [ 100. 3.14159265]\n", " [ 200. 3.14159265]\n", " [ 300. 3.14159265]\n", " [ 400. 3.14159265]\n", " [ 500. 3.14159265]\n", " [ 600. 3.14159265]\n", " [ 700. 3.14159265]\n", " [ 800. 9. ]\n", " [ 850. 3.14159265]\n", " [ 900. 10. ]]\n", "\n", "\n", "9) cs1[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)] = np.pi\n", "[[ 0. 3.14159265]\n", " [ 1. 3.14159265]\n", " [ 2. 3.14159265]\n", " [ 3. 3.14159265]\n", " [ 4. 3.14159265]\n", " [ 5. 3.14159265]\n", " [ 6. 3.14159265]\n", " [ 7. 3.14159265]\n", " [ 8. 3.14159265]\n", " [ 9. 3.14159265]\n", " [ 10. 3.14159265]\n", " [ 100. 3.14159265]\n", " [ 200. 3.14159265]\n", " [ 300. 3.14159265]\n", " [ 400. 3.14159265]\n", " [ 500. 3.14159265]\n", " [ 600. 3.14159265]\n", " [ 700. 3.14159265]\n", " [ 800. 9. ]\n", " [ 850. 3.14159265]\n", " [ 900. 10. ]]\n" ] } ], "source": [ "domain = np.arange(0, 1000, 100)\n", "range = np.linspace(1, 10, domain.size)\n", "\n", "cs1 = Signal(range, domain)\n", "\n", "print('1) cs1')\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('2) cs1[150.25]')\n", "print(cs1[150.25])\n", "\n", "print('\\n')\n", "\n", "print('3) cs1[np.linspace(100, 400, 10)]')\n", "print(cs1[np.linspace(100, 400, 10)])\n", "\n", "print('\\n')\n", "\n", "print('4) cs1[0:3]')\n", "print(cs1[0:3])\n", "\n", "print('\\n')\n", "\n", "print('5) cs1[10] = np.pi')\n", "cs1[10] = np.pi\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('6) cs1[(200, 300)] = np.pi')\n", "cs1[(200, 300)] = np.pi\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('7) cs1[(0, 850)] = np.pi')\n", "cs1[(0, 850)] = np.pi\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('8) cs1[0:9] = np.pi')\n", "cs1[0:9] = np.pi\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('9) cs1[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)] = np.pi')\n", "cs1[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)] = np.pi\n", "print(cs1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Contains" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) cs1\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "2) 110 in cs1\n", "True\n", "\n", "\n", "3) (110, 1000) in cs1\n", "False\n" ] } ], "source": [ "domain = np.arange(0, 1000, 100)\n", "range = np.linspace(1, 10, domain.size)\n", "\n", "cs1 = Signal(range, domain)\n", "\n", "print('1) cs1')\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('2) 110 in cs1')\n", "print(110 in cs1)\n", "\n", "print('\\n')\n", "\n", "print('3) (110, 1000) in cs1')\n", "print((110, 1000) in cs1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Equality" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) cs1 == cs2\n", "True\n", "\n", "\n", "2) cs1[0] = 0.1; cs1 == cs2\n", "False\n", "\n", "\n", "3)cs1.interpolation_method = \"Null\"; cs1 == cs2\n", "False\n" ] } ], "source": [ "domain = np.arange(0, 1000, 100)\n", "range = np.linspace(1, 10, domain.size)\n", "\n", "cs1 = Signal(range, domain)\n", "cs2 = cs1.copy()\n", "\n", "print('1) cs1 == cs2')\n", "print(cs1 == cs2)\n", "\n", "print('\\n')\n", "\n", "print('2) cs1[0] = 0.1; cs1 == cs2')\n", "cs1[0] = 0.1\n", "\n", "print(cs1 == cs2)\n", "\n", "print('\\n')\n", "\n", "print('3)cs1.interpolation_method = \"Null\"; cs1 == cs2')\n", "cs2 = cs1.copy()\n", "cs1.interpolation_method = 'Null'\n", "\n", "print(cs1 == cs2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Null Interpolator" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) cs1\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "2) cs1[100]\n", "2.0\n", "\n", "\n", "3) cs1[100.1, 500]\n", "[ nan 6.]\n", "\n", "\n", "4) cs1[100.0000001]\n", "2.0\n" ] } ], "source": [ "domain = np.arange(0, 1000, 100)\n", "range = np.linspace(1, 10, domain.size)\n", "\n", "cs1 = Signal(range, domain, interpolation_method='Null')\n", "\n", "print('1) cs1')\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('2) cs1[100]')\n", "print(cs1[100])\n", "\n", "print('\\n')\n", "\n", "print('3) cs1[100.1, 500]')\n", "print(cs1[100.1, 500])\n", "\n", "print('\\n')\n", "\n", "print('4) cs1[100.0000001]')\n", "print(cs1[100.0000001])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Uncertainty" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) cs1\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "2) cs1.uncertainty((0.1, 150, 200))\n", "[ 0.1 50. 0. ]\n" ] } ], "source": [ "domain = np.arange(0, 1000, 100)\n", "range = np.linspace(1, 10, domain.size)\n", "\n", "cs1 = Signal(range, domain)\n", "\n", "print('1) cs1')\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('2) cs1.uncertainty((0.1, 150, 200))')\n", "print(cs1.uncertainty((0.1, 150, 200)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Arithmetical Operations with Matching Domain" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) cs1\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "2) cs2\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "3) cs1 += cs2\n", "[[ 0. 2.]\n", " [ 100. 4.]\n", " [ 200. 6.]\n", " [ 300. 8.]\n", " [ 400. 10.]\n", " [ 500. 12.]\n", " [ 600. 14.]\n", " [ 700. 16.]\n", " [ 800. 18.]\n", " [ 900. 20.]]\n", "\n", "\n", "4) cs1 += 1\n", "[[ 0. 3.]\n", " [ 100. 5.]\n", " [ 200. 7.]\n", " [ 300. 9.]\n", " [ 400. 11.]\n", " [ 500. 13.]\n", " [ 600. 15.]\n", " [ 700. 17.]\n", " [ 800. 19.]\n", " [ 900. 21.]]\n", "\n", "\n", "5) cs1 -= np.ones(domain.size)\n", "[[ 0. 2.]\n", " [ 100. 4.]\n", " [ 200. 6.]\n", " [ 300. 8.]\n", " [ 400. 10.]\n", " [ 500. 12.]\n", " [ 600. 14.]\n", " [ 700. 16.]\n", " [ 800. 18.]\n", " [ 900. 20.]]\n", "\n", "\n", "6) cs2 = cs1 + cs1\n", "[[ 0. 4.]\n", " [ 100. 8.]\n", " [ 200. 12.]\n", " [ 300. 16.]\n", " [ 400. 20.]\n", " [ 500. 24.]\n", " [ 600. 28.]\n", " [ 700. 32.]\n", " [ 800. 36.]\n", " [ 900. 40.]]\n", "\n", "\n" ] } ], "source": [ "domain = np.arange(0, 1000, 100)\n", "range = np.linspace(1, 10, domain.size)\n", "\n", "cs1 = Signal(range, domain)\n", "cs2 = Signal(range, domain)\n", "\n", "print('1) cs1')\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('2) cs2')\n", "print(cs2)\n", "\n", "print('\\n')\n", "\n", "print('3) cs1 += cs2')\n", "cs1 += cs2\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('4) cs1 += 1')\n", "cs1 += 1\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('5) cs1 -= np.ones(domain.size)')\n", "cs1 -= np.ones(domain.size)\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('6) cs2 = cs1 + cs1')\n", "cs2 = cs1 + cs1\n", "print(cs2)\n", "\n", "print('\\n')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Arithmetical Operations with Mismatching Domain" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) cs1\n", "[[ 0. 1.]\n", " [ 100. 2.]\n", " [ 200. 3.]\n", " [ 300. 4.]\n", " [ 400. 5.]\n", " [ 500. 6.]\n", " [ 600. 7.]\n", " [ 700. 8.]\n", " [ 800. 9.]\n", " [ 900. 10.]]\n", "\n", "\n", "2) cs2\n", "[[ 4.00000000e+02 1.00000000e+00]\n", " [ 5.00000000e+02 2.00000000e+00]\n", " [ 6.00000000e+02 3.00000000e+00]\n", " [ 7.00000000e+02 4.00000000e+00]\n", " [ 8.00000000e+02 5.00000000e+00]\n", " [ 9.00000000e+02 6.00000000e+00]\n", " [ 1.00000000e+03 7.00000000e+00]\n", " [ 1.10000000e+03 8.00000000e+00]\n", " [ 1.20000000e+03 9.00000000e+00]\n", " [ 1.30000000e+03 1.00000000e+01]]\n", "\n", "\n", "3) cs1 += cs2\n", "[[ 0. nan]\n", " [ 100. nan]\n", " [ 200. nan]\n", " [ 300. nan]\n", " [ 400. 6.]\n", " [ 500. 8.]\n", " [ 600. 10.]\n", " [ 700. 12.]\n", " [ 800. 14.]\n", " [ 900. 16.]\n", " [ 1000. nan]\n", " [ 1100. nan]\n", " [ 1200. nan]\n", " [ 1300. nan]]\n", "\n", "\n", "4) cs1 += 1\n", "[[ 0. nan]\n", " [ 100. nan]\n", " [ 200. nan]\n", " [ 300. nan]\n", " [ 400. 7.]\n", " [ 500. 9.]\n", " [ 600. 11.]\n", " [ 700. 13.]\n", " [ 800. 15.]\n", " [ 900. 17.]\n", " [ 1000. nan]\n", " [ 1100. nan]\n", " [ 1200. nan]\n", " [ 1300. nan]]\n", "\n", "\n", "5) cs1 -= np.ones(cs1.domain.size)\n", "[[ 0. nan]\n", " [ 100. nan]\n", " [ 200. nan]\n", " [ 300. nan]\n", " [ 400. 6.]\n", " [ 500. 8.]\n", " [ 600. 10.]\n", " [ 700. 12.]\n", " [ 800. 14.]\n", " [ 900. 16.]\n", " [ 1000. nan]\n", " [ 1100. nan]\n", " [ 1200. nan]\n", " [ 1300. nan]]\n", "\n", "\n", "6) cs2 = cs1 + cs1\n", "[[ 0. nan]\n", " [ 100. nan]\n", " [ 200. nan]\n", " [ 300. nan]\n", " [ 400. 12.]\n", " [ 500. 16.]\n", " [ 600. 20.]\n", " [ 700. 24.]\n", " [ 800. 28.]\n", " [ 900. nan]\n", " [ 1000. nan]\n", " [ 1100. nan]\n", " [ 1200. nan]\n", " [ 1300. nan]]\n", "\n", "\n", "7) Cubic Spline interpolation fails with Nan(s) values.\n", "[[ 0. nan]\n", " [ 100. nan]\n", " [ 200. nan]\n", " [ 300. nan]\n", " [ 400. nan]\n", " [ 500. nan]\n", " [ 600. nan]\n", " [ 700. nan]\n", " [ 800. nan]\n", " [ 900. nan]\n", " [ 1000. nan]\n", " [ 1100. nan]\n", " [ 1200. nan]\n", " [ 1300. nan]]\n", "\n", "\n", "8) Cubic Spline interpolation with filled Nan(s) values.\n", "[[ 0.00000000e+00 1.21014310e-14]\n", " [ 1.00000000e+02 -5.41233725e-15]\n", " [ 2.00000000e+02 -2.72698530e-15]\n", " [ 3.00000000e+02 1.24067423e-14]\n", " [ 4.00000000e+02 1.20000000e+01]\n", " [ 5.00000000e+02 1.60000000e+01]\n", " [ 6.00000000e+02 2.00000000e+01]\n", " [ 7.00000000e+02 2.40000000e+01]\n", " [ 8.00000000e+02 2.80000000e+01]\n", " [ 9.00000000e+02 3.20000000e+01]\n", " [ 1.00000000e+03 -8.88178420e-16]\n", " [ 1.10000000e+03 -6.55031585e-15]\n", " [ 1.20000000e+03 -5.19029264e-15]\n", " [ 1.30000000e+03 -7.85482790e-15]]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/colour-science/colour/colour/utilities/verbose.py:125: UserWarning: \"range\" variable is not finite, unpredictable results may occur!\n", "[ nan nan nan nan 7. 9. 11. 13. 15. 17. nan nan nan nan]\n", " warn(*args, **kwargs)\n", "/colour-science/colour/colour/utilities/verbose.py:125: UserWarning: \"range\" variable is not finite, unpredictable results may occur!\n", "[ nan nan nan nan 6. 8. 10. 12. 14. 16. nan nan nan nan]\n", " warn(*args, **kwargs)\n" ] } ], "source": [ "domain = np.arange(0, 1000, 100)\n", "range = np.linspace(1, 10, domain.size)\n", "\n", "cs1 = Signal(range, domain)\n", "cs2 = Signal(range, domain + 400)\n", "\n", "print('1) cs1')\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('2) cs2')\n", "print(cs2)\n", "\n", "print('\\n')\n", "\n", "print('3) cs1 += cs2')\n", "cs1 += cs2\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('4) cs1 += 1')\n", "cs1 += 1\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('5) cs1 -= np.ones(cs1.domain.size)')\n", "cs1 -= np.ones(cs1.domain.size)\n", "print(cs1)\n", "\n", "print('\\n')\n", "\n", "print('6) cs2 = cs1 + cs1')\n", "cs2 = cs1 + cs1\n", "print(cs2)\n", "\n", "print('\\n')\n", "\n", "print('7) Cubic Spline interpolation fails with Nan(s) values.')\n", "cs1.interpolation_method = 'Cubic Spline'\n", "cs2 = cs1 + cs1\n", "print(cs2)\n", "\n", "print('\\n')\n", "\n", "print('8) Cubic Spline interpolation with filled Nan(s) values.')\n", "cs1.fill_nan('constant')\n", "cs2 = cs1 + cs1\n", "print(cs2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Spectral Power Distribution" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [], "source": [ "from colour.colorimetry.dataset.illuminants.spds import ILLUMINANTS_RELATIVE_SPDS_DATA\n", "\n", "class Spectrum(Signal):\n", " def __init__(self, *args, **kwargs):\n", " # TODO: Define relevant default for spectral computations. \n", " settings = {\n", " 'interpolation_method': 'Pchip',\n", " 'extrapolation_options': {'left': None, 'right': None}}\n", " \n", " settings.update(kwargs)\n", " \n", " super(Spectrum, self).__init__(*args, **settings)\n", " \n", " @property\n", " def wavelengths(self):\n", " return self.domain\n", "\n", " @wavelengths.setter\n", " def wavelengths(self, value):\n", " self.domain = value\n", "\n", " @property\n", " def values(self):\n", " return self.range\n", "\n", " @values.setter\n", " def values(self, value):\n", " self.range = value\n", " \n", " @property\n", " def title(self):\n", " if self.__title is not None:\n", " return self.__title\n", " else:\n", " return self.__name\n", "\n", " @title.setter\n", " def title(self, value):\n", " if value is not None:\n", " assert type(value) in (str, unicode), ( # noqa\n", " ('\"{0}\" attribute: \"{1}\" type is not '\n", " '\"str\" or \"unicode\"!').format('title', value))\n", " self.__title = value\n", "\n", " def normalise(self, factor=100):\n", " self.range = (self.range * (1 / np.max(self.range))) * factor\n", " \n", " return self" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Representation" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) repr(s1)\n", "Spectrum([[ 300. , 0.930483],\n", " [ 305. , 1.12821 ],\n", " [ 310. , 1.35769 ],\n", " [ 315. , 1.62219 ],\n", " [ 320. , 1.92508 ],\n", " [ 325. , 2.2698 ],\n", " [ 330. , 2.65981 ],\n", " [ 335. , 3.09861 ],\n", " [ 340. , 3.58968 ],\n", " [ 345. , 4.13648 ],\n", " [ 350. , 4.74238 ],\n", " [ 355. , 5.4107 ],\n", " [ 360. , 6.14462 ],\n", " [ 365. , 6.9472 ],\n", " [ 370. , 7.82135 ],\n", " [ 375. , 8.7698 ],\n", " [ 380. , 9.7951 ],\n", " [ 385. , 10.8996 ],\n", " [ 390. , 12.0853 ],\n", " [ 395. , 13.3543 ],\n", " [ 400. , 14.708 ],\n", " [ 405. , 16.148 ],\n", " [ 410. , 17.6753 ],\n", " [ 415. , 19.2907 ],\n", " [ 420. , 20.995 ],\n", " [ 425. , 22.7883 ],\n", " [ 430. , 24.6709 ],\n", " [ 435. , 26.6425 ],\n", " [ 440. , 28.7027 ],\n", " [ 445. , 30.8508 ],\n", " [ 450. , 33.0859 ],\n", " [ 455. , 35.4068 ],\n", " [ 460. , 37.8121 ],\n", " [ 465. , 40.3002 ],\n", " [ 470. , 42.8693 ],\n", " [ 475. , 45.5174 ],\n", " [ 480. , 48.2423 ],\n", " [ 485. , 51.0418 ],\n", " [ 490. , 53.9132 ],\n", " [ 495. , 56.8539 ],\n", " [ 500. , 59.8611 ],\n", " [ 505. , 62.932 ],\n", " [ 510. , 66.0635 ],\n", " [ 515. , 69.2525 ],\n", " [ 520. , 72.4959 ],\n", " [ 525. , 75.7903 ],\n", " [ 530. , 79.1326 ],\n", " [ 535. , 82.5193 ],\n", " [ 540. , 85.947 ],\n", " [ 545. , 89.4124 ],\n", " [ 550. , 92.912 ],\n", " [ 555. , 96.4423 ],\n", " [ 560. , 100. ],\n", " [ 565. , 103.582 ],\n", " [ 570. , 107.184 ],\n", " [ 575. , 110.803 ],\n", " [ 580. , 114.436 ],\n", " [ 585. , 118.08 ],\n", " [ 590. , 121.731 ],\n", " [ 595. , 125.386 ],\n", " [ 600. , 129.043 ],\n", " [ 605. , 132.697 ],\n", " [ 610. , 136.346 ],\n", " [ 615. , 139.988 ],\n", " [ 620. , 143.618 ],\n", " [ 625. , 147.235 ],\n", " [ 630. , 150.836 ],\n", " [ 635. , 154.418 ],\n", " [ 640. , 157.979 ],\n", " [ 645. , 161.516 ],\n", " [ 650. , 165.028 ],\n", " [ 655. , 168.51 ],\n", " [ 660. , 171.963 ],\n", " [ 665. , 175.383 ],\n", " [ 670. , 178.769 ],\n", " [ 675. , 182.118 ],\n", " [ 680. , 185.429 ],\n", " [ 685. , 188.701 ],\n", " [ 690. , 191.931 ],\n", " [ 695. , 195.118 ],\n", " [ 700. , 198.261 ],\n", " [ 705. , 201.359 ],\n", " [ 710. , 204.409 ],\n", " [ 715. , 207.411 ],\n", " [ 720. , 210.365 ],\n", " [ 725. , 213.268 ],\n", " [ 730. , 216.12 ],\n", " [ 735. , 218.92 ],\n", " [ 740. , 221.667 ],\n", " [ 745. , 224.361 ],\n", " [ 750. , 227. ],\n", " [ 755. , 229.585 ],\n", " [ 760. , 232.115 ],\n", " [ 765. , 234.589 ],\n", " [ 770. , 237.008 ],\n", " [ 775. , 239.37 ],\n", " [ 780. , 241.675 ]])\n" ] } ], "source": [ "s1 = Spectrum(ILLUMINANTS_RELATIVE_SPDS_DATA['A'])\n", "\n", "print('1) repr(s1)')\n", "\n", "print(repr(s1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Normalisation" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1) s1.normalise()\n", "[[ 3.00000000e+02 3.85014172e-01]\n", " [ 3.05000000e+02 4.66829420e-01]\n", " [ 3.10000000e+02 5.61783387e-01]\n", " [ 3.15000000e+02 6.71227889e-01]\n", " [ 3.20000000e+02 7.96557360e-01]\n", " [ 3.25000000e+02 9.39195200e-01]\n", " [ 3.30000000e+02 1.10057308e+00]\n", " [ 3.35000000e+02 1.28213924e+00]\n", " [ 3.40000000e+02 1.48533361e+00]\n", " [ 3.45000000e+02 1.71158788e+00]\n", " [ 3.50000000e+02 1.96229647e+00]\n", " [ 3.55000000e+02 2.23883314e+00]\n", " [ 3.60000000e+02 2.54251371e+00]\n", " [ 3.65000000e+02 2.87460432e+00]\n", " [ 3.70000000e+02 3.23630909e+00]\n", " [ 3.75000000e+02 3.62875763e+00]\n", " [ 3.80000000e+02 4.05300507e+00]\n", " [ 3.85000000e+02 4.51002379e+00]\n", " [ 3.90000000e+02 5.00064136e+00]\n", " [ 3.95000000e+02 5.52572670e+00]\n", " [ 4.00000000e+02 6.08585911e+00]\n", " [ 4.05000000e+02 6.68170063e+00]\n", " [ 4.10000000e+02 7.31366505e+00]\n", " [ 4.15000000e+02 7.98208338e+00]\n", " [ 4.20000000e+02 8.68728665e+00]\n", " [ 4.25000000e+02 9.42931623e+00]\n", " [ 4.30000000e+02 1.02082963e+01]\n", " [ 4.35000000e+02 1.10241026e+01]\n", " [ 4.40000000e+02 1.18765698e+01]\n", " [ 4.45000000e+02 1.27654081e+01]\n", " [ 4.50000000e+02 1.36902452e+01]\n", " [ 4.55000000e+02 1.46505845e+01]\n", " [ 4.60000000e+02 1.56458467e+01]\n", " [ 4.65000000e+02 1.66753698e+01]\n", " [ 4.70000000e+02 1.77384090e+01]\n", " [ 4.75000000e+02 1.88341368e+01]\n", " [ 4.80000000e+02 1.99616427e+01]\n", " [ 4.85000000e+02 2.11200166e+01]\n", " [ 4.90000000e+02 2.23081411e+01]\n", " [ 4.95000000e+02 2.35249405e+01]\n", " [ 5.00000000e+02 2.47692562e+01]\n", " [ 5.05000000e+02 2.60399297e+01]\n", " [ 5.10000000e+02 2.73356781e+01]\n", " [ 5.15000000e+02 2.86552188e+01]\n", " [ 5.20000000e+02 2.99972691e+01]\n", " [ 5.25000000e+02 3.13604221e+01]\n", " [ 5.30000000e+02 3.27433951e+01]\n", " [ 5.35000000e+02 3.41447398e+01]\n", " [ 5.40000000e+02 3.55630496e+01]\n", " [ 5.45000000e+02 3.69969587e+01]\n", " [ 5.50000000e+02 3.84450191e+01]\n", " [ 5.55000000e+02 3.99057826e+01]\n", " [ 5.60000000e+02 4.13778835e+01]\n", " [ 5.65000000e+02 4.28600393e+01]\n", " [ 5.70000000e+02 4.43504707e+01]\n", " [ 5.75000000e+02 4.58479363e+01]\n", " [ 5.80000000e+02 4.73511948e+01]\n", " [ 5.85000000e+02 4.88590049e+01]\n", " [ 5.90000000e+02 5.03697114e+01]\n", " [ 5.95000000e+02 5.18820730e+01]\n", " [ 6.00000000e+02 5.33952622e+01]\n", " [ 6.05000000e+02 5.49072101e+01]\n", " [ 6.10000000e+02 5.64170891e+01]\n", " [ 6.15000000e+02 5.79240716e+01]\n", " [ 6.20000000e+02 5.94260888e+01]\n", " [ 6.25000000e+02 6.09227268e+01]\n", " [ 6.30000000e+02 6.24127444e+01]\n", " [ 6.35000000e+02 6.38949002e+01]\n", " [ 6.40000000e+02 6.53683666e+01]\n", " [ 6.45000000e+02 6.68319023e+01]\n", " [ 6.50000000e+02 6.82850936e+01]\n", " [ 6.55000000e+02 6.97258715e+01]\n", " [ 6.60000000e+02 7.11546498e+01]\n", " [ 6.65000000e+02 7.25697735e+01]\n", " [ 6.70000000e+02 7.39708286e+01]\n", " [ 6.75000000e+02 7.53565739e+01]\n", " [ 6.80000000e+02 7.67265956e+01]\n", " [ 6.85000000e+02 7.80804800e+01]\n", " [ 6.90000000e+02 7.94169856e+01]\n", " [ 6.95000000e+02 8.07356988e+01]\n", " [ 7.00000000e+02 8.20362056e+01]\n", " [ 7.05000000e+02 8.33180925e+01]\n", " [ 7.10000000e+02 8.45801179e+01]\n", " [ 7.15000000e+02 8.58222820e+01]\n", " [ 7.20000000e+02 8.70445847e+01]\n", " [ 7.25000000e+02 8.82457846e+01]\n", " [ 7.30000000e+02 8.94258819e+01]\n", " [ 7.35000000e+02 9.05844626e+01]\n", " [ 7.40000000e+02 9.17211131e+01]\n", " [ 7.45000000e+02 9.28358332e+01]\n", " [ 7.50000000e+02 9.39277956e+01]\n", " [ 7.55000000e+02 9.49974139e+01]\n", " [ 7.60000000e+02 9.60442743e+01]\n", " [ 7.65000000e+02 9.70679632e+01]\n", " [ 7.70000000e+02 9.80688942e+01]\n", " [ 7.75000000e+02 9.90462398e+01]\n", " [ 7.80000000e+02 1.00000000e+02]]\n" ] } ], "source": [ "s1 = Spectrum(ILLUMINANTS_RELATIVE_SPDS_DATA['A'])\n", "\n", "print('1) s1.normalise()')\n", "\n", "print(s1.normalise())" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }