Imports System.Collections Imports System.Collections.Generic Imports System.Linq Imports System.IO Public Class ControlChart Friend myData As New List(Of ControlChart.CalPoint) Public Sub New() End Sub Public Sub ExportData(ByVal FilePath As String) Try Dim Data As String Data = "Date" & vbTab & "Measured Value" & vbTab & "Measured Unc" & vbTab & "Predicted Value" & vbTab & "Predicted Unc" & vbTab & "Upper Bound" & vbTab & "Lower Bound" & vbCrLf 'Add The DataPoints For Each item In Me.myData Data = Data & item.vDate & vbTab & item.CalValue & vbTab & item.Unc & vbTab & PredictedValue(item.vDate) & vbTab & PredictedUnc(item.vDate) & vbTab & PredictedValue(item.vDate) + (2 * PredictedUnc(item.vDate)) & vbTab & PredictedValue(item.vDate) - (2 * PredictedUnc(item.vDate)) & vbCrLf Next File.WriteAllText(FilePath, Data) Catch ex As Exception ' ErrorLog.Log(ex) Throw ex End Try End Sub Public Sub AddCalPoint(ByVal CalPoint As CalPoint) Try myData.Add(CalPoint) Catch ex As Exception 'ErrorLog.Log(ex) End Try End Sub Public Function CalcSlope() As Double Try Dim Data As IEnumerable(Of CalPoint) = Me.myData Dim averageX As Double = Data.Average(Function(d) d.Days) Dim averageY As Double = Data.Average(Function(d) d.CalValue) Return Data.Sum(Function(d) (d.Days - averageX) * (d.CalValue - averageY)) / Data.Sum(Function(d) Math.Pow(d.Days - averageX, 2)) Catch ex As Exception 'ErrorLog.Log(ex) Return "39e39" End Try End Function Public Function CalcIntercept() As Double Try Dim Data As IEnumerable(Of CalPoint) = Me.myData Dim slope As Double = CalcSlope() Return Data.Average(Function(d) d.CalValue) - slope * Data.Average(Function(d) d.Days) Catch ex As Exception 'ErrorLog.Log(ex) Return "39e39" End Try End Function Public Function PredictedValue(ByVal dDate As Date) As Double Try Dim Data As IEnumerable(Of CalPoint) = Me.myData Dim RefDate As Date = New Date(1900, 1, 1) Dim days As Double = dDate.Subtract(RefDate).Days Return days * CalcSlope() + CalcIntercept() Catch ex As Exception 'ErrorLog.Log(ex) Return "39e39" End Try End Function Public Function PredictedUnc(ByVal dDate As Date) As Double Try Dim Data As IEnumerable(Of CalPoint) = Me.myData Dim LastCal As Date = Data.Max(Function(d) d.vDate) Dim FirstCal As Date = Data.Min(Function(d) d.vDate) Dim StartDays As Double = Data.Min(Function(d) d.Days) Dim SumSqrVal As Double Dim SumSqrDay As Double Dim SumDay As Double 'Get all the Values For Each DataPoint In Me.myData SumSqrVal = SumSqrVal + (DataPoint.CalValue - PredictedValue(DataPoint.vDate)) ^ 2 SumDay = SumDay + (DataPoint.Days - StartDays) SumSqrDay = SumSqrDay + ((DataPoint.Days - StartDays) ^ 2) Next Dim StdErr = Math.Sqrt(SumSqrVal) / 2 Dim Sxx = SumSqrDay - ((SumDay ^ 2) / (Me.myData.Count)) Dim MeanCalTime = SumDay / Me.myData.Count Dim DaysFromLastcal = dDate.Subtract(LastCal).Days Dim CalDays As Double = LastCal.Subtract(FirstCal).Days Dim Value As Double = StdErr * (Math.Sqrt(1 + (1 / (Me.myData.Count)) + ((((CalDays + DaysFromLastcal) - MeanCalTime) ^ 2) / Sxx))) Return Value Catch ex As Exception 'ErrorLog.Log(ex) Return "39e39" End Try End Function Public Function PredictedPoint(ByVal dDate As Date) As CalcPoint Try Dim Data As IEnumerable(Of CalPoint) = Me.myData Dim RefDate As Date = New Date(1900, 1, 1) Dim days As Double = dDate.Subtract(RefDate).Days Dim LastCal As Date = Data.Max(Function(d) d.vDate) Dim FirstCal As Date = Data.Min(Function(d) d.vDate) Dim StartDays As Double = Data.Min(Function(d) d.Days) Dim SumSqrVal As Double Dim SumSqrDay As Double Dim SumDay As Double 'Get all the Values For Each DataPoint In Me.myData SumSqrVal = SumSqrVal + (DataPoint.CalValue - PredictedValue(DataPoint.vDate)) ^ 2 SumDay = SumDay + (DataPoint.Days - StartDays) SumSqrDay = SumSqrDay + ((DataPoint.Days - StartDays) ^ 2) Next Dim StdErr = Math.Sqrt(SumSqrVal) / 2 Dim Sxx = SumSqrDay - ((SumDay ^ 2) / (Me.myData.Count)) Dim MeanCalTime = SumDay / Me.myData.Count Dim DaysFromLastcal = dDate.Subtract(LastCal).Days Dim CalDays As Double = LastCal.Subtract(FirstCal).Days Dim Unc As Double = StdErr * (Math.Sqrt(1 + (1 / (Me.myData.Count)) + ((((CalDays + DaysFromLastcal) - MeanCalTime) ^ 2) / Sxx))) Dim Value As Double = days * CalcSlope() + CalcIntercept() Return CalcPoint.NewDataPoint(Value, Unc) Catch ex As Exception 'ErrorLog.Log(ex) Return CalcPoint.NewDataPoint(Val("39e39"), Val("39e39")) End Try End Function Public Class CalPoint Public Property vDate As Date Public Property Days As Double Public Property CalValue As Double Public Property Unc As Double Public Sub New() End Sub Shared Function NewDataPoint(ByVal vDate As Date, ByVal Value As Double, ByVal Unc As Double) As CalPoint Dim NewData As New CalPoint Dim RefDate As Date = New Date(1900, 1, 1) Dim days As Double = vDate.Subtract(RefDate).Days NewData.vDate = vDate NewData.Days = days NewData.CalValue = Value NewData.Unc = Unc Return NewData End Function End Class Public Class CalcPoint Public Property CalValue As Double Public Property Unc As Double Shared Function NewDataPoint(ByVal Value As Double, ByVal Unc As Double) As CalcPoint Dim NewData As New CalcPoint NewData.CalValue = Value NewData.Unc = Unc Return NewData End Function End Class End Class