3 start include statements
5 use ext
::Math
::MatrixReal
;
10 # }}} include statements
16 if ( defined $this -> {'tablename'} ) {
17 $this -> add_data
( 'init_data' => {'filename' => $this -> {'tablename'},
18 'idcolumn' => $this -> {'tableidcolumn'},
19 'debug' => $this -> {'debug'}} );
21 $this -> _read_simulation
;
22 $this -> _read_iteration_path
;
24 $this -> _read_minimization_message
;
26 $this -> _read_significant_digits
;
28 $this -> _read_thomsi
;
29 $this -> _read_sethomsi
;
30 if ($this -> {'covariance_step_run'}) {
31 $this -> _read_covmatrix
;
34 $this -> _read_npomegas
;
35 $this -> _compute_cvsetheta
;
36 $this -> _compute_cvseomega
;
37 $this -> _compute_cvsesigma
;
39 $this -> _compute_comegas
;
40 $this -> _compute_csigmas
;
41 $this -> _set_thetanames
;
42 $this -> _set_omeganames
;
43 $this -> _set_sigmanames
;
49 # {{{ register_in_database
51 start register_in_database
52 if ( $PsN::config
-> {'_'} -> {'use_database'} ) {
53 my $dbh = DBI
-> connect("DBI:mysql:host=".$PsN::config
-> {'_'} -> {'database_server'}.
54 ";databse=".$PsN::config
-> {'_'} -> {'project'},
55 $PsN::config
-> {'_'} -> {'user'},
56 $PsN::config
-> {'_'} -> {'password'},
60 if ( defined $self->{'minimization_message'} ) {
61 $term_str = join("\n",@
{$self->{'minimization_message'}});
63 my @mod_str = ('','');
64 if ( defined $model_id ) {
65 @mod_str = ('model_id,',"$model_id,");
67 $sth = $dbh -> prepare
("INSERT INTO ".$PsN::config
-> {'_'} -> {'project'}.
69 "(problem_id,output_id,".
72 "covariance_step_successful,".
73 "covariance_step_warnings,".
75 "final_zero_gradients,".
80 "significant_digits,".
82 "minimization_successful,".
83 "minimization_message,".
85 "VALUES ( '$problem_id' ,".
88 "'$self->{'condition_number'}' ,".
89 "'$self->{'covariance_step_successful'}' ,".
90 "'$self->{'covariance_step_warnings'}' ,".
91 "'$self->{'eval'}' ,".
92 "'$self->{'final_zero_gradients'}' ,".
93 "'$self->{'hessian_reset'}' ,".
95 "'$self->{'rounding_errors'}' ,".
96 "'$self->{'s_matrix_singular'}' ,".
97 "'$self->{'significant_digits'}' ,".
98 "'$self->{'simulation'}' ,".
99 "'$self->{'minimization_successful'}' ,".
101 "'$self->{'zero_gradients'}' )");
103 $self -> {'subproblem_id'} = $sth->{'mysql_insertid'};
104 $self -> {'problem_id'} = $problem_id;
105 $self -> {'output_id'} = $output_id;
106 $self -> {'model_id'} = $model_id;
107 foreach my $param ( 'theta', 'omega', 'sigma' ) {
109 foreach my $par_str ( @
{$self -> {$param.'s'}} ) {
110 $sth = $dbh -> prepare
("INSERT INTO ".$PsN::config
-> {'_'} -> {'project'}.
112 "(subproblem_id,problem_id,output_id,".
114 "type,value, number, label) ".
115 "VALUES ( '$self->{'subproblem_id'}' ,".
116 "'$self->{'problem_id'}' ,".
117 "'$self->{'output_id'}' ,".
119 "'$param','$par_str', '$i', 'test_label')");
121 push( @
{$self -> {'estimate_ids'}}, $sth->{'mysql_insertid'} );
129 # if ( $PsN::config -> {'_'} -> {'use_database'} ) {
130 # my $dbh = DBI -> connect("DBI:mysql:host=".$PsN::config -> {'_'} -> {'database_server'}.
131 # ";databse=".$PsN::config -> {'_'} -> {'project'},
132 # $PsN::config -> {'_'} -> {'user'},
133 # $PsN::config -> {'_'} -> {'password'},
134 # {'RaiseError' => 1});
135 # my $sth = $dbh -> prepare( "UPDATE ".$PsN::config -> {'_'} -> {'project'}.
137 # "SET condition_number='".
138 # $self -> {'condition_number'}."'".
139 # "WHERE model_id='".$self -> {'model_id'}."'" );
140 # $sth -> execute or debug -> die( message => $sth->errstr ) ;
142 # $dbh -> disconnect;
144 end register_in_database
146 # }}} register_in_database
148 # {{{ _compute_comegas_or_csigmas
150 start _compute_comegas_or_csigmas
152 # This method transforms omegas or sigmas.
154 # First we check if we have omegas or sigmas.
155 if ( defined $self -> {'raw_' . $omega_or_sigma . 's'} ) {
157 my @raw_omegas_or_sigmas = @
{$self -> {'raw_' . $omega_or_sigma . 's'}};
158 # If the omega or sigma matrix has no offdiagonal elements, the
159 # transformation is quite straightforward.
160 if( $self -> { $omega_or_sigma . '_block_structure_type'} eq 'DIAGONAL' ){
162 # All diagonal omegas or sigmas will be in
163 # @raw_omegas_or_sigmas, so we loop over it and take the square
164 # root of non-negative, non-zero numbers (those become
167 for( my $i = 0; $i <= $#raw_omegas_or_sigmas; $i+=$row_size ){
168 my $omega_or_sigma_value = sqrt( $raw_omegas_or_sigmas[$i] );
169 push( @
{$self -> {'c' . $omega_or_sigma .'s'}}, $omega_or_sigma_value );
173 } elsif( $self -> {$omega_or_sigma . '_block_structure_type'} eq 'BLOCK' ) {
175 # If the omega or sigma matrix has block form, the transformation
176 # becomes a bit more complex. The transformation for diagonal
177 # elements is the same. But for offdiagonals it takes more into
180 # $current_row_size is the number of omegas or sigmas in the row
181 # in the matrix that we are currently transforming.
182 my $current_row_size = 1;
184 # $diagonal_index is the index in @raw_omegas_or_sigmas where the current
185 # on-diagonal omega or sigma we are transforming.
186 my $diagonal_index = 0;
188 # $y_idx is the y-coordinate of the element in the matrix we
192 # First get all block sets sorted.
193 my @keys = sort {$a <=> $b} keys( %{$self -> { $omega_or_sigma . '_block_sets'}} );
194 # print Dumper \@keys;
195 # print Dumper $self -> { $omega_or_sigma . '_block_sets'};
196 foreach my $key ( @keys ) {
198 # If this is a block set $block_dimension will be > 1
199 # otherwise it will be 1.
200 my $block_dimension = $self -> { $omega_or_sigma . '_block_sets'}{$key}{'dimension'};
202 # The outer loop will be over the rows in the block
204 for( my $i = 0; $i < $block_dimension; $i ++ ){
206 # x_idx is the x-coordinate of the omega or sigma we are
209 my $x_idx = $current_row_size - $i;
210 # print "X: $x_idx, Y: $y_idx\n";
212 # The inner loop is over the row elements in the block set.
213 for( my $j = 0; $j <= $i; $j++ ){
215 # $omega_or_sigma will hold the transformed value.
216 my $omega_or_sigma_value;
218 if( $x_idx == $y_idx ) {
220 # If we are on the diagonal, just take the square root
221 # of the diagonal element.
222 $omega_or_sigma_value = $raw_omegas_or_sigmas[ $diagonal_index ];
223 $omega_or_sigma_value = sqrt( $omega_or_sigma_value );
226 # If we are of the diagonal, we need to find two
227 # on-diagonal omegas, one on the same column and one on
230 # The equation y*(y+1)/2 is a geometric sum that gives
231 # the index of the diagonal element on row y in the
232 # compacted matrixarray @raw_omegas_or_sigmas. The equation
233 # x*(x+1)/2 gives the diagonal element on column x in
236 # We find the omega by finding the index of the diagonal
237 # element on row y and subtracting the the difference
238 # between the number of elements on the row ($i) and the
239 # number of elements we have transformed ($j).
241 $omega_or_sigma_value = $raw_omegas_or_sigmas[(($y_idx*($y_idx+1))/2)-1 - ($i - $j)];
242 my $denominator = $raw_omegas_or_sigmas[ (($x_idx*($x_idx+1))/2)-1 ]
244 $raw_omegas_or_sigmas[ (($y_idx*($y_idx+1))/2)-1 ];
245 if( $denominator <= 0 ){ # To avoiding division by zero
246 $omega_or_sigma_value = undef;
247 } elsif( $omega_or_sigma_value >= sqrt($denominator) ) {
248 # This rounding handles cases when the offdiagonals
249 # are greater or equal to one.
250 $omega_or_sigma_value = $omega_or_sigma_value/( int( 10000 * sqrt($denominator) )/10000 )
252 $omega_or_sigma_value = $omega_or_sigma_value/sqrt($denominator);
255 push( @
{$self -> {'c' . $omega_or_sigma . 's'}}, $omega_or_sigma_value );
257 # Move the x-coordinate forwards.
261 # Move the y-coordinate forwards.
263 # Calculate the new row size.
264 $current_row_size ++;
265 # Skip one row and we get the index of the next diagonal.
267 $diagonal_index += $current_row_size;
271 'debug' -> warn( level
=> 1,
272 message
=> $omega_or_sigma . ' matrix has unknown form.' );
276 end _compute_comegas_or_csigmas
278 # }}} _compute_comegas_or_sigmas
280 # {{{ _compute_comegas
281 start _compute_comegas
283 $self -> _compute_comegas_or_csigmas
( omega_or_sigma
=> 'omega' );
287 # This is the old algoritm for transforming omegas. It can't handle
288 # of-diagonals omegas that are zero, if that should ever happen.
292 # my @computed_omegas;
296 # @raw_omegas = @{$self -> {'raw_omegas'}};
297 # @computed_omegas = ();
299 # if( $self -> {'omega_structure_type'} eq 'DIAGONAL' ){
300 # @diags = @raw_omegas;
302 # ## Collect the diagonals
303 # foreach $i (0..$#raw_omegas) {
304 # if( $self -> _isdiagonal('index' => $i+1) ){
305 # push( @diags, $raw_omegas[$i] );
310 # foreach $i (0..$#raw_omegas){
311 # if($self -> _isdiagonal('index' => $i+1)) {
312 # if( $raw_omegas[$i] <= 0 ){
313 # push( @computed_omegas, $raw_omegas[$i] );
316 # push @computed_omegas, sqrt($raw_omegas[$i]);
319 # @indices = $self -> _rowcolind( index => $i+1 );
320 # if( ($raw_omegas[$i] == 0) or ($diags[$indices[0]-1]*$diags[$indices[1]-1]) <= 0 ) {
323 # push @computed_omegas,
324 # $raw_omegas[$i]/sqrt($diags[$indices[0]-1]*$diags[$indices[1]-1]);
328 # $self -> {'comegas'}= \@computed_omegas;}
332 # {{{ _compute_csigmas
333 start _compute_csigmas
335 $self -> _compute_comegas_or_csigmas
( omega_or_sigma
=> 'sigma' );
338 # This is the old algoritm for transforming sigmass. It can't handle
339 # of-diagonals sigmass that are zero, if that should ever happen.
342 # if (defined $self -> {'raw_sigmas'} ) {
344 # my ( @om, @com, @diags, @indices );
345 # @om = @{$self -> {'raw_sigmas'}};
347 # ## Collect the diagonals
348 # foreach $i (0..$#om) {
349 # push @diags,$om[$i] if $self -> _isdiagonal('index' => $i+1);
351 # foreach $i (0..$#om){
352 # if($self -> _isdiagonal('index' => $i+1)) {
353 # if( $om[$i] <= 0 ){
356 # push @com, sqrt($om[$i]);
359 # @indices = $self -> _rowcolind( index => $i+1 );
360 # if( ($om[$i] == 0) or ($diags[$indices[0]-1]*$diags[$indices[1]-1] <= 0) ) {
364 # $om[$i]/sqrt($diags[$indices[0]-1]*$diags[$indices[1]-1]);
368 # $self -> {'csigmas'}= \@com;
372 # }}} _compute_csigmas
374 # {{{ _compute_cvseomega
376 start _compute_cvseomega
378 my @raw_omegas = @
{$self -> {'raw_omegas'}};
379 my @raw_seomegas = @
{$self -> {'raw_seomegas'}};
382 if ( scalar @raw_seomegas > 0) {
384 my ( @init_om, @init_seom );
386 foreach $i (0.. $#raw_seomegas){
387 if( $self -> _isdiagonal
('index' => $i+1)) {
388 push @init_seom, $raw_seomegas[$i];
391 if(($raw_seomegas[$i] eq 'NA') or ($raw_seomegas[$i] == 0)) {
394 push @init_seom, $raw_seomegas[$i];
399 foreach $i (0..$#raw_omegas){
400 if( $self -> _isdiagonal
('index' => $i+1)) {
401 push @init_om, $raw_omegas[$i];
404 if($raw_omegas[$i] == 0) {
407 push @init_om, $raw_omegas[$i];
412 foreach my $i (0..$#init_om) {
413 if( $init_seom[$i] ne 'NA' and $init_om[$i] ne 'NA' ){
414 push @cvseomega,$init_seom[$i]/abs($init_om[$i]);
416 push @cvseomega,undef;
418 # push @cvseomega,$init_seom[$i]/$init_om[$i]
419 # if ($init_seom[$i] && $init_om[$i]);
420 # push @cvseomega,"NA" unless ($init_seom[$i] && $init_om[$i]);
425 $self -> {'cvseomegas'} = [@cvseomega];
427 end _compute_cvseomega
429 # }}} _compute_cvseomega
431 # {{{ _compute_cvsesigma
432 start _compute_cvsesigma
434 my @raw_sigmas = @
{$self -> {'raw_sigmas'}};
435 my @raw_sesigmas = @
{$self -> {'raw_sesigmas'}};
438 if ( scalar @raw_sesigmas > 0) {
440 my ( @init_si, @init_sesi );
442 foreach $i (0.. $#raw_sesigmas){
443 if($self -> _isdiagonal
('index' => $i+1)) {
444 push @init_sesi, $raw_sesigmas[$i];
447 if(($raw_sesigmas[$i] eq 'NA') or ($raw_sesigmas[$i] == 0)) {
450 push @init_sesi, $raw_sesigmas[$i];
455 foreach $i (0.. $#raw_sigmas){
456 if($self -> _isdiagonal
('index' => $i+1)) {
457 push @init_si, $raw_sigmas[$i];
460 if($raw_sigmas[$i] == 0) {
463 push @init_si, $raw_sigmas[$i];
468 foreach my $i (0..$#init_si) {
469 if( $init_sesi[$i] ne 'NA' and $init_si[$i] ne 'NA' ){
470 push @cvsesigma,$init_sesi[$i]/abs($init_si[$i]);
472 push @cvsesigma,undef;
478 $self -> {'cvsesigmas'}= [@cvsesigma];
480 end _compute_cvsesigma
481 # }}} _compute_cvsesigma
483 # {{{ _compute_cvsetheta
484 start _compute_cvsetheta
486 my @thetas = @
{$self -> {'thetas'}};
487 my @sethetas = @
{$self -> {'sethetas'}};
490 if ( scalar @sethetas > 0 ) {
491 foreach my $i (0..$#thetas) {
492 push @cvsethetas,$sethetas[$i]/abs($thetas[$i])
493 if ($sethetas[$i] && $thetas[$i]);
494 push @cvsethetas,"NA" unless ($sethetas[$i] && $thetas[$i]);
498 $self -> {'cvsethetas'}= [@cvsethetas];
500 end _compute_cvsetheta
501 # }}} _compute_cvsetheta
508 return(1) if $index == 1;
509 foreach my $j (2..100) {
510 return(1) if $index == $previ+$j;
512 last if $index < $previ;
518 # {{{ _read_matrixoestimates
519 start _read_matrixoestimates
521 # Reads one matrix structure and returns the file handle at
522 # the beginning of the next structure
523 while ( $_ = @
{$self -> {'lstfile'}}[ $pos++ ] ) {
525 # Rewind one step if we find something that marks the end of
527 $pos-- and last if ( /^ PROBLEM.*SUBPROBLEM/ or /^ PROBLEM NO\.:\s+\d/ );
528 $pos-- and last if (/^[a-df-zA-DF-Z]/);
530 next if ( /^\s+TH/ or /^\s+OM/ or /^\s+SG/ ); # Header row
531 next if ( /^1/ ); # Those annoying 1's
533 chomp; # Get rid of line-feed
535 shift( @row ) if ( $row[0] eq '+' ); # Get rid of +-sign
537 next if ( $#row < 0 ); # Blank row
539 push( @subprob_matrix, @row );
541 $success = 1 if( scalar @subprob_matrix > 0 );
543 end _read_matrixoestimates
544 # }}} _read_matrixoestimates
546 # {{{ _read_covmatrix
547 start _read_covmatrix
550 my ( $t_success, $c_success, $corr_success, $i_success ) = (0,0,0,0);
551 my $start_pos = $self -> {'lstfile_pos'}-1;
557 my @matrix = @
{$m_ref};
558 # get rid of '........'
560 foreach ( @matrix ) {
561 push( @clear, $_ ) unless ( $_ eq '.........' );
563 # print Dumper \@clear;
569 # {{{ sub make square
573 my @matrix = @
{$m_ref};
574 # Make the matrix square:
575 my $elements = scalar @matrix; # = M*(M+1)/2
576 my $M = -0.5 + sqrt( 0.25 + 2 * $elements );
578 for ( my $m = 1; $m <= $M; $m++ ) {
579 for ( my $n = 1; $n <= $m; $n++ ) {
580 push( @
{$square[$m-1]}, $matrix[($m-1)*$m/2 + $n - 1] );
581 unless ( $m == $n ) {
582 push( @
{$square[$n-1]}, $matrix[($m-1)*$m/2 + $n - 1] );
591 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
593 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
594 if (/^ TH (\d)/ or /^\s+TH (\d) \| /) { # Read matrix and get out of inner while loop
595 ( $start_pos, $self -> {'raw_tmatrix'}, $t_success ) = $self ->
596 _read_matrixoestimates
( pos => $start_pos ) and last;
599 last; # No covariance matrix will be found!
601 if (/ COVARIANCE MATRIX OF ESTIMATE/) {
602 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
603 if (/^ TH (\d)/ or /^\s+TH (\d) \| /) { # Read matrix and get out of inner while loop
604 ( $start_pos, $self -> {'raw_covmatrix'}, $c_success ) = $self ->
605 _read_matrixoestimates
( pos => $start_pos ) and last;
609 if (/ CORRELATION MATRIX OF ESTIMATE/) {
610 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
611 if (/^ TH (\d)/ or /^\s+TH (\d) \| /) { # Read matrix and get out of inner while loop
612 ( $start_pos, $self -> {'raw_cormatrix'}, $corr_success ) = $self ->
613 _read_matrixoestimates
( pos => $start_pos ) and last;
617 if (/ INVERSE COVARIANCE MATRIX OF ESTIMATE/) {
618 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
619 if (/^ TH (\d)/ or /^\s+TH (\d) \| /) { # Read matrix and get out of inner while loop
620 ( $start_pos, $self -> {'raw_invcovmatrix'}, $i_success ) = $self ->
621 _read_matrixoestimates
( pos => $start_pos ) and last;
627 foreach my $element ( @
{$self -> {'raw_tmatrix'}} ) {
628 push( @
{$self -> {'t_matrix'}}, eval($element) ) unless ( $element eq '.........' );
630 foreach my $element ( @
{$self -> {'raw_covmatrix'}} ) {
631 push( @
{$self -> {'covariance_matrix'}}, eval($element) ) unless ( $element eq '.........' );
633 foreach my $element ( @
{$self -> {'raw_cormatrix'}} ) {
634 push( @
{$self -> {'correlation_matrix'}}, eval($element) ) unless ( $element eq '.........' );
637 if( defined $self -> {'raw_invcovmatrix'} ) {
638 $self -> {'inverse_covariance_matrix'} = Math
::MatrixReal
->
639 new_from_cols
( make_square
( clear_dots
( $self -> {'raw_invcovmatrix'} ) ) );
642 # foreach my $element ( @{$self -> {'raw_invcovmatrix'}} ) {
643 # push( @{$self -> {'inverse_covariance_matrix'}}, eval($element) ) unless ( $element eq '.........' );
646 #If something has gone right!
647 $self-> {'lstfile_pos'} = $start_pos if ( $t_success + $c_success + $corr_success + $i_success );
650 # }}} _read_covmatrix
657 my $start_pos = $self -> {'lstfile_pos'};
659 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
661 if ( /EIGENVALUES OF COR MATRIX OF ESTIMATE/ ) {
663 $start_pos = $start_pos + 4 ; # Jump forward to the index numbers
664 debug
-> warn( level
=> 2,
665 message
=> "Found the eigenvalue area" );
666 INNER
: while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) { # Get rid of indexes
667 last INNER
if ( not /^\s+\d/ );
668 # $start_pos++ and last INNER if ( not /^\s+\d/ );
672 $start_pos-- and last if (/^[a-df-zA-DF-Z]/); #Rewind one step
673 last if ( /^\s*\*/ or /^1/ );
674 push( @eigens, split );
676 $start_pos-- and last if ( /^ PROBLEM.*SUBPROBLEM/ or /^ PROBLEM NO\.:\s+\d/ );
677 $start_pos-- and last if (/^[a-df-zA-DF-Z]/); #Rewind one step
679 if ( scalar @eigens > 0 ) {
680 my @list = sort { $a <=> $b } @eigens;
681 $self -> {'condition_number'} = abs($list[$#list]/$list[0]) if ( $list[0] != 0 );
683 @
{$self -> {'eigens'}} = @eigens;
692 my $start_pos = $self -> {'lstfile_pos'};
695 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
696 if ( /MINIMUM VALUE OF OBJECTIVE FUNCTION/ or
697 / NO. OF SIG. DIGITS IN FINAL EST./){
698 debug
-> warn( level
=> 2,
699 message
=> "Hmmm, we have gone too far" );
702 if ( / NO. OF FUNCTION EVALUATIONS USED:\s*(\d*)/ ){
703 $self -> {'feval'} = $1;
708 unless ( $success ) {
709 debug
-> warn( level
=> 2,
710 message
=> "rewinding to first position..." );
712 debug
-> warn( level
=> 2,
713 message
=> "Found number of Function evaluations" );
714 $self -> {'lstfile_pos'} = $start_pos;
720 # {{{ _read_iteration_path
721 start _read_iteration_path
723 my $start_pos = $self -> {'lstfile_pos'};
725 my (@func_eval, @parameter_vectors,
726 @gradient_vectors) = ((), (), (), (), ());
728 my $cumulative_evals = 0;
729 my $zero_gradients = 0;
730 my $hessian_reset = 0;
731 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) { #Large reading loop
732 if (/^0ITERATION NO/) {
733 debug
-> die( message
=> "Error in reading iteration path!\n$!" )
734 unless (/0ITERATION NO\.:\s+(\d+)\s+OBJECTIVE VALUE:\s+(\S+)\s+NO\. OF FUNC\. EVALS\.:\s*(.+)/);
736 push(@
{$self -> {'iternum'}}, $1);
739 unless( $ofvpath eq '**' ){ # If funcion evals are more than 10000, NONMEM will print out two stars.
740 push(@
{$self -> {'ofvpath'}}, $ofvpath );
741 } # If, in fact, we find stars, the number of evaluations are calculated below
743 my (@parameter_vector, @gradient_vector) = ((), ());
745 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos ] ) {
746 if (/^ CUMULATIVE NO\. OF FUNC\. EVALS\.:\s*(\d+)/) {
749 if( $ofvpath eq '**' ){
750 my $ofvpath = $eval_path - $cumulative_evals;
751 $cumulative_evals = $eval_path;
752 debug
-> warn( level
=> 2,
753 message
=> "Calculated eval_path = $ofvpath" );
754 push(@
{$self -> {'ofvpath'}}, $ofvpath );
757 push(@
{$self -> {'funcevalpath'}}, $eval_path);
759 if (/RESET HESSIAN, TYPE (\w+)/) {
764 } elsif ( s/^ PARAMETER:\s*// ) {
766 push(@parameter_vector, split);
767 $_ = @
{$self -> {'lstfile'}}[ ++$start_pos ];
768 } while ( defined($_) and not /^ GRADIENT:\s*/ );
769 } elsif (s/^ GRADIENT:\s*//) {
771 push(@gradient_vector, split);
772 $_ = @
{$self -> {'lstfile'}}[ ++$start_pos ]
773 } while ( defined($_) and not /[A-D][F-X]/ );
778 foreach my $grad ( @gradient_vector ) {
779 $zero_gradients++ if $grad == 0;
781 $self -> {'initgrad'} = \
@gradient_vector unless($self -> {'initgrad'});
782 $self -> {'final_gradients'} = \
@gradient_vector;
783 $self -> {'finalparam'} = \
@parameter_vector;
784 push(@parameter_vectors, \
@parameter_vector);
785 push(@gradient_vectors, \
@gradient_vector);
787 last unless(/^0ITERATION NO/);
788 } #End of if iteration no
789 } #End of large reading loop
791 my ($kill_found, $file_end, $kill_message, $search_pos) = (0, 0, "", $start_pos);
792 while ( $_ = @
{$self -> {'lstfile'}}[ $search_pos++ ] ) { #Have a look, a few lines down...
798 # $kill_found = 1 and $kill_message = $_ and last if(/kill/i);
799 if( $search_pos + 1 == scalar @
{$self -> {'lstfile'}} ) {
801 $search_pos = $start_pos + 4;
803 last if( $search_pos > $start_pos + 3 )
804 # last if (--$kill_found < -2);
806 if (($kill_found == 1) or $file_end) { #Crash before last iteration
807 $self -> {'minimization_message'} = ["PsN message:","The output file seems to have an abrupt ending," .
808 " before the last","iteration has finished."];
809 if ($kill_found == 1) {
810 push(@
{$self -> {'minimization_message'}}, "String found in output file: $kill_message" );
812 push(@
{$self -> {'minimization_message'}}, " This is probably due to a crash");
817 debug
-> warn( level
=> 2,
818 message
=> "rewinding to first position..." );
820 $self -> {'lstfile_pos'} = $start_pos;
821 $self -> {'parameter_path'} = \
@parameter_vectors;
822 $self -> {'gradient_path'} = \
@gradient_vectors;
823 $self -> {'zero_gradients'} = $zero_gradients;
824 my $final_zero_gradients = 0;
825 foreach my $grad ( @
{$self -> {'final_gradients'}} ) {
826 $final_zero_gradients++ if $grad == 0;
828 $self -> {'final_zero_gradients'} = $final_zero_gradients;
829 $self -> {'hessian_reset'} = $hessian_reset;
832 end _read_iteration_path
833 # }}} _read_iteration_path
839 my $start_pos = $self -> {'lstfile_pos'};
843 my $npetabararea = 0;
845 my ( @npetabar, @npomega, @T, $i );
847 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
848 $nparea = 1 if /NONPARAMETRIC ESTIMATE/;
849 last if ( /THERE ARE ERROR MESSAGES IN FILE PRDERR/ and $nparea );
850 last if ( /^1/ and $nparea );
851 last if ( /^1NONLINEAR/ and $nparea );
852 last if ( /^[A-W]/ and $nparea );
854 if (/MINIMUM VALUE OF OBJECTIVE FUNCTION/ and $nparea ){ #Only nonmem6 version
857 if ( /EXPECTED VALUE OF ETA/ and $nparea ) {
862 if ( /COVARIANCE MATRIX OF ETA/ and $nparea ) {
866 if($npofvarea and /^\s+(-?\d*\.\d*)/) { #Assignment of attribute at the spot
867 $self -> {'npofv'} = $1;
870 if($npetabararea and /^\s*-?\d*\.\d*/) {
872 for $i (0..(@T-1)) {$T[$i] = eval($T[$i]);}
875 if($npomegarea and /^(\+|\s{2,})/) {
878 shift @T if $T[0] eq '+';
879 for $i (0..(@T-1)) {$T[$i] = eval($T[$i]);}
883 $self -> {'npetabar'} = [@npetabar];
884 $self -> {'npomegas'} = [@npomega];
885 unless ( $success ) {
886 debug
-> warn( level
=> 2,
887 message
=> "rewinding to first position..." );
889 $self -> {'lstfile_pos'} = $start_pos;
891 # print Dumper $self -> {'npomegas'};
892 # print Dumper $self -> {'npetabar'};
902 my $start_pos = $self -> {'lstfile_pos'};
905 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
906 if ( /^\s\*{50}\s+/ ) {
907 (undef, my $ofvt, undef) = split(' ',$_,3);
908 if ( $ofvt =~ /\*\*\*\*\*\*/ ) {
909 $self -> {'ofv'} = undef;
911 $self -> {'ofv'} = $ofvt;
913 debug
-> warn( level
=> 2,
914 message
=> "OFV = $ofvt" );
919 unless ( $success ) {
920 debug
-> warn( level
=> 2,
921 message
=> "rewinding to first position..." );
923 debug
-> warn( level
=> 2,
924 message
=> "Found ofv" );
925 $self -> {'lstfile_pos'} = $start_pos;
937 while ( not $found ) {
938 my $test = $index - ($i-1)*($i)/2;
947 # my @startind = (2,5,9,14,20,27,35,44);
951 # OUTER: foreach $col (1..8) {
952 # $prevind = $startind[$col-1];
953 # foreach $row (($col+1)..8) {
955 # ## If this is the first element of the column
956 # if($index == $prevind) {
960 # ## If it is a later element in the column
961 # if($index == $prevind+$row) {
962 # # print "$index $col ",$row+1," ",$startind[$col-1],"\n" ;
966 # $prevind = $prevind+$row;
971 # print "$index ",$row," $col\n";
977 # {{{ _read_significant_digits
978 start _read_significant_digits
980 my $start_pos = $self -> {'lstfile_pos'};
983 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
984 if ( /MINIMUM VALUE OF OBJECTIVE FUNCTION/ ){
987 if ( / NO. OF SIG. DIGITS IN FINAL EST.:\s*(-?\d*\.*\d*)/ ){
988 $self -> {'significant_digits'} = $1;
993 unless ( $success ) {
994 debug
-> warn( level
=> 2,
995 message
=> "No Number of Significant digits found" );
997 debug
-> warn( level
=> 2,
998 message
=> "Found significant_digits" );
999 $self -> {'lstfile_pos'} = $start_pos;
1002 end _read_significant_digits
1003 # }}} _read_significant_digits
1005 # {{{ _read_sethomsi
1006 start _read_sethomsi
1008 my $start_pos = $self -> {'lstfile_pos'};
1015 my ( @setheta, @seomega, @sesigma, @T, $i, $tmp );
1016 my ( @raw_setheta, @raw_seomega, @raw_sesigma );
1017 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
1019 $searea = 1 if /STANDARD ERROR OF ESTIMATE/;
1021 if ( /THETA - VECTOR OF FIXED EFFECTS PARAMETERS/ ) {
1022 debug
-> warn( level
=> 2,
1023 message
=> "Found standard erros of thetas" );
1027 if ( /OMEGA - COV MATRIX FOR RANDOM EFFECTS - ETAS/ ) {
1028 debug
-> warn( level
=> 2,
1029 message
=> "Found standard erros of omega" );
1033 if ( /SIGMA - COV MATRIX FOR RANDOM EFFECTS - EPSILONS/ ) {
1034 debug
-> warn( level
=> 2,
1035 message
=> "Found standard erros of sigmas" );
1040 last if ( / COVARIANCE MATRIX OF ESTIMATE/ );
1041 last if ( /THERE ARE ERROR MESSAGES IN FILE PRDERR/ );
1042 # The row below checking for a one '1', crashes behaviour with MANY etas (>15)
1044 last if ( /^[A-W]/ and $searea );
1045 if ( $thetarea and /^\s*-?\d*\.\d*/ ) {
1047 for $i (0..(@T-1)) {
1048 $T[$i] = eval($T[$i]);
1052 if($omegarea and /^(\+|\s{2,})/) {
1055 shift @T if $T[0] eq '+';
1056 if ( not defined $self -> {'omega_block_structure'} ) {
1057 for $i (0..(@T-1)) {
1058 if(($T[$i] ne '.........') and (eval($T[$i]) != 0) ) {
1059 push(@seomega,eval($T[$i]));
1063 for $i (0..(@T-1)) {
1064 if($T[$i] ne '.........') {
1065 $tmp = eval($T[$i]);
1071 push(@raw_seomega,@T);
1073 if($sigmarea and /^(\+|\s{2,})/) {
1076 shift @T if $T[0] eq '+';
1077 if ( not defined $self -> {'sigma_block_structure'} ) {
1078 for $i (0..(@T-1)) {
1079 if(($T[$i] ne '.........') and (eval($T[$i]) != 0) ) {
1080 push(@sesigma,eval($T[$i]));
1084 for $i (0..(@T-1)) {
1085 if ($T[$i] ne '.........') {
1086 $tmp = eval($T[$i]);
1092 push(@raw_sesigma,@T);
1098 if ( defined $self -> {'omega_block_structure'} ) {
1099 my @omblock = @
{$self -> {'omega_block_structure'}};
1100 debug
-> warn( level
=> 2,
1101 message
=> "OMEGA BLOCK DEFINED" ) if ( scalar @omblock > 0 );
1104 foreach my $row ( @omblock ) {
1105 foreach my $element ( @
{$row} ) {
1106 push ( @seomega, $raw_seomega[$i] ) if ( $element );
1112 if ( defined $self -> {'sigma_block_structure'} ) {
1113 my @siblock = @
{$self -> {'sigma_block_structure'}};
1116 debug
-> warn( level
=> 2,
1117 message
=> "SIGMA BLOCK DEFINED" ) if ( scalar @siblock > 0 );
1118 foreach my $row ( @siblock ) {
1119 foreach my $element ( @
{$row} ) {
1120 push ( @sesigma, $raw_sesigma[$i] ) if ( $element );
1126 $self -> {'sethetas'} = [@setheta];
1127 $self -> {'raw_seomegas'} = [@raw_seomega];
1128 $self -> {'raw_sesigmas'} = [@raw_sesigma];
1129 $self -> {'seomegas'} = [@seomega];
1130 $self -> {'sesigmas'} = [@sesigma];
1132 if ( scalar @setheta <= 0 ) {
1133 $self -> {'covariance_step_successful'} = 0;
1135 $self -> {'covariance_step_successful'} = 1;
1138 unless ( $success ) {
1139 debug
-> warn( level
=> 2,
1140 message
=> "No standard errors for thetas, sigmas or omegas." );
1142 $self -> {'lstfile_pos'} = $start_pos;
1146 # }}} _read_sethomsi
1148 # {{{ _read_simulation
1149 start _read_simulation
1151 my $start_pos = $self -> {'lstfile_pos'};
1152 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos ++ ] ) {
1153 if ( /MINIMUM VALUE OF OBJECTIVE FUNCTION/ ) {
1156 if ( /^\s*MONITORING OF SEARCH:/) {
1159 if ( /\s*SIMULATION STEP PERFORMED/ ) {
1160 $self ->{'simulationstep'} = 1;
1165 if ( $self -> {'simulationstep'} ) {
1166 $self -> {'lstfile_pos'} = $start_pos;
1169 end _read_simulation
1170 # }}} _read_simulation
1176 my $start_pos = $self -> {'lstfile_pos'};
1180 $self -> {'minimization_successful'} = 0;
1181 if ( $self -> {'covariance_step_run'} ) {
1182 $self -> {'covariance_step_successful'} = 1;
1183 # If there are problems in the cov-step they will be caught later
1185 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
1186 $self -> {'s_matrix_singular'} = 1 if ( /^0S MATRIX ALGORITHMICALLY SINGULAR/ );
1187 if ( /^0R MATRIX ALGORITHMICALLY SINGULAR/ or
1188 /^0S MATRIX ALGORITHMICALLY SINGULAR/ ) {
1189 $self -> {'covariance_step_warnings'} = 1;
1192 if ( /^0ESTIMATE OF THETA IS NEAR THE BOUNDARY AND/ or
1193 /0PARAMETER ESTIMATE IS NEAR ITS BOUNDARY/ ) {
1194 $self -> {'estimate_near_boundary'} = 1;
1196 if ( /ROUNDING ERRORS/ ) {
1197 $self -> {'rounding_errors'} = 1;
1199 if ( /0COVARIANCE STEP ABORTED/ ) {
1200 $self -> {'covariance_step_successful'} = 0;
1203 if ( /^0MINIMIZATION SUCCESSFUL/ ) {
1204 $self -> {'minimization_successful'} = 1;
1207 if ( /MINIMUM VALUE OF OBJECTIVE FUNCTION/ ) {
1208 debug
-> warn( level
=> 2,
1209 message
=> "Hmmm, reached the OFV area" );
1212 $success_pos = $start_pos unless ( $success );
1215 debug
-> warn( level
=> 2,
1216 message
=> "Found a minimization statement" );
1217 $self -> {'lstfile_pos'} = $success_pos; #Back to successline.
1219 debug
-> warn( level
=> 2,
1220 message
=> "No minimization statement found" ); #Back to starting line
1227 # {{{ _read_minimization_message
1229 start _read_minimization_message
1232 my (@mess, @etabar,@pval);
1235 my $start_pos = $self -> {'lstfile_pos'};
1236 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
1237 if ( /^ PROBLEM NO\.:\s*\d+\s*SUBPROBLEM NO\.:\s*(\d+)/) {
1238 last unless ($1 == 1); #Continuition of the same subproblem
1240 last if ( / PROBLEM NO\.:\s*\d+\n/);
1241 if ( not $termarea and ( /(^0MINIMIZATION.*$)/ or /(^0PROGRAM TERMINATED.*$)/ ) ) {
1243 my $tmp = $self -> {'lstfile_pos'};
1244 debug
-> warn( level
=> 2,
1245 message
=> "Setting firstpos from $tmp to $start_pos" );
1246 $self -> {'lstfile_pos'} = $start_pos;
1247 $tmp = $self -> {'lstfile_pos'};
1248 debug
-> warn( level
=> 2,
1249 message
=> "0MINIMIZATION found! and firstpos is: $tmp" );
1251 if ( $termarea and /^1/ ) {
1252 debug
-> warn( level
=> 2,
1253 message
=> "Found minimization area and reached the \'\^1\'" );
1255 $start_pos = $self -> {'lstfile_pos'};
1259 if ( /MINIMUM VALUE OF OBJECTIVE FUNCTION/ ) {
1260 debug
-> warn( level
=> 2,
1261 message
=> "Hmmm, reached the OFV area" );
1269 push( @
{$self -> {'minimization_message'}}, @mess );
1271 # if ( $self -> {'minimization_message'} ) { # PsN message in sub _read_iteration_path
1272 # $self -> {'minimization_message'} .= join "", @mess;
1274 # $self -> {'minimization_message'} = join "", @mess;
1279 if (s/\s+ETABAR:\s+//) {
1281 push @etabar, @temp;
1282 # print "Etabar Push of: $_ \n";
1283 for (@mess) { #If wrapped etabar-lines
1285 last if(/a-zA-DF-Z/);
1286 last unless (s/^\s+//);
1289 push @etabar, @temp;
1294 # Initialize the attribute only if we have found any data
1295 $self -> {'etabar'} = \
@etabar if ( $#etabar > 0 );
1299 if (s/\s+P VAL\.:\s+//) {
1302 # print "Pval Push of: $_ \n";
1303 for (@mess) { #If wrapped etabar-lines
1305 last if(/a-zA-DF-Z/);
1306 last unless (s/^\s+//);
1314 $self -> {'pval'} = \
@pval;
1316 unless ( $success ) {
1317 debug
-> warn( level
=> 2,
1318 message
=> "No minimization message found" );
1320 $self -> {'lstfile_pos'} = $start_pos;
1323 end _read_minimization_message
1325 # }}} _read_minimization_message
1331 my $start_pos = $self -> {'lstfile_pos'};
1338 my ( @theta, @omega, @raw_omega, @sigma, @raw_sigma, @T, $i, $tmp );
1340 while ( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
1342 $estarea = 1 if /FINAL PARAMETER ESTIMATE/;
1343 last if ( /STANDARD ERROR OF ESTIMATE/ and $estarea );
1344 last if ( /^1NONLINEAR/ and $estarea );
1345 if ( /THETA - VECTOR OF FIXED EFFECTS PARAMETERS/ and $estarea ) {
1346 debug
-> warn( level
=> 2,
1347 message
=> "Found the theta estimates area" );
1351 if ( /OMEGA - COV MATRIX FOR RANDOM EFFECTS - ETAS/ and $estarea ) {
1352 debug
-> warn( level
=> 2,
1353 message
=> "Found the omega estimates area" );
1358 if ( /SIGMA - COV MATRIX FOR RANDOM EFFECTS - EPSILONS/ and $estarea ) {
1359 debug
-> warn( level
=> 2,
1360 message
=> "Found the sigma estimates area" );
1365 last if ( /THERE ARE ERROR MESSAGES IN FILE PRDERR/ and $estarea );
1366 # The row below checking for a one '1', crashes behaviour with MANY etas (>15)
1367 # last if ( /^1/ and $estarea );
1368 last if ( /^\s+\*\*\*\*\*\*\*\*\*\*\*\*/ and ( $sigmarea or $thetarea or $omegarea ));
1369 last if ( /^[A-W]/ and $estarea );
1371 if( $thetarea and /^\s*-?\d*\.\d*/ ) {
1373 for $i (0..(@T-1)) {
1374 $T[$i] = eval($T[$i]);
1379 if($omegarea and /^(\+|\s{2,})/) {
1382 shift @T if $T[0] eq '+';
1383 if ( $self -> {'omega_block_structure_type'} eq 'DIAGONAL' ) {
1384 for $i (0..(@T-1)) {
1385 if(($T[$i] ne '.........') and (eval($T[$i]) != 0) ) {
1386 push(@omega,eval($T[$i]));
1390 for $i (0..(@T-1)) {
1391 if($T[$i] ne '.........') {
1392 $tmp = eval($T[$i]);
1398 push(@raw_omega,@T);
1401 if($sigmarea and /^(\+|\s{2,})/) {
1405 shift @T if $T[0] eq '+';
1406 if ( $self -> {'sigma_block_structure_type'} eq 'DIAGONAL' ) {
1407 for $i (0..(@T-1)) {
1408 if(($T[$i] ne '.........') and (eval($T[$i]) != 0) ) {
1409 push(@sigma,eval($T[$i]));
1413 for $i (0..(@T-1)) {
1414 if($T[$i] ne '.........') {
1415 $tmp = eval($T[$i]);
1421 push(@raw_sigma,@T);
1426 if ( $self -> {'omega_block_structure_type'} eq 'BLOCK' ) {
1427 my @omblock = @
{$self -> {'omega_block_structure'}};
1428 debug
-> warn( level
=> 2,
1429 message
=> "OMEGA BLOCK DEFINED" ) if ( scalar @omblock > 0 );
1432 foreach my $row ( @omblock ) {
1433 foreach my $element ( @
{$row} ) {
1434 push ( @omega, $raw_omega[$i] ) if ( $element );
1440 if ( $self -> {'sigma_block_structure_type'} eq 'BLOCK' ) {
1441 my @omblock = @
{$self -> {'sigma_block_structure'}};
1442 debug
-> warn( level
=> 2,
1443 message
=> "SIGMA BLOCK DEFINED" ) if ( scalar @omblock > 0 );
1446 foreach my $row ( @omblock ) {
1447 foreach my $element ( @
{$row} ) {
1448 push ( @sigma, $raw_sigma[$i] ) if ( $element );
1454 $self -> {'thetas'} = \
@theta;
1455 $self -> {'nth'} = $#theta + 1;
1456 $self -> {'raw_omegas'} = \
@raw_omega;
1457 $self -> {'nrom'} = $#raw_omega + 1;
1458 $self -> {'omegas'} = \
@omega;
1459 $self -> {'nom'} = $#omega + 1;
1460 $self -> {'raw_sigmas'} = \
@raw_sigma;
1461 $self -> {'sigmas'} = \
@sigma;
1464 # Gather the "true" estimates, i.e. for the parameters that are not fixed or SAME.
1465 foreach my $param ( 'theta', 'omega', 'sigma' ) {
1466 my @allests = eval( '@'.$param );
1467 my @estflags = @
{$self -> {'estimated_'.$param.'s'}};
1470 # print Dumper \@allests;
1471 # print Dumper \@estflags;
1473 die "Something is wrong: All $param"."s: ".($#allests+1)." and estimated $param"."s: ".
1474 ($#estflags+1)." do not match\n" unless
1475 ( $#allests == -1 or $#estflags == $#allests );
1477 for( my $i = 0; $i <= $#allests; $i++ ) {
1478 if( $estflags[$i] ) {
1479 if ( defined $allests[$i] ) {
1480 push( @ests, $allests[$i]);
1487 $self -> {'est_'.$param.'s'} = \
@ests;
1489 # if( $#ests > -1 and $defs > 0 ) {
1490 # $self -> {'est_'.$param.'s'} = Math::MatrixReal ->
1491 # new_from_cols( [\@ests] );
1495 unless ( $success ) {
1496 debug
-> warn( level
=> 2,
1497 message
=> "No thetas, omegas or sigmas found" );
1500 # if ( $PsN::config -> {'_'} -> {'use_database'} and
1501 # $self -> {'register_in_database'} ) {
1502 # my $dbh = DBI -> connect("DBI:mysql:host=".$PsN::config -> {'_'} -> {'database_server'}.
1503 # ";databse=".$PsN::config -> {'_'} -> {'project'},
1504 # $PsN::config -> {'_'} -> {'user'},
1505 # $PsN::config -> {'_'} -> {'password'},
1506 # {'RaiseError' => 1});
1508 # my @mod_str = ('','');
1509 # if ( defined $self -> {'model_id'} ) {
1510 # @mod_str = ('model_id,',"$self->{'model_id'},");
1512 # foreach my $param ( 'theta', 'omega', 'sigma' ) {
1514 # foreach my $par_str ( eval('@'.$param) ) {
1515 # $sth = $dbh -> prepare("INSERT INTO ".$PsN::config -> {'_'} -> {'project'}.
1517 # "(subproblem_id,problem_id,output_id,".
1519 # "type,value, number, label) ".
1520 # "VALUES ( '$self->{'subproblem_id'}' ,".
1521 # "'$self->{'problem_id'}' ,".
1522 # "'$self->{'output_id'}' ,".
1524 # "'$param','$par_str', '$i', 'test_label')");
1526 # push( @{$self -> {'estimate_ids'}}, $sth->{'mysql_insertid'} );
1531 # $dbh -> disconnect;
1535 $self -> {'lstfile_pos'} = $start_pos-1;
1542 # {{{ _set_omeganames
1543 start _set_omeganames
1545 my @raw_omegas = @
{$self -> {'raw_omegas'}};
1547 unless ( scalar @raw_omegas > 0 ) {
1552 my ( @omeganames, %omeganameval, @omegas );
1555 foreach $j (1..scalar @raw_omegas) {
1556 push @omeganames, "OM".++$ndiags and next if $self -> _isdiagonal
('index' => $j);
1557 if ($raw_omegas[$j-1] !=0) {
1558 @indices = $self -> _rowcolind
( index => $j);
1559 push @omeganames,"OM".$indices[0]."\.".$indices[1];
1562 @omegas = @
{$self -> {'omegas'}};
1563 for ( my $i = 0; $i <= $#omeganames; $i++ ) {
1564 $omeganameval{$omeganames[$i]} = $omegas[$i];
1566 $self ->{'omeganameval'} = \
%omeganameval;
1567 $self ->{'omeganames'} = \
@omeganames;
1570 # }}} _set_omeganames
1572 # {{{ _set_sigmanames
1573 start _set_sigmanames
1575 my @sigmas = @
{$self -> {'raw_sigmas'}};
1576 unless ( scalar @sigmas > 0 ) {
1580 my ( @sigmanames, %sigmanameval );
1583 foreach $j (1..scalar @sigmas) {
1584 push @sigmanames, "SI".++$ndiags and next if $self -> _isdiagonal
('index' => $j);
1585 if ($sigmas[$j-1] !=0) {
1586 @indices = $self -> _rowcolind
( index => $j);
1587 push @sigmanames,"SI".$indices[0].$indices[1];
1590 @sigmas = @
{$self -> {'sigmas'}};
1591 for ( my $i = 0; $i <= $#sigmanames; $i++ ) {
1592 $sigmanameval{$sigmanames[$i]} = $sigmas[$i];
1594 $self ->{'sigmanameval'} = \
%sigmanameval;
1595 $self ->{'sigmanames'} = \
@sigmanames;
1598 # }}} _set_sigmanames
1600 # {{{ _set_thetanames
1601 start _set_thetanames
1603 my $nth = $self -> {'nth'};
1604 my ( @thetanames, %thetanameval, @thetas );
1607 push @thetanames, "TH$_";
1609 @thetas = @
{$self -> {'thetas'}};
1610 for ( my $i = 0; $i <= $#thetanames; $i++ ) {
1611 $thetanameval{$thetanames[$i]} = $thetas[$i];
1613 $self ->{'thetanameval'} = \
%thetanameval;
1614 $self ->{'thetanames'} = \
@thetanames;
1617 # }}} _set_thetanames