Пример #1
0
BUS_Status I2C_Start(void)
{

    //before: SCL=H SDA=H,means bus is free
	SDA_H;			//1
	SCL_H;			//2
    I2C_delay();	//3
	
	if(!(SDA_read))
	{
        ERROR_MACRO(IIC_DEV,I2C_Start_ERROR_BUS_BUSY);
		return BUS_BUSY;
	}

	SDA_L;			//4
	I2C_delay();	//5

//	SDA_L;			//6
//	I2C_delay();	//7
	
	if(SDA_read)
	{
        ERROR_MACRO(IIC_DEV,I2C_Start_ERROR_BUS_ERROR);
		return BUS_ERROR;
	}

    SCL_L;

    //After: SCL=L SDA=L
	
	return BUS_READY;
}
Пример #2
0
Status TMP102_Init(void)//初始化TMP102
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    //send start------------------1
    if(I2C_Start()!=BUS_READY){
        ERROR_MACRO(TMP102_DEV,INT_ERROR_SEND_START);
        return ERROR_FAILED;
    }

    //send SlaveADDR with write
    I2C_SendByte(TMP102_WRITE_ADDR);//------------------2
    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,INT_ERROR_SEND_DEVADDR);//------------------3
        return ERROR_FAILED;
    }

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    //send CONF_ADDR------------------4
    I2C_SendByte(TMP102_CONF_REG);
    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,INT_ERROR_SEND_CONFADDR);//------------------5
        return ERROR_FAILED;
    }

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    //写Configuration Register 12位温度 连续转换//------------------6
    I2C_SendByte(0x60);
    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,INT_ERROR_WRITE_CONFA);//------------------7
        return ERROR_FAILED;
    }

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    I2C_SendByte(TMP102_8HZ);//------------------8
    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,INT_ERROR_WRITE_CONFB);//------------------9
        return ERROR_FAILED;
    }

    //send stop
    I2C_Stop();//------------------10
    return OK_PASS;
}
Пример #3
0
Status ReadTMP102(u16 *TO_EEPROM,u16 *Data_ptr)//读取tmp101的2个字节温度
{
    u16 TMP102_Data=0x0000;


    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	


    //send start------------------1
    if(I2C_Start()!=BUS_READY){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_START);
        return ERROR_FAILED;
    }


    //send SlaveADDR with write
    I2C_SendByte(TMP102_WRITE_ADDR);//------------------2



    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_DEVADDR);//------------------3
        return ERROR_FAILED;
    }



	


    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    //send CONF_ADDR------------------4
    I2C_SendByte(TMP102_TEMP_REG);
    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_TEMPADDR);//------------------5
        return ERROR_FAILED;
    }

    I2C_Stop();//------------------NiMa没看到!!!!!!!!!!!!!!

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    //send start------------------6
    if(I2C_Start()!=BUS_READY){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_RESTART);
        return ERROR_FAILED;
    }

    //send SlaveADDR with write
    I2C_SendByte(TMP102_READ_ADDR);//------------------7
    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_RDEVADDR);//------------------8
        return ERROR_FAILED;
    }

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    //read TEMP
    TMP102_Data=0x0000;

    TMP102_Data = I2C_ReceiveByte();//--Byte1-------9
    I2C_Ack();//------------------10


    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    TMP102_Data<<=8;
    TMP102_Data |= I2C_ReceiveByte();//---Byte2-----11
    I2C_Ack();//------------------12

    //send stop
    I2C_Stop();//------------------13

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~   Done   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    TMP102_Data>>=4;


    *Data_ptr = TMP102_Data;

    //==============================================================
    //-25~80



    if(TMP102_Data&(0x800)){
        //负数要转换
        TMP102_Data-=(0x0E70-0x0500-1);
    }

    if(TMP102_Data<=0x690){
        *TO_EEPROM = TMP102_Data*4;
    }
    else{
        printf("Out of range from TMP102,TMP102=%X\t\r\n",*Data_ptr);
        *TO_EEPROM = TO_EEPROM_ERROR;
    }

    //printf("TMP102=%X\tEEPROM=%X\r\n",*Data_ptr,*TO_EEPROM);
    return OK_PASS;
}
Пример #4
0
u16 ReadTMP102_REG(unsigned char reg)
{
    u16 TMP102_Data=0x0000;


    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/



    //send start------------------1
    if(I2C_Start()!=BUS_READY){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_START);
    }


    //send SlaveADDR with write
    I2C_SendByte(TMP102_WRITE_ADDR);//------------------2
    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_DEVADDR);//------------------3
    }






    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    //send CONF_ADDR------------------4
    I2C_SendByte(reg);
    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_TEMPADDR);//------------------5
    }

    I2C_Stop();//------------------NiMa没看到!!!!!!!!!!!!!!

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    //send start------------------6
    if(I2C_Start()!=BUS_READY){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_RESTART);
        return ERROR_FAILED;
    }

    //send SlaveADDR with write
    I2C_SendByte(TMP102_READ_ADDR);//------------------7
    if(I2C_WaitAck()!=BUS_ACK){
        ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_RDEVADDR);//------------------8
        return ERROR_FAILED;
    }

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    //read TEMP
    TMP102_Data=0x0000;

    TMP102_Data = I2C_ReceiveByte();//--Byte1-------9
    I2C_Ack();//------------------10

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~  Frame 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    TMP102_Data=(TMP102_Data<<8);
    TMP102_Data |=(u8)I2C_ReceiveByte();//---Byte2-----11
    I2C_Ack();//------------------12

    //send stop
    I2C_Stop();//------------------13

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~   Done   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    return TMP102_Data;

}
Пример #5
0
/*
 * Return an optimized hypercube according to the criteria given
 *
 */
