Skip to content

Commit 5b7d941

Browse files
committed
xml-комментарии
1 parent 7848708 commit 5b7d941

18 files changed

Lines changed: 517 additions & 275 deletions

.github/copilot-instructions.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Всегда пиши комментарии в коде на русском языке.
33
Комментарии к классам, структурам делегатам и перечислениям, а также к их членам всегда пиши в системном виде.
44
При написании комментариев (ели они короткие) в коде предпочитай размещение комментария в конце той же строке, что и сам комментируемый код.
5+
Если ты пишешь xml-комментарий, и он состоит из одного приложения, то тебе нужно написать весь комментарий в одной строке включая открывающий и закрывающий теги.
6+
Обращай особое внимание на конструкторы классов по умолчанию, а также на их параметры - не пропускай их при генерации xml-комментариев.
57
Старайся избегать тривиальных комментариев.
68
При герерации кода старайся минимизировать количество фигурных скобок.
79
При генерации кода используй самые современные виды синтаксических конструкций языка.
@@ -12,4 +14,4 @@
1214
Ппредпочитай английский язык при именовании переменных, методов, классов и прочих сущностей.
1315
При инициализации массивов, списков и словарей используй выражения инициализации массивов.
1416
При объявлении переменных предпочитай использовать ключевое слово var.
15-
При написании системных комментариев старайся писать их компактно в одну строку, если длина текста небольшая.
17+
При написании системных комментариев старайся писать их компактно в одну строку, если длина текста небольшая.

MathCore.DSP.sln.DotSettings

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@
3535
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0422_044C_044E_043A_0438/@EntryIndexedValue">True</s:Boolean>
3636
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0430_043D_0430_043B_043E_0433_0432_043E_0433_043E/@EntryIndexedValue">True</s:Boolean>
3737
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0438_0441_043A_0440_0435_0442/@EntryIndexedValue">True</s:Boolean>
38-
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043A_0435_0448_0438_0440_043E_0432_0430_043D_0438_0435_043C/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
38+
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043A_0435_0448_0438_0440_043E_0432_0430_043D_0438_0435_043C/@EntryIndexedValue">True</s:Boolean>
39+
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043F_0435_0440_0435_0447_0441_0438_0442_044B_0432_0430_0435_043C/@EntryIndexedValue">True</s:Boolean>
40+
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043F_043E_043B_043E_0441_043E_0437_0430_0433_0440_0430_0436_0434_0430_044E_0449_0435_0433_043E/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

MathCore.DSP/Filters/AnalogBasedFilter.cs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
namespace MathCore.DSP.Filters;
88

