void Check( const ISC_STATUS &error_code, ISC_STATUS *pSV, ibAPI *pibAPI) { SAString sErr; if(error_code) { char sMsg[512]; long nLen; ISC_STATUS *pvector; // Pointer to pointer to status vector. // walk through error vector and constract error string pvector = pSV; // (Re)set to start of status vector. while((nLen = pibAPI->isc_interprete(sMsg, &pvector)) != 0) // More messages? { if(!sErr.IsEmpty()) sErr += "\n"; sErr += SAString(sMsg, nLen); } throw SAException( SA_DBMS_API_Error, error_code, -1, sErr); } }
void DGSM::setN(const int n) { if (n<=10) { throw SAException(ERROR_TOO_SMALL_SAMPLE_SIZE); } N_ = n; }
void Jansen::setR(const int r) { if (r<=0) { throw SAException(ERROR_TOO_SMALL_SAMPLE_SIZE); } r_ = r; }
void DGSM::doSA() { int k = m_InputList->size(); /* number of input factors */ /* 1. Allocates input/output data */ std::unique_ptr<DMatrix> X(nullptr); std::unique_ptr<ResultMatrix> y(nullptr); if (m_SaveInput) { m_InputData.reset(new DMatrix(N_*(k+1), k)); X = std::move(m_InputData->subMatrix(0, N_)); } else { X.reset(new DMatrix(N_, k)); } if (m_SaveOutput) { m_OutputData.reset(new ResultMatrix(N_*(k+1), m_NumOutputs)); y = std::move(m_OutputData->subMatrix(0, N_)); } else { y.reset(new ResultMatrix(N_, m_NumOutputs)); } std::unique_ptr<DMatrix> x(new DMatrix(N_, k)); /* 2. Generates the first N samples */ m_RNG.LHS(*x); /* Copies then converts to target distributions */ x->copy(*X); m_RNG.convert(*X, m_InputList); /* 3. Runs simulation for the first N samples */ simulate(*X, *y); /* 4. Allocates xdiff, ydiff if needs * xdiff is the 1-column different from X and ydiff is its corresponding * output * */ std::unique_ptr<DMatrix> xdiff(nullptr); if (!m_SaveInput) { xdiff.reset(new DMatrix(N_, k)); } std::unique_ptr<ResultMatrix> ydiff(nullptr); if (!m_SaveOutput) { ydiff.reset(new ResultMatrix(N_, m_NumOutputs)); } std::unique_ptr<DMatrix> stats(new DMatrix(3, m_NumOutputs)); const int* labels = y->getLabels(); /* 5. Estimate sensitivity indices for each input factor */ for (int iK=0; iK<k; ++iK) { /* Makes xdiff, ydiff refer to their correct location if needs */ if (m_SaveInput) { xdiff = std::move(m_InputData->subMatrix((iK+1)*N_, N_)); } if (m_SaveOutput) { ydiff = std::move(m_OutputData->subMatrix((iK+1)*N_, N_)); } /* Copy the first N samples to xdiff and diffs the column iK*/ x->copy(*xdiff); for (int iRow=0; iRow<N_; ++iRow) { /* Changes values in column iK */ double* row = xdiff->getRow(iRow); if (row[iK] + delta_ >= 1) row[iK] -= delta_; else row[iK] += delta_; } /* Converts xdiff to target distributions */ m_RNG.convert(*xdiff, m_InputList); /* Runs simulation */ simulate(*xdiff, *ydiff); /* Estimates sensitivity indices */ const int* labelsdiff = ydiff->getLabels(); double* sens = m_Sens->getRow(iK); for (int iOut=0; iOut< m_NumOutputs; ++iOut) { double mean=0, absmean=0, std=0; double derivative = 0; int cnt = 0; for (int iRow = 0; iRow < N_; ++iRow) { if (labels[iRow] == SIM_SUCCESS && labelsdiff[iRow] == SIM_SUCCESS) { derivative = (ydiff->getRow(iRow)[iOut] - y->getRow(iRow)[iOut]) / (X->getRow(iRow)[iK] - xdiff->getRow(iRow)[iK]); cnt++; mean += derivative; absmean += derivative > 0 ? derivative : -derivative; std += derivative*derivative; } } if (cnt < N_ * (1-m_FailureRate)) throw SAException(ERROR_EXCEEDING_FAILURE_RATE); mean /= cnt; absmean /= cnt; std = sqrt(std/cnt - mean*mean); sens[iOut*iK] = mean; sens[iOut*iK+1] = absmean; sens[iOut*iK+2] = std; } } }
void DGSM::setDelta(const double delta) { if (delta>=0.5) throw SAException(ERROR_DGSM_BIG_DELTA); delta_ = delta; }
void Jansen::estimate() { int k = m_InputData->getNumCols(); /* number of input factors */ int N = k*(r_+1); double minCnt = (1-m_FailureRate) * r_; int* labels = m_OutputData->getLabels(); /* allocates a temporary vector of Di of input factors */ std::unique_ptr<double[]> Dvec_ptr(new double[k]); double* Dvec = Dvec_ptr.get(); /* allocate a temporary vector of Dt of input factors */ std::unique_ptr<double[]> Dtvec_ptr(new double[k]); double* Dtvec = Dtvec_ptr.get(); double ** outputs = m_OutputData->getData(); for (int iOut = 0; iOut< m_OutputData->getNumCols(); ++iOut) /* for each output */ { double D=0; /* total output variance */ double f0 = 0; /* mean of outputs */ for (int iK=0; iK<k; ++iK) /* for each input factor */ { int cnts[3] = {0, 0, 0}; /* countt the numbers of valid simulation results */ Dvec[iK] = 0; Dtvec[iK] = 0; double colD = 0; /* output variance of column iK */ double f0 = 0; /* mean of column iK */ /* Iterates from the first row to 'r' row of the winding stair design * matrix of outputs */ for (int iR=0; iR<=r_; ++iR) { /* Identifies row ids of samples for variance estimation * - a sample at baseId row belongs to column iK of winding stairs design * * Since the total number of samples is N=(r+1)*k, nextId and prevId * should never exceed N **/ int baseId = iR*k + iK; int prevId = baseId-1; int nextId = baseId + k-1; if (labels[baseId] == SIM_SUCCESS) { cnts[0]++; f0 += outputs[baseId][iOut]; colD += outputs[baseId][iOut]*outputs[baseId][iOut]; if (nextId<N && labels[prevId] == SIM_SUCCESS) { cnts[1]++; double diff = outputs[baseId][iOut] - outputs[nextId][iOut]; Dvec[iK] += diff*diff; } if (prevId>0 && labels[nextId] == SIM_SUCCESS) { cnts[2]++; double diff = outputs[baseId][iOut] - outputs[prevId][iOut]; Dtvec[iK] += diff*diff; } } } if (cnts[0] < minCnt || cnts[1] < minCnt || cnts[2] < minCnt ) { throw SAException(ERROR_EXCEEDING_FAILURE_RATE); } f0 /= cnts[0]; D += (colD/cnts[0]-f0*f0); Dvec[iK] /= 2*cnts[1]; Dtvec[iK] /= 2*cnts[2]; } /* estimate D */ D /= k; /* estimate sensitivity measures */ for (int iK=0; iK<k; ++iK) { double* sens = m_Sens->getRow(iK); sens[2*iOut] = 1 - Dvec[iK]/D; sens[2*iOut+1] = Dtvec[iK]/D; } } }
void RBD::doSA() { /* 1. Determine sampling size */ if (N_ < 2*omega_ + 1) throw SAException(ERROR_RBD_SMALL_SAMPLE_SIZE); int N = N_ % 2 == 1 ? N_ : N_ + 1; /* Makes N an odd number (it is not important) */ if (useFFT_) N = len4FFT(N_); /* 2. Allocates data */ int k = m_InputList->size(); std::unique_ptr<DMatrix> x(new DMatrix(N, k)); /* Input data */ std::unique_ptr<IMatrix> p(new IMatrix(k, N)); /* Array of permutation vectors */ std::unique_ptr<ResultMatrix> y(new ResultMatrix(N, m_NumOutputs)); /* Output data */ double** xdata = x->getData(); int** pdata = p->getData(); double** ydata = y->getData(); /* 3. Sets up permuation vectors */ for (int iK=0; iK<k; ++iK) { for (int iN=0; iN<N; ++iN) { pdata[iK][iN] = iN; } m_RNG.shuffle(pdata[iK], N); } /* 4. Inits the pilot sample */ std::unique_ptr<double[]> x0ptr(new double[2*N]); /* pilot sample */ double* x0 = x0ptr.get(); double* s = &x0[N]; for (int i=0; i<N; ++i) { s[i] = MY_PI*(2*i+1-N)/N; x0[i] = 0.5 + asin(sin(omega_*s[i])); } /* 5. Samples input data */ for (int iK=0; iK<k; ++iK) { for (int iN=0; iN<N; ++iN) { xdata[pdata[iK][iN]][iK] = x0[iN]; } } /* 6. Converts input data to target distributions */ m_RNG.convert(*x, m_InputList); /* 7. Runs simulation */ simulate(*x, *y); /* 8. Estimates sensitivity indices */ std::unique_ptr<double[]> ytmp_ptr(new double[N]); double* ytmp = ytmp_ptr.get(); int* labels = y->getLabels(); for (int iK=0; iK<k; ++iK) { for (int iOut=0; iOut< m_NumOutputs; ++iOut) { for (int iN=0; iN<N; ++iN) { ytmp[iN] = ydata[pdata[iK][iN]][iOut]; } interpolate(ytmp, labels, N); if (useFFT_) { /* Estimate Fourier coeffients using FFT */ sdft(ytmp, N); double V=0; for (int iN=1; iN<N/2; ++iN) { V += ytmp[iN]; } double Vi = 0; for (int iM=1; iM<M_+1; ++iM) { Vi += ytmp[iM*omega_]; } m_Sens->getRow(iK)[iOut]= Vi/V; } else /* Estimates Fourier coefficients directly */ { double V=0, f0=0; /* estimates total variance */ for (int iN=0; iN<N; ++iN) { f0 += ytmp[iN]; V += ytmp[iN] * ytmp[iN]; } f0 /= N; V /= N; V -= f0*f0; /* estimate Fourier coefficients and Vi */ double Vi = 0; for (int iM=1; iM<M_+1; ++iM) { double A=0, B=0; for (int iN = 0; iN<N; ++iN) { A += ytmp[iN] * cos(iM*omega_*s[iN]); B += ytmp[iN] * sin(iM*omega_*s[iN]); } A /= N; B /= N; Vi += A*A + B*B; } m_Sens->getRow(iK)[iOut] = 2*Vi/V; } } } /* 9. Retains input/output data if needs */ if (m_SaveInput) m_InputData = std::move(x); if (m_SaveOutput) m_OutputData = std::move(y); }
void RBD::setOmega(const int om) { if (om <= 0) throw SAException(ERROR_RBD_NONE_POSITIVE_OMEGA); omega_ = om; }