private void setCIMs(IModel<Double, CTDiscreteNode> model, SufficientStatistics lData[]) throws RuntimeException {
		// Parameter calculation
		NodeIndexing nodeIndexing = model.getNodeIndexing();
		for( int iNode = 0; iNode < nodeIndexing.getNodesNumber(); ++iNode) {
			CTDiscreteNode node = model.getNode(iNode);
			if( node.isStaticNode()) {
				for( int pE = 0; pE < node.getNumberParentsEntries(); ++pE) {
					// Probability distribution calculation
					double[][] prob = new double[1][node.getStatesNumber()];
					for( int sE = 0; sE < node.getStatesNumber(); ++sE)
						prob[0][sE] = lData[iNode].Px[pE][0][sE] / lData[iNode].counts[pE];
					node.setCIM( pE, prob);
				}
			}else {
				for( int pE = 0; pE < node.getNumberParentsEntries(); ++pE) {
					double[][] cim = new double[node.getStatesNumber()][node.getStatesNumber()];
					for( int fsE = 0; fsE < node.getStatesNumber(); ++fsE) {
						// CIM calculation
						cim[fsE][fsE] = -lData[iNode].Mx[pE][fsE] /  lData[iNode].Tx[pE][fsE];
						for( int ssE = 0; ssE < node.getStatesNumber(); ++ssE)
							if( fsE != ssE)
								cim[fsE][ssE] = lData[iNode].Mxx[pE][fsE][ssE] / lData[iNode].Tx[pE][fsE];
								// cim[fsE][ssE] = -cim[fsE][fsE] * (lData[iNode].Mxx[pE][fsE][ssE] / lData[iNode].Mx[pE][fsE]);
					}
					node.setCIM(pE, cim);
				}
			}
			
			int check = node.checkCIMs();
			if( check != -1)
				throw new RuntimeException("Error: unexpected error in CIM validation for node " + node.getName() + " and parent entry " + check + " (the inserting of the priors imaginary counts can solve this exception)");  
		}
	}