/*
	Create a simple Bayesian Network.
	Alvaro Marin - alvaro@rigel.deusto.es
	Abril 2005.	
*/

#include "stdio.h"
#include "pnl_dll.hpp"
#include "cvsvd.h"

PNL_USING

void printBayesianNetwork( CBNet *netbay )
{
		
	const CFactor *pCPD;
	const CNumericDenseMatrix *pMatForCPD;
	const float *dataCPD;
	int numOfEl; 
  	int f; 

	// Get information from learned model (number of factors)
  	int nFactors = netbay->GetNumberOfFactors();
  
	for( f = 0; f < nFactors; f++ )
  	{
  		std::cout<GetFactor(f);
	  	pMatForCPD = static_cast *>(pCPD->GetMatrix(matTable));
	  	pMatForCPD->GetRawData( &numOfEl, &dataCPD );
	  	int j;
	  	for( j = 0; j < numOfEl; j++ )
  		{
		      	std::cout<<" "<AddNodes(numOfNds);
	pGraph->AddEdge(0,1,1);
	pGraph->AddEdge(0,2,1);
	pGraph->AddEdge(1,3,1);
	pGraph->AddEdge(2,3,1);
	
	pGraph->Dump();

	CNodeType *nodeTypes = new CNodeType [4];
	nodeTypes[0].SetType(1, 2);
	nodeTypes[1].SetType(1, 2);
	nodeTypes[2].SetType(1, 2);
	nodeTypes[3].SetType(1, 2);
	
	int *nodeAssociation = new int[numOfNds];
	for ( int i = 0; i < numOfNds; i++ )
    	{
        	nodeAssociation[i] = i;
    	}

	CBNet *pBNet;
	try{
		pBNet = CBNet::Create( numOfNds, numOfNds /*NumOfNodeTypes*/, nodeTypes, nodeAssociation, pGraph );
	}
	catch (pnl::CException ex)
  	{
		printf("[PNL] EXCEPTION %d: %s\n",ex.GetCode(),ex.GetMessage());
  	}	

	// printBayesianNetwork(pBNet); -> Violacion de Segmento por no tener datos. Factores no alojados aun :/
	
	float table0[] = { 0.5f, 0.5f }; 
	float table1[] = { 0.5f, 0.5f }; 
	float table2[] = { 0.5f, 0.5f }; 
	float table3[] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f };
	
	float* table[] = { table0, table1, table2, table3 }; 
		
	// Factor == CPD == Celda. Vamos alojando los CPD (Conditional Probabilistic Distribution) en cada Factor
	for( int i = 0; i < numOfNds; ++i ) 
	{ 
		pBNet->AllocFactor(i); 
		CFactor* pFactor = pBNet->GetFactor(i); 
		pFactor->AllocMatrix( table[i], matTable );			
	}

	
	printf("\n[PNL] pBNet created.\n");

	printBayesianNetwork(pBNet);
	
	getchar();

	// Que pasa si tenemos una red de 100 nodos? Alojar Factors 1 a 1? NO -> A partir de una red existente (no hace falta que tenga 
	// CPDs, podemos crear una con CPDs Random -> Comentamos desde los floats hasta aqui
   	CBNet *pBNetRand = CBNet::CreateWithRandomMatrices( pGraph, pBNet->GetModelDomain() );	
	printf("[PNL] pBNetRand created with Random Matrices.\n");

	printBayesianNetwork(pBNetRand);

}


int main(int argc, char* argv[])
{

	printf("\n\nCrearemos la siguiente red bayesiana:\n\n");
	printf("    0\n   / \\\n  1   2\n   \\ / \n    3 \n\n");
	getchar();
	createBNet();
	return 0;

}