diff --git a/colour/adaptation/cie1994.py b/colour/adaptation/cie1994.py index 3f41c5a4c..6c548d116 100644 --- a/colour/adaptation/cie1994.py +++ b/colour/adaptation/cie1994.py @@ -19,7 +19,7 @@ import numpy as np from colour.adaptation import CAT_VON_KRIES -from colour.algebra import sdiv, sdiv_mode, spow, vector_dot +from colour.algebra import sdiv, sdiv_mode, spow, vecmul from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( as_float_array, @@ -188,7 +188,7 @@ def XYZ_to_RGB_CIE1994(XYZ: ArrayLike) -> NDArrayFloat: array([ 25.8244273..., 18.6791422..., 4.8390194...]) """ - return vector_dot(MATRIX_XYZ_TO_RGB_CIE1994, XYZ) + return vecmul(MATRIX_XYZ_TO_RGB_CIE1994, XYZ) def RGB_to_XYZ_CIE1994(RGB: ArrayLike) -> NDArrayFloat: @@ -212,7 +212,7 @@ def RGB_to_XYZ_CIE1994(RGB: ArrayLike) -> NDArrayFloat: array([ 28. , 21.26, 5.27]) """ - return vector_dot(MATRIX_RGB_TO_XYZ_CIE1994, RGB) + return vecmul(MATRIX_RGB_TO_XYZ_CIE1994, RGB) def intermediate_values(xy_o: ArrayLike) -> NDArrayFloat: diff --git a/colour/adaptation/cmccat2000.py b/colour/adaptation/cmccat2000.py index f01bde426..fa804441a 100644 --- a/colour/adaptation/cmccat2000.py +++ b/colour/adaptation/cmccat2000.py @@ -27,7 +27,7 @@ import numpy as np from colour.adaptation import CAT_CMCCAT2000 -from colour.algebra import vector_dot +from colour.algebra import vecmul from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, @@ -168,9 +168,9 @@ def chromatic_adaptation_forward_CMCCAT2000( L_A1 = as_float_array(L_A1) L_A2 = as_float_array(L_A2) - RGB = vector_dot(CAT_CMCCAT2000, XYZ) - RGB_w = vector_dot(CAT_CMCCAT2000, XYZ_w) - RGB_wr = vector_dot(CAT_CMCCAT2000, XYZ_wr) + RGB = vecmul(CAT_CMCCAT2000, XYZ) + RGB_w = vecmul(CAT_CMCCAT2000, XYZ_w) + RGB_wr = vecmul(CAT_CMCCAT2000, XYZ_wr) D = surround.F * ( 0.08 * np.log10(0.5 * (L_A1 + L_A2)) @@ -182,7 +182,7 @@ def chromatic_adaptation_forward_CMCCAT2000( a = D * XYZ_w[..., 1] / XYZ_wr[..., 1] RGB_c = RGB * (a[..., None] * (RGB_wr / RGB_w) + 1 - D[..., None]) - XYZ_c = vector_dot(CAT_INVERSE_CMCCAT2000, RGB_c) + XYZ_c = vecmul(CAT_INVERSE_CMCCAT2000, RGB_c) return from_range_100(XYZ_c) @@ -261,9 +261,9 @@ def chromatic_adaptation_inverse_CMCCAT2000( L_A1 = as_float_array(L_A1) L_A2 = as_float_array(L_A2) - RGB_c = vector_dot(CAT_CMCCAT2000, XYZ_c) - RGB_w = vector_dot(CAT_CMCCAT2000, XYZ_w) - RGB_wr = vector_dot(CAT_CMCCAT2000, XYZ_wr) + RGB_c = vecmul(CAT_CMCCAT2000, XYZ_c) + RGB_w = vecmul(CAT_CMCCAT2000, XYZ_w) + RGB_wr = vecmul(CAT_CMCCAT2000, XYZ_wr) D = surround.F * ( 0.08 * np.log10(0.5 * (L_A1 + L_A2)) @@ -275,7 +275,7 @@ def chromatic_adaptation_inverse_CMCCAT2000( a = D * XYZ_w[..., 1] / XYZ_wr[..., 1] RGB = RGB_c / (a[..., None] * (RGB_wr / RGB_w) + 1 - D[..., None]) - XYZ = vector_dot(CAT_INVERSE_CMCCAT2000, RGB) + XYZ = vecmul(CAT_INVERSE_CMCCAT2000, RGB) return from_range_100(XYZ) diff --git a/colour/adaptation/fairchild1990.py b/colour/adaptation/fairchild1990.py index 524122f1b..68e03ce1b 100644 --- a/colour/adaptation/fairchild1990.py +++ b/colour/adaptation/fairchild1990.py @@ -20,7 +20,7 @@ import numpy as np from colour.adaptation import CAT_VON_KRIES -from colour.algebra import sdiv, sdiv_mode, spow, vector_dot +from colour.algebra import sdiv, sdiv_mode, spow, vecmul from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( as_float_array, @@ -129,9 +129,9 @@ def chromatic_adaptation_Fairchild1990( XYZ_r = to_domain_100(XYZ_r) Y_n = as_float_array(Y_n) - LMS_1 = vector_dot(MATRIX_XYZ_TO_RGB_FAIRCHILD1990, XYZ_1) - LMS_n = vector_dot(MATRIX_XYZ_TO_RGB_FAIRCHILD1990, XYZ_n) - LMS_r = vector_dot(MATRIX_XYZ_TO_RGB_FAIRCHILD1990, XYZ_r) + LMS_1 = vecmul(MATRIX_XYZ_TO_RGB_FAIRCHILD1990, XYZ_1) + LMS_n = vecmul(MATRIX_XYZ_TO_RGB_FAIRCHILD1990, XYZ_n) + LMS_r = vecmul(MATRIX_XYZ_TO_RGB_FAIRCHILD1990, XYZ_r) p_LMS = degrees_of_adaptation(LMS_1, Y_n, discount_illuminant=discount_illuminant) @@ -141,16 +141,16 @@ def chromatic_adaptation_Fairchild1990( A_1 = row_as_diagonal(a_LMS_1) A_2 = row_as_diagonal(a_LMS_2) - LMSp_1 = vector_dot(A_1, LMS_1) + LMSp_1 = vecmul(A_1, LMS_1) c = 0.219 - 0.0784 * np.log10(Y_n) C = row_as_diagonal(tstack([c, c, c])) - LMS_a = vector_dot(C, LMSp_1) - LMSp_2 = vector_dot(np.linalg.inv(C), LMS_a) + LMS_a = vecmul(C, LMSp_1) + LMSp_2 = vecmul(np.linalg.inv(C), LMS_a) - LMS_c = vector_dot(np.linalg.inv(A_2), LMSp_2) - XYZ_c = vector_dot(MATRIX_RGB_TO_XYZ_FAIRCHILD1990, LMS_c) + LMS_c = vecmul(np.linalg.inv(A_2), LMSp_2) + XYZ_c = vecmul(MATRIX_RGB_TO_XYZ_FAIRCHILD1990, LMS_c) return from_range_100(XYZ_c) @@ -176,7 +176,7 @@ def XYZ_to_RGB_Fairchild1990(XYZ: ArrayLike) -> NDArrayFloat: array([ 22.1231935..., 23.6054224..., 22.9279534...]) """ - return vector_dot(MATRIX_XYZ_TO_RGB_FAIRCHILD1990, XYZ) + return vecmul(MATRIX_XYZ_TO_RGB_FAIRCHILD1990, XYZ) def RGB_to_XYZ_Fairchild1990(RGB: ArrayLike) -> NDArrayFloat: @@ -200,7 +200,7 @@ def RGB_to_XYZ_Fairchild1990(RGB: ArrayLike) -> NDArrayFloat: array([ 19.53, 23.07, 24.97]) """ - return vector_dot(MATRIX_RGB_TO_XYZ_FAIRCHILD1990, RGB) + return vecmul(MATRIX_RGB_TO_XYZ_FAIRCHILD1990, RGB) def degrees_of_adaptation( @@ -247,7 +247,7 @@ def degrees_of_adaptation( v = as_float_array(v) # E illuminant. - LMS_E = vector_dot(CAT_VON_KRIES, ones(LMS.shape)) + LMS_E = vecmul(CAT_VON_KRIES, ones(LMS.shape)) Ye_n = spow(Y_n, v) diff --git a/colour/adaptation/fairchild2020.py b/colour/adaptation/fairchild2020.py index f0a97cd5e..7bcd6b067 100644 --- a/colour/adaptation/fairchild2020.py +++ b/colour/adaptation/fairchild2020.py @@ -22,7 +22,7 @@ import numpy as np from colour.adaptation import CHROMATIC_ADAPTATION_TRANSFORMS -from colour.algebra import matrix_dot, sdiv, sdiv_mode, vector_dot +from colour.algebra import sdiv, sdiv_mode, vecmul from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, @@ -202,15 +202,15 @@ def matrix_chromatic_adaptation_vk20( D_n, D_r, D_p = coefficients - LMS_n = vector_dot(M, XYZ_n) - LMS_r = vector_dot(M, XYZ_r) - LMS_p = vector_dot(M, XYZ_p) + LMS_n = vecmul(M, XYZ_n) + LMS_r = vecmul(M, XYZ_r) + LMS_p = vecmul(M, XYZ_p) with sdiv_mode(): D = row_as_diagonal(sdiv(1, (D_n * LMS_n + D_r * LMS_r + D_p * LMS_p))) - M_CAT = matrix_dot(np.linalg.inv(M), D) - M_CAT = matrix_dot(M_CAT, M) + M_CAT = np.matmul(np.linalg.inv(M), D) + M_CAT = np.matmul(M_CAT, M) return M_CAT @@ -316,6 +316,6 @@ def chromatic_adaptation_vK20( M_CAT = matrix_chromatic_adaptation_vk20( XYZ_p, XYZ_n, XYZ_r, transform, coefficients ) - XYZ_a = vector_dot(M_CAT, XYZ) + XYZ_a = vecmul(M_CAT, XYZ) return from_range_1(XYZ_a) diff --git a/colour/adaptation/vonkries.py b/colour/adaptation/vonkries.py index 060e67215..3201d59fa 100644 --- a/colour/adaptation/vonkries.py +++ b/colour/adaptation/vonkries.py @@ -19,7 +19,7 @@ import numpy as np from colour.adaptation import CHROMATIC_ADAPTATION_TRANSFORMS -from colour.algebra import matrix_dot, sdiv, sdiv_mode, vector_dot +from colour.algebra import sdiv, sdiv_mode, vecmul from colour.hints import ( ArrayLike, LiteralChromaticAdaptationTransform, @@ -117,16 +117,16 @@ def matrix_chromatic_adaptation_VonKries( M = CHROMATIC_ADAPTATION_TRANSFORMS[transform] - RGB_w = vector_dot(M, XYZ_w) - RGB_wr = vector_dot(M, XYZ_wr) + RGB_w = vecmul(M, XYZ_w) + RGB_wr = vecmul(M, XYZ_wr) with sdiv_mode(): D = sdiv(RGB_wr, RGB_w) D = row_as_diagonal(D) - M_CAT = matrix_dot(np.linalg.inv(M), D) - M_CAT = matrix_dot(M_CAT, M) + M_CAT = np.matmul(np.linalg.inv(M), D) + M_CAT = np.matmul(M_CAT, M) return M_CAT @@ -202,6 +202,6 @@ def chromatic_adaptation_VonKries( XYZ = to_domain_1(XYZ) M_CAT = matrix_chromatic_adaptation_VonKries(XYZ_w, XYZ_wr, transform) - XYZ_a = vector_dot(M_CAT, XYZ) + XYZ_a = vecmul(M_CAT, XYZ) return from_range_1(XYZ_a) diff --git a/colour/adaptation/zhai2018.py b/colour/adaptation/zhai2018.py index a77b70adc..229ef4d61 100644 --- a/colour/adaptation/zhai2018.py +++ b/colour/adaptation/zhai2018.py @@ -16,7 +16,7 @@ import numpy as np from colour.adaptation import CHROMATIC_ADAPTATION_TRANSFORMS -from colour.algebra import vector_dot +from colour.algebra import vecmul from colour.hints import ArrayLike, Literal, NDArrayFloat, Union from colour.utilities import ( as_float_array, @@ -152,10 +152,10 @@ def chromatic_adaptation_Zhai2018( transform = validate_method(transform, ("CAT02", "CAT16")) M = CHROMATIC_ADAPTATION_TRANSFORMS[transform] - RGB_b = vector_dot(M, XYZ_b) - RGB_wb = vector_dot(M, XYZ_wb) - RGB_wd = vector_dot(M, XYZ_wd) - RGB_wo = vector_dot(M, XYZ_wo) + RGB_b = vecmul(M, XYZ_b) + RGB_wb = vecmul(M, XYZ_wb) + RGB_wd = vecmul(M, XYZ_wd) + RGB_wo = vecmul(M, XYZ_wo) D_RGB_b = D_b * (Y_wb / Y_wo) * (RGB_wo / RGB_wb) + 1 - D_b D_RGB_d = D_d * (Y_wd / Y_wo) * (RGB_wo / RGB_wd) + 1 - D_d @@ -164,6 +164,6 @@ def chromatic_adaptation_Zhai2018( RGB_d = D_RGB * RGB_b - XYZ_d = vector_dot(np.linalg.inv(M), RGB_d) + XYZ_d = vecmul(np.linalg.inv(M), RGB_d) return from_range_100(XYZ_d) diff --git a/colour/algebra/__init__.py b/colour/algebra/__init__.py index 77a2679e8..538277838 100644 --- a/colour/algebra/__init__.py +++ b/colour/algebra/__init__.py @@ -16,8 +16,7 @@ spow, normalise_vector, normalise_maximum, - vector_dot, - matrix_dot, + vecmul, euclidean_distance, manhattan_distance, linear_conversion, @@ -65,8 +64,7 @@ "spow", "normalise_vector", "normalise_maximum", - "vector_dot", - "matrix_dot", + "vecmul", "euclidean_distance", "manhattan_distance", "linear_conversion", @@ -163,6 +161,14 @@ def __getattr__(self, attribute) -> Any: } """Defines the *colour.algebra* sub-package API changes.""" +# v0.4.5 +API_CHANGES["ObjectRenamed"] = [ + [ + "colour.algebra.vector_dot", + "colour.algebra.vecmul", + ], +] + if not is_documentation_building(): sys.modules["colour.algebra"] = algebra( # pyright: ignore sys.modules["colour.algebra"], build_API_changes(API_CHANGES) diff --git a/colour/algebra/common.py b/colour/algebra/common.py index b04091eac..3af821ab9 100644 --- a/colour/algebra/common.py +++ b/colour/algebra/common.py @@ -47,8 +47,7 @@ "spow", "normalise_vector", "normalise_maximum", - "vector_dot", - "matrix_dot", + "vecmul", "euclidean_distance", "manhattan_distance", "linear_conversion", @@ -554,13 +553,15 @@ def normalise_maximum( return np.clip(a, 0, factor) if clip else a -def vector_dot(m: ArrayLike, v: ArrayLike) -> NDArrayFloat: +def vecmul(m: ArrayLike, v: ArrayLike) -> NDArrayFloat: """ - Perform the dot product of the matrix array :math:`m` with the vector - array :math:`v`. + Perform the batched multiplication between the matrix array :math:`m` and + vector array :math:`v`. - This definition is a convenient wrapper around :func:`np.einsum` with the - following subscripts: *'...ij,...j->...i'*. + It is in intent equivalent to :func:`np.matmul` but with the specific intent + of vector multiplication by a matrix. With that intent, vector dimensionality + will be increased to enable broadcasting. This definition can be expressed + with :func:`np.einsum` using the following subscripts: *'...ij,...j->...i'*. Parameters ---------- @@ -572,7 +573,7 @@ def vector_dot(m: ArrayLike, v: ArrayLike) -> NDArrayFloat: Returns ------- :class:`numpy.ndarray` - Transformed vector array :math:`v`. + Multiplied vector array :math:`v`. Examples -------- @@ -586,7 +587,7 @@ def vector_dot(m: ArrayLike, v: ArrayLike) -> NDArrayFloat: >>> m = np.reshape(np.tile(m, (6, 1)), (6, 3, 3)) >>> v = np.array([0.20654008, 0.12197225, 0.05136952]) >>> v = np.tile(v, (6, 1)) - >>> vector_dot(m, v) # doctest: +ELLIPSIS + >>> vecmul(m, v) # doctest: +ELLIPSIS array([[ 0.1954094..., 0.0620396..., 0.0527952...], [ 0.1954094..., 0.0620396..., 0.0527952...], [ 0.1954094..., 0.0620396..., 0.0527952...], @@ -595,66 +596,7 @@ def vector_dot(m: ArrayLike, v: ArrayLike) -> NDArrayFloat: [ 0.1954094..., 0.0620396..., 0.0527952...]]) """ - return np.einsum("...ij,...j->...i", as_float_array(m), as_float_array(v)) - - -def matrix_dot(a: ArrayLike, b: ArrayLike) -> NDArrayFloat: - """ - Perform the dot product of the matrix array :math:`a` with the matrix - array :math:`b`. - - This definition is a convenient wrapper around :func:`np.einsum` with the - following subscripts: *'...ij,...jk->...ik'*. - - Parameters - ---------- - a - Matrix array :math:`a`. - b - Matrix array :math:`b`. - - Returns - ------- - :class:`numpy.ndarray` - - Examples - -------- - >>> a = np.array( - ... [ - ... [0.7328, 0.4296, -0.1624], - ... [-0.7036, 1.6975, 0.0061], - ... [0.0030, 0.0136, 0.9834], - ... ] - ... ) - >>> a = np.reshape(np.tile(a, (6, 1)), (6, 3, 3)) - >>> b = a - >>> matrix_dot(a, b) # doctest: +ELLIPSIS - array([[[ 0.2342420..., 1.0418482..., -0.2760903...], - [-1.7099407..., 2.5793226..., 0.1306181...], - [-0.0044203..., 0.0377490..., 0.9666713...]], - - [[ 0.2342420..., 1.0418482..., -0.2760903...], - [-1.7099407..., 2.5793226..., 0.1306181...], - [-0.0044203..., 0.0377490..., 0.9666713...]], - - [[ 0.2342420..., 1.0418482..., -0.2760903...], - [-1.7099407..., 2.5793226..., 0.1306181...], - [-0.0044203..., 0.0377490..., 0.9666713...]], - - [[ 0.2342420..., 1.0418482..., -0.2760903...], - [-1.7099407..., 2.5793226..., 0.1306181...], - [-0.0044203..., 0.0377490..., 0.9666713...]], - - [[ 0.2342420..., 1.0418482..., -0.2760903...], - [-1.7099407..., 2.5793226..., 0.1306181...], - [-0.0044203..., 0.0377490..., 0.9666713...]], - - [[ 0.2342420..., 1.0418482..., -0.2760903...], - [-1.7099407..., 2.5793226..., 0.1306181...], - [-0.0044203..., 0.0377490..., 0.9666713...]]]) - """ - - return np.einsum("...ij,...jk->...ik", as_float_array(a), as_float_array(b)) + return np.matmul(as_float_array(m), as_float_array(v)[..., None]).squeeze(-1) def euclidean_distance(a: ArrayLike, b: ArrayLike) -> NDArrayFloat: diff --git a/colour/algebra/tests/test_common.py b/colour/algebra/tests/test_common.py index 19a9e0c2b..1a7845ef9 100644 --- a/colour/algebra/tests/test_common.py +++ b/colour/algebra/tests/test_common.py @@ -14,7 +14,6 @@ linear_conversion, linstep_function, manhattan_distance, - matrix_dot, normalise_maximum, normalise_vector, sdiv, @@ -24,7 +23,7 @@ smoothstep_function, spow, spow_enable, - vector_dot, + vecmul, ) from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors @@ -49,7 +48,6 @@ "TestNormaliseVector", "TestNormaliseMaximum", "TestVectorDot", - "TestMatrixDot", "TestEuclideanDistance", "TestManhattanDistance", "TestLinearConversion", @@ -403,12 +401,12 @@ def test_normalise_maximum(self): class TestVectorDot: """ - Define :func:`colour.algebra.common.vector_dot` definition unit tests + Define :func:`colour.algebra.common.vecmul` definition unit tests methods. """ - def test_vector_dot(self): - """Test :func:`colour.algebra.common.vector_dot` definition.""" + def test_vecmul(self): + """Test :func:`colour.algebra.common.vecmul` definition.""" m = np.array( [ @@ -423,7 +421,7 @@ def test_vector_dot(self): v = np.tile(v, (6, 1)) np.testing.assert_allclose( - vector_dot(m, v), + vecmul(m, v), np.array( [ [0.19540944, 0.06203965, 0.05279523], @@ -438,66 +436,6 @@ def test_vector_dot(self): ) -class TestMatrixDot: - """ - Define :func:`colour.algebra.common.matrix_dot` definition unit tests - methods. - """ - - def test_matrix_dot(self): - """Test :func:`colour.algebra.common.matrix_dot` definition.""" - - a = np.array( - [ - [0.7328, 0.4296, -0.1624], - [-0.7036, 1.6975, 0.0061], - [0.0030, 0.0136, 0.9834], - ] - ) - a = np.reshape(np.tile(a, (6, 1)), (6, 3, 3)) - - b = a - - np.testing.assert_allclose( - matrix_dot(a, b), - np.array( - [ - [ - [0.23424208, 1.04184824, -0.27609032], - [-1.70994078, 2.57932265, 0.13061813], - [-0.00442036, 0.03774904, 0.96667132], - ], - [ - [0.23424208, 1.04184824, -0.27609032], - [-1.70994078, 2.57932265, 0.13061813], - [-0.00442036, 0.03774904, 0.96667132], - ], - [ - [0.23424208, 1.04184824, -0.27609032], - [-1.70994078, 2.57932265, 0.13061813], - [-0.00442036, 0.03774904, 0.96667132], - ], - [ - [0.23424208, 1.04184824, -0.27609032], - [-1.70994078, 2.57932265, 0.13061813], - [-0.00442036, 0.03774904, 0.96667132], - ], - [ - [0.23424208, 1.04184824, -0.27609032], - [-1.70994078, 2.57932265, 0.13061813], - [-0.00442036, 0.03774904, 0.96667132], - ], - [ - [0.23424208, 1.04184824, -0.27609032], - [-1.70994078, 2.57932265, 0.13061813], - [-0.00442036, 0.03774904, 0.96667132], - ], - ] - ), - atol=TOLERANCE_ABSOLUTE_TESTS, - ) - - class TestEuclideanDistance: """ Define :func:`colour.algebra.common.euclidean_distance` definition unit diff --git a/colour/appearance/atd95.py b/colour/appearance/atd95.py index 3f2d549db..b527ff3fd 100644 --- a/colour/appearance/atd95.py +++ b/colour/appearance/atd95.py @@ -30,7 +30,7 @@ import numpy as np -from colour.algebra import spow, vector_dot +from colour.algebra import spow, vecmul from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( MixinDataclassArithmetic, @@ -327,7 +327,7 @@ def XYZ_to_LMS_ATD95(XYZ: ArrayLike) -> NDArrayFloat: array([ 6.2283272..., 7.4780666..., 3.8859772...]) """ - LMS = vector_dot( + LMS = vecmul( [ [0.2435, 0.8524, -0.0516], [-0.3954, 1.1642, 0.0837], diff --git a/colour/appearance/cam16.py b/colour/appearance/cam16.py index b5d2a2072..783a59efa 100644 --- a/colour/appearance/cam16.py +++ b/colour/appearance/cam16.py @@ -26,7 +26,7 @@ import numpy as np from colour.adaptation import CAT_CAT16 -from colour.algebra import spow, vector_dot +from colour.algebra import spow, vecmul from colour.appearance.ciecam02 import ( VIEWING_CONDITIONS_CIECAM02, InductionFactors_CIECAM02, @@ -261,7 +261,7 @@ def XYZ_to_CAM16( # Step 0 # Converting *CIE XYZ* tristimulus values to sharpened *RGB* values. - RGB_w = vector_dot(MATRIX_16, XYZ_w) + RGB_w = vecmul(MATRIX_16, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -283,7 +283,7 @@ def XYZ_to_CAM16( # Step 1 # Converting *CIE XYZ* tristimulus values to sharpened *RGB* values. - RGB = vector_dot(MATRIX_16, XYZ) + RGB = vecmul(MATRIX_16, XYZ) # Step 2 RGB_c = D_RGB * RGB @@ -445,7 +445,7 @@ def CAM16_to_XYZ( # Step 0 # Converting *CIE XYZ* tristimulus values to sharpened *RGB* values. - RGB_w = vector_dot(MATRIX_16, XYZ_w) + RGB_w = vecmul(MATRIX_16, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -505,6 +505,6 @@ def CAM16_to_XYZ( RGB = RGB_c / D_RGB # Step 7 - XYZ = vector_dot(MATRIX_INVERSE_16, RGB) + XYZ = vecmul(MATRIX_INVERSE_16, RGB) return from_range_100(XYZ) diff --git a/colour/appearance/ciecam02.py b/colour/appearance/ciecam02.py index 2ed7121ab..4e96426be 100644 --- a/colour/appearance/ciecam02.py +++ b/colour/appearance/ciecam02.py @@ -38,7 +38,7 @@ import numpy as np from colour.adaptation import CAT_CAT02 -from colour.algebra import matrix_dot, sdiv, sdiv_mode, spow, vector_dot +from colour.algebra import sdiv, sdiv_mode, spow, vecmul from colour.appearance.hunt import ( MATRIX_HPE_TO_XYZ, MATRIX_XYZ_TO_HPE, @@ -336,8 +336,8 @@ def XYZ_to_CIECAM02( # Converting *CIE XYZ* tristimulus values to *CMCCAT2000* transform # sharpened *RGB* values. - RGB = vector_dot(CAT_CAT02, XYZ) - RGB_w = vector_dot(CAT_CAT02, XYZ_w) + RGB = vecmul(CAT_CAT02, XYZ) + RGB_w = vecmul(CAT_CAT02, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -534,7 +534,7 @@ def CIECAM02_to_XYZ( # Converting *CIE XYZ* tristimulus values to *CMCCAT2000* transform # sharpened *RGB* values. - RGB_w = vector_dot(CAT_CAT02, XYZ_w) + RGB_w = vecmul(CAT_CAT02, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -586,7 +586,7 @@ def CIECAM02_to_XYZ( # Converting *CMCCAT2000* transform sharpened *RGB* values to *CIE XYZ* # tristimulus values. - XYZ = vector_dot(CAT_INVERSE_CAT02, RGB) + XYZ = vecmul(CAT_INVERSE_CAT02, RGB) return from_range_100(XYZ) @@ -849,7 +849,7 @@ def RGB_to_rgb(RGB: ArrayLike) -> NDArrayFloat: array([ 19.9969397..., 20.0018612..., 20.0135053...]) """ - rgb = vector_dot(matrix_dot(MATRIX_XYZ_TO_HPE, CAT_INVERSE_CAT02), RGB) + rgb = vecmul(np.matmul(MATRIX_XYZ_TO_HPE, CAT_INVERSE_CAT02), RGB) return rgb @@ -876,7 +876,7 @@ def rgb_to_RGB(rgb: ArrayLike) -> NDArrayFloat: array([ 19.9937078..., 20.0039363..., 20.0132638...]) """ - RGB = vector_dot(matrix_dot(CAT_CAT02, MATRIX_HPE_TO_XYZ), rgb) + RGB = vecmul(np.matmul(CAT_CAT02, MATRIX_HPE_TO_XYZ), rgb) return RGB @@ -1689,7 +1689,7 @@ def matrix_post_adaptation_non_linear_response_compression( b = as_float_array(b) RGB_a = ( - vector_dot( + vecmul( [ [460, 451, 288], [460, -891, -261], diff --git a/colour/appearance/ciecam16.py b/colour/appearance/ciecam16.py index 006fbe3ab..c41242848 100644 --- a/colour/appearance/ciecam16.py +++ b/colour/appearance/ciecam16.py @@ -25,7 +25,7 @@ import numpy as np -from colour.algebra import spow, vector_dot +from colour.algebra import spow, vecmul from colour.appearance.cam16 import MATRIX_16, MATRIX_INVERSE_16 from colour.appearance.ciecam02 import ( VIEWING_CONDITIONS_CIECAM02, @@ -275,7 +275,7 @@ def XYZ_to_CIECAM16( # Step 0 # Converting *CIE XYZ* tristimulus values to sharpened *RGB* values. - RGB_w = vector_dot(MATRIX_16, XYZ_w) + RGB_w = vecmul(MATRIX_16, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -297,7 +297,7 @@ def XYZ_to_CIECAM16( # Step 1 # Converting *CIE XYZ* tristimulus values to sharpened *RGB* values. - RGB = vector_dot(MATRIX_16, XYZ) + RGB = vecmul(MATRIX_16, XYZ) # Step 2 RGB_c = D_RGB * RGB @@ -478,7 +478,7 @@ def CIECAM16_to_XYZ( # Step 0 # Converting *CIE XYZ* tristimulus values to sharpened *RGB* values. - RGB_w = vector_dot(MATRIX_16, XYZ_w) + RGB_w = vecmul(MATRIX_16, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -538,7 +538,7 @@ def CIECAM16_to_XYZ( RGB = RGB_c / D_RGB # Step 7 - XYZ = vector_dot(MATRIX_INVERSE_16, RGB) + XYZ = vecmul(MATRIX_INVERSE_16, RGB) return from_range_100(XYZ) diff --git a/colour/appearance/hellwig2022.py b/colour/appearance/hellwig2022.py index d48e55f61..c0807fa23 100644 --- a/colour/appearance/hellwig2022.py +++ b/colour/appearance/hellwig2022.py @@ -29,7 +29,7 @@ import numpy as np -from colour.algebra import sdiv, sdiv_mode, spow, vector_dot +from colour.algebra import sdiv, sdiv_mode, spow, vecmul from colour.appearance.cam16 import ( MATRIX_16, MATRIX_INVERSE_16, @@ -307,7 +307,7 @@ def XYZ_to_Hellwig2022( # Step 0 # Converting *CIE XYZ* tristimulus values to sharpened *RGB* values. - RGB_w = vector_dot(MATRIX_16, XYZ_w) + RGB_w = vecmul(MATRIX_16, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -329,7 +329,7 @@ def XYZ_to_Hellwig2022( # Step 1 # Converting *CIE XYZ* tristimulus values to sharpened *RGB* values. - RGB = vector_dot(MATRIX_16, XYZ) + RGB = vecmul(MATRIX_16, XYZ) # Step 2 RGB_c = D_RGB * RGB @@ -549,7 +549,7 @@ def Hellwig2022_to_XYZ( # Step 0 # Converting *CIE XYZ* tristimulus values to sharpened *RGB* values. - RGB_w = vector_dot(MATRIX_16, XYZ_w) + RGB_w = vecmul(MATRIX_16, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -606,7 +606,7 @@ def Hellwig2022_to_XYZ( RGB = RGB_c / D_RGB # Step 7 - XYZ = vector_dot(MATRIX_INVERSE_16, RGB) + XYZ = vecmul(MATRIX_INVERSE_16, RGB) return from_range_100(XYZ) diff --git a/colour/appearance/hunt.py b/colour/appearance/hunt.py index 7bc569baf..4d9c61195 100644 --- a/colour/appearance/hunt.py +++ b/colour/appearance/hunt.py @@ -24,7 +24,7 @@ import numpy as np -from colour.algebra import spow, vector_dot +from colour.algebra import spow, vecmul from colour.hints import ArrayLike, NDArrayFloat, cast from colour.utilities import ( CanonicalMapping, @@ -619,7 +619,7 @@ def XYZ_to_rgb(XYZ: ArrayLike) -> NDArrayFloat: array([ 19.4743367..., 20.3101217..., 21.78 ]) """ - return vector_dot(MATRIX_XYZ_TO_HPE, XYZ) + return vecmul(MATRIX_XYZ_TO_HPE, XYZ) def f_n(x: ArrayLike) -> NDArrayFloat: diff --git a/colour/appearance/kim2009.py b/colour/appearance/kim2009.py index 20ba08d5b..26d9d89e8 100644 --- a/colour/appearance/kim2009.py +++ b/colour/appearance/kim2009.py @@ -27,7 +27,7 @@ import numpy as np from colour.adaptation import CAT_CAT02 -from colour.algebra import spow, vector_dot +from colour.algebra import spow, vecmul from colour.appearance.ciecam02 import ( CAT_INVERSE_CAT02, VIEWING_CONDITIONS_CIECAM02, @@ -305,8 +305,8 @@ def XYZ_to_Kim2009( # Converting *CIE XYZ* tristimulus values to *CMCCAT2000* transform # sharpened *RGB* values. - RGB = vector_dot(CAT_CAT02, XYZ) - RGB_w = vector_dot(CAT_CAT02, XYZ_w) + RGB = vecmul(CAT_CAT02, XYZ) + RGB_w = vecmul(CAT_CAT02, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -483,7 +483,7 @@ def Kim2009_to_XYZ( # Converting *CIE XYZ* tristimulus values to *CMCCAT2000* transform # sharpened *RGB* values. - RGB_w = vector_dot(CAT_CAT02, XYZ_w) + RGB_w = vecmul(CAT_CAT02, XYZ_w) # Computing degree of adaptation :math:`D`. D = ( @@ -540,7 +540,7 @@ def Kim2009_to_XYZ( [1.0000, -0.1568, -4.4904], ] ) - LMS_p = vector_dot(M, tstack([A, a, b])) + LMS_p = vecmul(M, tstack([A, a, b])) LMS = spow((-spow(L_A, n_c) * LMS_p) / (LMS_p - 1), 1 / n_c) # Converting to *Hunt-Pointer-Estevez* colourspace. @@ -549,6 +549,6 @@ def Kim2009_to_XYZ( # Applying inverse full chromatic adaptation. RGB = full_chromatic_adaptation_inverse(RGB_c, RGB_w, Y_w, D) - XYZ = vector_dot(CAT_INVERSE_CAT02, RGB) + XYZ = vecmul(CAT_INVERSE_CAT02, RGB) return from_range_100(XYZ) diff --git a/colour/appearance/llab.py b/colour/appearance/llab.py index 8963d18e7..373b1dd93 100644 --- a/colour/appearance/llab.py +++ b/colour/appearance/llab.py @@ -35,7 +35,7 @@ sdiv, sdiv_mode, spow, - vector_dot, + vecmul, ) from colour.hints import ArrayLike, NDArrayFloat, Optional, Union from colour.utilities import ( @@ -402,7 +402,7 @@ def XYZ_to_RGB_LLAB(XYZ: ArrayLike) -> NDArrayFloat: XYZ = as_float_array(XYZ) with sdiv_mode(): - return vector_dot(MATRIX_XYZ_TO_RGB_LLAB, sdiv(XYZ, XYZ[..., 1, None])) + return vecmul(MATRIX_XYZ_TO_RGB_LLAB, sdiv(XYZ, XYZ[..., 1, None])) def chromatic_adaptation( @@ -461,7 +461,7 @@ def chromatic_adaptation( Y = tstack([Y, Y, Y]) - XYZ_r = vector_dot(MATRIX_RGB_TO_XYZ_LLAB, RGB_r * Y) + XYZ_r = vecmul(MATRIX_RGB_TO_XYZ_LLAB, RGB_r * Y) return XYZ_r diff --git a/colour/appearance/nayatani95.py b/colour/appearance/nayatani95.py index 9ec402353..7e1aafdef 100644 --- a/colour/appearance/nayatani95.py +++ b/colour/appearance/nayatani95.py @@ -30,7 +30,7 @@ exponential_factors, intermediate_values, ) -from colour.algebra import spow, vector_dot +from colour.algebra import spow, vecmul from colour.hints import ArrayLike, NDArrayFloat, cast from colour.models import XYZ_to_xy from colour.utilities import ( @@ -383,7 +383,7 @@ def XYZ_to_RGB_Nayatani95(XYZ: ArrayLike) -> NDArrayFloat: array([ 20.0005206..., 19.999783 ..., 19.9988316...]) """ - return vector_dot(MATRIX_XYZ_TO_RGB_NAYATANI95, XYZ) + return vecmul(MATRIX_XYZ_TO_RGB_NAYATANI95, XYZ) def scaling_coefficient(x: ArrayLike, y: ArrayLike) -> NDArrayFloat: diff --git a/colour/appearance/rlab.py b/colour/appearance/rlab.py index e7999bfa1..8566f3dbc 100644 --- a/colour/appearance/rlab.py +++ b/colour/appearance/rlab.py @@ -24,7 +24,7 @@ import numpy as np -from colour.algebra import matrix_dot, sdiv, sdiv_mode, spow, vector_dot +from colour.algebra import sdiv, sdiv_mode, spow, vecmul from colour.appearance.hunt import MATRIX_XYZ_TO_HPE, XYZ_to_rgb from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( @@ -266,8 +266,8 @@ def XYZ_to_RLAB( LMS_a_L = (LMS_p_L + D[..., None] * (1 - LMS_p_L)) / LMS_n - M = matrix_dot(matrix_dot(MATRIX_R, row_as_diagonal(LMS_a_L)), MATRIX_XYZ_TO_HPE) - XYZ_ref = vector_dot(M, XYZ) + M = np.matmul(np.matmul(MATRIX_R, row_as_diagonal(LMS_a_L)), MATRIX_XYZ_TO_HPE) + XYZ_ref = vecmul(M, XYZ) X_ref, Y_ref, Z_ref = tsplit(XYZ_ref) diff --git a/colour/blindness/machado2009.py b/colour/blindness/machado2009.py index a78c12578..596f84c1a 100644 --- a/colour/blindness/machado2009.py +++ b/colour/blindness/machado2009.py @@ -30,7 +30,7 @@ import numpy as np -from colour.algebra import matrix_dot, vector_dot +from colour.algebra import vecmul from colour.blindness import CVD_MATRICES_MACHADO2010 from colour.characterisation import RGB_DisplayPrimaries from colour.colorimetry import ( @@ -108,7 +108,7 @@ def matrix_RGB_to_WSYBRG( """ wavelengths = cmfs.wavelengths - WSYBRG = vector_dot(MATRIX_LMS_TO_WSYBRG, cmfs.values) + WSYBRG = vecmul(MATRIX_LMS_TO_WSYBRG, cmfs.values) WS, YB, RG = tsplit(WSYBRG) primaries = reshape_msds( @@ -308,7 +308,7 @@ def matrix_anomalous_trichromacy_Machado2009( cmfs_a = msds_cmfs_anomalous_trichromacy_Machado2009(cmfs, d_LMS) M_a = matrix_RGB_to_WSYBRG(cmfs_a, primaries) - return matrix_dot(np.linalg.inv(M_n), M_a) + return np.matmul(np.linalg.inv(M_n), M_a) def matrix_cvd_Machado2009( diff --git a/colour/characterisation/aces_it.py b/colour/characterisation/aces_it.py index 41a67e581..f4255c33f 100644 --- a/colour/characterisation/aces_it.py +++ b/colour/characterisation/aces_it.py @@ -63,7 +63,7 @@ from colour.adaptation import matrix_chromatic_adaptation_VonKries from colour.algebra import ( euclidean_distance, - vector_dot, + vecmul, ) from colour.characterisation import ( MSDS_ACES_RICD, @@ -700,7 +700,7 @@ def training_data_sds_to_XYZ( chromatic_adaptation_transform, ) - XYZ = vector_dot(M_CAT, XYZ) + XYZ = vecmul(M_CAT, XYZ) return XYZ @@ -781,9 +781,7 @@ def objective_function( M = finaliser_function(M) - XYZ_t = vector_dot( - RGB_COLOURSPACE_ACES2065_1.matrix_RGB_to_XYZ, vector_dot(M, RGB) - ) + XYZ_t = vecmul(RGB_COLOURSPACE_ACES2065_1.matrix_RGB_to_XYZ, vecmul(M, RGB)) Lab_t = XYZ_to_optimization_colour_model(XYZ_t) return as_float(np.linalg.norm(Lab_t - Lab)) @@ -847,9 +845,7 @@ def objective_function( M = finaliser_function(M) - XYZ_t = vector_dot( - RGB_COLOURSPACE_ACES2065_1.matrix_RGB_to_XYZ, vector_dot(M, RGB) - ) + XYZ_t = vecmul(RGB_COLOURSPACE_ACES2065_1.matrix_RGB_to_XYZ, vecmul(M, RGB)) Jab_t = XYZ_to_optimization_colour_model(XYZ_t) return as_float(np.sum(euclidean_distance(Jab, Jab_t))) @@ -1175,4 +1171,4 @@ def camera_RGB_to_ACES2065_1( RGB_r = np.clip(RGB_r, -np.inf, 1) if clip else RGB_r - return k * vector_dot(B, RGB_r) + return k * vecmul(B, RGB_r) diff --git a/colour/colorimetry/transformations.py b/colour/colorimetry/transformations.py index f9e48a60f..178c4b4c2 100644 --- a/colour/colorimetry/transformations.py +++ b/colour/colorimetry/transformations.py @@ -34,7 +34,7 @@ import numpy as np -from colour.algebra import vector_dot +from colour.algebra import vecmul from colour.colorimetry import ( MSDS_CMFS_LMS, MSDS_CMFS_RGB, @@ -116,7 +116,7 @@ def RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs( ] ) - xyz = vector_dot(M1, rgb) / vector_dot(M2, rgb) + xyz = vecmul(M1, rgb) / vecmul(M2, rgb) x, y, z = xyz[..., 0], xyz[..., 1], xyz[..., 2] @@ -183,7 +183,7 @@ def RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs( ] ) - xyz_bar = vector_dot(M, rgb_bar) + xyz_bar = vecmul(M, rgb_bar) return xyz_bar @@ -236,7 +236,7 @@ def RGB_10_degree_cmfs_to_LMS_10_degree_cmfs( ] ) - lms_bar = vector_dot(M, rgb_bar) + lms_bar = vecmul(M, rgb_bar) lms_bar[..., -1][np.asarray(np.asarray(wavelength) > 505)] = 0 return lms_bar @@ -289,7 +289,7 @@ def LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs( ] ) - xyz_bar = vector_dot(M, lms_bar) + xyz_bar = vecmul(M, lms_bar) return xyz_bar @@ -341,6 +341,6 @@ def LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs( ] ) - xyz_bar = vector_dot(M, lms_bar) + xyz_bar = vecmul(M, lms_bar) return xyz_bar diff --git a/colour/io/luts/operator.py b/colour/io/luts/operator.py index ccadf6165..1488e9cad 100644 --- a/colour/io/luts/operator.py +++ b/colour/io/luts/operator.py @@ -14,7 +14,7 @@ import numpy as np -from colour.algebra import vector_dot +from colour.algebra import vecmul from colour.hints import ( Any, ArrayLike, @@ -519,7 +519,7 @@ def apply( if apply_offset_first: RGB += offset - RGB = vector_dot(M, RGB) + RGB = vecmul(M, RGB) if not apply_offset_first: RGB += offset diff --git a/colour/models/common.py b/colour/models/common.py index 3eb22bac0..99003f9c2 100644 --- a/colour/models/common.py +++ b/colour/models/common.py @@ -21,7 +21,7 @@ import numpy as np -from colour.algebra import cartesian_to_polar, polar_to_cartesian, vector_dot +from colour.algebra import cartesian_to_polar, polar_to_cartesian, vecmul from colour.hints import ArrayLike, Callable, NDArrayFloat from colour.utilities import ( CanonicalMapping, @@ -395,9 +395,9 @@ def XYZ_to_Iab( XYZ = to_domain_1(XYZ) - LMS = vector_dot(matrix_XYZ_to_LMS, XYZ) + LMS = vecmul(matrix_XYZ_to_LMS, XYZ) LMS_p = LMS_to_LMS_p_callable(LMS) - Iab = vector_dot(matrix_LMS_p_to_Iab, LMS_p) + Iab = vecmul(matrix_LMS_p_to_Iab, LMS_p) return from_range_1(Iab) @@ -485,8 +485,8 @@ def Iab_to_XYZ( Iab = to_domain_1(Iab) - LMS = vector_dot(matrix_Iab_to_LMS_p, Iab) + LMS = vecmul(matrix_Iab_to_LMS_p, Iab) LMS_p = LMS_p_to_LMS_callable(LMS) - XYZ = vector_dot(matrix_LMS_to_XYZ, LMS_p) + XYZ = vecmul(matrix_LMS_to_XYZ, LMS_p) return from_range_1(XYZ) diff --git a/colour/models/hdr_ipt.py b/colour/models/hdr_ipt.py index 6665df54d..a06d1baad 100644 --- a/colour/models/hdr_ipt.py +++ b/colour/models/hdr_ipt.py @@ -25,7 +25,7 @@ import numpy as np -from colour.algebra import vector_dot +from colour.algebra import vecmul from colour.colorimetry import ( lightness_Fairchild2010, lightness_Fairchild2011, @@ -208,13 +208,13 @@ def XYZ_to_hdr_IPT( e = exponent_hdr_IPT(Y_s, Y_abs, method)[..., None] - LMS = vector_dot(MATRIX_IPT_XYZ_TO_LMS, XYZ) + LMS = vecmul(MATRIX_IPT_XYZ_TO_LMS, XYZ) # Domain and range scaling has already been handled. with domain_range_scale("ignore"): LMS_prime = np.sign(LMS) * np.abs(lightness_callable(LMS, e)) - IPT_hdr = vector_dot(MATRIX_IPT_LMS_P_TO_IPT, LMS_prime) + IPT_hdr = vecmul(MATRIX_IPT_LMS_P_TO_IPT, LMS_prime) return from_range_100(IPT_hdr) @@ -290,12 +290,12 @@ def hdr_IPT_to_XYZ( e = exponent_hdr_IPT(Y_s, Y_abs, method)[..., None] - LMS = vector_dot(MATRIX_IPT_IPT_TO_LMS_P, IPT_hdr) + LMS = vecmul(MATRIX_IPT_IPT_TO_LMS_P, IPT_hdr) # Domain and range scaling has already be handled. with domain_range_scale("ignore"): LMS_prime = np.sign(LMS) * np.abs(luminance_callable(LMS, e)) - XYZ = vector_dot(MATRIX_IPT_LMS_TO_XYZ, LMS_prime) + XYZ = vecmul(MATRIX_IPT_LMS_TO_XYZ, LMS_prime) return from_range_1(XYZ) diff --git a/colour/models/jzazbz.py b/colour/models/jzazbz.py index 7d90879df..95afe3c1f 100644 --- a/colour/models/jzazbz.py +++ b/colour/models/jzazbz.py @@ -25,7 +25,7 @@ import numpy as np -from colour.algebra import vector_dot +from colour.algebra import vecmul from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.models.rgb.transfer_functions import ( eotf_inverse_ST2084, @@ -251,15 +251,15 @@ def XYZ_to_Izazbz( XYZ_p_D65 = tstack([X_p_D65, Y_p_D65, Z_D65]) - LMS = vector_dot(MATRIX_JZAZBZ_XYZ_TO_LMS, XYZ_p_D65) + LMS = vecmul(MATRIX_JZAZBZ_XYZ_TO_LMS, XYZ_p_D65) with domain_range_scale("ignore"): LMS_p = eotf_inverse_ST2084(LMS, 10000, constants) if method == "safdar 2017": - Izazbz = vector_dot(MATRIX_JZAZBZ_LMS_P_TO_IZAZBZ_SAFDAR2017, LMS_p) + Izazbz = vecmul(MATRIX_JZAZBZ_LMS_P_TO_IZAZBZ_SAFDAR2017, LMS_p) else: - Izazbz = vector_dot(MATRIX_JZAZBZ_LMS_P_TO_IZAZBZ_SAFDAR2021, LMS_p) + Izazbz = vecmul(MATRIX_JZAZBZ_LMS_P_TO_IZAZBZ_SAFDAR2021, LMS_p) Izazbz[..., 0] -= constants.d_0 return Izazbz @@ -344,15 +344,15 @@ def Izazbz_to_XYZ( ) if method == "safdar 2017": - LMS_p = vector_dot(MATRIX_JZAZBZ_IZAZBZ_TO_LMS_P_SAFDAR2017, Izazbz) + LMS_p = vecmul(MATRIX_JZAZBZ_IZAZBZ_TO_LMS_P_SAFDAR2017, Izazbz) else: Izazbz[..., 0] += constants.d_0 - LMS_p = vector_dot(MATRIX_JZAZBZ_IZAZBZ_TO_LMS_P_SAFDAR2021, Izazbz) + LMS_p = vecmul(MATRIX_JZAZBZ_IZAZBZ_TO_LMS_P_SAFDAR2021, Izazbz) with domain_range_scale("ignore"): LMS = eotf_ST2084(LMS_p, 10000, constants) - X_p_D65, Y_p_D65, Z_p_D65 = tsplit(vector_dot(MATRIX_JZAZBZ_LMS_TO_XYZ, LMS)) + X_p_D65, Y_p_D65, Z_p_D65 = tsplit(vecmul(MATRIX_JZAZBZ_LMS_TO_XYZ, LMS)) X_D65 = (X_p_D65 + (constants.b - 1) * Z_p_D65) / constants.b Y_D65 = (Y_p_D65 + (constants.g - 1) * X_D65) / constants.g diff --git a/colour/models/osa_ucs.py b/colour/models/osa_ucs.py index f7cf2a646..a129bbe5b 100644 --- a/colour/models/osa_ucs.py +++ b/colour/models/osa_ucs.py @@ -23,7 +23,7 @@ import numpy as np from scipy.optimize import fmin -from colour.algebra import sdiv, sdiv_mode, spow, vector_dot +from colour.algebra import sdiv, sdiv_mode, spow, vecmul from colour.hints import ArrayLike, NDArrayFloat from colour.models import XYZ_to_xyY from colour.utilities import ( @@ -126,7 +126,7 @@ def XYZ_to_OSA_UCS(XYZ: ArrayLike) -> NDArrayFloat: Y_0_s = Y_0 - 30 Lambda = 5.9 * (Y_0_es + 0.042 * spow(Y_0_s, o_3)) - RGB = vector_dot(MATRIX_XYZ_TO_RGB_OSA_UCS, XYZ) + RGB = vecmul(MATRIX_XYZ_TO_RGB_OSA_UCS, XYZ) RGB_3 = spow(RGB, 1 / 3) with sdiv_mode(): diff --git a/colour/models/rgb/hanbury2003.py b/colour/models/rgb/hanbury2003.py index 91a3d9213..28cfbbdd0 100644 --- a/colour/models/rgb/hanbury2003.py +++ b/colour/models/rgb/hanbury2003.py @@ -19,7 +19,7 @@ import numpy as np -from colour.algebra import sdiv, sdiv_mode, vector_dot +from colour.algebra import sdiv, sdiv_mode, vecmul from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( from_range_1, @@ -96,7 +96,7 @@ def RGB_to_IHLS(RGB: ArrayLike) -> NDArrayFloat: RGB = to_domain_1(RGB) R, G, B = tsplit(RGB) - Y, C_1, C_2 = tsplit(vector_dot(MATRIX_RGB_TO_YC_1_C_2, RGB)) + Y, C_1, C_2 = tsplit(vecmul(MATRIX_RGB_TO_YC_1_C_2, RGB)) C = np.hypot(C_1, C_2) @@ -165,6 +165,6 @@ def IHLS_to_RGB(HYS: ArrayLike) -> NDArrayFloat: C_1 = C * np.cos(H) C_2 = -C * np.sin(H) - RGB = vector_dot(MATRIX_YC_1_C_2_TO_RGB, tstack([Y, C_1, C_2])) + RGB = vecmul(MATRIX_YC_1_C_2_TO_RGB, tstack([Y, C_1, C_2])) return from_range_1(RGB) diff --git a/colour/models/rgb/ictcp.py b/colour/models/rgb/ictcp.py index 3d556dcba..2bcca2edc 100644 --- a/colour/models/rgb/ictcp.py +++ b/colour/models/rgb/ictcp.py @@ -29,7 +29,7 @@ import numpy as np -from colour.algebra import vector_dot +from colour.algebra import vecmul from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import ( ArrayLike, @@ -251,15 +251,15 @@ def RGB_to_ICtCp( is_hlg_method = "hlg" in method is_BT2100_2_method = "2100-2" in method - LMS = vector_dot(MATRIX_ICTCP_RGB_TO_LMS, RGB) + LMS = vecmul(MATRIX_ICTCP_RGB_TO_LMS, RGB) with domain_range_scale("ignore"): LMS_p = oetf_BT2100_HLG(LMS) if is_hlg_method else eotf_inverse_ST2084(LMS, L_p) ICtCp = ( - vector_dot(MATRIX_ICTCP_LMS_P_TO_ICTCP_BT2100_HLG_2, LMS_p) + vecmul(MATRIX_ICTCP_LMS_P_TO_ICTCP_BT2100_HLG_2, LMS_p) if (is_hlg_method and is_BT2100_2_method) - else vector_dot(MATRIX_ICTCP_LMS_P_TO_ICTCP, LMS_p) + else vecmul(MATRIX_ICTCP_LMS_P_TO_ICTCP, LMS_p) ) return ICtCp @@ -383,9 +383,9 @@ def ICtCp_to_RGB( is_BT2100_2_method = "2100-2" in method LMS_p = ( - vector_dot(MATRIX_ICTCP_ICTCP_TO_LMS_P_BT2100_HLG_2, ICtCp) + vecmul(MATRIX_ICTCP_ICTCP_TO_LMS_P_BT2100_HLG_2, ICtCp) if (is_hlg_method and is_BT2100_2_method) - else vector_dot(MATRIX_ICTCP_ICTCP_TO_LMS_P, ICtCp) + else vecmul(MATRIX_ICTCP_ICTCP_TO_LMS_P, ICtCp) ) with domain_range_scale("ignore"): @@ -393,7 +393,7 @@ def ICtCp_to_RGB( oetf_inverse_BT2100_HLG(LMS_p) if is_hlg_method else eotf_ST2084(LMS_p, L_p) ) - RGB = vector_dot(MATRIX_ICTCP_LMS_TO_RGB, LMS) + RGB = vecmul(MATRIX_ICTCP_LMS_TO_RGB, LMS) return RGB diff --git a/colour/models/rgb/rgb_colourspace.py b/colour/models/rgb/rgb_colourspace.py index 5e2fac73c..62627ecd5 100644 --- a/colour/models/rgb/rgb_colourspace.py +++ b/colour/models/rgb/rgb_colourspace.py @@ -30,7 +30,7 @@ import numpy as np from colour.adaptation import matrix_chromatic_adaptation_VonKries -from colour.algebra import matrix_dot, vector_dot +from colour.algebra import vecmul from colour.hints import ( Any, ArrayLike, @@ -1049,9 +1049,9 @@ def XYZ_to_RGB( transform=chromatic_adaptation_transform, ) - XYZ = vector_dot(M_CAT, XYZ) + XYZ = vecmul(M_CAT, XYZ) - RGB = vector_dot(matrix_XYZ_to_RGB, XYZ) + RGB = vecmul(matrix_XYZ_to_RGB, XYZ) if apply_cctf_encoding and cctf_encoding is not None: with domain_range_scale("ignore"): @@ -1180,7 +1180,7 @@ def RGB_to_XYZ( with domain_range_scale("ignore"): RGB = cctf_decoding(RGB) - XYZ = vector_dot(matrix_RGB_to_XYZ, RGB) + XYZ = vecmul(matrix_RGB_to_XYZ, RGB) if chromatic_adaptation_transform is not None: M_CAT = matrix_chromatic_adaptation_VonKries( @@ -1189,7 +1189,7 @@ def RGB_to_XYZ( transform=chromatic_adaptation_transform, ) - XYZ = vector_dot(M_CAT, XYZ) + XYZ = vecmul(M_CAT, XYZ) return from_range_1(XYZ) @@ -1266,9 +1266,9 @@ def matrix_RGB_to_RGB( chromatic_adaptation_transform, ) - M = matrix_dot(M_CAT, input_colourspace.matrix_RGB_to_XYZ) + M = np.matmul(M_CAT, input_colourspace.matrix_RGB_to_XYZ) - M = matrix_dot(output_colourspace.matrix_XYZ_to_RGB, M) + M = np.matmul(output_colourspace.matrix_XYZ_to_RGB, M) return M @@ -1375,7 +1375,7 @@ def RGB_to_RGB( input_colourspace, output_colourspace, chromatic_adaptation_transform ) - RGB = vector_dot(M, RGB) + RGB = vecmul(M, RGB) if apply_cctf_encoding and output_colourspace.cctf_encoding is not None: with domain_range_scale("ignore"): diff --git a/colour/models/rgb/ycbcr.py b/colour/models/rgb/ycbcr.py index 6f3eb8d26..7b68aab92 100644 --- a/colour/models/rgb/ycbcr.py +++ b/colour/models/rgb/ycbcr.py @@ -244,12 +244,12 @@ def matrix_YCbCr( Matching the default output of the :func:`colour.RGB_to_YCbCr` is done as follows: - >>> from colour.algebra import vector_dot + >>> from colour.algebra import vecmul >>> from colour.utilities import as_int_array >>> RGB = np.array([1.0, 1.0, 1.0]) >>> RGB_to_YCbCr(RGB) # doctest: +ELLIPSIS array([ 0.9215686..., 0.5019607..., 0.5019607...]) - >>> YCbCr = vector_dot(np.linalg.inv(matrix_YCbCr(is_legal=True)), RGB) + >>> YCbCr = vecmul(np.linalg.inv(matrix_YCbCr(is_legal=True)), RGB) >>> YCbCr += offset_YCbCr(is_legal=True) >>> YCbCr # doctest: +ELLIPSIS array([ 0.9215686..., 0.5019607..., 0.5019607...]) @@ -261,7 +261,7 @@ def matrix_YCbCr( >>> RGB_to_YCbCr(RGB, in_bits=8, in_int=True, out_bits=8, out_int=True) ... # doctest: +SKIP array([ 38, 140, 171]) - >>> YCbCr = vector_dot(np.linalg.inv(matrix_YCbCr(is_legal=True)), RGB) + >>> YCbCr = vecmul(np.linalg.inv(matrix_YCbCr(is_legal=True)), RGB) >>> YCbCr += offset_YCbCr(is_legal=True, is_int=True) >>> as_int_array(np.around(YCbCr)) ... # doctest: +SKIP diff --git a/colour/models/rgb/ycocg.py b/colour/models/rgb/ycocg.py index 5e5741eee..c8d0a324e 100644 --- a/colour/models/rgb/ycocg.py +++ b/colour/models/rgb/ycocg.py @@ -19,7 +19,7 @@ import numpy as np -from colour.algebra import vector_dot +from colour.algebra import vecmul from colour.hints import ArrayLike, NDArrayFloat __author__ = "Colour Developers" @@ -82,7 +82,7 @@ def RGB_to_YCoCg(RGB: ArrayLike) -> NDArrayFloat: array([ 0.5625, 0.125 , -0.0625]) """ - return vector_dot(MATRIX_RGB_TO_YCOCG, RGB) + return vecmul(MATRIX_RGB_TO_YCOCG, RGB) def YCoCg_to_RGB(YCoCg: ArrayLike) -> NDArrayFloat: @@ -112,4 +112,4 @@ def YCoCg_to_RGB(YCoCg: ArrayLike) -> NDArrayFloat: array([ 0.75, 0.5 , 0.5 ]) """ - return vector_dot(MATRIX_YCOCG_TO_RGB, YCoCg) + return vecmul(MATRIX_YCOCG_TO_RGB, YCoCg) diff --git a/colour/models/tests/test_yrg.py b/colour/models/tests/test_yrg.py index 598d42f93..c8d069b60 100644 --- a/colour/models/tests/test_yrg.py +++ b/colour/models/tests/test_yrg.py @@ -225,7 +225,11 @@ def test_domain_range_scale_XYZ_to_Yrg(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_equal(XYZ_to_Yrg(XYZ * factor), Yrg * factor) + np.testing.assert_allclose( + XYZ_to_Yrg(XYZ * factor), + Yrg * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) @ignore_numpy_errors def test_nan_XYZ_to_Yrg(self): diff --git a/colour/models/yrg.py b/colour/models/yrg.py index ccf82c427..cadac4f0c 100644 --- a/colour/models/yrg.py +++ b/colour/models/yrg.py @@ -20,7 +20,7 @@ import numpy as np -from colour.algebra import sdiv, sdiv_mode, vector_dot +from colour.algebra import sdiv, sdiv_mode, vecmul from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( from_range_1, @@ -227,7 +227,7 @@ def XYZ_to_Yrg(XYZ: ArrayLike) -> NDArrayFloat: array([ 0.1313780..., 0.4903764..., 0.3777738...]) """ - return LMS_to_Yrg(vector_dot(MATRIX_XYZ_TO_LMS_KIRK2019, XYZ)) + return LMS_to_Yrg(vecmul(MATRIX_XYZ_TO_LMS_KIRK2019, XYZ)) def Yrg_to_XYZ(Yrg: ArrayLike) -> NDArrayFloat: @@ -274,4 +274,4 @@ def Yrg_to_XYZ(Yrg: ArrayLike) -> NDArrayFloat: array([ 0.2065468..., 0.1219717..., 0.0513819...]) """ - return vector_dot(MATRIX_LMS_TO_XYZ_KIRK2019, Yrg_to_LMS(Yrg)) + return vecmul(MATRIX_LMS_TO_XYZ_KIRK2019, Yrg_to_LMS(Yrg)) diff --git a/colour/plotting/blindness.py b/colour/plotting/blindness.py index 184f144a5..5c9acd34b 100644 --- a/colour/plotting/blindness.py +++ b/colour/plotting/blindness.py @@ -12,7 +12,7 @@ from matplotlib.axes import Axes from matplotlib.figure import Figure -from colour.algebra import vector_dot +from colour.algebra import vecmul from colour.blindness import matrix_cvd_Machado2009 from colour.hints import ( Any, @@ -98,6 +98,6 @@ def plot_cvd_simulation_Machado2009( settings.update(kwargs) return plot_image( - CONSTANTS_COLOUR_STYLE.colour.colourspace.cctf_encoding(vector_dot(M_a, RGB)), + CONSTANTS_COLOUR_STYLE.colour.colourspace.cctf_encoding(vecmul(M_a, RGB)), **settings, ) diff --git a/colour/utilities/__init__.py b/colour/utilities/__init__.py index 63824ef4e..5831d6d45 100644 --- a/colour/utilities/__init__.py +++ b/colour/utilities/__init__.py @@ -247,8 +247,6 @@ "tstack", "tsplit", "row_as_diagonal", - "vector_dot", - "matrix_dot", "orient", "centroid", "linear_conversion", @@ -301,17 +299,13 @@ def __getattr__(self, attribute) -> Any: "colour.utilities.linear_conversion", "colour.algebra.linear_conversion", ], - [ - "colour.utilities.matrix_dot", - "colour.algebra.matrix_dot", - ], [ "colour.utilities.normalise_maximum", "colour.algebra.normalise_maximum", ], [ - "colour.utilities.vector_dot", - "colour.algebra.vector_dot", + "colour.utilities.vecmul", + "colour.algebra.vecmul", ], ], } @@ -335,6 +329,16 @@ def __getattr__(self, attribute) -> Any: API_CHANGES """ +# v0.4.5 +API_CHANGES["ObjectRemoved"] = [ + "colour.algebra.matrix_dot", +] +""" +Define the *colour.utilities* sub-package API changes. + +API_CHANGES +""" + if not is_documentation_building(): sys.modules["colour.utilities"] = utilities( # pyright: ignore sys.modules["colour.utilities"], build_API_changes(API_CHANGES) diff --git a/docs/colour.algebra.rst b/docs/colour.algebra.rst index efb949f41..85a9d5e9f 100644 --- a/docs/colour.algebra.rst +++ b/docs/colour.algebra.rst @@ -125,8 +125,7 @@ Common spow normalise_vector normalise_maximum - vector_dot - matrix_dot + vecmul euclidean_distance manhattan_distance linear_conversion diff --git a/pyproject.toml b/pyproject.toml index 7c3c6e84b..5b26cf54f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ classifiers = [ python = ">= 3.9, < 3.13" imageio = ">= 2, < 3" numpy = ">= 1.22, < 2" -scipy = ">= 1.8, < 2, != 1.13.0" +scipy = ">= 1.8, < 2, != 1.13" typing-extensions = ">= 4, < 5" [tool.poetry.group.optional.dependencies]