| Math-Orthonormalize documentation | Contained in the Math-Orthonormalize distribution. |
Math::Orthonormalize - Gram-Schmidt Orthonormalization of vectors
use Math::Orthonormalize qw(:all);
my @base_of_r_2 = (
[2, 1],
[1, 3]
);
my $vector = [1, 2, 3];
my @orthonormalized = orthonormalize(@base_of_r_2);
my @orthogonalized = orthogonalize(@base_of_r_2);
my $normalized = normalize($vector);
my $scaled = scale(2, $vector);
my $scalar = scalar_product($vector1, $vector2);
Math::Orthonormalize offers subroutines to compute normalized or non-normalized orthogonal bases of Euclidean vector spaces. That means: Given a vector base of R^n, it computes a new base of R^n whose individual vectors are all orthogonal. If those new base vectors all have a length of 1, the base is orthonormalized.
The module uses the Gram-Schmidt Algorithm.
No subroutines are exported by default, but the standart Exporter semantics are in place, including the ':all' tag that imports all of the exportable subroutines which are listed below.
Takes any number (>1) of vectors (array refs of vector components) as argument which form a base (that is, they are linearly independent) and returns an orthogonalized and normalized base of the same vector space (that is, n new array references).
Takes any number (>1) of vectors (array refs of vector components) as argument which form a base (that is, they are linearly independent) and returns an orthogonalized base of the same vector space (that is, n new array references).
Normalizes a vector. That is, it changes the vector length to 1 without changing the vector's direction.
Takes an array reference with the vector components as argument and returns a new array reference containing the normalized vector components.
Takes a scalar and a vector (array reference of vector components) as arguments. Multiplies every component of the vector by the specified scalar and returns a new array reference containing the scaled vector components.
Computes the scalar product of two vectors. Expects two array references with vector components (same number of components) as argument and returns their scalar product.
Steffen Mueller, orthonormalize-module at steffen-mueller dot net
(German) Merziger, Wirth: "Repetitorium der Höheren Mathematik" (Binomi, 1999)
You may find the current versions of this module at http://steffen-mueller.net/ or on CPAN.
Copyright (C) 2004-2005 by Steffen Mueller
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.6.1 or, at your option, any later version of Perl 5 you may have available.
| Math-Orthonormalize documentation | Contained in the Math-Orthonormalize distribution. |
package Math::Orthonormalize; use 5.006; use strict; use warnings; use Math::Symbolic qw/parse_from_string/; use Carp; our $VERSION = '1.00'; require Exporter; our @ISA = qw(Exporter); our %EXPORT_TAGS = ( 'all' => [ qw( orthonormalize orthogonalize scalar_product normalize scale ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = ();
sub orthonormalize { my @vectors = @_; croak "No arguments to orthogonalize" if not @vectors; croak "Arguments to orthogonalize must be array refs (vectors)" if grep {ref($_) ne 'ARRAY'} @vectors; my $dim = @{$vectors[0]}; croak "Vectors must have same dimension for orthogonalization" if grep {@$_ != $dim} @vectors; my @base = orthogonalize(@vectors); @base = map {normalize($_)} @base; return @base; }
sub orthogonalize { my @vectors = @_; croak "No arguments to orthogonalize" if not @vectors; croak "Arguments to orthogonalize must be array refs (vectors)" if grep {ref($_) ne 'ARRAY'} @vectors; my $dim = @{$vectors[0]}; croak "Vectors must have same dimension for orthogonalization" if grep {@$_ != $dim} @vectors; my @newbase; push @newbase, $vectors[0]; my @squares; push @squares, scalar_product($vectors[0], $vectors[0]) if @vectors > 1; foreach my $i (1..$#vectors) { my $new = $vectors[$i]; foreach my $j (0..$#newbase) { my $vec = scale( scalar_product($vectors[$i], $newbase[$j]) / $squares[$j], $newbase[$j] ); @$new = map {$_ -= shift @$vec} @$new; } push @newbase, $new; push @squares, scalar_product($new, $new) if $i < $#vectors; } return @newbase; }
sub normalize { my $v = shift; croak "Argument to normalize() must be an array ref (vector)" if not ref($v) eq 'ARRAY'; croak "Cannot normalize 0-dimensional vectors" if @$v == 0; my $sum = $v->[0]**2; $sum += $v->[$_]**2 for 1..$#$v; $sum = sqrt($sum); croak "Cannot normalize 0-vector" if $sum == 0; return [map {$_ / $sum} @$v]; }
sub scale { croak "scale() takes a scalar and a vector (ary ref) as arguments" if not @_ == 2 or not ref($_[1]) eq 'ARRAY'; croak "Cannot handle 0-dimensional vectors" if @{$_[1]} == 0; my $new = []; foreach (@{$_[1]}) { push @$new, $_[0] * $_; } return $new; }
sub scalar_product { croak "Invalid number of arguments to scalar_product()" if not @_ == 2; my ($v1, $v2) = @_; croak "Cannot compute the scalar product of vectors of different ", "dimensions" if @$v1 != @$v2; croak "Cannot deal with 0-dimensional vectors" if @$v1 == 0; my $sum = $v1->[0] * $v2->[0]; return $sum if @$v1 == 1; $sum += $v1->[$_] * $v2->[$_] for 1..$#$v1; return $sum; } 1; __END__