1 # Det finns ingen mening med att kunna specificera subproblem eftersom vi bara kan fixera
2 # parametervärden på problemnivå.
3 # Det finns dessutom lite värde i att kunna spec. problem eftersom vi än så länge inte kan
4 # köra problem var för sig via PsN och om man har flera problem i en modellfil så skulle
5 # alla köras även om man bara är intresserad av ett. Så man får helt enkelt editera
6 # modellfilen och ta bort onödiga problem.
10 start include statements
12 use ext
::Math
::SigFigs
;
17 # }}} include statements
23 my @various_input_formats = ( 'run_thetas', 'run_omegas', 'run_sigmas',
24 'rse_thetas', 'rse_omegas', 'rse_sigmas' );
25 foreach my $var ( @various_input_formats ) {
26 if ( defined $this -> {$var} ) {
27 if ( ref( $this -> {$var} ) eq 'ARRAY' and ref( $this -> {$var} -> [0] ) eq 'ARRAY' ) {
28 if ( scalar @
{$this -> {$var}} != scalar @
{$this -> {'models'}} ) {
29 debug
-> die( message
=> 'If you define the thetas per model, the first '.
30 'dimension of run_thetas must match the number of models' );
33 my $variable = $this -> {$var};
35 if ( scalar @
{$this -> {'models'}} > 1) {
36 for ( my $j = 1; $j <= scalar @
{$variable}; $j++ ) {
37 debug
-> warn( level
=> 2,
38 message
=> "All models: using the same $var $j" );
41 foreach my $model ( @
{$this -> {'models'}} ) {
42 push ( @
{$this -> {$var}}, $variable ) ;
44 foreach my $param ( 'theta', 'omega', 'sigma' ) {
45 if ( defined $this -> {$var} and defined $this -> {'rse_'.$param}
46 and $var eq 'rse_'.$param.'s' ) {
47 for ( my $i = 0; $i < scalar @
{$this -> {$var}}; $i++ ) {
48 debug
-> die( message
=> "The number of run_".$param."s (".
49 scalar @
{$this -> {'run_'.$param}[$i]}.
50 ") does not match the number of supplied ".$var.
51 " (".scalar @
{$this -> {$var}[$i]}.")" )
52 if ( not scalar @
{$this -> {'run_'.$param}[$i]} ==
53 scalar @
{$this -> {$var}[$i]} );
61 # First check if parameters are of BLOCK type, then we must adjust numbers.
62 # Then check if parameters are of SAME or FIX type, then we will print an ERROR!!
63 if( 0 ) { #-- PONTUS -- This is work in progress. Don't remove please -- PONTUS --
65 $run{'thetas'} = (ref( $this -> {'run_thetas'} -> [0] ) eq 'ARRAY') ?
66 $this -> {'run_thetas'} -> [0]:$this -> {'run_thetas'};
67 $run{'omegas'} = (ref( $this -> {'run_omegas'} -> [0] ) eq 'ARRAY') ?
68 $this -> {'run_omegas'} -> [0]:$this -> {'run_omegas'};
69 $run{'sigmas'} = (ref( $this -> {'run_sigmas'} -> [0] ) eq 'ARRAY') ?
70 $this -> {'run_sigmas'} -> [0]:$this -> {'run_sigmas'};
72 my $model = $this -> {'models'} -> [0];
74 # Loop over the parameters
75 foreach my $parameter_type ( keys %run ) {
76 # jump to next parameter if no parameter of this type should be run
77 next unless ( defined $run{$parameter_type} and
78 scalar @
{$run{$parameter_type}} > 0 and
79 $run{$parameter_type}->[0] ne '' );
81 my @parameter_numbers = @
{$run{$parameter_type}};
83 foreach my $parameter_number ( @parameter_numbers ){
85 if( defined( $model -> problems
-> [0] -> $parameter_type )) {
86 my $global_parameter_number = 0;
87 for( my $i = 0; $i < scalar @
{$model -> problems
-> [0] -> $parameter_type} ; $i++ ){
88 my $init_record = $model -> problems
-> [0] -> $parameter_type -> [$i];
89 unless( defined $init_record ){
90 debug
-> die( message
=> "The LLP tool can not be run on $parameter_type number $parameter_number because it does not exist.");
92 print "$parameter_type $init_record $parameter_number\n";
93 for( my $j = 0 ; $j < scalar @
{$init_record -> options
}; $j++ ){
94 if( $parameter_number - 1 == $global_parameter_number ){
95 if( $init_record -> same
){
96 debug
-> die( message
=> "The LLP tool can not be run on $parameter_type number $parameter_number because it is \"SAME\"" );
97 } elsif( $init_record -> fix
){
98 debug
-> die( message
=> "The LLP tool can not be run on $parameter_type number $parameter_number because it is \"FIX\"" );
101 $global_parameter_number ++;
109 foreach my $file ( 'logfile', 'unstacked_logfile', 'raw_results_file' ) {
110 if ( not( ref($this -> {$file}) eq 'ARRAY' or
111 ref($this -> {$file}) eq 'HASH' ) ) {
112 my ($ldir, $filename) = OSspecific
::absolute_path
( $this -> {'directory'},
114 $this -> {$file} = [];
115 for ( my $i = 1; $i <= scalar @
{$this -> {'models'}}; $i++ ) {
118 push ( @
{$this -> {$file}}, $ldir.$tmp ) ;
132 my $model = $self -> {'models'} -> [$model_number-1];
134 my $mfit_threads = ref( $self -> {'threads'} ) eq 'ARRAY' ?
135 $self -> {'threads'} -> [1]:$self -> {'threads'};
136 my $own_threads = ref( $self -> {'threads'} ) eq 'ARRAY' ?
137 $self -> {'threads'} -> [0]:$self -> {'threads'};
139 # Check which models that hasn't been run and run them
140 # This will be performed each step but will only result in running
141 # models at the first step, if at all.
143 # If more than one process is used, there is a VERY high risk of interaction
144 # between the processes when creating directories for model fits. Therefore
145 # the {'directory'} attribute is given explicitly below.
147 unless ( $model -> is_run
) {
149 # ----------------------- Run original run ------------------------------
154 if ( defined $self -> {'subtool_arguments'} ) {
155 %subargs = %{$self -> {'subtool_arguments'}};
157 my $orig_fit = tool
::modelfit
->
158 new
( reference_object
=> $self,
160 threads
=> $mfit_threads,
161 base_directory
=> $self -> {'directory'},
162 directory
=> $self -> {'directory'}.'/orig_modelfit_dir'.$model_number,
164 parent_threads
=> $own_threads,
165 parent_tool_id
=> $self -> {'tool_id'},
167 raw_results
=> undef,
168 prepared_models
=> undef,
170 # ( models => [$model],
173 # run_on_nordugrid => $self -> {'run_on_nordugrid'},
174 # cpu_time => $self -> {'cpu_time'},
176 # run_on_lsf => $self -> {'run_on_lsf'},
177 # no_remote_execution => $self -> {'no_remote_execution'},
178 # no_remote_compile => $self -> {'no_remote_compile'},
179 # lsf_queue => $self -> {'lsf_queue'},
180 # lsf_options => $self -> {'lsf_options'},
181 # lsf_job_name => $self -> {'lsf_job_name'},
182 # lsf_project_name => $self -> {'lsf_project_name'},
184 # clean => $self -> {'clean'},
185 # nm_version => $self -> {'nm_version'},
186 # picky => $self -> {'picky'},
187 # compress => $self -> {'compress'},
188 # threads => $mfit_threads,
189 # retries => $self -> {'retries'},
190 # remove_temp_files => $self -> {'remove_temp_files'},
191 # base_directory => $self -> {'directory'},
192 # directory => $self -> {'directory'}.'/orig_modelfit_dir'.$model_number.'/',
193 # parent_tool_id => $self -> {'tool_id'},
194 # parent_threads => $own_threads );
195 ui
-> print( category
=> 'llp',
196 message
=> "Evaluating basic model" ) unless $self -> {'parent_threads'} > 1;
205 unless ( defined $self -> {'theta_log'} or
206 defined $self -> {'omega_log'} or
207 defined $self -> {'sigma_log'} ) {
208 # First step, register the estimates from the original runs
209 debug
-> warn( level
=> 2,
210 message
=> "First llp step, register estimates from original run" );
211 $self -> _register_estimates
( first
=> 1,
212 model_number
=> $model_number);
216 # If we are resuming, there should exist a 'done' file
218 if ( -e
$self -> {'directory'}.'/m'.$model_number."/done" ) {
219 # Recreate the datasets and models from a checkpoint
223 # Make new guesses for the parameter values
224 $self -> _make_new_guess
( first
=> $first,
225 model_number
=> $model_number,
228 # Construct new models for this step from the observed OFV's from the
230 # They should be placed in m1, m2 and so on for each model.
231 $self -> {'prepared_models'} =
232 $self -> _create_models
( model_number
=> $model_number,
235 # --------------------- Create the modelfit -------------------------------
239 if( defined $self -> {'prepared_models'} and scalar @
{$self -> {'prepared_models'}} > 0 ) {
240 # Create a modelfit tool for all the models of this step.
241 # This is the last setup part before running the step.
243 if ( defined $self -> {'subtool_arguments'} ) {
244 %subargs = %{$self -> {'subtool_arguments'}};
246 push( @
{$self -> {'tools'}},
248 new
( reference_object
=> $self,
249 models
=> $self -> {'prepared_models'},
250 threads
=> $mfit_threads,
251 base_directory
=> $self -> {'directory'},
252 directory
=> $self -> {'directory'}.'/modelfit_dir'.$model_number,
253 _raw_results_callback
=> $self -> _modelfit_raw_results_callback
,
255 parent_threads
=> $own_threads,
256 parent_tool_id
=> $self -> {'tool_id'},
257 raw_results_file
=> $self -> {'raw_results_file'}[$model_number-1],
259 raw_results
=> undef,
260 prepared_models
=> undef,
261 raw_results_header
=> undef,
265 # $Data::Dumper::Maxdepth = 3;
266 # die Dumper $self -> {'tools'} if not $first;
268 # ( raw_results_file => $self -> {'raw_results_file'}[$model_number-1],
270 # run_on_lsf => $self -> {'run_on_lsf'},
271 # no_remote_execution => $self -> {'no_remote_execution'},
272 # no_remote_compile => $self -> {'no_remote_compile'},
273 # lsf_queue => $self -> {'lsf_queue'},
274 # lsf_options => $self -> {'lsf_options'},
275 # lsf_job_name => $self -> {'lsf_job_name'},
276 # lsf_project_name => $self -> {'lsf_project_name'},
278 # run_on_nordugrid => $self -> {'run_on_nordugrid'},
279 # cpu_time => $self -> {'cpu_time'},
281 # parent_tool_id => $self -> {'tool_id'},
283 # clean => $self -> {'clean'},
284 # models => $self -> {'prepared_models'},
285 # nm_version => $self -> {'nm_version'},
286 # picky => $self -> {'picky'},
287 # compress => $self -> {'compress'},
288 # threads => $mfit_threads,
289 # retries => $self -> {'retries'},
290 # remove_temp_files => $self -> {'remove_temp_files'},
291 # base_directory => $self -> {'directory'},
292 # directory => $self -> {'directory'}.'/modelfit_dir'.$model_number.'/',
294 # parent_tool_id => $self -> {'tool_id'},
295 # parent_threads => $own_threads,
296 # _raw_results_callback => $self -> _modelfit_raw_results_callback,
311 # -------------------- Initiate the run parameters -------------------------
313 # {{{ initiate params
316 $run{'thetas'} = (ref( $self -> {'run_thetas'} -> [0] ) eq 'ARRAY') ?
317 $self -> {'run_thetas'} -> [$model_number-1]:$self -> {'run_thetas'};
318 $run{'omegas'} = (ref( $self -> {'run_omegas'} -> [0] ) eq 'ARRAY') ?
319 $self -> {'run_omegas'} -> [$model_number-1]:$self -> {'run_omegas'};
320 $run{'sigmas'} = (ref( $self -> {'run_sigmas'} -> [0] ) eq 'ARRAY') ?
321 $self -> {'run_sigmas'} -> [$model_number-1]:$self -> {'run_sigmas'};
323 my $model = $self -> {'models'} -> [$model_number-1];
325 # }}} initiate params
327 # ------------------ Create the fixed parameter models ---------------------
331 # Loop over the parameters
332 foreach my $param ( 'theta', 'omega', 'sigma' ) {
333 # jump to next parameter if no parameter of this type should be run
334 next unless ( defined $run{$param.'s'} and
335 scalar @
{$run{$param.'s'}} > 0 and
336 $run{$param.'s'}->[0] ne '' );
337 my @par_nums = @
{$run{$param.'s'}};
338 my %par_log = %{$self -> {$param.'_log'}};
339 # Loop over the parameter numbers of interest
340 foreach my $num ( @par_nums ) {
341 my @active = @
{$model -> active_problems
};
343 foreach my $val ( @active ) {
344 $skip_model = 0 if ( $val );
346 foreach my $side ( 'lower', 'upper' ) {
347 # todo: Maybe not necessary to copy data file as well. This is done by
348 # default in model->copy.
349 my $filename = substr($param,0,2).$num.$side.'.mod';
350 my $model_dir = $self -> {'directory'}.'/m'.$model_number.'/';
351 my ($output_dir, $outputfilename) =
352 OSspecific
::absolute_path
( $self -> {'directory'}.'/m'.$model_number.'/',
353 substr($param,0,2).$num.
357 # ---------------------- Create model -----------------------------
361 my $new_mod = $model -> copy
( filename
=> $filename,
362 directory
=> $model_dir,
365 # According to Lars 2005-01-31 removing tables and covariances is a bug.
366 #foreach my $problem ( @{$new_mod -> problems} ) {
367 # $problem -> tables([]);
368 # $problem -> covariances([]);
370 $new_mod -> extra_files
( $model -> extra_files
),
371 $new_mod -> ignore_missing_files
( 1 );
372 $new_mod -> outputfile
( $output_dir . $outputfilename );
373 $new_mod -> ignore_missing_files
( 0 );
377 $new_mod -> update_inits
( from_output
=> $model -> outputs
-> [0] );
379 # Loop over the problems:
380 for ( my $j = 1; $j <= scalar @
{$par_log{$num}}; $j++ ) {
381 # Is this side of the problem finished?
382 debug
-> warn( level
=> 2,
383 message
=> "This side is finished!" )
384 if ( $self->{$param.'_log'}->{$num}->[$j-1]->[2]->{$side} );
385 next if $self->{$param.'_log'}->{$num}->[$j-1]->[2]->{$side};
386 my $sofar = scalar @
{$par_log{$num}->[$j-1]->[0]};
388 if ( $side eq 'lower' ) {
389 $guess = $par_log{$num}->[$j-1]->[0]->[0];
391 $guess = $par_log{$num}->[$j-1]->[0]->[$sofar-1];
394 @
{$new_mod -> initial_values
( parameter_type
=> $param,
395 parameter_numbers
=> [[$num]],
396 problem_numbers
=> [$j],
397 new_values
=> [[$guess]] )};
398 if ( $side eq 'lower' ) {
399 $par_log{$num}->[$j-1]->[0]->[0] = $diagnostics[0][2];
401 $par_log{$num}->[$j-1]->[0]->[$sofar-1] = $diagnostics[0][2];
403 debug
-> warn( level
=> 2,
404 message
=> "Registering used value ".
405 $diagnostics[0][2]." for the $side side" );
406 $new_mod -> fixed
( parameter_type
=> $param,
407 parameter_numbers
=> [[$num]],
408 problem_numbers
=> [$j],
409 new_values
=> [[1]] );
412 if ( $active_flag ) {
414 push( @new_models, $new_mod );
415 $self->{$param.'_models'}->{$num}->{$side} = $new_mod;
422 # ------------------------- Resume --------------------------------
427 # Loop over the problems:
428 for ( my $j = 1; $j <= scalar @
{$par_log{$num}}; $j++ ) {
429 # Is this side of the problem finished?
430 debug
-> warn( level
=> 2,
431 message
=> "This side is finished!" )
432 if ( $self->{$param.'_log'}->{$num}->[$j-1]->[2]->{$side} );
433 next if $self->{$param.'_log'}->{$num}->[$j-1]->[2]->{$side};
436 if ( $active_flag ) {
437 my $new_mod = model
-> new
( directory
=> $model_dir,
438 filename
=> $filename,
439 outputfile
=> $outputfilename,
440 extra_files
=> $model -> extra_files
,
442 ignore_missing_files
=> 1 );
443 # Set the correct data file for the object
444 my $moddir = $model -> directory
;
445 my @datafiles = @
{$model -> datafiles
};
446 for( my $df = 0; $df <= $#datafiles; $df++ ) {
447 $datafiles[$df] = $moddir.'/'.$datafiles[$df];
449 $new_mod -> datafiles
( new_names
=> \
@datafiles );
450 push( @new_models, $new_mod );
451 $self->{$param.'_models'}->{$num}->{$side} = $new_mod;
468 # {{{ _register_estimates
470 start _register_estimates
473 # Förenkla loggen: param_log{parameternr}[prob][[estimates...][ofv...]]
474 # Antag att man spec. paramnr som gäller ? alla modeller och problem,
475 # dvs att run_param = [2,4,3] tex.
477 $run{'thetas'} = (ref( $self -> {'run_thetas'} -> [0] ) eq 'ARRAY') ?
478 $self -> {'run_thetas'} -> [$model_number-1]:$self -> {'run_thetas'};
479 $run{'omegas'} = (ref( $self -> {'run_omegas'} -> [0] ) eq 'ARRAY') ?
480 $self -> {'run_omegas'} -> [$model_number-1]:$self -> {'run_omegas'};
481 $run{'sigmas'} = (ref( $self -> {'run_sigmas'} -> [0] ) eq 'ARRAY') ?
482 $self -> {'run_sigmas'} -> [$model_number-1]:$self -> {'run_sigmas'};
488 my ( $orig_output, $orig_ofvs );
491 # Global activity flag for this model:
494 my $orig_model = $self -> {'models'} -> [$model_number-1];
496 my $mode = $first ?
'>' : '>>';
497 open( LOG
, $mode.$self -> {'logfile'}[$model_number-1] );
498 open( LOG2
, $mode.$self -> {'unstacked_logfile'}[$model_number-1] );
499 print LOG2
sprintf("%10s",'Parameter'),',',sprintf("%10s",'Side'),
500 ',',sprintf("%10s",'Value'),',',sprintf("%10s",'OFV.diff'),"\n" if( $first );
503 'debug' -> die( message
=> "No output object defined through model" )
504 unless ( defined $orig_model -> outputs
-> [0] );
505 $orig_output = $orig_model -> outputs
-> [0];
506 $orig_ofvs = $orig_output -> ofv
;
507 # Save the ofvs in {'orig_ofvs'}
508 $self -> {'orig_ofvs'} = $orig_ofvs;
511 foreach my $param ( 'theta', 'omega', 'sigma' ) {
512 next unless ( defined $run{$param.'s'} and
513 scalar @
{$run{$param.'s'}} > 0 and
514 $run{$param.'s'}->[0] ne '' );
515 my @par_nums = @
{$run{$param.'s'}};
516 my $accessor = $param.'s';
517 my $orig_ests = $orig_output -> $accessor;
518 # Loop the parameter numbers
519 foreach my $num ( @par_nums ) {
521 for ( my $j = 0; $j < scalar @
{$orig_ests}; $j++ ) {
522 my $label = uc($param).$num."_".($j+1);
523 $ui_text = $ui_text.sprintf("%10s",$label).','.sprintf("%10s",'OFV_DIFF').',';
524 print LOG
sprintf("%10s",$label),',',sprintf("%10s",'OFV_DIFF'),',';
528 ui
-> print( category
=> 'llp',
533 # It is much more time efficient to store all bounds, estimates etc in
534 # an array and access that when doing the registration than calling the
535 # tools within the loop:
536 # Loop over the parameter names
538 foreach my $param ( 'theta', 'omega', 'sigma' ) {
539 # jump to next parameter if no parameter of this type should be run
540 next unless ( defined $run{$param.'s'} and
541 scalar @
{$run{$param.'s'}} > 0 and
542 $run{$param.'s'}->[0] ne '' );
543 my $accessor = $param.'s';
544 my @par_nums = @
{$run{$param.'s'}};
545 my $orig_ests = $orig_output -> $accessor;
546 my $se_accessor = 'se'.$param.'s';
547 my $orig_se_ests = $orig_output -> $se_accessor;
548 # Loop over the parameter numbers of interest
549 my %all_num_est = ();
550 foreach my $num ( @par_nums ) {
551 my @all_prob_est = ();
552 # Loop over the problems:
553 for ( my $j = 0; $j < scalar @
{$orig_ests}; $j++ ) {
554 debug
-> die( message
=> "Subproblems are not allowed for the log-likelihood profiling tool" )
555 if ( scalar @
{$orig_ests->[$j]} > 1 );
556 # For the original estimates, we need to use the estimates from the original output file.
557 my $orig = $orig_ests->[$j][0][$num-1];
558 # my $orig = $orig_model -> initial_values( parameter_type => 'theta' ) -> [0][$num - 1];
559 # Store original estimates. The [0] is there for print_results.
560 push(@
{$self -> {'original_estimates'}[$model_number-1][$j][0]}, $orig);
561 # all_prob_est: [fixed estimates][ofv_diffs][finished_flag(lower,upper)]
562 my %finished = ( 'lower' => 0, 'upper' => 0 );
563 push( @all_prob_est, [[$orig],[0],\
%finished]);
564 # If we end up here, the the llp of this model is still active
566 $ui_text = $ui_text.sprintf("%10f",$orig).','.sprintf("%10f",0).',';
567 print LOG
sprintf("%10f",$orig),',',sprintf("%10f",0),',';
568 print LOG2
sprintf("%10s",$param.$num),',',sprintf("%10s",'orig'),
569 ',',sprintf("%10f",$orig),',',sprintf("%10f",0),"\n";
571 $all_num_est{$num} = \
@all_prob_est;
573 $self -> {$param.'_log'} = \
%all_num_est;
575 ui
-> print( category
=> 'llp',
580 @prep_models = @
{$self -> {'prepared_models'}};
582 # It is much more time efficient to store all bounds, estimates etc in
583 # an array and access that when doing the registration than calling the
584 # tools within the loop:
585 # Loop over the parameter names
586 foreach my $side ( 'lower', 'upper' ) {
587 # reset the user interface text
589 foreach my $param ( 'theta', 'omega', 'sigma' ) {
590 # jump to next parameter if no parameter of this type should be run
591 next unless ( defined $run{$param.'s'} and
592 scalar @
{$run{$param.'s'}} > 0 and
593 $run{$param.'s'}->[0] ne '' );
596 $orig_model -> lower_bounds
( parameter_type
=> $param );
598 $orig_model -> upper_bounds
( parameter_type
=> $param );
600 my $accessor = $param.'s';
601 my @par_nums = @
{$run{$param.'s'}};
602 # get the stored ofvs
603 $orig_ofvs = $self -> {'orig_ofvs'};
604 # Loop over the parameter numbers of interest
605 foreach my $num ( @par_nums ) {
606 my ( $model, $output, $ofvs, $ests );
607 # Check if there exists any model for this side (if not, it is
608 # probably (hopefully) finished
609 if (defined $self->{$param.'_models'} -> {$num} -> {$side}) {
610 $model = $self->{$param.'_models'} -> {$num} -> {$side};
611 $output = $model -> outputs
-> [0];
612 $ofvs = $output -> ofv
;
613 my $accessor = $param.'s';
614 $ests = $output -> $accessor;
616 # Loop over the problems:
617 for ( my $j = 0; $j < scalar @
{$orig_ofvs}; $j++ ) {
618 # Is this side of the problem finished?
619 if ( $self->{$param.'_log'}->{$num}->[$j]->[2]->{$side} ) {
620 $ui_text = $ui_text.sprintf("%10s",$PsN::out_miss_data
).','.sprintf("%10s",$PsN::out_miss_data
).',';
621 print LOG
sprintf("%10s",$PsN::out_miss_data
),',',sprintf("%10s",$PsN::out_miss_data
),',';
624 # Collect the model outputs
625 my $diff = $ofvs->[$j][0]-$orig_ofvs->[$j][0];
626 #my $est = $ests -> [$j][0][$num-1];
627 my $est = $model -> initial_values
( parameter_type
=> $param ) -> [0][$num - 1];
628 $ui_text = $ui_text.sprintf("%10f",$est).','.sprintf("%10f",$diff).',';
629 print LOG
sprintf("%10f",$est),',',sprintf("%10f",$diff),',';
630 print LOG2
sprintf("%10s",$param.$num),',',sprintf("%10s",$side),',',
631 sprintf("%10f",$est),',',sprintf("%10f",$diff),"\n";
632 my $bound = $bounds{$side}->[$j][$num-1];
633 debug
-> warn( level
=> 2,
634 message
=> "Registering diff $diff" );
635 if ( $side eq 'lower' ) {
636 unshift( @
{$self->{$param.'_log'}->{$num}->[$j]->[1]}, $diff );
637 $est = $self->{$param.'_log'}->{$num}->[$j]->[0]->[0];
639 push( @
{$self->{$param.'_log'}->{$num}->[$j]->[1]}, $diff );
640 my $sofar = scalar @
{$self->{$param.'_log'}->{$num}->[$j]->[0]};
641 $est = $self->{$param.'_log'}->{$num}->[$j]->[0]->[$sofar-1];
643 my $finished = $self -> _test_sigdig
( number
=> $diff,
644 goal
=> $self -> {'ofv_increase'},
645 sigdig
=> $self -> {'significant_digits'} );
646 my $print_diff = &FormatSigFigs
($diff, $self -> {'significant_digits'} );
647 debug
-> warn( level
=> 2,
648 message
=> "New OFV diff: $print_diff" );
649 debug
-> warn( level
=> 2,
650 message
=> " equals goal ".$self->{'ofv_increase'}.
651 ". This side is finished" ) if $finished;
653 $self->{$param.'_log'}->{$num}->[$j]->[2]->{$side} = 1;
654 } elsif ( defined $bound and
655 $self -> _test_sigdig
( number
=> $est,
658 debug
-> warn( level
=> 1,
659 message
=> "Estimate $est too close to $side boundary $bound".
660 " terminating search" );
661 $self->{$param.'_log'}->{$num}->[$j]->[2]->{$side} = 2;
665 $model -> datas
-> [0] -> flush
;
666 $model -> outputs
-> [0] -> flush
;
670 # Print to screen if we are in the right context
671 ui
-> print( category
=> 'llp',
680 end _register_estimates
682 # }}} _register_estimates
684 # {{{ modelfit_analyze
686 start modelfit_analyze
688 my $own_threads = ref( $self -> {'threads'} ) eq 'ARRAY' ?
689 $self -> {'threads'} -> [0]:$self -> {'threads'};
691 # 1. Register fixed values and ofvs
692 # and check if ofvs are close enough to target
693 my $active = $self -> _register_estimates
( model_number
=> $model_number );
695 my ( $returns, $prep_models );
696 # 3. Return logged values-ofv pairs to calling tool
698 if ( $self -> {'max_iterations'} > 1 ) {
699 $self -> update_raw_results
( model_number
=> $model_number );
700 # !!! The results_file attribute should not be set when calling
701 # llp recursively. If set, a result file will be written for each
702 # recurrence level which is redundant.
704 $run{'thetas'} = (ref( $self -> {'run_thetas'} -> [0] ) eq 'ARRAY') ?
705 $self -> {'run_thetas'} -> [$model_number-1]:$self -> {'run_thetas'};
706 $run{'omegas'} = (ref( $self -> {'run_omegas'} -> [0] ) eq 'ARRAY') ?
707 $self -> {'run_omegas'} -> [$model_number-1]:$self -> {'run_omegas'};
708 $run{'sigmas'} = (ref( $self -> {'run_sigmas'} -> [0] ) eq 'ARRAY') ?
709 $self -> {'run_sigmas'} -> [$model_number-1]:$self -> {'run_sigmas'};
711 if ( defined $self -> {'subtool_arguments'} ) {
712 %subargs = %{$self -> {'subtool_arguments'}};
716 new
( reference_object
=> $self,
717 raw_results_file
=> [$self -> {'raw_results_file'}[$model_number-1]],
718 parent_tool_id
=> $self -> {'tool_id'},
719 base_directory
=> $self -> {'directory'},
720 directory
=> $self -> {'directory'}.'/llp_dir'.$model_number,
721 logfile
=> [$self -> {'logfile'}[$model_number-1]],
722 unstacked_logfile
=> [$self -> {'unstacked_logfile'}[$model_number-1]],
723 max_iterations
=> ($self -> {'max_iterations'} - 1),
724 iteration
=> ($self -> {'iteration'} + 1),
725 models
=> [$self -> {'models'} -> [$model_number-1]],
726 run_thetas
=> [$self -> {'run_thetas'} -> [$model_number-1]],
727 run_omegas
=> [$self -> {'run_omegas'} -> [$model_number-1]],
728 run_sigmas
=> [$self -> {'run_sigmas'} -> [$model_number-1]],
729 parent_tool_id
=> $self -> {'tool_id'},
730 parent_threads
=> $own_threads,
731 raw_results
=> undef,
732 prepared_models
=> undef,
736 raw_results_header
=> undef,
738 prepared_models
=> undef,
742 # $Data::Dumper::Maxdepth = 2;
743 # die Dumper $internal_llp;
745 # new ( raw_results_file => [$self -> {'raw_results_file'}[$model_number-1]],
746 # nm_version => $self -> {'nm_version'},
748 # run_on_lsf => $self -> {'run_on_lsf'},
749 # no_remote_execution => $self -> {'no_remote_execution'},
750 # no_remote_compile => $self -> {'no_remote_compile'},
751 # lsf_queue => $self -> {'lsf_queue'},
752 # lsf_options => $self -> {'lsf_options'},
753 # lsf_job_name => $self -> {'lsf_job_name'},
754 # lsf_project_name => $self -> {'lsf_project_name'},
756 # run_on_nordugrid => $self -> {'run_on_nordugrid'},
757 # cpu_time => $self -> {'cpu_time'},
759 # parent_tool_id => $self -> {'tool_id'},
761 # picky => $self -> {'picky'},
762 # compress => $self -> {'compress'},
763 # threads => $self -> {'threads'},
764 # retries => $self -> {'retries'},
765 # remove_temp_files => $self -> {'remove_temp_files'},
766 # base_directory => $self -> {'directory'},
767 # directory => $self -> {'directory'}.'/llp_dir'.$model_number.'/',
768 # logfile => [$self -> {'logfile'}[$model_number-1]],
769 # unstacked_logfile => [$self -> {'unstacked_logfile'}[$model_number-1]],
770 # max_iterations => ($self -> {'max_iterations'} - 1),
771 # iteration => ($self -> {'iteration'} + 1),
772 # significant_digits => $self -> {'significant_digits'},
773 # normq => $self -> {'normq'},
774 # ofv_increase => $self -> {'ofv_increase'},
775 # models => [$self -> {'models'} -> [$model_number-1]],
776 # subtools => $self -> {'subtools'},
777 # run_thetas => [$self -> {'run_thetas'} -> [$model_number-1]],
778 # run_omegas => [$self -> {'run_omegas'} -> [$model_number-1]],
779 # run_sigmas => [$self -> {'run_sigmas'} -> [$model_number-1]],
780 # theta_log => $self -> {'theta_log'},
781 # omega_log => $self -> {'omega_log'},
782 # sigma_log => $self -> {'sigma_log'},
783 # orig_ofvs => $self -> {'orig_ofvs'},
784 # parent_tool_id => $self -> {'tool_id'},
785 # parent_threads => $own_threads );
787 ( $returns, $prep_models ) = $internal_llp -> run
;
789 if ( defined $prep_models ) {
790 debug
-> warn( level
=> 2,
791 message
=> "Inside ".ref($self).
792 " have called internal llp ".
793 scalar @
{$prep_models} );
794 push ( @
{$self -> {'prepared_models'}[$model_number-1]{'subtools'}},
797 debug
-> warn( level
=> 1,
798 message
=> "Inside analyze".ref($self).
799 " but no prep_models defined from internal llp" );
802 #push( @{$self -> {'raw_results'}[$model_number-1]},
803 # @{$internal_llp -> raw_results -> [0]} );
806 $self -> {'raw_results'}[$model_number-1] =
807 $self -> {'tools'} -> [0] -> raw_results
;
808 $self -> update_raw_results
( model_number
=> $model_number );
811 $self -> {'raw_results'}[$model_number-1] =
812 $self -> {'tools'} -> [0] -> raw_results
if( defined $self -> {'tools'} -> [0] );
814 if( $self -> iteration
() < 2 and
815 defined $PsN::config
-> {'_'} -> {'R'} and
816 -e
$PsN::lib_dir
. '/R-scripts/llp.R' ) {
817 # copy the llp R-script
818 cp
( $PsN::lib_dir
. '/R-scripts/llp.R', $self -> {'directory'} );
820 system( $PsN::config
-> {'_'} -> {'R'}." CMD BATCH llp.R" );
825 # }}} modelfit_analyze
827 # {{{ prepare_results
829 start prepare_results
831 # if ( not defined $self -> {'raw_results'} ) {
832 $self -> read_raw_results
();
835 for ( my $i = 0; $i < scalar @
{$self->{'raw_results'}}; $i++ ) { # All models
836 my $orig_mod = $self -> {'models'}[$i];
837 my @params = ( 'theta', 'omega', 'sigma' );
838 my ( %param_nums, %labels, %orig_estimates );
839 foreach my $param ( @params ) {
840 my $modlabels = $orig_mod -> labels
( parameter_type
=> $param );
841 $labels{$param} = $modlabels -> [0]; # Only one problem
842 $param_nums{$param} = scalar @
{$modlabels -> [0]} if ( defined $modlabels );
843 my $accessor = $param.'s';
844 $orig_estimates{$param} = $orig_mod -> outputs
-> [0] -> $accessor -> [0][0];
846 my ( %ci, %near_bound, %max_iterations, %interval_ratio,
847 %skewed, %within_interval );
849 # The 9 on the row below is offset for iteration,
850 # parameter.type, parameter.number, side, finish.message,
851 # model, problem, subproblem, ofv
853 my $cols = scalar @
{$self -> {'diagnostic_parameters'}} + 9;
855 # my $cols = scalar @{$self -> {'raw_results'}[$i][0]}; # first non-header row
857 for ( my $j = 1; $j < scalar @
{$self -> {'raw_results'}[$i]}; $j++ ) {
859 my $row = $self -> {'raw_results'}[$i][$j];
860 if ( $row -> [1] eq 'theta' ) {
861 $num = $cols + ($row -> [2] - 1);
862 } elsif ( $row -> [1] eq 'omega' ) {
863 $num = $cols + $param_nums{'theta'} + ($row -> [2] - 1);
865 $num = $cols + $param_nums{'theta'} + $param_nums{'omega'} + ($row -> [2] - 1);
867 my $row = $self -> {'raw_results'}[$i][$j];
868 $ci{$row -> [1]}{$row -> [2]}{$row -> [3]} = $row -> [$num];
869 if ( $row -> [4] eq 'near.boundary' ) {
870 $near_bound{$row -> [1]}{$row -> [2]}{$row -> [3]} = 1;
871 } elsif ( $row -> [4] eq 'max.iterations' ) {
872 $max_iterations{$row -> [1]}{$row -> [2]}{$row -> [3]} = 1;
875 my ( @ci_labels, @ci_values, @li_values );
876 $ci_labels[1] = [ 'lower', 'maximum.likelihood.estimate',
877 'upper', 'interval.ratio', 'near.bound','max.iterations' ];
878 foreach my $param ( @params ) {
879 next if ( not defined $ci{$param} );
880 my @nums = sort { $a <=> $b } keys %{$ci{$param}};
881 foreach my $num ( @nums ) {
882 push( @
{$ci_labels[0]}, $labels{$param}[$num-1] );
883 if ( defined $ci{$param}{$num}{'lower'} and
884 defined $ci{$param}{$num}{'upper'} ) {
885 if( abs( $ci{$param}{$num}{'lower'} - $orig_estimates{$param}[$num-1] ) == 0 ){
886 $interval_ratio{$param}{$num} = 'INF';
888 $interval_ratio{$param}{$num} =
889 abs( $ci{$param}{$num}{'upper'} - $orig_estimates{$param}[$num-1] ) /
890 abs( $ci{$param}{$num}{'lower'} - $orig_estimates{$param}[$num-1] );
891 if ( $interval_ratio{$param}{$num} > $self -> {$param.'_interval_ratio_check'} or
892 $interval_ratio{$param}{$num} < 1/$self -> {$param.'_interval_ratio_check'} ) {
893 $skewed{$param}{$num} = 1;
895 $skewed{$param}{$num} = 0;
897 if ( $self -> {'within_interval_check'} < $ci{$param}{$num}{'upper'} and
898 $self -> {'within_interval_check'} > $ci{$param}{$num}{'lower'} ) {
899 $within_interval{$param}{$num} = 1;
901 $within_interval{$param}{$num} = 0;
906 push( @row, $ci{$param}{$num}{'lower'} );
907 push( @row, $orig_estimates{$param}[$num-1] );
908 push( @row, $ci{$param}{$num}{'upper'} );
909 push( @row, $interval_ratio{$param}{$num} );
910 push( @row, $near_bound{$param}{$num}{'upper'} ?
1 : $near_bound{$param}{$num}{'lower'} ?
1 : 0 );
911 push( @row, $max_iterations{$param}{$num}{'upper'} ?
1 : $max_iterations{$param}{$num}{'lower'} ?
1 : 0 );
912 push( @ci_values, \
@row );
915 #print Dumper \%ci;die;
916 $self -> {'confidence_intervals'}[$i] = \
%ci;
917 $self -> {'interval_ratio'}[$i] = \
%interval_ratio;
918 $self -> {'skewed_intervals'}[$i] = \
%skewed;
919 $self -> {'hit_max_iterations'}[$i] = \
%max_iterations;
920 $self -> {'near_boundary'}[$i] = \
%near_bound;
921 $self -> {'within_interval'}[$i] = \
%within_interval;
923 $return_section{'name'} = 'confidence.intervals';
924 $return_section{'labels'} = \
@ci_labels;
925 $return_section{'values'} = \
@ci_values;
926 unshift( @
{$self -> {'results'}[$i]{'own'}},\
%return_section );
928 # # Lasse 2005-04-29: This section may be reduced when the results array turns into a hash
929 # my ( @ofv_log1, @labels0 );
930 # # print Dumper $self -> {'theta_log'};
931 # foreach my $param ( 'theta', 'omega', 'sigma' ) {
932 # my $accessor = $param.'names';
933 # my @param_names = @{$self -> models -> [$model_number -1] -> outputs -> [0] -> $accessor};
934 # my @par_nums = keys %{$self -> {$param.'_log'}};
935 # if ( defined $par_nums[0] ) {
936 # # Loop the problems
937 # for ( my $i = 0; $i < scalar @{$self -> {$param.'_log'}{$par_nums[0]}}; $i++ ) {
938 # foreach my $num ( @par_nums ) {
939 # for ( my $j = 0; $j < scalar @{$self -> {$param.'_log'}{$num}[$i][0]}; $j++ ) {
940 # push( @{$ofv_log1[$i][0]}, [ $self -> {$param.'_log'}{$num}[$i][0][$j],
941 # $self -> {$param.'_log'}{$num}[$i][1][$j] ] );
942 # push( @{$labels0[$i][0][0]}, $param_names[$i][$num-1] );
945 # $labels0[$i][0][1] = ['fixed.value','OFV'];
949 # # print Dumper \@ofv_log1;
950 # my %return_section;
951 # $return_section{'name'} = 'ofv.trace';
952 # $return_section{'labels'} = \@labels0;
953 # $return_section{'values'} = \@ofv_log1;
954 # push( @{$self -> {'results'}[$model_number-1]{'own'}},\%return_section );
956 # my ( @last_values, @labels1, @labels2, @l_dist_ratio, @labels3, @all, @labels4 );
957 # foreach my $param ( 'theta', 'omega', 'sigma' ) {
958 # my $accessor = $param.'names';
959 # my @param_names = @{$self -> models -> [$model_number -1] -> outputs -> [0] -> $accessor};
960 # $accessor = $param.'s';
961 # my @origs = @{$self -> models -> [$model_number -1] -> outputs -> [0] -> $accessor};
962 # my @par_nums = keys %{$self -> {$param.'_log'}};
963 # if ( defined $par_nums[0] ) {
964 # # Loop the problems
965 # for ( my $i = 0; $i < scalar @{$self -> {$param.'_log'}{$par_nums[0]}}; $i++ ) {
966 # foreach my $num ( @par_nums ) {
967 # my $last = scalar @{$self -> {$param.'_log'}{$num}[$i][0]} - 1;
968 # # the first [0] in last_values is there only to add a subproblem level
969 # # for the general print_results method. The first [0] of the param_log
970 # # indicates the log of the fixed parameter values.
972 # push( @{$last_values[$i][0][0]}, $self -> {$param.'_log'}{$num}[$i][0][0] );
974 # push( @{$last_values[$i][0][1]}, $self -> {$param.'_log'}{$num}[$i][0][$last] );
975 # my $ratio = (abs( $self -> {$param.'_log'}{$num}[$i][0][$last] -
976 # $origs[$i][0][$num-1] ) / $origs[$i][0][$num-1] ) /
977 # (abs( $self -> {$param.'_log'}{$num}[$i][0][0] -
978 # $origs[$i][0][$num-1] ) / $origs[$i][0][$num-1] );
979 # push( @{$l_dist_ratio[$i][0][0]}, $ratio );
980 # push( @{$all[$i][0]},[ $origs[$i][0][$num-1],
981 # $self -> {$param.'_log'}{$num}[$i][0][0],
982 # $self -> {$param.'_log'}{$num}[$i][0][$last],
984 # push( @{$labels1[$i][0][1]}, $param_names[$i][$num-1] );
985 # push( @{$labels2[$i][0][1]}, $param_names[$i][$num-1] );
986 # push( @{$labels3[$i][0][1]}, $param_names[$i][$num-1] );
987 # push( @{$labels4[$i][0][0]}, $param_names[$i][$num-1] );
989 # $labels1[$i][0][0] = ['lower', 'upper'];
990 # $labels2[$i][0][0] = [];
991 # $labels3[$i][0][0] = [];
992 # $labels4[$i][0][1] = ['original', 'lower', 'upper', 'ratio'];
996 # my %return_section;
997 # $return_section{'name'} = '';
998 # $return_section{'labels'} = \@labels4;
999 # $return_section{'values'} = \@all;
1000 # unshift( @{$self -> {'results'}[$model_number-1]{'own'}},\%return_section );
1001 # my %return_section;
1002 # $return_section{'name'} = 'limit.distance.ratio';
1003 # $return_section{'labels'} = \@labels3;
1004 # $return_section{'values'} = \@l_dist_ratio;
1005 # unshift( @{$self -> {'results'}[$model_number-1]{'own'}},\%return_section );
1006 # my %return_section;
1007 # $return_section{'name'} = 'confidence.intervals';
1008 # $return_section{'labels'} = \@labels1;
1009 # $return_section{'values'} = \@last_values;
1010 # unshift( @{$self -> {'results'}[$model_number-1]{'own'}},\%return_section );
1011 # my %return_section;
1012 # $return_section{'name'} = 'original.estimates';
1013 # $return_section{'labels'} = \@labels2;
1014 # $return_section{'values'} = $self -> {'original_estimates'};
1015 # unshift( @{$self -> {'results'}[$model_number-1]{'own'}},\%return_section );
1016 # # print Dumper $self -> {'results'}[$model_number-1]{'own'};
1021 # }}} prepare_results
1023 # {{{ _modelfit_raw_results_callback
1025 start _modelfit_raw_results_callback
1028 # This functions creates a subrouting which will be called by
1029 # the modelfit subtool. The subroutine will add columns to the
1030 # result rows from the modelfit. The result rows will then be
1031 # printed to the "raw_results" file by the modelfit.
1033 # First we create some variables that the subroutine needs. To
1034 # avoid confuision we avoid using the $self variable in the
1035 # subroutine, instead we create these variables which become
1036 # available to the subroutine.
1038 my $iteration = $self -> {'iteration'};
1040 my @models = @
{$self -> {'models'}};
1041 my $model_number = $self -> {'model_number'};
1043 OSspecific
::absolute_path
( $self -> {'directory'},
1044 $self -> {'raw_results_file'}[$model_number-1] );
1046 $run{'thetas'} = (ref( $self -> {'run_thetas'} -> [0] ) eq 'ARRAY') ?
1047 $self -> {'run_thetas'} -> [$model_number-1]:$self -> {'run_thetas'};
1048 $run{'omegas'} = (ref( $self -> {'run_omegas'} -> [0] ) eq 'ARRAY') ?
1049 $self -> {'run_omegas'} -> [$model_number-1]:$self -> {'run_omegas'};
1050 $run{'sigmas'} = (ref( $self -> {'run_sigmas'} -> [0] ) eq 'ARRAY') ?
1051 $self -> {'run_sigmas'} -> [$model_number-1]:$self -> {'run_sigmas'};
1053 foreach my $param ( 'theta', 'omega', 'sigma' ) {
1054 $log{$param} = $self -> {$param.'_log'};
1057 # The raw results of the original model should be put as the first row
1058 my $orig_mod = $self -> {'models'}[$model_number-1];
1060 # And here is the subroutine which is given to the modelfit.
1061 my $callback = sub {
1062 # The modelfit object is given to us. It could have been
1063 # retrieved from $self but this was easier.
1065 my $modelfit = shift;
1067 my $raw_results_header = $modelfit -> raw_results_header
;
1068 my $raw_results = $modelfit -> raw_results
;
1070 $modelfit -> raw_results_append
( 1 ) if( $iteration > 1 );
1072 if ( $iteration == 1 ) {
1073 # Loop through the unchanged header and use the header names as accessors
1074 # for the original model raw results.
1075 # Model zero: original run. Problem 1 and subproblem 1
1076 # my @orig_res = ( 0, undef, undef, undef, undef, 0, 1, 1 );
1077 # foreach my $param ( @{$raw_results_header} ){
1078 # next if( $param eq 'model' or $param eq 'problem' or $param eq 'subproblem' );
1079 # my ( $accessor, $res );
1080 # if ( $param eq 'theta' or $param eq 'omega' or $param eq 'sigma' or
1081 # $param eq 'setheta' or $param eq 'seomega' or $param eq 'sesigma' or
1082 # $param eq 'npomega' or $param eq 'eigen' ) {
1083 # $accessor = $param.'s';
1084 # $res = $orig_mod -> {'outputs'} -> [0] -> $accessor;
1086 # } elsif ( $param eq 'shrinkage_etas' ) {
1088 # # Shrinkage does not work for subproblems right now.
1089 # $res = $orig_mod -> eta_shrinkage;
1091 # } elsif ( $param eq 'shrinkage_wres' ) {
1093 # $res = $orig_mod -> wres_shrinkage;
1097 # $res = $orig_mod -> {'outputs'} -> [0] -> $param;
1101 # # {{{ Push results
1103 # # To handle settings on problem level.
1105 # if( defined $res and ref $res -> [0] eq 'ARRAY' ){
1106 # $res = $res -> [0][0];
1108 # $res = $res -> [0];
1111 # if( $max_hash{$param} > 1 or ref $res eq 'ARRAY' ) {
1112 # if( defined $res ) {
1113 # push( @orig_res, @{$res} );
1114 # push( @orig_res, (undef) x ($max_hash{$param}- scalar @{$res}) );
1116 # push( @orig_res, (undef) x $max_hash{$param} );
1119 # push( @orig_res, $res );
1121 # # $res = defined $res ? $res -> [0][0] : undef;
1122 # # if ( ref $res eq 'ARRAY' ) {
1123 # # push( @orig_res, @{$res} );
1125 # # push( @orig_res, $res );
1128 # # }}} Push results
1132 my ($raw_results_rows,$row_structrure) = $self -> create_raw_results_rows
( max_hash
=> $mh_ref,
1133 model
=> $orig_mod );
1135 unshift( @
{$raw_results_rows -> [0]}, ( 0, undef, undef, undef, undef ));
1137 unshift( @
{$raw_results}, @
{$raw_results_rows} );
1140 # Set the header once.
1141 if ( $iteration == 1 ) {
1142 unshift( @
{$raw_results_header} , ('iteration', 'parameter.type',
1143 'parameter.number', 'side', 'finish.message' ) );
1147 # First prepend llp specific stuff.
1149 # It is implicitly true that the inner loop will execute once
1150 # for each row in the raw_results array. We keep track of its
1151 # the row index with $result_row.
1153 my $result_row = $iteration == 1 ?
1 : 0; # skip the original results row
1155 foreach my $param ( 'theta', 'omega', 'sigma' ) {
1156 foreach my $num ( @
{$run{$param.'s'}} ) {
1157 foreach my $side ( 'lower', 'upper' ) {
1158 next unless ( defined $run{$param.'s'} and
1159 scalar @
{$run{$param.'s'}} > 0 );
1160 next if $log{$param}{$num}[0][2]{$side};
1161 if ( defined $raw_results -> [$result_row] ) {
1162 unshift( @
{$raw_results -> [$result_row]}, ($iteration, $param, $num, $side, undef ) );
1169 # Then fix label names.
1170 my %max_hash = %{$mh_ref};
1171 my ( @new_header, %param_names );
1172 my @params = ( 'theta', 'omega', 'sigma' );
1173 foreach my $param ( @params ) {
1174 my $labels = $orig_mod -> labels
( parameter_type
=> $param );
1175 $param_names{$param} = $labels -> [0] if ( defined $labels );
1178 foreach my $name ( @
{$modelfit -> {'raw_results_header'}} ) {
1180 foreach my $param ( @params, 'eigen', 'shrinkage_etas', 'shrinkage_wres' ) {
1181 if ( $name eq $param ){
1182 if( defined $param_names{$name} ) {
1183 push( @new_header , @
{$param_names{$name}} );
1185 for ( my $i = 1; $i <= $max_hash{ $name }; $i++ ) {
1186 push ( @new_header, uc(substr($name,0,2)).$i );
1191 } elsif ( $name eq 'se'.$param ) {
1193 for ( my $i = 1; $i <= $max_hash{ $name }; $i++ ) {
1194 push ( @new_names, uc(substr($param,0,2)).$i );
1196 map ( $_ = 'se'.$_, @new_names );
1198 push( @new_header, @new_names );
1204 push( @new_header, $name );
1208 $modelfit -> {'raw_results_header'} = \
@new_header;
1209 @
{$self -> {'raw_results_header'}} = @
{$modelfit -> {'raw_results_header'}};
1216 end _modelfit_raw_results_callback
1218 # }}} _modelfit_raw_results_callback
1220 # {{{ update_raw_results
1222 start update_raw_results
1224 my ($dir,$file) = OSspecific
::absolute_path
( $self -> {'directory'},
1225 $self -> {'raw_results_file'}[$model_number-1] );
1226 open( RRES
, $dir.$file );
1229 open( RRES
, '>',$dir.$file );
1231 foreach my $row_str ( @rres ) {
1233 my @row = split( ',', $row_str );
1234 if ( $row[0] eq $self -> {'iteration'} ) {
1235 # The [0] is the problem level, should be removed
1236 if ( $self -> {$row[1].'_log'}{$row[2]}[0][2]{$row[3]} == 1 ) {
1237 $row[4] = 'limit.found';
1238 } elsif ( $self -> {$row[1].'_log'}{$row[2]}[0][2]{$row[3]} == 2 ) {
1239 $row[4] = 'near.boundary';
1240 } elsif ( $self -> {'max_iterations'} <= 1 ) {
1241 $row[4] = 'max.iterations';
1244 push( @new_rres, \
@row );
1245 print RRES
join(',',@row ),"\n";
1248 $self -> {'raw_results'}[$model_number-1] = \
@new_rres;
1250 end update_raw_results
1252 # }}} update_raw_results
1260 my $outcome = shift;
1262 my $l = (7 - length( $outcome ))/2;
1264 $c_num = '07' if ( $outcome eq 'OK' );
1265 $c_num = '13' if ( $outcome eq 'WARNING' );
1266 $c_num = '05' if ( $outcome eq 'ERROR' );
1267 # my $text = sprintf( "%-66s%2s%7s%-5s\n\n", $name, '[ ', $outcome. ' ' x $l, ' ]' );
1268 my $text = sprintf( "%-66s%2s%7s%-5s", $name, '[ ', $outcome. ' ' x
$l, ' ]' );
1269 # cprintf( "%-66s%2s\x03$c_num%7s\x030%-5s", $name, '[ ', $outcome. ' ' x $l, ' ]' );
1270 # my $text = cprintf( "%-66s%2s\x03$c_num%7s\x030%-5s", $name, '[ ', $outcome. ' ' x $l, ' ]' );
1271 print $text, "\n\n";
1272 print $file $text if defined $file;
1275 my @params = ( 'theta', 'omega', 'sigma' );
1280 foreach my $param ( @params ) {
1281 next if ( not defined $arr -> {$param} );
1282 my @nums = sort { $a <=> $b } keys %{$arr -> {$param}};
1283 foreach my $num ( @nums ) {
1284 if ( ref($arr -> {$param}{$num}) eq 'HASH' ) {
1285 my @sides = sort { $a <=> $b } keys %{$arr -> {$param}{$num}};
1286 foreach my $side ( @sides ) {
1287 $sum += $arr -> {$param}{$num}{$side};
1290 $sum += $arr -> {$param}{$num};
1296 my $diag_number = scalar @
{$self -> {'diagnostic_parameters'}} - 1;
1298 for ( my $i = 0; $i <= $diag_number; $i++ ) {
1299 $diag_idxs{$self -> {'diagnostic_parameters'} -> [$i]} = $i;
1302 open( my $log, ">test.log" );
1303 for ( my $i = 0; $i < scalar @
{$self -> {'raw_results'}} ; $i++ ) { # All models
1304 print "MODEL ",$i+1,"\n" if ( scalar @
{$self -> {'raw_results'}} > 1 );
1305 my $sum = sum
( $self -> {'within_interval'}[$i] );
1306 if ( not defined $sum or $sum < 1 ) {
1307 acknowledge
( 'No confidence intervals include '.
1308 $self -> {'within_interval_check'}, 'OK', $log );
1310 acknowledge
( "$sum confidence intervals include ".
1311 $self -> {'within_interval_check'}, 'WARNING', $log );
1312 foreach my $param ( @params ) {
1313 next if ( not defined $self -> {'within_interval'}[$i]{$param} );
1314 my @nums = sort { $a <=> $b } keys %{$self -> {'within_interval'}[$i]{$param}};
1315 foreach my $num ( @nums ) {
1316 printf( "\t%-20s%3.3f\t%3.3f\n", uc(substr($param,0,2)).$num,
1317 $self -> {'confidence_intervals'}[$i]{$param}{$num}{'lower'},
1318 $self -> {'confidence_intervals'}[$i]{$param}{$num}{'upper'} )
1319 if ( $self -> {'within_interval'}[$i]{$param}{$num} );
1320 print $log sprintf( "\t%-20s\n",uc($param).$num )
1321 if ( $self -> {'within_interval'}[$i]{$param}{$num} );
1326 my $sum = sum
( $self -> {'near_boundary'}[$i] );
1327 if ( not defined $sum or $sum < 1 ) {
1328 acknowledge
( 'No confidence interval limit search ended near a boundary '.
1329 $self -> {'near_boundary_check'}, 'OK', $log );
1331 acknowledge
( "$sum searches for confidence intervals limits ended near a boundary ",
1333 foreach my $param ( @params ) {
1334 next if ( not defined $self -> {'near_boundary'}[$i]{$param} );
1335 my @nums = sort { $a <=> $b } keys %{$self -> {'near_boundary'}[$i]{$param}};
1336 foreach my $num ( @nums ) {
1337 next if ( not defined $self -> {'near_boundary'}[$i]{$param} );
1338 foreach my $side ( 'lower', 'upper' ) {
1339 printf( "\t%-20s%-8s%3.3f\n", uc(substr($param,0,2)).$num, $side,
1340 $self -> {'confidence_intervals'}[$i]{$param}{$num}{$side} )
1341 if ( $self -> {'near_boundary'}[$i]{$param}{$num}{$side} );
1342 print $log sprintf( "\t%-20s%-8s%3.3f\n", uc(substr($param,0,2)).$num, $side,
1343 $self -> {'confidence_intervals'}[$i]{$param}{$num}{$side} )
1344 if ( $self -> {'near_boundary'}[$i]{$param}{$num}{$side} );
1350 my $sum = sum
( $self -> {'hit_max_iterations'}[$i] );
1351 if ( not defined $sum or $sum < 1 ) {
1352 acknowledge
( 'No confidence interval limit search reached the maximum number of iterations '.
1353 $self -> {'hit_max_iterations_check'}, 'OK', $log );
1355 acknowledge
( "$sum searches for confidence intervals limits reached the maximum number of iterations ",
1357 foreach my $param ( @params ) {
1358 next if ( not defined $self -> {'hit_max_iterations'}[$i]{$param} );
1359 my @nums = sort { $a <=> $b } keys %{$self -> {'hit_max_iterations'}[$i]{$param}};
1360 foreach my $num ( @nums ) {
1361 next if ( not defined $self -> {'hit_max_iterations'}[$i]{$param} );
1362 foreach my $side ( 'lower', 'upper' ) {
1363 printf( "\t%-20s%-8s\n", uc(substr($param,0,2)).$num, $side )
1364 if ( $self -> {'hit_max_iterations'}[$i]{$param}{$num}{$side} );
1365 print $log sprintf( "\t%-20s%-8s\n", uc(substr($param,0,2)).$num, $side )
1366 if ( $self -> {'hit_max_iterations'}[$i]{$param}{$num}{$side} );
1372 my $sum = sum
( $self -> {'skewed_intervals'}[$i] );
1373 if ( not defined $sum or $sum < 1 ) {
1374 acknowledge
( 'No CI limit distance ratio exceeds the given thresholds', 'OK', $log );
1376 acknowledge
( "$sum CI limit distance ratios exceed the given thresholds", 'WARNING', $log );
1377 foreach my $param ( @params ) {
1378 next if ( not defined $self -> {'skewed_intervals'}[$i]{$param} );
1379 my @nums = sort { $a <=> $b } keys %{$self -> {'skewed_intervals'}[$i]{$param}};
1380 foreach my $num ( @nums ) {
1381 printf( "\t%-15s%3.3f is less than %3.3f or larger than %3.3f\n", uc(substr($param,0,2)).$num,
1382 $self -> {'interval_ratio'}[$i]{$param}{$num},
1383 (1/$self -> {$param.'_interval_ratio_check'}),
1384 $self -> {$param.'_interval_ratio_check'} )
1385 if ( $self -> {'skewed_intervals'}[$i]{$param}{$num} );
1386 print $log sprintf( "\t%-20s\n",uc($param).$num )
1387 if ( $self -> {'skewed_intervals'}[$i]{$param}{$num} );
1401 # Anv䮤 sort f?tt f堦ram l䧳ta och h?a pr?e v?et
1402 # anv䮤 de f?tt fixa estimat utanf?r䮳erna.
1404 if ( ( $side eq 'lower' and $guess < $bound ) or
1405 ( $side eq 'upper' and $guess > $bound ) ) {
1406 my @s_log = sort { $a <=> $b } @param_log;
1407 if ( $side eq 'lower' and $guess < $bound ) {
1408 $guess = ( $bound - $s_log[0])*0.9+$s_log[0];
1409 debug
-> warn( level
=> 1,
1410 message
=> "Corrected lower guess to $guess" );
1412 if ( $side eq 'upper' and $guess > $bound ) {
1413 $guess = ( $bound - $s_log[$#s_log])*0.9+$s_log[$#s_log];
1414 debug
-> warn( level
=> 1,
1415 message
=> "Corrected upper guess to $guess" );
1419 $new_value = $guess;
1429 my $total = scalar(@x);
1430 debug
-> die( message
=> "No data supplied to the polynomial approximation".
1431 " algorithm in the log-likelihood profiling tool" ) if ( $total < 1 );
1433 my $y=0; my $y2=0; my $x1=0; my $x2=0;
1434 my $x3=0; my $x4=0; my $x1y=0; my $x2y=0;
1437 while ($count<$total){
1439 $y2+=($y[$count])**2;
1441 $x2+=($x[$count])**2;
1442 $x3+=($x[$count])**3;
1443 $x4+=($x[$count])**4;
1444 $x1y+=$x[$count]*$y[$count];
1445 $x2y+=(($x[$count])**2)*$y[$count];
1448 my $a = $x1y - $x1*$y/$total;
1449 my $b = $x3 - $x1*$x2/$total;
1450 my $c = $x2 - $x1**2/$total;
1451 my $d = $x2y - $x2*$y/$total;
1452 my $e = $x4 - $x2**2/$total;
1454 # Try to avoid division by zero
1455 $c = $c == 0 ?
0.00001 : $c;
1456 my $tmp = ($b**2/$c - $e);
1457 $tmp = $tmp == 0 ?
0.00001 : $tmp;
1459 my $apr1 = ($a*$b/$c - $d) / $tmp;
1460 my $apr2 = $a/$c - $b*$apr1/$c;
1461 my $apr3 = ($y - $apr2*$x1 - $apr1*$x2)/$total;
1463 @polynomial = ($apr1,$apr2,$apr3);
1473 my @x = @
{$param_log[0]};
1474 my @y = @
{$param_log[1]};
1476 debug
-> die( message
=> 'The number of logged parameter values ('.
1477 scalar @
{$param_log[0]}.
1478 ') does not match the number of logged ofv-diffs ('.
1479 scalar @
{$param_log[1]}.')' ) if ( scalar @
{$param_log[0]} !=
1480 scalar @
{$param_log[1]} );
1483 my $points = scalar(@x);
1487 while ($y[$zero] > 0){
1491 if ( $side eq 'lower' ) {
1496 @x1 = @x[$points-3..$points-1];
1497 @y1 = @y[$points-3..$points-1];
1500 my $goal = $y[$zero]+ $self -> {'ofv_increase'};
1502 my @pol = @
{$self -> _aag
( x
=> \
@x1,
1507 # print "pol: @pol\n";
1508 # print "goal: $goal\n";
1509 if( $pol[0] == 0 ) {
1510 print "The log-likelihood profile could not be approximated by a second order polynomial\n".
1511 "The output may not be correct\n";
1515 if ( $side eq 'lower' ){
1517 $guess = -$pol[1]/2/$pol[0] -
1518 (($pol[1]/2/$pol[0])**2 - ($pol[2]-$goal)/$pol[0])**(0.5);
1519 # print "guess: $guess\n";
1521 $guess = -$pol[1]/2/$pol[0] +
1522 (($pol[1]/2/$pol[0])**2 - ($pol[2]-$goal)/$pol[0])**(0.5);
1527 $guess = -$pol[1]/2/$pol[0] +
1528 (($pol[1]/2/$pol[0])**2 - ($pol[2]-$goal)/$pol[0])**(0.5);
1529 # print "guess: $guess\n";
1531 $guess = -$pol[1]/2/$pol[0] -
1532 (($pol[1]/2/$pol[0])**2 - ($pol[2]-$goal)/$pol[0])**(0.5);
1536 if ($guess eq 'nan' or $guess eq '-1.#IND' ){ #'-1.#IND' - is that a compiler spec. signal?
1537 if ( ($y[0] - $y[1]) == 0 or ($x[0] - $x[1]) == 0 or
1538 ($y[$points-1] - $y[$points-2]) == 0 or ($x[$points-1] - $x[$points-2]) == 0 ) {
1541 if ( $side eq 'lower' ){
1542 $guess = $x[0] - ($goal - $y[0]) / ( ($y[0] - $y[1])/($x[0] - $x[1]));
1544 $guess = $x[$points-1] + ($goal - $y[$points-1]) / ( ($y[$points-1] - $y[$points-2])/($x[$points-1] - $x[$points-2]));
1549 # print "Goal: $goal\n";
1550 # print LOG "X1: @x1, Y1: @y1\n";
1551 # print "Polynom: @pol\n";
1552 # print "Guess side $side: $guess\n";
1562 $number = &FormatSigFigs
($number, $sigdig );
1564 $number = sprintf( "%.4f", $number );
1565 $goal = sprintf( "%.4f", $goal );
1567 $goal = &FormatSigFigs
($goal, $sigdig );
1569 $test = $number eq $goal ?
1 : 0;
1575 # {{{ _make_new_guess
1577 start _make_new_guess
1579 # if ( not $done ) {
1581 $run{'thetas'} = (ref( $self -> {'run_thetas'} -> [0] ) eq 'ARRAY') ?
1582 $self -> {'run_thetas'} -> [$model_number-1]:$self -> {'run_thetas'};
1583 $run{'omegas'} = (ref( $self -> {'run_omegas'} -> [0] ) eq 'ARRAY') ?
1584 $self -> {'run_omegas'} -> [$model_number-1]:$self -> {'run_omegas'};
1585 $run{'sigmas'} = (ref( $self -> {'run_sigmas'} -> [0] ) eq 'ARRAY') ?
1586 $self -> {'run_sigmas'} -> [$model_number-1]:$self -> {'run_sigmas'};
1589 my $orig_model = $self -> {'models'} -> [$model_number-1];
1591 'debug' -> die( message
=> "No output object defined through model" )
1592 unless ( defined $orig_model -> outputs
-> [0] );
1593 $orig_output = $orig_model -> outputs
-> [0];
1595 # Loop over the parameter names
1596 foreach my $param ( 'theta', 'omega', 'sigma' ) {
1597 # jump to next parameter if no parameter of this type should be run
1598 next unless ( defined $run{$param.'s'} and
1599 scalar @
{$run{$param.'s'}} > 0 and
1600 $run{$param.'s'}->[0] ne '' );
1603 $orig_model -> lower_bounds
( parameter_type
=> $param );
1605 $orig_model -> upper_bounds
( parameter_type
=> $param );
1606 my $accessor = $param.'s';
1607 my @par_nums = @
{$run{$param.'s'}};
1609 my $orig_ests = $orig_output -> $accessor;
1610 my $se_accessor = 'se'.$param.'s';
1611 my $orig_se_ests = $orig_output -> $se_accessor;
1612 # Loop over the parameter numbers of interest
1613 foreach my $num ( @par_nums ) {
1614 # Loop over the problems:
1615 for ( my $j = 0; $j < scalar @
{$orig_ests}; $j++ ) {
1616 die "Subproblems are not allowed for the log-likelihood profiling tool\n"
1617 if ( scalar @
{$orig_ests->[$j]} > 1 );
1618 my $orig = $orig_ests->[$j][0][$num-1];
1619 my $upbnd = $bounds{'upper'}->[$j][$num-1];
1620 my $lobnd = $bounds{'lower'}->[$j][$num-1];
1622 if ( defined $orig_se_ests->[$j][0][$num-1] ) {
1623 $width = abs( $orig_se_ests->[$j][0][$num-1] *
1624 $self -> {'normq'} );
1625 } elsif ( defined $self -> {'rse_'.$param.'s'}->[$model_number-1]{$num} ) {
1626 $width = abs( $self -> {'rse_'.$param.'s'}->[$model_number-1]{$num}/100*abs($orig) *
1627 $self -> {'normq'} );
1629 die "No estimate of the standard error of $param $num is available from the output file nor from the command line\n";
1631 my $upper = $orig + $width;
1632 my $lower = $orig - $width;
1633 # print "Upper: $upper, lower: $lower\n";
1634 $lower = ( defined $lobnd and $lower < $lobnd ) ?
1635 ($lobnd-$orig)*0.9+$orig : $lower;
1636 $upper = ( defined $upbnd and $upper > $upbnd ) ?
1637 ($upbnd-$orig)*0.9+$orig : $upper;
1638 # print "Upbnd: $upbnd, lobnd: $lobnd\n";
1639 # print "Upper: $upper, lower: $lower\n";
1640 unshift( @
{$self->{$param.'_log'}->{$num}->[$j]->[0]}, $lower );
1641 push( @
{$self->{$param.'_log'}->{$num}->[$j]->[0]}, $upper );
1645 # Loop over the parameter numbers of interest
1646 foreach my $num ( @par_nums ) {
1647 # Loop over the problems:
1648 for ( my $j = 0; $j < scalar @
{$bounds{'lower'}}; $j++ ) {
1650 foreach my $side ( 'lower', 'upper' ) {
1651 # Is this side of the problem finished?
1652 next if $self->{$param.'_log'}->{$num}->[$j]->[2]->{$side};
1653 # Collect the model outputs
1654 debug
-> warn( level
=> 2,
1655 message
=> "Making new guess for $param number $num on the $side side" );
1656 my $bound = $bounds{$side}->[$j][$num-1];
1658 $self -> _guess
( param_log
=> $self->{$param.'_log'}->{$num}->[$j],
1660 # print "G1: $num : $guess\n";
1661 if ( defined $bounds{$side}->[$j][$num-1] ) {
1663 $self -> _try_bounds
( guess
=> $guess,
1665 bound
=> $bounds{$side}->[$j][$num-1],
1666 param_log
=> $self->{$param.'_log'}->
1669 # print "G2: $guess\n" if $num == 9;
1671 $guesses{$side} = $guess;
1672 if ( not defined $guess ) {
1673 print "Warning: The search for the $side CI-limit for $param $num ".
1674 "could not continue due to numerical difficulties\n";
1675 $self->{$param.'_log'}->{$num}->[$j]->[2]->{$side} = 1;
1678 unshift( @
{$self->{$param.'_log'}->{$num}->[$j]->[0]}, $guesses{'lower'} )
1679 if ( defined $guesses{'lower'} );
1680 push( @
{$self->{$param.'_log'}->{$num}->[$j]->[0]}, $guesses{'upper'} )
1681 if ( defined $guesses{'upper'} );
1686 # Logging must be done fairly quick, therefore this loop by itself
1687 open( DONE
, '>'.$self -> {'directory'}."/m$model_number/done" );
1688 foreach my $param ( 'theta', 'omega', 'sigma' ) {
1689 next unless ( defined $self->{$param.'_log'} );
1690 while ( my ( $num, $probs ) = each %{$self->{$param.'_log'}} ) {
1691 # Loop over the problems:
1692 for ( my $prob = 0; $prob < scalar @
{$probs}; $prob++ ) {
1693 foreach my $side ( 'lower', 'upper' ) {
1694 next if $self->{$param.'_log'}->{$num}->[$prob]->[2]->{$side};
1695 my $log_size = scalar @
{$probs -> [$prob] -> [0]};
1696 if ( $side eq 'lower' ) {
1697 print DONE
"$param $num $prob $side ",
1698 $probs -> [$prob] -> [0] -> [0],"\n";
1699 } elsif ( $side eq 'upper' ) {
1700 print DONE
"$param $num $prob $side ",
1701 $probs -> [$prob] -> [0] -> [$log_size-1],"\n";
1709 # open( DONE, $self -> {'directory'}."/m$model_number/done" );
1710 # my @rows = <DONE>;
1712 # for( my $i = 0; $i <= $#rows; $i++ ) { # skip first row
1713 # my ( $param, $num, $prob, $side, $guess ) = split(' ',$rows[$i],5);
1714 # next if $self->{$param.'_log'}->{$num}->[$prob]->[2]->{$side};
1715 # unshift( @{$self->{$param.'_log'}->{$num}->[$prob]->[0]}, $guess )
1716 # if ( $side eq 'lower' );
1717 # push( @{$self->{$param.'_log'}->{$num}->[$prob]->[0]}, $guess )
1718 # if ( $side eq 'upper' );
1724 # }}} _make_new_guess
1726 # {{{ confidence_limits
1728 start confidence_limits
1730 if ( defined $self -> {'results'} ){
1731 for ( my $i = 0; $i < scalar @
{$self -> {'results'} -> {'own'}}; $i++ ) {
1733 if ( defined $self->{'results'} -> {'own'}->[$i]->{$parameter.'_log'} ) {
1734 # print "$parameter defined\n";
1735 # print "REF: ",ref($self->{'results'}->
1736 # [$i]->{$parameter.'_log'}),"\n";
1737 # print "KEYS: ",keys %{$self->{'results'}->
1738 # [$i]->{$parameter.'_log'}},"\n";
1739 my @nums = sort {$a <=> $b} keys %{$self->{'results'} -> {'own'} ->
1740 [$i]->{$parameter.'_log'}};
1741 foreach my $num ( @nums ) {
1743 # print "REF: ",ref($self->{'results'}->
1744 # [$i]->{$parameter.'_log'}->{$num}),"\n";
1745 for ( my $j = 0; $j < scalar @
{$self->{'results'} -> {'own'}->
1746 [$i]->{$parameter.'_log'}->{$num}}; $j++ ) {
1747 my @last_lvl = @
{$self->{'results'} -> {'own'}->
1748 [$i]->{$parameter.'_log'}->{$num}->[$j]};
1749 push( @prob_lim, [$last_lvl[0][0],$last_lvl[0][scalar @
{$last_lvl[0]}-1]] );
1750 # print "REF: ",ref($self->{'results'}->
1751 # [$i]->{$parameter.'_log'}->{$num}->[$j]),"\n";
1752 # print "UP fini: ",$last_lvl[2]->{'upper'},"\n";
1753 # print "LO limit: ",$last_lvl[0][0],"\n";
1754 # print "UP limit: ",$last_lvl[0][scalar @{$last_lvl[0]}-1],"\n";
1756 $num_lim{$num} = \
@prob_lim;
1759 push( @limits, \
%num_lim );
1763 end confidence_limits
1765 # }}} confidence_limits
1771 # Run the print_results specific for the subtool
1772 my $sub_print_results = $self -> {'subtools'} -> [0];
1773 if ( defined $sub_print_results ) {
1777 my $size_ref = shift;
1779 if ( defined $arr and ref($arr) eq 'ARRAY' ) {
1780 push( @
{$size_ref}, scalar @
{$arr} );
1781 ( $dim, $size_ref ) = get_dim
( $arr->[0], $dim, $size_ref );
1783 return ( $dim, $size_ref );
1787 if ( not defined $val or $val eq '' ) {
1788 return sprintf("%10s",$PsN::output_style
).',';
1791 my $nodot = /.*\..*/ ?
0 : 1;
1793 if ( /.*\D+.*/ or $nodot) {
1794 return sprintf("%10s",$val).',';
1796 return sprintf("%10.5f",$val).',';
1800 debug
-> die( message
=> "No results_file defined" )
1801 unless ( defined $self -> {'results_file'} );
1802 open ( RES
, ">".$self -> {'directory'}.'/'.$self -> {'results_file'} );
1803 if ( defined $self -> {'results'} ) {
1804 my @all_results = @
{$self -> {'results'}};
1805 for ( my $i = 0; $i <= $#all_results; $i++ ) {
1806 if ( defined $all_results[$i]{'own'} ) {
1807 my @my_results = @
{$all_results[$i]{'own'}};
1808 for ( my $j = 0; $j <= $#my_results; $j++ ) {
1809 # These size estimates include the problem and sub_problem dimensions:
1810 my ( $ldim, $lsize_ref ) = get_dim
( $my_results[$j]{'labels'}, -1, [] );
1811 my ( $vdim, $vsize_ref ) = get_dim
( $my_results[$j]{'values'}, -1, [] );
1812 print RES
$my_results[$j]{'name'},"\n" if ( $vdim > 1 );
1813 if ( defined $my_results[$j]{'values'} and
1814 scalar @
{$my_results[$j]{'values'}} >= 0 ) {
1815 my @values = @
{$my_results[$j]{'values'}};
1817 if ( defined $my_results[$j]{'labels'} and
1818 scalar @
{$my_results[$j]{'labels'}} >= 0 ) {
1819 @labels = @
{$my_results[$j]{'labels'}};
1821 # Print Header Labels
1823 my $label = \
@labels;
1824 print RES
','.format_value
($label),"\n";
1825 } elsif ( $ldim == 2 ) {
1827 for ( my $n = 0; $n < scalar @
{$labels[1]}; $n++ ) {
1828 my $label = $labels[1][$n];
1829 print RES format_value
($label);
1831 print RES
"\n" if ( scalar @
{$labels[1]} );
1835 print RES
','.format_value
(\
@values),"\n";
1836 } elsif ( $vdim == 1 ) {
1837 for ( my $m = 0; $m < scalar @
{\
@values}; $m++ ) {
1838 my $label = $labels[$m];
1839 print RES
','.format_value
($label);
1840 my $val = $values[$m];
1841 print RES
','.format_value
($val),"\n";
1843 } elsif ( $vdim == 2 ) {
1844 for ( my $m = 0; $m < scalar @
{\
@values}; $m++ ) {
1847 $label = $labels[$m];
1848 } elsif ( $ldim == 2 ) {
1849 $label = $labels[0][$m];
1851 print RES format_value
($label);
1852 if ( defined $values[$m] ) {
1853 for ( my $n = 0; $n < scalar @
{$values[$m]}; $n++ ) {
1854 print RES format_value
($values[$m][$n]);
1867 debug
-> warn( level
=> 2,
1868 message
=> "No subtools defined".
1869 ", using default printing routine" );
1876 # {{{ create_matlab_scripts
1877 start create_matlab_scripts
1879 if( defined $PsN::lib_dir
){
1880 unless( -e
$PsN::lib_dir
. '/profiles.m') {
1881 'debug' -> die( message
=> 'LLP matlab template scripts are not installed, no matlab scripts will be generated.' );
1885 open( PROF
, $PsN::lib_dir
. '/profiles.m' );
1889 my $code_area_start=0;
1890 my $code_area_end=0;
1892 for(my $i = 0;$i < scalar(@file); $i++) {
1893 if( $file[$i] =~ /% ---------- Autogenerated code below ----------/ ){
1895 $code_area_start = $i;
1897 if( $file[$i] =~ /% ---------- End autogenerated code ----------/ ){
1898 unless( $found_code ){
1899 'debug' -> die ( message
=> 'LLP matlab template script is malformated, no matlab scripts will be generated' );
1902 $code_area_end = $i;
1907 push( @auto_code, "str_format = '%30s';\n\n" );
1911 push( @auto_code, "col_names = [ " );
1913 foreach my $param ( 'theta','omega','sigma' ) {
1914 my $labels = $self -> {'models'} -> [0] -> labels
( parameter_type
=> $param );
1915 if ( defined $labels ){
1916 foreach my $label ( @
{$labels -> [0]} ){
1917 push( @auto_code, " sprintf(str_format,'",$label,"');\n" );
1921 push( @auto_code, " ];\n\n" );
1922 push( @auto_code, "goal = 3.84;\n\n" );
1924 push( @auto_code, "filename = 'llplog1_no_header.csv';\n" );
1926 splice( @file, $code_area_start, ($code_area_end - $code_area_start), @auto_code );
1927 open( OUTFILE
, ">", $self -> {'directory'} . "/profiles.m" );
1928 print OUTFILE
"addpath " . $PsN::lib_dir
. ";\n";
1929 print OUTFILE
@file ;
1932 open( LOGFILE
, "<", $self -> {'directory'} . "/llplog1.csv" );
1933 my @log = <LOGFILE
>;
1936 open( OUTFILE
, ">", $self -> {'directory'} . "/llplog1_no_header.csv" );
1937 for( my $i = 1; $i <= $#log; $i ++ ){ #Skip header
1938 print OUTFILE
$log[$i];
1943 'debug' -> die( message
=> 'matlab_dir not configured, no matlab scripts will be generated.');
1947 end create_matlab_scripts
1950 # {{{ create_R_scripts
1951 start create_R_scripts
1953 unless( -e
$PsN::lib_dir
. '/R-scripts/llp.R' ){
1954 'debug' -> die( message
=> 'LLP R-script are not installed, no R scripts will be generated.' );
1957 cp
( $PsN::lib_dir
. '/R-scripts/llp.R', $self -> {'directory'} );
1959 end create_R_scripts