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; }
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; }
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; }
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; }
/* * 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 }
/* * 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 }
/* * 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 }