From b6557fb991c378a8b417a2a6d712d0d2d6a3cb58 Mon Sep 17 00:00:00 2001 From: Thierry Moisan Date: Tue, 9 Dec 2008 10:56:08 -0500 Subject: [PATCH] Overloading multiplication for matrices (not dot product) --- Changes | 1 + pod/Matrix.pod | 28 +++++++++++++++++++++++++--- t/Matrix.t | 44 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index ba0ffc5..3770e0f 100644 --- a/Changes +++ b/Changes @@ -24,6 +24,7 @@ - All test files now keep track of how many tests should run - Fix an include bug in Histogram2D which caused the build to fail - Operator overloading for addition and subtraction with matrices + - Operator overloading for multiplication with matrices =head1 v0.14 - October 21 2008 diff --git a/pod/Matrix.pod b/pod/Matrix.pod index 50359aa..76e97a7 100644 --- a/pod/Matrix.pod +++ b/pod/Matrix.pod @@ -5,6 +5,7 @@ use Carp qw/croak/; use Math::GSL qw/:all/; use Math::GSL::Errno qw/:all/; use overload + '*' => \&_multiplication, '+' => \&_addition, '-' => \&_subtract, fallback => 1, @@ -349,7 +350,12 @@ Math::GSL::Matrix - Mathematical functions concerning Matrices my $matrix2 = $matrix1 + 4; # You can add or substract values or matrices to OO matrices my $matrix3 = $matrix1 - 4; my $matrix4 = $matrix2 + $matrix1; - my $matrix5 = gsl_matrix_alloc(5,5); # standard interface + my $matrix5 = $matrix2 * $matrix1; # This is NOT a scalar product, it simply multiply each element + # with the element of $matrix1 that have the same position + # See Math::GSL::BLAS if you want scalar product + + my $matrix6 = $matrix2 * 8; # Multiply every elements of $matrix2 by 8 + my $matrix7 = gsl_matrix_alloc(5,5); # standard interface =head1 Objected Oriented Interface to GSL Math::GSL::Matrix @@ -568,7 +574,7 @@ sub _addition { if ( $left->cols == $right->cols && $left->rows == $right->rows ) { gsl_matrix_add($lcopy->raw, $right->raw); } else { - croak "Math::GSL - addition of matrices must be called with two objects matrices and must have the same number of columnss and rows"; + croak "Math::GSL - addition of matrices must be called with two objects matrices and must have the same number of columns and rows"; } } else { gsl_matrix_add_constant($lcopy->raw, $right); @@ -585,7 +591,7 @@ sub _subtract { if ( $left->cols == $right->cols && $left->rows == $right->rows ) { gsl_matrix_sub($lcopy->raw, $right->raw); } else { - croak "Math::GSL - subtraction of matrices must be called with two objects matrices and must have the same number of columnss and rows"; + croak "Math::GSL - subtraction of matrices must be called with two objects matrices and must have the same number of columns and rows"; } } else { gsl_matrix_add_constant($lcopy->raw, $right*-1); @@ -593,6 +599,22 @@ sub _subtract { return $lcopy; } +sub _multiplication { + my ($left,$right) = @_; + my $lcopy = $left->copy; + + if ( blessed $right && $right->isa('Math::GSL::Matrix') ) { + if ( $left->cols == $right->cols && $left->rows == $right->rows ) { + gsl_matrix_mul_elements($lcopy->raw, $right->raw); + } else { + croak "Math::GSL - multiplication of elements of matrices must be called with two objects matrices and must have the same number of columns and rows"; + } } + else { + gsl_matrix_scale($lcopy->raw, $right); + } + return $lcopy; +} + =head1 DESCRIPTION Here is a list of all the functions included in this module : diff --git a/t/Matrix.t b/t/Matrix.t index 2617bd1..b99e18a 100644 --- a/t/Matrix.t +++ b/t/Matrix.t @@ -1,6 +1,6 @@ package Math::GSL::Matrix::Test; use base q{Test::Class}; -use Test::More tests => 191; +use Test::More tests => 209; use Math::GSL qw/:all/; use Math::GSL::Test qw/:all/; use Math::GSL::Matrix qw/:all/; @@ -576,6 +576,11 @@ sub GSL_MATRIX_OO_ADDITION_CONSTANT : Tests { ok_similar([$m2->col(1)->as_list], [8,9,10]); ok_similar([$m2->col(2)->as_list], [13,12,11]); ok_similar([$m2->col(0)->as_list], [4,4,4]); + + my $m3 = 4 + $m; + ok_similar([$m3->col(1)->as_list], [8,9,10]); + ok_similar([$m3->col(2)->as_list], [13,12,11]); + ok_similar([$m3->col(0)->as_list], [4,4,4]); } sub GSL_MATRIX_OO_ADDITION_MATRICES : Tests { @@ -626,4 +631,41 @@ sub GSL_MATRIX_OO_SUBSTRACTION_MATRICES : Tests { ok_similar([$m2->col(2)->as_list], [0,0,0]); } +sub GSL_MATRIX_OO_MULTIPLICATION_CONSTANT : Tests { + my $m = Math::GSL::Matrix->new(3,3); + $m->set_col(1, [4,5,6]) + ->set_col(2, [9,8,7]); + my $m2 = $m * 4; + ok_similar([$m->col(2)->as_list], [9,8,7]); + ok_similar([$m->col(1)->as_list], [4,5,6]); + ok_similar([$m->col(0)->as_list], [0,0,0]); + + ok_similar([$m2->col(1)->as_list], [16,20,24]); + ok_similar([$m2->col(2)->as_list], [36,32,28]); + ok_similar([$m2->col(0)->as_list], [0,0,0]); + + my $m3 = 4 * $m; + ok_similar([$m3->col(1)->as_list], [16,20,24]); + ok_similar([$m3->col(2)->as_list], [36,32,28]); + ok_similar([$m3->col(0)->as_list], [0,0,0]); +} + +sub GSL_MATRIX_OO_MULTIPLICATION_MATRICES : Tests { + my $m = Math::GSL::Matrix->new(3,3); + my $m3 = Math::GSL::Matrix->new(3,3); + $m->set_col(1, [4,5,6]) + ->set_col(2, [9,8,7]) + ->set_col(0, [1,2,3]); + $m3->set_col(1, [1,2,3]) + ->set_col(2, [9,8,7]) + ->set_col(0, [1,2,3]); + my $m2 = $m * $m3; + ok_similar([$m->col(0)->as_list], [1,2,3]); + ok_similar([$m->col(2)->as_list], [9,8,7]); + ok_similar([$m->col(1)->as_list], [4,5,6]); + + ok_similar([$m2->col(0)->as_list], [1,4,9]); + ok_similar([$m2->col(1)->as_list], [4,10,18]); + ok_similar([$m2->col(2)->as_list], [81,64,49]); +} Test::Class->runtests; -- 2.11.4.GIT