/*******************************************************************************
 * Copyright (c) 2012 Michael Kutschke.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Michael Kutschke - initial API and implementation
 ******************************************************************************/
package bayesnet.jayes.io.xdsl;

import static bayesnet.jayes.io.xdsl.Constants.*;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import bayesnet.jayes.BayesNet;
import bayesnet.jayes.BayesNode;
import bayesnet.jayes.io.IBayesNetWriter;
import bayesnet.jayes.io.util.XMLUtil;

public class XDSLWriter implements IBayesNetWriter {

    private static final String XML_HEADER = "\n";
    private static final String COMMENT = "\n";
    private final Writer out;

    public XDSLWriter(OutputStream out) {
        this.out = new OutputStreamWriter(out);

    }

    @Override
    public void write(BayesNet net) throws IOException {
        StringBuilder bldr = new StringBuilder();
        bldr.append(XML_HEADER);
        bldr.append(COMMENT);

        int offset = bldr.length();
        getVariableDefs(bldr, net);
        getGenieExtensions(bldr, net);
        XMLUtil.surround(offset, bldr, "smile", "version", "1.0", ID, XMLUtil.escape(net.getName()), "numsamples",
                "1000");

        out.write(bldr.toString());
        out.flush();
    }

    private void getGenieExtensions(StringBuilder bldr, BayesNet net) {
        int offset = bldr.length();
        for (BayesNode node : net.getNodes()) {
            int nodeOffset = bldr.length();
            bldr.append(XMLUtil.escape(node.getName()));
            XMLUtil.surround(nodeOffset, bldr, "name");
            bldr.append('\n');
            int posOffset = bldr.length();
            bldr.append("0 0 100 100");
            XMLUtil.surround(posOffset, bldr, "position");
            bldr.append('\n');
            XMLUtil.emptyTag(bldr, "font", "color", "000000", "name", "Arial", "size", "8");
            bldr.append('\n');
            XMLUtil.emptyTag(bldr, "interior", "color", "e5f6f7");
            bldr.append('\n');
            XMLUtil.emptyTag(bldr, "outline", "color", "000000");
            bldr.append('\n');
            XMLUtil.surround(nodeOffset, bldr, "node", "id", XMLUtil.escape(node.getName()));
        }
        XMLUtil.surround(offset, bldr, "genie", "version", "1.0", "name", XMLUtil.escape(net.getName()));
        XMLUtil.surround(offset, bldr, "extensions");

    }

    private void getVariableDefs(StringBuilder bldr, BayesNet net) {
        int offset = bldr.length();
        for (BayesNode node : net.getNodes()) {
            int nodeOffset = bldr.length();
            encodeStates(bldr, node);
            encodeParents(bldr, node);
            bldr.append('\n');
            encodeProbabilities(bldr, node);
            XMLUtil.surround(nodeOffset, bldr, CPT, ID, XMLUtil.escape(node.getName()));
            bldr.append('\n');
        }
        XMLUtil.surround(offset, bldr, "nodes");
    }

    private void encodeStates(StringBuilder bldr, BayesNode node) {
        for (String outcome : node.getOutcomes()) {
            XMLUtil.emptyTag(bldr, STATE, ID, XMLUtil.escape(outcome));
            bldr.append('\n');
        }
    }

    private void encodeParents(StringBuilder bldr, BayesNode node) {
        int offset = bldr.length();
        for (BayesNode p : node.getParents()) {
            // XDSL can't handle names containing whitespaces!
            bldr.append(XMLUtil.escape(p.getName()));
            bldr.append(' ');
        }
        if (!node.getParents().isEmpty()) {
            bldr.deleteCharAt(bldr.length() - 1); // delete last whitespace
        }

        XMLUtil.surround(offset, bldr, PARENTS);
    }

    private void encodeProbabilities(StringBuilder bldr, BayesNode node) {
        if (node.getProbabilities().length == 0) {
            throw new IllegalArgumentException("Bayesian Network is broken: " + node.getName()
                    + " has an empty conditional probability table");
        }
        int offset = bldr.length();
        for (double d : node.getProbabilities()) {
            bldr.append(d);
            bldr.append(' ');
        }
        bldr.deleteCharAt(bldr.length() - 1); // delete last whitespace
        XMLUtil.surround(offset, bldr, PROBABILITIES);
    }

    @Override
    public void close() throws IOException {
        out.close();
    }
}

 

Ads help maintain this website.