diff mayachemtools/lib/Vector.pm @ 0:73ae111cf86f draft

Uploaded
author deepakjadmin
date Wed, 20 Jan 2016 11:55:01 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mayachemtools/lib/Vector.pm	Wed Jan 20 11:55:01 2016 -0500
@@ -0,0 +1,1554 @@
+package Vector;
+#
+# $RCSfile: Vector.pm,v $
+# $Date: 2015/02/28 20:47:30 $
+# $Revision: 1.34 $
+#
+# Author: Manish Sud <msud@san.rr.com>
+#
+# Copyright (C) 2015 Manish Sud. All rights reserved.
+#
+# This file is part of MayaChemTools.
+#
+# MayaChemTools is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your option) any
+# later version.
+#
+# MayaChemTools is distributed in the hope that it will be useful, but without
+# any warranty; without even the implied warranty of merchantability of fitness
+# for a particular purpose.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
+# write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
+# Boston, MA, 02111-1307, USA.
+#
+
+use strict;
+use Carp;
+use Exporter;
+use Scalar::Util ();
+use StatisticsUtil ();
+
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+
+@ISA = qw(Exporter);
+@EXPORT = qw(IsVector UnitXVector UnitYVector UnitZVector UnitVector ZeroVector);
+@EXPORT_OK = qw(SetValuePrintFormat);
+
+%EXPORT_TAGS = (
+		all  => [@EXPORT, @EXPORT_OK]
+	       );
+
+# Setup class variables...
+my($ClassName, $ValueFormat);
+_InitializeClass();
+
+#
+# Using the following explicity overloaded operators, Perl automatically generates methods
+# for operations with no explicitly defined methods. Autogenerated methods are possible for
+# these operators:
+#
+#    o Arithmetic operators: += -= *= /= **= %= ++ -- x= .=
+#    o Increment and decrement: ++ --
+#
+# 'fallback' is set to 'false' to raise exception for all other operators.
+#
+use overload '""' => 'StringifyVector',
+
+  '0+' => '_NumifyVector',
+
+  '@{}' => '_VectorToArrayOperator',
+
+  '+' => '_VectorAdditionOperator',
+  '-' => '_VectorSubtractionOperator',
+  '*' => '_VectorMultiplicationOperator',
+  '/' => '_VectorDivisionOperator',
+  '**' => '_VectorExponentiationOperator',
+  '%' => '_VectorModulusOperator',
+
+  'x' => '_VectorCrossProductOperator',
+  '.' => '_VectorDotProductOperator',
+
+  'bool' => '_VectorBooleanOperator',
+  '!' => '_VectorNotBooleanOperator',
+
+  '==' => '_VectorEqualOperator',
+  '!=' => '_VectorNotEqualOperator',
+  '<' => '_VectorLessThanOperator',
+  '<=' => '_VectorLessThanEqualOperator',
+  '>' => '_VectorGreatarThanOperator',
+  '>=' => '_VectorGreatarThanEqualOperator',
+
+  'neg' => '_VectorNegativeValueOperator',
+
+  'abs' => '_VectorAbsoluteValueOperator',
+  'exp' => '_VectorExpNaturalBaseOperator',
+  'log' => '_VectorLogNaturalBaseOperator',
+  'sqrt' => '_VectorSquareRootOperator',
+  'cos' => '_VectorCosineOperator',
+  'sin' => '_VectorSineOperator',
+
+  'fallback' => undef;
+
+# Class constructor...
+sub new {
+  my($Class, @Values) = @_;
+
+  # Initialize object...
+  my $This = {};
+  bless $This, ref($Class) || $Class;
+  $This->_InitializeVector();
+
+  $This->_AddValues(@Values);
+
+  return $This;
+}
+
+# Initialize object data...
+#
+sub _InitializeVector {
+  my($This) = @_;
+
+  @{$This->{Values}} = ();
+}
+
+# Initialize class ...
+sub _InitializeClass {
+  #Class name...
+  $ClassName = __PACKAGE__;
+
+  # Print format for vector values...
+  $ValueFormat = "%g";
+}
+
+# Initialize vector values using:
+#    o List of values
+#    o Reference to an list of values
+#    o Another vector object
+#
+sub _AddValues {
+  my($This, @Values) = @_;
+
+  if (!@Values) {
+    return;
+  }
+
+  # Set vector values...
+  my($FirstValue, $TypeOfFirstValue);
+  $FirstValue = $Values[0];
+  $TypeOfFirstValue = ref $FirstValue;
+  if ($TypeOfFirstValue =~ /^(SCALAR|HASH|CODE|REF|GLOB)/) {
+    croak "Error: ${ClassName}->_AddValues: Trying to add values to vector object with a reference to unsupported value format...";
+  }
+
+  if (_IsVector($FirstValue)) {
+    # Initialize using Vector...
+    push @{$This->{Values}}, @{$FirstValue->{Values}};
+  }
+  elsif ($TypeOfFirstValue =~ /^ARRAY/) {
+    # Initialize using array refernce...
+    push @{$This->{Values}}, @{$FirstValue};
+  }
+  else {
+    # It's a list of values...
+    push @{$This->{Values}}, @Values;
+  }
+}
+
+# Add values to a vector using a vector, reference to an array or an array...
+sub AddValues {
+  my($This, @Values) = @_;
+
+  $This->_AddValues(@Values);
+
+  return $This;
+}
+
+# Copy vector...
+sub Copy {
+  my($This) = @_;
+  my($Vector);
+
+  # Copy vector values...
+  $Vector = (ref $This)->new(\@{$This->{Values}});
+
+  # Copy value format for stringification...
+  if (exists $This->{ValueFormat}) {
+    $Vector->{ValueFormat} = $This->{ValueFormat};
+  }
+  return $Vector;
+}
+
+# Get 3D vector length...
+sub GetLength {
+  my($This) = @_;
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->GetGetLength: Object must be a 3D vector...";
+  }
+  my($Length, $DotProduct);
+  $DotProduct = $This . $This;
+  $Length = sqrt $DotProduct;
+
+  return $Length;
+}
+
+# Length of a 3D vector by another name...
+sub GetMagnitude {
+  my($This) = @_;
+  return $This->GetLength();
+}
+
+# Normalize 3D vector...
+sub Normalize {
+  my($This) = @_;
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->GetGetLength: Object must be a 3D vector...";
+  }
+  my($Vector, $Length);
+  $Length = $This->GetLength();
+  $Vector = $This / $Length;
+
+  return $Vector;
+}
+
+# Is it a vector object?
+sub IsVector ($) {
+  my($Object) = @_;
+
+  return _IsVector($Object);
+}
+
+# Get size...
+sub GetSize {
+  my($This) = @_;
+
+  return scalar @{$This->{Values}};
+}
+
+# Get X value of a 3D vector...
+sub GetX {
+  my($This) = @_;
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->GetX: Object must be a 3D vector...";
+  }
+  return $This->_GetValue(0);
+}
+
+# Set X value of a 3D vector...
+sub SetX {
+  my($This, $Value) = @_;
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->SetX: Object must be a 3D vector...";
+  }
+  return $This->_SetValue(0, $Value);
+}
+
+# Get Y value of a 3D vector...
+sub GetY {
+  my($This) = @_;
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->GetY: Object must be a 3D vector...";
+  }
+  return $This->_GetValue(1);
+}
+
+# Set Y value of a 3D vector...
+sub SetY {
+  my($This, $Value) = @_;
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->SetY: Object must be a 3D vector...";
+  }
+  return $This->_SetValue(1, $Value);
+}
+
+# Get Z value of a 3D vector...
+sub GetZ {
+  my($This) = @_;
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->GetZ: Object must be a 3D vector...";
+  }
+  return $This->_GetValue(2);
+}
+
+# Set Z value of a 3D vector...
+sub SetZ {
+  my($This, $Value) = @_;
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->SetZ: Object must be a 3D vector...";
+  }
+  return $This->_SetValue(2, $Value);
+}
+
+# Set XYZ value of a 3D vector using:
+#    o List of values
+#    o Reference to an list of values
+#    o Another vector object
+#
+sub SetXYZ {
+  my($This, @Values) = @_;
+
+  if (!@Values) {
+    croak "Error: ${ClassName}->SetXYZ: No values specified...";
+  }
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->SetXYZ: Object must be a 3D vector...";
+  }
+
+  # Set vector values...
+  my($FirstValue, $TypeOfFirstValue);
+  $FirstValue = $Values[0];
+  $TypeOfFirstValue = ref $FirstValue;
+  if ($TypeOfFirstValue =~ /^(SCALAR|HASH|CODE|REF|GLOB)/) {
+    croak "Error: ${ClassName}->SetXYZ: A reference to unsupported value format specified...";
+  }
+
+  my($X, $Y, $Z);
+  if (_IsVector($FirstValue)) {
+    # SetXYZ using vector...
+    if ($FirstValue->GetSize() != 3) {
+      croak "Error: ${ClassName}->SetXYZ: Input object must be a 3D vector...";
+    }
+    ($X, $Y, $Z) = @{$FirstValue->{Values}};
+  }
+  elsif ($TypeOfFirstValue =~ /^ARRAY/) {
+    # SetXYZ using array reference...
+    if (@{$FirstValue} != 3) {
+      croak "Error: ${ClassName}->SetXYZ: Input array reference must correspond to an array with three values...";
+    }
+    ($X, $Y, $Z) = @{$FirstValue};
+  }
+  else {
+    # It's a list of values...
+    if (@Values != 3) {
+      croak "Error: ${ClassName}->SetXYZ: Input array must contain three values...";
+    }
+    ($X, $Y, $Z) = @Values;
+  }
+  $This->{Values}[0] = $X;
+  $This->{Values}[1] = $Y;
+  $This->{Values}[2] = $Z;
+
+  return $This;
+}
+
+# Get XYZ as an array or a reference to an array...
+#
+sub GetXYZ {
+  my($This) = @_;
+
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->GetXYZ: Object must be a 3D vector...";
+  }
+  return wantarray ? @{$This->{Values}} : \@{$This->{Values}};
+}
+
+# Get a specific value from vector with indicies starting from 0..
+sub GetValue {
+  my($This, $Index) = @_;
+
+  if ($Index < 0) {
+    croak "Error: ${ClassName}->GetValue: Index value must be a positive number...";
+  }
+  if ($Index >= $This->GetSize()) {
+    croak "Error: ${ClassName}->GetValue: Index value must be less than size of vector...";
+  }
+  return $This->_GetValue($Index);
+}
+
+# Get a vector value...
+sub _GetValue {
+  my($This, $Index) = @_;
+
+  return $This->{Values}[$Index];
+}
+
+# Set a specific value in vector with indicies starting from 0..
+sub SetValue {
+  my($This, $Index, $Value, $SkipCheck) = @_;
+
+  # Just set it...
+  if ($SkipCheck) {
+    return $This->_SetValue($Index, $Value);
+  }
+
+  # Check and set...
+  if ($Index < 0) {
+    croak "Error: ${ClassName}->SetValue: Index value must be a positive number...";
+  }
+  if ($Index >= $This->GetSize()) {
+    croak "Error: ${ClassName}->SetValue: Index vaue must be less than size of vector...";
+  }
+
+  return $This->_SetValue($Index, $Value);
+}
+
+# Set a vector value...
+sub _SetValue {
+  my($This, $Index, $Value) = @_;
+
+  $This->{Values}[$Index] = $Value;
+
+  return $This;
+}
+
+# Return vector values as an array or reference to an array...
+sub GetValues {
+  my($This) = @_;
+
+  return wantarray ? @{$This->{Values}} : \@{$This->{Values}};
+}
+
+# Get number of non-zero values in vector...
+#
+sub GetNumOfNonZeroValues {
+  my($This) = @_;
+  my($Count, $Index, $Size);
+
+  $Count = 0;
+  $Size = $This->GetSize();
+
+  for $Index (0 .. ($Size -1)) {
+    if ($This->{Values}[$Index] != 0) {
+      $Count++;
+    }
+  }
+  return $Count;
+}
+
+# Get percent of non-zero values...
+#
+sub GetPercentOfNonZeroValues {
+  my($This) = @_;
+
+  return $This->GetSize() ? (($This->GetNumOfNonZeroValues()/$This->GetSize())*100) : 0;
+}
+
+# Set value print format for an individual object or the whole class...
+sub SetValuePrintFormat ($;$) {
+  my($FirstParameter, $SecondParameter) = @_;
+
+  if ((@_ == 2) && (_IsVector($FirstParameter))) {
+    # Set value print format for the specific object...
+    my($This, $ValuePrintFormat) = ($FirstParameter, $SecondParameter);
+
+    $This->{ValueFormat} = $ValuePrintFormat;
+  }
+  else {
+    # Set value print format for the class...
+    my($ValuePrintFormat) = ($FirstParameter);
+
+    $ValueFormat = $ValuePrintFormat;
+  }
+}
+
+# Zero vector of specified size or size 3...
+sub ZeroVector (;$) {
+  my($Size) = @_;
+  my($Vector, @Values);
+
+  $Size = (defined $Size) ? $Size : 3;
+  @Values = ('0') x $Size;
+
+  $Vector = new Vector(\@Values);
+  return $Vector;
+}
+
+# Unit vector of specified size or size 3...
+sub UnitVector (;$) {
+  my($Size) = @_;
+  my($Vector, @Values);
+
+  $Size = (defined $Size) ? $Size : 3;
+  @Values = ('1') x $Size;
+
+  $Vector = new Vector(\@Values);
+  return $Vector;
+}
+
+# Unit X vector of size 3...
+sub UnitXVector () {
+  my($Vector);
+
+  $Vector = new Vector(1, 0, 0);
+  return $Vector;
+}
+
+# Unit Y vector of size 3...
+sub UnitYVector () {
+  my($Vector);
+
+  $Vector = new Vector(0, 1, 0);
+  return $Vector;
+}
+
+# Unit Z vector of size 3...
+sub UnitZVector () {
+  my($Vector);
+
+  $Vector = new Vector(0, 0, 1);
+  return $Vector;
+}
+
+#
+# Vector addition operator supports two addition modes:
+#   . Addition of two vectors by adding corresponding vector values
+#   . Addition of a scalar value to vector values ($Vector + 1)
+#
+# Caveats:
+#   . Addition of a vector to scalar is not allowed (1 + $Vector)
+#
+sub _VectorAdditionOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorAdditionOperator: Vector addition failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Do the addition. Order can be ignored: It's a commumative operation.
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] += $Other->{Values}[$Index];
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar addition...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] += $Other;
+    }
+  }
+  return $Vector;
+}
+
+#
+# Vector subtraction operator supports two subtraction modes:
+#   . Subtraction of two vectors by subtracting corresponding vector values
+#   . Subtraction of a scalar value from vector values ($Vector - 1)
+#
+# Caveats:
+#   . Subtraction of a vector from scalar is not allowed (1 - $Vector)
+#
+sub _VectorSubtractionOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorSubtractionOperator: Vector subtracttion failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Do the subtraction...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] -= $Other->{Values}[$Index];
+    }
+  }
+  else {
+    # Scalar subtraction...
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] -= $Other;
+    }
+  }
+  return $Vector;
+}
+
+#
+# Vector multiplication operator supports two multiplication modes:
+#   . Multiplication of two vectors by multiplying corresponding vector values
+#   . Multiplying vector values by a scalar ($Vector * 1)
+#
+# Caveats:
+#   . Multiplication of a scalar by a vector is not allowed (1 * $Vector)
+#
+sub _VectorMultiplicationOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorMultiplicationOperator: Vector addition failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Do the multiplication...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] *= $Other->{Values}[$Index];
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar multiplication...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] *= $Other;
+    }
+  }
+  return $Vector;
+}
+
+#
+# Vector division operator supports two division modes:
+#   . Division of two vectors by dividing corresponding vector values
+#   . Dividing vector values by a scalar ($Vector / 2)
+#
+# Caveats:
+#   . Division of a scalar by a vector is not allowed (1 / $Vector)
+#
+sub _VectorDivisionOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorDivisionOperator: Vector division failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Do the division...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] /= $Other->{Values}[$Index];
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar divison...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] /=  $Other;
+    }
+  }
+  return $Vector;
+}
+
+#
+# Vector exponentiation operator supports two exponentiation modes:
+#   . Exponentiation of two vectors by exponentiation of  corresponding vector values
+#   . Exponentiation of vector values by a scalar ($Vector ** 2)
+#
+# Caveats:
+#   . Exponent of scalar by a vector is not allowed (2 ** $Vector)
+#
+sub _VectorExponentiationOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorExponentiationOperator: Vector exponentiation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Do the exponentiation...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] **= $Other->{Values}[$Index];
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar exponentiation...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] **=  $Other;
+    }
+  }
+  return $Vector;
+}
+
+#
+# Vector modulus operator supports two modulus modes:
+#   . Modulus of two vectors by taking modulus between corresponding vector values
+#   . Modulus of vector values by a scalar ($Vector % 2)
+#
+# Caveats:
+#   . Modulus of scalar by a vector is not allowed (2 % $Vector)
+#
+sub _VectorModulusOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorModulusOperator: Vector exponentiation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Take the modulus...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] %= $Other->{Values}[$Index];
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar modulus...
+    for $Index (0 .. ($ThisSize -1)) {
+      $Vector->{Values}[$Index] %=  $Other;
+    }
+  }
+  return $Vector;
+}
+
+#
+# Vector dot product operator supports two modes:
+#   . Dot product of two 3D vectors
+#   . Concatenation of a vector and a scalar
+#
+sub _VectorDotProductOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorDotProductOperator: Vector dot product failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  if ($OtherIsVector) {
+    # Calculate dot product of two 3D vectors...
+    my($DotProduct);
+    if ($This->GetSize() != 3) {
+      croak "Error: ${ClassName}->${ErrorMsg}: Both vectors must be 3D vectors...";
+    }
+    $DotProduct = $This->GetX() * $Other->GetX + $This->GetY() * $Other->GetY() + $This->GetZ * $Other->GetZ();
+    return $DotProduct;
+  }
+  else {
+    # Do a string concatenation and return the string...
+    if ($OrderFlipped) {
+      return $Other . $This->StringifyVector();
+    }
+    else {
+      return $This->StringifyVector() . $Other;
+    }
+  }
+}
+
+#
+# Vector cross product operator genrates a new vector which is the cross
+# product of two 3D vectors.
+#
+# For two vectors, V1 (X1, Y1, Z1) and V2 (X2, Y2, Z2), cross product
+# V1 x V2 corresponds: (Y1.Z2 - Z1.Y2), (Z1.X2 - X1.Z2), (X1.Y2 - Y1.X2)
+#
+sub _VectorCrossProductOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorCrossProductOperator: Vector cross product failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  if (!$OtherIsVector) {
+    croak "Error: ${ClassName}->${ErrorMsg}: Both object must be vectors...";
+  }
+
+  # Calculate cross product of two 3D vectors...
+  if ($This->GetSize() != 3) {
+    croak "Error: ${ClassName}->${ErrorMsg}: Both vectors must be 3D vectors...";
+  }
+  my($Vector, $X, $Y, $Z);
+  $X = $This->GetY() * $Other->GetZ() - $This->GetZ() * $Other->GetY();
+  $Y = $This->GetZ() * $Other->GetX() - $This->GetX() * $Other->GetZ();
+  $Z = $This->GetX() * $Other->GetY() - $This->GetY() * $Other->GetX();
+
+  $Vector = (ref $This)->new($X, $Y, $Z);
+
+  return $Vector;
+}
+
+#
+# Vector booelan operator checks whether a vector contains at least one non-zero
+# value...
+#
+sub _VectorBooleanOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorBooleanOperator: Vector boolean operation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  my($Size, $Index);
+  $Size = $This->GetSize();
+
+  for $Index (0 .. ($Size - 1)) {
+    if ($This->{Values}[$Index] != 0) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+#
+# Vector not booelan operator checks whether all values of a vector are zero.
+#
+sub _VectorNotBooleanOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorNotBooleanOperator: Vector not boolean operation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  my($Size, $Index);
+  $Size = $This->GetSize();
+
+  for $Index (0 .. ($Size - 1)) {
+    if ($This->{Values}[$Index] != 0) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+#
+# Vector equal operator supports two modes:
+#   . Comparion of corresponding values in two vectors
+#   . Comparing vectors values to a scalar ($Vector == 2)
+#
+# Caveats:
+#   . Comparison of a scalar to vector values is not allowed (2 == $Vector)
+#
+sub _VectorEqualOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg, $CheckVectorSizes);
+
+  $ErrorMsg = "_VectorEqualOperator: Vector equal comparison failed";
+  $CheckVectorSizes = 0;
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckVectorSizes);
+
+  # Do the comparison...
+  my($ThisSize, $Index);
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    my($OtherSize) = $Other->GetSize();
+    if ($ThisSize != $OtherSize) {
+      return 0;
+    }
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] != $Other->{Values}[$Index]) {
+	return 0;
+      }
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar comparison...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] != $Other) {
+	return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+#
+# Vector not equal operator supports two modes:
+#   . Comparion of corresponding values in two vectors
+#   . Comparing vectors values to a scalar ($Vector != 2)
+#
+# Caveats:
+#   . Comparison of a scalar to vector values is not allowed (2 != $Vector2)
+#
+sub _VectorNotEqualOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg, $CheckVectorSizes);
+
+  $ErrorMsg = "_VectorNotEqualOperator: Vector not equal comparison failed";
+  $CheckVectorSizes = 0;
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckVectorSizes);
+
+  # Do the comparison...
+  my($ThisSize, $Index);
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    my($OtherSize) = $Other->GetSize();
+    if ($ThisSize != $OtherSize) {
+      return 1;
+    }
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] == $Other->{Values}[$Index]) {
+	return 0;
+      }
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar comparison...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] == $Other) {
+	return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+#
+# Vector less than operator supports two modes:
+#   . Comparion of corresponding values in two vectors
+#   . Comparing vectors values to a scalar ($Vector < 2)
+#
+# Caveats:
+#   . Comparison of a scalar to vector values is not allowed (2 < $Vector2)
+#
+sub _VectorLessThanOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorLessThanOperator: Vector less than comparison failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Do the comparison...
+  my($ThisSize, $Index);
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] >= $Other->{Values}[$Index]) {
+	return 0;
+      }
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar comparison...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] >= $Other) {
+	return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+#
+# Vector less than equla operator supports two modes:
+#   . Comparion of corresponding values in two vectors
+#   . Comparing vectors values to a scalar ($Vector <= 2)
+#
+# Caveats:
+#   . Comparison of a scalar to vector values is not allowed (2 <= $Vector2)
+#
+sub _VectorLessThanEqualOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorLessThanEqualOperator: Vector less than equal comparison failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Do the comparison...
+  my($ThisSize, $Index);
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] > $Other->{Values}[$Index]) {
+	return 0;
+      }
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar comparison...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] > $Other) {
+	return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+#
+# Vector greatar than operator supports two modes:
+#   . Comparion of corresponding values in two vectors
+#   . Comparing vectors values to a scalar ($Vector > 2)
+#
+# Caveats:
+#   . Comparison of a scalar to vector values is not allowed (2 > $Vector2)
+#
+sub _VectorGreatarThanOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorGreatarThanOperator: Vector greatar than comparison failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Do the comparison...
+  my($ThisSize, $Index);
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] <= $Other->{Values}[$Index]) {
+	return 0;
+      }
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar comparison...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] <= $Other) {
+	return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+#
+# Vector greatar than equal operator supports two modes:
+#   . Comparion of corresponding values in two vectors
+#   . Comparing vectors values to a scalar ($Vector >= 2)
+#
+# Caveats:
+#   . Comparison of a scalar to vector values is not allowed (2 <= $Vector2)
+#
+sub _VectorGreatarThanEqualOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorGreatarThanEqualOperator: Vector greatar than equal comparison failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Do the comparison...
+  my($ThisSize, $Index);
+  $ThisSize = $This->GetSize();
+
+  if ($OtherIsVector) {
+    # $OrderFlipped is set to false for two vectors...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] < $Other->{Values}[$Index]) {
+	return 0;
+      }
+    }
+  }
+  else {
+    if ($OrderFlipped) {
+      croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
+    }
+    # Scalar comparison...
+    for $Index (0 .. ($ThisSize -1)) {
+      if ($This->{Values}[$Index] < $Other) {
+	return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+#
+# Vector negative value operator returns a vector with values corresponding to
+# negative values of a vector
+#
+sub _VectorNegativeValueOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorNegativeValueOperator: Vector negative value operation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Take the negative value...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  for $Index (0 .. ($ThisSize -1)) {
+    $Vector->{Values}[$Index] = - $This->{Values}[$Index];
+  }
+  return $Vector;
+}
+
+#
+# Vector absolute value operator returns a vector with values corresponding to
+# absolute values of a vector
+#
+sub _VectorAbsoluteValueOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorAbsoluteValueOperator: Vector absolute value operation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Take the absolute value...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  for $Index (0 .. ($ThisSize -1)) {
+    $Vector->{Values}[$Index] = abs $This->{Values}[$Index];
+  }
+  return $Vector;
+}
+
+#
+# Vector exp natural base operator returns a vector with values corresponding to
+# e raised to the power of values in a vector
+#
+sub _VectorExpNaturalBaseOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorExpNaturalBaseOperator: Vector exp operation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Take the absolute value...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  for $Index (0 .. ($ThisSize -1)) {
+    $Vector->{Values}[$Index] = exp $This->{Values}[$Index];
+  }
+  return $Vector;
+}
+
+#
+# Vector log natural base operator returns a vector with values corresponding to
+# log of values in a vector
+#
+sub _VectorLogNaturalBaseOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorLogNaturalBaseOperator: Vector log operation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Take the absolute value...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  for $Index (0 .. ($ThisSize -1)) {
+    $Vector->{Values}[$Index] = log $This->{Values}[$Index];
+  }
+  return $Vector;
+}
+
+#
+# Vector cosine operator returns a vector with values corresponding to cosine of values
+# in a vector. Input vector values are assumed to be in radians.
+#
+sub _VectorCosineOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorCosineOperator: Vector cos operation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Take the absolute value...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  for $Index (0 .. ($ThisSize -1)) {
+    $Vector->{Values}[$Index] = cos $This->{Values}[$Index];
+  }
+  return $Vector;
+}
+
+#
+# Vector sine operator returns a vector with values corresponding to sine of values
+# in a vector. Input vector values are assumed to be in radians.
+#
+sub _VectorSineOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorSineOperator: Vector sin operation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Take the absolute value...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  for $Index (0 .. ($ThisSize -1)) {
+    $Vector->{Values}[$Index] = sin $This->{Values}[$Index];
+  }
+  return $Vector;
+}
+
+#
+# Vector square root  returns a vector with values corresponding to sqrt of values
+# in a vector.
+#
+sub _VectorSquareRootOperator {
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
+
+  $ErrorMsg = "_VectorSquareRootOperator: Vector sqrt operation failed";
+  ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
+
+  # Take the absolute value...
+  my($Vector, $ThisSize, $Index);
+  $Vector = $This->Copy();
+  $ThisSize = $This->GetSize();
+
+  for $Index (0 .. ($ThisSize -1)) {
+    $Vector->{Values}[$Index] = sqrt $This->{Values}[$Index];
+  }
+  return $Vector;
+}
+
+# Turn vector into array for @{$Vector} operation...
+sub _VectorToArrayOperator {
+  my($This) = @_;
+
+  return \@{$This->{Values}};
+}
+
+# Turn vector into number for $#Vector operation: It's the size of vector...
+sub _NumifyVector {
+  my($This) = @_;
+
+  return $This->GetSize();
+}
+
+# Process parameters passed to overloaded operators...
+#
+# For uninary operators, $SecondParameter is not defined.
+sub _ProcessOverloadedOperatorParameters {
+  my($ErrorMsg, $FirstParameter, $SecondParameter, $ParametersOrderStatus, $CheckVectorSizesStatus) = @_;
+  my($This, $Other, $OrderFlipped, $OtherIsVector, $CheckVectorSizes);
+
+  ($This, $Other) =  ($FirstParameter, $SecondParameter);
+  $OrderFlipped = (defined($ParametersOrderStatus) && $ParametersOrderStatus) ? 1 : 0;
+  $CheckVectorSizes = (defined $CheckVectorSizesStatus) ? $CheckVectorSizesStatus : 1;
+
+  _ValidateVector($ErrorMsg, $This);
+
+  $OtherIsVector = 0;
+  if (defined($Other) && (ref $Other)) {
+    # Make sure $Other is a vector...
+    _ValidateVector($ErrorMsg, $Other);
+    if ($CheckVectorSizes) {
+      _ValidateVectorSizesAreEqual($ErrorMsg, $This, $Other);
+    }
+    $OtherIsVector = 1;
+  }
+  return ($This, $Other, $OrderFlipped, $OtherIsVector);
+}
+
+# Is it a vector object?
+sub _IsVector {
+  my($Object) = @_;
+
+  return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0;
+}
+
+# Make sure it's a vector reference...
+sub _ValidateVector {
+  my($ErrorMsg, $Vector) = @_;
+
+  if (!_IsVector($Vector)) {
+    croak "Error: ${ClassName}->${ErrorMsg}: Object must be a vector...";
+  }
+}
+
+# Make sure size of the two vectors contain the same number of values...
+sub _ValidateVectorSizesAreEqual {
+  my($ErrorMsg, $Vector1, $Vector2) = @_;
+
+  if ($Vector1->GetSize() != $Vector2->GetSize()) {
+    croak "Error: ${ClassName}->${ErrorMsg}: Size of the vectors must be same...";
+  }
+}
+
+# Return a string containing vector values...
+sub StringifyVector {
+  my($This) = @_;
+  my($VectorString, $FormatString, $PrintFormat, $Size, @ValuesFormat);
+
+  $PrintFormat = (exists $This->{ValueFormat}) ? $This->{ValueFormat} : $ValueFormat;
+
+  @ValuesFormat = ($PrintFormat) x scalar @{$This->{Values}};
+  $FormatString = join ' ', @ValuesFormat;
+
+  $Size = $This->GetSize();
+
+  $VectorString = sprintf "<Size: $Size; Values: [ $FormatString ] >", @{$This->{Values}};
+
+  return $VectorString;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Vector
+
+=head1 SYNOPSIS
+
+use Vector;
+
+use Vector qw(:all);
+
+=head1 DESCRIPTION
+
+B<Vector> class provides the following methods:
+
+new, AddValues, Copy, GetLength, GetMagnitude, GetNumOfNonZeroValues,
+GetPercentOfNonZeroValues, GetSize, GetValue, GetValues, GetX, GetXYZ, GetY,
+GetZ, IsVector, Normalize, SetValue, SetValuePrintFormat,
+SetX, SetXYZ, SetY, SetZ, StringifyVector, IsVector
+
+The following functions are available:
+
+IsVector, SetValuePrintFormat UnitXVector, UnitYVector, UnitZVector, UnitVector,
+ZeroVector
+
+The following operators are overloaded:
+
+    "" 0+ bool
+    @{}
+    + - * / %
+    x .
+    == != < <= > >=
+    neg
+    abs exp log sqrt cos sin
+
+=head2 FUNCTIONS
+
+=over 4
+
+=item B<new>
+
+    $NewVector = new Vector();
+    $NewVector = new Vector(@Values);
+    $NewVector = new Vector(\@Values);
+    $NewVector = new Vector($AnotherVector);
+
+Creates a new B<Vector> object containing I<Values> and returns B<NewVector> object.
+In case no I<Values> are specified, an empty B<Vector> is created.
+
+=item B<AddValues>
+
+    $Vector->AddValues(@Values);
+    $Vector->AddValues(\@Values);
+    $Vector->AddValues($AnotherVector);
+
+Adds values to I<Vector> using an array, reference to an array or another vector and returns
+I<Vector>.
+
+=item B<Copy>
+
+    $NewVector = $Vector->Copy();
+
+Creates a copy of I<Vector> and returns I<NewVector>.
+
+=item B<GetLength>
+
+    $Length = $Vector->GetLength();
+
+Returns I<Lengh> of a 3D I<Vector> corresponding to its dot product.
+
+=item B<GetMagnitude>
+
+    $Length = $Vector->GetMagnitude();
+
+Returns I<Lengh> of a 3D I<Vector> corresponding to its dot product.
+
+=item B<GetNumOfNonZeroValues>
+
+    $Value = $Vector->GetNumOfNonZeroValues();
+
+Returns number of non-zero values in I<Vector>.
+
+=item B<GetPercentOfNonZeroValues>
+
+    $Value = $Vector->GetPercentOfNonZeroValues();
+
+Returns percent of non-zero values in I<Vector>.
+
+=item B<GetSize>
+
+    $Size = $Vector->GetSize();
+
+Returns size of a I<Vector> corresponding to number of its values.
+
+=item B<GetValue>
+
+    $Value = $Vector->GetValues($Index);
+
+Returns vector B<Value> specified using I<Index> starting at 0.
+
+=item B<GetValues>
+
+    @Values = $Vector->GetValues();
+    $ValuesRef = $Vector->GetValues();
+
+Returns an array or a reference to an array containing all I<Vector> values.
+
+=item B<GetX>
+
+    $X = $Vector->GetX();
+
+Returns B<X> value of a 3D I<Vector>
+
+=item B<GetXYZ>
+
+    @XYZValues = $Vector->GetXYZ();
+    $XYZValuesRef = $Vector->GetXYZ();
+
+Returns B<XYZ> values of a 3D I<Vector> as an array or a reference to an array
+containing the values.
+
+=item B<GetY>
+
+    $Y = $Vector->GetY();
+
+Returns B<Y> value of a 3D I<Vector>.
+
+=item B<GetZ>
+
+    $Z = $Vector->GetZ();
+
+Returns B<Z> value of a 3D I<Vector>.
+
+=item B<IsVector>
+
+    $Status = Vector::IsVector($Object);
+
+Returns 1 or 0 based on whether I<Object> is a B<Vector> object.
+
+=item B<Normalize>
+
+    $Vector->Normalize();
+
+Normalizes a 3D I<Vector> by dividing its values by the length and returns I<Vector>.
+
+=item B<SetValue>
+
+    $Vector->SetValue($Index, $Value);
+
+Sets a I<Vector> value specified by I<Index> to I<Value> and returns I<Vector>.
+
+=item B<SetValuePrintFormat>
+
+    $Vector->SetValuePrintFormat($ValuePrintFormat);
+    Vector::SetValuePrintFormat($ValuePrintFormat);
+
+Sets format for printing vector values for a specified I<Vector> or the whole class. Default
+format: I<%g>.
+
+=item B<SetX>
+
+    $Vector->SetX($Value);
+
+Sets B<X> value of a 3D vector to I<Value> and returns I<Vector>.
+
+=item B<SetXYZ>
+
+    $Vector->SetXYZ(@Values);
+    $Vector->SetXYZ(\@Values);
+    $Vector->SetXYZ($AnotherVector);
+
+Sets B<XYZ> values of a 3D vector and returns I<Vector>.
+
+=item B<SetY>
+
+    $Vector->SetY($Value);
+
+Sets B<Y> value of a 3D vector to I<Value> and returns I<Vector>.
+
+=item B<SetZ>
+
+    $Vector->SetZ($Value);
+
+Sets B<Z> value of a 3D vector to I<Value> and returns I<Vector>.
+
+=item B<StringifyVector>
+
+    $String = $Vector->StringifyVector();
+
+Returns a string containing information about I<Vector> object.
+
+=item B<UnitVector>
+
+    $UnitVector = UnitVector([$Size]);
+    $UnitVector = Vector::UnitVector([$Size]);
+
+Returns a B<UnitVector> of I<Size>. Default size: I<3>.
+
+=item B<UnitXVector>
+
+    $UnitXVector = UnitXVector();
+
+Returns a 3D B<UnitXVector>.
+
+=item B<UnitYVector>
+
+    $UnitYVector = UnitYVector();
+
+Returns a 3D B<UnitYVector>.
+
+=item B<UnitZVector>
+
+    $UnitZVector = UnitZVector();
+
+Returns a 3D B<UnitZVector>.
+
+=item B<ZeroVector>
+
+    $UnitVector = ZeroVector([$Size]);
+    $UnitVector = Vector::ZeroVector([$Size]);
+
+Returns a B<ZeroVector> of I<Size>. Default size: I<3>.
+
+=back
+
+=head1 AUTHOR
+
+Manish Sud <msud@san.rr.com>
+
+=head1 SEE ALSO
+
+BitVector.pm
+
+=head1 COPYRIGHT
+
+Copyright (C) 2015 Manish Sud. All rights reserved.
+
+This file is part of MayaChemTools.
+
+MayaChemTools is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation; either version 3 of the License, or (at your option)
+any later version.
+
+=cut