/// <summary> Normalizes PDF and CDF such that area under curve adds to 100 </summary> public void Normalize_Dists(ref ExceedanceCurve thisCurve) { double pdfSum = 0; if (thisCurve.distSize <= 1) { return; } double pdfInt = (thisCurve.upperBound - thisCurve.lowerBound) / (thisCurve.distSize - 1); for (int i = 0; i < thisCurve.distSize; i++) { pdfSum = pdfSum + thisCurve.probDist[i]; } pdfSum = pdfSum * pdfInt; if (pdfSum > 0) { for (int i = 0; i < thisCurve.distSize; i++) { thisCurve.probDist[i] = thisCurve.probDist[i] / pdfSum; } } thisCurve.cumulDist[0] = thisCurve.probDist[0] * pdfInt; for (int i = 1; i < thisCurve.distSize; i++) // Cumulative distribution function (CDF) of normal distribution = sum of PDF for all x <= X { thisCurve.cumulDist[i] = thisCurve.cumulDist[i - 1] + thisCurve.probDist[i] * pdfInt; } }
/// <summary> Calculates the probability density function from the cumulative distribution function </summary> public void Calc_PDF_from_CDF(ref ExceedanceCurve thisExceed) { double distInt = (thisExceed.upperBound - thisExceed.lowerBound) / (thisExceed.distSize - 1); thisExceed.probDist[0] = thisExceed.cumulDist[0] * distInt; if (distInt == 0) { return; } for (int i = 1; i < thisExceed.distSize - 1; i++) { thisExceed.probDist[i] = (thisExceed.cumulDist[i + 1] - thisExceed.cumulDist[i]) / distInt; } }
/// <summary> Deletes specified exceedance curve from list </summary> public void Delete_Exceed(string Delete_Exceed_str) { ExceedanceCurve[] newCurves = new ExceedanceCurve[Num_Exceed() - 1]; int newCrvInd = 0; foreach (ExceedanceCurve theseExceed in exceedCurves) { if (theseExceed.exceedStr != Delete_Exceed_str) { newCurves[newCrvInd] = theseExceed; newCrvInd++; } } exceedCurves = newCurves; }
/// <summary> Gets performance factor for specified exceedance curve with specified X-value (0 - 1) </summary> /// <returns> Returns performance factor </returns> public double Get_PF_Value(double val, ExceedanceCurve thisCurve) { double Exceed_Val = 0; for (int i = 0; i < thisCurve.distSize - 1; i++) { if (val <= thisCurve.cumulDist[i + 1] && val >= thisCurve.cumulDist[i]) { Exceed_Val = thisCurve.xVals[i]; break; } } if (Exceed_Val == 0) { Exceed_Val = thisCurve.xVals[0]; } return(Exceed_Val); }
/// <summary> Calculates weighted average probability and cumulative distribution with specified mean, SD and weights of defined modes </summary> public void CalculateProbDist(ref ExceedanceCurve thisCurve) { double X_int; int numModes = thisCurve.modes.Length; if (numModes == 0) { return; } if (thisCurve.upperBound > thisCurve.lowerBound && thisCurve.upperBound != thisCurve.lowerBound) { X_int = (thisCurve.upperBound - thisCurve.lowerBound) / (thisCurve.distSize - 1); } else { return; } // Reset PDF Array.Resize(ref thisCurve.probDist, thisCurve.probDist.Length); for (int i = 0; i < thisCurve.distSize; i++) { thisCurve.xVals[i] = thisCurve.lowerBound + X_int * i; for (int j = 0; j < numModes; j++) { double thisMean = thisCurve.modes[j].mean; double thisSD = thisCurve.modes[j].SD; double thisWeight = thisCurve.modes[j].weight; // Probability density function of normal distribution thisCurve.probDist[i] = thisCurve.probDist[i] + thisWeight * (1 / Math.Pow((2 * Math.Pow(thisSD, 2) * Math.PI), 0.5) * Math.Pow(Math.E, -(Math.Pow((thisCurve.xVals[i] - thisMean), 2) / (2 * Math.Pow(thisSD, 2))))); } } }
/// <summary> Used when importing CDF from a .CSV file. Fills in all Performance factors by interpolating between points in file. </summary> public void Interpolate_CDF(ref ExceedanceCurve thisCurve, double[,] Imported_CDF) { thisCurve.lowerBound = Imported_CDF[0, 0]; thisCurve.upperBound = Imported_CDF[Imported_CDF.GetUpperBound(0), 0]; int numPts = Imported_CDF.GetUpperBound(0) + 1; double Delta_X = (thisCurve.upperBound - thisCurve.lowerBound) / (thisCurve.distSize - 1); for (int i = 0; i < thisCurve.distSize; i++) { thisCurve.xVals[i] = thisCurve.lowerBound + i * Delta_X; for (int j = 0; j < numPts - 1; j++) { if ((thisCurve.xVals[i] >= Imported_CDF[j, 0]) && (thisCurve.xVals[i] <= Imported_CDF[j + 1, 0])) { // interpolate between points thisCurve.cumulDist[i] = Imported_CDF[j, 1] + (thisCurve.xVals[i] - Imported_CDF[j, 0]) / (Imported_CDF[j + 1, 0] - Imported_CDF[j, 0]) * (Imported_CDF[j + 1, 1] - Imported_CDF[j, 1]); break; } } } }
/// <summary> Imports exeedance curves </summary> public void ImportExceedCurves(Continuum thisInst) { if (thisInst.ofdExceedCurves.ShowDialog() == DialogResult.OK) { string fileName = thisInst.ofdExceedCurves.FileName; StreamReader sr = new StreamReader(fileName); sr.ReadLine(); // Header sr.ReadLine(); // Date sr.ReadLine(); // Blank ExceedanceCurve[] importedCurves = new ExceedanceCurve[0]; int curveCount = 0; while (sr.EndOfStream == false) { try { // Read in exceed curve name string exceedName = sr.ReadLine(); curveCount++; string[] exceedNameStrs = exceedName.Split(','); Array.Resize(ref importedCurves, curveCount); importedCurves[curveCount - 1].exceedStr = exceedNameStrs[0]; // Read in lower bound string lwrBound = sr.ReadLine(); string[] lwrBounds = lwrBound.Split(','); importedCurves[curveCount - 1].lowerBound = Convert.ToDouble(lwrBounds[1]) / 100; // Read in lower bound string uprBound = sr.ReadLine(); string[] uprBounds = uprBound.Split(','); importedCurves[curveCount - 1].upperBound = Convert.ToDouble(uprBounds[1]) / 100; // Read in modes string thisMode = sr.ReadLine(); string[] modeNum = thisMode.Split(',', ' '); int numModes = 0; while (modeNum[0] == "Mode") { numModes++; if (numModes == 1) { importedCurves[curveCount - 1].modes = new Mode_Def[1]; } else { Array.Resize(ref importedCurves[curveCount - 1].modes, numModes); } // Read in mode mean string meanStr = sr.ReadLine(); string[] meanStrs = meanStr.Split(','); importedCurves[curveCount - 1].modes[numModes - 1].mean = Convert.ToSingle(meanStrs[2]) / 100; // Read in mode SD string sdStr = sr.ReadLine(); string[] sdStrs = sdStr.Split(','); importedCurves[curveCount - 1].modes[numModes - 1].SD = Convert.ToSingle(sdStrs[2]) / 100; // Read in mode weight string weightStr = sr.ReadLine(); string[] weightStrs = weightStr.Split(','); importedCurves[curveCount - 1].modes[numModes - 1].weight = Convert.ToSingle(weightStrs[2]) / 100; thisMode = sr.ReadLine(); modeNum = thisMode.Split(',', ' '); } // Read in performance factors (x values) string[] pf = modeNum; // modeNum holds the performance factor array if (numModes == 0) { string allPFs = sr.ReadLine(); pf = allPFs.Split(','); } int distSize = pf.Length - 2; // Minus due to "PF" at the beginning and one empty space at end Array.Resize(ref importedCurves[curveCount - 1].xVals, distSize); Array.Resize(ref importedCurves[curveCount - 1].probDist, distSize); Array.Resize(ref importedCurves[curveCount - 1].cumulDist, distSize); importedCurves[curveCount - 1].distSize = distSize; for (int i = 0; i < distSize; i++) { importedCurves[curveCount - 1].xVals[i] = Convert.ToDouble(pf[i + 1]) / 100; } string allPDFs = sr.ReadLine(); pf = allPDFs.Split(','); // Read in PDFs for (int i = 0; i < distSize; i++) { importedCurves[curveCount - 1].probDist[i] = Convert.ToDouble(pf[i + 1]); } string allCDFs = sr.ReadLine(); pf = allCDFs.Split(','); // Read in CDFs for (int i = 0; i < distSize; i++) { importedCurves[curveCount - 1].cumulDist[i] = Convert.ToDouble(pf[i + 1]); } // Empty line before next sr.ReadLine(); } catch { MessageBox.Show("Error reading in exceedance curves.", "Continuum 3"); sr.Close(); return; } } thisInst.turbineList.exceed.exceedCurves = importedCurves; sr.Close(); } }