void optimumLHS_C(int* N, int* K, int* MAXSWEEPS, double* EPS, int* pOld,
                  double* J1, int* J2, int* J3, int* jLen, int* pNew)
{
	double gOld;
	double deltag1 = 0.0;
	double deltag;
	int test, iter, i, j, k, r, posit, row, col;

	/* find the initial optimality measure */
	gOld = sumInvDistance_int(pOld, N, K);

	PRINT_MACRO("Beginning Optimality Criterion %f \n", gOld);

#if PRINT_RESULT
	lhsPrint(N, K, pOld, 1);
#endif

	test = 0;
	iter = 0;
	j = 0;

	while (test == 0)
	{
		if (iter == *MAXSWEEPS) break;
		iter++;
		/* iterate over the columns */
		for (j = 0; j < *K; j++)
		{
			r = 0;
			/* iterate over the rows for the first point from 0 to N-2 */
			for (i = 0; i < (*N - 1); i++)
			{
				/* iterate over the rows for the second point from i+1 to N-1 */
				for (k = (i + 1); k < *N; k++)
				{
				/* put the values from pOld into pNew */
					for (row = 0; row < *N; row++)
					{
						for (col = 0; col < *K; col++)
						{
							pNew[row * (*K) + col] = pOld[row * (*K) + col];
						}
					}
					/* exchange two values (from the ith and kth rows) in the jth column
					* and place them in the new matrix */
					pNew[i * (*K) + j] = pOld[k * (*K) + j];
					pNew[k * (*K) + j] = pOld[i * (*K) + j];

					/* store the optimality of the newly created matrix and the rows that
					* were interchanged */
					J1[r] = sumInvDistance_int(pNew, N, K);
					J2[r] = i;
					J3[r] = k;
					r++;
				}
			}
			/* once all combinations of the row interchanges have been completed for
			* the current column j, store the old optimality measure (the one we are
			* trying to beat) */
			J1[r] = gOld;
			J2[r] = 0;
			J3[r] = 0;

			/* Find which optimality measure is the lowest for the current column.
			* In other words, which two row interchanges made the hypercube better in
			* this column */
			posit = 0;
			for (k = 0; k < *jLen; k++)
			{
				if (J1[k] < J1[posit]) posit = k;
			}

			/* If the new minimum optimality measure is better than the old measure */
			if (J1[posit] < gOld)
			{
				/* put pOld in pNew */
				for (row = 0; row < *N; row++)
				{
					for (col = 0; col < *K; col++)
					{
						pNew[row * (*K) + col] = pOld[row * (*K) + col];
					}
				}
				/* Interchange the rows that were the best for this column */
				pNew[J2[posit] * (*K) + j] = pOld[J3[posit] * (*K) + j];
				pNew[J3[posit] * (*K) + j] = pOld[J2[posit] * (*K) + j];

				/* put pNew back in pOld for the next iteration */
				for (row = 0; row < *N; row++)
				{
					for (col = 0; col < *K; col++)
					{
						pOld[row * (*K) + col] = pNew[row * (*K) + col];
					}
				}

				/* if this is not the first column we have used for this sweep */
				if (j > 0)
				{
					/* check to see how much benefit we gained from this sweep */
					deltag = fabs(J1[posit] - gOld);
					if (deltag < ((*EPS) * deltag1))
					{
						test = 1;
						PRINT_MACRO("Algorithm stopped when the change in the inverse distance measure was smaller than %f \n", ((*EPS) * deltag1));
					}
				}
				/* if this is first column of the sweep, then store the benefit gained */
				else
				{
					deltag1 = fabs(J1[posit] - gOld);
				}

				/* replace the old optimality measure with the current one */
				gOld = J1[posit];
			}
			/* if the new and old optimality measures are equal */
			else if (J1[posit] == gOld)
			{
				test = 1;
				PRINT_MACRO("Algorithm stopped when changes did not impove design optimality\n");
			}
			/* if the new optimality measure is worse */
			else if (J1[posit] > gOld)
			{
				ERROR_MACRO("Unexpected Result: Algorithm produced a less optimal design\n");
				test = 1;
			}
			/* if there is a reason to exit... */
			if (test == 1) break;
		}
	}

	/* if we made it through all the sweeps */
	if (iter == *MAXSWEEPS)
	{
		PRINT_MACRO("%d full sweeps completed\n", *MAXSWEEPS);
	}
	/* if we didn't make it through all of them */
	else
	{
		PRINT_MACRO("Algorithm used %d sweep(s) and %d extra column(s)\n", iter-1, j);
	}

	PRINT_MACRO("Final Optimality Criterion %f \n", gOld);

	test = lhsCheck(N, K, pOld, 1);

	if (test == 0)
	{
		/* the error function should send an error message through R */
		ERROR_MACRO("Invalid Hypercube\n");
	}

#if PRINT_RESULT
	lhsPrint(N, K, pOld, 1);
#endif
}
Пример #6
0
/*
 * Return an optimized hypercube according to the criteria given
 *
 */
