#!/usr/bin/perl #process data on spherical unitary representations and write a report #data from stembridge, barbasch or yu (different formats) BEGIN{unshift(@INC, '/home/atlas/www/perl');} use strict; use Math::Fraction; use Getopt::Long qw(:config no_ignore_case); use vars qw(@INC $format $facets $dataFile $dir $outFile $closures $compare $testMatrices $help $type $outFile $note $verbose); use Data::Dumper; use rootSystem; use rootSystem; my %options=('f' => \$facets, 'd' => \$dataFile, 'F' => \$format, 'C' => \$compare, 'h' => \$help, 'c' => \$closures, 'D' => \$dir, 't' => \$type, 'o' => \$outFile, 'n' => \$note, 'T' => \$testMatrices, 'v' => \$verbose ); GetOptions(\%options,qw(f=s d=s F=s c! C! T! D=s h! o=s t=s n=s v!)); if ($help||!($compare||$format||$facets||$dataFile||$outFile||$dir||$testMatrices)){ help(); exit; } if ($dir){ $dir = "$dir/" unless ($dir =~ /\/$/); } print "dir:$dir\n" if ($verbose); $dataFile||='data'; if ($compare){ compare(); exit; } unless ($type){ $type=$dir; unless ($type){ print "You must enter a type with -t unless it is given by -D\n"; exit; } $type =~ s/\/$//; $type =~ s/.*\///g; $type =~ s/data//; } my $rank=$type; $rank =~ s/^.//; $type =~ s/[0-9]*//g; print "type:$type\nrank:$rank\n" if ($verbose); my $flip; $flip='flip' if ($type =~ /B|C|D/); my $fundamentalWeights=rootSystem::fundamentalWeights($type,$rank,$flip); my $simpleCoRoots=rootSystem::simpleCoRoots($type,$rank,$flip); if ($testMatrices){ print "Testing matrices for $type$rank\n"; # my $s=rootSystem::transpose(rootSystem::getSimpleCoRoots($type,$rank)); # my $f=rootSystem::getFundamentalWeights($type,$rank); &_testMatrices($fundamentalWeights,$simpleCoRoots); #make sure these are inverses exit; } my $data=&readData(); &report($data); sub readData{ print "readData\n" if ($verbose); my @data; my @lineNumbers; my $lineNumber=0; open(IN,"<$dir$dataFile")||die("Can't open $dir$dataFile"); my @posCoRoots; foreach my $line (){ # print "LINE:", $line; next unless $line =~ /^[0-9]/; $line =~ s/.*\[(.*)\].*/\1/; my @line = split ',', $line; push @posCoRoots, \@line; } # print "pcr:", join ',', @posCoRoots; close(IN); open(IN,"<$dir$facets")||die("Can't open $dir$facets"); foreach my $line (){ my @point; my %item; my $index=1; $lineNumber++; if ($format eq 's'){ last if ($line =~ /end/); next unless ($line =~ /^\[/); $line =~ s/\[(.*)\].*/\1/; @point = split ',', $line; @point = makeFrac(@point); $item{'point'}=\@point; $item{'lineNumber'}=$lineNumber; my @pointStandard=@{matrixMult([\@point],$fundamentalWeights)->[0]}; @pointStandard=makeFrac(@pointStandard); $item{'pointStandard'}=\@pointStandard; }elsif ($format eq 'b'){ # next unless ($line =~ /^[\|(]{/); next unless ($line =~ /^[{|(]/); $line =~ s/\{|\}.*//g; $line =~ s/\(|\).*//g; chomp $line; my @pointStandard = split ',', $line; @pointStandard=makeFrac(@pointStandard); @point=@{matrixMult([\@pointStandard],transpose($simpleCoRoots))->[0]}; $item{'point'}=\@point; $item{'lineNumber'}=$lineNumber; $item{'pointStandard'}=\@pointStandard; }else{ print "You didn't specify a format -F s or -F b\n"; exit; } my @chamber; my $dimension=scalar(@point); foreach my $coRoot (@posCoRoots){ my $sign= myDotProduct(\@point,$coRoot); if ($sign <1){ push @chamber, '-'; }elsif ($sign == 1){ push @chamber, '1'; $dimension = $dimension-1; }else{ push @chamber, '+'; } } $dimension=0 if ($dimension<0); $item{'chamber'}=\@chamber; $item{'dimension'}=$dimension; push @data, \%item; } close(IN); my @dataTmp=sort {$b->{'dimension'} <=> $a->{'dimension'} || (join '', @{$b->{'chamber'}}) cmp (join '', @{$a->{'chamber'}})} @data; # foreach my $i (0..$#dataTmp){ # print "\n", join ',', @{$dataTmp[$i]->{'chamber'}}; # } @data=($dataTmp[0]); foreach my $i (1..$#dataTmp){ my $new=join '', @{$dataTmp[$i]->{'chamber'}}; my $previous=join '', @{$data[-1]->{'chamber'}}; # print "\n$new:\n$previous:\n"; if ($new eq $previous){ # print "SAME"; next; } push @data, $dataTmp[$i]; } return \@data; } sub makeFrac{ my @vector=@_; foreach my $i (0..$#vector){ my $x=$vector[$i]; next unless ($x =~ /\//); my ($n,$d) = ($x =~ /([0-9-]+)\/([0-9]+)/); $vector[$i]=frac($n,$d); } return @vector; } sub myDotProduct{ my ($a,$b)=@_; my @a=@$a; my @b=@$b; my $rv=0; foreach my $i (0..$#a){ $rv += $a[$i]*$b[$i]; } return $rv; } sub report{ my $data=shift; my @data=@$data; open (STDOUT,">$dir$outFile") if ($outFile); print "Generated by sphericalReport.pl ",scalar localtime(),"\n"; print "Data from $dir$facets\n"; print "$note\n" if ($note); print "List of positive coroots from $dir$dataFile\n"; print "Dynkin Diagram: "; print rootSystem::diagram($type,$rank,$flip); print "\n"; print "\nNumber of facets of each dimension: "; my $facetsByDimension=&summary($data); foreach my $i (0..$rank){ print $rank-$i,":",$facetsByDimension->{$rank-$i}," "; } print "\nTotal number of facets: ", scalar(@data),"\n\n"; print "[number(line number)] dimension (standard){weight}\n"; my $flip='flip' if ($type =~ /B|C|D/); my $fundamentalWeights=rootSystem::fundamentalWeights($type,$rank,$flip); foreach my $i (0..$#data){ my $item =$data[$i]; my $point=$item->{'point'}; $point = join ',', @$point; $point =~ s/ //g; $point =~ s/\/1,/,/g; $point =~ s/\/1$//g; chomp $point; my @pointStandard=@{$item->{'pointStandard'}}; my $pointStandard = join ',', @pointStandard; $pointStandard =~ s/ //g; $pointStandard =~ s/\/1,/,/g; $pointStandard =~ s/\/1$//g; chomp $pointStandard; my $chamber=$item->{'chamber'}; $chamber = join ',', @$chamber; my $dimension=$item->{'dimension'}; my $lineNumber=$item->{'lineNumber'}; my $index=$i+1; print "[$index($lineNumber)] $dimension ($pointStandard) {$point} <$chamber>"; print "\n"; } if ($closures){ my $closureRelations=closureRelations($data); reportFacetClosures($data,$closureRelations); print "\nClosure Matrix:\n"; foreach my $i (0..$#{@$closureRelations}){ print join ',', @{$closureRelations->[$i]}; print "\n"; } } close(STDOUT); print "\n\nDONE\n"; } sub summary{ my $data=shift; my %facetsByDimension; foreach my $i (0..$rank){ $facetsByDimension{$i}=0; } foreach my $facet (@$data){ $facetsByDimension{$facet->{'dimension'}} +=1; } return \%facetsByDimension; } sub closureRelations{ my $data=shift; my @data=@$data; my @closureRelations; foreach my $i (0..$#data){ $closureRelations[$i][$i] ='+'; foreach my $j ($i+1..$#data){ $closureRelations[$i][$j]=0; $closureRelations[$j][$i]=0; my @chamberi=@{$data[$i]->{'chamber'}}; my @chamberj=@{$data[$j]->{'chamber'}}; my $noRelation=0; my $i_inClosure_j=0; my $j_inClosure_i=0; K: foreach my $k (0..$#chamberi){ my $signik=$chamberi[$k]; my $signjk=$chamberj[$k]; if ((($signik eq '+')&&($signjk eq '-')) || (($signik eq '-')&&($signjk eq '+'))){ $noRelation=1; last K; } if (($signik eq '1') && ($signjk =~ /\+|\-/)){ if ($j_inClosure_i){ $noRelation=1; last K; }else{ $i_inClosure_j=1; } } if (($signjk eq '1') && ($signik =~ /\+|\-/)){ if ($i_inClosure_j){ $noRelation=1; last K; }else{ $j_inClosure_i=1; } } } unless ($noRelation){ if ($j_inClosure_i){ $closureRelations[$i][$j]='+'; $closureRelations[$j][$i]='-'; } if ($i_inClosure_j){ $closureRelations[$i][$j]='-'; $closureRelations[$j][$i]='+'; } } } } return \@closureRelations; } sub reportFacetClosures{ my $data=shift; my $closureRelations=shift; print "\nFacet Closures [Facet number/dimension]\n"; my @maximal; my @nonMaximal; foreach my $i (0..$#{@$closureRelations}){ my @row=@{$closureRelations->[$i]}; if (grep {/-/} @row){ push @nonMaximal, $i; }else{ push @maximal,$i; } } print " Maximal Facets:\n "; foreach my $i (@maximal){ print "[",$i+1,"/$data->[$i]->{'dimension'}]:"; my @row=@{$closureRelations->[$i]}; foreach my $j (0..$#row){ print "[",$j+1,"/$data->[$j]->{'dimension'}]" if ($row[$j] eq '+'); } print "\n "; } print "\n Other Facets:\n "; foreach my $i (@nonMaximal){ print "[",$i+1,"/$data->[$i]->{'dimension'}]:"; my @row=@{$closureRelations->[$i]}; foreach my $j (0..$#row){ print "[",$j+1,"/$data->[$j]->{'dimension'}]" if ($row[$j] eq '+'); } print "\n "; } print "\n"; } # sub getFundamentalWeights{ # # my $type=shift; # # my $rank=$type; # # $rank =~ s/^.//; # # $type =~ s/[0-9]*//g; # my @fundamentalWeights; # if ($type eq 'A'){ # my $n=$rank+1; # foreach my $i (1..$rank){ # push @fundamentalWeights, [ (frac($n-$i,$n))x$i, (frac(-$i,$n))x($n-$i)]; # } # } # elsif ($type eq 'B'){ # foreach my $i (1..$rank-1){ # push @fundamentalWeights, [ (1)x$i, (0)x($rank-$i)]; # } # push @fundamentalWeights, [(1/2)x$rank]; # } # elsif ($type eq 'C'){ # foreach my $i (1..$rank){ # push @fundamentalWeights, [ (1)x$i, (0)x($rank-$i)]; # } # } # elsif ($type eq 'D'){ # foreach my $i (1..$rank-2){ # push @fundamentalWeights, [ (1)x$i, (0)x($rank-$i)]; # } # push @fundamentalWeights, [(1/2)x($rank-1),(-1/2)]; # push @fundamentalWeights, [(1/2)x$rank]; # } # elsif ($type eq 'F'){ # @fundamentalWeights=([1,0,0,0],[3/2,1/2,1/2,1/2],[2,1,1,0],[1,1,0,0]); # } # elsif ($type eq 'G'){ # @fundamentalWeights=([0,-1,1],[-1,-1,2]); # } # elsif ($type eq 'E'){ # if ($rank == 6){ # @fundamentalWeights=([0,0,0,0,0,-2/3,-2/3,2/3], # [1/2,1/2,1/2,1/2,1/2,-1/2,-1/2,1/2], # [-1/2,1/2,1/2,1/2,1/2,-5/6,-5/6,5/6], # [0,0,1,1,1,-1,-1,1], # [0,0,0,1,1,-2/3,-2/3,2/3], # [0,0,0,0,1,-1/3,-1/3,1/3]); # } # elsif ($rank == 7){ # @fundamentalWeights=([0,0,0,0,0,0,-1,1], # [1/2,1/2,1/2,1/2,1/2,1/2,-1,1], # [-1/2,1/2,1/2,1/2,1/2,1/2,-3/2,3/2], # [0,0,1,1,1,1,-2,2], # [0,0,0,1,1,1,-3/2,3/2], # [0,0,0,0,1,1,-1,1], # [0,0,0,0,0,1,-1/2,1/2]); # } # elsif ($rank == 8){ # @fundamentalWeights=([0,0,0,0,0,0,00,2], # [1/2,1/2,1/2,1/2,1/2,1/2,1/2,5/8], # [-1/2,1/2,1/2,1/2,1/2,1/2,1/2,7/8], # [0,0,1,1,1,1,1,5], # [0,0,0,1,1,1,1,4], # [0,0,0,0,1,1,1,3], # [0,0,0,0,0,1,1,2], # [0,0,0,0,0,0,1,1]) # } # } # return \@fundamentalWeights; # } # sub getSimpleCoRoots{ # my @simpleCoRoots; # if ($type eq 'A'){ # my $r=$rank+1; #number of rows # my $c=$rank; #number of columns # @simpleCoRoots = [1,(0)x($c-1)]; # foreach my $i (2..$r-1){ # push @simpleCoRoots, [(0)x($i-2), -1,1,(0)x($c-$i)]; # } # push @simpleCoRoots, [(0)x($c-1),(-1)]; # } # elsif ($type eq 'B'){ # @simpleCoRoots = [1,(0)x($rank-1)]; # foreach my $i (2..$rank-1){ # push @simpleCoRoots, [(0)x($i-2), -1,1,(0)x($rank-$i)]; # } # push @simpleCoRoots, [(0)x($rank-2),(-1,2)]; # } # elsif ($type eq 'C'){ # @simpleCoRoots = [1,(0)x($rank-1)]; # foreach my $i (2..$rank-1){ # push @simpleCoRoots, [(0)x($i-2), -1,1,(0)x($rank-$i)]; # } # push @simpleCoRoots, [(0)x($rank-2),(-1,1)]; # } # elsif ($type eq 'D'){ # @simpleCoRoots = [1,(0)x($rank-1)]; # foreach my $i (2..$rank-2){ # push @simpleCoRoots, [(0)x($i-2), -1,1,(0)x($rank-$i)]; # } # push @simpleCoRoots, [(0)x($rank-3),(-1,1,1)]; # push @simpleCoRoots, [(0)x($rank-2),(-1,1)]; # } # elsif ($type eq 'F'){ # @simpleCoRoots=([1,0,0,0],[-1,0,0,1],[-1,0,1,-1],[-1,2,-1,0]); # } # elsif ($type eq 'G'){ # @simpleCoRoots=([1,-2/3],[-1,1/3],[0,1/3]); # } # elsif ($type eq 'E'){ # if ($rank == 6){ # @simpleCoRoots=( # [1/2,1,-1,0,0,0], # [-1/2,1,1,-1,0,0], # [-1/2,0,0,1,-1,0], # [-1/2,0,0,0,1,-1], # [-1/2,0,0,0,0,1], # [-1/2,0,0,0,0,0], # [-1/2,0,0,0,0,0], # [1/2,0,0,0,0,0]); # }elsif ($rank == 7){ # @simpleCoRoots=([1/2,1,-1,0,0,0,0], # [-1/2,1,1,-1,0,0,0], # [-1/2,0,0,1,-1,0,0], # [-1/2,0,0,0,1,-1,0], # [-1/2,0,0,0,0,1,-1], # [-1/2,0,0,0,0,0,1], # [-1/2,0,0,0,0,0,0], # [1/2,0,0,0,0,0,0]); # }elsif ($rank == 8){ # @simpleCoRoots=([1/2,1,-1,0,0,0,0,0], # [-1/2,1,1,-1,0,0,0,0], # [-1/2,0,0,1,-1,0,0,0], # [-1/2,0,0,0,1,-1,0,0], # [-1/2,0,0,0,0,1,-1,0], # [-1/2,0,0,0,0,0,1,-1], # [-1/2,0,0,0,0,0,0,1], # [1/2,0,0,0,0,0,0,0]); # } # } # return \@simpleCoRoots; # } sub compare{ my $file1="$dir".$ARGV[0]; my $file2="$dir".$ARGV[1]; my $data1=readReport($file1); my $data2=readReport($file2); my @chambers1=keys(%$data1); my @chambers2=keys(%$data2); open(OUT,">$dir$outFile")||die("Can't open $outFile for output"); print "Comparing files $file1 $file2\n"; print "Generated by sphericalReport.pl ",scalar localtime(),"\n\n"; print "$note\n" if ($note); print "In file 1 but not file 2:\n"; print OUT "Comparing files $file1 $file2\n"; print OUT "$note\n" if ($note); print OUT "Generated by sphericalReport.pl ",scalar localtime(),"\n\n"; print OUT "In file 1 but not file 2:\n"; my $missed=0; foreach my $chamber (@chambers1){ next if ($data2->{$chamber}); $missed=1; print $data1->{$chamber}->[0]; print OUT $data1->{$chamber}->[0]; } print "None\n" unless ($missed>0); print OUT "None\n" unless ($missed>0); $missed=0; print "\nIn file 2 but not file 1:\n"; print OUT "\nIn file 2 but not file 1:\n"; foreach my $chamber (@chambers2){ next if ($data1->{$chamber}); $missed=1; print $data2->{$chamber}->[0]; print OUT $data2->{$chamber}->[0]; } print "None\n" unless ($missed>0); print OUT "None\n" unless ($missed>0); print "\n"; print OUT "\n"; print "In both files:\n[number(line) file 1][number(line) file 2] dimension (standard file 1){weight file 1}(standard file 2){weight file 2}\n"; print OUT "In both files:\n[number(line) file 1][number(line) file 2] dimension (standard file 1){weight file 1}(standard file 2){weight file 2}\n"; my @both; foreach my $chamber (@chambers1){ next unless (($data1->{$chamber}) and ($data2->{$chamber})); my $row1=$data1->{$chamber}; my $row2=$data2->{$chamber}; push @both, "[$row1->[1]][$row2->[1]] $row1->[2] ($row1->[3]){$row1->[4]}($row2->[3]){$row2->[4]}<$chamber>\n"; } @both = sort { my $A=$a; $A =~ s/^\[([0-9]*).*/\1/;my $B=$b; $B=~ s/^\[([0-9]*).*/\1/; $A <=> $B;} @both; print join '', @both; print OUT join '', @both; close(OUT); } sub readReport{ my $file=shift; open(IN,"<$file")||die("Can't open $file for input"); my %data; # [8(121)] 2 (13/16,13/48,7/48,1/16) {1/8,1/12,1/8,1/3} <-,-,-,-,-,-,-,-,-,1,-,-,-,+,-,-,+,-,+,-,+,1,+,+> foreach my $line (){ next unless $line =~ /^\[/; my $row=$line; my ($label,$dim,$pointStandard,$pointWeight,$chamber) = ($row =~ /\[(.*)\] ([0-9]*) \((.*)\) {(.*)} <(.*)>/); next unless ($chamber); $data{$chamber}=[$line,$label,$dim,$pointStandard,$pointWeight]; } return \%data; } sub matrixMultOld { my ($m1,$m2) = @_; # print "m1,m2",Dumper($m1),Dumper($m2); my ($m1rows,$m1cols) = matrixDim($m1); my ($m2rows,$m2cols) = matrixDim($m2); unless ($m1cols == $m2rows) { # raise exception print "ERROR"; # print "\nm1:",Dumper($m1); # print "\nm2:",Dumper($m2); die "IndexError: matrices don't match: $m1cols != $m2rows"; } my $result = []; my ($i, $j, $k); for $i (range($m1rows)) { for $j (range($m2cols)) { for $k (range($m1cols)) { $result->[$i][$j] += $m1->[$i][$k] * $m2->[$k][$j]; } } } # print "m1:",Dumper($m1);print "m2:",Dumper($m2);print "result:", Dumper($result); return $result; } sub range { 0 .. ($_[0] - 1) } sub matrixDim { my $matrix = $_[0]; my $rows = scalar(@$matrix); my $cols = scalar(@{$matrix->[0]}); return ($rows, $cols); } sub _testMatrices{ my $f=shift; my $s=shift; my @test=@{matrixMult($f,$s)}; print "\n\n"; print "f:\n"; print showMatrix($f); print "s:\n"; print showMatrix($s); print "product:\n";print showMatrix(\@test); # foreach my $i (0..$#test){ # print join ',', @{$test[$i]}; # print "\n"; # } } sub showMatrix{ my $m=shift; my @m=@$m; foreach my $i (0..$#m){ print join ',', @{$m[$i]}; print "\n"; } } sub help{ print <