Example #1
0
int testGibbsInference()
{
    int ret = TRS_OK;
    int seed = time(0);
    std::cout<<"seed = "<< seed<<std::endl;
    pnlSeed(seed);
   
 /////////////////////////////////////////////////////////////////////////////

    float eps = -1.0f;
    while( eps <= 0 )
    {
	trssRead( &eps, "1.5e-1f", "accuracy in test" );
    }

	ret = ret && GibbsForTreeBNet();
    ret = ret && GibbsMPEforScalarGaussianBNet( eps );
    ret = ret && GibbsForSingleGaussian( eps );
    ret = ret && GibbsForMixtureBNet(eps);
    ret = ret && GibbsForScalarGaussianBNet(  eps );
    ret = ret && GibbsForSimplestGaussianBNet( eps );
    ret = ret && GibbsForGaussianBNet( eps );
    ret = ret && GibbsForAsiaBNet( eps );
    ret = ret && GibbsForMNet( eps );
    ret = ret && GibbsMPEForMNet( eps );
    ret = ret && GibbsForInceneratorBNet( eps );
    ret = ret && GibbsForSparseBNet( eps );

    return trsResult( ret, ret == TRS_OK ? "No errors" :
    "Bad test on Gibbs Sampling Inference" );

}
int test1_5JTreeInfDBNCondGauss()
{
    

    int ret = TRS_OK;
    int seed = pnlTestRandSeed();
    std::cout<<"seed"<<seed<<std::endl;

    srand( seed );
    CDBN *pDBN = tCreateArHMMwithGaussObs();


    int nTimeSlice = -1;
    while(nTimeSlice <= 0)
    {
	trsiRead (&nTimeSlice, "4", "Number of slices");
    }

    float eps = -1.0f;
    while( eps <= 0 )
    {
	trssRead( &eps, "1e-2f", "accuracy in test");
    }


    int result = 1;
    result = CompareSmoothingArHMM( pDBN, nTimeSlice,  eps );
    if( !result )
    {
	ret = TRS_FAIL;
    }

    result = CompareFilteringArHMM( pDBN, nTimeSlice,  eps );

    if( !result )
    {
	ret = TRS_FAIL;
    }

    result = CompareFixLagSmoothingArHMM( pDBN, nTimeSlice,  eps );
    if( !result )
    {
	ret = TRS_FAIL;
    }
    result = CompareViterbyArHMM( pDBN, nTimeSlice,  eps );
    if( !result )
    {
	ret = TRS_FAIL;
    }

    //////////////////////////////////////////////////////////////////////////
    delete pDBN;
    return trsResult( ret, ret == TRS_OK ? "No errors"
	: "Bad test on 1_5 Slice JTree DBN");
}
Example #3
0
int testBKInfUsingClusters()
{
    
    
    int ret = TRS_OK;

    int seed = pnlTestRandSeed();
    pnlSeed( seed );
    std::cout<<"seed"<<seed<<std::endl;
    
    
    int nTimeSlices = -1;
    while(nTimeSlices <= 5)
    {
        trsiRead (&nTimeSlices, "10", "Number of slices");
    }
    
    float eps = -1.0f;
    while( eps <= 0 )
    {
        trssRead( &eps, "1.0e-1f", "accuracy in test");
    }
    
    
    CDBN *pDBN = CDBN::Create( pnlExCreateBatNetwork() );
    
    intVecVector clusters;
    intVector interfNds;
    pDBN->GetInterfaceNodes( &interfNds );
    int numIntNds = interfNds.size();
    int numOfClusters = pnlRand( 1, numIntNds );
    clusters.resize(numOfClusters);
    int i;
    for( i = 0; i < numIntNds; i++ )
    {
	( clusters[pnlRand( 0, numOfClusters-1 )] ).push_back( interfNds[i] );
    }

    intVecVector validClusters;
    validClusters.reserve(numOfClusters);
    for( i = 0; i < clusters.size(); i++ )
    {
	if(! clusters[i].empty())
	{
	    validClusters.push_back(clusters[i]);
	}
    }
        
    CBKInfEngine *pBKInf;
    pBKInf = CBKInfEngine::Create( pDBN, validClusters );

    C1_5SliceJtreeInfEngine *pJTreeInf;
    pJTreeInf = C1_5SliceJtreeInfEngine::Create( pDBN );

    intVector nSlices( 1, nTimeSlices );
    pEvidencesVecVector pEvid;
    
    pDBN->GenerateSamples( &pEvid, nSlices);
    int nnodesPerSlice = pDBN->GetNumberOfNodes();
    intVector nodes(nnodesPerSlice, 0);
    for( i = 0; i < nnodesPerSlice; i++ )
    {
	nodes[i] = i;
    }
    intVector ndsToToggle;
    for( i = 0; i < nTimeSlices; i++ )
    {
	std::random_shuffle( nodes.begin(), nodes.end() );
	ndsToToggle.resize( pnlRand(1, nnodesPerSlice) );
	int j;
	for( j = 0; j < ndsToToggle.size(); j++ )
	{
	    ndsToToggle[j] = nodes[j];
	}
	
	(pEvid[0])[i]->ToggleNodeState( ndsToToggle );
    }
    pBKInf->DefineProcedure( ptSmoothing, nTimeSlices );
    pBKInf->EnterEvidence( &(pEvid[0]).front(), nTimeSlices );
    pBKInf->Smoothing();

    pJTreeInf->DefineProcedure( ptSmoothing, nTimeSlices );
    pJTreeInf->EnterEvidence( &pEvid[0].front(), nTimeSlices );
    pJTreeInf->Smoothing();
    
    int querySlice = pnlRand( 0, nTimeSlices - 1 );
    int queryNode = pnlRand( 0, nnodesPerSlice - 1);
    queryNode += (querySlice ? nnodesPerSlice : 0);

    intVector query;
    pDBN->GetGraph()->GetParents( queryNode, &query );
    query.push_back( queryNode );
    std::random_shuffle( query.begin(), query.end() );
    query.resize( pnlRand(1, query.size()) );

    pBKInf->MarginalNodes(&query.front(), query.size(), querySlice);
    pJTreeInf->MarginalNodes(&query.front(), query.size(), querySlice);

    const CPotential *potBK = pBKInf->GetQueryJPD();
    const CPotential *potJTree = pJTreeInf->GetQueryJPD();
    if( !potBK->IsFactorsDistribFunEqual( potJTree , eps ) )
    {
	std::cout<<"BK query JPD \n";
	potBK->Dump();
	std::cout<<"JTree query JPD \n";
	potJTree->Dump();

	ret = TRS_FAIL;
    }
    for( i = 0; i < nTimeSlices; i++ )
    {
	delete (pEvid[0])[i];
    }
    
    delete pBKInf;
    delete pJTreeInf;
    delete pDBN;
 
    return trsResult( ret, ret == TRS_OK ? "No errors" : 
    "Bad test on BK Inference using clusters");
    
    
}
Example #4
0
static int foaThreshold( void* prm )
{
    long          lParam  = (long)prm;
    int           Flavour = lParam & 0xf;
    CvThreshType  Type    = (CvThreshType)((lParam >> 4) & 0xf);

    IplImage* Src8uR;
    IplImage* Src8sR;
    IplImage* Src32fR;
    IplImage* Src8uControlR;
    IplImage* Src8sControlR;
    IplImage* Src32fControlR;

    int    height;
    int    width;

    long   Errors = NULL;

    float  ThreshMax;
    float  ThreshMin;
    float  _Thresh;

    int    i;

    static int  read_param = 0;

    /* Initialization global parameters */
    if( !read_param )
    {
        read_param = 1;
        trslRead( &Len,    "106", "Size of sourse array" );
        trssRead( &Thresh, "125", "Threshold value" );
    }

    width = Len;
    height = Len / 2 + 1;
    
    Src8uR         = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
    Src8sR         = cvCreateImage(cvSize(width, height), IPL_DEPTH_8S, 1);
    Src32fR        = cvCreateImage(cvSize(width, height), IPL_DEPTH_32F, 1);
    Src8uControlR  = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
    Src8sControlR  = cvCreateImage(cvSize(width, height), IPL_DEPTH_8S, 1);
    Src32fControlR = cvCreateImage(cvSize(width, height), IPL_DEPTH_32F, 1);
    
    assert( Src8uR );
    assert( Src8sR );
    assert( Src32fR );
    assert( Src8uControlR );
    assert( Src8sControlR );
    assert( Src32fControlR );

    ThreshMin = (Flavour == ATS_8U ? MAX( -Thresh, 0 ) :
                 Flavour == ATS_8S ? MAX( -Thresh, -128 ) : -Thresh);
    ThreshMax = Thresh;

    for( _Thresh = ThreshMin; _Thresh <= ThreshMax; _Thresh++ )
    {
        CvSize size = cvSize( width, height );
        
        for( i = 0; i < height; i++ )
        {
            ats1bInitRandom( 0, 255, (uchar*)Src8uControlR->imageData + i * Src8uControlR->widthStep, Len );
            ats1cInitRandom( -128, 127, Src8sControlR->imageData + i * Src8sControlR->widthStep, Len );
            ats1flInitRandom( -255, 255, (float*)(Src32fControlR->imageData + i * Src32fControlR->widthStep), Len );
        }

        /* Run CVL function comparing results */
        switch( Flavour )
        {
        case ATS_8U:
            cvThreshold( Src8uControlR, Src8uR, _Thresh, 250, Type );
            /* Run my function */
            myThreshR( Src8uControlR,
                       Src8sControlR,
                       Src32fControlR,
                       _Thresh, 250, Type );
            Errors += atsCompare2Db( (uchar*)Src8uR->imageData, (uchar*)Src8uControlR->imageData,
                                     size, Src8uR->widthStep, 0 );
            break;
        case ATS_8S:
            cvThreshold( Src8sControlR,Src8sR, _Thresh, 120, Type );
            /* Run my function */
            myThreshR( Src8uControlR,
                       Src8sControlR,
                       Src32fControlR,
                       _Thresh, 120, Type );
            Errors += atsCompare2Dc( Src8sR->imageData, Src8sControlR->imageData,
                                     size, Src8sR->widthStep, 0 );
            break;
        case ATS_32F:
            cvThreshold( Src32fControlR, Src32fR, _Thresh, 250, Type );
            /* Run my function */
            myThreshR( Src8uControlR,
                       Src8sControlR,
                       Src32fControlR,
                       _Thresh, 250, Type );
            Errors += atsCompare2Dfl( (float*)Src32fR->imageData, (float*)Src32fControlR->imageData,
                                      size, Src32fR->widthStep, 0 );
            break;
        default:
            assert( 0 );
        }
    }
    cvReleaseImage( &Src8uR );
    cvReleaseImage( &Src8sR );
    cvReleaseImage( &Src32fR );
    cvReleaseImage( &Src8uControlR );
    cvReleaseImage( &Src8sControlR );
    cvReleaseImage( &Src32fControlR );

    return Errors == 0 ? TRS_OK : trsResult( TRS_FAIL, "Fixed %d errors", Errors );
}
int testBayesLearningEngine()
{
    
    int ret = TRS_OK;
    int i, j;
    const int nnodes = 4;//Number of nodes
    int numNt = 1;//number of Node Types

    float eps = -1.0f;
    while( eps <= 0)
    {
	trssRead( &eps, "0.01f", "accuracy in test");
    }
    CNodeType *nodeTypes = new CNodeType [numNt];
    for( i=0; i < numNt; i++ )
    {
	nodeTypes[i] = CNodeType(1,2);//all nodes are discrete and binary
    }

    int nodeAssociation[] = {0, 0, 0, 0};
    int obs_nodes[] = { 0, 1, 2, 3 };
    int numOfNeigh[] = { 2, 2, 2, 2};

    int neigh0[] = { 1, 2 };
    int neigh1[] = { 0, 3 };
    int neigh2[] = { 0, 3 };
    int neigh3[] = { 1, 2 };

    ENeighborType orient0[] = { ntChild, ntChild };
    ENeighborType orient1[] = { ntParent, ntChild };
    ENeighborType orient2[] = { ntParent, ntChild };
    ENeighborType orient3[] = { ntParent, ntParent };

    int *neigh[] = { neigh0, neigh1, neigh2, neigh3 };
    ENeighborType *orient[] = { orient0, orient1, orient2, orient3 };

    float prior0[] = { 1.f, 1.f };
    float prior1[] = { 1.f, 1.f, 1.f, 1.f };
    float prior2[] = { 1.f, 1.f, 1.f, 1.f };
    float prior3[] = { 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f };

    float* priors[] = { prior0,prior1,prior2,prior3 };

    float zero_array[] = { 1,1,1,1, 1,1,1,1 };

    float test_data0[] = { 0.636364f, 0.363636f };
    float test_data1[] = { 0.6f, 0.4f, 0.777778f, 0.222222f };
    float test_data2[] = { 0.866667f, 0.133333f, 0.111111f, 0.888889f };
    float test_data3[] = { 0.888889f, 0.111111f, 0.111111f, 0.888889f,
	0.142857f, 0.857143f, 0.333333f, 0.666667f };
    float* test_data_first[] = { test_data0, test_data1, test_data2, test_data3 };

    float test_data4[] = { 0.519231f, 0.480769f };
    float test_data5[] = { 0.571429f, 0.428571f, 0.884615f, 0.115385f };
    float test_data6[] = { 0.857143f, 0.142857f, 0.0769231f, 0.923077f };
    float test_data7[] = { 0.937500f, 0.0625000f, 0.12f, 0.88f,
	0.166667f, 0.833333f, 0.2f, 0.8f };
    float* test_data_second[] = { test_data4, test_data5, test_data6, test_data7 };

    CGraph* Graph = CGraph::Create( nnodes, numOfNeigh, neigh,
	orient);

    CBNet *myBNet = CBNet::Create(nnodes, numNt, nodeTypes,
	nodeAssociation, Graph );

    myBNet->AllocFactors();
    for ( int node = 0; node < nnodes; node++ )
    {
	myBNet->AllocFactor( node );
	//allocate empty CPT matrix, it needs to be allocated even if
	//we are going to learn train it.
	(myBNet->GetFactor( node ))->AllocMatrix( zero_array, matTable );
	//allocate prior matrices
	(myBNet->GetFactor( node ))->AllocMatrix( priors[node], matDirichlet );
	static_cast<CCPD *>(myBNet->GetFactor( node ))->NormalizeCPD();
    }

    ///////////////////////////////////////////////////////////////
    //Reading cases from disk

    FILE *fp;
    const int nEv = 50;
    CEvidence **m_pEv;
    m_pEv = new CEvidence *[nEv];
    std::vector<valueVector> Evidence(nEv);
    for( int ev = 0; ev < nEv; ev++)
    {
	Evidence[ev].resize(nnodes);
    }

    int simbol;
    char *argv = "../c_pgmtk/tests/testdata/cases1";
    fp = fopen(argv, "r");
    if(!fp)
    {
        argv = "../testdata/cases1";
        if ((fp = fopen(argv, "r")) == NULL)
	{
            printf( "can't open file %s\n", argv );
	    ret = TRS_FAIL;
	    return trsResult( ret, ret == TRS_OK ? "No errors" :
	        "Bad test: no file with cases");
	}
    }
    if (fp)
    {
	i = 0;
	j = 0;
	while( i < nEv)
	{
	    simbol = getc( fp );
	    if( isdigit( simbol ) )
	    {
		(Evidence[i])[j].SetInt(simbol - '0');
		j++;
		if( ( j - nnodes ) == 0 )
		{
		    i++;
		    j = 0;
		}
	    }
	}
    }

    for( i = 0; i < nEv; i++ )
    {
	m_pEv[i] = CEvidence::Create(myBNet->GetModelDomain(),
	    nnodes, obs_nodes, Evidence[i]);
    }

    //create bayesin learning engine
    CBayesLearningEngine *pLearn = CBayesLearningEngine::Create(myBNet);

    //Learn only portion of evidences
    pLearn->SetData(20, m_pEv);
    pLearn ->Learn();

    ///////////////////////////////////////////////////////////////////////////////
    CNumericDenseMatrix<float> *pMatrix;
    int length = 0;
    const float *output;

    for ( i = 0; i < nnodes; i++)
    {
	pMatrix = static_cast<CNumericDenseMatrix<float>*>(myBNet->
	    GetFactor(i)->GetMatrix(matTable));
	pMatrix->GetRawData(&length, &output);
	for (j = 0; j < length; j++)
	{
	    if( fabs(output[j] - test_data_first[i][j] ) > eps )
	    {
		ret = TRS_FAIL;
		return trsResult( ret, ret == TRS_OK ? "No errors" :
		"Bad test on BayesLearningEngine");
		break;
	    }

	}
    }

    //Learn second portion of evidences
    pLearn->AppendData(20, m_pEv+20);
    pLearn->AppendData(10, m_pEv+40);
    pLearn ->Learn();

    //check second portion
    for ( i = 0; i < nnodes; i++)
    {
	pMatrix = static_cast<CNumericDenseMatrix<float>*>(myBNet->
	    GetFactor(i)->GetMatrix(matTable));
	pMatrix->GetRawData(&length, &output);
	for (j = 0; j < length; j++)
	{
	    if( fabs(output[j] - test_data_second[i][j] ) > eps )
	    {
		ret = TRS_FAIL;
		return trsResult( ret, ret == TRS_OK ? "No errors" :
		"Bad test on BayesLearningEngine");
		break;
	    }

	}
    }

    for( i = 0; i < nEv; i++ )
    {
	delete (m_pEv[i]);

    }
    delete []m_pEv;
    delete (pLearn);
    delete (myBNet);
    delete [](nodeTypes);
    fclose(fp);
    return trsResult( ret, ret == TRS_OK ? "No errors"
	: "Bad test on BayesLearningEngine");
}
Example #6
0
static int foaCamShiftC1R( void* prm )
{
    /* Some variables */
    long       lParam  = (long)prm;
    int        Flvr = (lParam >> 4) & 0xf;
    int        depth = (Flvr == ATS_8U ? IPL_DEPTH_8U : 
                        Flvr == ATS_8S ? IPL_DEPTH_8S : IPL_DEPTH_32F);
    int        Type = lParam & 0xf;
    int        Errors = 0;

    CvTermCriteria criteria;
    CvRect     Window;
    CvSize     roi;

    IplImage*  src;

    float      alpha = 0;
    int        i;
    int        x, y;

    float      destOrientation = 0;
    float      destLen = 0;
    float      destWidth = 0;
    float      destArea = 0;
    int        destIters = 0;

    static int  read_param = 0;

    /* Initialization global parameters */
    if( !read_param )
    {
        read_param = 1;
        trsiRead( &height, "512", "source array length" );
        trsiRead( &width, "512", "source array width" );
        trsiRead( &Length, "68", "oval length" );
        trsiRead( &Width, "15", "oval width" );
        trsiRead( &iter, "10", "iterations" );
        trsiRead( &steps, "10", "steps" );
        trssRead( &epsilon, "1", "epsilon" );
    }

    /* Initilization */
    Window.x = width / 4;
    Window.y = height / 4;
    Window.width = width / 2;
    Window.height = height / 2;

    roi.width = width;
    roi.height = height;

    criteria.type = Type;
    criteria.epsilon = epsilon;
    criteria.maxIter = iter;

    /* Allocating source arrays; */
    src = cvCreateImage(roi, depth, 1);
    assert(src);

    for( alpha = -Pi / 2; alpha < Pi / 2; alpha += Pi / steps )
    {
        x = (int)(width  / 2 + width / 8 * cos(alpha));
        y = (int)(height / 2 + height / 8 * sin(alpha));

        switch( Flvr )
        {
        case ATS_8U:
            atsbInitEllipse( (uchar*)src->imageData,
                             roi.width,
                             roi.height,
                             src->widthStep,
                             x,
                             y,
                             Length,
                             Width,
                             alpha,
                             10 );
            break;
        case ATS_8S:
            atsbInitEllipse( (uchar*)src->imageData,
                             roi.width,
                             roi.height,
                             src->widthStep,
                             x,
                             y,
                             Length,
                             Width,
                             alpha,
                             10 );
            break;
        case ATS_32F:
            atsfInitEllipse( (float*)src->imageData,
                             roi.width,
                             roi.height,
                             src->widthStep,
                             x,
                             y,
                             Length,
                             Width,
                             alpha,
                             10 );
            break;
        } /* switch( Flvr ) */

        putchar('.');

        for( i = 0; i < steps; i++ )
        {
            CvConnectedComp comp;
            CvBox2D box;
            destIters = cvCamShift( src, Window, criteria, &comp, &box );
            Window = comp.rect;
            destArea = (float) comp.area;
            destOrientation = box.angle;
            destLen = box.size.height;
            destWidth = box.size.width;
        }
        
        /* Checking results */
        /* Checking orientation */
        if( fabs( alpha - destOrientation ) > 0.01 &&
            fabs( alpha + Pi - destOrientation ) > 0.01 )
        {
            Errors++;
            trsWrite( ATS_LST,
                      "orientation: act: %f,  exp: %f\n",
                      destOrientation,
                      alpha );
        }
        /* Checking length */
        if( fabs( destLen - Length * 2 ) > epsilon )
        {
            Errors++;
            trsWrite( ATS_LST,
                      "length: act: %f,  exp: %d\n",
                      destLen,
                      Length );
        }
        /* Checking width */
        if( fabs( destWidth - Width * 2 ) > epsilon )
        {
            Errors++;
            trsWrite( ATS_LST,
                      "width: act: %f,  exp: %d\n",
                      destWidth,
                      Width );
        }
    }

    cvReleaseImage(&src);

    return Errors == 0 ? TRS_OK : trsResult( TRS_FAIL, "Fixed %d errors", Errors );

} /* foaCamShiftC1R */
Example #7
0
static int fmaKMeans(void)
{
    CvTermCriteria crit;
    float** vectors;
    int*    output;
    int*    etalon_output;

    int lErrors = 0;
    int lNumVect = 0;
    int lVectSize = 0;
    int lNumClust = 0;
    int lMaxNumIter = 0;
    float flEpsilon = 0;

    int i,j;
    static int  read_param = 0;

    /* Initialization global parameters */
    if( !read_param )
    {
        read_param = 1;
        /* Read test-parameters */
        trsiRead( &lNumVect, "1000", "Number of vectors" );
        trsiRead( &lVectSize, "10", "Number of vectors" );
        trsiRead( &lNumClust, "20", "Number of clusters" );
        trsiRead( &lMaxNumIter,"100","Maximal number of iterations");
        trssRead( &flEpsilon, "0.5", "Accuracy" );
    }

    crit = cvTermCriteria( CV_TERMCRIT_EPS|CV_TERMCRIT_ITER, lMaxNumIter, flEpsilon );
    
    //allocate vectors
    vectors = (float**)cvAlloc( lNumVect * sizeof(float*) );
    for( i = 0; i < lNumVect; i++ )
    {
        vectors[i] = (float*)cvAlloc( lVectSize * sizeof( float ) );
    }

    output = (int*)cvAlloc( lNumVect * sizeof(int) );
    etalon_output = (int*)cvAlloc( lNumVect * sizeof(int) );
    
    //fill input vectors
    for( i = 0; i < lNumVect; i++ )
    {
        ats1flInitRandom( -2000, 2000, vectors[i], lVectSize );
    }
    
    /* run etalon kmeans */
    /* actually it is the simpliest realization of kmeans */

    int ni = _real_kmeans( lNumClust, vectors, lNumVect, lVectSize, etalon_output, crit.epsilon, crit.max_iter );

    trsWrite(  ATS_CON, "%d iterations done\n",  ni );
                  
    /* Run OpenCV function */
#define _KMEANS_TIME 0

#if _KMEANS_TIME
    //timing section 
    trsTimerStart(0);
    __int64 tics = atsGetTickCount();  
#endif  

    cvKMeans( lNumClust, vectors, lNumVect, lVectSize, 
              crit, output );

#if _KMEANS_TIME
    tics = atsGetTickCount() - tics;     
    trsTimerStop(0);
    //output result
    //double dbUsecs =ATS_TICS_TO_USECS((double)tics);
    trsWrite( ATS_CON, "Tics per iteration %d\n", tics/ni );    

#endif

    //compare results
    for( j = 0; j < lNumVect; j++ )
    {
        if ( output[j] != etalon_output[j] )
        {
            lErrors++;
        }
    }

    //free memory
    for( i = 0; i < lNumVect; i++ )
    {
        cvFree( &(vectors[i]) );
    }
    cvFree(&vectors);
    cvFree(&output);
    cvFree(&etalon_output);      
   
   if( lErrors == 0 ) return trsResult( TRS_OK, "No errors fixed for this text" );
    else return trsResult( TRS_FAIL, "Detected %d errors", lErrors );

}