void CJtreeInfEngine::PropagateBetweenClqs(int source, int sink, bool isCollect) { PNL_CHECK_RANGES( source, 0, m_pJTree->GetNumberOfNodes() - 1 ); PNL_CHECK_RANGES( sink, 0, m_pJTree->GetNumberOfNodes() - 1 ); if (source == sink) { PNL_THROW(CInvalidOperation, " source and sink should differ "); } if (!m_pJTree->GetGraph()->IsExistingEdge(source, sink)) { PNL_THROW(CInvalidOperation, " there is no edge between source and sink "); } bool isDense = true; if(!m_pJTree->GetNodeType(source)->IsDiscrete() || !m_pJTree->GetNodeType(sink)->IsDiscrete()) { isDense = false; } CPotential *potSource = m_pJTree->GetNodePotential(source), *potSink = m_pJTree->GetNodePotential(sink); if(potSource->IsSparse() || potSink->IsSparse()) { isDense = false; } // check that nodes source and sink are discrete if(isDense && !m_bMaximize) { pnl::CNumericDenseMatrix< float > *sorceMatrix, *sepMatrix, *sinkMatrix; int *dims_to_keep, *dims_to_mul; int num_dims_to_keep, num_dims_to_mul; if (GetDataForMargAndMult(source, sink, &sorceMatrix, &dims_to_keep, num_dims_to_keep, &sepMatrix, &sinkMatrix, &dims_to_mul, num_dims_to_mul)) { DoPropagate(sorceMatrix, dims_to_keep, num_dims_to_keep, sepMatrix, sinkMatrix, dims_to_mul, num_dims_to_mul, isCollect); delete [] dims_to_keep; delete [] dims_to_mul; } else { CPotential *potSink = m_pJTree->GetNodePotential(sink); potSink->Normalize(); } } else { int numNdsInSepDom; const int *sepDom; int numNdsInSDom; const int *sDom; potSource->GetDomain( &numNdsInSDom, &sDom ); CPotential *potSep = m_pJTree->GetSeparatorPotential( source, sink ); CPotential *newPotSep, *updateRatio; potSep->GetDomain( &numNdsInSepDom, &sepDom ); newPotSep = potSource->Marginalize( sepDom, numNdsInSepDom, m_bMaximize ); updateRatio = newPotSep->Divide(potSep); *potSink *= *updateRatio; potSink->Normalize(); potSep->SetDistribFun(newPotSep->GetDistribFun()); delete newPotSep; delete updateRatio; } }