summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/libcamera/internal/matrix.h71
-rw-r--r--include/libcamera/internal/vector.h17
-rw-r--r--include/libcamera/meson.build1
3 files changed, 60 insertions, 29 deletions
diff --git a/include/libcamera/internal/matrix.h b/include/libcamera/internal/matrix.h
index a055e692..47513b99 100644
--- a/include/libcamera/internal/matrix.h
+++ b/include/libcamera/internal/matrix.h
@@ -8,6 +8,7 @@
#include <algorithm>
#include <sstream>
+#include <type_traits>
#include <vector>
#include <libcamera/base/log.h>
@@ -20,17 +21,19 @@ namespace libcamera {
LOG_DECLARE_CATEGORY(Matrix)
#ifndef __DOXYGEN__
-template<typename T, unsigned int Rows, unsigned int Cols,
- std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
-#else
-template<typename T, unsigned int Rows, unsigned int Cols>
+template<typename T>
+bool matrixInvert(Span<const T> dataIn, Span<T> dataOut, unsigned int dim,
+ Span<T> scratchBuffer, Span<unsigned int> swapBuffer);
#endif /* __DOXYGEN__ */
+
+template<typename T, unsigned int Rows, unsigned int Cols>
class Matrix
{
+ static_assert(std::is_arithmetic_v<T>, "Matrix type must be arithmetic");
+
public:
- Matrix()
+ constexpr Matrix()
{
- data_.fill(static_cast<T>(0));
}
Matrix(const std::array<T, Rows * Cols> &data)
@@ -38,7 +41,12 @@ public:
std::copy(data.begin(), data.end(), data_.begin());
}
- static Matrix identity()
+ Matrix(const Span<const T, Rows * Cols> data)
+ {
+ std::copy(data.begin(), data.end(), data_.begin());
+ }
+
+ static constexpr Matrix identity()
{
Matrix ret;
for (size_t i = 0; i < std::min(Rows, Cols); i++)
@@ -66,14 +74,14 @@ public:
return out.str();
}
- Span<const T, Rows * Cols> data() const { return data_; }
+ constexpr Span<const T, Rows * Cols> data() const { return data_; }
- Span<const T, Cols> operator[](size_t i) const
+ constexpr Span<const T, Cols> operator[](size_t i) const
{
return Span<const T, Cols>{ &data_.data()[i * Cols], Cols };
}
- Span<T, Cols> operator[](size_t i)
+ constexpr Span<T, Cols> operator[](size_t i)
{
return Span<T, Cols>{ &data_.data()[i * Cols], Cols };
}
@@ -90,8 +98,30 @@ public:
return *this;
}
+ Matrix<T, Rows, Cols> inverse(bool *ok = nullptr) const
+ {
+ static_assert(Rows == Cols, "Matrix must be square");
+
+ Matrix<T, Rows, Cols> inverse;
+ std::array<T, Rows * Cols * 2> scratchBuffer;
+ std::array<unsigned int, Rows> swapBuffer;
+ bool res = matrixInvert(Span<const T>(data_),
+ Span<T>(inverse.data_),
+ Rows,
+ Span<T>(scratchBuffer),
+ Span<unsigned int>(swapBuffer));
+ if (ok)
+ *ok = res;
+ return inverse;
+ }
+
private:
- std::array<T, Rows * Cols> data_;
+ /*
+ * \todo The initializer is only necessary for the constructor to be
+ * constexpr in C++17. Remove the initializer as soon as we are on
+ * C++20.
+ */
+ std::array<T, Rows * Cols> data_ = {};
};
#ifndef __DOXYGEN__
@@ -123,21 +153,16 @@ Matrix<U, Rows, Cols> operator*(const Matrix<U, Rows, Cols> &m, T d)
return d * m;
}
-#ifndef __DOXYGEN__
-template<typename T,
- unsigned int R1, unsigned int C1,
- unsigned int R2, unsigned int C2,
- std::enable_if_t<C1 == R2> * = nullptr>
-#else
-template<typename T, unsigned int R1, unsigned int C1, unsigned int R2, unsigned in C2>
-#endif /* __DOXYGEN__ */
-Matrix<T, R1, C2> operator*(const Matrix<T, R1, C1> &m1, const Matrix<T, R2, C2> &m2)
+template<typename T1, unsigned int R1, unsigned int C1, typename T2, unsigned int R2, unsigned int C2>
+constexpr Matrix<std::common_type_t<T1, T2>, R1, C2> operator*(const Matrix<T1, R1, C1> &m1,
+ const Matrix<T2, R2, C2> &m2)
{
- Matrix<T, R1, C2> result;
+ static_assert(C1 == R2, "Matrix dimensions must match for multiplication");
+ Matrix<std::common_type_t<T1, T2>, R1, C2> result;
for (unsigned int i = 0; i < R1; i++) {
for (unsigned int j = 0; j < C2; j++) {
- T sum = 0;
+ std::common_type_t<T1, T2> sum = 0;
for (unsigned int k = 0; k < C1; k++)
sum += m1[i][k] * m2[k][j];
@@ -150,7 +175,7 @@ Matrix<T, R1, C2> operator*(const Matrix<T, R1, C1> &m1, const Matrix<T, R2, C2>
}
template<typename T, unsigned int Rows, unsigned int Cols>
-Matrix<T, Rows, Cols> operator+(const Matrix<T, Rows, Cols> &m1, const Matrix<T, Rows, Cols> &m2)
+constexpr Matrix<T, Rows, Cols> operator+(const Matrix<T, Rows, Cols> &m1, const Matrix<T, Rows, Cols> &m2)
{
Matrix<T, Rows, Cols> result;
diff --git a/include/libcamera/internal/vector.h b/include/libcamera/internal/vector.h
index a67a0947..16b6aef0 100644
--- a/include/libcamera/internal/vector.h
+++ b/include/libcamera/internal/vector.h
@@ -13,6 +13,7 @@
#include <numeric>
#include <optional>
#include <ostream>
+#include <type_traits>
#include <libcamera/base/log.h>
#include <libcamera/base/span.h>
@@ -42,8 +43,12 @@ public:
constexpr Vector(const std::array<T, Rows> &data)
{
- for (unsigned int i = 0; i < Rows; i++)
- data_[i] = data[i];
+ std::copy(data.begin(), data.end(), data_.begin());
+ }
+
+ constexpr Vector(const Span<const T, Rows> data)
+ {
+ std::copy(data.begin(), data.end(), data_.begin());
}
const T &operator[](size_t i) const
@@ -291,13 +296,13 @@ private:
template<typename T>
using RGB = Vector<T, 3>;
-template<typename T, unsigned int Rows, unsigned int Cols>
-Vector<T, Rows> operator*(const Matrix<T, Rows, Cols> &m, const Vector<T, Cols> &v)
+template<typename T, typename U, unsigned int Rows, unsigned int Cols>
+Vector<std::common_type_t<T, U>, Rows> operator*(const Matrix<T, Rows, Cols> &m, const Vector<U, Cols> &v)
{
- Vector<T, Rows> result;
+ Vector<std::common_type_t<T, U>, Rows> result;
for (unsigned int i = 0; i < Rows; i++) {
- T sum = 0;
+ std::common_type_t<T, U> sum = 0;
for (unsigned int j = 0; j < Cols; j++)
sum += m[i][j] * v[j];
result[i] = sum;
diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build
index 9297f3fa..30ea76f9 100644
--- a/include/libcamera/meson.build
+++ b/include/libcamera/meson.build
@@ -90,6 +90,7 @@ foreach mode, entry : controls_map
command : [gen_controls, '-o', '@OUTPUT@',
'--mode', mode, '-t', template_file,
'-r', ranges_file, '@INPUT@'],
+ depend_files : [py_mod_controls],
env : py_build_env,
install : true,
install_dir : libcamera_headers_install_dir)