• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "base/geometry/least_square_impl.h"
17 
18 #include "base/geometry/matrix3.h"
19 #include "base/geometry/matrix4.h"
20 #include "base/log/log.h"
21 
22 namespace OHOS::Ace {
GetLeastSquareParams(std::vector<double> & params)23 bool LeastSquareImpl::GetLeastSquareParams(std::vector<double>& params)
24 {
25     if (xVals_.size() <= 1 || ((paramsNum_ != Matrix3::DIMENSION) && (paramsNum_ != Matrix4::DIMENSION))) {
26         LOGE("size is invalid, %{public}d, %{public}d", static_cast<int32_t>(xVals_.size()), paramsNum_);
27         return false;
28     }
29     params.resize(paramsNum_, 0);
30     if (isResolved_) {
31         params.assign(params_.begin(), params_.end());
32         return true;
33     }
34     auto countNum = std::min(countNum_, static_cast<int32_t>(std::distance(xVals_.begin(), xVals_.end())));
35     std::vector<double> xVals;
36     xVals.resize(countNum, 0);
37     std::vector<double> yVals;
38     yVals.resize(countNum, 0);
39     int32_t size = countNum - 1;
40     for (auto iter = xVals_.rbegin(); iter != xVals_.rend(); iter++) {
41         xVals[size] = *iter;
42         size--;
43         if (size < 0) {
44             break;
45         }
46     }
47     size = countNum - 1;
48     for (auto iter = yVals_.rbegin(); iter != yVals_.rend(); iter++) {
49         yVals[size] = *iter;
50         size--;
51         if (size < 0) {
52             break;
53         }
54     }
55     if (paramsNum_ == Matrix3::DIMENSION) {
56         MatrixN3 matrixn3 { countNum };
57         for (auto i = 0; i < countNum; i++) {
58             const auto& value = xVals[i];
59             matrixn3[i][2] = 1;
60             matrixn3[i][1] = value;
61             matrixn3[i][0] = value * value;
62         }
63         Matrix3 invert;
64         auto transpose = matrixn3.Transpose();
65         if (!(transpose * matrixn3).Invert(invert)) {
66             LOGE("fail to invert");
67             return false;
68         }
69         auto matrix3n = invert * transpose;
70         auto ret = matrix3n.MapScalars(yVals, params);
71         if (ret) {
72             params_.assign(params.begin(), params.end());
73             isResolved_ = true;
74         }
75         return ret;
76     }
77     MatrixN4 matrixn4 { countNum };
78     for (auto i = 0; i < countNum; i++) {
79         const auto& value = xVals[i];
80         matrixn4[i][3] = 1;
81         matrixn4[i][2] = value;
82         matrixn4[i][1] = value * value;
83         matrixn4[i][0] = value * value * value;
84     }
85     auto transpose = matrixn4.Transpose();
86     auto inversMatrix4 = Matrix4::Invert(transpose * matrixn4);
87     auto matrix4n = inversMatrix4 * transpose;
88     auto ret = matrix4n.MapScalars(yVals, params);
89     if (ret) {
90         params_.assign(params.begin(), params.end());
91         isResolved_ = true;
92     }
93     return ret;
94 }
95 } // namespace OHOS::Ace
96