------------------------------------------------------------------------------ Solves for the least squares best fit matrix for the equation X'M' = Y'. Uses pseudoinverse to get the ordinary least squares. The inputs and output are transposed matrices. Dimensions: X' is numberOfSamples by xOrder, Y' is numberOfSamples by yOrder, M' dimension is xOrder by yOrder. M' should be pre-allocated. All mat
| 1010 | // the system is known not to be homogeneous, invoke with checkHomogeneous=0. |
| 1011 | // Returns success/fail. |
| 1012 | vtkTypeBool vtkMath::SolveLeastSquares(int numberOfSamples, double** xt, int xOrder, double** yt, |
| 1013 | int yOrder, double** mt, int checkHomogeneous) |
| 1014 | { |
| 1015 | // check dimensional consistency |
| 1016 | if ((numberOfSamples < xOrder) || (numberOfSamples < yOrder)) |
| 1017 | { |
| 1018 | vtkGenericWarningMacro("Insufficient number of samples. Underdetermined."); |
| 1019 | return 0; |
| 1020 | } |
| 1021 | |
| 1022 | int i, j, k; |
| 1023 | |
| 1024 | bool someHomogeneous = false; |
| 1025 | bool allHomogeneous = true; |
| 1026 | double** hmt = nullptr; |
| 1027 | vtkTypeBool homogRC = 0; |
| 1028 | int* homogenFlags = new int[yOrder]; |
| 1029 | vtkTypeBool successFlag; |
| 1030 | |
| 1031 | // Ok, first init some flags check and see if all the systems are homogeneous |
| 1032 | if (checkHomogeneous) |
| 1033 | { |
| 1034 | // If Y' is zero, it's a homogeneous system and can't be solved via |
| 1035 | // the pseudoinverse method. Detect this case, warn the user, and |
| 1036 | // invoke SolveHomogeneousLeastSquares instead. Note that it doesn't |
| 1037 | // really make much sense for yOrder to be greater than one in this case, |
| 1038 | // since that's just yOrder occurrences of a 0 vector on the RHS, but |
| 1039 | // we allow it anyway. N |
| 1040 | |
| 1041 | // Initialize homogeneous flags on a per-right-hand-side basis |
| 1042 | for (j = 0; j < yOrder; ++j) |
| 1043 | { |
| 1044 | homogenFlags[j] = 1; |
| 1045 | } |
| 1046 | for (i = 0; i < numberOfSamples; ++i) |
| 1047 | { |
| 1048 | for (j = 0; j < yOrder; ++j) |
| 1049 | { |
| 1050 | if (std::abs(yt[i][j]) > VTK_SMALL_NUMBER) |
| 1051 | { |
| 1052 | allHomogeneous = false; |
| 1053 | homogenFlags[j] = 0; |
| 1054 | } |
| 1055 | } |
| 1056 | } |
| 1057 | |
| 1058 | // If we've got one system, and it's homogeneous, do it and bail out quickly. |
| 1059 | if (allHomogeneous && yOrder == 1) |
| 1060 | { |
| 1061 | vtkGenericWarningMacro( |
| 1062 | "Detected homogeneous system (Y=0), calling SolveHomogeneousLeastSquares()"); |
| 1063 | delete[] homogenFlags; |
| 1064 | return vtkMath::SolveHomogeneousLeastSquares(numberOfSamples, xt, xOrder, mt); |
| 1065 | } |
| 1066 | |
| 1067 | // Ok, we've got more than one system of equations. |
| 1068 | // Figure out if we need to calculate the homogeneous equation solution for |
| 1069 | // any of them. |
nothing calls this directly
no test coverage detected