99
/// <summary>Цифровой фильтр на основе аналогового прототипа</summary>
10-
//[KnownType(typeof(BesselFilter))] // Наихудшее аппроксимация прямоугольной АЧХ (близка по форме к гаусовой кривой), но наилучшая форма переходной хар-ки
10+
//[KnownType(typeof(BesselFilter))] // Наихудшая аппроксимация прямоугольной АЧХ (близка по форме к гауссовой кривой), но наилучшая форма переходной хар-ки
1111
[KnownType(typeof(ButterworthFilter))] // Промежуточные качества по прямоугольности АЧХ и переходной хар-ке
1212
[KnownType(typeof(ChebyshevFilter))] // АЧХ наиболее приближена к прямоугольной - наибольшие пульсации в переходной хор-ке
1313
[KnownType(typeof(EllipticFilter))] // Максимальная крутизна АЧХ
1414
public abstract class AnalogBasedFilter : IIR
1515
{
1616
//https://ru.dsplib.org/content/filter_low2low/filter_low2low.html
17+
/// <summary>Класс преобразований нулей и полюсов аналоговых прототипов</summary>
1718
public static class Transform
1819
{
1920
/// <summary>Преобразование нулей/полюсов фильтра ФНЧ-ФНЧ</summary>
@@ -28,9 +29,13 @@ public static class Transform
2829
/// <returns>Нули/полюса нового фильтра ФВЧ</returns>
2930
public static IEnumerable<Complex> ToHigh(IEnumerable<Complex> Z, double wp) => Z.Select(z => z * wp);
3031

32+
/// <summary>Установить значения новых полюсов/нулей</summary>
33+
/// <param name="p">Исходное значение</param>
34+
/// <param name="D">Смещение</param>
35+
/// <param name="p1">Первое значение</param>
36+
/// <param name="p2">Второе значение</param>
3137
private static void Set(in Complex p, in Complex D, out Complex p1, out Complex p2) => (p1, p2) = (p + D, p - D);
3238

33-
3439
/// <summary>Преобразование нулей/полюсов фильтра ФНЧ-ППФ</summary>
3540
/// <param name="Poles">Полюса прототипа (нормированного ФНЧ)</param>
3641
/// <param name="Zeros">Нули прототипа (нормированного ФНЧ)</param>
@@ -49,7 +54,7 @@ public static (Complex[] Poles, Complex[] Zeros) ToBandPass(
4954
if (Poles.Length == 0) throw new ArgumentException("Размер вектора полюсов должен быть больше 0", nameof(Poles));
5055
if (Zeros.Length > Poles.Length) throw new ArgumentException("Число нулей не должна быть больше числа полюсов", nameof(Zeros));
5156

52-
var (wpl, wph) = (pi2 * fpl, pi2 * fph);
57+
var (wpl, wph) = (pi2 * fpl, pi2 * fph);
5358
var (dw05, wc2) = ((wph - wph) / 2, wpl * wph);
5459

5560
// На каждый исходный полюс формируется пара новых полюсов
@@ -98,7 +103,7 @@ public static (Complex[] Poles, Complex[] Zeros) ToBandStop(
98103
if (count_p == 0) throw new ArgumentException("Размер вектора полюсов должен быть больше 0", nameof(Poles));
99104
if (count_0 > count_p) throw new ArgumentException("Число нулей не должна быть больше числа полюсов", nameof(Zeros));
100105

101-
var (wpl, wph) = (pi2 * fpl, pi2 * fph);
106+
var (wpl, wph) = (pi2 * fpl, pi2 * fph);
102107
var (dw05, wc2) = ((wph - wph) / 2, wpl * wph);
103108

104109
// На каждый исходный полюс формируется пара новых полюсов
@@ -236,6 +241,12 @@ public Specification(double dt, double fp, double fs, double Gp, double Gs)
236241
(Wp, Ws) = (pi2 * Fp, pi2 * Fs);
237242
}
238243

244+
/// <summary>Деконструктор спецификации фильтра</summary>
245+
/// <param name="dt">Период дискретизации</param>
246+
/// <param name="fp">Граничная частота полосы пропускания</param>
247+
/// <param name="fs">Граничная частота полосы заграждения</param>
248+
/// <param name="Gp">Коэффициент передачи в полосе пропускания</param>
249+
/// <param name="Gs">Коэффициент передачи в полосе заграждения</param>
239250
public void Deconstruct(out double dt, out double fp, out double fs, out double Gp, out double Gs) =>
240251
(dt, fp, fs, Gp, Gs) = (this.dt, this.fp, this.fs, this.Gp, this.Gs);
241252
}
@@ -276,10 +287,12 @@ public void Deconstruct(out double dt, out double fp, out double fs, out double
276287
/// <param name="Spec">Спецификация фильтра</param>
277288
protected AnalogBasedFilter(double[] B, double[] A, Specification Spec) : base(B, A) => (dt, fp, fs, Gp, Gs) = Spec;
278289

290+
/// <inheritdoc/>
279291
public override Complex FrequencyResponse(double f) => base.FrequencyResponse(f / fd);
280292

293+
/// <inheritdoc/>
281294
public override Complex FrequencyResponse(double f, double dt) => base.FrequencyResponse(f * dt);
282-
295+
283296
/// <summary>Метод преобразования нулей и полюсов нормированного ФНЧ в нули и полюса ППФ</summary>
284297
/// <param name="Normed">Нормированные нули и полюса ФНЧ</param>
285298
/// <param name="fmin">Нижняя частота среза</param>
@@ -332,18 +345,34 @@ public static IEnumerable<Complex> TransformToBandStopW(IEnumerable<Complex> Nor
332345
}
333346
}
334347

348+
/// <summary>Преобразование нулей/полюсов нормированного ФНЧ в нули/полюса ФНЧ с другой частотой среза</summary>
349+
/// <param name="Normed">Нормированные нули/полюса ФНЧ</param>
350+
/// <param name="fp">Новая частота среза</param>
351+
/// <returns>Нули/полюса нового ФНЧ</returns>
335352
public static IEnumerable<Complex> TransformToLowPass(IEnumerable<Complex> Normed, double fp) =>
336353
TransformToLowPassW(Normed, pi2 * fp);
337354

355+
/// <summary>Преобразование нулей/полюсов нормированного ФНЧ в нули/полюса ФНЧ с другой частотой среза (в циклических частотах)</summary>
356+
/// <param name="Normed">Нормированные нули/полюса ФНЧ</param>
357+
/// <param name="wp">Новая циклическая частота среза</param>
358+
/// <returns>Нули/полюса нового ФНЧ</returns>
338359
public static IEnumerable<Complex> TransformToLowPassW(IEnumerable<Complex> Normed, double wp)
339360
{
340361
foreach (var p in Normed)
341362
yield return wp * p;
342363
}
343364

344-
public static IEnumerable<Complex> TransformToHighPass(IEnumerable<Complex> Normed, double fp) =>
365+
/// <summary>Преобразование нулей/полюсов нормированного ФНЧ в нули/полюса ФВЧ с другой частотой среза</summary>
366+
/// <param name="Normed">Нормированные нули/полюса ФНЧ</param>
367+
/// <param name="fp">Новая частота среза</param>
368+
/// <returns>Нули/полюса нового ФВЧ</returns>
369+
public static IEnumerable<Complex> TransformToHighPass(IEnumerable<Complex> Normed, double fp) =>
345370
TransformToHighPassW(Normed, pi2 * fp);
346371

372+
/// <summary>Преобразование нулей/полюсов нормированного ФНЧ в нули/полюса ФВЧ с другой частотой среза (в циклических частотах)</summary>
373+
/// <param name="Normed">Нормированные нули/полюса ФНЧ</param>
374+
/// <param name="wp">Новая циклическая частота среза</param>
375+
/// <returns>Нули/полюса нового ФВЧ</returns>
347376
public static IEnumerable<Complex> TransformToHighPassW(IEnumerable<Complex> Normed, double wp)
348377
{
349378
foreach (var p in Normed)

MathCore.DSP/Filters/ButterworthBandPass.cs

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System.Diagnostics;
22

3+
using MathCore.Extensions;
4+
35
using static System.Math;
46

57
using static MathCore.Consts;
@@ -17,87 +19,85 @@ private static void CheckFrequencies(double dt, double fsl, double fpl, double f
1719
{
1820
if (dt <= 0)
1921
throw new InvalidOperationException($"Период дискретизации dt={dt} не может быть меньше, либо равен нулю")
20-
{
21-
Data =
22-
{
23-
{ nameof(dt), dt },
24-
{ "fd", 1/dt },
25-
{ nameof(fsl), fsl },
26-
{ nameof(fpl), fpl },
27-
{ nameof(fph), fph },
28-
{ nameof(fsh), fsh },
29-
}
30-
};
22+
.WithData(nameof(dt), dt)
23+
.WithData("fd", 1 / dt)
24+
.WithData(nameof(fsl), fsl)
25+
.WithData(nameof(fpl), fpl)
26+
.WithData(nameof(fph), fph)
27+
.WithData(nameof(fsh), fsh);
3128

3229
if (1 / dt == 0)
3330
throw new InvalidOperationException("Частота дискретизации не может быть равна нулю")
34-
{
35-
Data =
36-
{
37-
{ nameof(dt), dt },
38-
{ "fd", 1/dt },
39-
{ nameof(fsl), fsl },
40-
{ nameof(fpl), fpl },
41-
{ nameof(fph), fph },
42-
{ nameof(fsh), fsh },
43-
}
44-
};
31+
.WithData(nameof(dt), dt)
32+
.WithData("fd", 1 / dt)
33+
.WithData(nameof(fsl), fsl)
34+
.WithData(nameof(fpl), fpl)
35+
.WithData(nameof(fph), fph)
36+
.WithData(nameof(fsh), fsh);
4537

4638
if (fsl >= fpl)
47-
throw new InvalidOperationException($"Нижняя частота среза fsl должна быть ниже нижней частоты пропускания fpl\r\n dt={dt}\r\n fsl={fsl}\r\n fpl={fpl}\r\n fph={fph}\r\n fsh={fsh}")
48-
{
49-
Data =
50-
{
51-
{ nameof(dt), dt },
52-
{ "fd", 1/dt },
53-
{ nameof(fsl), fsl },
54-
{ nameof(fpl), fpl },
55-
{ nameof(fph), fph },
56-
{ nameof(fsh), fsh },
57-
}
58-
};
39+
throw new InvalidOperationException($"""
40+
Нижняя частота среза fsl должна быть ниже нижней частоты пропускания fpl
41+
dt={dt}
42+
fsl={fsl}
43+
fpl={fpl}
44+
fph={fph}
45+
fsh={fsh}
46+
""")
47+
.WithData(nameof(dt), dt)
48+
.WithData("fd", 1 / dt)
49+
.WithData(nameof(fsl), fsl)
50+
.WithData(nameof(fpl), fpl)
51+
.WithData(nameof(fph), fph)
52+
.WithData(nameof(fsh), fsh);
5953

6054
if (fpl >= fph)
61-
throw new InvalidOperationException($"Нижняя частота пропускания fpl должна быть ниже верхней частоты пропускания fph\r\n dt={dt}\r\n fsl={fsl}\r\n fpl={fpl}\r\n fph={fph}\r\n fsh={fsh}")
62-
{
63-
Data =
64-
{
65-
{ nameof(dt), dt },
66-
{ "fd", 1/dt },
67-
{ nameof(fsl), fsl },
68-
{ nameof(fpl), fpl },
69-
{ nameof(fph), fph },
70-
{ nameof(fsh), fsh },
71-
}
72-
};
55+
throw new InvalidOperationException($"""
56+
Нижняя частота пропускания fpl должна быть ниже верхней частоты пропускания fph
57+
dt={dt}
58+
fsl={fsl}
59+
fpl={fpl}
60+
fph={fph}
61+
fsh={fsh}
62+
""")
63+
.WithData(nameof(dt), dt)
64+
.WithData("fd", 1 / dt)
65+
.WithData(nameof(fsl), fsl)
66+
.WithData(nameof(fpl), fpl)
67+
.WithData(nameof(fph), fph)
68+
.WithData(nameof(fsh), fsh);
7369

7470
if (fph >= fsh)
75-
throw new InvalidOperationException($"Верхняя частота пропускания fph должна быть ниже верхней частоты среза fsh\r\n dt={dt}\r\n fsl={fsl}\r\n fpl={fpl}\r\n fph={fph}\r\n fsh={fsh}")
76-
{
77-
Data =
78-
{
79-
{ nameof(dt), dt },
80-
{ "fd", 1/dt },
81-
{ nameof(fsl), fsl },
82-
{ nameof(fpl), fpl },
83-
{ nameof(fph), fph },
84-
{ nameof(fsh), fsh },
85-
}
86-
};
71+
throw new InvalidOperationException($"""
72+
Верхняя частота пропускания fph должна быть ниже верхней частоты среза fsh
73+
dt={dt}
74+
fsl={fsl}
75+
fpl={fpl}
76+
fph={fph}
77+
fsh={fsh}
78+
""")
79+
.WithData(nameof(dt), dt)
80+
.WithData("fd", 1 / dt)
81+
.WithData(nameof(fsl), fsl)
82+
.WithData(nameof(fpl), fpl)
83+
.WithData(nameof(fph), fph)
84+
.WithData(nameof(fsh), fsh);
8785

8886
if (fsh >= 1 / dt / 2)
89-
throw new InvalidOperationException($"Верхняя частота среза fsh должна быть ниже половины частоты дискретизации fd={1 / dt} (1 / (dt={dt}))\r\n dt={dt}\r\n fsl={fsl}\r\n fpl={fpl}\r\n fph={fph}\r\n fsh={fsh}")
90-
{
91-
Data =
92-
{
93-
{ nameof(dt), dt },
94-
{ "fd", 1/dt },
95-
{ nameof(fsl), fsl },
96-
{ nameof(fpl), fpl },
97-
{ nameof(fph), fph },
98-
{ nameof(fsh), fsh },
99-
}
100-
};
87+
throw new InvalidOperationException($"""
88+
Верхняя частота среза fsh должна быть ниже половины частоты дискретизации fd={1 / dt} (1 / (dt={dt}))
89+
dt={dt}
90+
fsl={fsl}
91+
fpl={fpl}
92+
fph={fph}
93+
fsh={fsh}
94+
""")
95+
.WithData(nameof(dt), dt)
96+
.WithData("fd", 1 / dt)
97+
.WithData(nameof(fsl), fsl)
98+
.WithData(nameof(fpl), fpl)
99+
.WithData(nameof(fph), fph)
100+
.WithData(nameof(fsh), fsh);
101101
}
102102

103103
/// <summary>Формирование спецификации фильтра</summary>
@@ -138,10 +138,10 @@ private static Specification GetSpecification(
138138
var dW = Wph - Wpl;
139139

140140
// Выбор опорной частоты
141-
// Если Wc / Wsh > Wsl
142-
// то есть Wc > Wsl*Wsh
143-
// то есть Wsl*Wsh > Wsl*Wsh
144-
// то есть центральная частота по границам подавления > центральной частоты по границам пропускания
141+
// Если Wc / Wsh > Wsl, то есть,
142+
// Wc > Wsl*Wsh, то есть
143+
// Wsl*Wsh > Wsl*Wsh, то есть
144+
// центральная частота по границам подавления > центральной частоты по границам пропускания
145145
// то выбираем в качестве опорной частоты выбираем верхнюю границу пропускания
146146
// иначе, выбираем нижнюю границу пропускания
147147
var Ws = Wc / Wsh > Wsl

0 commit comments

Comments
 (0)