Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement Matrix , its Methods and Some Functions including Strassen Matrix Multiplication in Go #662

Merged
merged 20 commits into from
Oct 26, 2023

Conversation

mohit07raghav19
Copy link
Contributor

@mohit07raghav19 mohit07raghav19 commented Sep 30, 2023

Title: Implementation of Matrix and Associated Methods in Go

Description:

This pull request introduces several enhancements to the math/matrix directory:

  • Matrix Data Type: Implemented a new Matrix data type in Go, providing a foundation for matrix operations.
  • Matrix Methods: Developed associated methods for the Matrix data type, enabling operations such as addition, subtraction, and multiplication.
  • Strassen's Algorithm: Included an efficient implementation of Strassen's Matrix Multiplication algorithm.
  • Error Handling: Integrated robust error handling for matrix operations to manage incompatible inputs effectively.
  • Concurrency Utilization: Leveraged Go's concurrency features for improved performance on large matrix computations.
  • Test Coverage: Added comprehensive unit tests to ensure the correctness of the matrix operations and Strassen's algorithm.

Closes #661 (if applicable)

- Added the Strassen matrix multiplication algorithm for efficient matrix multiplication.
- Added strassenmatrixmultiply.go to include the new algorithm.
- Added example usage and test functions for verification.
- Introduced benchmarks for performance evaluation.

Closes TheAlgorithms#661 (if applicable)
math/matrix/strassenmatrixmultiply.go Outdated Show resolved Hide resolved
math/matrix/strassenmatrixmultiply.go Outdated Show resolved Hide resolved
math/matrix/strassenmatrixmultiply.go Outdated Show resolved Hide resolved
math/matrix/strassenmatrixmultiply.go Outdated Show resolved Hide resolved
math/matrix/strassenmatrixmultiply_test.go Outdated Show resolved Hide resolved
math/matrix/strassenmatrixmultiply_test.go Outdated Show resolved Hide resolved
math/matrix/strassenmatrixmultiply_test.go Outdated Show resolved Hide resolved
math/matrix/strassenmatrixmultiply_test.go Outdated Show resolved Hide resolved
along with the following supporting functions and test cases:

1. `AddMatrices`: Function to add two matrices.
2. `SubtractMatrices`: Function to subtract two matrices.
3. `MultiplyMatrices`: Function to multiply two matrices simply using loops.
4. `PrintMatrix`: Function to print a matrix for debugging purposes.
5. `EqualMatrix`: Function to check if two matrices are equal.
6. `StrassenMatrixMultiply` : Function to multiply two matrices using strassen algorithm
@mohit07raghav19
Copy link
Contributor Author

@raklaptudirm , I have made the required changes in the code.
I request you to Verify the same.
Please let me know if I could do something related to it further.
Thank YOU :)

Copy link
Member

@raklaptudirm raklaptudirm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note the Go idiom that you should not repeat the package name. For example, in matrix.AddMatrices, you are using the word "Matrix" twice. matrix.Add is a much simpler name and it doesn't lose any information. Change the names accordingly.

Also, you could make some simple functions that find the lenght/breadth of a matrix, given you are trying to find that multiple times.

math/matrix/addmatrices.go Outdated Show resolved Hide resolved
math/matrix/equalmatrix.go Outdated Show resolved Hide resolved
math/matrix/printmatrix.go Outdated Show resolved Hide resolved
math/matrix/strassenmatrixmultiply.go Outdated Show resolved Hide resolved
@mohit07raghav19
Copy link
Contributor Author

Also, you could make some simple functions that find the length/breadth of a matrix, given you are trying to find that multiple times.

@raklaptudirm
For getting the Breadth of a matrix (only valid matrix.),

// Breadth returns the number of columns in a valid matrix.
func Breadth[T any](matrix [][]T) (int, error) {
	if err := IsValid(matrix); err != nil {
		return 0, err
	}

	if len(matrix) == 0 {
		return 0, nil // Return 0 if the matrix is empty and valid.
	}

	return len(matrix[0]), nil
}

in which IsValid func is used as

// IsValid checks if a matrix is valid, meaning all rows have the same number of columns.
func IsValid[T any](matrix [][]T) error {
	if len(matrix) == 0 {
		return nil // an empty matrix is considered valid
	}

	columns := len(matrix[0]) // Number of columns in the first row.

	for _, row := range matrix {
		if len(row) != columns {
			return errors.New("invalid matrix: rows have different numbers of columns")
		}
	}

	return nil
}

and Len func returns the length only if matrix is valid.

func Len[T any](matrix [][]T) (int, error) {
	if err := IsValid(matrix); err != nil {
		return 0, err
	}
	return len(matrix), nil
}

BUT now in many functions simple len(matrix) is used After verifying that it is a valid matrix. The code can become unnecessarily extended like for
result := make([][]T, len(matrix1)) , The code would be

// checked for IsValid(matrix1) above.
    length , err := Len(matrix1) // There is _no need_ to check for a valid matrix again
    if err!=nil {
         result := make([][]T, length)
         // ... appropriate code
    }

Do I need to change them to Len or Breadth ?

