summaryrefslogtreecommitdiff
path: root/common/math_util.c
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-08-17 14:58:32 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-08-24 19:08:20 +0000
commit0e01759cedcd25868196508177791388b89450e5 (patch)
treed361152082ad7a92a37d3e5fb9d7981202c40b19 /common/math_util.c
parentde42bb285fa45a777ed7a27be9f4c99c8f606ed8 (diff)
downloadchrome-ec-0e01759cedcd25868196508177791388b89450e5.tar.gz
math: Add inverse matrix calculation
Add a slow inverse matrix calculation function. It is needed to apply factory offset properly. Also consider the NULL matrix the identity matrix. BRANCH=smaug,cyan TEST=Unit test BUG=chromium:517675 Change-Id: Ifa11954992e6f2fab02b4e92684e7b01bbaafe94 Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/294594 Reviewed-by: Sheng-liang Song <ssl@chromium.org>
Diffstat (limited to 'common/math_util.c')
-rw-r--r--common/math_util.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/common/math_util.c b/common/math_util.c
index 120d13d63f..4077590c1a 100644
--- a/common/math_util.c
+++ b/common/math_util.c
@@ -166,6 +166,13 @@ void rotate(const vector_3_t v, const matrix_3x3_t R, vector_3_t res)
{
int64_t t[3];
+ if (R == NULL) {
+ if (v != res)
+ memcpy(res, v, sizeof(*v));
+ return;
+ }
+
+
/* Rotate */
t[0] = (int64_t)v[0] * R[0][0] +
(int64_t)v[1] * R[1][0] +
@@ -182,3 +189,53 @@ void rotate(const vector_3_t v, const matrix_3x3_t R, vector_3_t res)
res[1] = t[1] >> FP_BITS;
res[2] = t[2] >> FP_BITS;
}
+
+void rotate_inv(const vector_3_t v, const matrix_3x3_t R, vector_3_t res)
+{
+ int64_t t[3];
+ fp_t deter;
+
+ if (R == NULL) {
+ if (v != res)
+ memcpy(res, v, sizeof(*v));
+ return;
+ }
+
+ deter = fp_mul(R[0][0], (fp_mul(R[1][1], R[2][2]) -
+ fp_mul(R[2][1], R[1][2]))) -
+ fp_mul(R[0][1], (fp_mul(R[1][0], R[2][2]) -
+ fp_mul(R[1][2], R[2][0]))) +
+ fp_mul(R[0][2], (fp_mul(R[1][0], R[2][1]) -
+ fp_mul(R[1][1], R[2][0])));
+
+ /*
+ * invert the matrix: from
+ * http://stackoverflow.com/questions/983999/
+ * simple-3x3-matrix-inverse-code-c
+ */
+ t[0] = (int64_t)v[0] * (fp_mul(R[1][1], R[2][2]) -
+ fp_mul(R[2][1], R[1][2])) -
+ (int64_t)v[1] * (fp_mul(R[1][0], R[2][2]) -
+ fp_mul(R[1][2], R[2][0])) +
+ (int64_t)v[2] * (fp_mul(R[1][0], R[2][1]) -
+ fp_mul(R[2][0], R[1][1]));
+
+ t[1] = (int64_t)v[0] * (fp_mul(R[0][1], R[2][2]) -
+ fp_mul(R[0][2], R[2][1])) * -1 +
+ (int64_t)v[1] * (fp_mul(R[0][0], R[2][2]) -
+ fp_mul(R[0][2], R[2][0])) -
+ (int64_t)v[2] * (fp_mul(R[0][0], R[2][1]) -
+ fp_mul(R[2][0], R[0][1]));
+
+ t[2] = (int64_t)v[0] * (fp_mul(R[0][1], R[1][2]) -
+ fp_mul(R[0][2], R[1][1])) -
+ (int64_t)v[1] * (fp_mul(R[0][0], R[1][2]) -
+ fp_mul(R[1][0], R[0][2])) +
+ (int64_t)v[2] * (fp_mul(R[0][0], R[1][1]) -
+ fp_mul(R[1][0], R[0][1]));
+
+ /* Scale by fixed point shift when writing back to result */
+ res[0] = fp_div(t[0], deter) >> FP_BITS;
+ res[1] = fp_div(t[1], deter) >> FP_BITS;
+ res[2] = fp_div(t[2], deter) >> FP_BITS;
+}