5284cb807cf66626703e5e409cc51e405352a646
[libdai.git] / scripts / convert-fastInf-DAI.pl
1 #! /usr/local/bin/perl
2 #
3 # This file is part of libDAI - http://www.libdai.org/
4 #
5 # Copyright (c) 2006-2011, The libDAI authors. All rights reserved.
6 #
7 # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
8
9
10 use strict;
11 use warnings;
12
13 my $HOME = $ENV{HOME} ;
14
15 if ($#ARGV == 0) {
16 push (@ARGV,"$ARGV[0].fg") ;
17 }
18
19 my $expectedArgc = 2 ;
20 if ($#ARGV != $expectedArgc-1) {
21 die ("Usage: $0 <inModelFile> <outModelFile>\n") ;
22 }
23
24 my ($inModelFile,$outModelFile) = @ARGV ;
25
26 # First we read the model:
27 my (@variables,@cliques,@measures,%cliq2meas,$truePartition) ;
28 &readModel ($inModelFile,\@variables,\@cliques,\@measures,\%cliq2meas,\$truePartition) ;
29
30
31 open (OUT, ">$outModelFile") or die ("[ERROR] Cannot open output file $outModelFile\n") ;
32
33 print OUT "# Converted $inModelFile from fastInf format into DAI format\n" ;
34
35 print OUT scalar(@cliques), "\n\n" ;
36
37 for (my $i=0 ; $i<scalar(@cliques) ; $i++) {
38 my $cliqLine = $cliques[$i] ;
39 my @splitCliq = split (/\t/, $cliqLine) ;
40 #print "Num vars = " , $splitCliq[1] , " vars: " , $splitCliq[2] , "\n" ;
41 print OUT $splitCliq[1], "\n" ;
42 print OUT $splitCliq[2], "\n" ;
43
44 my $meas = $cliq2meas{$i} ;
45 my $measLine = $measures[$meas] ;
46 my @splitMeas = split (/\t/, $measLine) ;
47 print OUT $splitMeas[2], "\n" ;
48
49 my @params = split (/\s+/, $splitMeas[3]) ;
50 print OUT scalar(@params) , "\n" ;
51 for (my $j=0 ; $j<scalar(@params) ; $j++) {
52 print OUT $j, " ", $params[$j], "\n" ;
53 }
54 print OUT "\n" ;
55 }
56
57 close OUT ;
58
59
60
61 #################
62 ## Subroutines ##
63 #################
64 sub readModel {
65 my ($modelFile,$variables,$cliques,$measures,$cliq2meas,$truePartition) = @_ ;
66
67 open (MOD_IN , "<$modelFile") or die ("[ERROR] Cannot read model from $modelFile\n") ;
68
69 while (defined (my $line=<MOD_IN>)) {
70
71 if ($line =~ m/^\@Variables/) {
72 &readLines (*MOD_IN , $variables) ;
73 }
74 elsif ($line =~ m/^\@Cliques/) {
75 &readLines (*MOD_IN , $cliques) ;
76 }
77 elsif ($line =~ m/^\@Measures/) {
78 &readLines (*MOD_IN , $measures) ;
79 }
80 elsif ($line =~ m/^\@CliqueToMeasure/) {
81 &readCliq2Meas (*MOD_IN , $cliq2meas) ;
82 }
83 elsif ($line =~ m/^# Exact Partitition function:/) {
84 my $partLine ;
85 if (not defined ($partLine = <MOD_IN>)) { die ("[ERROR] Cannot read exact partition function."); }
86 if ($partLine =~ m/^# (\S+)/) {
87 $$truePartition = $1 ;
88 }
89 }
90 # else do nothing
91
92 } # while read line from model file
93
94 close MOD_IN ;
95 }
96
97 sub readLines {
98 my ($IN,$variables) = @_ ;
99
100 my $endReached = 0 ;
101 while (defined (my $line = <$IN>)) {
102 if ($line =~ m/^\@End/) {
103 $endReached = 1 ;
104 last ;
105 }
106 else {
107 push (@$variables,$line) ;
108 }
109 }
110
111 if (not $endReached) { die ("[ERROR] Could not find \@End statement.\n") ; }
112 }
113
114 sub readCliq2Meas {
115 my ($IN,$cliq2meas) = @_ ;
116
117 my $endReached = 0 ;
118 while (defined (my $line = <$IN>)) {
119 if ($line =~ m/^\@End/) {
120 $endReached = 1 ;
121 last ;
122 }
123 else {
124 my @splitLine = split(/\t/,$line) ;
125 my $cliq = $splitLine[0] ;
126 my $meas = $splitLine[1] ;
127 $cliq2meas->{$cliq} = $meas ;
128 }
129 }
130
131 if (not $endReached) { die ("[ERROR] Could not find \@End statement.\n") ; }
132 }