Пример #1
0

_REFIND_DECL = [(NF32DTYPE[:], NF32DTYPE[:]), (NF64DTYPE[:], NFDTYPE[:]),
                (NC64DTYPE[:], NC64DTYPE[:]), (NC128DTYPE[:], NCDTYPE[:])]


@numba.njit(_REFIND_DECL, cache=NUMBA_CACHE)
def _refind2eps(refind, out):
    out[0] = refind[0]**2
    out[1] = refind[1]**2
    out[2] = refind[2]**2


_REFIND_DECL = [
    NF32DTYPE(NF32DTYPE),
    NFDTYPE(NF64DTYPE),
    NC64DTYPE(NC64DTYPE),
    NCDTYPE(NC128DTYPE)
]


@numba.vectorize(_REFIND_DECL, cache=NUMBA_CACHE)
def refind2eps(refind):
    """Converts refractive index to epsilon"""
    return refind**2


_EPS_DECL = [(NF32DTYPE, NF32DTYPE[:], NF32DTYPE[:]),
             (NF64DTYPE, NF64DTYPE[:], NFDTYPE[:]),
             (NF32DTYPE, NC64DTYPE[:], NC64DTYPE[:]),
             (NF64DTYPE, NC128DTYPE[:], NCDTYPE[:])]
Пример #2
0

# D65 standard light 5nm specter
D65PATH = os.path.join(DATAPATH, "D65.dat" )
#: color matrix for sRGB color space in D65 reference white
XYZ2RGBD65 = np.array([[ 3.2404542, -1.5371385, -0.4985314],
                       [-0.9692660,  1.8760108,  0.0415560],
                       [ 0.0556434, -0.2040259,  1.0572252]])
RGB2XYZ = np.linalg.inv(XYZ2RGBD65)
#Srgb tranfer function constants
SRGBIGAMMA = 1/2.4
SRGBSLOPE = 12.92
SRGBLINPOINT = 0.0031308
SRGBA = 0.055

@numba.vectorize([NFDTYPE(NFDTYPE, NFDTYPE)], nopython = True, target = NUMBA_TARGET, cache = NUMBA_CACHE) 
def apply_gamma(value, gamma):
    """apply_gamma(value, gamma)
    
Applies standard gamma function (transfer function) to the given (linear) data.
    
Parameters
----------
value : float
    Input value
gamma : float
    Gamma factor"""
    if value > 1.:
        return 1.
    if value < 0:
        return 0.
Пример #3
0
# D65 standard light 5nm specter
D65PATH = os.path.join(DATAPATH, "D65.dat")
#: color matrix for sRGB color space in D65 reference white
XYZ2RGBD65 = np.array([[3.2404542, -1.5371385, -0.4985314],
                       [-0.9692660, 1.8760108, 0.0415560],
                       [0.0556434, -0.2040259, 1.0572252]])
RGB2XYZ = np.linalg.inv(XYZ2RGBD65)
#Srgb tranfer function constants
SRGBIGAMMA = 1 / 2.4
SRGBSLOPE = 12.92
SRGBLINPOINT = 0.0031308
SRGBA = 0.055


@numba.vectorize([NFDTYPE(NFDTYPE, NFDTYPE)],
                 nopython=True,
                 target=NUMBA_TARGET,
                 cache=NUMBA_CACHE)
def apply_gamma(value, gamma):
    """apply_gamma(value, gamma)
    
Applies standard gamma function (transfer function) to the given (linear) data.
    
Parameters
----------
value : float
    Input value
gamma : float
    Gamma factor"""
    if value > 1.:
