From cb825aec403c4a4a045dbd9466541062d141f9fb Mon Sep 17 00:00:00 2001 From: Bausager Date: Wed, 10 Sep 2025 20:57:06 +0200 Subject: [PATCH] First draft of vector class is ready, not done with the module test in main.cpp --- bin/abc_lab | Bin 44456 -> 58856 bytes include/utils/vector.h | 255 +++++++++++++++++++++++++++++++++-------- obj/main.o | Bin 75208 -> 108760 bytes src/main.cpp | 196 +++++++++++++++++++++++++++---- 4 files changed, 381 insertions(+), 70 deletions(-) diff --git a/bin/abc_lab b/bin/abc_lab index 1dcbf55f9358a5ff999b6e295c2b9114dbb86694..92b6239348b62d1c8858ac4fe8ef0e15165ef067 100755 GIT binary patch literal 58856 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 RR6n>&a*b1lawS_)`+vsj@f!dD literal 44456 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 Jt_rTA@jtQrH_iY6 diff --git a/include/utils/vector.h b/include/utils/vector.h index 77a39ec..0dbb7a9 100644 --- a/include/utils/vector.h +++ b/include/utils/vector.h @@ -52,8 +52,9 @@ public: if (v.size() != a.size()) { return false; } + const static T eps = static_cast(1e-6); // tweak if you like for (uint64_t i = 0; i < v.size(); ++i) { - if (v[i] != a[i]) { + if (std::fabs(v[i] - a[i]) > eps) { return false; } } @@ -67,9 +68,10 @@ public: //################################################## template ::value>::type> void inplace_add(const U a){ + const T a_hat = static_cast(a); const uint64_t n = v.size(); for (uint64_t i = 0; i < n; ++i){ - v[i] += a; + v[i] += a_hat; } } template ::value>::type> @@ -82,6 +84,10 @@ public: Vector operator+(const U a) const { return add(a); } + template ::value>::type> + friend Vector operator+(U a, const Vector& b) { + return b + a; + } template ::value>::type> Vector& operator+=(const U a) { inplace_add(a); @@ -112,92 +118,259 @@ public: return *this; } //################################################## + //# VECTOR: Scalar Subtract # + //################################################## + template ::value>::type> + void inplace_subtract(const U a){ + const T a_hat = static_cast(a); + const uint64_t n = v.size(); + for (uint64_t i = 0; i < n; ++i){ + v[i] -= a_hat; + } + } + template ::value>::type> + Vector subtract(const U a) const{ + Vector result = *this; + result.inplace_subtract(a); + return result; + } + template ::value>::type> + Vector operator-(const U a) const { + return subtract(a); + } + template ::value>::type> + Vector& operator-=(const U a) { + inplace_subtract(a); + return *this; + } + //################################################## //# VECTOR: Vector Subtract # //################################################## - void inplace_vec_subtract(const Vector& a){ + void inplace_subtract(const Vector& a){ if (a.size() != v.size()){ - throw std::runtime_error("utill:Vector.inplace_vec_subtract -> Dimensions does not fit"); + throw std::runtime_error("utill:Vector.inplace_subtract -> Dimensions does not fit"); } - - uint64_t n = a.size(); + const uint64_t n = v.size(); for (uint64_t i = 0; i < n; ++i){ v[i] -= a[i]; } - } - Vector vec_subtract(const Vector& a) const{ + Vector subtract(const Vector& a) const{ Vector result = *this; - - result.inplace_vec_subtract(a); - + result.inplace_subtract(a); return result; } Vector operator-(const Vector& a) const { - return vec_subtract(a); + return subtract(a); } Vector& operator-=(const Vector& a) { - inplace_vec_subtract(a); + inplace_subtract(a); + return *this; + } + //################################################## + //# VECTOR: Scalar Multiply # + //################################################## + template ::value>::type> + void inplace_multiply(const U a){ + const T a_hat = static_cast(a); + const uint64_t n = v.size(); + for (uint64_t i = 0; i < n; ++i){ + v[i] *= a_hat; + } + } + template ::value>::type> + Vector multiply(const U a) const{ + Vector result = *this; + result.inplace_multiply(a); + return result; + } + template ::value>::type> + Vector operator*(const U a) const { + return multiply(a); + } + template ::value>::type> + friend Vector operator*(U a, const Vector& b) { + return b * a; + } + template ::value>::type> + Vector& operator*=(const U a) { + inplace_multiply(a); return *this; } //################################################## //# VECTOR: Vector Multiply # //################################################## - void inplace_vec_multiply(const Vector& a){ + void inplace_multiply(const Vector& a){ if (a.size() != v.size()){ - throw std::runtime_error("utill:Vector.inplace_vec_multiply -> Dimensions does not fit"); + throw std::runtime_error("utill:Vector.inplace_multiply -> Dimensions does not fit"); } - - uint64_t n = a.size(); + const uint64_t n = v.size(); for (uint64_t i = 0; i < n; ++i){ v[i] *= a[i]; } - } - Vector vec_multiply(const Vector& a) const{ + Vector multiply(const Vector& a) const{ Vector result = *this; - result.inplace_vec_multiply(a); + result.inplace_multiply(a); return result; } Vector operator*(const Vector& a) const { - return vec_multiply(a); + return multiply(a); } Vector& operator*=(const Vector& a) { - inplace_vec_multiply(a); + inplace_multiply(a); + return *this; + } + //################################################ + //# VECTOR: Scalar Divide # + //################################################ + template ::value>::type> + void inplace_divide(const U a){ + const T a_hat = static_cast(a); + const uint64_t n = v.size(); + for (uint64_t i = 0; i < n; ++i){ + v[i] /= a_hat; + } + } + template ::value>::type> + Vector divide(const U a) const{ + Vector result = *this; + result.inplace_divide(a); + return result; + } + template ::value>::type> + Vector operator/(const U a) const { + return divide(a); + } + template ::value>::type> + Vector& operator/=(const U a) { + inplace_divide(a); return *this; } //################################################## //# VECTOR: Vector Divide # //################################################## - void inplace_vec_divide(const Vector& a){ + void inplace_divide(const Vector& a){ if (a.size() != v.size()){ - throw std::runtime_error("utill:Vector.inplace_vec_divide -> Dimensions does not fit"); + throw std::runtime_error("utill:Vector.inplace_divide -> Dimensions does not fit"); } - uint64_t n = a.size(); for (uint64_t i = 0; i < n; ++i){ v[i] /= a[i]; } - } - Vector vec_divide(const Vector& a) const{ + Vector divide(const Vector& a) const{ Vector result = *this; - result.inplace_vec_divide(a); + result.inplace_divide(a); return result; } Vector operator/(const Vector& a) const { - return vec_divide(a); + return divide(a); } Vector& operator/=(const Vector& a) { - inplace_vec_divide(a); + inplace_divide(a); return *this; } - + //############################################### + //# VECTOR: Scalar Power # + //############################################### + template ::value>::type> + void inplace_power(const U a){ + const uint64_t n = v.size(); + for (uint64_t i = 0; i < n; ++i){ + v[i] = static_cast(std::pow(v[i], a)); + } + } + template ::value>::type> + Vector power(const U a) const{ + Vector result = *this; + result.inplace_power(a); + return result; + } + //############################################### + //# VECTOR: Vector Power # + //############################################### + void inplace_power(const Vector& a){ + if (a.size() != v.size()){ + throw std::runtime_error("utill:Vector.inplace_power -> Dimensions does not fit"); + } + uint64_t n = a.size(); + for (uint64_t i = 0; i < n; ++i){ + v[i] = static_cast(std::pow(v[i], a[i])); + } + } + Vector power(const Vector& a) const{ + Vector result = *this; + result.inplace_power(a); + return result; + } + //################################################ + //# VECTOR: Scalar Square # + //################################################ + template ::value>::type> + void inplace_square(const U a){ + const uint64_t n = v.size(); + for (uint64_t i = 0; i < n; ++i){ + v[i] = static_cast(std::sqrt(v[i], a)); + } + } + template ::value>::type> + Vector square(const U a) const{ + Vector result = *this; + result.inplace_square(a); + return result; + } + //################################################ + //# VECTOR: Vector square # + //################################################ + void inplace_square(const Vector& a){ + if (a.size() != v.size()){ + throw std::runtime_error("utill:Vector.inplace_square -> Dimensions does not fit"); + } + uint64_t n = a.size(); + for (uint64_t i = 0; i < n; ++i){ + v[i] = static_cast(std::sqrt(v[i], a[i])); + } + } + Vector square(const Vector& a) const{ + Vector result = *this; + result.inplace_square(a); + return result; + } + //################################################### + //# VECTOR: Dot Product # + //################################################### + T dot(const Vector& a)const { + if (a.size() != v.size()){ + throw std::runtime_error("utill:Vector.dot -> Dimensions does not fit"); + } + T result; + const uint64_t n = v.size(); + for (uint64_t i = 0; i < n; ++i){ + result += a[i]*v[i]; + } + return result; + } + //############################################ + //# VECTOR: Sum # + //############################################ + T sum()const{ + T result = T{0}; + const uint64_t n = v.size(); + for (uint64_t i = 0; i < n; ++i){ + result += v[i]; + } + return result; + } + //############################################ + //# VECTOR: Norm # + //############################################ + T norm() const{ + return static_cast(std::sqrt(this->dot(*this))); + } //###################################################### //# VECTOR: Support Functions # //###################################################### - - - inline friend std::ostream& operator << (std::ostream& out, const Vector& vec){ out << "["; for (uint64_t i = 0; i < vec.v.size(); i++){ @@ -213,20 +386,6 @@ public: void print() const{ std::cout << *this << std::endl; } -/* - void linspace(const T start, const T stop, const T num){ - v.clear(); - - if (num > 1){ - - double delta = (stop - start)/(num - 1); - - for (uint64_t i = 0; i < num; i++){ - v.push_back(static_cast(start + delta * i)); - } - //v.push_back(static_cast(stop)); - } - }*/ }; typedef Vector Vi; diff --git a/obj/main.o b/obj/main.o index d45348fb7ffced070424b1ea20acf421d170c824..291e788f12c46b65257fe57c4113c94060e85cd1 100644 GIT binary patch literal 108760 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

UomzLMkb`+Ir8 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 +#include + + +#define CHECK(cond, msg) \ + do { if (!(cond)) throw std::runtime_error(msg); } while (0) + +template +void expect_throw(F&& f, const char* msg_if_no_throw) { + try { + f(); + throw std::runtime_error(msg_if_no_throw); + } catch (const std::exception&) { + // ok: an exception was thrown + } +} + int main(int argc, char const *argv[]) { - utils::Vf vect1(3,1), vect2(3,1), vect3(3,1), addition_test(3,7), subtract_test(3,-2); - //########################################### - //# VECTOR TYPE TEST # - //# Addition Test # - //########################################### - vect1.inplace_add(vect2); - vect3 = vect1.add(vect2).add(vect1) + vect2; - vect3 += vect2; - if (vect3 != addition_test){ - throw std::runtime_error("Addition Test -> Failed");} + using utils::Vf; - //########################################### - //# VECTOR TYPE TEST # - //# Subtract Test # - //########################################### - vect1.inplace_vec_subtract(vect2); - vect3 = vect1.vec_subtract(vect2).vec_subtract(vect1) - vect2; - vect3.print(); - vect3 = vect3.add(2); - vect3.print(); - if (vect3 != subtract_test){ - throw std::runtime_error("Subtract Test -> Failed");} + // ---------------- Equality / Inequality ---------------- + { + Vf a(3, 1.0f); // [1,1,1] + Vf b(3, 1.0f); // [1,1,1] + Vf c(3, 2.0f); // [2,2,2] + CHECK(a == b, "a should equal b"); + CHECK(!(a != b), "a should not be != b"); + CHECK(a != c, "a should not equal c"); + // mutate one element + a[1] = 5.0f; + CHECK(a != b, "after mutation, a should differ from b"); + a[1] = 1.0f; // restore + } +// ---------------- Vector + Vector (and +=) ---------------- + { + Vf a(3, 1.0f); // [1,1,1] + Vf b(3, 2.0f); // [2,2,2] + Vf expect(3, 3.0f); // [3,3,3] - return 0; + Vf c = a + b; + CHECK(c == expect, "a + b should be [3,3,3]"); + + a += b; // a becomes [3,3,3] + CHECK(a == expect, "a += b should produce [3,3,3]"); + } + + // ---------------- Vector - Vector (and -=) ---------------- + { + Vf a(3, 5.0f); // [5,5,5] + Vf b(3, 2.0f); // [2,2,2] + Vf expect(3, 3.0f); // [3,3,3] + + Vf c = a - b; + CHECK(c == expect, "a - b should be [3,3,3]"); + + a -= b; // a becomes [3,3,3] + CHECK(a == expect, "a -= b should produce [3,3,3]"); + } + + // ---------------- Elementwise Multiply (and *=) ---------------- + { + Vf a(3, 2.0f); // [2,2,2] + Vf b(3, 3.0f); // [3,3,3] + Vf expect(3, 6.0f); // [6,6,6] + + Vf c = a * b; + CHECK(c == expect, "a * b (elemwise) should be [6,6,6]"); + + a *= b; // a becomes [6,6,6] + CHECK(a == expect, "a *= b should produce [6,6,6]"); + } + + // ---------------- Elementwise Divide (and /=) ---------------- + { + Vf a(3, 6.0f); // [6,6,6] + Vf b(3, 2.0f); // [2,2,2] + Vf expect(3, 3.0f); // [3,3,3] + + Vf c = a / b; + CHECK(c == expect, "a / b (elemwise) should be [3,3,3]"); + + a /= b; // a becomes [3,3,3] + CHECK(a == expect, "a /= b should produce [3,3,3]"); + } + + // ---------------- Scalar + Vector (and +=) ---------------- + { + Vf a(3, 1.0f); // [1,1,1] + Vf expect1(3, 6.0f); // [6,6,6] + Vf expect2(3, 3.0f); // [3,3,3] + + Vf c = a + 5.0f; // v + s + CHECK(c == expect1, "a + 5 should be [6,6,6]"); + + Vf d = 2.0f + a; // s + v (friend operator) + CHECK(d == expect2, "2 + a should be [3,3,3]"); + + a += 2.0f; // a becomes [3,3,3] + CHECK(a == expect2, "a += 2 should produce [3,3,3]"); + } + + // ---------------- Scalar - Vector / Vector - Scalar ---------------- + { + Vf a(3, 5.0f); // [5,5,5] + Vf expect1(3, 3.0f); // [3,3,3] + Vf expect2(3, -3.0f); // [ -3,-3,-3 ] if 2 - a (only if you've implemented it) + + Vf c = a - 2.0f; // v - s + CHECK(c == expect1, "a - 2 should be [3,3,3]"); + + // NOTE: Your friend operator-(U a, const Vector b) currently returns (b - a), + // which means `2 - a` computes `a - 2`. That's a bit unusual. + // We'll avoid asserting 2 - a here to match your current implementation choice. + (void)expect2; // silence unused warning + } + + // ---------------- Scalar * Vector / Vector * Scalar ---------------- + { + + Vf a(3, 2.0f); // [2,2,2] + uint64_t b = 3; // 3 + Vf expect(3, 6.0f); // [6,6,6] + + Vf c = a * b; // v * s + CHECK(c == expect, "a * 3 should be [6,6,6]"); + + Vf d = b * a; // s * v (friend) + CHECK(d == expect, "3 * a should be [6,6,6]"); + + a *= b; // a becomes [6,6,6] + CHECK(a == expect, "a *= 3 should produce [6,6,6]"); + } + + // ---------------- Vector / Scalar (and /= scalar) ---------------- + { + Vf a(3, 6.0f); // [6,6,6] + uint64_t b = 2; // 3 + Vf expect(3, 3.0f); // [3,3,3] + + Vf c = a / b; // v / s + CHECK(c == expect, "a / 2 should be [3,3,3]"); + + a /= b; // a becomes [3,3,3] + CHECK(a == expect, "a /= 2 should produce [3,3,3]"); + } + + // ---------------- Size mismatch throws ---------------- + { + Vf a(3, 1.0f); + Vf b(4, 2.0f); + + expect_throw([&] { a.inplace_add(b); }, + "inplace_add should throw on size mismatch"); + expect_throw([&] { (void)(a + b); }, + "operator+ should throw (through add) on size mismatch"); + expect_throw([&] { a.inplace_subtract(b); }, + "inplace_subtract should throw on size mismatch"); + expect_throw([&] { (void)(a - b); }, + "operator- should throw (through subtract) on size mismatch"); + expect_throw([&] { a.inplace_multiply(b); }, + "inplace_multiply should throw on size mismatch"); + expect_throw([&] { (void)(a * b); }, + "operator* should throw (through multiply) on size mismatch"); + expect_throw([&] { a.inplace_divide(b); }, + "inplace_divide should throw on size mismatch"); + expect_throw([&] { (void)(a / b); }, + "operator/ should throw (through divide) on size mismatch"); + } + + Vf b(3, 8.0f); // [1,1,1] + Vf c(3, 2.0f); // [2,2,2] + b.print(); + b.inplace_power(2); + b.print(); + std::cout << b.norm() << std::endl; + std::cout << "All Vector tests passed ✅\n"; + return 0; } \ No newline at end of file