/// <summary> /// Estimates the Hurst Exponent, considering the specified hypothetical next value of the already stored time series. /// </summary> /// <remarks> /// Operation does not change the instance data. /// </remarks> /// <returns>The resulting linear fit object.</returns> public LinearFit ComputeNext(double simValue) { //Affect the simulated next value into the existing averages double[] avgValues = new double[_avgCollection.Count]; Parallel.For(0, _subIntervalLengthCollection.Count, _subIntervalIdx => { int intervalLength = _subIntervalLengthCollection[_subIntervalIdx]; RescaledRange intervalRescaledRange = new RescaledRange(intervalLength); for (int valueIdx = (_valueCollection.Count - intervalLength) + 1; valueIdx < _valueCollection.Count; valueIdx++) { intervalRescaledRange.AddValue(_valueCollection[valueIdx]); } intervalRescaledRange.AddValue(simValue); avgValues[_subIntervalIdx] = _avgCollection[_subIntervalIdx].SimulateNext(intervalRescaledRange.Compute()); }); //Add updated existing points LinearFit linFit = new LinearFit(); for (int i = 0; i < _avgCollection.Count; i++) { double x = Math.Log(_subIntervalLengthCollection[i]); double avg = avgValues[i]; double y = 0; if (avg != 0) { y = Math.Log(avg); } linFit.AddSamplePoint(x, y); } //Return return(linFit); }
public SensitivityAnalysis(GrowthCurve GD, MatrixArrayPlot.ArrayPlot AP) { this.GD = GD; if (GD.ExpModelFitted && GD.ODValues.Max() > .08) { double current = GD.GrowthRate.GrowthRate; double MaxAllowed = 1.2 * current; double MinAllowed = .8 * current; double BaseGrowthRate = GD.ExpFit.GrowthRate; Measurements = (GD.TimeValues_As_Double.Zip(GD.ODValues, (time, od) => new Measurement() { ODValue = od, Time = time })).ToList(); TrimCurve(); double[,] Array = new double[Measurements.Count, Measurements.Count]; double lastValue = Double.NaN; for (int i = 0; i < Measurements.Count; i++) { Array[i, i] = Double.NaN; for (int j = (i + 1); j < Measurements.Count; j++) { double value = lastValue; var Fit = from b in Enumerable.Range(i, (j - i + 1)) select Measurements[b]; double[] times = (from b in Fit select b.Time).ToArray(); double[] ods = (from b in Fit select b.ODValue).ToArray(); int count = times.Length; value = Double.NaN; double[] LogValues = ods.Select(z => Math.Log(z)).ToArray(); if (count > 2) { ExponentialFit EF = new ExponentialFit(times, ods); //LinearFit EF = new LinearFit(times, LogValues); value = EF.GrowthRate; AllFitValues.Add(value); } if (count == 2) { AllFitValues.Add(value); LinearFit LF = new LinearFit(times, LogValues); value = LF.Slope; } if (value <MinAllowed | value> MaxAllowed) { value = Double.NaN; } Array[i, j] = value; Array[j, i] = value; lastValue = value; } } string[] rowNames = (from x in Measurements select x.ODValue.ToString("g2")).ToArray(); string[] colNames = Enumerable.Range(0, rowNames.Length).Select(x => x % 2 == 0?rowNames[x]:"").ToArray(); AP.SetMatrixForPlotting(Array, rowNames, colNames); } else { //throw new Exception("Your maximum OD is below 0.2 or your curve has not been fit. Obtain higher quality data before fitting"); } }
protected internal override double CalculateGrowthRate(double[] times, double[] ods) { double value = Double.NaN; int count = times.Length; if (count >= 2) { double[] LogValues = ods.Select(z => Math.Log(z)).ToArray(); LinearFit LF = new LinearFit(times, LogValues); value = LF.Slope; } return(value); }
/// <summary> /// Estimates the Hurst Exponent. /// </summary> /// <returns>The resulting linear fit object</returns> public LinearFit Compute() { LinearFit linFit = new LinearFit(); for (int i = 0; i < _avgCollection.Count; i++) { double x = Math.Log(_subIntervalLengthCollection[i]); double avg = _avgCollection[i].Result; double y = 0; if (avg != 0) { y = Math.Log(avg); } linFit.AddSamplePoint(x, y); } return(linFit); }
/// <summary> /// Computes Hurst exponent estimation for next hypothetical value in time series. /// Function does not change the instance, it is a simulation only. /// </summary> /// <param name="simValue">Next time series value</param> public double ComputeNext(double simValue) { //Affect new value to existing averages double[] avgValues = new double[_avgCollection.Count]; Parallel.For(0, _subIntervalLengthCollection.Count, _subIntervalIdx => { int intervalLength = _subIntervalLengthCollection[_subIntervalIdx]; RescalledRange intervalRescalledRange = new RescalledRange(intervalLength); for (int valueIdx = (_valueCollection.Count - intervalLength) + 1; valueIdx < _valueCollection.Count; valueIdx++) { intervalRescalledRange.AddValue(_valueCollection[valueIdx]); } intervalRescalledRange.AddValue(simValue); avgValues[_subIntervalIdx] = _avgCollection[_subIntervalIdx].SimulateNext(intervalRescalledRange.Compute()); }); //Add updated existing points LinearFit linFit = new LinearFit(); for (int i = 0; i < _avgCollection.Count; i++) { double x = Math.Log(_subIntervalLengthCollection[i]); double avg = avgValues[i]; double y = 0; if (avg != 0) { y = Math.Log(avg); } linFit.AddSamplePoint(x, y); } //Add new point for sub-interval length = (_timeSeries.Length + 1) RescalledRange fullRescalledRange = new RescalledRange(_valueCollection.Count + 1); foreach (double value in _valueCollection) { fullRescalledRange.AddValue(value); } fullRescalledRange.AddValue(simValue); double fullRangeAvg = fullRescalledRange.Compute(); linFit.AddSamplePoint(Math.Log(_valueCollection.Count + 1), fullRangeAvg == 0 ? 0 : Math.Log(fullRangeAvg)); //Return return(linFit.A); }
protected internal virtual double CalculateGrowthRate(double[] times, double[] ods) { double value = Double.NaN; int count = times.Length; if (count > 2) { ExponentialFit EF = new ExponentialFit(times, ods); //LinearFit EF = new LinearFit(times, LogValues); value = EF.GrowthRate; } if (count == 2) { double[] LogValues = ods.Select(z => Math.Log(z)).ToArray(); LinearFit LF = new LinearFit(times, LogValues); value = LF.Slope; } return(value); }
//获取某元素波长的方程,前置约束为调用者已经完成所有所有标样的读取 //函数返回方程的同时,将返回方程进行计算时用到的标样点 public static LinearFit.LfReValue get_equation(spec_metadata spec_obj, int element_index, ref double[] concentration, ref double[] standards_integration_average_strenth, int bs) { double[] wave_all = spec_obj.read_wave_all; double[] env = spec_obj.env_spec; standard[] standards = spec_obj.standards; int standard_cnt = spec_obj.standard_cnt; select_element element = spec_obj.elements[element_index]; double[,,] spec_standard = spec_obj.read_standard_spec; //提取该元素列标样数据,得到方程 standards_integration_average_strenth = new double[standard_cnt]; //标样平均的积分平均强度 for (int i = 0; i < standard_cnt; i++) //每个标样 { double standard_element_interval_average = 0.0; //平均的平均 //如果点击的为标样,在计算方程的循环中直接获取多次积分平均值 double[] strenght_oneshot = get_oneshot_all_strength(spec_obj, i, element_index); for (int t = 0; t < standards[i].average_times; t++) { standard_element_interval_average += strenght_oneshot[t]; } standards_integration_average_strenth[i] = standard_element_interval_average / standards[i].average_times; } concentration = new double[standard_cnt]; //浓度 for (int j = 0; j < standard_cnt; j++) { concentration[j] = standards[j].standard_ppm[element.sequece_index - 1]; } LinearFit.LfReValue equation; //过空白或不过空白读取 if (bs == 0) { equation = LinearFit.linearFitFunc(concentration, standards_integration_average_strenth, standard_cnt); } else { equation = LinearFit.linearFitFunc_blank(concentration, standards_integration_average_strenth, standard_cnt); } return(equation); }
//根据实际测量数据spec_standard和spec_sample,选择的各元素,标样,样本,计算出将要显示的表格数据 //返回值standard_val和sample_val分别为计算后表格要显示的标样/样本的浓度或强度数据 private static void fill_datagrid_data(spec_metadata spec_obj, ref double[,] standard_val, ref double[,] sample_val, int bs) { select_element[] elements = spec_obj.elements; standard[] standards = spec_obj.standards; sample[] samples = spec_obj.samples; double[] wave_all = spec_obj.read_wave_all; double[] env = spec_obj.env_spec; double[,,] spec_standard = spec_obj.read_standard_spec; double[,,] spec_sample = spec_obj.read_sample_spec; int standard_cnt = spec_obj.standard_cnt; int sample_cnt = spec_obj.sample_cnt; int element_cnt = spec_obj.element_cnt; int pixel_cnt = spec_obj.read_wave_all.Length; double[,] standards_integration_average_strenth = new double[standard_cnt, element_cnt]; double[,] samples_integration_average_strenth = new double[sample_cnt, element_cnt]; //标样平均的积分平均强度 for (int i = 0; i < standard_cnt; i++) //每个标样 { if (!standards[i].is_readed) { continue; } for (int t = 0; t < standards[i].average_times; t++) { double[] spec_temp_all = new double[pixel_cnt]; for (int k = 0; k < pixel_cnt; k++) { spec_temp_all[k] = spec_standard[i, t, k]; } for (int j = 0; j < element_cnt; j++) //每一个元素 { standards_integration_average_strenth[i, j] += data_util.get_integration_average(wave_all, spec_temp_all, env, elements[j].interval_start, elements[j].interval_end); } } for (int j = 0; j < element_cnt; j++) { standards_integration_average_strenth[i, j] /= standards[i].average_times; } } //样本的平均积分平均强度 for (int i = 0; i < sample_cnt; i++) //每个标样 { if (!samples[i].is_read) { continue; } for (int t = 0; t < samples[i].average_times; t++) { double[] spec_temp_all = new double[pixel_cnt]; for (int k = 0; k < pixel_cnt; k++) { spec_temp_all[k] = spec_sample[i, t, k]; } for (int j = 0; j < element_cnt; j++) //每一个元素 { samples_integration_average_strenth[i, j] += data_util.get_integration_average(wave_all, spec_temp_all, env, elements[j].interval_start, elements[j].interval_end); } } for (int j = 0; j < element_cnt; j++) { samples_integration_average_strenth[i, j] /= samples[i].average_times; } } //显示强度,直接提取spec数组数据,根据元素(波长)积分区间来得到计算值 if (datagrid_control.show_strenth) { standard_val = standards_integration_average_strenth; sample_val = samples_integration_average_strenth; } // 当已经读取所有标样,则计算线性拟合方程,计算样本浓度 else { //所有标样都已经读取完,才需要计算样本浓度 bool is_need_calculate = true; for (int i = 0; i < standard_cnt; i++) { if (!standards[i].is_readed) { is_need_calculate = false; //标样没有全部读取完,则不需要计算方程 } for (int j = 0; j < element_cnt; j++) { standard_val[i, j] = standards[i].standard_ppm[j]; } } //样本需要根据线性方程进行计算 if (is_need_calculate) { // 根据标样浓度和对应强度计算 for (int i = 0; i < element_cnt; i++) { double[] concentration = new double[standard_cnt]; //浓度 double[] strenth = new double[standard_cnt]; for (int j = 0; j < standard_cnt; j++) { concentration[j] = standards[j].standard_ppm[i]; strenth[j] = standards_integration_average_strenth[j, i]; } LinearFit.LfReValue equation; if (bs == 0) { equation = LinearFit.linearFitFunc(concentration, strenth, standard_cnt); } else { equation = LinearFit.linearFitFunc_blank(concentration, strenth, standard_cnt); } //根据方程进行样本浓度推算 for (int j = 0; j < sample_cnt; j++) { if (!samples[j].is_read) { continue; } sample_val[j, i] = (samples_integration_average_strenth[j, i] - equation.getA()) / equation.getB(); } } } else //不需要计算时设置为0 { for (int i = 0; i < sample_cnt; i++) { for (int j = 0; j < element_cnt; j++) { sample_val[i, j] = 0; } } } } }