diff --git a/LinearAlgebra/Matrix.cpp b/LinearAlgebra/Matrix.cpp index 689f86d..cbb7b7d 100644 --- a/LinearAlgebra/Matrix.cpp +++ b/LinearAlgebra/Matrix.cpp @@ -1,26 +1,53 @@ #include "Matrix.h" +#include #pragma region Matrix2 Matrix2::Matrix2(int nRows, int nCols) : nRows(nRows), nCols(nCols) { this->nValues = nRows * nCols; - data = new float[nValues](); + if (this->nValues == 0) + data = nullptr; + else { + this->data = new float[nValues](); + this->externalData = false; + } } Matrix2::Matrix2(float* data, int nRows, int nCols) - : nRows(nRows), nCols(nCols), data(data) { + : nRows(nRows), nCols(nCols), data(data){ this->nValues = nRows * nCols; + this->externalData = true; } Matrix2::~Matrix2() { - delete[] data; + if (data != nullptr && !this->externalData) + delete[] data; +} + +// Move constructor +Matrix2::Matrix2(Matrix2&& other) noexcept + : nRows(other.nRows), nCols(other.nCols), nValues(other.nValues), data(other.data) { + other.data = nullptr; // Set the other object's pointer to nullptr to avoid double deletion +} + +// Move assignment operator +Matrix2& Matrix2::operator=(Matrix2&& other) noexcept { + if (this != &other) { + delete[] data; // Clean up current data + nRows = other.nRows; + nCols = other.nCols; + nValues = other.nValues; + data = other.data; + other.data = nullptr; // Avoid double deletion + } + return *this; } Matrix2 Matrix2::Zero(int nRows, int nCols) { - Matrix2 m = Matrix2(nRows, nCols); - for (int ix = 0; ix < m.nValues; ix++) - m.data[ix] = 0; - return m; + Matrix2 r = Matrix2(nRows, nCols); + for (int ix = 0; ix < r.nValues; ix++) + r.data[ix] = 0; + return r; } Matrix2 Matrix2::Identity(int size) { @@ -31,7 +58,7 @@ Matrix2 Matrix2::Diagonal(float f, int size) { Matrix2 r = Matrix2(size, size); float* data = r.data; int valueIx = 0; - for (int ix = 0; ix < r.nValues; ix++) { + for (int ix = 0; ix < size; ix++) { data[valueIx] = f; valueIx += size + 1; } @@ -71,12 +98,15 @@ Matrix2 LinearAlgebra::Matrix2::operator*(const Matrix2& B) const { int BColOffset = i * BCols; // BColOffset is constant for each row of B for (int j = 0; j < BCols; ++j) { float sum = 0; + std::cout << " 0"; int BIndex = j; for (int k = 0; k < ACols; ++k) { + std::cout << " + " << this->data[ARowOffset + k] << " * " << B.data[BIndex]; sum += this->data[ARowOffset + k] * B.data[BIndex]; BIndex += BCols; } r.data[BColOffset + j] = sum; + std::cout << " = " << sum << " ix: " << BColOffset + j << "\n"; } } return r; diff --git a/LinearAlgebra/Matrix.h b/LinearAlgebra/Matrix.h index 5348f58..cd5bd76 100644 --- a/LinearAlgebra/Matrix.h +++ b/LinearAlgebra/Matrix.h @@ -11,11 +11,12 @@ class Matrix2 { int nCols = 0; int nValues = 0; float* data = nullptr; + bool externalData = true; Matrix2(int nRows, int nCols); Matrix2(float* data, int nRows, int nCols); - ~Matrix2(); + ~Matrix2(); static Matrix2 Zero(int nRows, int nCols); @@ -30,6 +31,10 @@ class Matrix2 { Matrix2 operator*(const Matrix2& m) const; void SetSlice(int rowStart, int rowStop, int colStart, int colStop, const Matrix2& m) const; +//private: + // move constructor and move assignment operator + Matrix2(Matrix2&& other) noexcept; + Matrix2& operator=(Matrix2&& other) noexcept; }; /// @brief Single precision float matrix diff --git a/LinearAlgebra/test/Matrix_test.cc b/LinearAlgebra/test/Matrix_test.cc index a782afc..4cb66b8 100644 --- a/LinearAlgebra/test/Matrix_test.cc +++ b/LinearAlgebra/test/Matrix_test.cc @@ -1,60 +1,88 @@ #if GTEST #include -#include #include +#include #include "Matrix.h" -TEST(Matrix2, Multiplication) { - // Test 1: Multiplying two 2x2 matrices - float dataA[] = {1, 2, 3, 4}; - float dataB[] = {5, 6, 7, 8}; - Matrix2 A(dataA, 2, 2); - Matrix2 B(dataB, 2, 2); - - Matrix2 result = A * B; - - float expectedData[] = {19, 22, 43, 50}; - for (int i = 0; i < 4; ++i) { - //assert(result.data[i] == expectedData[i]); - EXPECT_TRUE(result.data[i] == expectedData[i]); - } - std::cout << "Test 1 passed: 2x2 matrix multiplication.\n"; - - // Test 2: Multiplying a 3x2 matrix with a 2x3 matrix - float dataC[] = {1, 2, 3, 4, 5, 6}; - float dataD[] = {7, 8, 9, 10, 11, 12}; - Matrix2 C(dataC, 3, 2); - Matrix2 D(dataD, 2, 3); - - Matrix2 result2 = C * D; - - float expectedData2[] = {29, 32, 35, 65, 72, 79, 101, 112, 123}; - for (int i = 0; i < 9; ++i) { - assert(result2.data[i] == expectedData2[i]); - EXPECT_TRUE(result2.data[i] == expectedData2[i]); - } - std::cout << "Test 2 passed: 3x2 * 2x3 matrix multiplication.\n"; - - // Test 3: Multiplying with a zero matrix +TEST(Matrix2, Zero) { + // Test case 1: 2x2 zero matrix Matrix2 zeroMatrix = Matrix2::Zero(2, 2); - Matrix2 result3 = A * zeroMatrix; - - for (int i = 0; i < 4; ++i) { - assert(result3.data[i] == 0); - EXPECT_TRUE(result3.data[i] == 0); + EXPECT_TRUE(zeroMatrix.nRows == 2); + EXPECT_TRUE(zeroMatrix.nCols == 2); + for (int i = 0; i < zeroMatrix.nValues; ++i) { + EXPECT_TRUE(zeroMatrix.data[i] == 0.0f); } - std::cout << "Test 3 passed: Multiplication with zero matrix.\n"; + std::cout << "Test case 1 passed: 2x2 zero matrix\n"; - // Test 4: Multiplying with an identity matrix - Matrix2 identityMatrix = Matrix2::Identity(2); - Matrix2 result4 = A * identityMatrix; - - for (int i = 0; i < 4; ++i) { - assert(result4.data[i] == A.data[i]); - EXPECT_TRUE(result4.data[i] == A.data[i]); + // Test case 2: 3x3 zero matrix + zeroMatrix = Matrix2::Zero(3, 3); + EXPECT_TRUE(zeroMatrix.nRows == 3); + EXPECT_TRUE(zeroMatrix.nCols == 3); + for (int i = 0; i < zeroMatrix.nValues; ++i) { + EXPECT_TRUE(zeroMatrix.data[i] == 0.0f); } - std::cout << "Test 4 passed: Multiplication with identity matrix.\n"; + std::cout << "Test case 2 passed: 3x3 zero matrix\n"; + + // Test case 3: 1x1 zero matrix + zeroMatrix = Matrix2::Zero(1, 1); + EXPECT_TRUE(zeroMatrix.nRows == 1); + EXPECT_TRUE(zeroMatrix.nCols == 1); + EXPECT_TRUE(zeroMatrix.data[0] == 0.0f); + std::cout << "Test case 3 passed: 1x1 zero matrix\n"; + + // Test case 4: 0x0 matrix (edge case) + zeroMatrix = Matrix2::Zero(0, 0); + EXPECT_TRUE(zeroMatrix.nRows == 0); + EXPECT_TRUE(zeroMatrix.nCols == 0); + EXPECT_TRUE(zeroMatrix.data == nullptr); + std::cout << "Test case 4 passed: 0x0 matrix\n"; +} + +TEST(Matrix2, Multiplication) { + // Test 1: Multiplying two 2x2 matrices + float dataA[] = {1, 2, 3, 4}; + float dataB[] = {5, 6, 7, 8}; + Matrix2 A(dataA, 2, 2); + Matrix2 B(dataB, 2, 2); + + Matrix2 result = A * B; + + float expectedData[] = {19, 22, 43, 50}; + for (int i = 0; i < 4; ++i) + EXPECT_TRUE(result.data[i] == expectedData[i]); + std::cout << "Test 1 passed: 2x2 matrix multiplication.\n"; + + + // Test 2: Multiplying a 3x2 matrix with a 2x3 matrix + float dataC[] = {1, 2, 3, 4, 5, 6}; + float dataD[] = {7, 8, 9, 10, 11, 12}; + Matrix2 C(dataC, 3, 2); + Matrix2 D(dataD, 2, 3); + + Matrix2 result2 = C * D; + + float expectedData2[] = {27, 30, 33, 61, 68, 75, 95, 106, 117}; + for (int i = 0; i < 9; ++i) + EXPECT_TRUE(result2.data[i] == expectedData2[i]); + std::cout << "Test 2 passed: 3x2 * 2x3 matrix multiplication.\n"; + + // Test 3: Multiplying with a zero matrix + Matrix2 zeroMatrix = Matrix2::Zero(2, 2); + Matrix2 result3 = A * zeroMatrix; + + for (int i = 0; i < 4; ++i) + EXPECT_TRUE(result3.data[i] == 0); + std::cout << "Test 3 passed: Multiplication with zero matrix.\n"; + + // Test 4: Multiplying with an identity matrix + Matrix2 identityMatrix = Matrix2::Identity(2); + Matrix2 result4 = A * identityMatrix; + + for (int i = 0; i < 4; ++i) + EXPECT_TRUE(result4.data[i] == A.data[i]); + std::cout << "Test 4 passed: Multiplication with identity matrix.\n"; + } TEST(MatrixSingle, Init) { diff --git a/LocalParticipant.h b/LocalParticipant.h index aa8d7d5..07c0ca2 100644 --- a/LocalParticipant.h +++ b/LocalParticipant.h @@ -86,10 +86,11 @@ class LocalParticipant : public Participant { #if defined(__unix__) || defined(__APPLE__) int sock; +#elif defined(_WIN32) || defined(_WIN64) + sockaddr_in remote_addr; + sockaddr_in server_addr; + sockaddr_in broadcast_addr; #endif - // sockaddr_in remote_addr; - // sockaddr_in server_addr; - // sockaddr_in broadcast_addr; #endif