comparison lib/Vector.pm @ 0:4816e4a8ae95 draft default tip

Uploaded
author deepakjadmin
date Wed, 20 Jan 2016 09:23:18 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4816e4a8ae95
1 package Vector;
2 #
3 # $RCSfile: Vector.pm,v $
4 # $Date: 2015/02/28 20:47:30 $
5 # $Revision: 1.34 $
6 #
7 # Author: Manish Sud <msud@san.rr.com>
8 #
9 # Copyright (C) 2015 Manish Sud. All rights reserved.
10 #
11 # This file is part of MayaChemTools.
12 #
13 # MayaChemTools is free software; you can redistribute it and/or modify it under
14 # the terms of the GNU Lesser General Public License as published by the Free
15 # Software Foundation; either version 3 of the License, or (at your option) any
16 # later version.
17 #
18 # MayaChemTools is distributed in the hope that it will be useful, but without
19 # any warranty; without even the implied warranty of merchantability of fitness
20 # for a particular purpose. See the GNU Lesser General Public License for more
21 # details.
22 #
23 # You should have received a copy of the GNU Lesser General Public License
24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
26 # Boston, MA, 02111-1307, USA.
27 #
28
29 use strict;
30 use Carp;
31 use Exporter;
32 use Scalar::Util ();
33 use StatisticsUtil ();
34
35 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
36
37 @ISA = qw(Exporter);
38 @EXPORT = qw(IsVector UnitXVector UnitYVector UnitZVector UnitVector ZeroVector);
39 @EXPORT_OK = qw(SetValuePrintFormat);
40
41 %EXPORT_TAGS = (
42 all => [@EXPORT, @EXPORT_OK]
43 );
44
45 # Setup class variables...
46 my($ClassName, $ValueFormat);
47 _InitializeClass();
48
49 #
50 # Using the following explicity overloaded operators, Perl automatically generates methods
51 # for operations with no explicitly defined methods. Autogenerated methods are possible for
52 # these operators:
53 #
54 # o Arithmetic operators: += -= *= /= **= %= ++ -- x= .=
55 # o Increment and decrement: ++ --
56 #
57 # 'fallback' is set to 'false' to raise exception for all other operators.
58 #
59 use overload '""' => 'StringifyVector',
60
61 '0+' => '_NumifyVector',
62
63 '@{}' => '_VectorToArrayOperator',
64
65 '+' => '_VectorAdditionOperator',
66 '-' => '_VectorSubtractionOperator',
67 '*' => '_VectorMultiplicationOperator',
68 '/' => '_VectorDivisionOperator',
69 '**' => '_VectorExponentiationOperator',
70 '%' => '_VectorModulusOperator',
71
72 'x' => '_VectorCrossProductOperator',
73 '.' => '_VectorDotProductOperator',
74
75 'bool' => '_VectorBooleanOperator',
76 '!' => '_VectorNotBooleanOperator',
77
78 '==' => '_VectorEqualOperator',
79 '!=' => '_VectorNotEqualOperator',
80 '<' => '_VectorLessThanOperator',
81 '<=' => '_VectorLessThanEqualOperator',
82 '>' => '_VectorGreatarThanOperator',
83 '>=' => '_VectorGreatarThanEqualOperator',
84
85 'neg' => '_VectorNegativeValueOperator',
86
87 'abs' => '_VectorAbsoluteValueOperator',
88 'exp' => '_VectorExpNaturalBaseOperator',
89 'log' => '_VectorLogNaturalBaseOperator',
90 'sqrt' => '_VectorSquareRootOperator',
91 'cos' => '_VectorCosineOperator',
92 'sin' => '_VectorSineOperator',
93
94 'fallback' => undef;
95
96 # Class constructor...
97 sub new {
98 my($Class, @Values) = @_;
99
100 # Initialize object...
101 my $This = {};
102 bless $This, ref($Class) || $Class;
103 $This->_InitializeVector();
104
105 $This->_AddValues(@Values);
106
107 return $This;
108 }
109
110 # Initialize object data...
111 #
112 sub _InitializeVector {
113 my($This) = @_;
114
115 @{$This->{Values}} = ();
116 }
117
118 # Initialize class ...
119 sub _InitializeClass {
120 #Class name...
121 $ClassName = __PACKAGE__;
122
123 # Print format for vector values...
124 $ValueFormat = "%g";
125 }
126
127 # Initialize vector values using:
128 # o List of values
129 # o Reference to an list of values
130 # o Another vector object
131 #
132 sub _AddValues {
133 my($This, @Values) = @_;
134
135 if (!@Values) {
136 return;
137 }
138
139 # Set vector values...
140 my($FirstValue, $TypeOfFirstValue);
141 $FirstValue = $Values[0];
142 $TypeOfFirstValue = ref $FirstValue;
143 if ($TypeOfFirstValue =~ /^(SCALAR|HASH|CODE|REF|GLOB)/) {
144 croak "Error: ${ClassName}->_AddValues: Trying to add values to vector object with a reference to unsupported value format...";
145 }
146
147 if (_IsVector($FirstValue)) {
148 # Initialize using Vector...
149 push @{$This->{Values}}, @{$FirstValue->{Values}};
150 }
151 elsif ($TypeOfFirstValue =~ /^ARRAY/) {
152 # Initialize using array refernce...
153 push @{$This->{Values}}, @{$FirstValue};
154 }
155 else {
156 # It's a list of values...
157 push @{$This->{Values}}, @Values;
158 }
159 }
160
161 # Add values to a vector using a vector, reference to an array or an array...
162 sub AddValues {
163 my($This, @Values) = @_;
164
165 $This->_AddValues(@Values);
166
167 return $This;
168 }
169
170 # Copy vector...
171 sub Copy {
172 my($This) = @_;
173 my($Vector);
174
175 # Copy vector values...
176 $Vector = (ref $This)->new(\@{$This->{Values}});
177
178 # Copy value format for stringification...
179 if (exists $This->{ValueFormat}) {
180 $Vector->{ValueFormat} = $This->{ValueFormat};
181 }
182 return $Vector;
183 }
184
185 # Get 3D vector length...
186 sub GetLength {
187 my($This) = @_;
188
189 if ($This->GetSize() != 3) {
190 croak "Error: ${ClassName}->GetGetLength: Object must be a 3D vector...";
191 }
192 my($Length, $DotProduct);
193 $DotProduct = $This . $This;
194 $Length = sqrt $DotProduct;
195
196 return $Length;
197 }
198
199 # Length of a 3D vector by another name...
200 sub GetMagnitude {
201 my($This) = @_;
202 return $This->GetLength();
203 }
204
205 # Normalize 3D vector...
206 sub Normalize {
207 my($This) = @_;
208
209 if ($This->GetSize() != 3) {
210 croak "Error: ${ClassName}->GetGetLength: Object must be a 3D vector...";
211 }
212 my($Vector, $Length);
213 $Length = $This->GetLength();
214 $Vector = $This / $Length;
215
216 return $Vector;
217 }
218
219 # Is it a vector object?
220 sub IsVector ($) {
221 my($Object) = @_;
222
223 return _IsVector($Object);
224 }
225
226 # Get size...
227 sub GetSize {
228 my($This) = @_;
229
230 return scalar @{$This->{Values}};
231 }
232
233 # Get X value of a 3D vector...
234 sub GetX {
235 my($This) = @_;
236
237 if ($This->GetSize() != 3) {
238 croak "Error: ${ClassName}->GetX: Object must be a 3D vector...";
239 }
240 return $This->_GetValue(0);
241 }
242
243 # Set X value of a 3D vector...
244 sub SetX {
245 my($This, $Value) = @_;
246
247 if ($This->GetSize() != 3) {
248 croak "Error: ${ClassName}->SetX: Object must be a 3D vector...";
249 }
250 return $This->_SetValue(0, $Value);
251 }
252
253 # Get Y value of a 3D vector...
254 sub GetY {
255 my($This) = @_;
256
257 if ($This->GetSize() != 3) {
258 croak "Error: ${ClassName}->GetY: Object must be a 3D vector...";
259 }
260 return $This->_GetValue(1);
261 }
262
263 # Set Y value of a 3D vector...
264 sub SetY {
265 my($This, $Value) = @_;
266
267 if ($This->GetSize() != 3) {
268 croak "Error: ${ClassName}->SetY: Object must be a 3D vector...";
269 }
270 return $This->_SetValue(1, $Value);
271 }
272
273 # Get Z value of a 3D vector...
274 sub GetZ {
275 my($This) = @_;
276
277 if ($This->GetSize() != 3) {
278 croak "Error: ${ClassName}->GetZ: Object must be a 3D vector...";
279 }
280 return $This->_GetValue(2);
281 }
282
283 # Set Z value of a 3D vector...
284 sub SetZ {
285 my($This, $Value) = @_;
286
287 if ($This->GetSize() != 3) {
288 croak "Error: ${ClassName}->SetZ: Object must be a 3D vector...";
289 }
290 return $This->_SetValue(2, $Value);
291 }
292
293 # Set XYZ value of a 3D vector using:
294 # o List of values
295 # o Reference to an list of values
296 # o Another vector object
297 #
298 sub SetXYZ {
299 my($This, @Values) = @_;
300
301 if (!@Values) {
302 croak "Error: ${ClassName}->SetXYZ: No values specified...";
303 }
304
305 if ($This->GetSize() != 3) {
306 croak "Error: ${ClassName}->SetXYZ: Object must be a 3D vector...";
307 }
308
309 # Set vector values...
310 my($FirstValue, $TypeOfFirstValue);
311 $FirstValue = $Values[0];
312 $TypeOfFirstValue = ref $FirstValue;
313 if ($TypeOfFirstValue =~ /^(SCALAR|HASH|CODE|REF|GLOB)/) {
314 croak "Error: ${ClassName}->SetXYZ: A reference to unsupported value format specified...";
315 }
316
317 my($X, $Y, $Z);
318 if (_IsVector($FirstValue)) {
319 # SetXYZ using vector...
320 if ($FirstValue->GetSize() != 3) {
321 croak "Error: ${ClassName}->SetXYZ: Input object must be a 3D vector...";
322 }
323 ($X, $Y, $Z) = @{$FirstValue->{Values}};
324 }
325 elsif ($TypeOfFirstValue =~ /^ARRAY/) {
326 # SetXYZ using array reference...
327 if (@{$FirstValue} != 3) {
328 croak "Error: ${ClassName}->SetXYZ: Input array reference must correspond to an array with three values...";
329 }
330 ($X, $Y, $Z) = @{$FirstValue};
331 }
332 else {
333 # It's a list of values...
334 if (@Values != 3) {
335 croak "Error: ${ClassName}->SetXYZ: Input array must contain three values...";
336 }
337 ($X, $Y, $Z) = @Values;
338 }
339 $This->{Values}[0] = $X;
340 $This->{Values}[1] = $Y;
341 $This->{Values}[2] = $Z;
342
343 return $This;
344 }
345
346 # Get XYZ as an array or a reference to an array...
347 #
348 sub GetXYZ {
349 my($This) = @_;
350
351 if ($This->GetSize() != 3) {
352 croak "Error: ${ClassName}->GetXYZ: Object must be a 3D vector...";
353 }
354 return wantarray ? @{$This->{Values}} : \@{$This->{Values}};
355 }
356
357 # Get a specific value from vector with indicies starting from 0..
358 sub GetValue {
359 my($This, $Index) = @_;
360
361 if ($Index < 0) {
362 croak "Error: ${ClassName}->GetValue: Index value must be a positive number...";
363 }
364 if ($Index >= $This->GetSize()) {
365 croak "Error: ${ClassName}->GetValue: Index value must be less than size of vector...";
366 }
367 return $This->_GetValue($Index);
368 }
369
370 # Get a vector value...
371 sub _GetValue {
372 my($This, $Index) = @_;
373
374 return $This->{Values}[$Index];
375 }
376
377 # Set a specific value in vector with indicies starting from 0..
378 sub SetValue {
379 my($This, $Index, $Value, $SkipCheck) = @_;
380
381 # Just set it...
382 if ($SkipCheck) {
383 return $This->_SetValue($Index, $Value);
384 }
385
386 # Check and set...
387 if ($Index < 0) {
388 croak "Error: ${ClassName}->SetValue: Index value must be a positive number...";
389 }
390 if ($Index >= $This->GetSize()) {
391 croak "Error: ${ClassName}->SetValue: Index vaue must be less than size of vector...";
392 }
393
394 return $This->_SetValue($Index, $Value);
395 }
396
397 # Set a vector value...
398 sub _SetValue {
399 my($This, $Index, $Value) = @_;
400
401 $This->{Values}[$Index] = $Value;
402
403 return $This;
404 }
405
406 # Return vector values as an array or reference to an array...
407 sub GetValues {
408 my($This) = @_;
409
410 return wantarray ? @{$This->{Values}} : \@{$This->{Values}};
411 }
412
413 # Get number of non-zero values in vector...
414 #
415 sub GetNumOfNonZeroValues {
416 my($This) = @_;
417 my($Count, $Index, $Size);
418
419 $Count = 0;
420 $Size = $This->GetSize();
421
422 for $Index (0 .. ($Size -1)) {
423 if ($This->{Values}[$Index] != 0) {
424 $Count++;
425 }
426 }
427 return $Count;
428 }
429
430 # Get percent of non-zero values...
431 #
432 sub GetPercentOfNonZeroValues {
433 my($This) = @_;
434
435 return $This->GetSize() ? (($This->GetNumOfNonZeroValues()/$This->GetSize())*100) : 0;
436 }
437
438 # Set value print format for an individual object or the whole class...
439 sub SetValuePrintFormat ($;$) {
440 my($FirstParameter, $SecondParameter) = @_;
441
442 if ((@_ == 2) && (_IsVector($FirstParameter))) {
443 # Set value print format for the specific object...
444 my($This, $ValuePrintFormat) = ($FirstParameter, $SecondParameter);
445
446 $This->{ValueFormat} = $ValuePrintFormat;
447 }
448 else {
449 # Set value print format for the class...
450 my($ValuePrintFormat) = ($FirstParameter);
451
452 $ValueFormat = $ValuePrintFormat;
453 }
454 }
455
456 # Zero vector of specified size or size 3...
457 sub ZeroVector (;$) {
458 my($Size) = @_;
459 my($Vector, @Values);
460
461 $Size = (defined $Size) ? $Size : 3;
462 @Values = ('0') x $Size;
463
464 $Vector = new Vector(\@Values);
465 return $Vector;
466 }
467
468 # Unit vector of specified size or size 3...
469 sub UnitVector (;$) {
470 my($Size) = @_;
471 my($Vector, @Values);
472
473 $Size = (defined $Size) ? $Size : 3;
474 @Values = ('1') x $Size;
475
476 $Vector = new Vector(\@Values);
477 return $Vector;
478 }
479
480 # Unit X vector of size 3...
481 sub UnitXVector () {
482 my($Vector);
483
484 $Vector = new Vector(1, 0, 0);
485 return $Vector;
486 }
487
488 # Unit Y vector of size 3...
489 sub UnitYVector () {
490 my($Vector);
491
492 $Vector = new Vector(0, 1, 0);
493 return $Vector;
494 }
495
496 # Unit Z vector of size 3...
497 sub UnitZVector () {
498 my($Vector);
499
500 $Vector = new Vector(0, 0, 1);
501 return $Vector;
502 }
503
504 #
505 # Vector addition operator supports two addition modes:
506 # . Addition of two vectors by adding corresponding vector values
507 # . Addition of a scalar value to vector values ($Vector + 1)
508 #
509 # Caveats:
510 # . Addition of a vector to scalar is not allowed (1 + $Vector)
511 #
512 sub _VectorAdditionOperator {
513 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
514
515 $ErrorMsg = "_VectorAdditionOperator: Vector addition failed";
516 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
517
518 # Do the addition. Order can be ignored: It's a commumative operation.
519 my($Vector, $ThisSize, $Index);
520 $Vector = $This->Copy();
521 $ThisSize = $This->GetSize();
522
523 if ($OtherIsVector) {
524 # $OrderFlipped is set to false for two vectors...
525 for $Index (0 .. ($ThisSize -1)) {
526 $Vector->{Values}[$Index] += $Other->{Values}[$Index];
527 }
528 }
529 else {
530 if ($OrderFlipped) {
531 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
532 }
533 # Scalar addition...
534 for $Index (0 .. ($ThisSize -1)) {
535 $Vector->{Values}[$Index] += $Other;
536 }
537 }
538 return $Vector;
539 }
540
541 #
542 # Vector subtraction operator supports two subtraction modes:
543 # . Subtraction of two vectors by subtracting corresponding vector values
544 # . Subtraction of a scalar value from vector values ($Vector - 1)
545 #
546 # Caveats:
547 # . Subtraction of a vector from scalar is not allowed (1 - $Vector)
548 #
549 sub _VectorSubtractionOperator {
550 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
551
552 $ErrorMsg = "_VectorSubtractionOperator: Vector subtracttion failed";
553 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
554
555 # Do the subtraction...
556 my($Vector, $ThisSize, $Index);
557 $Vector = $This->Copy();
558 $ThisSize = $This->GetSize();
559
560 if ($OtherIsVector) {
561 # $OrderFlipped is set to false for two vectors...
562 for $Index (0 .. ($ThisSize -1)) {
563 $Vector->{Values}[$Index] -= $Other->{Values}[$Index];
564 }
565 }
566 else {
567 # Scalar subtraction...
568 if ($OrderFlipped) {
569 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
570 }
571 for $Index (0 .. ($ThisSize -1)) {
572 $Vector->{Values}[$Index] -= $Other;
573 }
574 }
575 return $Vector;
576 }
577
578 #
579 # Vector multiplication operator supports two multiplication modes:
580 # . Multiplication of two vectors by multiplying corresponding vector values
581 # . Multiplying vector values by a scalar ($Vector * 1)
582 #
583 # Caveats:
584 # . Multiplication of a scalar by a vector is not allowed (1 * $Vector)
585 #
586 sub _VectorMultiplicationOperator {
587 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
588
589 $ErrorMsg = "_VectorMultiplicationOperator: Vector addition failed";
590 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
591
592 # Do the multiplication...
593 my($Vector, $ThisSize, $Index);
594 $Vector = $This->Copy();
595 $ThisSize = $This->GetSize();
596
597 if ($OtherIsVector) {
598 # $OrderFlipped is set to false for two vectors...
599 for $Index (0 .. ($ThisSize -1)) {
600 $Vector->{Values}[$Index] *= $Other->{Values}[$Index];
601 }
602 }
603 else {
604 if ($OrderFlipped) {
605 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
606 }
607 # Scalar multiplication...
608 for $Index (0 .. ($ThisSize -1)) {
609 $Vector->{Values}[$Index] *= $Other;
610 }
611 }
612 return $Vector;
613 }
614
615 #
616 # Vector division operator supports two division modes:
617 # . Division of two vectors by dividing corresponding vector values
618 # . Dividing vector values by a scalar ($Vector / 2)
619 #
620 # Caveats:
621 # . Division of a scalar by a vector is not allowed (1 / $Vector)
622 #
623 sub _VectorDivisionOperator {
624 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
625
626 $ErrorMsg = "_VectorDivisionOperator: Vector division failed";
627 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
628
629 # Do the division...
630 my($Vector, $ThisSize, $Index);
631 $Vector = $This->Copy();
632 $ThisSize = $This->GetSize();
633
634 if ($OtherIsVector) {
635 # $OrderFlipped is set to false for two vectors...
636 for $Index (0 .. ($ThisSize -1)) {
637 $Vector->{Values}[$Index] /= $Other->{Values}[$Index];
638 }
639 }
640 else {
641 if ($OrderFlipped) {
642 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
643 }
644 # Scalar divison...
645 for $Index (0 .. ($ThisSize -1)) {
646 $Vector->{Values}[$Index] /= $Other;
647 }
648 }
649 return $Vector;
650 }
651
652 #
653 # Vector exponentiation operator supports two exponentiation modes:
654 # . Exponentiation of two vectors by exponentiation of corresponding vector values
655 # . Exponentiation of vector values by a scalar ($Vector ** 2)
656 #
657 # Caveats:
658 # . Exponent of scalar by a vector is not allowed (2 ** $Vector)
659 #
660 sub _VectorExponentiationOperator {
661 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
662
663 $ErrorMsg = "_VectorExponentiationOperator: Vector exponentiation failed";
664 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
665
666 # Do the exponentiation...
667 my($Vector, $ThisSize, $Index);
668 $Vector = $This->Copy();
669 $ThisSize = $This->GetSize();
670
671 if ($OtherIsVector) {
672 # $OrderFlipped is set to false for two vectors...
673 for $Index (0 .. ($ThisSize -1)) {
674 $Vector->{Values}[$Index] **= $Other->{Values}[$Index];
675 }
676 }
677 else {
678 if ($OrderFlipped) {
679 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
680 }
681 # Scalar exponentiation...
682 for $Index (0 .. ($ThisSize -1)) {
683 $Vector->{Values}[$Index] **= $Other;
684 }
685 }
686 return $Vector;
687 }
688
689 #
690 # Vector modulus operator supports two modulus modes:
691 # . Modulus of two vectors by taking modulus between corresponding vector values
692 # . Modulus of vector values by a scalar ($Vector % 2)
693 #
694 # Caveats:
695 # . Modulus of scalar by a vector is not allowed (2 % $Vector)
696 #
697 sub _VectorModulusOperator {
698 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
699
700 $ErrorMsg = "_VectorModulusOperator: Vector exponentiation failed";
701 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
702
703 # Take the modulus...
704 my($Vector, $ThisSize, $Index);
705 $Vector = $This->Copy();
706 $ThisSize = $This->GetSize();
707
708 if ($OtherIsVector) {
709 # $OrderFlipped is set to false for two vectors...
710 for $Index (0 .. ($ThisSize -1)) {
711 $Vector->{Values}[$Index] %= $Other->{Values}[$Index];
712 }
713 }
714 else {
715 if ($OrderFlipped) {
716 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
717 }
718 # Scalar modulus...
719 for $Index (0 .. ($ThisSize -1)) {
720 $Vector->{Values}[$Index] %= $Other;
721 }
722 }
723 return $Vector;
724 }
725
726 #
727 # Vector dot product operator supports two modes:
728 # . Dot product of two 3D vectors
729 # . Concatenation of a vector and a scalar
730 #
731 sub _VectorDotProductOperator {
732 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
733
734 $ErrorMsg = "_VectorDotProductOperator: Vector dot product failed";
735 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
736
737 if ($OtherIsVector) {
738 # Calculate dot product of two 3D vectors...
739 my($DotProduct);
740 if ($This->GetSize() != 3) {
741 croak "Error: ${ClassName}->${ErrorMsg}: Both vectors must be 3D vectors...";
742 }
743 $DotProduct = $This->GetX() * $Other->GetX + $This->GetY() * $Other->GetY() + $This->GetZ * $Other->GetZ();
744 return $DotProduct;
745 }
746 else {
747 # Do a string concatenation and return the string...
748 if ($OrderFlipped) {
749 return $Other . $This->StringifyVector();
750 }
751 else {
752 return $This->StringifyVector() . $Other;
753 }
754 }
755 }
756
757 #
758 # Vector cross product operator genrates a new vector which is the cross
759 # product of two 3D vectors.
760 #
761 # For two vectors, V1 (X1, Y1, Z1) and V2 (X2, Y2, Z2), cross product
762 # V1 x V2 corresponds: (Y1.Z2 - Z1.Y2), (Z1.X2 - X1.Z2), (X1.Y2 - Y1.X2)
763 #
764 sub _VectorCrossProductOperator {
765 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
766
767 $ErrorMsg = "_VectorCrossProductOperator: Vector cross product failed";
768 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
769
770 if (!$OtherIsVector) {
771 croak "Error: ${ClassName}->${ErrorMsg}: Both object must be vectors...";
772 }
773
774 # Calculate cross product of two 3D vectors...
775 if ($This->GetSize() != 3) {
776 croak "Error: ${ClassName}->${ErrorMsg}: Both vectors must be 3D vectors...";
777 }
778 my($Vector, $X, $Y, $Z);
779 $X = $This->GetY() * $Other->GetZ() - $This->GetZ() * $Other->GetY();
780 $Y = $This->GetZ() * $Other->GetX() - $This->GetX() * $Other->GetZ();
781 $Z = $This->GetX() * $Other->GetY() - $This->GetY() * $Other->GetX();
782
783 $Vector = (ref $This)->new($X, $Y, $Z);
784
785 return $Vector;
786 }
787
788 #
789 # Vector booelan operator checks whether a vector contains at least one non-zero
790 # value...
791 #
792 sub _VectorBooleanOperator {
793 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
794
795 $ErrorMsg = "_VectorBooleanOperator: Vector boolean operation failed";
796 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
797
798 my($Size, $Index);
799 $Size = $This->GetSize();
800
801 for $Index (0 .. ($Size - 1)) {
802 if ($This->{Values}[$Index] != 0) {
803 return 1;
804 }
805 }
806 return 0;
807 }
808
809 #
810 # Vector not booelan operator checks whether all values of a vector are zero.
811 #
812 sub _VectorNotBooleanOperator {
813 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
814
815 $ErrorMsg = "_VectorNotBooleanOperator: Vector not boolean operation failed";
816 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
817
818 my($Size, $Index);
819 $Size = $This->GetSize();
820
821 for $Index (0 .. ($Size - 1)) {
822 if ($This->{Values}[$Index] != 0) {
823 return 0;
824 }
825 }
826 return 1;
827 }
828
829 #
830 # Vector equal operator supports two modes:
831 # . Comparion of corresponding values in two vectors
832 # . Comparing vectors values to a scalar ($Vector == 2)
833 #
834 # Caveats:
835 # . Comparison of a scalar to vector values is not allowed (2 == $Vector)
836 #
837 sub _VectorEqualOperator {
838 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg, $CheckVectorSizes);
839
840 $ErrorMsg = "_VectorEqualOperator: Vector equal comparison failed";
841 $CheckVectorSizes = 0;
842 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckVectorSizes);
843
844 # Do the comparison...
845 my($ThisSize, $Index);
846 $ThisSize = $This->GetSize();
847
848 if ($OtherIsVector) {
849 # $OrderFlipped is set to false for two vectors...
850 my($OtherSize) = $Other->GetSize();
851 if ($ThisSize != $OtherSize) {
852 return 0;
853 }
854 for $Index (0 .. ($ThisSize -1)) {
855 if ($This->{Values}[$Index] != $Other->{Values}[$Index]) {
856 return 0;
857 }
858 }
859 }
860 else {
861 if ($OrderFlipped) {
862 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
863 }
864 # Scalar comparison...
865 for $Index (0 .. ($ThisSize -1)) {
866 if ($This->{Values}[$Index] != $Other) {
867 return 0;
868 }
869 }
870 }
871 return 1;
872 }
873
874 #
875 # Vector not equal operator supports two modes:
876 # . Comparion of corresponding values in two vectors
877 # . Comparing vectors values to a scalar ($Vector != 2)
878 #
879 # Caveats:
880 # . Comparison of a scalar to vector values is not allowed (2 != $Vector2)
881 #
882 sub _VectorNotEqualOperator {
883 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg, $CheckVectorSizes);
884
885 $ErrorMsg = "_VectorNotEqualOperator: Vector not equal comparison failed";
886 $CheckVectorSizes = 0;
887 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckVectorSizes);
888
889 # Do the comparison...
890 my($ThisSize, $Index);
891 $ThisSize = $This->GetSize();
892
893 if ($OtherIsVector) {
894 # $OrderFlipped is set to false for two vectors...
895 my($OtherSize) = $Other->GetSize();
896 if ($ThisSize != $OtherSize) {
897 return 1;
898 }
899 for $Index (0 .. ($ThisSize -1)) {
900 if ($This->{Values}[$Index] == $Other->{Values}[$Index]) {
901 return 0;
902 }
903 }
904 }
905 else {
906 if ($OrderFlipped) {
907 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
908 }
909 # Scalar comparison...
910 for $Index (0 .. ($ThisSize -1)) {
911 if ($This->{Values}[$Index] == $Other) {
912 return 0;
913 }
914 }
915 }
916 return 1;
917 }
918
919 #
920 # Vector less than operator supports two modes:
921 # . Comparion of corresponding values in two vectors
922 # . Comparing vectors values to a scalar ($Vector < 2)
923 #
924 # Caveats:
925 # . Comparison of a scalar to vector values is not allowed (2 < $Vector2)
926 #
927 sub _VectorLessThanOperator {
928 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
929
930 $ErrorMsg = "_VectorLessThanOperator: Vector less than comparison failed";
931 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
932
933 # Do the comparison...
934 my($ThisSize, $Index);
935 $ThisSize = $This->GetSize();
936
937 if ($OtherIsVector) {
938 # $OrderFlipped is set to false for two vectors...
939 for $Index (0 .. ($ThisSize -1)) {
940 if ($This->{Values}[$Index] >= $Other->{Values}[$Index]) {
941 return 0;
942 }
943 }
944 }
945 else {
946 if ($OrderFlipped) {
947 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
948 }
949 # Scalar comparison...
950 for $Index (0 .. ($ThisSize -1)) {
951 if ($This->{Values}[$Index] >= $Other) {
952 return 0;
953 }
954 }
955 }
956 return 1;
957 }
958
959 #
960 # Vector less than equla operator supports two modes:
961 # . Comparion of corresponding values in two vectors
962 # . Comparing vectors values to a scalar ($Vector <= 2)
963 #
964 # Caveats:
965 # . Comparison of a scalar to vector values is not allowed (2 <= $Vector2)
966 #
967 sub _VectorLessThanEqualOperator {
968 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
969
970 $ErrorMsg = "_VectorLessThanEqualOperator: Vector less than equal comparison failed";
971 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
972
973 # Do the comparison...
974 my($ThisSize, $Index);
975 $ThisSize = $This->GetSize();
976
977 if ($OtherIsVector) {
978 # $OrderFlipped is set to false for two vectors...
979 for $Index (0 .. ($ThisSize -1)) {
980 if ($This->{Values}[$Index] > $Other->{Values}[$Index]) {
981 return 0;
982 }
983 }
984 }
985 else {
986 if ($OrderFlipped) {
987 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
988 }
989 # Scalar comparison...
990 for $Index (0 .. ($ThisSize -1)) {
991 if ($This->{Values}[$Index] > $Other) {
992 return 0;
993 }
994 }
995 }
996 return 1;
997 }
998
999 #
1000 # Vector greatar than operator supports two modes:
1001 # . Comparion of corresponding values in two vectors
1002 # . Comparing vectors values to a scalar ($Vector > 2)
1003 #
1004 # Caveats:
1005 # . Comparison of a scalar to vector values is not allowed (2 > $Vector2)
1006 #
1007 sub _VectorGreatarThanOperator {
1008 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
1009
1010 $ErrorMsg = "_VectorGreatarThanOperator: Vector greatar than comparison failed";
1011 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1012
1013 # Do the comparison...
1014 my($ThisSize, $Index);
1015 $ThisSize = $This->GetSize();
1016
1017 if ($OtherIsVector) {
1018 # $OrderFlipped is set to false for two vectors...
1019 for $Index (0 .. ($ThisSize -1)) {
1020 if ($This->{Values}[$Index] <= $Other->{Values}[$Index]) {
1021 return 0;
1022 }
1023 }
1024 }
1025 else {
1026 if ($OrderFlipped) {
1027 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
1028 }
1029 # Scalar comparison...
1030 for $Index (0 .. ($ThisSize -1)) {
1031 if ($This->{Values}[$Index] <= $Other) {
1032 return 0;
1033 }
1034 }
1035 }
1036 return 1;
1037 }
1038
1039 #
1040 # Vector greatar than equal operator supports two modes:
1041 # . Comparion of corresponding values in two vectors
1042 # . Comparing vectors values to a scalar ($Vector >= 2)
1043 #
1044 # Caveats:
1045 # . Comparison of a scalar to vector values is not allowed (2 <= $Vector2)
1046 #
1047 sub _VectorGreatarThanEqualOperator {
1048 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
1049
1050 $ErrorMsg = "_VectorGreatarThanEqualOperator: Vector greatar than equal comparison failed";
1051 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1052
1053 # Do the comparison...
1054 my($ThisSize, $Index);
1055 $ThisSize = $This->GetSize();
1056
1057 if ($OtherIsVector) {
1058 # $OrderFlipped is set to false for two vectors...
1059 for $Index (0 .. ($ThisSize -1)) {
1060 if ($This->{Values}[$Index] < $Other->{Values}[$Index]) {
1061 return 0;
1062 }
1063 }
1064 }
1065 else {
1066 if ($OrderFlipped) {
1067 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a vector...";
1068 }
1069 # Scalar comparison...
1070 for $Index (0 .. ($ThisSize -1)) {
1071 if ($This->{Values}[$Index] < $Other) {
1072 return 0;
1073 }
1074 }
1075 }
1076 return 1;
1077 }
1078
1079 #
1080 # Vector negative value operator returns a vector with values corresponding to
1081 # negative values of a vector
1082 #
1083 sub _VectorNegativeValueOperator {
1084 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
1085
1086 $ErrorMsg = "_VectorNegativeValueOperator: Vector negative value operation failed";
1087 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1088
1089 # Take the negative value...
1090 my($Vector, $ThisSize, $Index);
1091 $Vector = $This->Copy();
1092 $ThisSize = $This->GetSize();
1093
1094 for $Index (0 .. ($ThisSize -1)) {
1095 $Vector->{Values}[$Index] = - $This->{Values}[$Index];
1096 }
1097 return $Vector;
1098 }
1099
1100 #
1101 # Vector absolute value operator returns a vector with values corresponding to
1102 # absolute values of a vector
1103 #
1104 sub _VectorAbsoluteValueOperator {
1105 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
1106
1107 $ErrorMsg = "_VectorAbsoluteValueOperator: Vector absolute value operation failed";
1108 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1109
1110 # Take the absolute value...
1111 my($Vector, $ThisSize, $Index);
1112 $Vector = $This->Copy();
1113 $ThisSize = $This->GetSize();
1114
1115 for $Index (0 .. ($ThisSize -1)) {
1116 $Vector->{Values}[$Index] = abs $This->{Values}[$Index];
1117 }
1118 return $Vector;
1119 }
1120
1121 #
1122 # Vector exp natural base operator returns a vector with values corresponding to
1123 # e raised to the power of values in a vector
1124 #
1125 sub _VectorExpNaturalBaseOperator {
1126 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
1127
1128 $ErrorMsg = "_VectorExpNaturalBaseOperator: Vector exp operation failed";
1129 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1130
1131 # Take the absolute value...
1132 my($Vector, $ThisSize, $Index);
1133 $Vector = $This->Copy();
1134 $ThisSize = $This->GetSize();
1135
1136 for $Index (0 .. ($ThisSize -1)) {
1137 $Vector->{Values}[$Index] = exp $This->{Values}[$Index];
1138 }
1139 return $Vector;
1140 }
1141
1142 #
1143 # Vector log natural base operator returns a vector with values corresponding to
1144 # log of values in a vector
1145 #
1146 sub _VectorLogNaturalBaseOperator {
1147 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
1148
1149 $ErrorMsg = "_VectorLogNaturalBaseOperator: Vector log operation failed";
1150 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1151
1152 # Take the absolute value...
1153 my($Vector, $ThisSize, $Index);
1154 $Vector = $This->Copy();
1155 $ThisSize = $This->GetSize();
1156
1157 for $Index (0 .. ($ThisSize -1)) {
1158 $Vector->{Values}[$Index] = log $This->{Values}[$Index];
1159 }
1160 return $Vector;
1161 }
1162
1163 #
1164 # Vector cosine operator returns a vector with values corresponding to cosine of values
1165 # in a vector. Input vector values are assumed to be in radians.
1166 #
1167 sub _VectorCosineOperator {
1168 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
1169
1170 $ErrorMsg = "_VectorCosineOperator: Vector cos operation failed";
1171 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1172
1173 # Take the absolute value...
1174 my($Vector, $ThisSize, $Index);
1175 $Vector = $This->Copy();
1176 $ThisSize = $This->GetSize();
1177
1178 for $Index (0 .. ($ThisSize -1)) {
1179 $Vector->{Values}[$Index] = cos $This->{Values}[$Index];
1180 }
1181 return $Vector;
1182 }
1183
1184 #
1185 # Vector sine operator returns a vector with values corresponding to sine of values
1186 # in a vector. Input vector values are assumed to be in radians.
1187 #
1188 sub _VectorSineOperator {
1189 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
1190
1191 $ErrorMsg = "_VectorSineOperator: Vector sin operation failed";
1192 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1193
1194 # Take the absolute value...
1195 my($Vector, $ThisSize, $Index);
1196 $Vector = $This->Copy();
1197 $ThisSize = $This->GetSize();
1198
1199 for $Index (0 .. ($ThisSize -1)) {
1200 $Vector->{Values}[$Index] = sin $This->{Values}[$Index];
1201 }
1202 return $Vector;
1203 }
1204
1205 #
1206 # Vector square root returns a vector with values corresponding to sqrt of values
1207 # in a vector.
1208 #
1209 sub _VectorSquareRootOperator {
1210 my($This, $Other, $OrderFlipped, $OtherIsVector, $ErrorMsg);
1211
1212 $ErrorMsg = "_VectorSquareRootOperator: Vector sqrt operation failed";
1213 ($This, $Other, $OrderFlipped, $OtherIsVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1214
1215 # Take the absolute value...
1216 my($Vector, $ThisSize, $Index);
1217 $Vector = $This->Copy();
1218 $ThisSize = $This->GetSize();
1219
1220 for $Index (0 .. ($ThisSize -1)) {
1221 $Vector->{Values}[$Index] = sqrt $This->{Values}[$Index];
1222 }
1223 return $Vector;
1224 }
1225
1226 # Turn vector into array for @{$Vector} operation...
1227 sub _VectorToArrayOperator {
1228 my($This) = @_;
1229
1230 return \@{$This->{Values}};
1231 }
1232
1233 # Turn vector into number for $#Vector operation: It's the size of vector...
1234 sub _NumifyVector {
1235 my($This) = @_;
1236
1237 return $This->GetSize();
1238 }
1239
1240 # Process parameters passed to overloaded operators...
1241 #
1242 # For uninary operators, $SecondParameter is not defined.
1243 sub _ProcessOverloadedOperatorParameters {
1244 my($ErrorMsg, $FirstParameter, $SecondParameter, $ParametersOrderStatus, $CheckVectorSizesStatus) = @_;
1245 my($This, $Other, $OrderFlipped, $OtherIsVector, $CheckVectorSizes);
1246
1247 ($This, $Other) = ($FirstParameter, $SecondParameter);
1248 $OrderFlipped = (defined($ParametersOrderStatus) && $ParametersOrderStatus) ? 1 : 0;
1249 $CheckVectorSizes = (defined $CheckVectorSizesStatus) ? $CheckVectorSizesStatus : 1;
1250
1251 _ValidateVector($ErrorMsg, $This);
1252
1253 $OtherIsVector = 0;
1254 if (defined($Other) && (ref $Other)) {
1255 # Make sure $Other is a vector...
1256 _ValidateVector($ErrorMsg, $Other);
1257 if ($CheckVectorSizes) {
1258 _ValidateVectorSizesAreEqual($ErrorMsg, $This, $Other);
1259 }
1260 $OtherIsVector = 1;
1261 }
1262 return ($This, $Other, $OrderFlipped, $OtherIsVector);
1263 }
1264
1265 # Is it a vector object?
1266 sub _IsVector {
1267 my($Object) = @_;
1268
1269 return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0;
1270 }
1271
1272 # Make sure it's a vector reference...
1273 sub _ValidateVector {
1274 my($ErrorMsg, $Vector) = @_;
1275
1276 if (!_IsVector($Vector)) {
1277 croak "Error: ${ClassName}->${ErrorMsg}: Object must be a vector...";
1278 }
1279 }
1280
1281 # Make sure size of the two vectors contain the same number of values...
1282 sub _ValidateVectorSizesAreEqual {
1283 my($ErrorMsg, $Vector1, $Vector2) = @_;
1284
1285 if ($Vector1->GetSize() != $Vector2->GetSize()) {
1286 croak "Error: ${ClassName}->${ErrorMsg}: Size of the vectors must be same...";
1287 }
1288 }
1289
1290 # Return a string containing vector values...
1291 sub StringifyVector {
1292 my($This) = @_;
1293 my($VectorString, $FormatString, $PrintFormat, $Size, @ValuesFormat);
1294
1295 $PrintFormat = (exists $This->{ValueFormat}) ? $This->{ValueFormat} : $ValueFormat;
1296
1297 @ValuesFormat = ($PrintFormat) x scalar @{$This->{Values}};
1298 $FormatString = join ' ', @ValuesFormat;
1299
1300 $Size = $This->GetSize();
1301
1302 $VectorString = sprintf "<Size: $Size; Values: [ $FormatString ] >", @{$This->{Values}};
1303
1304 return $VectorString;
1305 }
1306
1307 1;
1308
1309 __END__
1310
1311 =head1 NAME
1312
1313 Vector
1314
1315 =head1 SYNOPSIS
1316
1317 use Vector;
1318
1319 use Vector qw(:all);
1320
1321 =head1 DESCRIPTION
1322
1323 B<Vector> class provides the following methods:
1324
1325 new, AddValues, Copy, GetLength, GetMagnitude, GetNumOfNonZeroValues,
1326 GetPercentOfNonZeroValues, GetSize, GetValue, GetValues, GetX, GetXYZ, GetY,
1327 GetZ, IsVector, Normalize, SetValue, SetValuePrintFormat,
1328 SetX, SetXYZ, SetY, SetZ, StringifyVector, IsVector
1329
1330 The following functions are available:
1331
1332 IsVector, SetValuePrintFormat UnitXVector, UnitYVector, UnitZVector, UnitVector,
1333 ZeroVector
1334
1335 The following operators are overloaded:
1336
1337 "" 0+ bool
1338 @{}
1339 + - * / %
1340 x .
1341 == != < <= > >=
1342 neg
1343 abs exp log sqrt cos sin
1344
1345 =head2 FUNCTIONS
1346
1347 =over 4
1348
1349 =item B<new>
1350
1351 $NewVector = new Vector();
1352 $NewVector = new Vector(@Values);
1353 $NewVector = new Vector(\@Values);
1354 $NewVector = new Vector($AnotherVector);
1355
1356 Creates a new B<Vector> object containing I<Values> and returns B<NewVector> object.
1357 In case no I<Values> are specified, an empty B<Vector> is created.
1358
1359 =item B<AddValues>
1360
1361 $Vector->AddValues(@Values);
1362 $Vector->AddValues(\@Values);
1363 $Vector->AddValues($AnotherVector);
1364
1365 Adds values to I<Vector> using an array, reference to an array or another vector and returns
1366 I<Vector>.
1367
1368 =item B<Copy>
1369
1370 $NewVector = $Vector->Copy();
1371
1372 Creates a copy of I<Vector> and returns I<NewVector>.
1373
1374 =item B<GetLength>
1375
1376 $Length = $Vector->GetLength();
1377
1378 Returns I<Lengh> of a 3D I<Vector> corresponding to its dot product.
1379
1380 =item B<GetMagnitude>
1381
1382 $Length = $Vector->GetMagnitude();
1383
1384 Returns I<Lengh> of a 3D I<Vector> corresponding to its dot product.
1385
1386 =item B<GetNumOfNonZeroValues>
1387
1388 $Value = $Vector->GetNumOfNonZeroValues();
1389
1390 Returns number of non-zero values in I<Vector>.
1391
1392 =item B<GetPercentOfNonZeroValues>
1393
1394 $Value = $Vector->GetPercentOfNonZeroValues();
1395
1396 Returns percent of non-zero values in I<Vector>.
1397
1398 =item B<GetSize>
1399
1400 $Size = $Vector->GetSize();
1401
1402 Returns size of a I<Vector> corresponding to number of its values.
1403
1404 =item B<GetValue>
1405
1406 $Value = $Vector->GetValues($Index);
1407
1408 Returns vector B<Value> specified using I<Index> starting at 0.
1409
1410 =item B<GetValues>
1411
1412 @Values = $Vector->GetValues();
1413 $ValuesRef = $Vector->GetValues();
1414
1415 Returns an array or a reference to an array containing all I<Vector> values.
1416
1417 =item B<GetX>
1418
1419 $X = $Vector->GetX();
1420
1421 Returns B<X> value of a 3D I<Vector>
1422
1423 =item B<GetXYZ>
1424
1425 @XYZValues = $Vector->GetXYZ();
1426 $XYZValuesRef = $Vector->GetXYZ();
1427
1428 Returns B<XYZ> values of a 3D I<Vector> as an array or a reference to an array
1429 containing the values.
1430
1431 =item B<GetY>
1432
1433 $Y = $Vector->GetY();
1434
1435 Returns B<Y> value of a 3D I<Vector>.
1436
1437 =item B<GetZ>
1438
1439 $Z = $Vector->GetZ();
1440
1441 Returns B<Z> value of a 3D I<Vector>.
1442
1443 =item B<IsVector>
1444
1445 $Status = Vector::IsVector($Object);
1446
1447 Returns 1 or 0 based on whether I<Object> is a B<Vector> object.
1448
1449 =item B<Normalize>
1450
1451 $Vector->Normalize();
1452
1453 Normalizes a 3D I<Vector> by dividing its values by the length and returns I<Vector>.
1454
1455 =item B<SetValue>
1456
1457 $Vector->SetValue($Index, $Value);
1458
1459 Sets a I<Vector> value specified by I<Index> to I<Value> and returns I<Vector>.
1460
1461 =item B<SetValuePrintFormat>
1462
1463 $Vector->SetValuePrintFormat($ValuePrintFormat);
1464 Vector::SetValuePrintFormat($ValuePrintFormat);
1465
1466 Sets format for printing vector values for a specified I<Vector> or the whole class. Default
1467 format: I<%g>.
1468
1469 =item B<SetX>
1470
1471 $Vector->SetX($Value);
1472
1473 Sets B<X> value of a 3D vector to I<Value> and returns I<Vector>.
1474
1475 =item B<SetXYZ>
1476
1477 $Vector->SetXYZ(@Values);
1478 $Vector->SetXYZ(\@Values);
1479 $Vector->SetXYZ($AnotherVector);
1480
1481 Sets B<XYZ> values of a 3D vector and returns I<Vector>.
1482
1483 =item B<SetY>
1484
1485 $Vector->SetY($Value);
1486
1487 Sets B<Y> value of a 3D vector to I<Value> and returns I<Vector>.
1488
1489 =item B<SetZ>
1490
1491 $Vector->SetZ($Value);
1492
1493 Sets B<Z> value of a 3D vector to I<Value> and returns I<Vector>.
1494
1495 =item B<StringifyVector>
1496
1497 $String = $Vector->StringifyVector();
1498
1499 Returns a string containing information about I<Vector> object.
1500
1501 =item B<UnitVector>
1502
1503 $UnitVector = UnitVector([$Size]);
1504 $UnitVector = Vector::UnitVector([$Size]);
1505
1506 Returns a B<UnitVector> of I<Size>. Default size: I<3>.
1507
1508 =item B<UnitXVector>
1509
1510 $UnitXVector = UnitXVector();
1511
1512 Returns a 3D B<UnitXVector>.
1513
1514 =item B<UnitYVector>
1515
1516 $UnitYVector = UnitYVector();
1517
1518 Returns a 3D B<UnitYVector>.
1519
1520 =item B<UnitZVector>
1521
1522 $UnitZVector = UnitZVector();
1523
1524 Returns a 3D B<UnitZVector>.
1525
1526 =item B<ZeroVector>
1527
1528 $UnitVector = ZeroVector([$Size]);
1529 $UnitVector = Vector::ZeroVector([$Size]);
1530
1531 Returns a B<ZeroVector> of I<Size>. Default size: I<3>.
1532
1533 =back
1534
1535 =head1 AUTHOR
1536
1537 Manish Sud <msud@san.rr.com>
1538
1539 =head1 SEE ALSO
1540
1541 BitVector.pm
1542
1543 =head1 COPYRIGHT
1544
1545 Copyright (C) 2015 Manish Sud. All rights reserved.
1546
1547 This file is part of MayaChemTools.
1548
1549 MayaChemTools is free software; you can redistribute it and/or modify it under
1550 the terms of the GNU Lesser General Public License as published by the Free
1551 Software Foundation; either version 3 of the License, or (at your option)
1552 any later version.
1553
1554 =cut