sub
new {
my
$type
=
shift
;
my
$self
= [];
my
$len
=
scalar
(@{
$_
[0]});
for
(
@_
) {
return
undef
if
scalar
(@{
$_
}) !=
$len
;
push
(@{
$self
}, [@{
$_
}]);
}
bless
$self
,
$type
;
}
sub
concat {
my
$self
=
shift
;
my
$other
=
shift
;
my
$result
= new PDF::API2::Matrix (@{
$self
});
return
undef
if
scalar
(@{
$self
}) !=
scalar
(@{
$other
});
for
my
$i
(0 .. $
push
@{
$result
->[
$i
]}, @{
$other
->[
$i
]};
}
$result
;
}
sub
transpose {
my
$self
=
shift
;
my
@result
;
my
$m
;
for
my
$col
(@{
$self
->[0]}) {
push
@result
, [];
}
for
my
$row
(@{
$self
}) {
$m
=0;
for
my
$col
(@{
$row
}) {
push
(@{
$result
[
$m
++]},
$col
);
}
}
new PDF::API2::Matrix (
@result
);
}
sub
vekpro {
my
(
$a
,
$b
) =
@_
;
my
$result
=0;
for
my
$i
(0 .. $
$result
+=
$a
->[
$i
] *
$b
->[
$i
];
}
$result
;
}
sub
multiply {
my
$self
=
shift
;
my
$other
=
shift
->transpose;
my
@result
;
my
$m
;
return
undef
if
$
for
my
$row
(@{
$self
}) {
my
$rescol
= [];
for
my
$col
(@{
$other
}) {
push
(@{
$rescol
}, vekpro(
$row
,
$col
));
}
push
(
@result
,
$rescol
);
}
new PDF::API2::Matrix (
@result
);
}
sub
solve {
my
$m
= new PDF::API2::Matrix (@{
$_
[0]});
my
$mr
= $
my
$mc
= $
my
$f
;
my
$try
;
my
$k
;
my
$i
;
my
$j
;
my
$eps
= 0.000001;
return
undef
if
$mc
<=
$mr
;
ROW:
for
(
$i
= 0;
$i
<=
$mr
;
$i
++) {
$try
=
$i
;
while
(
abs
(
$m
->[
$i
]->[
$i
]) <
$eps
) {
last
ROW
if
$try
++ >
$mr
;
my
$row
=
splice
(@{
$m
},
$i
,1);
push
(@{
$m
},
$row
);
}
$f
=
$m
->[
$i
]->[
$i
];
for
(
$k
= 0;
$k
<=
$mc
;
$k
++) {
$m
->[
$i
]->[
$k
] /=
$f
;
}
for
(
$j
= 0;
$j
<=
$mr
;
$j
++) {
next
if
$i
==
$j
;
$f
=
$m
->[
$j
]->[
$i
];
for
(
$k
= 0;
$k
<=
$mc
;
$k
++) {
$m
->[
$j
]->[
$k
] -=
$m
->[
$i
]->[
$k
] *
$f
;
}
}
}
transpose new PDF::API2::Matrix @{
$m
->transpose}[
$mr
+1 ..
$mc
];
}
sub
print
{
my
$self
=
shift
;
print
STDERR
"Matrix: \n"
;
print
@_
if
scalar
(
@_
);
for
my
$row
(@{
$self
}) {
for
my
$col
(@{
$row
}) {
printf
STDERR
"%10.5f "
,
$col
;
}
print
STDERR
"\n"
;
}
}
1;