Math-Zap
view release on metacpan or search on metacpan
lib/Math/Zap/Matrix.pm view on Meta::CPAN
sub new3v($$$)
{my ($a, $b, $c) = @_;
vectorCheck(@_) if debug;
my $m = round(bless(
{11=>$a->x, 12=>$b->x, 13=>$c->x,
21=>$a->y, 22=>$b->y, 23=>$c->y,
31=>$a->z, 32=>$b->z, 33=>$c->z,
}));
singular($m, 1);
$m;
}
=head3 new3vnc
Create a matrix from three vectors without checking
=cut
sub new3vnc($$$)
{my ($a, $b, $c) = vectorCheck(@_);
my $m = round(bless(
{11=>$a->x, 12=>$b->x, 13=>$c->x,
21=>$a->y, 22=>$b->y, 23=>$c->y,
31=>$a->z, 32=>$b->z, 33=>$c->z,
}));
$m;
}
=head2 Methods
=head3 check
Check its a matrix
=cut
sub check(@)
{if (debug)
{for my $m(@_)
{confess "$m is not a matrix" unless ref($m) eq __PACKAGE__;
}
}
return (@_)
}
=head3 is
Test its a matrix
=cut
sub is(@)
{for my $m(@_)
{return 0 unless ref($m) eq __PACKAGE__;
}
'matrix';
}
=head3 singular
Singular matrix?
=cut
sub singular($$)
{my $m = shift; # Matrix
my $a = 1e-2; # Accuracy
my $A = shift; # Action 0: return indicator, 1: confess
my $n = abs
($m->{11}*$m->{22}*$m->{33}
-$m->{11}*$m->{23}*$m->{32}
-$m->{12}*$m->{21}*$m->{33}
+$m->{12}*$m->{23}*$m->{31}
+$m->{13}*$m->{21}*$m->{32}
-$m->{13}*$m->{22}*$m->{31})
< $a;
confess "Singular matrix2" if $n and $A;
$n;
}
=head3 accuracy
Get/Set accuracy for comparisons
=cut
my $accuracy = 1e-10;
sub accuracy
{return $accuracy unless scalar(@_);
$accuracy = shift();
}
=head3 round
Round: round to nearest integer if within accuracy of that integer
=cut
sub round($)
{my ($a) = @_;
check(@_) if debug;
my ($n, $N);
for my $k(qw(11 12 13 21 22 23 31 32 33))
{$n = $a->{$k};
lib/Math/Zap/Matrix.pm view on Meta::CPAN
=cut
sub matrixMatrixMultiply($$)
{my ($a, $b) = check(@_); # Matrices
round bless
{11=>$a->{11}*$b->{11}+$a->{12}*$b->{21}+$a->{13}*$b->{31}, 12=>$a->{11}*$b->{12}+$a->{12}*$b->{22}+$a->{13}*$b->{32}, 13=>$a->{11}*$b->{13}+$a->{12}*$b->{23}+$a->{13}*$b->{33},
21=>$a->{21}*$b->{11}+$a->{22}*$b->{21}+$a->{23}*$b->{31}, 22=>$a->{21}*$b->{12}+$a->{22}*$b->{22}+$a->{23}*$b->{32}, 23=>$a->{21}*$b->{13}+$a->{22}*$b->{23}+$a->{23}*$b->{33},
31=>$a->{31}*$b->{11}+$a->{32}*$b->{21}+$a->{33}*$b->{31}, 32=>$a->{31}*$b->{12}+$a->{32}*$b->{22}+$a->{33}*$b->{32}, 33=>$a->{31}*$b->{13}+$a->{32}*$b->{23}+$a->{33}*$b->{33},
};
}
=head3 matrixScalarDivide
Matrix=Matrix / non zero scalar
=cut
sub matrixScalarDivide($$)
{my ($a) = check(@_[0..0]); # Matrices
my ($b) = @_[1..1]; # Scalar
confess "$b is not a scalar" if ref($b);
confess "$b is zero" if $b == 0;
round bless
{11=>$a->{11}/$b, 12=>$a->{12}/$b, 13=>$a->{13}/$b,
21=>$a->{21}/$b, 22=>$a->{22}/$b, 23=>$a->{23}/$b,
31=>$a->{31}/$b, 32=>$a->{32}/$b, 33=>$a->{33}/$b,
};
}
=head3 det
Determinant of matrix.
=cut
sub det($)
{my ($a) = @_; # Matrix
check(@_) if debug; # Check
+$a->{11}*$a->{22}*$a->{33}
-$a->{11}*$a->{23}*$a->{32}
-$a->{12}*$a->{21}*$a->{33}
+$a->{12}*$a->{23}*$a->{31}
+$a->{13}*$a->{21}*$a->{32}
-$a->{13}*$a->{22}*$a->{31};
}
=head3 d2
Determinant of 2*2 matrix
=cut
sub d2($$$$)
{my ($a, $b, $c, $d) = @_;
$a*$d-$b*$c;
}
=head3 inverse
Inverse of matrix
=cut
sub inverse($)
{my ($a) = @_; # Matrix
check(@_) if debug; # Check
return $a->{inverse} if defined($a->{inverse});
my $d = det($a);
return undef if $d == 0;
my $i = round bless
{11=>d2($a->{22}, $a->{32}, $a->{23}, $a->{33})/$d,
21=>d2($a->{23}, $a->{33}, $a->{21}, $a->{31})/$d,
31=>d2($a->{21}, $a->{31}, $a->{22}, $a->{32})/$d,
12=>d2($a->{13}, $a->{33}, $a->{12}, $a->{32})/$d,
22=>d2($a->{11}, $a->{31}, $a->{13}, $a->{33})/$d,
32=>d2($a->{12}, $a->{32}, $a->{11}, $a->{31})/$d,
13=>d2($a->{12}, $a->{22}, $a->{13}, $a->{23})/$d,
23=>d2($a->{13}, $a->{23}, $a->{11}, $a->{21})/$d,
33=>d2($a->{11}, $a->{21}, $a->{12}, $a->{22})/$d,
};
$a->{inverse} = $i;
$i;
}
=head3 identity
Identity matrix
=cut
sub identity()
{bless
{11=>1, 21=>0, 31=>0,
12=>0, 22=>1, 32=>0,
13=>0, 23=>0, 33=>1,
};
}
=head3 equals
Equals to within accuracy
=cut
( run in 0.623 second using v1.01-cache-2.11-cpan-524268b4103 )