| 1 | package felix.operator; |
| 2 | |
| 3 | import java.io.BufferedReader; |
| 4 | import java.io.BufferedWriter; |
| 5 | import java.io.FileInputStream; |
| 6 | import java.io.FileWriter; |
| 7 | import java.io.InputStream; |
| 8 | import java.io.InputStreamReader; |
| 9 | import java.sql.Array; |
| 10 | import java.util.ArrayList; |
| 11 | import java.util.Arrays; |
| 12 | import java.util.Date; |
| 13 | import java.util.HashMap; |
| 14 | import java.util.HashSet; |
| 15 | |
| 16 | import org.apache.commons.collections.Bag; |
| 17 | import org.apache.commons.collections.bag.HashBag; |
| 18 | import org.postgresql.PGConnection; |
| 19 | |
| 20 | |
| 21 | import tuffy.db.RDB; |
| 22 | import tuffy.mln.Literal; |
| 23 | import tuffy.ra.ConjunctiveQuery; |
| 24 | import tuffy.util.Config; |
| 25 | import tuffy.util.ExceptionMan; |
| 26 | import tuffy.util.FileMan; |
| 27 | import tuffy.util.StringMan; |
| 28 | import tuffy.util.Timer; |
| 29 | import tuffy.util.UIMan; |
| 30 | import felix.dstruct.DataMovementOperator; |
| 31 | import felix.dstruct.FelixPredicate; |
| 32 | import felix.dstruct.FelixQuery; |
| 33 | import felix.dstruct.StatOperator; |
| 34 | import felix.dstruct.FelixPredicate.FPProperty; |
| 35 | import felix.parser.FelixCommandOptions; |
| 36 | import felix.util.FelixConfig; |
| 37 | import felix.util.FelixStringMan; |
| 38 | import felix.util.FelixUIMan; |
| 39 | |
| 40 | /** |
| 41 | * A LR operator in Felix. |
| 42 | * @author Ce Zhang |
| 43 | * |
| 44 | */ |
| 45 | public class LROperator extends StatOperator{ |
| 46 | |
| 47 | /** |
| 48 | * Target predicate of this LR operator. |
| 49 | */ |
| 50 | FelixPredicate lrHead; |
| 51 | |
| 52 | |
| 53 | /** |
| 54 | * Mapping from label's constant ID to a new label ID. This new label ID is from 0, which |
| 55 | * is used in the inference of LR (s.t., we can use array to represent |
| 56 | * labels). |
| 57 | */ |
| 58 | HashMap<String, Integer> label2ID = new HashMap<String, Integer>(); |
| 59 | |
| 60 | /** |
| 61 | * The inverse map of {@link LROperator#label2ID}. |
| 62 | */ |
| 63 | HashMap<Integer, String[]> id2Label = new HashMap<Integer, String[]>(); |
| 64 | |
| 65 | /** |
| 66 | * All DataMovementOperators used as LR rules. |
| 67 | */ |
| 68 | ArrayList<DataMovementOperator> lrDMOs = new ArrayList<DataMovementOperator>(); |
| 69 | |
| 70 | /** |
| 71 | * The DataMovementOperator which is the union of all LR rules. |
| 72 | */ |
| 73 | DataMovementOperator lrDMO = null; |
| 74 | |
| 75 | /** |
| 76 | * The DataMovementOperator representing the table/view for all unigram features. |
| 77 | */ |
| 78 | DataMovementOperator unigramDMO = null; |
| 79 | |
| 80 | /** |
| 81 | * The DataMovementOperator representing the table/view for all possible labels. |
| 82 | */ |
| 83 | DataMovementOperator labelDomainDMO = null; |
| 84 | |
| 85 | /** |
| 86 | * The DataMovementOperator fetching all unigram features. |
| 87 | */ |
| 88 | DataMovementOperator getAllUnigramFeaturesDMO = null; |
| 89 | |
| 90 | /** |
| 91 | * @deprecated |
| 92 | */ |
| 93 | DataMovementOperator getAllLearningFeatureDMO = null; |
| 94 | |
| 95 | /** |
| 96 | * @deprecated |
| 97 | */ |
| 98 | DataMovementOperator getGroundTruthDMO = null; |
| 99 | |
| 100 | /** |
| 101 | * @deprecated |
| 102 | */ |
| 103 | DataMovementOperator getFeatureTableDMO = null; |
| 104 | |
| 105 | /** |
| 106 | * The constructor of LROperator. |
| 107 | * @param _fq Felix query. |
| 108 | * @param _goalPredicates target predicates of this coref operator. |
| 109 | * @param _opt Command line options of this Felix run. |
| 110 | */ |
| 111 | public LROperator(FelixQuery _fq, HashSet<FelixPredicate> _goalPredicates, |
| 112 | FelixCommandOptions _opt) { |
| 113 | super(_fq, _goalPredicates, _opt); |
| 114 | this.type = OPType.LR; |
| 115 | this.precedence = 4; |
| 116 | |
| 117 | } |
| 118 | |
| 119 | /** |
| 120 | * Adds object to domain if necessary. |
| 121 | * @param obj |
| 122 | * @param map |
| 123 | * @return |
| 124 | */ |
| 125 | public <E> Integer getAndAddToDomain(E obj, HashMap<String, Integer> map){ |
| 126 | int rs; |
| 127 | if(map.containsKey(obj.toString())){ |
| 128 | return map.get(obj.toString()); |
| 129 | } |
| 130 | rs = map.size() + 1; |
| 131 | map.put(obj.toString(), rs); |
| 132 | return rs; |
| 133 | } |
| 134 | |
| 135 | /** |
| 136 | * @deprecated |
| 137 | */ |
| 138 | @Override |
| 139 | public void learn() { |
| 140 | |
| 141 | } |
| 142 | |
| 143 | |
| 144 | boolean prepared = false; |
| 145 | |
| 146 | /** |
| 147 | * Prepares operator for execution. |
| 148 | */ |
| 149 | @Override |
| 150 | public void prepare() { |
| 151 | |
| 152 | lrDMOs.clear(); |
| 153 | allDMOs.clear(); |
| 154 | |
| 155 | //if(!prepared){ |
| 156 | |
| 157 | db = RDB.getRDBbyConfig(Config.db_schema); |
| 158 | |
| 159 | lrHead = this.getTargetPredicateIfHasOnlyOne(); |
| 160 | |
| 161 | HashSet<ConjunctiveQuery> lrQueries; |
| 162 | |
| 163 | if(options.isDLearningMode){ |
| 164 | //lrQueries = |
| 165 | // this.translateFelixClasesIntoLearningQueriesForVictor(lrHead, FPProperty.NON_RECUR); |
| 166 | //this.prepareDMO4ForLearning(lrQueries); |
| 167 | |
| 168 | }else{ |
| 169 | lrQueries = |
| 170 | this.translateFelixClasesIntoFactorGraphEdgeQueries(lrHead, false, this.inputPredicateScope, FPProperty.NON_RECUR); |
| 171 | this.prepareDMO(lrQueries); |
| 172 | } |
| 173 | |
| 174 | prepared = true; |
| 175 | |
| 176 | //db.close(); |
| 177 | |
| 178 | //} |
| 179 | |
| 180 | } |
| 181 | |
| 182 | |
| 183 | /** |
| 184 | * Returns string representation of string array. |
| 185 | * @param _array |
| 186 | * @return |
| 187 | */ |
| 188 | String array2str(String[] _array){ |
| 189 | String ret = ""; |
| 190 | for(String s : _array){ |
| 191 | ret = ret + ":" + s; |
| 192 | } |
| 193 | return ret; |
| 194 | } |
| 195 | |
| 196 | /** |
| 197 | * Executes operator. |
| 198 | */ |
| 199 | @Override |
| 200 | public void run() { |
| 201 | |
| 202 | if(options.isDLearningMode){ |
| 203 | this.learn(); |
| 204 | }else{ |
| 205 | |
| 206 | this.isMarginal = belongsToBucket.isMarginal(); |
| 207 | |
| 208 | UIMan.println(">>> Start Running " + this); |
| 209 | |
| 210 | ArrayList<Integer> nonZeroWeights = new ArrayList<Integer>(); |
| 211 | |
| 212 | try{ |
| 213 | |
| 214 | Timer.start("LR-Operator-" + lrHead.getName()); |
| 215 | |
| 216 | BufferedWriter bw = new BufferedWriter( |
| 217 | new FileWriter(Config.getLoadingDir() + "/_loading_lr_" + lrHead.getName() + this.getId())); |
| 218 | |
| 219 | // get the domain of Label, and assign them an integer ID (start from 0, s.t., we |
| 220 | // can use array to store them |
| 221 | int labelID = 0; |
| 222 | int nLabelFileds = lrHead.getLabelFieldsArgs().size(); |
| 223 | if(this.labelDomainDMO != null){ |
| 224 | this.labelDomainDMO.execute(null, new ArrayList<Integer>()); |
| 225 | while(this.labelDomainDMO.next()){ |
| 226 | String[] currLabel = new String[nLabelFileds]; |
| 227 | |
| 228 | for(int i=0;i<nLabelFileds;i++){ |
| 229 | currLabel[i] = this.labelDomainDMO.getNext(i+1).toString(); |
| 230 | } |
| 231 | |
| 232 | this.id2Label.put(labelID, currLabel); |
| 233 | this.label2ID.put(array2str(currLabel), labelID); |
| 234 | labelID++; |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | |
| 239 | if(this.id2Label.size() == 0 && this.isBinaryArbLR == false){ |
| 240 | return; |
| 241 | } |
| 242 | |
| 243 | if(this.unigramDMO == null){ |
| 244 | UIMan.warn("There are no LR-rules for predicate " + lrHead.getName()); |
| 245 | return; |
| 246 | } |
| 247 | |
| 248 | int ct = 0; |
| 249 | |
| 250 | String workingSignature = null; |
| 251 | this.getAllUnigramFeaturesDMO.db.disableAutoCommitForNow(); |
| 252 | this.getAllUnigramFeaturesDMO.execute(null, new ArrayList<Integer>()); |
| 253 | double[] weights; |
| 254 | |
| 255 | if(this.isBinaryArbLR == false){ |
| 256 | weights = new double[this.label2ID.keySet().size()]; |
| 257 | }else{ |
| 258 | weights = new double[1]; |
| 259 | } |
| 260 | |
| 261 | String[] currLabel = new String[lrHead.getLabelFieldsArgs().size()]; |
| 262 | |
| 263 | while(this.getAllUnigramFeaturesDMO.next()){ |
| 264 | |
| 265 | String currSignature = ""; |
| 266 | int lct = 0; |
| 267 | |
| 268 | ArrayList<String> toSig = new ArrayList<String>(); |
| 269 | if(this.isBinaryArbLR == false){ |
| 270 | for(int i=0;i<lrHead.arity();i++){ |
| 271 | if(lrHead.getLabelPositions().contains(i)){ |
| 272 | currLabel[lct++] = this.getAllUnigramFeaturesDMO.getNext(i+1).toString(); |
| 273 | toSig.add("%s"); |
| 274 | }else{ |
| 275 | toSig.add(this.getAllUnigramFeaturesDMO.getNext(i+1).toString()); |
| 276 | |
| 277 | //if(this.getAllUnigramFeaturesDMO.getNext(i+1).toString().equals("264014")){ |
| 278 | // System.out.println(); |
| 279 | //} |
| 280 | } |
| 281 | } |
| 282 | }else{ |
| 283 | for(int i=0;i<lrHead.arity();i++){ |
| 284 | toSig.add(this.getAllUnigramFeaturesDMO.getNext(i+1).toString()); |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | currSignature = StringMan.commaList(toSig); |
| 289 | Double weight = this.getAllUnigramFeaturesDMO.getNextDouble(lrHead.arity()+1); |
| 290 | |
| 291 | if(! currSignature.equals(workingSignature)){ |
| 292 | //dump and init. |
| 293 | if(workingSignature != null){ |
| 294 | if(ct % 10000 == 0){ |
| 295 | UIMan.verbose(3, "" + (ct++)); |
| 296 | } |
| 297 | this.inferAndDumpToTmpFile(workingSignature, weights, nonZeroWeights, bw); |
| 298 | for(int i : nonZeroWeights){ |
| 299 | weights[i] = 0; |
| 300 | } |
| 301 | nonZeroWeights.clear(); |
| 302 | } |
| 303 | workingSignature = currSignature; |
| 304 | } |
| 305 | |
| 306 | if(this.isBinaryArbLR == false){ |
| 307 | /* |
| 308 | System.out.println("! " + array2str(currLabel) + ""); |
| 309 | System.out.println("@ " + this.label2ID.get(array2str(currLabel)) + ""); |
| 310 | System.out.println("# " + weight + "\n\n"); |
| 311 | */ |
| 312 | currLabel = currLabel; |
| 313 | array2str(currLabel); |
| 314 | int wlen = this.label2ID.get(array2str(currLabel)); |
| 315 | //System.out.print(wlen + " | "); |
| 316 | //System.out.print(weights.length + " | "); |
| 317 | //System.out.println(weight); |
| 318 | weights[this.label2ID.get(array2str(currLabel))] += weight; |
| 319 | nonZeroWeights.add(this.label2ID.get(array2str(currLabel))); |
| 320 | }else{ |
| 321 | weights[0] += weight; |
| 322 | } |
| 323 | } |
| 324 | if(workingSignature != null){ |
| 325 | this.inferAndDumpToTmpFile(workingSignature, weights, nonZeroWeights, bw); |
| 326 | } |
| 327 | |
| 328 | |
| 329 | this.getAllUnigramFeaturesDMO.db.setAutoCommit(true); |
| 330 | bw.close(); |
| 331 | |
| 332 | //System.out.println("~\t" + Timer.elapsed("LR-Operator-" + lrHead.getName())); |
| 333 | |
| 334 | //UIMan.print("Start COPY..."); |
| 335 | FileInputStream in = new FileInputStream(Config.getLoadingDir() + "/_loading_lr_" + lrHead.getName() + this.getId()); |
| 336 | PGConnection con = (PGConnection)db.getConnection(); |
| 337 | |
| 338 | String sql; |
| 339 | |
| 340 | if(options.useDualDecomposition){ |
| 341 | for(FelixPredicate fp : this.dd_CommonOutput){ |
| 342 | if(!fp.getName().equals(this.lrHead.getName())){ |
| 343 | ExceptionMan.die("LR 583: There must be something wrong with the parser!"); |
| 344 | continue; |
| 345 | } |
| 346 | |
| 347 | in = new FileInputStream(Config.getLoadingDir() + |
| 348 | "/_loading_lr_" + lrHead.getName() + this.getId()); |
| 349 | String tableName = this.dd_commonOutputPredicate_2_tableName.get(fp); |
| 350 | |
| 351 | |
| 352 | sql = "COPY " + tableName + "(truth, prior, club, " + StringMan.commaList(lrHead.getArgs()) + " ) FROM STDIN CSV"; |
| 353 | con.getCopyAPI().copyIn(sql, in); |
| 354 | in.close(); |
| 355 | |
| 356 | } |
| 357 | |
| 358 | if(FelixConfig.isFirstRunOfDD){ |
| 359 | in = new FileInputStream(Config.getLoadingDir() + |
| 360 | "/_loading_lr_" + lrHead.getName() + this.getId()); |
| 361 | |
| 362 | sql = "COPY " + lrHead.getRelName() + "(truth, prior, club, " + StringMan.commaList(lrHead.getArgs()) + " ) FROM STDIN CSV"; |
| 363 | con.getCopyAPI().copyIn(sql, in); |
| 364 | in.close(); |
| 365 | } |
| 366 | lrHead.isCurrentlyView = false; |
| 367 | |
| 368 | }else{ |
| 369 | sql = "COPY " + lrHead.getRelName() + "(truth, prior, club, " + StringMan.commaList(lrHead.getArgs()) + " ) FROM STDIN CSV"; |
| 370 | con.getCopyAPI().copyIn(sql, in); |
| 371 | in.close(); |
| 372 | lrHead.isCurrentlyView = false; |
| 373 | } |
| 374 | |
| 375 | FelixUIMan.println(0,0,"\n>>> {" + this + "} uses " + Timer.elapsed("LR-Operator-" + lrHead.getName())); |
| 376 | |
| 377 | // for(FelixPredicate fp : this.outputPredicates){ |
| 378 | // fp.setClosedWorld(true); |
| 379 | // } |
| 380 | |
| 381 | lrHead.setHasSoftEvidence(true); |
| 382 | |
| 383 | |
| 384 | this.db.close(); |
| 385 | |
| 386 | if(!options.useDualDecomposition){ |
| 387 | this.belongsToBucket.runNextOperatorInBucket(); |
| 388 | } |
| 389 | |
| 390 | |
| 391 | return; |
| 392 | |
| 393 | }catch(Exception e){ |
| 394 | e.printStackTrace(); |
| 395 | } |
| 396 | } |
| 397 | |
| 398 | } |
| 399 | |
| 400 | @Override |
| 401 | public String explain() { |
| 402 | |
| 403 | return null; |
| 404 | } |
| 405 | |
| 406 | /** |
| 407 | * Generate Data Movement Operator used by this LR Operator. |
| 408 | * @param rules rules defining this operator. |
| 409 | */ |
| 410 | public void prepareDMO(HashSet<ConjunctiveQuery> lrQueries){ |
| 411 | |
| 412 | try { |
| 413 | |
| 414 | // DMO for LR rules |
| 415 | for(ConjunctiveQuery cq : lrQueries){ |
| 416 | |
| 417 | DataMovementOperator dmo = new DataMovementOperator(db, this); |
| 418 | dmo.logicQueryPlan.addQuery(cq, cq.head.getPred().getArgs(), |
| 419 | new ArrayList<String>(Arrays.asList("weight", "prov", "deepprov")) ); |
| 420 | |
| 421 | dmo.predictedBB = 0; |
| 422 | dmo.PredictedFF = 1; |
| 423 | dmo.PredictedBF = 0; |
| 424 | |
| 425 | dmo.allowOptimization = false; |
| 426 | |
| 427 | allDMOs.add(dmo); |
| 428 | lrDMOs.add(dmo); |
| 429 | } |
| 430 | |
| 431 | //the DMO for the union of all LR DMOs |
| 432 | if(this.lrDMOs.size() > 0){ |
| 433 | this.lrDMO = DataMovementOperator.UnionAll(db, this, |
| 434 | this.lrDMOs, StringMan.zeros(this.lrHead.arity() + 3), new ArrayList<Integer>()); |
| 435 | allDMOs.add(lrDMO); |
| 436 | |
| 437 | // if(!db.isTableExists(FelixConfig.db_schema, "_prov_metainfo")){ |
| 438 | // db.execute("CREATE TABLE _prov_metainfo (predicate TEXT, property TEXT, value TEXT)"); |
| 439 | // } |
| 440 | // |
| 441 | // db.execute("INSERT INTO _prov_metainfo (predicate, property, value) VALUES ('" + lrHead.getName() |
| 442 | // + "', 'optype', '" + "lr" + "')"); |
| 443 | // db.execute("INSERT INTO _prov_metainfo (predicate, property, value) VALUES ('" + lrHead.getName() |
| 444 | // + "', 'provtable', '" + lrDMO.getAllFreeViewName()+ "')"); |
| 445 | // db.execute("INSERT INTO _prov_metainfo (predicate, property, value) VALUES ('" + lrHead.getName() |
| 446 | // + "', 'labelfield', '" + StringMan.commaList(lrHead.getLabelFieldsArgs())+ "')"); |
| 447 | |
| 448 | |
| 449 | //the DMO for all unigram features. |
| 450 | this.unigramDMO = new DataMovementOperator(db, this); |
| 451 | this.unigramDMO.allowOptimization = false; |
| 452 | this.unigramDMO.asView = false; |
| 453 | this.unigramDMO.logicQueryPlan.addQuery(db.getPrepareStatement( |
| 454 | "SELECT " + StringMan.commaList(lrDMO.selListFromRule) + ", sum(weight) AS sumweight " + |
| 455 | " FROM " + lrDMO.getAllFreeViewName() + " GROUP BY " + StringMan.commaList(lrDMO.selListFromRule) + |
| 456 | (lrHead.getKeyFieldsArgs().size() == 0 ? "" : |
| 457 | " ORDER BY " + StringMan.commaList(lrHead.getKeyFieldsArgs())) ), |
| 458 | lrDMO.selListFromRule, new ArrayList<String>(Arrays.asList("sumweight"))); |
| 459 | allDMOs.add(this.unigramDMO); |
| 460 | } |
| 461 | |
| 462 | //the DMO for the label domain |
| 463 | if(this.isBinaryArbLR == false){ |
| 464 | this.labelDomainDMO = new DataMovementOperator(db, this); |
| 465 | this.labelDomainDMO.allowOptimization = false; |
| 466 | ArrayList<String> fields = lrHead.getLabelFieldsTypeTable(); |
| 467 | ArrayList<String> fieldsViewName = new ArrayList<String>(); |
| 468 | for(int i=0;i<fields.size();i++){ |
| 469 | fieldsViewName.add("t" + i + "." + "constantid AS l" + i); |
| 470 | fields.set(i, fields.get(i) + " t" + i); |
| 471 | } |
| 472 | this.labelDomainDMO.logicQueryPlan.addQuery(db.getPrepareStatement( |
| 473 | "SELECT " + StringMan.commaList(fieldsViewName) +" FROM " + StringMan.commaList(fields)), |
| 474 | lrHead.getLabelFieldsArgs(), |
| 475 | new ArrayList<String>()); |
| 476 | allDMOs.add(this.labelDomainDMO); |
| 477 | } |
| 478 | |
| 479 | if(this.unigramDMO != null){ |
| 480 | this.getAllUnigramFeaturesDMO = DataMovementOperator.Select(db, this, |
| 481 | this.unigramDMO, new ArrayList<String>()); |
| 482 | this.getAllUnigramFeaturesDMO.isIntermediaDMO = true; |
| 483 | this.getAllUnigramFeaturesDMO.hasKnownFetchingOrder = true; |
| 484 | allDMOs.add(this.getAllUnigramFeaturesDMO); |
| 485 | } |
| 486 | |
| 487 | } catch (Exception e) { |
| 488 | e.printStackTrace(); |
| 489 | } |
| 490 | } |
| 491 | |
| 492 | /** |
| 493 | * Returns sum of given log numbers. |
| 494 | * @param logX |
| 495 | * @param logY |
| 496 | * @return |
| 497 | */ |
| 498 | //ACKNOWLEDGE: FROM https://facwiki.cs.byu.edu/nlp/index.php/Log_Domain_Computations |
| 499 | //COPYRIGHT OF THIS FUNCTION BELONGS TO ITS ORIGINAL AUTHOR |
| 500 | public static double logAdd(double logX, double logY) { |
| 501 | |
| 502 | if (logY > logX) { |
| 503 | double temp = logX; |
| 504 | logX = logY; |
| 505 | logY = temp; |
| 506 | } |
| 507 | |
| 508 | if (logX == Double.NEGATIVE_INFINITY) { |
| 509 | return logX; |
| 510 | } |
| 511 | |
| 512 | double negDiff = logY - logX; |
| 513 | if (negDiff < -200) { |
| 514 | return logX; |
| 515 | } |
| 516 | |
| 517 | return logX + java.lang.Math.log(1.0 + java.lang.Math.exp(negDiff)); |
| 518 | } |
| 519 | |
| 520 | /** |
| 521 | * Infer and dump answers to the given buffered writer (with a format that can be COPY |
| 522 | * into postgres table directly). |
| 523 | * @param signature signature of current predicate instance. |
| 524 | * @param weights array of weights. Each entry corresponding to the weight of a label. |
| 525 | * @param bw |
| 526 | */ |
| 527 | public void inferAndDumpToTmpFile(String signature, double[] weights, ArrayList<Integer> noneZeroWeights, BufferedWriter bw){ |
| 528 | |
| 529 | try{ |
| 530 | |
| 531 | double sum = Double.NEGATIVE_INFINITY; |
| 532 | double tmp = Double.NEGATIVE_INFINITY; |
| 533 | double max = Double.NEGATIVE_INFINITY; |
| 534 | int nmax = -1; |
| 535 | |
| 536 | for(int i : noneZeroWeights){ |
| 537 | // for(int i=0;i<weights.length;i++){ |
| 538 | tmp = weights[i]; |
| 539 | if(tmp > max){ |
| 540 | max = tmp; |
| 541 | nmax = i; |
| 542 | } |
| 543 | sum = logAdd(tmp, sum); |
| 544 | } |
| 545 | |
| 546 | if(max < 0){ |
| 547 | for(int i=0;i<weights.length;i++){ |
| 548 | if(weights[i] >= 0){ |
| 549 | max = weights[i]; |
| 550 | nmax = i; |
| 551 | break; |
| 552 | } |
| 553 | } |
| 554 | } |
| 555 | |
| 556 | sum = logAdd(sum, Math.log(this.label2ID.size() - noneZeroWeights.size())); |
| 557 | |
| 558 | if(this.isBinaryArbLR == true){ |
| 559 | sum = logAdd(0,sum); |
| 560 | } |
| 561 | |
| 562 | if(this.isMarginal || (FelixConfig.isFirstRunOfDD && dd_commonOutputPredicate_2_tableName.containsKey(lrHead) ) ){ |
| 563 | |
| 564 | if(nmax == -1){ |
| 565 | return; |
| 566 | } |
| 567 | |
| 568 | for(int i : noneZeroWeights){ |
| 569 | // for(int i=0;i<weights.length;i++){ |
| 570 | |
| 571 | tmp = weights[i]; |
| 572 | |
| 573 | double prob = Math.exp(tmp - sum); |
| 574 | |
| 575 | if(prob >= Config.soft_evidence_activation_threshold){ |
| 576 | |
| 577 | ArrayList<String> parts = new ArrayList<String>(); |
| 578 | //parts.add(Integer.toString(lrHead.nextTupleIDAndUpdate())); |
| 579 | parts.add("TRUE"); |
| 580 | parts.add(Double.toString(prob)); |
| 581 | |
| 582 | if(options.useDualDecomposition){ |
| 583 | parts.add(Integer.toString(2)); |
| 584 | }else{ |
| 585 | parts.add(Integer.toString(2)); |
| 586 | } |
| 587 | //parts.add("1");//this is for vote |
| 588 | |
| 589 | String tmpstr = String.format(signature, (Object[]) id2Label.get(i)); |
| 590 | tmpstr = tmpstr.replaceAll("INTERNAL_MARGINAL", prob+""); |
| 591 | |
| 592 | bw.append(FelixStringMan.commaListNoSpace(parts) + "," + tmpstr + "\n"); |
| 593 | } |
| 594 | } |
| 595 | |
| 596 | }else{ |
| 597 | |
| 598 | if(nmax == -1){ |
| 599 | return; |
| 600 | } |
| 601 | |
| 602 | // double prob = Math.exp(weights[nmax]- sum); |
| 603 | |
| 604 | if(this.isBinaryArbLR == true){ |
| 605 | if(Math.exp(weights[0] - sum) <= 0.5){ |
| 606 | return; |
| 607 | } |
| 608 | } |
| 609 | |
| 610 | ArrayList<String> parts = new ArrayList<String>(); |
| 611 | //parts.add(Integer.toString(lrHead.nextTupleIDAndUpdate())); |
| 612 | parts.add("TRUE"); |
| 613 | parts.add(""); |
| 614 | |
| 615 | if(options.useDualDecomposition){ |
| 616 | parts.add(Integer.toString(2)); |
| 617 | }else{ |
| 618 | parts.add(Integer.toString(2)); |
| 619 | } |
| 620 | |
| 621 | |
| 622 | //parts.add("1");//this is for vote |
| 623 | |
| 624 | String tmpstr = String.format(signature, (Object[]) id2Label.get(nmax)); |
| 625 | |
| 626 | tmpstr = tmpstr.replaceAll("INTERNAL_MARGINAL", "1"); |
| 627 | |
| 628 | bw.append(FelixStringMan.commaListNoSpace(parts) + "," + tmpstr + "\n"); |
| 629 | |
| 630 | } |
| 631 | |
| 632 | }catch(Exception e){ |
| 633 | e.printStackTrace(); |
| 634 | } |
| 635 | |
| 636 | } |
| 637 | |
| 638 | |
| 639 | |
| 640 | |
| 641 | |
| 642 | } |