content: /*
   *
   *
   *    Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
   *    See the NOTICE file distributed with this work for additional information regarding copyright ownership.
   *    The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use
   *    this file except in compliance with the License.  You may obtain a copy of the License at
   *
   *            http://www.apache.org/licenses/LICENSE-2.0
   *
   *    Unless required by applicable law or agreed to in writing, software distributed under the License is
   *    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *    See the License for the specific language governing permissions and limitations under the License.
   *
   *
   */
  
  package eu.amidst.huginlink.examples.learning;
  
  
  import com.google.common.base.Stopwatch;
  import eu.amidst.core.datastream.DataInstance;
  import eu.amidst.core.datastream.DataStream;
  import eu.amidst.core.io.BayesianNetworkLoader;
  import eu.amidst.core.learning.parametric.ParallelMaximumLikelihood;
  import eu.amidst.core.models.BayesianNetwork;
  import eu.amidst.core.utils.BayesianNetworkSampler;
  import eu.amidst.huginlink.learning.ParallelTAN;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  
  /**
   * This example shows how to use <a href="https://www.hugin.com">Hugin</a>'s functionality to learn in parallel a TAN model.
   * An important remark is that Hugin only allows to learn the TAN model for a data set completely loaded into RAM
   * memory. The case where our data set does not fit into memory, it solved in AMIDST in the following way. We learn
   * the structure using a smaller data set produced by <a href="https://en.wikipedia.org/wiki/Reservoir_sampling">Reservoir sampling</a>
   * and, then, we use AMIDST's {@link ParallelMaximumLikelihood} to learn the parameters of the TAN over the whole data set.
   *
   * <p> For further details about the implementation of the parallel TAN algorithm look at the following paper: </p>
   *
   * <i> Madsen, A.L. et al. A New Method for Vertical Parallelisation of TAN Learning Based on Balanced Incomplete
   * Block Designs. Probabilistic Graphical Models. Lecture Notes in Computer Science Volume 8754, 2014, pp 302-317. </i>
   */
  public class ParallelTANExample {
  
      public static void main(String[] args) throws Exception {
  
          //We load a Bayesian network to generate a data stream
          //using BayesianNewtorkSampler class.
          int sampleSize = 100000;
          BayesianNetwork bn = BayesianNetworkLoader.loadFromFile("networks/dataWeka/Pigs.bn");
          BayesianNetworkSampler sampler = new BayesianNetworkSampler(bn);
  
          //We fix the number of samples in memory used for performing the structural learning.
          //They are randomly sub-sampled using Reservoir sampling.
          int samplesOnMemory = 5000;
  
          //We make different trials with different number of cores
          ArrayList<Integer> vNumCores = new ArrayList(Arrays.asList(1, 2, 3, 4));
  
          for (Integer numCores : vNumCores) {
              System.out.println("Learning TAN: " + samplesOnMemory + " samples on memory, " + numCores + " core/s ...");
              DataStream<DataInstance> data = sampler.sampleToDataStream(sampleSize);
  
              //The class ParallelTAN is created
              ParallelTAN tan = new ParallelTAN();
  
              //We activate the parallel mode.
              tan.setParallelMode(true);
  
              //We set the number of cores to be used for the structural learning
              tan.setNumCores(numCores);
  
              //We set the number of samples to be used for the learning the structure
              tan.setNumSamplesOnMemory(samplesOnMemory);
  
              //We set the root variable to be first variable
              tan.setNameRoot(bn.getVariables().getListOfVariables().get(0).getName());
  
              //We set the class variable to be the last variable
              tan.setNameTarget(bn.getVariables().getListOfVariables().get(bn.getVariables().getListOfVariables().size()-1).getName());
  
              Stopwatch watch = Stopwatch.createStarted();
  
              //We just invoke this mode to learn the TAN model for the data stream
              BayesianNetwork model = tan.learn(data);
  
              System.out.println(watch.stop());
          }
      }
  }