From 0ba303bbf94df1527cd2559f87cb4086ccf92c5c Mon Sep 17 00:00:00 2001 From: jakb-wilczski Date: Mon, 9 Dec 2024 00:07:34 +0100 Subject: [PATCH 1/2] =?UTF-8?q?wersja=20z=20najmniejsz=C4=85=20dotychczas?= =?UTF-8?q?=20liczb=C4=85=20error=C3=B3w=20(niestety=20nie=20trafi=C5=82a?= =?UTF-8?q?=20na=20Moodle)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poly.h | 101 +++++++++++++++++++++++---------------------------------- 1 file changed, 40 insertions(+), 61 deletions(-) diff --git a/poly.h b/poly.h index b5b5c30..7f8d915 100644 --- a/poly.h +++ b/poly.h @@ -8,6 +8,7 @@ #include #define DEBUG 1 +#define MAX(a, b) ((a) > (b) ? (a) : (b)) #if DEBUG #define DBG_PRINT(x) \ @@ -18,6 +19,16 @@ #define DBG_PRINT(x) #endif +template +void printuj(const T& obj) { + std::cout << obj << "(" << obj.to_string() << ")\n"; +} + +template +void printuj(std::string msg, const T& obj) { + std::cout << msg << obj << "(" << obj.to_string() << ")\n"; +} + template concept PolyConvertible = (M <= N) && std::is_convertible_v; @@ -41,38 +52,17 @@ template class poly { private: std::array coefs{}; - std::ostringstream oss(int var) const { - std::ostringstream res; - for (std::size_t i = 0; i < N; ++i) { - const T& a = this->coefs[i]; - if constexpr (requires { typename T::value_type; }) { - res << "(" << a.oss(var+1).str() << ")"; - } - else { - res << a; - } - if (i > 0) { - res << "*x" << var; - } - if (i > 1) { - res << "^" << i; - } - if (i < N-1) { - res << " + "; - } - } - return res; - } - - public: - std::string to_string() const { - return this->oss(1).str(); + template + static constexpr auto at_array(const P& p, const std::array& arr) { + return at_array_impl(p, arr, std::make_index_sequence{}); } - friend std::ostream& operator<<(std::ostream& os, const poly& p) { - return os << "poly<" << typeid(T).name() << ", " << N << ">"; + template + static constexpr auto at_array_impl(const P& p, const std::array& arr, std::index_sequence) { + return p.at(arr[Is]...); } + public: constexpr poly() = default; template @@ -255,7 +245,7 @@ template class poly { return *this; } - template + template requires std::convertible_to constexpr std::common_type_t at(const U& arg) const { if (N == 0) { @@ -273,7 +263,7 @@ template class poly { } template - requires std::convertible_to, T> + requires std::convertible_to constexpr auto at(const poly& arg) const { constexpr std::size_t res_size = (N-1)*(M-1) + 1; using res_type = poly, res_size>; @@ -287,15 +277,15 @@ template class poly { res_type term(arg); for (std::size_t exp = 1; exp < i; ++exp) { - res_type temp_result{}; - for (std::size_t k = 0; k < term.size(); ++k) { - for (std::size_t j = 0; j < arg.size(); ++j) { - if (k + j < temp_result.size()) { - temp_result[k + j] += term[k] * arg[j]; + res_type temp{}; + for (std::size_t k = 0; k < res_size; ++k) { + for (std::size_t j = 0; j < M; ++j) { + if (k + j < res_size) { + temp[k + j] += term[k] * arg[j]; } } } - term = temp_result; + term = temp; } for (std::size_t k = 0; k < term.size(); ++k) { @@ -307,33 +297,22 @@ template class poly { return res; } - + template - constexpr auto at(const U& first, Args&&... args) const - requires (std::convertible_to, T> && (std::convertible_to, T> && ...)) { - if (N <= 1) { - return this->at(first); - } - - using result_type = decltype(this->coefs[0].at(args...)); - result_type result = this->coefs[0].at(args...); - - for (std::size_t i = 1; i < N; ++i) { - result += this->coefs[i].at(args...) * pow(first, i); - } - - return result; + requires (std::convertible_to, T> && (std::convertible_to, T> && ...)) + constexpr auto at(const U& first, Args&&... args) const { + auto res = this->at(first); + + if (N > 1) { + if constexpr (requires { typename decltype(res.coefs[0])::value_type; }) { + for (std::size_t i = 1; i < N; ++i) { + res.coefs[i] = res.coefs[i].at(args...); + } + } + } + + return res; } - - template - static constexpr auto at_array(const P& p, const std::array& arr) { - return at_array_impl(p, arr, std::make_index_sequence{}); - } - - template - static constexpr auto at_array_impl(const P& p, const std::array& arr, std::index_sequence) { - return p.at(arr[Is]...); - } template constexpr auto at(const std::array& arr) const { From 21b521f54372eb9ba96cb187abdf54ed92084bf0 Mon Sep 17 00:00:00 2001 From: jakb-wilczski Date: Sun, 19 Jan 2025 22:31:04 +0100 Subject: [PATCH 2/2] wersja z Moodle'a, minimalnie zmieniona --- poly.h | 220 +++++++++++++++++++++++---------------------------------- 1 file changed, 88 insertions(+), 132 deletions(-) diff --git a/poly.h b/poly.h index 7f8d915..b739e45 100644 --- a/poly.h +++ b/poly.h @@ -1,67 +1,31 @@ #ifndef POLY_H #define POLY_H -#endif #include #include +#include #include -#include - -#define DEBUG 1 -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - -#if DEBUG -#define DBG_PRINT(x) \ - if (!std::is_constant_evaluated()) { \ - std::cout << x << std::endl; \ - } -#else -#define DBG_PRINT(x) -#endif - -template -void printuj(const T& obj) { - std::cout << obj << "(" << obj.to_string() << ")\n"; -} - -template -void printuj(std::string msg, const T& obj) { - std::cout << msg << obj << "(" << obj.to_string() << ")\n"; -} template concept PolyConvertible = (M <= N) && std::is_convertible_v; -// To be able to use the "poly" type name before its definition +// To be able to use the "poly" type name before its definition. template class poly; // For recursive deduction of the base type of poly<...>. -template -struct BaseType { +template struct BaseType { using type = T; }; -template -struct BaseType> { +template struct BaseType> { using type = typename BaseType::type; }; -template -using base_type = typename BaseType::type; +template using base_type = typename BaseType::type; template class poly { private: std::array coefs{}; - template - static constexpr auto at_array(const P& p, const std::array& arr) { - return at_array_impl(p, arr, std::make_index_sequence{}); - } - - template - static constexpr auto at_array_impl(const P& p, const std::array& arr, std::index_sequence) { - return p.at(arr[Is]...); - } - public: constexpr poly() = default; @@ -89,9 +53,10 @@ template class poly { } template - requires(sizeof...(Args) >= 2 && sizeof...(Args) <= N && (std::convertible_to && ...)) - constexpr poly(Args&&... args) : coefs{static_cast(std::forward(args))...} { - } + requires(sizeof...(Args) >= 2 && sizeof...(Args) <= N && + (std::convertible_to && ...)) + constexpr poly(Args&&... args) + : coefs{static_cast(std::forward(args))...} {} constexpr std::size_t size() const { return N; } @@ -202,7 +167,7 @@ template class poly { return result; } - // Multiplication of a poly object with a scalar + // Multiplication of a poly object with a scalar. template requires std::convertible_to constexpr auto operator*(const U& value) const { @@ -213,7 +178,7 @@ template class poly { return result; } - // Addition of a poly object with a scalar + // Addition of a poly object with a scalar. template requires std::convertible_to constexpr auto operator+(const U& value) const { @@ -222,7 +187,7 @@ template class poly { return result; } - // Subtraction of a poly object with a scalar + // Subtraction of a poly object with a scalar. template requires std::convertible_to constexpr auto operator-(const U& value) const { @@ -232,109 +197,101 @@ template class poly { } template - requires std::convertible_to - static constexpr std::common_type_t eval_term(const T& coef, const U& pow_base, std::size_t pow_exp) { - std::common_type_t res = coef; - for (std::size_t i = 1; i <= pow_exp; ++i) { - res *= pow_base; - } - return res; - } - - constexpr const poly& at() const { - return *this; + requires std::convertible_to + static constexpr U eval_term(const T& coef, const U& pow_base, + std::size_t pow_exp) { + U res = coef; + for (std::size_t i = 1; i <= pow_exp; ++i) { + res *= pow_base; + } + return res; } + constexpr const poly& at() const { return *this; } + template - requires std::convertible_to - constexpr std::common_type_t at(const U& arg) const { - if (N == 0) { - return T{}; - } - - std::common_type_t res = this->coefs[0]; - - for (std::size_t i = 1; i < N; ++i) { - std::common_type_t term = eval_term(this->coefs[i], arg, i); - res += term; - } - - return res; - } + requires std::convertible_to + constexpr auto at(const U& arg) const { + using R = decltype(coefs[0] * arg); + if (N == 0) { + return R{}; + } + + R res = coefs[N - 1]; + for (std::size_t i = N - 1; i > 0; --i) { + res = res * arg + coefs[i - 1]; + } + + return res; + } + template - requires std::convertible_to + requires std::convertible_to, T> constexpr auto at(const poly& arg) const { - constexpr std::size_t res_size = (N-1)*(M-1) + 1; + constexpr std::size_t res_size = (N - 1) * (M - 1) + 1; using res_type = poly, res_size>; - + if (N == 0) { - return res_type(); - } + return res_type(); + } res_type res(this->coefs[0]); - - for (std::size_t i = 1; i < N; ++i) { - res_type term(arg); - - for (std::size_t exp = 1; exp < i; ++exp) { - res_type temp{}; - for (std::size_t k = 0; k < res_size; ++k) { - for (std::size_t j = 0; j < M; ++j) { - if (k + j < res_size) { - temp[k + j] += term[k] * arg[j]; - } - } - } - term = temp; - } - - for (std::size_t k = 0; k < term.size(); ++k) { - term[k] *= this->coefs[i]; - } - - res += term; - } - - return res; + + for (std::size_t i = N - 1; i > 0; --i) { + res = res * arg + res_type(this->coefs[i - 1]); + /*res_type term(arg); + + for (std::size_t exp = 1; exp < i; ++exp) { + res_type temp_result{}; + for (std::size_t k = 0; k < term.size(); ++k) { + for (std::size_t j = 0; j < arg.size(); ++j) { + if (k + j < temp_result.size()) { + temp_result[k + j] += term[k] * arg[j]; + } + } + } + term = temp_result; + } + + for (std::size_t k = 0; k < term.size(); ++k) { + term[k] *= this->coefs[i]; + } + + res += term;*/ + } + + return res; } - template - requires (std::convertible_to, T> && (std::convertible_to, T> && ...)) - constexpr auto at(const U& first, Args&&... args) const { - auto res = this->at(first); - - if (N > 1) { - if constexpr (requires { typename decltype(res.coefs[0])::value_type; }) { - for (std::size_t i = 1; i < N; ++i) { - res.coefs[i] = res.coefs[i].at(args...); - } - } - } - - return res; - } - - template - constexpr auto at(const std::array& arr) const { - return at_array(*this, arr); + template + constexpr auto at(const A& a, const Args&... rest) const { + using R = decltype(this->coefs[0].at(rest...) * a); + if (N == 0) { + return R{}; + } + R res = coefs[N-1].at(rest...); + for (std::size_t i = N - 1; i > 0; --i) { + res = res * a + this->coefs[i - 1].at(rest...); + } + return res; } }; -// Non-member operator* for scalar multiplication. +// Non-member operator* for scalar multiplication. template requires std::convertible_to constexpr auto operator*(const U& value, const poly& p) { return p * value; } -// Non-member operator+ for scalar addition. +// Non-member operator+ for scalar addition. template requires std::convertible_to constexpr auto operator+(const U& value, const poly& p) { return p + value; } -// Non-member operator- for scalar subtraction. +// Non-member operator- for scalar subtraction. template requires std::convertible_to constexpr auto operator-(const U& value, const poly& p) { @@ -343,9 +300,9 @@ constexpr auto operator-(const U& value, const poly& p) { template constexpr auto const_poly(const poly& p) { - DBG_PRINT("const_poly constructor called"); return poly, 1>{p}; } + namespace detail { template struct is_poly_impl : std::false_type {}; @@ -353,11 +310,9 @@ template struct is_poly_impl : std::false_type {}; template struct is_poly_impl> : std::true_type {}; -template -struct is_poly : is_poly_impl> {}; +template struct is_poly : is_poly_impl> {}; -template -inline constexpr bool is_poly_v = is_poly::value; +template inline constexpr bool is_poly_v = is_poly::value; } // namespace detail // std::common_type specialization for poly. @@ -369,17 +324,16 @@ struct common_type, poly> { }; template - requires (!detail::is_poly_v) + requires(!detail::is_poly_v) struct common_type, U> { using type = poly, N>; }; template - requires (!detail::is_poly_v) + requires(!detail::is_poly_v) struct common_type> { using type = poly, M>; }; - } // namespace std template @@ -418,3 +372,5 @@ template constexpr auto cross(const T1& a, const T2& b) { return a * b; } + +#endif // POLY_H