в случае матрицы вращения (не однородной), если матрица идентична, то:
- abs значение каждой строки и столбца равно
1.0
- точка между любыми двумя строками равна
0.0
- точка между любыми двумя строками равна
0.0
- нет двух строк равны
- никакие два столбца не равны
, поэтому просто проверьте все строки или столбцы с некоторым порогом. Для «близко к» вы могли бы построить счет. Например, что-то вроде этого:
m[n][m]; // your n x m matrix
score=0.0; // score
for (i=0;i<n;i++) // abs value of rows
{
a=0.0;
for (j=0;j<m;j++ ) a += m[i][j]*m[i][j];
score+=abs(1.0-sqrt(a))/n;
}
for (i=0;i<n;i++) // dot between rows
for (j=i+1;j<n;j++)
{
a=0.0;
for (k=0;k<m;k++ ) a += m[i][k]*m[j][k];
score+=abs(a)/(n*n);
}
Теперь score
должно содержать некоторое значение. чем ближе к нулю, тем ближе к тождеству матрица. чем больше значение, тем менее близко к идентичности. Итак:
if (score<threshold) matrix_is_identity;
где порог - это какое-то небольшое значение, такое как 1e-3
, в зависимости от того, что вы считаете «близким» к идентичности. Я построил пример оценки, поэтому он должен быть инвариантным по размеру матрицы. Вы можете добавить весовые коэффициенты между размерами и точечными произведениями или добавить собственные тесты ... Первая часть оценки показывает, насколько далеко ваши базисные векторы от размера единицы, а вторая часть определяет перпендикулярность ваших базисных векторов.
В в некоторых случаях лучше набрать max
вместо +=
, например:
score = max(score,a);
вместо:
score+= a/n;
или:
score+= a/(n*n);
зависит от поведения, которое вы хотите ...