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.
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
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