Understanding Hessian matrix

Discussion in 'Physics & Math' started by Luis Vasquez Cardenas, Aug 16, 2016.

  1. Luis Vasquez Cardenas Registered Member

    Messages:
    2
    I work on computational chemistry and I am trying to ¨read¨,
    the hessian matrix from a calculation.
    The Hessian should be a square of 15x15, however the programme
    gives it in a strange manner.

    1 2 3 4 5
    1 0.584657D+00
    2 0.000000D+00 0.248875D+00
    3 0.000000D+00 0.000000D+00 0.412748D+00
    4 -0.262232D+00 0.000000D+00 0.137132D+00 0.269473D+00
    5 0.000000D+00 -0.315146D-01 0.000000D+00 0.000000D+00 0.518830D-01
    6 0.141387D+00 0.000000D+00 -0.137124D+00 -0.143249D+00 0.000000D+00
    7 -0.262232D+00 0.000000D+00 -0.137132D+00 -0.170104D-01 0.000000D+00
    8 0.000000D+00 -0.315146D-01 0.000000D+00 0.000000D+00 0.224750D-02
    9 -0.141387D+00 0.000000D+00 -0.137124D+00 0.154602D-01 0.000000D+00
    10 -0.300967D-01 0.000000D+00 0.000000D+00 0.488457D-02 -0.139225D-01
    11 0.000000D+00 -0.929227D-01 0.645795D-01 0.328563D-02 -0.113079D-01
    12 0.000000D+00 0.493914D-01 -0.692503D-01 -0.467139D-02 0.176985D-01
    13 -0.300967D-01 0.000000D+00 0.000000D+00 0.488457D-02 0.139225D-01
    14 0.000000D+00 -0.929227D-01 -0.645795D-01 -0.328563D-02 -0.113079D-01
    15 0.000000D+00 -0.493914D-01 -0.692503D-01 -0.467139D-02 -0.176985D-01
    6 7 8 9 10
    6 0.140680D+00
    7 -0.154602D-01 0.269473D+00
    8 0.000000D+00 0.000000D+00 0.518830D-01
    9 0.133128D-01 0.143249D+00 0.000000D+00 0.140680D+00
    10 0.866108D-02 0.488457D-02 0.139225D-01 -0.866108D-02 0.179751D-01
    11 0.767865D-02 -0.328563D-02 -0.113079D-01 0.767865D-02 0.000000D+00
    12 -0.843460D-02 0.467139D-02 0.176985D-01 -0.843460D-02 0.000000D+00
    13 0.866108D-02 0.488457D-02 -0.139225D-01 -0.866108D-02 0.235249D-02
    14 -0.767865D-02 0.328563D-02 -0.113079D-01 -0.767865D-02 0.000000D+00
    15 -0.843460D-02 0.467139D-02 -0.176985D-01 -0.843460D-02 0.000000D+00

    11 12 13 14 15
    11 0.145540D+00
    12 -0.823626D-01 0.777265D-01
    13 0.000000D+00 0.000000D+00 0.179751D-01
    14 -0.300013D-01 -0.242577D-02 0.000000D+00 0.145540D+00
    15 0.242577D-02 0.839298D-02 0.000000D+00 0.823626D-01 0.777265D-01


    As far as I understood this a kind of zip hessian, I would like to unzip it, however I have not idea
    how to do it. So I have a hessian of 15x15 but all the cells have a value different from 0. in this case the half is not zero.
    I would appreciate any help.
     
  2. Google AdSense Guest Advertisement



    to hide all adverts.
  3. rpenner Fully Wired Valued Senior Member

    Messages:
    4,833
    This is half of a symmetric matrix. It's printed out in strips only 5-columns wide so that it can be meaningfully displayed on a narrow screen/printer with no line wrapping.

    To read it in, you need to pick a language, understand what you can do in that language, understand the data, and craft a specific solution. Here for example is how you might go about it in Perl, a language which has lots of nice string processing.

    Code:
    #!/usr/bin/perl
    # -*- cperl -*-
    # $Id$
    
    use strict; # disallow certain unsafe syntax constructions
    use warnings; # inform user of curious conditions, like treating a string
                  # like a number even though it doesn't look like a number
    use Carp; # improved error reporting
    use Readonly; # mark values as immutable
    
    our $VERSION = '1.0';
    
    # Constants
    Readonly::Scalar my $N            => 15;
    Readonly::Scalar my $ALL_ELEMENTS => -1;
    Readonly::Scalar my $LAST_ELEMENT => -1;
    
    # Input
    
    # Initialize a $N x $N array of zeros
    my @array = map {
        [ map { 0 } ( 1 .. $N ) ]
    } ( 1 .. $N );
    
    while (<>) {    # read a line into $_
        s/\s+\z//xms;    # remove any trailing whitespace, including newlines
        next if !$_;    # skip blank lines as meaningless
        my (@columns) = split /\s+/xms, $_,
          $ALL_ELEMENTS;    # break line apart into some number, $k,  of
                            # integer column labels
        my $k = scalar @columns;
        while (<>)
        {    # Knowing the columns we are expecting to read,
            # we now read the associated rows
            s/\s+\z//xms;
            next if !$_;
            my ( $row, @values ) = split /\s+/xms, $_, $ALL_ELEMENTS
              ; # Each line consists of a row label and up to $k
                # double-precision floating point values
            if ( $k < scalar @values ) {
                    # Fatal error if too many values
                    croak "expected no more than $k values "
                    . " but got @{[scalar @values]} values";
            }
            for my $index ( ( 0 .. ( ( scalar @values ) - 1 ) ) )
            {    # loop over 0-based indices of the values.
                my $column = $columns[$index]; # convert the index to a
                                              # column label
                my $value  = $values[$index];  # then extract the value
                $value =~ s/D/E/xms
                  ; # Perl doesn't recognize the FORTRAN D-style exponents
                    # for double-precision so we change it prior to attempting
                    # to interpret it as a number
                $value = 0 +
                  $value
                  ; # force conversion to internal representation as double
                    # precision number
                $array[ $row - 1 ][ $column - 1 ] = $value
                  ; # store the value. Note that C and Perl use 0-based
                    # arrays, so must shift row/column labels by 1
                if ( $row != $column ) {
                    $array[ $column - 1 ][ $row - 1 ] = $value
                      ; # store the mirror image as this is a symmetric
                        # matrix. This would be wasted effort if we were on
                        # the diagonal.
                }
            }
            last
              if $row == $N
            ; # we are done with this batch of column labels if the row
              # label matched $N
        }
        last
          if $columns[$LAST_ELEMENT] ==
              $N;  # we are done with the array if the last column label
                    # matched $N
    }
    
    # Output
    foreach my $row ( 1 .. $N ) {    # loop over rows
        my (@strings) =
          map { sprintf '% 7.4f', $_ }
          @{ $array[ $row - 1 ]
          };    # loop over columns of each row, converting to string
        print "@strings\n"
          ; # print space-separate strings for each element of the row,
            # followed by newline.
    }
    Sample run:
    Code:
    $ ./reader.pl < input.txt
     0.5847  0.0000  0.0000 -0.2622  0.0000  0.1414 -0.2622  0.0000 -0.1414 -0.0301  0.0000  0.0000 -0.0301  0.0000  0.0000
     0.0000  0.2489  0.0000  0.0000 -0.0315  0.0000  0.0000 -0.0315  0.0000  0.0000 -0.0929  0.0494  0.0000 -0.0929 -0.0494
     0.0000  0.0000  0.4127  0.1371  0.0000 -0.1371 -0.1371  0.0000 -0.1371  0.0000  0.0646 -0.0693  0.0000 -0.0646 -0.0693
    -0.2622  0.0000  0.1371  0.2695  0.0000 -0.1432 -0.0170  0.0000  0.0155  0.0049  0.0033 -0.0047  0.0049 -0.0033 -0.0047
     0.0000 -0.0315  0.0000  0.0000  0.0519  0.0000  0.0000  0.0022  0.0000 -0.0139 -0.0113  0.0177  0.0139 -0.0113 -0.0177
     0.1414  0.0000 -0.1371 -0.1432  0.0000  0.1407 -0.0155  0.0000  0.0133  0.0087  0.0077 -0.0084  0.0087 -0.0077 -0.0084
    -0.2622  0.0000 -0.1371 -0.0170  0.0000 -0.0155  0.2695  0.0000  0.1432  0.0049 -0.0033  0.0047  0.0049  0.0033  0.0047
     0.0000 -0.0315  0.0000  0.0000  0.0022  0.0000  0.0000  0.0519  0.0000  0.0139 -0.0113  0.0177 -0.0139 -0.0113 -0.0177
    -0.1414  0.0000 -0.1371  0.0155  0.0000  0.0133  0.1432  0.0000  0.1407 -0.0087  0.0077 -0.0084 -0.0087 -0.0077 -0.0084
    -0.0301  0.0000  0.0000  0.0049 -0.0139  0.0087  0.0049  0.0139 -0.0087  0.0180  0.0000  0.0000  0.0024  0.0000  0.0000
     0.0000 -0.0929  0.0646  0.0033 -0.0113  0.0077 -0.0033 -0.0113  0.0077  0.0000  0.1455 -0.0824  0.0000 -0.0300  0.0024
     0.0000  0.0494 -0.0693 -0.0047  0.0177 -0.0084  0.0047  0.0177 -0.0084  0.0000 -0.0824  0.0777  0.0000 -0.0024  0.0084
    -0.0301  0.0000  0.0000  0.0049  0.0139  0.0087  0.0049 -0.0139 -0.0087  0.0024  0.0000  0.0000  0.0180  0.0000  0.0000
     0.0000 -0.0929 -0.0646 -0.0033 -0.0113 -0.0077  0.0033 -0.0113 -0.0077  0.0000 -0.0300 -0.0024  0.0000  0.1455  0.0824
     0.0000 -0.0494 -0.0693 -0.0047 -0.0177 -0.0084  0.0047 -0.0177 -0.0084  0.0000  0.0024  0.0084  0.0000  0.0824  0.0777
    
     
    Last edited: Aug 16, 2016
    Luis Vasquez Cardenas likes this.
  4. Google AdSense Guest Advertisement



    to hide all adverts.
  5. Luis Vasquez Cardenas Registered Member

    Messages:
    2
    I was reading a paper yesterday when I understood that this is only the half of the matrix. Thanks a lot for you useful answer rpenner. Now I need to read it, the point is that unfortunately I am new in programming, so I will need to figure out a solution, namely in python. But thanks to your example I already have a idea about what I should do. I was able to understand big part of the code thanks to toe comments. 1000 thanks
     
  6. Google AdSense Guest Advertisement



    to hide all adverts.

Share This Page