in reply to Re^3: The problem of getting the unit vector "Undefined subroutine &main::Normalize"
in thread The problem of getting the unit vector "Undefined subroutine &main::Normalize"

That's cool, buddy! I am trying to obtain the unit vector of the dipole moment (a vector) using sub Normalize.

# get dipole moment my $dipoleMoment = $setMolecule->DipoleMoment; # get the unit vector of dipole moment my $direction=Normalize($dipoleMoment);

unit vector=±a/|a|. For example, if I want to have the unit vector of (2,-3,6), the calculation process is unit vector=±(2,-3,6)/√4+9+36=±(2/7,-3/7,6/7).

$dipoleMoment is a vector with (X, Y, Z), I am trying to have the unit vector of $dipoleMoment, would you please write sub Normalize to fulfill this calculation?

  • Comment on Re^4: The problem of getting the unit vector "Undefined subroutine &main::Normalize"
  • Download Code

Replies are listed 'Best First'.
Re^5: The problem of getting the unit vector "Undefined subroutine &main::Normalize"
by NetWallah (Canon) on Sep 01, 2017 at 05:31 UTC
    Check out Math::Vector::Real.

    With the untested code below, you can probably make it "Normalize" for you:

    use strict; use warnings; use Math::Vector::Real; my $v = V(2,-3,6); # Your example vector print "Norm = ", Normalize ($v),"\n"; print "Versor= ", $v->versor(),"\n"; sub Normalize{ my ($v) = @_; # parameter is a single vector my $result = $v->div ( $v->abs() ); # abs of vector (x,y,z) = sqrt(x**2 + y**2 + z**2) return $result; }
    Update 1:Fixed "print" statement (Original post needed +Normalize(), and tested. It works correctly, producing the output:
    Norm = {0.285714285714286, -0.428571428571429, 0.857142857142857} Versor= {0.285714285714286, -0.428571428571429, 0.857142857142857}
    Update 2: I found out that the "versor()" method does exactly the same thing as Normalize() , and both produce identical results.

                    All power corrupts, but we need electricity.

Re^5: The problem of getting the unit vector "Undefined subroutine &main::Normalize"
by roboticus (Chancellor) on Aug 31, 2017 at 17:07 UTC

    windcrazy86:

    If you know the formula (i.e., how to create the result by hand) you shouldn't have any difficulty in creating the subroutine yourself. What difficulty are you having with it?

    As I see it, you'd start with something like:

    sub Normalize { my $v = shift; my $vSquared = InProduct($v, $v); my $divisor = ... square root of sum of components of vSquared ... my $newVec1 = ... vector created by components of v divided by posi +tive divisor ... my $newVec2 = ... vector created by componets of v divided by negat +ive divisor ... .... whatever else is needed ... return $stuff; } my @dipoleMomentVectors = Normalize($dipoleMoment);

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Thanks, I am new to perl, so I am still reading the tutorial online. I will test your code and see what's going on.

Re^5: The problem of getting the unit vector "Undefined subroutine &main::Normalize"
by Anonymous Monk on Aug 31, 2017 at 17:06 UTC
    The problem is, we don't know your MaterialsScript module, so we'd be guessing. It seems to be a closed-source product of Accelrys, and I don't see any documentation online.

      Yeap, you are right. I thought Normalize is a function in accelrys or perl before. However, it seems it's not for both. So I am using perl to write the sub Normalize to get unit vector from vector and it doesn't have relationship to materialsscript module anymore. Because I am new to perl, it takes me time to read related rules in perl and write it