Speed up matrix operations (unit-wise, no interface is touched)

This commit is contained in:
Stephan Lenor 2023-03-25 06:06:38 +01:00 committed by Jehan
parent 82d5743e77
commit f5cc64ddd6
2 changed files with 92 additions and 92 deletions

View file

@ -221,27 +221,26 @@ gimp_matrix2_identity (GimpMatrix2 *matrix)
/**
* gimp_matrix2_mult:
* @matrix1: The first input matrix.
* @matrix2: The second input matrix which will be overwritten by the result.
* @left: The first input matrix.
* @right: The second input matrix which will be overwritten by the result.
*
* Multiplies two matrices and puts the result into the second one.
*/
void
gimp_matrix2_mult (const GimpMatrix2 *matrix1,
GimpMatrix2 *matrix2)
gimp_matrix2_mult (const GimpMatrix2 *left,
GimpMatrix2 *right)
{
GimpMatrix2 tmp;
gdouble r00 = right->coeff[0][0];
gdouble r01 = right->coeff[0][1];
tmp.coeff[0][0] = (matrix1->coeff[0][0] * matrix2->coeff[0][0] +
matrix1->coeff[0][1] * matrix2->coeff[1][0]);
tmp.coeff[0][1] = (matrix1->coeff[0][0] * matrix2->coeff[0][1] +
matrix1->coeff[0][1] * matrix2->coeff[1][1]);
tmp.coeff[1][0] = (matrix1->coeff[1][0] * matrix2->coeff[0][0] +
matrix1->coeff[1][1] * matrix2->coeff[1][0]);
tmp.coeff[1][1] = (matrix1->coeff[1][0] * matrix2->coeff[0][1] +
matrix1->coeff[1][1] * matrix2->coeff[1][1]);
*matrix2 = tmp;
right->coeff[0][0] = (left->coeff[0][0] * r00 +
left->coeff[0][1] * right->coeff[1][0]);
right->coeff[0][1] = (left->coeff[0][0] * r01 +
left->coeff[0][1] * right->coeff[1][1]);
right->coeff[1][0] = (left->coeff[1][0] * r00 +
left->coeff[1][1] * right->coeff[1][0]);
right->coeff[1][1] = (left->coeff[1][0] * r01 +
left->coeff[1][1] * right->coeff[1][1]);
}
/**
@ -519,34 +518,36 @@ gimp_matrix3_transform_point (const GimpMatrix3 *matrix,
/**
* gimp_matrix3_mult:
* @matrix1: The first input matrix.
* @matrix2: The second input matrix which will be overwritten by the result.
* @left: The first input matrix.
* @right: The second input matrix which will be overwritten by the result.
*
* Multiplies two matrices and puts the result into the second one.
*/
void
gimp_matrix3_mult (const GimpMatrix3 *matrix1,
GimpMatrix3 *matrix2)
gimp_matrix3_mult (const GimpMatrix3 *left,
GimpMatrix3 *right)
{
gint i, j;
GimpMatrix3 tmp;
gdouble t1, t2, t3;
gint i;
gdouble li0, li1, li2;
gdouble r00 = right->coeff[0][0];
gdouble r01 = right->coeff[0][1];
gdouble r02 = right->coeff[0][2];
gdouble r10 = right->coeff[1][0];
gdouble r11 = right->coeff[1][1];
gdouble r12 = right->coeff[1][2];
gdouble r20 = right->coeff[2][0];
gdouble r21 = right->coeff[2][1];
gdouble r22 = right->coeff[2][2];
for (i = 0; i < 3; i++)
{
t1 = matrix1->coeff[i][0];
t2 = matrix1->coeff[i][1];
t3 = matrix1->coeff[i][2];
for (j = 0; j < 3; j++)
{
tmp.coeff[i][j] = t1 * matrix2->coeff[0][j];
tmp.coeff[i][j] += t2 * matrix2->coeff[1][j];
tmp.coeff[i][j] += t3 * matrix2->coeff[2][j];
}
li0 = left->coeff[i][0];
li1 = left->coeff[i][1];
li2 = left->coeff[i][2];
right->coeff[i][0] = li0 * r00 + li1 * r10 + li2 * r20;
right->coeff[i][1] = li0 * r01 + li1 * r11 + li2 * r21;
right->coeff[i][2] = li0 * r02 + li1 * r12 + li2 * r22;
}
*matrix2 = tmp;
}
/**
@ -718,19 +719,15 @@ gimp_matrix3_affine (GimpMatrix3 *matrix,
gdouble
gimp_matrix3_determinant (const GimpMatrix3 *matrix)
{
gdouble determinant;
determinant = (matrix->coeff[0][0] *
(matrix->coeff[1][1] * matrix->coeff[2][2] -
matrix->coeff[1][2] * matrix->coeff[2][1]));
determinant -= (matrix->coeff[1][0] *
(matrix->coeff[0][1] * matrix->coeff[2][2] -
matrix->coeff[0][2] * matrix->coeff[2][1]));
determinant += (matrix->coeff[2][0] *
(matrix->coeff[0][1] * matrix->coeff[1][2] -
matrix->coeff[0][2] * matrix->coeff[1][1]));
return determinant;
gdouble m01 = matrix->coeff[0][1];
gdouble m02 = matrix->coeff[0][2];
gdouble m11 = matrix->coeff[1][1];
gdouble m12 = matrix->coeff[1][2];
gdouble m21 = matrix->coeff[2][1];
gdouble m22 = matrix->coeff[2][2];
return matrix->coeff[0][0] * (m11 * m22 - m12 * m21)
- matrix->coeff[1][0] * (m01 * m22 - m02 * m21)
+ matrix->coeff[2][0] * (m01 * m12 - m02 * m11);
}
/**
@ -742,44 +739,40 @@ gimp_matrix3_determinant (const GimpMatrix3 *matrix)
void
gimp_matrix3_invert (GimpMatrix3 *matrix)
{
GimpMatrix3 inv;
gdouble det;
gdouble det;
gdouble m00 = matrix->coeff[0][0];
gdouble m01 = matrix->coeff[0][1];
gdouble m02 = matrix->coeff[0][2];
gdouble m10 = matrix->coeff[1][0];
gdouble m11 = matrix->coeff[1][1];
gdouble m12 = matrix->coeff[1][2];
gdouble m20 = matrix->coeff[2][0];
gdouble m21 = matrix->coeff[2][1];
gdouble m22 = matrix->coeff[2][2];
det = gimp_matrix3_determinant (matrix);
/* To avoid redundant access to the coefficients, inline the determinant
* formula.
*
* See: https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/880#note_1727051
*/
det = m00 * (m11 * m22 - m12 * m21)
- m10 * (m01 * m22 - m02 * m21)
+ m20 * (m01 * m12 - m02 * m11);
if (det == 0.0)
return;
det = 1.0 / det;
inv.coeff[0][0] = (matrix->coeff[1][1] * matrix->coeff[2][2] -
matrix->coeff[1][2] * matrix->coeff[2][1]) * det;
inv.coeff[1][0] = - (matrix->coeff[1][0] * matrix->coeff[2][2] -
matrix->coeff[1][2] * matrix->coeff[2][0]) * det;
inv.coeff[2][0] = (matrix->coeff[1][0] * matrix->coeff[2][1] -
matrix->coeff[1][1] * matrix->coeff[2][0]) * det;
inv.coeff[0][1] = - (matrix->coeff[0][1] * matrix->coeff[2][2] -
matrix->coeff[0][2] * matrix->coeff[2][1]) * det;
inv.coeff[1][1] = (matrix->coeff[0][0] * matrix->coeff[2][2] -
matrix->coeff[0][2] * matrix->coeff[2][0]) * det;
inv.coeff[2][1] = - (matrix->coeff[0][0] * matrix->coeff[2][1] -
matrix->coeff[0][1] * matrix->coeff[2][0]) * det;
inv.coeff[0][2] = (matrix->coeff[0][1] * matrix->coeff[1][2] -
matrix->coeff[0][2] * matrix->coeff[1][1]) * det;
inv.coeff[1][2] = - (matrix->coeff[0][0] * matrix->coeff[1][2] -
matrix->coeff[0][2] * matrix->coeff[1][0]) * det;
inv.coeff[2][2] = (matrix->coeff[0][0] * matrix->coeff[1][1] -
matrix->coeff[0][1] * matrix->coeff[1][0]) * det;
*matrix = inv;
matrix->coeff[0][0] = (m11 * m22 - m12 * m21) * det;
matrix->coeff[1][0] = - (m10 * m22 - m12 * m20) * det;
matrix->coeff[2][0] = (m10 * m21 - m11 * m20) * det;
matrix->coeff[0][1] = - (m01 * m22 - m02 * m21) * det;
matrix->coeff[1][1] = (m00 * m22 - m02 * m20) * det;
matrix->coeff[2][1] = - (m00 * m21 - m01 * m20) * det;
matrix->coeff[0][2] = (m01 * m12 - m02 * m11) * det;
matrix->coeff[1][2] = - (m00 * m12 - m02 * m10) * det;
matrix->coeff[2][2] = (m00 * m11 - m01 * m10) * det;
}
@ -942,30 +935,37 @@ gimp_matrix4_identity (GimpMatrix4 *matrix)
/**
* gimp_matrix4_mult:
* @matrix1: The first input matrix.
* @matrix2: The second input matrix which will be overwritten by the result.
* @left: The first input matrix.
* @right: The second input matrix which will be overwritten by the result.
*
* Multiplies two matrices and puts the result into the second one.
*
* Since: 2.10.16
*/
void
gimp_matrix4_mult (const GimpMatrix4 *matrix1,
GimpMatrix4 *matrix2)
gimp_matrix4_mult (const GimpMatrix4 *left,
GimpMatrix4 *right)
{
GimpMatrix4 result = {};
gint i, j, k;
gint i, j;
gdouble li0, li1, li2, li3;
for (i = 0; i < 4; i++)
{
li0 = left->coeff[i][0];
li1 = left->coeff[i][1];
li2 = left->coeff[i][2];
li3 = left->coeff[i][3];
for (j = 0; j < 4; j++)
{
for (k = 0; k < 4; k++)
result.coeff[i][j] += matrix1->coeff[i][k] * matrix2->coeff[k][j];
result.coeff[i][j] = li0 * right->coeff[0][j]
+ li1 * right->coeff[1][j]
+ li2 * right->coeff[2][j]
+ li3 * right->coeff[3][j];
}
}
*matrix2 = result;
*right = result;
}
/**

View file

@ -54,8 +54,8 @@ GParamSpec * gimp_param_spec_matrix2 (const gchar *name,
void gimp_matrix2_identity (GimpMatrix2 *matrix);
void gimp_matrix2_mult (const GimpMatrix2 *matrix1,
GimpMatrix2 *matrix2);
void gimp_matrix2_mult (const GimpMatrix2 *left,
GimpMatrix2 *right);
gdouble gimp_matrix2_determinant (const GimpMatrix2 *matrix);
void gimp_matrix2_invert (GimpMatrix2 *matrix);
@ -90,8 +90,8 @@ GParamSpec * gimp_param_spec_matrix3 (const gchar *name,
void gimp_matrix3_identity (GimpMatrix3 *matrix);
void gimp_matrix3_mult (const GimpMatrix3 *matrix1,
GimpMatrix3 *matrix2);
void gimp_matrix3_mult (const GimpMatrix3 *left,
GimpMatrix3 *right);
void gimp_matrix3_translate (GimpMatrix3 *matrix,
gdouble x,
gdouble y);
@ -135,8 +135,8 @@ void gimp_matrix3_transform_point (const GimpMatrix3 *matrix,
/*****************/
void gimp_matrix4_identity (GimpMatrix4 *matrix);
void gimp_matrix4_mult (const GimpMatrix4 *matrix1,
GimpMatrix4 *matrix2);
void gimp_matrix4_mult (const GimpMatrix4 *left,
GimpMatrix4 *right);
void gimp_matrix4_to_deg (const GimpMatrix4 *matrix,
gdouble *a,