Пример #4
0
def _tensor_eig(tensor, is_real, eig, vec):
    """Computes eigenvalues of a tensor using analytical noniterative algorithm
    adapted from A Robust Eigensolver for 3 × 3 Symmetric Matrices by 
    David Eberly @ Geometric Tools.
    
    Input array is overwritten.
    """

    #if norm of the offdiagonal elements is smaller than this, treat the
    #tensor as a diagonal tensor. This improves handling of real diagonal epsilon
    #data treated as complex data, where the complex part introduces unwanted
    # rotations of the eigenframe, in particular when working with floats.
    normtol = 1e-12

    m1 = max(abs(tensor[0, 0]), abs(tensor[1, 1]))
    m2 = max(abs(tensor[2, 2]), abs(tensor[0, 1]))
    m3 = max(abs(tensor[0, 2]), abs(tensor[1, 2]))

    scale = max(max(m1, m2), m3)

    if scale == 0.:
        #zero matrix.. set eigenvalues to zero
        eig[0] = 0.
        eig[1] = 0.
        eig[2] = 0.
        vec[0] = (1, 0, 0)
        vec[1] = (0, 1, 0)
        vec[2] = (0, 0, 1)
    else:
        #precondition the matrix to avoid floating-point overflow
        scalem = 1 / scale
        a00 = tensor[0, 0] * scalem
        a11 = tensor[1, 1] * scalem
        a22 = tensor[2, 2] * scalem
        a01 = tensor[0, 1] * scalem
        a02 = tensor[0, 2] * scalem
        a12 = tensor[1, 2] * scalem

        q = (a00 + a11 + a22) / 3

        b00 = a00 - q
        b11 = a11 - q
        b22 = a22 - q

        norm = a01**2 + a02**2 + a12**2

        if abs(norm) > normtol:
            p = ((b00**2 + b11**2 + b22**2 + 2 * norm) / 6)**0.5

            c00 = b11 * b22 - a12 * a12
            c01 = a01 * b22 - a12 * a02
            c02 = a01 * a12 - b11 * a02

            half_det = (b00 * c00 - a01 * c01 + a02 * c02) / (p * p * p * 2)

            if is_real[0] == True:
                #for real data, half_det is between -1 and 1, to avoid possible rounding error, clamp it, just to make sure
                half_det = min(max(half_det.real, -1), 1)

            phi = np.arccos(half_det) / 3.

            #this number is closest to 2*np.pi/3 in float or double
            twoThirdsPi = NFDTYPE(2.09439510239319549)

            eig0 = np.cos(phi + twoThirdsPi) * 2
            eig2 = np.cos(phi) * 2
            eig1 = -(eig0 + eig2)

            #eigenvalues sorted by increasing
            eig0 = (eig0 * p + q)
            eig1 = (eig1 * p + q)
            eig2 = (eig2 * p + q)

            #now compute the eigenvectors
            if half_det.real >= 0:
                _eigvec0(a00, a11, a22, a01, a02, a12, eig2, vec[2], vec[1],
                         vec[0], eig)
                _eigvec1(a00, a11, a22, a01, a02, a12, vec[2], eig1, vec[1],
                         vec[0], eig)
                _cross(vec[1], vec[2], vec[0])
            else:
                _eigvec0(a00, a11, a22, a01, a02, a12, eig0, vec[0], vec[1],
                         vec[2], eig)
                _eigvec1(a00, a11, a22, a01, a02, a12, vec[0], eig1, vec[1],
                         vec[2], eig)
                _cross(vec[0], vec[1], vec[2])

            eig[0] = (eig0 * scale)
            eig[1] = (eig1 * scale)
            eig[2] = (eig2 * scale)
        else:
            #matrix is diagonal
            eig[0] = a00 * scale
            eig[1] = a11 * scale
            eig[2] = a22 * scale
            vec[0] = (1, 0, 0)
            vec[1] = (0, 1, 0)
            vec[2] = (0, 0, 1)

        _sort_eigvec(eig, vec, eig, vec)
Пример #5
0
"""
Numba optimized linear algebra functions for 4x4 matrices and 2x2 matrices.
"""

from __future__ import absolute_import, print_function, division
from dtmm.conf import NCDTYPE, NFDTYPE, NUMBA_TARGET, NUMBA_PARALLEL, NUMBA_CACHE, NUMBA_FASTMATH, CDTYPE, FDTYPE
from numba import njit, prange, guvectorize, boolean
import numpy as np

if not NUMBA_PARALLEL:
    prange = range


@njit([NFDTYPE(NFDTYPE[:]), NFDTYPE(NCDTYPE[:])],
      cache=NUMBA_CACHE,
      fastmath=NUMBA_FASTMATH)
def _vecabs2(v):
    """Computes vec.(vec.conj)"""
    out = 0.
    for i in range(len(v)):
        out = out + v[i].real**2 + v[i].imag**2
    return out


@njit([NFDTYPE(NFDTYPE[:]), NCDTYPE(NCDTYPE[:])],
      cache=NUMBA_CACHE,
      fastmath=NUMBA_FASTMATH)
def _vnorm2(v):
    """Computes vec.vec"""
    return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]
Пример #6
0
        F[3, 1] = -evpm * sfst

    #normalize base vectors
    for j in range(4):
        tmp = 0.
        for i in range(4):
            tmp += F[i, j].real * F[i, j].real + F[i, j].imag * F[i, j].imag

        tmp = tmp**0.5
        F[0, j] = F[0, j] / tmp
        F[1, j] = F[1, j] / tmp
        F[2, j] = F[2, j] / tmp
        F[3, j] = F[3, j] / tmp


@nb.njit([NFDTYPE(NCDTYPE[:])], cache=NUMBA_CACHE)
def _power(field):
    tmp1 = (field[0].real * field[1].real + field[0].imag * field[1].imag)
    tmp2 = (field[2].real * field[3].real + field[2].imag * field[3].imag)
    return tmp1 - tmp2


@nb.njit([(NCDTYPE[:], NCDTYPE[:, :], NCDTYPE[:], NCDTYPE[:, :])],
         cache=NUMBA_CACHE)
def _copy_sorted(alpha, fmat, out_alpha, out_fmat):
    i = 0
    j = 1
    for k in range(4):
        p = _power(fmat[:, k])
        if p >= 0.:
            out_alpha[i] = alpha[k]