コード例 #1
0
ファイル: SEGaussian.cpp プロジェクト: JacobCWard/PyPNL
int testSEGaussian()
{
    PNL_USING
   
    int i;
    int ret = TRS_OK;
    float eps = 1e-4f;
    //create Gaussian distribution (inside the potential) and try to multiply
    //is by Delta
    
    //create Model Domain
    int nSimNodes = 3;
    CNodeType simNT = CNodeType(0, 2);
    CModelDomain* pSimDomain = CModelDomain::Create( nSimNodes, simNT );
    //create 2 potentials
    intVector dom;
    dom.assign(3,0);
    dom[1] = 1;
    dom[2] = 2;
    floatVector mean;
    mean.assign(6, 0);
    floatVector cov;
    cov.assign(36, 0.1f);
    for( i = 0; i < 6; i++ )
    {
        mean[i] = 1.1f*i;
        cov[i*7] = 2.0f;
    }

	CGaussianPotential* pPot = CGaussianPotential::Create( dom, pSimDomain, 1,
        mean, cov, 1.0f );

    //create gaussian CPD with gaussian parent
    const pConstNodeTypeVector* pTypes = pPot->GetArgType();
    //create data weigth
    floatVector weights1;
    weights1.assign(4, 1.0f);
    floatVector weights2;
    weights2.assign(4, 2.0f);
    const float* weights[] = { &weights1.front(), &weights2.front()};
    CGaussianDistribFun* pGauCPD = CGaussianDistribFun::CreateInMomentForm( 0,
        3, &pTypes->front(), &mean.front(), &cov.front(), weights );

    pPot->Dump();
    pPot->Normalize();
    //try to get multiplied delta
    intVector pos;
    floatVector valuesDelta;
    intVector offsets;
    pPot->GetMultipliedDelta(&pos, &valuesDelta, &offsets);
    if( pos.size() != 0 )
    {
        ret = TRS_FAIL;
    }


    //enter evidence to the pot and after that expand and compare results
    //create evidence object
/*    valueVector obsVals;
    obsVals.assign(6,Value(0) );
    obsVals[0].SetFlt(1.0f);
    obsVals[1].SetFlt(1.5f);
    obsVals[2].SetFlt(2.0f);
    obsVals[3].SetFlt(2.5f);
    obsVals[4].SetFlt(3.0f);
    obsVals[5].SetFlt(3.5f);
    CEvidence* pEvid = CEvidence::Create( pSimDomain, 3, &dom.front(), obsVals );
    CPotential* pShrPot = pPot->ShrinkObservedNodes( pEvid );*/
    
    
    CGaussianPotential* pCanonicalPot = CGaussianPotential::Create( dom,
        pSimDomain, 0, mean, cov, 1.0f );
    CMatrix<float>* matrK = pCanonicalPot->GetMatrix(matK);
    intVector multIndex;
    multIndex.assign(2,5);
    matrK->SetElementByIndexes( 3.0f, &multIndex.front() );
    CMatrix<float>* matrH = pCanonicalPot->GetMatrix(matH);
    multIndex[0] = 0;
    matrH->SetElementByIndexes(0.0f, &multIndex.front());
    pPot->ConvertToSparse();
    pPot->ConvertToDense();
    //create other Gaussian potential for division
    i = 1;
    floatVector meanSmall;
    meanSmall.assign(2, 1.0f);
    floatVector covSmall;
    covSmall.assign(4, 0.0f);
    covSmall[0] = 1.0f;
    covSmall[3] = 1.0f;
    CGaussianPotential* pSmallPot = CGaussianPotential::Create( &i, 1,
        pSimDomain, 1, &meanSmall.front(), &covSmall.front(), 1.0f );
    //divide by distribution in moment form
    (*pCanonicalPot) /= (*pSmallPot);

    //create big unit function distribution and marginalize it
    CGaussianPotential* pBigUnitPot = 
        CGaussianPotential::CreateUnitFunctionDistribution(dom, pSimDomain, 1);
	CGaussianPotential* pCloneBigUniPot = static_cast<CGaussianPotential*>(
		pBigUnitPot->CloneWithSharedMatrices());
	if( !pCloneBigUniPot->IsFactorsDistribFunEqual(pBigUnitPot, eps) )
	{
		ret = TRS_FAIL;
	}
    CPotential* pMargUniPot = pBigUnitPot->Marginalize(&dom.front(), 1, 0);
    (*pBigUnitPot) /= (*pSmallPot);
    (*pBigUnitPot) *= (*pSmallPot);
    
    //check if there are some problems
    static_cast<CGaussianDistribFun*>(pBigUnitPot->GetDistribFun())->CheckCanonialFormValidity();

    if( pBigUnitPot->IsDistributionSpecific() != 1 )
    {
        ret = TRS_FAIL;
    }

    (*pBigUnitPot) /= (*pCanonicalPot);
    (*pBigUnitPot) *= (*pCanonicalPot);

    static_cast<CGaussianDistribFun*>(pBigUnitPot->GetDistribFun())->CheckCanonialFormValidity();

    if( pBigUnitPot->IsDistributionSpecific() != 1 )
    {
        ret = TRS_FAIL;
    }

    static_cast<CGaussianDistribFun*>(pSmallPot->GetDistribFun())->
        UpdateCanonicalForm();
    (*pPot) /= (*pSmallPot);
    pSmallPot->SetCoefficient(0.0f,1);
    pSmallPot->Dump();

    //create canonical potential without coefficient
    i = 0;

    CDistribFun* pCopyPotDistr = pPot->GetDistribFun()->ConvertCPDDistribFunToPot();
    CGaussianPotential* pCanSmallPot = CGaussianPotential::Create( &i, 1,
        pSimDomain, 0, &meanSmall.front(), &covSmall.front(), 1.0f );
    CGaussianPotential* pCanPotCopy = 
        static_cast<CGaussianPotential*>(pCanSmallPot->Clone());
    CGaussianPotential* pCanPotCopy1 = 
        static_cast<CGaussianPotential*>(pCanPotCopy->CloneWithSharedMatrices());

    (*pPot) /= (*pCanSmallPot);
    (*pPot) *= (*pCanSmallPot);
    //can compare results, if we want
    CDistribFun* pMultDivRes = pPot->GetDistribFun();
    float diff = 0;
    if( !pMultDivRes->IsEqual(pCopyPotDistr, eps,1, &diff) )
    {
        ret = TRS_FAIL;
        std::cout<<"the diff is "<<diff<<std::endl;
    }
    delete pCopyPotDistr;
    
    //create delta distribution
    floatVector deltaMean;
    deltaMean.assign( 2, 1.5f );
    i = 0;
    CGaussianPotential* pDeltaPot = CGaussianPotential::CreateDeltaFunction( 
        &i, 1, pSimDomain, &deltaMean.front(), 1 );
    
    CGaussianDistribFun* pDeltaDistr = static_cast<CGaussianDistribFun*>(
        pDeltaPot->GetDistribFun());
    pDeltaDistr->CheckMomentFormValidity();
    pDeltaDistr->CheckCanonialFormValidity();
    pDeltaPot->Dump();


    //multiply some potential by delta
    (*pCanSmallPot) *= (*pDeltaPot);

    (*pPot) *= (*pDeltaPot);
    //(*pPot) *= (*pDeltaPot);
    
    pPot->GetMultipliedDelta(&pos, &valuesDelta, &offsets);
    (*pCanonicalPot) *= (*pDeltaPot);
    //marginalize this distribFun multiplied by delta
    intVector margDims;
    margDims.assign(2,1);
    margDims[1] = 2;
    CPotential* pMargPot = pPot->Marginalize( &margDims.front(), 2 );
    i = 0;
    CPotential* pSmallMargPot = pPot->Marginalize(&i, 1);
    //marginalize in canonical form
    CPotential* pMargCanPot = pCanonicalPot->Marginalize( &margDims.front(), 2 );
    CPotential* pSmallCanPot = pCanonicalPot->Marginalize(&i,1);
    
    //create unit function distribution in canonical form
    i = 0;
    CGaussianPotential* pUnitPot = 
        CGaussianPotential::CreateUnitFunctionDistribution( &i, 1, pSimDomain,
        1);
    pUnitPot->Dump();
    CGaussianDistribFun* pUnitDistr = static_cast<CGaussianDistribFun*>(
        pUnitPot->GetDistribFun());
    pUnitDistr->CheckCanonialFormValidity();
    pUnitDistr->CheckMomentFormValidity();

    (*pPot) *= (*pUnitPot);

    if( pUnitPot->IsFactorsDistribFunEqual(pBigUnitPot, eps, 1) )
    {
        ret = TRS_FAIL;
    }

    deltaMean.resize(6);
    deltaMean[2] = 2.5f;
    deltaMean[3] = 2.5f;
    deltaMean[4] = 3.5f;
    deltaMean[5] = 3.5f;
    CGaussianPotential* pBigDeltaPot = CGaussianPotential::CreateDeltaFunction( 
        dom, pSimDomain, deltaMean, 1 );
    CGaussianPotential* pCloneBigDeltaPot = static_cast<CGaussianPotential*>(
		pBigDeltaPot->CloneWithSharedMatrices());
    //we can shrink observed nodes in this potential
    valueVector vals;
    vals.resize(2);
    vals[0].SetFlt(1.5f);
    vals[1].SetFlt(1.5f);
    i = 0;
    CEvidence* pDeltaEvid = CEvidence::Create( pSimDomain, 1, &i,vals ); 
    CGaussianPotential* pShrGauDeltaPot = static_cast<CGaussianPotential*>(
        pBigDeltaPot->ShrinkObservedNodes( pDeltaEvid ));
    delete pDeltaEvid;
    pShrGauDeltaPot->Dump();
    delete pShrGauDeltaPot;
    CPotential* pSmallDeltaMarg = pBigDeltaPot->Marginalize( &dom.front(), 1, 0 );
    pSmallDeltaMarg->Normalize();
    pDeltaPot->Normalize();
    if( !pSmallDeltaMarg->IsFactorsDistribFunEqual( pDeltaPot, eps, 1 ) )
    {
        ret = TRS_FAIL;
    }
    //call operator = for delta distributions
    (*pSmallDeltaMarg) = (*pDeltaPot);

    //call operator = for canonical and delta distribution
    (*pCanPotCopy) = (*pUnitPot);

    //call operator = for canonical and unit distribution
    (*pCanPotCopy1) = (*pDeltaPot);

    (*pUnitPot) = (*pUnitPot);
    

    (*pPot) *= (*pBigDeltaPot);

    (*pCloneBigDeltaPot) *= (*pDeltaPot);

	if( !pCloneBigDeltaPot->IsFactorsDistribFunEqual(pBigDeltaPot, eps) )
	{
		ret = TRS_FAIL;
	}

    //we can create the matrix which will be almost delta distribution,
    //but covariance matrix will contain almost zeros
    floatVector almostDeltaCov;
    almostDeltaCov.assign(4, 0.0f);
    almostDeltaCov[0] = 0.00001f;
    almostDeltaCov[3] = 0.00001f;
    i = 0;
    CGaussianPotential* pAlmostDeltaPot = CGaussianPotential::Create( &i, 1, 
        pSimDomain, 1, &deltaMean.front(), &almostDeltaCov.front(), 1.0f );
    if( !pDeltaPot->IsFactorsDistribFunEqual( pAlmostDeltaPot, eps, 0 ) )
    {
        ret = TRS_FAIL;
    }
    if( !pAlmostDeltaPot->IsFactorsDistribFunEqual( pDeltaPot, eps, 0 ) )
    {
        ret = TRS_FAIL;
    }
	(*pCloneBigUniPot ) = ( *pPot );
	if( !(pCloneBigUniPot->IsFactorsDistribFunEqual(pPot, eps)) )
	{
		ret = TRS_FAIL;
	}
	(*pCloneBigDeltaPot) = (*pPot);
	if( !(pCloneBigDeltaPot->IsFactorsDistribFunEqual(pPot, eps))  )
	{
		ret = TRS_FAIL;
	}

    delete pCanPotCopy;
    delete pCanPotCopy1;
    delete pAlmostDeltaPot;
    delete pMargUniPot;
	delete pCloneBigUniPot;
    delete pBigUnitPot;
    delete pCanSmallPot;
    delete pDeltaPot; 
    delete pUnitPot;
	delete pCloneBigDeltaPot;
    delete pBigDeltaPot;
    delete pMargCanPot;
    delete pSmallCanPot;
    delete pMargPot;
    delete pSmallMargPot;
    delete pCanonicalPot;
    //delete pShrPot;
    //delete pEvid;
	delete pGauCPD;
    delete pPot;
    delete pSimDomain;
    return trsResult( ret, ret == TRS_OK ? "No errors" : 
                        "Bad test on SEGaussian");

}
コード例 #2
0
//-----------------------------------------------------------------------------
CPotential* CSoftMaxCPD::ConvertWithEvidenceToGaussianPotential(
    const CEvidence* pEvidence,
    floatVector MeanContParents, 
    C2DNumericDenseMatrix<float>* CovContParents,
    const int *parentIndices,
    int flagSumOnMixtureNode ) const
{
    int SoftMaxSize = GetSoftMaxSize();
    if (SoftMaxSize != 2)
    {
        PNL_THROW(CNotImplemented, "It is not sigmoid");
    }
    else
    {
        if (m_CorrespDistribFun->GetDistributionType() == dtSoftMax)
        {
            CPotential* pot = ConvertToGaussianPotential(pEvidence, 
                m_CorrespDistribFun, MeanContParents, CovContParents);

            CPotential *pot2 = NULL;

            int domSize = pot->GetDomainSize();
            bool IsAllContUnobserved = true;
            const pConstNodeTypeVector* ntVec = pot->GetDistribFun()->GetNodeTypesVector();
            for( int i = 0; i < domSize-1; i++  )    
            {
              intVector Domain;
              pot->GetDomain(&Domain);
              int curNode =  Domain[i];
              if( (pEvidence->IsNodeObserved(curNode)))
              {
                if( !(*ntVec)[i]->IsDiscrete() )
                {
                  IsAllContUnobserved = false;
                }
              }
            }

            if ((pot->GetDomainSize() >= 3)&&(!IsAllContUnobserved))
            {
              pot2 = pot->ShrinkObservedNodes(pEvidence);
            }
            else
            {
              intVector Domain;
              pot->GetDomain(&Domain);
              pot2 = pot->Marginalize(&(Domain[0]), 1);
            }
            delete pot;
            return pot2;
        }
        else //it means m_CorrespDistribFun->GetDistributionType == dtCondSoftMax
        {
            int i;
            const CSoftMaxDistribFun* dtSM;

            dtSM = 
                static_cast<CCondSoftMaxDistribFun*>(m_CorrespDistribFun)->
                GetDistribution(parentIndices);
            
            intVector pObsNodes;
            pConstValueVector pObsValues;
            pConstNodeTypeVector pNodeTypes;
            pEvidence->GetObsNodesWithValues(&pObsNodes, &pObsValues, &pNodeTypes);
            
            int r = -1;
            for (i = 0; i < pObsNodes.size(); i++)
            {
                if (m_Domain[m_Domain.size()-1] == pObsNodes[i])
                {
                    r = pObsValues[i]->GetInt();
                    break;
                }
            }
            if (r == -1)
            {
                PNL_THROW(CNotImplemented, "Not exist evidence");
            }
            
            CDistribFun *gauFactData = const_cast<CSoftMaxDistribFun*>(dtSM)->
                ConvertCPDDistribFunToPotential(MeanContParents, CovContParents, r);
            
            intVector gauSubDomain;
            const CNodeType *nt;
            for(i = 0; i < m_Domain.size(); i++)
            {
                nt = GetModelDomain()->GetVariableType( m_Domain[i] );
                if(!(nt->IsDiscrete()))
                {
                    gauSubDomain.push_back(m_Domain[i]);
                }
            }
            
            intVector obsIndex;
            for( i = 0; i < gauSubDomain.size(); i++ )
            {
                if( pEvidence->IsNodeObserved(gauSubDomain[i]) )
                {
                    obsIndex.push_back( i );
                }
            }
            
            CGaussianPotential *resFactor = CGaussianPotential::Create(&gauSubDomain.front(), 
                gauSubDomain.size(), GetModelDomain());
            
            resFactor->SetDistribFun( gauFactData );


            CPotential *pot = NULL;

            int domSize = resFactor->GetDomainSize();
            bool IsAllContUnobserved = true;
            const pConstNodeTypeVector* ntVec = resFactor->GetDistribFun()->GetNodeTypesVector();
            for( i = 0; i < domSize-1; i++  )    
            {
              intVector Domain;
              resFactor->GetDomain(&Domain);
              int curNode =  Domain[i];
              if( (pEvidence->IsNodeObserved(curNode)))
              {
                if( !(*ntVec)[i]->IsDiscrete() )
                {
                  IsAllContUnobserved = false;
                }
              }
            }
            if ((resFactor->GetDomainSize() >= 3)&&(!IsAllContUnobserved))
            {
              pot = resFactor->ShrinkObservedNodes(pEvidence);
            }
            else
            {
              intVector Domain;
              resFactor->GetDomain(&Domain);
              pot = resFactor->Marginalize(&(Domain[0]), 1);
            }
            delete resFactor;
            
            delete gauFactData;
            return pot;
            
        }
    }
}