From e3f641c2bb9dadc8c39da36c6cea7eeb2f12421a Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 12 May 2023 11:25:54 +0200 Subject: [PATCH] fix: LA support fixed --- conanfile.py | 14 +- docs/usage.rst | 36 +++- docs/use_cases/linear_algebra.rst | 16 +- example/aliases/CMakeLists.txt | 9 +- example/aliases/linear_algebra.cpp | 176 +++-------------- example/literals/CMakeLists.txt | 9 +- example/literals/linear_algebra.cpp | 176 +++-------------- example/references/CMakeLists.txt | 9 +- example/references/linear_algebra.cpp | 177 +++--------------- src/CMakeLists.txt | 3 + src/core/include/units/bits/basic_concepts.h | 18 +- src/core/include/units/customization_points.h | 4 + src/core/include/units/quantity_cast.h | 10 + 13 files changed, 162 insertions(+), 495 deletions(-) diff --git a/conanfile.py b/conanfile.py index 4ff1a253..6004c142 100644 --- a/conanfile.py +++ b/conanfile.py @@ -78,7 +78,11 @@ class MPUnitsConan(ConanFile): @property def _build_all(self): - return bool(self.conf.get("user.build:all", default=True)) + return bool(self.conf.get("user.build:all", default=False)) + + @property + def _skip_la(self): + return bool(self.conf.get("user.build:skip_la", default=False)) @property def _skip_docs(self): @@ -114,9 +118,10 @@ class MPUnitsConan(ConanFile): def build_requirements(self): if self._build_all: self.test_requires("catch2/3.1.0") - self.test_requires("wg21-linear_algebra/0.7.3") - if not self._skip_docs: - self.tool_requires("doxygen/1.9.4") + if not self._skip_la: + self.test_requires("wg21-linear_algebra/0.7.3") + if not self._skip_docs: + self.tool_requires("doxygen/1.9.4") def validate(self): check_min_cppstd(self, self._min_cppstd) @@ -140,6 +145,7 @@ class MPUnitsConan(ConanFile): def generate(self): tc = CMakeToolchain(self) tc.variables["UNITS_DOWNCAST_MODE"] = str(self.options.downcast_mode).upper() + tc.variables["UNITS_BUILD_LA"] = self._build_all and not self._skip_la tc.variables["UNITS_BUILD_DOCS"] = self._build_all and not self._skip_docs tc.variables["UNITS_USE_LIBFMT"] = self._use_libfmt tc.generate() diff --git a/docs/usage.rst b/docs/usage.rst index 5c5bc9c1..5de27a80 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -146,8 +146,8 @@ Specifies how :ref:`design/downcasting:The Downcasting Facility` works: Conan Configuration Properties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -build_all -+++++++++ +user.build:all +++++++++++++++ **Values**: ``True``/``False`` @@ -158,14 +158,24 @@ To support this it requires some additional Conan build dependencies described i `Repository Structure and Dependencies`_. It also runs unit tests during Conan build (unless ``tools.build:skip_test`` configuration property is set to ``True``) -skip_docs -+++++++++ +user.build:skip_la +++++++++++++++++++ **Values**: ``True``/``False`` **Defaulted to**: ``False`` -If `build_all`_ is enabled, among others, Conan installs the documentation generation dependencies (i.e. doxygen) and +If `user.build:all`_ is enabled, among others, Conan installs the external `wg21-linear_algebra`_ +dependency and enables compilation of linear algebra based usage examples. Such behavior can be disabled with this option. + +user.build:skip_docs +++++++++++++++++++++ + +**Values**: ``True``/``False`` + +**Defaulted to**: ``False`` + +If `user.build:all`_ is enabled, among others, Conan installs the documentation generation dependencies (i.e. doxygen) and turns on the project documentation generation. Such behavior can be disabled with this option. CMake Options @@ -181,6 +191,16 @@ UNITS_AS_SYSTEM_HEADERS Exports library as system headers. +UNITS_BUILD_LA +++++++++++++++ + +**Values**: ``ON``/``OFF`` + +**Defaulted to**: ``ON`` + +Enables building code depending on the linear algebra library. + + UNITS_BUILD_DOCS ++++++++++++++++ @@ -414,8 +434,8 @@ In case you would like to build all the source code (with unit tests and example you should: 1. Use the *CMakeLists.txt* from the top-level directory. -2. Run Conan with `build_all`_ = ``True`` - (use ``-o build_docs=False`` if you want to skip the documentation generation). +2. Run Conan with `user.build:all`_ = ``True`` + (use ``-c user.build:skip_docs=True`` if you want to skip the documentation generation). .. code-block:: shell @@ -443,7 +463,7 @@ In case you would like to build the project's documentation, you should: 1. Use the *CMakeLists.txt* from the top-level directory. 2. Obtain Python dependencies. -3. Run Conan with `build_all`_ = ``True``. +3. Run Conan with `user.build:all`_ = ``True``. .. code-block:: shell diff --git a/docs/use_cases/linear_algebra.rst b/docs/use_cases/linear_algebra.rst index bb3c1111..0aa7de52 100644 --- a/docs/use_cases/linear_algebra.rst +++ b/docs/use_cases/linear_algebra.rst @@ -14,7 +14,7 @@ enough to be used with other Linear Algebra libraries existing on the market. or `Conan `_. Also, to simplify the examples all of them assume:: - using namespace std::math; + using namespace STD_LA; Linear Algebra of Quantities @@ -27,16 +27,16 @@ The official :term:`quantity` definition states: So the most common use case would be to create a vector or matrix of quantities:: - fs_vector, 3> v = { 1 * m, 2 * m, 3 * m }; - fs_vector, 3> u = { 3 * m, 2 * m, 1 * m }; - fs_vector, 3> t = { 3 * km, 2 * km, 1 * km }; + fixed_size_column_vector, 3> v = { 1 * m, 2 * m, 3 * m }; + fixed_size_column_vector, 3> u = { 3 * m, 2 * m, 1 * m }; + fixed_size_column_vector, 3> t = { 3 * km, 2 * km, 1 * km }; Having such definitions we can perform full dimensional analysis operations for the operations allowed by the Linear Algebra rules. For example:: std::cout << "v + u = " << v + u << "\n"; std::cout << "v + t = " << v + t << "\n"; - std::cout << "t[m] = " << fs_vector, 3>(t) << "\n"; + std::cout << "t[m] = " << fixed_size_column_vector, 3>(t) << "\n"; std::cout << "v * u = " << v * u << "\n"; std::cout << "2 * m * v = " << 2 * m * v << "\n"; @@ -66,9 +66,9 @@ types provided to a `quantity` class template. With this the above vector definitions can be rewritten as follows:: - si::length> v(fs_vector{ 1, 2, 3 }); - si::length> u(fs_vector{ 3, 2, 1 }); - si::length> t(fs_vector{ 3, 2, 1 }); + si::length> v(fixed_size_column_vector{ 1, 2, 3 }); + si::length> u(fixed_size_column_vector{ 3, 2, 1 }); + si::length> t(fixed_size_column_vector{ 3, 2, 1 }); Now the same code doing basic Linear Algebra operations will provide the following output: diff --git a/example/aliases/CMakeLists.txt b/example/aliases/CMakeLists.txt index 089b4770..1d40e9c5 100644 --- a/example/aliases/CMakeLists.txt +++ b/example/aliases/CMakeLists.txt @@ -57,8 +57,9 @@ if(NOT ${projectPrefix}LIBCXX) glide_computer_example-aliases PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_REFERENCES ) - # TODO uncomment the below when recipes in ConanCenter are fixed - # find_package(wg21_linear_algebra CONFIG REQUIRED) - # add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) - # target_link_libraries(linear_algebra-aliases PRIVATE wg21_linear_algebra::wg21_linear_algebra) + if(${projectPrefix}BUILD_LA) + find_package(wg21_linear_algebra CONFIG REQUIRED) + add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) + target_link_libraries(linear_algebra-aliases PRIVATE wg21_linear_algebra::wg21_linear_algebra) + endif() endif() diff --git a/example/aliases/linear_algebra.cpp b/example/aliases/linear_algebra.cpp index 3ed4897a..fcd8c622 100644 --- a/example/aliases/linear_algebra.cpp +++ b/example/aliases/linear_algebra.cpp @@ -27,12 +27,18 @@ #include // IWYU pragma: keep #include #include -#include +#include + +template +using vector = STD_LA::fixed_size_column_vector; + +template +using matrix = STD_LA::fixed_size_matrix; namespace STD_LA { -template -std::ostream& operator<<(std::ostream& os, const vector& v) +template +std::ostream& operator<<(std::ostream& os, const ::vector& v) { os << "|"; for (auto i = 0U; i < v.size(); ++i) { @@ -42,8 +48,8 @@ std::ostream& operator<<(std::ostream& os, const vector& v) return os; } -template -std::ostream& operator<<(std::ostream& os, const matrix& v) +template +std::ostream& operator<<(std::ostream& os, const ::matrix& v) { for (auto i = 0U; i < v.rows(); ++i) { os << "|"; @@ -61,18 +67,11 @@ namespace { using namespace units::aliases::isq::si; -template -using vector = std::math::fs_vector; - -template -using matrix = std::math::fs_matrix; - - void vector_of_quantity_add() { std::cout << "\nvector_of_quantity_add:\n"; - vector> v = {m<>(1), m<>(2), m<>(3)}; + vector> v = {m<>(4), m<>(8), m<>(12)}; vector> u = {m<>(3), m<>(2), m<>(1)}; vector> t = {km<>(3), km<>(2), km<>(1)}; @@ -85,35 +84,6 @@ void vector_of_quantity_add() std::cout << "t[m] = " << vector>(t) << "\n"; } -void vector_of_quantity_multiply_same() -{ - std::cout << "\nvector_of_quantity_multiply_same:\n"; - - vector> v = {m<>(1), m<>(2), m<>(3)}; - vector> u = {m<>(3), m<>(2), m<>(1)}; - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "m<>(2) * v = " << m<>(2.) * v << "\n"; -} - -void vector_of_quantity_multiply_different() -{ - std::cout << "\nvector_of_quantity_multiply_different:\n"; - - vector> v = {N<>(1), N<>(2), N<>(3)}; - vector> u = {m<>(3), m<>(2), m<>(1)}; - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "N<>(2) * u = " << N<>(2.) * u << "\n"; - std::cout << "2 * u = " << 2 * u << "\n"; -} - void vector_of_quantity_divide_by_scalar() { std::cout << "\nvector_of_quantity_divide_by_scalar:\n"; @@ -122,16 +92,13 @@ void vector_of_quantity_divide_by_scalar() std::cout << "v = " << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / s<>(2) = " << v / s<>(2) << "\n"; - // std::cout << "v / 2 = " << v / 2 << "\n"; + std::cout << "v / s<>(2) = " << v / s<>(2) << "\n"; + std::cout << "v / 2 = " << v / 2 << "\n"; } void vector_of_quantity_tests() { vector_of_quantity_add(); - vector_of_quantity_multiply_same(); - vector_of_quantity_multiply_different(); vector_of_quantity_divide_by_scalar(); } @@ -150,37 +117,7 @@ void matrix_of_quantity_add() std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + t =\n" << v + t << "\n"; - // TODO Uncomment when fixed in the LA lib - // std::cout << "v[mm] =\n" << matrix>(v) << "\n"; -} - -void matrix_of_quantity_multiply_same() -{ - std::cout << "\nmatrix_of_quantity_multiply_same:\n"; - - matrix> v = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}}; - vector> u = {m<>(3), m<>(2), m<>(1)}; - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "m<>(2) * u =\n" << m<>(2.) * u << "\n"; -} - -void matrix_of_quantity_multiply_different() -{ - std::cout << "\nmatrix_of_quantity_multiply_different:\n"; - - vector> v = {N<>(1), N<>(2), N<>(3)}; - matrix> u = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}}; - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "N<>(2) * u =\n" << N<>(2.) * u << "\n"; - std::cout << "2 * u =\n" << 2 * u << "\n"; + std::cout << "v[mm] =\n" << matrix>(v) << "\n"; } void matrix_of_quantity_divide_by_scalar() @@ -191,16 +128,13 @@ void matrix_of_quantity_divide_by_scalar() std::cout << "v =\n" << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n"; - // std::cout << "v / 2 =\n" << v / 2 << "\n"; + std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n"; + std::cout << "v / 2 =\n" << v / 2 << "\n"; } void matrix_of_quantity_tests() { matrix_of_quantity_add(); - matrix_of_quantity_multiply_same(); - matrix_of_quantity_multiply_different(); matrix_of_quantity_divide_by_scalar(); } @@ -216,7 +150,7 @@ void quantity_of_vector_add() { std::cout << "\nquantity_of_vector_add:\n"; - length_v<> v(vector<>{1, 2, 3}); + length_v<> v(vector<>{4, 8, 12}); length_v<> u(vector<>{3, 2, 1}); length_v t(vector<>{3, 2, 1}); @@ -229,35 +163,6 @@ void quantity_of_vector_add() std::cout << "t[m] = " << quantity_cast(t) << "\n"; } -void quantity_of_vector_multiply_same() -{ - std::cout << "\nquantity_of_vector_multiply_same:\n"; - - length_v<> v(vector<>{1, 2, 3}); - length_v<> u(vector<>{3, 2, 1}); - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "m<>(2) * v = " << m<>(2.) * v << "\n"; -} - -void quantity_of_vector_multiply_different() -{ - std::cout << "\nquantity_of_vector_multiply_different:\n"; - - force_v<> v(vector<>{1, 2, 3}); - length_v<> u(vector<>{3, 2, 1}); - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "N<>(2) * u = " << N<>(2.) * u << "\n"; - std::cout << "2 * u = " << 2 * u << "\n"; -} - void quantity_of_vector_divide_by_scalar() { std::cout << "\nquantity_of_vector_divide_by_scalar:\n"; @@ -266,16 +171,13 @@ void quantity_of_vector_divide_by_scalar() std::cout << "v = " << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / s<>(2) = " << v / s<>(2) << "\n"; - // std::cout << "v / 2 = " << v / 2 << "\n"; + std::cout << "v / s<>(2) = " << v / s<>(2) << "\n"; + std::cout << "v / 2 = " << v / 2 << "\n"; } void quantity_of_vector_tests() { quantity_of_vector_add(); - quantity_of_vector_multiply_same(); - quantity_of_vector_multiply_different(); quantity_of_vector_divide_by_scalar(); } @@ -297,39 +199,10 @@ void quantity_of_matrix_add() std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + t =\n" << v + t << "\n"; - // TODO Uncomment when fixed in the LA lib + // TODO Fix it // std::cout << "v[mm] =\n" << matrix>(v) << "\n"; } -void quantity_of_matrix_multiply_same() -{ - std::cout << "\nquantity_of_matrix_multiply_same:\n"; - - length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); - length_v<> u(vector<>{3, 2, 1}); - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "m<>(2) * u =\n" << m<>(2.) * u << "\n"; -} - -void quantity_of_matrix_multiply_different() -{ - std::cout << "\nquantity_of_matrix_multiply_different:\n"; - - force_v<> v(vector<>{1, 2, 3}); - length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "N<>(2) * u =\n" << N<>(2.) * u << "\n"; - std::cout << "2 * u =\n" << 2 * u << "\n"; -} - void quantity_of_matrix_divide_by_scalar() { std::cout << "\nquantity_of_matrix_divide_by_scalar:\n"; @@ -338,16 +211,13 @@ void quantity_of_matrix_divide_by_scalar() std::cout << "v =\n" << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n"; - // std::cout << "v / 2 =\n" << v / 2 << "\n"; + std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n"; + std::cout << "v / 2 =\n" << v / 2 << "\n"; } void quantity_of_matrix_tests() { quantity_of_matrix_add(); - quantity_of_matrix_multiply_same(); - quantity_of_matrix_multiply_different(); quantity_of_matrix_divide_by_scalar(); } diff --git a/example/literals/CMakeLists.txt b/example/literals/CMakeLists.txt index 218d1aa5..0db4de8a 100644 --- a/example/literals/CMakeLists.txt +++ b/example/literals/CMakeLists.txt @@ -56,8 +56,9 @@ if(NOT ${projectPrefix}LIBCXX) glide_computer_example-literals PRIVATE ${projectPrefix}NO_REFERENCES ${projectPrefix}NO_ALIASES ) - # TODO uncomment the below when recipes in ConanCenter are fixed - # find_package(wg21_linear_algebra CONFIG REQUIRED) - # add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) - # target_link_libraries(linear_algebra-literals PRIVATE wg21_linear_algebra::wg21_linear_algebra) + if(${projectPrefix}BUILD_LA) + find_package(wg21_linear_algebra CONFIG REQUIRED) + add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) + target_link_libraries(linear_algebra-literals PRIVATE wg21_linear_algebra::wg21_linear_algebra) + endif() endif() diff --git a/example/literals/linear_algebra.cpp b/example/literals/linear_algebra.cpp index e3d34c4e..afef901d 100644 --- a/example/literals/linear_algebra.cpp +++ b/example/literals/linear_algebra.cpp @@ -27,12 +27,18 @@ #include // IWYU pragma: keep #include #include -#include +#include + +template +using vector = STD_LA::fixed_size_column_vector; + +template +using matrix = STD_LA::fixed_size_matrix; namespace STD_LA { -template -std::ostream& operator<<(std::ostream& os, const vector& v) +template +std::ostream& operator<<(std::ostream& os, const ::vector& v) { os << "|"; for (auto i = 0U; i < v.size(); ++i) { @@ -42,8 +48,8 @@ std::ostream& operator<<(std::ostream& os, const vector& v) return os; } -template -std::ostream& operator<<(std::ostream& os, const matrix& v) +template +std::ostream& operator<<(std::ostream& os, const ::matrix& v) { for (auto i = 0U; i < v.rows(); ++i) { os << "|"; @@ -62,18 +68,11 @@ namespace { using namespace units::isq; using namespace units::isq::si::literals; -template -using vector = std::math::fs_vector; - -template -using matrix = std::math::fs_matrix; - - void vector_of_quantity_add() { std::cout << "\nvector_of_quantity_add:\n"; - vector> v = {1_q_m, 2_q_m, 3_q_m}; + vector> v = {4_q_m, 8_q_m, 12_q_m}; vector> u = {3_q_m, 2_q_m, 1_q_m}; vector> t = {3_q_km, 2_q_km, 1_q_km}; @@ -86,35 +85,6 @@ void vector_of_quantity_add() std::cout << "t[m] = " << vector>(t) << "\n"; } -void vector_of_quantity_multiply_same() -{ - std::cout << "\nvector_of_quantity_multiply_same:\n"; - - vector> v = {1_q_m, 2_q_m, 3_q_m}; - vector> u = {3_q_m, 2_q_m, 1_q_m}; - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "2_q_m * v = " << 2._q_m * v << "\n"; -} - -void vector_of_quantity_multiply_different() -{ - std::cout << "\nvector_of_quantity_multiply_different:\n"; - - vector> v = {1_q_N, 2_q_N, 3_q_N}; - vector> u = {3_q_m, 2_q_m, 1_q_m}; - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "2_q_N * u = " << 2._q_N * u << "\n"; - std::cout << "2 * u = " << 2 * u << "\n"; -} - void vector_of_quantity_divide_by_scalar() { std::cout << "\nvector_of_quantity_divide_by_scalar:\n"; @@ -123,16 +93,13 @@ void vector_of_quantity_divide_by_scalar() std::cout << "v = " << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / 2_q_s = " << v / 2_q_s << "\n"; - // std::cout << "v / 2 = " << v / 2 << "\n"; + std::cout << "v / 2_q_s = " << v / quantity_cast(2_q_s) << "\n"; + std::cout << "v / 2 = " << v / 2 << "\n"; } void vector_of_quantity_tests() { vector_of_quantity_add(); - vector_of_quantity_multiply_same(); - vector_of_quantity_multiply_different(); vector_of_quantity_divide_by_scalar(); } @@ -151,37 +118,7 @@ void matrix_of_quantity_add() std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + t =\n" << v + t << "\n"; - // TODO Uncomment when fixed in the LA lib - // std::cout << "v[mm] =\n" << matrix>(v) << "\n"; -} - -void matrix_of_quantity_multiply_same() -{ - std::cout << "\nmatrix_of_quantity_multiply_same:\n"; - - matrix> v = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}}; - vector> u = {3_q_m, 2_q_m, 1_q_m}; - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2_q_m * u =\n" << 2._q_m * u << "\n"; -} - -void matrix_of_quantity_multiply_different() -{ - std::cout << "\nmatrix_of_quantity_multiply_different:\n"; - - vector> v = {1_q_N, 2_q_N, 3_q_N}; - matrix> u = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}}; - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2_q_N * u =\n" << 2._q_N * u << "\n"; - std::cout << "2 * u =\n" << 2 * u << "\n"; + std::cout << "v[mm] =\n" << matrix>(v) << "\n"; } void matrix_of_quantity_divide_by_scalar() @@ -192,16 +129,13 @@ void matrix_of_quantity_divide_by_scalar() std::cout << "v =\n" << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n"; - // std::cout << "v / 2 =\n" << v / 2 << "\n"; + std::cout << "v / 2_q_s =\n" << v / quantity_cast(2_q_s) << "\n"; + std::cout << "v / 2 =\n" << v / 2 << "\n"; } void matrix_of_quantity_tests() { matrix_of_quantity_add(); - matrix_of_quantity_multiply_same(); - matrix_of_quantity_multiply_different(); matrix_of_quantity_divide_by_scalar(); } @@ -215,7 +149,7 @@ void quantity_of_vector_add() { std::cout << "\nquantity_of_vector_add:\n"; - length_v<> v(vector<>{1, 2, 3}); + length_v<> v(vector<>{4, 8, 12}); length_v<> u(vector<>{3, 2, 1}); length_v t(vector<>{3, 2, 1}); @@ -228,35 +162,6 @@ void quantity_of_vector_add() std::cout << "t[m] = " << quantity_cast(t) << "\n"; } -void quantity_of_vector_multiply_same() -{ - std::cout << "\nquantity_of_vector_multiply_same:\n"; - - length_v<> v(vector<>{1, 2, 3}); - length_v<> u(vector<>{3, 2, 1}); - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "2_q_m * v = " << 2._q_m * v << "\n"; -} - -void quantity_of_vector_multiply_different() -{ - std::cout << "\nquantity_of_vector_multiply_different:\n"; - - force_v<> v(vector<>{1, 2, 3}); - length_v<> u(vector<>{3, 2, 1}); - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "2_q_N * u = " << 2._q_N * u << "\n"; - std::cout << "2 * u = " << 2 * u << "\n"; -} - void quantity_of_vector_divide_by_scalar() { std::cout << "\nquantity_of_vector_divide_by_scalar:\n"; @@ -265,16 +170,13 @@ void quantity_of_vector_divide_by_scalar() std::cout << "v = " << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / 2_q_s = " << v / 2_q_s << "\n"; - // std::cout << "v / 2 = " << v / 2 << "\n"; + std::cout << "v / 2_q_s = " << v / 2_q_s << "\n"; + std::cout << "v / 2 = " << v / 2 << "\n"; } void quantity_of_vector_tests() { quantity_of_vector_add(); - quantity_of_vector_multiply_same(); - quantity_of_vector_multiply_different(); quantity_of_vector_divide_by_scalar(); } @@ -296,39 +198,10 @@ void quantity_of_matrix_add() std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + t =\n" << v + t << "\n"; - // TODO Uncomment when fixed in the LA lib + // TODO Fix it // std::cout << "v[mm] =\n" << matrix>(v) << "\n"; } -void quantity_of_matrix_multiply_same() -{ - std::cout << "\nquantity_of_matrix_multiply_same:\n"; - - length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); - length_v<> u(vector<>{3, 2, 1}); - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2_q_m * u =\n" << 2._q_m * u << "\n"; -} - -void quantity_of_matrix_multiply_different() -{ - std::cout << "\nquantity_of_matrix_multiply_different:\n"; - - force_v<> v(vector<>{1, 2, 3}); - length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2_q_N * u =\n" << 2._q_N * u << "\n"; - std::cout << "2 * u =\n" << 2 * u << "\n"; -} - void quantity_of_matrix_divide_by_scalar() { std::cout << "\nquantity_of_matrix_divide_by_scalar:\n"; @@ -337,16 +210,13 @@ void quantity_of_matrix_divide_by_scalar() std::cout << "v =\n" << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n"; - // std::cout << "v / 2 =\n" << v / 2 << "\n"; + std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n"; + std::cout << "v / 2 =\n" << v / 2 << "\n"; } void quantity_of_matrix_tests() { quantity_of_matrix_add(); - quantity_of_matrix_multiply_same(); - quantity_of_matrix_multiply_different(); quantity_of_matrix_divide_by_scalar(); } diff --git a/example/references/CMakeLists.txt b/example/references/CMakeLists.txt index 7adcabaa..de614d91 100644 --- a/example/references/CMakeLists.txt +++ b/example/references/CMakeLists.txt @@ -56,8 +56,9 @@ if(NOT ${projectPrefix}LIBCXX) glide_computer_example-references PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_ALIASES ) - # TODO uncomment the below when recipes in ConanCenter are fixed - # find_package(wg21_linear_algebra CONFIG REQUIRED) - # add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) - # target_link_libraries(linear_algebra-references PRIVATE wg21_linear_algebra::wg21_linear_algebra) + if(${projectPrefix}BUILD_LA) + find_package(wg21_linear_algebra CONFIG REQUIRED) + add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) + target_link_libraries(linear_algebra-references PRIVATE wg21_linear_algebra::wg21_linear_algebra) + endif() endif() diff --git a/example/references/linear_algebra.cpp b/example/references/linear_algebra.cpp index 293fc47b..adf0de38 100644 --- a/example/references/linear_algebra.cpp +++ b/example/references/linear_algebra.cpp @@ -27,12 +27,18 @@ #include // IWYU pragma: keep #include #include -#include +#include + +template +using vector = STD_LA::fixed_size_column_vector; + +template +using matrix = STD_LA::fixed_size_matrix; namespace STD_LA { -template -std::ostream& operator<<(std::ostream& os, const vector& v) +template +std::ostream& operator<<(std::ostream& os, const ::vector& v) { os << "|"; for (auto i = 0U; i < v.size(); ++i) { @@ -42,8 +48,8 @@ std::ostream& operator<<(std::ostream& os, const vector& v) return os; } -template -std::ostream& operator<<(std::ostream& os, const matrix& v) +template +std::ostream& operator<<(std::ostream& os, const ::matrix& v) { for (auto i = 0U; i < v.rows(); ++i) { os << "|"; @@ -61,19 +67,13 @@ namespace { using namespace units::isq; using namespace units::isq::si::length_references; -using namespace units::isq::si::force_references; - -template -using vector = std::math::fs_vector; - -template -using matrix = std::math::fs_matrix; +using namespace units::isq::si::time_references; void vector_of_quantity_add() { std::cout << "\nvector_of_quantity_add:\n"; - vector> v = {1 * m, 2 * m, 3 * m}; + vector> v = {4 * m, 8 * m, 12 * m}; vector> u = {3 * m, 2 * m, 1 * m}; vector> t = {3 * km, 2 * km, 1 * km}; @@ -86,35 +86,6 @@ void vector_of_quantity_add() std::cout << "t[m] = " << vector>(t) << "\n"; } -void vector_of_quantity_multiply_same() -{ - std::cout << "\nvector_of_quantity_multiply_same:\n"; - - vector> v = {1 * m, 2 * m, 3 * m}; - vector> u = {3 * m, 2 * m, 1 * m}; - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "2 * m * v = " << 2. * m * v << "\n"; -} - -void vector_of_quantity_multiply_different() -{ - std::cout << "\nvector_of_quantity_multiply_different:\n"; - - vector> v = {1 * N, 2 * N, 3 * N}; - vector> u = {3 * m, 2 * m, 1 * m}; - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "2 * N * u = " << 2. * N * u << "\n"; - std::cout << "2 * u = " << 2 * u << "\n"; -} - void vector_of_quantity_divide_by_scalar() { std::cout << "\nvector_of_quantity_divide_by_scalar:\n"; @@ -123,16 +94,13 @@ void vector_of_quantity_divide_by_scalar() std::cout << "v = " << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / (2 * s) = " << v / (2 * s) << "\n"; - // std::cout << "v / 2 = " << v / 2 << "\n"; + std::cout << "v / (2 * s) = " << v / (2 * s) << "\n"; + std::cout << "v / 2 = " << v / 2 << "\n"; } void vector_of_quantity_tests() { vector_of_quantity_add(); - vector_of_quantity_multiply_same(); - vector_of_quantity_multiply_different(); vector_of_quantity_divide_by_scalar(); } @@ -151,37 +119,7 @@ void matrix_of_quantity_add() std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + t =\n" << v + t << "\n"; - // TODO Uncomment when fixed in the LA lib - // std::cout << "v[mm] =\n" << matrix>(v) << "\n"; -} - -void matrix_of_quantity_multiply_same() -{ - std::cout << "\nmatrix_of_quantity_multiply_same:\n"; - - matrix> v = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}}; - vector> u = {3 * m, 2 * m, 1 * m}; - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2 * m * u =\n" << 2. * m * u << "\n"; -} - -void matrix_of_quantity_multiply_different() -{ - std::cout << "\nmatrix_of_quantity_multiply_different:\n"; - - vector> v = {1 * N, 2 * N, 3 * N}; - matrix> u = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}}; - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2 * N * u =\n" << 2. * N * u << "\n"; - std::cout << "2 * u =\n" << 2 * u << "\n"; + std::cout << "v[mm] =\n" << matrix>(v) << "\n"; } void matrix_of_quantity_divide_by_scalar() @@ -192,16 +130,13 @@ void matrix_of_quantity_divide_by_scalar() std::cout << "v =\n" << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n"; - // std::cout << "v / 2 =\n" << v / 2 << "\n"; + std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n"; + std::cout << "v / 2 =\n" << v / 2 << "\n"; } void matrix_of_quantity_tests() { matrix_of_quantity_add(); - matrix_of_quantity_multiply_same(); - matrix_of_quantity_multiply_different(); matrix_of_quantity_divide_by_scalar(); } @@ -215,7 +150,7 @@ void quantity_of_vector_add() { std::cout << "\nquantity_of_vector_add:\n"; - length_v<> v(vector<>{1, 2, 3}); + length_v<> v(vector<>{4, 8, 12}); length_v<> u(vector<>{3, 2, 1}); length_v t(vector<>{3, 2, 1}); @@ -228,35 +163,6 @@ void quantity_of_vector_add() std::cout << "t[m] = " << quantity_cast(t) << "\n"; } -void quantity_of_vector_multiply_same() -{ - std::cout << "\nquantity_of_vector_multiply_same:\n"; - - length_v<> v(vector<>{1, 2, 3}); - length_v<> u(vector<>{3, 2, 1}); - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "2 * m * v = " << 2. * m * v << "\n"; -} - -void quantity_of_vector_multiply_different() -{ - std::cout << "\nquantity_of_vector_multiply_different:\n"; - - force_v<> v(vector<>{1, 2, 3}); - length_v<> u(vector<>{3, 2, 1}); - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - - std::cout << "v * u = " << v * u << "\n"; - std::cout << "2 * N * u = " << 2. * N * u << "\n"; - std::cout << "2 * u = " << 2 * u << "\n"; -} - void quantity_of_vector_divide_by_scalar() { std::cout << "\nquantity_of_vector_divide_by_scalar:\n"; @@ -265,16 +171,13 @@ void quantity_of_vector_divide_by_scalar() std::cout << "v = " << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / 2 * s = " << v / 2 * s << "\n"; - // std::cout << "v / 2 = " << v / 2 << "\n"; + std::cout << "v / (2 * s) = " << v / (2 * s) << "\n"; + std::cout << "v / 2 = " << v / 2 << "\n"; } void quantity_of_vector_tests() { quantity_of_vector_add(); - quantity_of_vector_multiply_same(); - quantity_of_vector_multiply_different(); quantity_of_vector_divide_by_scalar(); } @@ -296,39 +199,10 @@ void quantity_of_matrix_add() std::cout << "v + u =\n" << v + u << "\n"; std::cout << "v + t =\n" << v + t << "\n"; - // TODO Uncomment when fixed in the LA lib + // TODO Fix it // std::cout << "v[mm] =\n" << matrix>(v) << "\n"; } -void quantity_of_matrix_multiply_same() -{ - std::cout << "\nquantity_of_matrix_multiply_same:\n"; - - length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); - length_v<> u(vector<>{3, 2, 1}); - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2 * m * u =\n" << 2. * m * u << "\n"; -} - -void quantity_of_matrix_multiply_different() -{ - std::cout << "\nquantity_of_matrix_multiply_different:\n"; - - force_v<> v(vector<>{1, 2, 3}); - length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - - std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2 * N * u =\n" << 2. * N * u << "\n"; - std::cout << "2 * u =\n" << 2 * u << "\n"; -} - void quantity_of_matrix_divide_by_scalar() { std::cout << "\nquantity_of_matrix_divide_by_scalar:\n"; @@ -337,16 +211,13 @@ void quantity_of_matrix_divide_by_scalar() std::cout << "v =\n" << v << "\n"; - // TODO Uncomment when bug in the LA is fixed - // std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n"; - // std::cout << "v / 2 =\n" << v / 2 << "\n"; + std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n"; + std::cout << "v / 2 =\n" << v / 2 << "\n"; } void quantity_of_matrix_tests() { quantity_of_matrix_add(); - quantity_of_matrix_multiply_same(); - quantity_of_matrix_multiply_different(); quantity_of_matrix_divide_by_scalar(); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 32a5e555..d81062f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,6 +28,9 @@ set(projectPrefix UNITS_) option(${projectPrefix}AS_SYSTEM_HEADERS "Exports library as system headers" OFF) message(STATUS "${projectPrefix}AS_SYSTEM_HEADERS: ${${projectPrefix}AS_SYSTEM_HEADERS}") +option(${projectPrefix}BUILD_LA "Build code depending on the linear algebra library" ON) +message(STATUS "${projectPrefix}BUILD_LA: ${${projectPrefix}BUILD_LA}") + list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") include(AddUnitsModule) diff --git a/src/core/include/units/bits/basic_concepts.h b/src/core/include/units/bits/basic_concepts.h index 397f5137..633ef880 100644 --- a/src/core/include/units/bits/basic_concepts.h +++ b/src/core/include/units/bits/basic_concepts.h @@ -401,8 +401,11 @@ concept castable_number_ = // exposition only template concept scalable_ = // exposition only - castable_number_ || (requires { typename T::value_type; } && castable_number_ && - scalable_number_>); + castable_number_ || + (requires { typename T::value_type; } && castable_number_ && + scalable_number_>) || + (requires { typename T::element_type; } && castable_number_ && + scalable_number_>); template concept scalable_with_ = // exposition only @@ -420,6 +423,12 @@ inline constexpr bool is_wrapped_quantity = Quantity || QuantityLike || is_wrapped_quantity; +template + requires requires { typename T::element_type; } +inline constexpr bool is_wrapped_quantity = + Quantity || QuantityLike || + is_wrapped_quantity; + template requires requires { typename T::quantity_type; } inline constexpr bool is_wrapped_quantity = Quantity; @@ -429,8 +438,9 @@ inline constexpr bool is_wrapped_quantity = Quantity` - * recursively (i.e. `std::optional>`). + * Satisfied by all wrapper types that satisfy `Quantity` or + * `Quantity` recursively + * (i.e. `std::optional>`). */ template concept wrapped_quantity_ = // exposition only diff --git a/src/core/include/units/customization_points.h b/src/core/include/units/customization_points.h index 106faffb..6eb7c0d0 100644 --- a/src/core/include/units/customization_points.h +++ b/src/core/include/units/customization_points.h @@ -44,6 +44,10 @@ template requires requires { typename T::value_type; } inline constexpr bool treat_as_floating_point = treat_as_floating_point; +template + requires requires { typename T::element_type; } +inline constexpr bool treat_as_floating_point = treat_as_floating_point; + /** * @brief A type trait that defines zero, one, min, and max for a representation type * diff --git a/src/core/include/units/quantity_cast.h b/src/core/include/units/quantity_cast.h index 8faf23e1..89c5d059 100644 --- a/src/core/include/units/quantity_cast.h +++ b/src/core/include/units/quantity_cast.h @@ -83,6 +83,16 @@ struct cast_traits { using rep_type = std::common_type_t; }; +template + requires(!common_type_with_, std::intmax_t> && + scalable_number_, std::intmax_t> && + requires { typename std::common_type_t::element_type; } && + common_type_with_::element_type, std::intmax_t>) +struct cast_traits { + using ratio_type = std::common_type_t::element_type, std::intmax_t>; + using rep_type = std::common_type_t; +}; + } // namespace detail /**