github.com/djordje200179/extendedlibrary/datastructures@v1.7.1-0.20240227175559-d09520a92dd4/other/matrix/math_operations.go (about)

     1  package matrix
     2  
     3  import "github.com/djordje200179/extendedlibrary/misc/math"
     4  
     5  // Add adds multiple matrices together and returns the result.
     6  // If the matrices are not of the same size, it panics.
     7  // If no matrices are provided, it returns nil.
     8  func Add[T math.Real](matrices ...*Matrix[T]) *Matrix[T] {
     9  	if len(matrices) == 0 {
    10  		return nil
    11  	}
    12  
    13  	for i := 1; i < len(matrices); i++ {
    14  		if matrices[i].Size() != matrices[i-1].Size() {
    15  			panic("Matrix sizes don't match")
    16  		}
    17  	}
    18  
    19  	size := matrices[0].Size()
    20  
    21  	result := Zeros[T](size)
    22  	for i := range size.Elements() {
    23  		for _, matrix := range matrices {
    24  			result.values[i] += matrix.values[i]
    25  		}
    26  	}
    27  
    28  	return result
    29  }
    30  
    31  // Subtract subtracts the second matrix from the first and returns the result.
    32  // If the matrices are not of the same size, it panics.
    33  func Subtract[T math.Real](first, second *Matrix[T]) *Matrix[T] {
    34  	if first.Size() != second.Size() {
    35  		panic("Matrix sizes don't match")
    36  	}
    37  
    38  	size := first.Size()
    39  
    40  	result := New[T](size)
    41  
    42  	for i := range size.Elements() {
    43  		result.values[i] = first.values[i] - second.values[i]
    44  	}
    45  
    46  	return result
    47  }
    48  
    49  // ScalarMultiply multiplies the matrix with a scalar and returns the result.
    50  func ScalarMultiply[T math.Real](matrix *Matrix[T], scalar T) *Matrix[T] {
    51  	result := New[T](matrix.Size())
    52  
    53  	for i := range result.Size().Elements() {
    54  		result.values[i] = matrix.values[i] * scalar
    55  	}
    56  
    57  	return result
    58  }
    59  
    60  // Multiply multiplies two matrices together and returns the result.
    61  func Multiply[T math.Real](first, second *Matrix[T]) *Matrix[T] {
    62  	if first.Size().Width != second.Size().Height {
    63  		panic("Matrix sizes don't match")
    64  	}
    65  
    66  	resultSize := Size{
    67  		first.Size().Height,
    68  		second.Size().Width,
    69  	}
    70  
    71  	result := Zeros[T](resultSize)
    72  	for i := range result.Size().Height {
    73  		for j := range result.Size().Width {
    74  			var sum T
    75  			for k := range first.Size().Width {
    76  				sum += first.Get(i, k) * second.Get(k, j)
    77  			}
    78  
    79  			result.Set(i, j, sum)
    80  		}
    81  	}
    82  
    83  	return result
    84  }
    85  
    86  // DotMultiply multiplies multiple matrices together and returns the result.
    87  // This function is equivalent to multiplying the matrices element by element.
    88  // If the matrices are not of the same size, it panics.
    89  // If no matrices are provided, it returns nil.
    90  func DotMultiply[T math.Real](matrices ...*Matrix[T]) *Matrix[T] {
    91  	if len(matrices) == 0 {
    92  		return nil
    93  	}
    94  
    95  	for i := 1; i < len(matrices); i++ {
    96  		if matrices[i].Size() != matrices[i-1].Size() {
    97  			panic("Matrix sizes don't match")
    98  		}
    99  	}
   100  
   101  	size := matrices[0].Size()
   102  
   103  	result := New[T](size)
   104  	for i := range size.Elements() {
   105  		result.values[i] = 1
   106  		for _, matrix := range matrices {
   107  			result.values[i] *= matrix.values[i]
   108  		}
   109  	}
   110  
   111  	return result
   112  }
   113  
   114  // Negate negates the matrix and returns the result.
   115  func Negate[T math.Real](matrix *Matrix[T]) *Matrix[T] {
   116  	return ScalarMultiply[T](matrix, -1)
   117  }