package Ernad::Eval; use strict; use warnings; use Carp qw(cluck longmess shortmess croak confess); use Data::Dumper; sub init_outcome { my $rela=shift or confess "I need a rela number here."; my $nobs=shift or confess "I need a nobs number here."; ## take the larger to be the n if($rela>$nobs) { confess "parameter order is rela, nobs"; } my $start=1; my $out; $out->[0]=$nobs; my $count=1; while($count<=$rela) { $out->[$count]=$count; $count++; } return $out; } sub print_outcome { my $in=shift; my $indent=shift // 0; my $to_print=&show_outcome($in,$indent); print $to_print, "\n"; } sub show_outcome { my $in=shift; my $indent=shift // 0; my $print=''; my $count=0; while($count++<=$indent) { $print.=' '; } $print.=&show_in($in).' '; $print.=&expand($in); return $print; } sub create_simul_outcomes { my $rela=shift or confess "I need a rela number here."; my $nobs=shift or confess "I need a nobs number here."; if($rela>$nobs) { confess "parameter order is rela, nobs"; } my $s; my $count=0; my $outcome=&init_outcome($rela,$nobs); my $c=0; while(defined($outcome->[$c])) { $s->[$count]->[$c]=$outcome->[$c]; $c++; } while($outcome=&next_outcome($outcome)) { $count++; my $c=0; while(defined($outcome->[$c])) { $s->[$count]->[$c]=$outcome->[$c]; $c++; } } return $s; } sub expand { my $in=shift; my @obs=@{$in}; my $nobs=shift @obs; my $rela=scalar(@obs); ## create a hash my $rel; my $count; $count=0; while($count<$rela) { $rel->{$obs[$count]}=1; $count++; } $count=1; my $out='['; while($count<$nobs+1) { if(defined($rel->{$count})) { $out.='1,'; } else { $out.='0,'; } $count++; } chop $out; $out.=']'; return $out; } sub simul_outcomes { my $rela=shift or confess "I need a rela number here."; my $nobs=shift or confess "I need a nobs number here."; my $funref=shift or confess "I need a function reference here."; my $verbose=shift // 1; if($rela>$nobs) { confess "parameter order is rela, nobs"; } my $outcome=&init_outcome($rela,$nobs); my $old_result; my $result=&{$funref}($outcome,$verbose); my $sum=$result; while($outcome=&next_outcome($outcome)) { if(not defined($old_result)) { $old_result=1; } ## funref takes the outcome and a verbosity ## with valiues 0,1 or 2 my $result=&{$funref}($outcome,$verbose); $sum+=$result; if($result>$old_result) { die "violation of natural order"; } $old_result=$result; } print "sum is $sum\n"; } sub show_simuls { my $rela=shift or confess "I need a rela number here."; my $nobs=shift or confess "I need a nobs number here."; if($rela>$nobs) { confess "parameter order is rela, nobs"; } my $outcome=&init_outcome($rela,$nobs); my $show_in=&show_in($outcome); my $expand=&expand($outcome); print "$show_in $expand\n"; my $old_result; my $count_simul=1; while($outcome=&next_outcome($outcome)) { $count_simul++; my $show_in=&show_in($outcome); my $expand=&expand($outcome); print "$show_in $expand\n"; } my $count_in_set=&count_in_set($rela,$nobs); if($count_in_set != $count_simul) { die "count_in_set $count_in_set, count_simul $count_simul"; } } sub factorial { my $n=shift; my $count=0; my $result=1; while($count++<$n) { $result=$result*$count; print "count $count result $result\n"; } return $result; } sub count_in_set { my $rela=shift or confess "I need a rela number here."; my $nobs=shift or confess "I need a nobs number here."; if($rela>$nobs) { confess "parameter order is rela, nobs"; } return factorial($nobs)/factorial($rela)/factorial($nobs-$rela); } sub next_outcome { my $in=shift or confess "I need in input to increment from."; my @obs=@{$in}; my $nobs=shift @obs; my $rela=scalar(@obs); my $count=1; my $done=''; while($count<$rela) { ## maximum number if($obs[$count-1]>$nobs-$rela+$count-1) { return ''; } my $delta=$obs[$count]-$obs[$count-1]; if($delta == 1) { $count++; next; } if($obs[$count-1]<$nobs) { $obs[$count-1]++; my $c=1; ## reset the lower parts while($c<$count) { $obs[$c-1]=$c; $c++; } $done=1; last; } $count++; } if(not $done and $obs[$rela-1]<$nobs) { $obs[$rela-1]++; my $c=1; ## reset the lower parts while($c<$rela) { $obs[$c-1]=$c; $c++; } $done=1; } ## nothing found any more if(not $done) { return ''; } $count=1; while(defined($in->[$count])) { $in->[$count]=$obs[$count-1]; $count++; } return $in; } sub show_in { my $in=shift; my $in_print=Dumper $in; $in_print=~s|\n||g; $in_print=~s|\s+||g; $in_print=~s|;||g; $in_print=~s|\$VAR1\s*=\s*||; return $in_print; } 1; # [5,1,2,3] [1,1,1,0,0] # [5,1,2,4] [1,1,0,1,0] # [5,1,3,4] [1,0,1,1,0] # [5,2,3,4] [0,1,1,1,0] # [5,1,2,5] [1,1,0,0,1] # [5,1,3,5] [1,0,1,0,1] # [5,2,3,5] [0,1,1,0,1] #*[5,1,4,5] [1,0,0,1,1] # [5,2,4,5] [0,1,0,1,1] # [5,3,4,5] [0,0,1,1,1]