void optSeededLHS_C(int* N, int* K, int* maxSweeps, double* eps, double* oldHypercube,
                    int* optimalityRecordLength, int* bVerbose)
{
    size_t nOptimalityRecordLength = static_cast<size_t>(*optimalityRecordLength);
    size_t nsamples = static_cast<size_t>(*N);
    size_t nparameters = static_cast<size_t>(*K);
    bool isVerbose = static_cast<bool>(*bVerbose);
    size_t nMaxSweeps = static_cast<size_t>(*maxSweeps);
    double eps_change = *eps;

    int extraColumns = 0;
    double gOptimalityOld;
    double optimalityChangeOld = 0.0;
    double optimalityChange;
    int test;
    size_t iter, posit, optimalityRecordIndex;

    matrix_unsafe<double> oldHypercube_new = matrix_unsafe<double>(nsamples, nparameters, oldHypercube, true);
    matrix<double> newHypercube_new = matrix<double>(nsamples, nparameters, true);
    std::vector<double> optimalityRecord_new = std::vector<double>(nOptimalityRecordLength);
    std::vector<size_t> interchangeRow1_new = std::vector<size_t>(nOptimalityRecordLength);
    std::vector<size_t> interchangeRow2_new = std::vector<size_t>(nOptimalityRecordLength);

    /* find the initial optimality measure */
    gOptimalityOld = utilityLHS::sumInvDistance<double>(oldHypercube_new.values, static_cast<int>(nsamples), static_cast<int>(nparameters));

    if (isVerbose)
        PRINT_MACRO("Beginning Optimality Criterion %f \n", gOptimalityOld);

#if PRINT_RESULT
    utilityLHS<double>::lhsPrint(nsamples, nparameters, oldHypercube);
#endif

    test = 0;
    iter = 0;

    while (test == 0)
    {
        if (iter == nMaxSweeps) break;
        iter++;
        /* iterate over the columns */
        for (size_t j = 0; j < nparameters; j++)
        {
            optimalityRecordIndex = 0;
            /* iterate over the rows for the first point from 0 to N-2 */
            for (size_t i = 0; i < nsamples - 1; i++)
            {
                /* iterate over the rows for the second point from i+1 to N-1 */
                for (size_t k = i + 1; k < nsamples; k++)
                {
                    /* put the values from oldHypercube into newHypercube */
                    for (size_t row = 0; row < nsamples; row++)
                    {
                        for (size_t col = 0; col < nparameters; col++)
                        {
                            newHypercube_new(row, col) = oldHypercube_new(row, col);
                        }
                    }
                    /* exchange two values (from the ith and kth rows) in the jth column
                    * and place them in the new matrix */
                    newHypercube_new(i, j) = oldHypercube_new(k, j);
                    newHypercube_new(k, j) = oldHypercube_new(i, j);

                    /* store the optimality of the newly created matrix and the rows that
                    * were interchanged */
                    optimalityRecord_new[optimalityRecordIndex] = utilityLHS::sumInvDistance<double>(newHypercube_new.values.data(), static_cast<int>(nsamples), static_cast<int>(nparameters));
                    interchangeRow1_new[optimalityRecordIndex] = i;
                    interchangeRow2_new[optimalityRecordIndex] = k;
                    optimalityRecordIndex++;
                }
            }
            /* once all combinations of the row interchanges have been completed for
            * the current column j, store the old optimality measure (the one we are
            * trying to beat) */
            optimalityRecord_new[optimalityRecordIndex] = gOptimalityOld;
            interchangeRow1_new[optimalityRecordIndex] = 0;
            interchangeRow2_new[optimalityRecordIndex] = 0;

            /* Find which optimality measure is the lowest for the current column.
            * In other words, which two row interchanges made the hypercube better in
            * this column */
            posit = 0;
            for (size_t k = 0; k < nOptimalityRecordLength; k++)
            {
                if (optimalityRecord_new[k] < optimalityRecord_new[posit]) posit = k;
            }

            /* If the new minimum optimality measure is better than the old measure */
            if (optimalityRecord_new[posit] < gOptimalityOld)
            {
                /* put oldHypercube in newHypercube */
                for (size_t row = 0; row < nsamples; row++)
                {
                    for (size_t col = 0; col < nparameters; col++)
                    {
                        newHypercube_new(row, col) = oldHypercube_new(row, col);
                    }
                }
                /* Interchange the rows that were the best for this column */
                newHypercube_new(interchangeRow1_new[posit], j) = oldHypercube_new(interchangeRow2_new[posit], j);
                newHypercube_new(interchangeRow2_new[posit], j) = oldHypercube_new(interchangeRow1_new[posit], j);

                /* put newHypercube back in oldHypercube for the next iteration */
                for (size_t row = 0; row < nsamples; row++)
                {
                    for (size_t col = 0; col < nparameters; col++)
                    {
                        oldHypercube_new(row, col) = newHypercube_new(row, col);
                    }
                }

                /* if this is not the first column we have used for this sweep */
                if (j > 0)
                {
                    /* check to see how much benefit we gained from this sweep */
                    optimalityChange = std::fabs(optimalityRecord_new[posit] - gOptimalityOld);
                    if (optimalityChange < eps_change * optimalityChangeOld)
                    {
                        test = 1;
                        if (isVerbose)
                            PRINT_MACRO("Algorithm stopped when the change in the inverse distance measure was smaller than %f \n", ((eps_change) * optimalityChangeOld));
                    }
                }
                /* if this is first column of the sweep, then store the benefit gained */
                else
                {
                    optimalityChangeOld = std::fabs(optimalityRecord_new[posit] - gOptimalityOld);
                }

                /* replace the old optimality measure with the current one */
                gOptimalityOld = optimalityRecord_new[posit];
            }
            /* if the new and old optimality measures are equal */
            else if (optimalityRecord_new[posit] == gOptimalityOld)
            {
                test = 1;
                if (isVerbose)
                    PRINT_MACRO("Algorithm stopped when changes did not impove design optimality\n");
            }
            /* if the new optimality measure is worse */
            else if (optimalityRecord_new[posit] > gOptimalityOld)
            {
                ERROR_MACRO("Unexpected Result: Algorithm produced a less optimal design\n");
                test = 1;
            }
            /* if there is a reason to exit... */
            if (test == 1) break;
            extraColumns++;
        }
    }

    /* if we made it through all the sweeps */
    if (iter == nMaxSweeps)
    {
        if (isVerbose)
            PRINT_MACRO("%d full sweeps completed\n", nMaxSweeps);
    }
    /* if we didn't make it through all of them */
    else
    {
        if (isVerbose)
            PRINT_MACRO("Algorithm used %d sweep(s) and %d extra column(s)\n", iter-1, extraColumns);
    }

    if (isVerbose)
        PRINT_MACRO("Final Optimality Criterion %f \n", gOptimalityOld);

#if PRINT_RESULT
    utilityLHS<double>::lhsPrint(nsamples, nparameters, oldHypercube_new.values);
#endif
}
Пример #7
0
    /*
     * Return an optimized hypercube according to the criteria given
     *
     */
    void optSeededLHS(int n, int k, int maxSweeps, double eps, bclib::matrix<double> & oldHypercube,
                      int optimalityRecordLength, bool bVerbose)
    {
        if (n < 1 || k < 1 || maxSweeps < 1 || eps <= 0)
        {
            throw std::runtime_error("nsamples or nparameters or maxSweeps are less than 1 or eps <= 0");
        }
        unsigned int nOptimalityRecordLength = static_cast<unsigned int>(optimalityRecordLength);
        msize_type nsamples = static_cast<msize_type>(n);
        msize_type nparameters = static_cast<msize_type>(k);
        unsigned int nMaxSweeps = static_cast<unsigned int>(maxSweeps);
        double eps_change = eps;

        int extraColumns = 0;
        double gOptimalityOld;
        double optimalityChangeOld = 0.0;
        double optimalityChange;
        int test;
        unsigned int iter, posit, optimalityRecordIndex;

        //matrix_unsafe<double> oldHypercube_new = matrix_unsafe<double>(nsamples, nparameters, oldHypercube, true);
        bclib::matrix<double> newHypercube = bclib::matrix<double>(nsamples, nparameters);
        std::vector<double> optimalityRecord = std::vector<double>(nOptimalityRecordLength);
        std::vector<unsigned int> interchangeRow1 = std::vector<unsigned int>(nOptimalityRecordLength);
        std::vector<unsigned int> interchangeRow2 = std::vector<unsigned int>(nOptimalityRecordLength);

        /* find the initial optimality measure */
        gOptimalityOld = sumInvDistance<double>(oldHypercube);

        if (bVerbose)
        {
            PRINT_MACRO("Beginning Optimality Criterion %f \n", gOptimalityOld);
        }

#if PRINT_RESULT
        lhslib::lhsPrint(oldHypercube, false);
        //utilityLHS<double>::lhsPrint(nsamples, nparameters, oldHypercube);
#endif

        test = 0;
        iter = 0;

        while (test == 0)
        {
            if (iter == nMaxSweeps) 
            {
                break;
            }
            iter++;
            /* iterate over the columns */
            for (msize_type j = 0; j < nparameters; j++)
            {
                optimalityRecordIndex = 0;
                /* iterate over the rows for the first point from 0 to N-2 */
                for (msize_type i = 0; i < nsamples - 1; i++)
                {
                    /* iterate over the rows for the second point from i+1 to N-1 */
                    for (msize_type k = i + 1; k < nsamples; k++)
                    {
                        /* put the values from oldHypercube into newHypercube */
                        copyMatrix<double>(newHypercube, oldHypercube);
                        
                        /* exchange two values (from the ith and kth rows) in the jth column
                        * and place them in the new matrix */
                        newHypercube(i, j) = oldHypercube(k, j);
                        newHypercube(k, j) = oldHypercube(i, j);

                        /* store the optimality of the newly created matrix and the rows that
                        * were interchanged */
                        optimalityRecord[optimalityRecordIndex] = sumInvDistance<double>(newHypercube);
                        interchangeRow1[optimalityRecordIndex] = i;
                        interchangeRow2[optimalityRecordIndex] = k;
                        optimalityRecordIndex++;
                    }
                }
                /* once all combinations of the row interchanges have been completed for
                * the current column j, store the old optimality measure (the one we are
                * trying to beat) */
                optimalityRecord[optimalityRecordIndex] = gOptimalityOld;
                interchangeRow1[optimalityRecordIndex] = 0;
                interchangeRow2[optimalityRecordIndex] = 0;

                /* Find which optimality measure is the lowest for the current column.
                * In other words, which two row interchanges made the hypercube better in
                * this column */
                posit = 0;
                for (vsize_type k = 0; k < nOptimalityRecordLength; k++)
                {
                    if (optimalityRecord[k] < optimalityRecord[posit])
                    {
                        posit = k;
                    }
                }

                /* If the new minimum optimality measure is better than the old measure */
                if (optimalityRecord[posit] < gOptimalityOld)
                {
                    /* put oldHypercube in newHypercube */
                    copyMatrix<double>(newHypercube, oldHypercube);
                    
                    /* Interchange the rows that were the best for this column */
                    newHypercube(interchangeRow1[posit], j) = oldHypercube(interchangeRow2[posit], j);
                    newHypercube(interchangeRow2[posit], j) = oldHypercube(interchangeRow1[posit], j);

                    /* put newHypercube back in oldHypercube for the next iteration */
                    copyMatrix<double>(oldHypercube, newHypercube);

                    /* if this is not the first column we have used for this sweep */
                    if (j > 0)
                    {
                        /* check to see how much benefit we gained from this sweep */
                        optimalityChange = std::fabs(optimalityRecord[posit] - gOptimalityOld);
                        if (optimalityChange < eps_change * optimalityChangeOld)
                        {
                            test = 1;
                            if (bVerbose)
                            {
                                PRINT_MACRO("Algorithm stopped when the change in the inverse distance measure was smaller than %f \n", ((eps_change) * optimalityChangeOld));
                            }
                        }
                    }
                    /* if this is first column of the sweep, then store the benefit gained */
                    else
                    {
                        optimalityChangeOld = std::fabs(optimalityRecord[posit] - gOptimalityOld);
                    }

                    /* replace the old optimality measure with the current one */
                    gOptimalityOld = optimalityRecord[posit];
                }
                /* if the new and old optimality measures are equal */
                else if (optimalityRecord[posit] == gOptimalityOld)
                {
                    test = 1;
                    if (bVerbose)
                    {
                        PRINT_MACRO("Algorithm stopped when changes did not impove design optimality\n");
                    }
                }
                /* if the new optimality measure is worse */
                else if (optimalityRecord[posit] > gOptimalityOld)
                {
                    ERROR_MACRO("Unexpected Result: Algorithm produced a less optimal design\n");
                    test = 1;
                }
                /* if there is a reason to exit... */
                if (test == 1)
                {
                    break;
                }
                extraColumns++;
            }
        }

        /* if we made it through all the sweeps */
        if (iter == nMaxSweeps)
        {
            if (bVerbose)
            {
                PRINT_MACRO("%d full sweeps completed\n", static_cast<int>(nMaxSweeps));
            }
        }
        /* if we didn't make it through all of them */
        else
        {
            if (bVerbose)
            {
                PRINT_MACRO("Algorithm used %d sweep(s) and %d extra column(s)\n", static_cast<int>(iter-1), static_cast<int>(extraColumns));
            }
        }

        if (bVerbose)
        {
            PRINT_MACRO("Final Optimality Criterion %f \n", gOptimalityOld);
        }

#if PRINT_RESULT
        lhsPrint(oldHypercube, false);
#endif
    }