/// <summary> /// Генерирование квазистаионарного сигнала /// </summary> /// <returns></returns> public static double[] GetQstSignal(List <HarmonicTemplate> templates, int samplingFrequency) { int size = templates.Select(h => h.Time).Sum() * samplingFrequency; int segmentSize, i = 0; double[] result = new double[size]; double t, dt; dt = SignalUtilities.GetSamplingPeriod(samplingFrequency); foreach (var segment in templates) { segmentSize = (int)segment.Time * samplingFrequency; foreach (var harmonic in segment.Harmonics) { t = 0; for (int j = 0; j < segmentSize; j++) { result[j + i] += harmonic.amplitude * Math.Cos(DigitalSignalsGenerator.DoublePi * harmonic.frequency * t - harmonic.phase); t += dt; } } i += segmentSize; } return(result); }
/// <summary> /// Генерирование гармонического сигнала /// </summary> /// <returns></returns> public static double[] GetHarmonicSignal(List <HarmonicSignal> harmonics, int samplingFrequency, int modelingTime, double manualSamplingPeriod = 0) { int size = modelingTime * samplingFrequency; double[] result = new double[size]; double t, dt; // если период дискретизации введен вручную if (manualSamplingPeriod != 0) { dt = manualSamplingPeriod; } else { dt = SignalUtilities.GetSamplingPeriod(samplingFrequency); } foreach (var harmonic in harmonics) { t = 0; for (int j = 0; j < size; j++) { result[j] += harmonic.amplitude * Math.Cos(DoublePi * harmonic.frequency * t - harmonic.phase); t += dt; } } return(result); }
/// <summary> /// Отрисовка графика спектальной плотности мощности для случайного сигнала /// </summary> private void DrawPowerSpectralDensityGraphic() { try { if (polyHarmonicPoints == null && polyHarmonicPoints.Length == 0) { return; } if (chartSPD.Series != null) { chartSPD.Series.Clear(); } chartSPD.Series.Add("SpectralPowerDensety"); chartSPD.Series["SpectralPowerDensety"].ChartType = SeriesChartType.Line; chartSPD.Series["SpectralPowerDensety"].Color = Color.Crimson; chartSPD.Series["SpectralPowerDensety"].IsVisibleInLegend = false; double[] spdResp = SignalUtilities.SpectralPowerDensity(noizeblePolyHarmonicPoints.ToList()); chartSPD.ChartAreas[0].AxisX.Maximum = (spdResp.Length + spdResp.Length / 10); chartSPD.ChartAreas[0].AxisX.Minimum = 0; chartSPD.ChartAreas[0].AxisY.Minimum = 0; for (int i = 0; i < spdResp.Length; i++) { chartSPD.Series[0].Points.AddXY(i, spdResp[i]); } } catch (Exception ex) { MessageBox.Show($"{ex.Message} [{ex.TargetSite.Name}]"); } }
/// <summary> /// Инициализация генератора сигналов и значений гармоник /// </summary> public void InitHarmonics() { try { totalTime = int.Parse(textBoxTime.Text); totalSamplingFrequency = int.Parse(textBoxFrequency.Text); chartModlingResults.Series.Clear(); var rows = dataGridViewHarmonics.Rows; DataGridViewRow row; double fr, am, ph, maxFr = double.MinValue; if (checkBoxUseNoize.Checked) { maxFr = double.Parse(textBoxNoizeFrequency.Text); } harmonics.Clear(); foreach (var r in rows) { row = r as DataGridViewRow; if (row.Cells[1].Value == null) { break; } fr = Convert.ToDouble(row.Cells[1].Value); am = Convert.ToDouble(row.Cells[2].Value); ph = Convert.ToDouble(row.Cells[3].Value); maxFr = maxFr < fr ? fr : maxFr; harmonics.Add(new DigitalSignalsGenerator.HarmonicSignal(fr, am, ph)); } if (totalSamplingFrequency < maxFr * 2) { MessageBox.Show($"Частота дискретизации должна быть как минимум в 2 раза больше максимальной частоты ({maxFr})", "Ошибка!"); return; } dT = SignalUtilities.GetSamplingPeriod(double.Parse(textBoxFrequency.Text)); textBoxManualPeriod.Text = dT.ToString(); textBoxTimeSteps.Text = (totalTime * totalSamplingFrequency).ToString(); var chart = chartModlingResults.ChartAreas[0]; chart.AxisY.LabelStyle.IsEndLabelVisible = true; } catch (Exception ex) { MessageBox.Show($"{ex.Message} [{ex.TargetSite.Name}]"); } }
/// <summary> /// Моделирование шаблона квазистационарного сигнала /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonDrawQstSignalSegment_Click(object sender, EventArgs e) { try { dT = SignalUtilities.GetSamplingPeriod(double.Parse(textBoxQstDiscFr.Text)); DrawSegment(); } catch (Exception ex) { MessageBox.Show($"{ex.Message} [{ex.TargetSite.Name}]"); } }
/// <summary> /// Отрисовка графиков корреляционной функции для детерминированного и случайного сигналов /// </summary> private void DrawCorrelationGraphics() { try { if (polyHarmonicPoints == null && polyHarmonicPoints.Length == 0) { return; } if (chartСFDetermenistic.Series != null) { chartСFDetermenistic.Series.Clear(); } if (chartСFRandom.Series != null) { chartСFRandom.Series.Clear(); } chartСFDetermenistic.Series.Add("CorrelationFuncRespDetermenistic"); chartСFDetermenistic.Series["CorrelationFuncRespDetermenistic"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; chartСFDetermenistic.Series["CorrelationFuncRespDetermenistic"].Color = Color.Crimson; chartСFDetermenistic.Series["CorrelationFuncRespDetermenistic"].IsVisibleInLegend = false; chartСFRandom.Series.Add("CorrelationFuncRespRandom"); chartСFRandom.Series["CorrelationFuncRespRandom"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; chartСFRandom.Series["CorrelationFuncRespRandom"].Color = Color.Crimson; chartСFRandom.Series["CorrelationFuncRespRandom"].IsVisibleInLegend = false; double[] corrFncRespDet = SignalUtilities.GetAutoCorrelationOfSeries(noizeblePolyHarmonicPoints); double[] corrFncRespRandom = SignalUtilities.GetAutoCorrelationOfSeries(noizePoints); chartСFDetermenistic.ChartAreas[0].AxisX.Maximum = corrFncRespDet.Length; chartСFDetermenistic.ChartAreas[0].AxisX.Minimum = 0; chartСFDetermenistic.ChartAreas[0].AxisY.Maximum = 1; chartСFDetermenistic.ChartAreas[0].AxisY.Minimum = -1; chartСFRandom.ChartAreas[0].AxisX.Maximum = corrFncRespDet.Length; chartСFRandom.ChartAreas[0].AxisX.Minimum = 0; chartСFRandom.ChartAreas[0].AxisY.Maximum = 1; chartСFRandom.ChartAreas[0].AxisY.Minimum = -1; for (int i = 0; i < corrFncRespDet.Length; i++) { chartСFDetermenistic.Series[0].Points.AddXY(i, corrFncRespDet[i]); chartСFRandom.Series[0].Points.AddXY(i, corrFncRespRandom[i]); } } catch (Exception ex) { MessageBox.Show($"{ex.Message} [{ex.TargetSite.Name}]"); } }
/// <summary> /// Вывод характеристик сигналов /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void GetSignalsStats() { try { if (polyHarmonicPoints == null && noizeblePolyHarmonicPoints == null) { return; } chartPower.Series.Clear(); double[] powerPoints = SignalUtilities.GetPower(polyHarmonicPoints); labelAvgPower.Text = SignalUtilities.GetAvgPower(powerPoints).ToString(); labelFullPower.Text = SignalUtilities.GetFullPower(powerPoints).ToString(); labelMaxAmpltd.Text = SignalUtilities.GetMaxAmplitude(polyHarmonicPoints).ToString(); labelMu.Text = SignalUtilities.MathExpectation(noizeblePolyHarmonicPoints).ToString(); labelDis.Text = SignalUtilities.Deviation(noizeblePolyHarmonicPoints).ToString(); labelSigma.Text = SignalUtilities.SquareDeviation(noizeblePolyHarmonicPoints).ToString(); var maxAm = powerPoints.Max(); chartPower.Series.Add("Power"); chartPower.Series["Power"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.SplineArea; chartPower.Series["Power"].Color = Color.MediumSlateBlue; chartPower.Series["Power"].IsVisibleInLegend = false; chartPower.ChartAreas[0].AxisX.Maximum = totalTime; chartPower.ChartAreas[0].AxisX.Minimum = 0; chartPower.ChartAreas[0].AxisY.Interval = 1; chartPower.ChartAreas[0].AxisY.Minimum = 0; chartPower.ChartAreas[0].AxisY.Maximum = maxAm; double x = 0; foreach (var p in powerPoints) { chartPower.Series[0].Points.AddXY(x, p); x += dT; } } catch (Exception ex) { MessageBox.Show($"{ex.Message} [{ex.TargetSite.Name}]"); } }
/// <summary> /// Генерация шума /// </summary> /// <param name="min"></param> /// <param name="max"></param> /// <param name="length"></param> /// <returns></returns> public static double[] GetNoize(double max, int frequency, int time, int samplingFrequency) { if (frequency < 0) { return(null); } int size = time * samplingFrequency; double[] result = new double[size]; double t = 0, dt = SignalUtilities.GetSamplingPeriod(samplingFrequency); var rnd = new Random(); for (int j = 0; j < size; j++) { result[j] += max * Math.Cos(DoublePi * frequency * t - 0); t += dt; } double d; for (int i = 0; i < size; i++) { d = result[i] % 1; if (result[i] > 0) { result[i] = rnd.Next(0, (int)result[i] + 1); } else if (result[i] < 0) { result[i] = rnd.Next((int)result[i], 1); } if (result[i] != 0 || Math.Abs(d) < 0.3) { result[i] += d; } } return(result); }
/// <summary> /// Выполнение сегментации исходного сигнала /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonGetQstSegments_Click(object sender, EventArgs e) { if (qstNoizebleSignalPoints == null || qstNoizebleSignalPoints.Count() == 0) { MessageBox.Show("Выполните зашумление исходного сигнала", "Ошибка!"); return; } Meta.Numerics.Statistics.BivariateSample bevar = new Meta.Numerics.Statistics.BivariateSample(); Dictionary <string, SignalUtilities.SegmentBounds> bounds = new Dictionary <string, SignalUtilities.SegmentBounds>(); int discfrecuency = int.Parse(textBoxQstDiscFr.Text); foreach (var segment in qstSignal) { var segmentPoins = DigitalSignalsGenerator.GetHarmonicSignal(segment.Harmonics, discfrecuency, segment.Time); var segmentBounds = SignalUtilities.GetSegment(qstNoizebleSignalPoints, segmentPoins); bounds.Add(segment.Name, segmentBounds); } DrawSegmentsAttributes(bounds, chartQstSignal); }
/// <summary> /// Отрисовка амплитудно и фазо-частотных графиков для детерменированного синала /// </summary> private void DrawFrequencyResponseGraphics() { try { if (polyHarmonicPoints == null && polyHarmonicPoints.Length == 0) { return; } if (chartAFR.Series != null) { chartAFR.Series.Clear(); } int maxFr = (int)harmonics.Max(h => h.frequency); int maxPh = (int)harmonics.Max(h => Math.Abs(h.phase)); chartAFR.Series.Clear(); chartPFR.Series.Clear(); chartAFR.Series.Add("AmplitudeFrequencyResponse"); chartAFR.Series["AmplitudeFrequencyResponse"].ChartType = SeriesChartType.Column; chartAFR.Series["AmplitudeFrequencyResponse"].Color = Color.Crimson; chartAFR.Series["AmplitudeFrequencyResponse"].IsVisibleInLegend = false; chartPFR.Series.Add("PhaseFrequencyResponse"); chartPFR.Series["PhaseFrequencyResponse"].ChartType = SeriesChartType.Column; chartPFR.Series["PhaseFrequencyResponse"].Color = Color.Crimson; chartPFR.Series["PhaseFrequencyResponse"].IsVisibleInLegend = false; List <double> phsFrResp = SignalUtilities.Phase(polyHarmonicPoints.ToList()); List <double> amplFrResp = SignalUtilities.Amplitude(polyHarmonicPoints.ToList()); chartAFR.ChartAreas[0].AxisX.Maximum = (maxFr + maxFr / 2); chartAFR.ChartAreas[0].AxisX.Minimum = 0; chartAFR.ChartAreas[0].AxisX.Interval = maxFr / 10; chartAFR.ChartAreas[0].AxisY.Interval = 2; chartPFR.ChartAreas[0].AxisX.Maximum = (maxFr + maxFr / 2); chartPFR.ChartAreas[0].AxisX.Minimum = 0; chartPFR.ChartAreas[0].AxisY.Maximum = (maxPh + maxPh / 2); chartPFR.ChartAreas[0].AxisY.Minimum = -(maxPh + maxPh / 2); chartPFR.ChartAreas[0].AxisX.Interval = maxFr / 10; chartPFR.ChartAreas[0].AxisY.Interval = 1; for (int i = 0; i < maxFr + maxFr / 2; i++) { chartAFR.Series["AmplitudeFrequencyResponse"].Points.AddXY(i, amplFrResp[i] * 2); //chartAFR.Series["AmplitudeFrequencyResponse"].Points.AddXY(-i, amplFrResp[i] * 2); } for (int i = 0; i < maxFr + maxFr / 2; i++) { chartPFR.Series["PhaseFrequencyResponse"].Points.AddXY(i, phsFrResp[i]); //chartPFR.Series["PhaseFrequencyResponse"].Points.AddXY(-i, -phsFrResp[i] * 2); } } catch (Exception ex) { MessageBox.Show($"{ex.Message} [{ex.TargetSite.Name}]"); } }