Renamed files and functions:
- addmatrices.go to add.go
- addmatrices_test.go to add_test.go
- matrixmultiply.go to multiply.go
- matrixmultiply_test.go to multiply_test.go
- subtractmatrices.go to subtract.go
- subtractmatrices_test.go to subtract_test.go
- printmatrix.go to print.go
- printmatrix_test.go to print_test.go

New files:
- breadth.go
- breadth_test.go
- checkequal.go
- checkequal_test.go
- isvalid.go
- isvalid_test.go
- length.go
- length_test.go
- samedimensions.go
- samedimensions_test.go

Modified files:
- strassenmatrixmultiply.go
- strassenmatrixmultiply_test.go

This commit includes renaming and restructuring files for clarity, adding new functionality, and removing some obsolete files.
@raklaptudirm
Copy link
Member

Don't do a validity check in the Length or Breadth functions, let the user decide when to do that.

Even better, you could make matrix a type with a constructor that ensures that the number of columns in each row is the same.

This commit introduces a new  type, represented as a struct with methods for creating, manipulating, and performing operations on matrices. The following changes have been made:

- Added the `Matrix` struct with fields for elements, rows, and columns.
- Implemented the `New` function to create a new matrix with specified dimensions and initial values.
- Implemented the `NewFromElements` function to create a matrix from a provided 2D slice of elements.
- Added the `Get` and `Set` methods to access and modify matrix elements by row and column indices.
- Implemented the `Print` method to print the matrix to the console.
- Introduced the `SameDimensions` method to check if two matrices have the same dimensions.
- Implemented functions for matrix operations, including `Add`, `Subtract`, `Multiply`, and `CheckEqual`.
- Added a helper function `IsValid` to check if a given matrix has consistent row lengths.

These changes provide a foundation for working with matrices in Go, allowing for easy creation, manipulation, and comparison of matrices.
In this commit, the following key additions have been made to the  folder:

- Implemented `StrassenMatrixMultiply`, a fast matrix multiplication algorithm, to efficiently multiply two matrices.

- Introduced  `Copy` method to create a deep copy of a matrix, allowing for independent manipulation without affecting the original matrix.

- Implemented `Submatrix` method to extract a submatrix from an existing matrix based on specified row and column indices.

- Added `Rows` and `Columns` methods to retrieve rows and columns of matrix.

- Included comprehensive test cases to ensure the correctness and robustness of these newly implemented features.

These enhancements expand the capabilities of the  type, making it more versatile and efficient in performing matrix operations.
@mohit07raghav19 mohit07raghav19 changed the title feat: Implemented Strassen Matrix Multiplication feat: Implement Matrix , its Methods and Some Functions including Strassen Matrix Multiplication in Go Oct 4, 2023
math/matrix/add.go Outdated Show resolved Hide resolved
@raklaptudirm
Copy link
Member

Also fix the CI errors.

In this commit, the following significant changes have been made:

1. Refactored the `Matrix` type from a pointer to a value type. Using a pointer for a small structure like `Matrix` was deemed unnecessary and has been updated to enhance code simplicity.

2. Added comprehensive benchmarks to all functions. These benchmarks will help ensure that the code performs efficiently and allows for easy performance profiling.

3. Fixed code integration errors that were identified during the refactoring process.
Copy link
Member

@tjgurwara99 tjgurwara99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't reviewed it fully, so will come back to this later. But I've left some thoughts on the PR 😄

math/matrix/print.go Outdated Show resolved Hide resolved
math/matrix/samedimensions.go Outdated Show resolved Hide resolved
math/matrix/samedimensions.go Outdated Show resolved Hide resolved
math/matrix/samedimensions.go Outdated Show resolved Hide resolved
math/matrix/add.go Outdated Show resolved Hide resolved
math/matrix/samedimensions.go Outdated Show resolved Hide resolved
math/matrix/add.go Outdated Show resolved Hide resolved
math/matrix/add.go Outdated Show resolved Hide resolved
…imensions to MatchDimensions, and remove unnecessary code

This commit updates the type variable T to constraints.Integer, providing a more specific type constraint. It also renames the SameDimensions function to MatchDimensions for clarity. Additionally, unnecessary code lines have been removed for cleaner and more optimized code.
math/matrix/add.go Outdated Show resolved Hide resolved
mohit07raghav19 and others added 5 commits October 26, 2023 00:50
Body:
- Updated the Add,Subtract, SubMatrix, and Multiply functions in the matrix package to use the context and sync packages for goroutine management and error handling.
- Removed the use of the errgroup package in these functions.
Body:
- Updated the Add,Subtract, SubMatrix, and Multiply functions in the matrix package to use the context and sync packages for goroutine management and error handling.
- Removed the use of the errgroup package in these functions.
@tjgurwara99
Copy link
Member

Well done! This is looking much better now 😄

PS: you might need to make an empty commit - the update GoDoc action has stopped the execution of other actions for some reason 😓

The GoDoc action has stopped the execution of other actions. This empty commit is a workaround to trigger the other actions to run.
Copy link
Member

@raklaptudirm raklaptudirm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A very good quality pr, LGTM :)

@raklaptudirm raklaptudirm merged commit 855c430 into TheAlgorithms:master Oct 26, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT]: Strassen Matrix Multiplication Implementation in Go
3 participants