Skip to content

Commit 3c1432d

Browse files
committed
Развитие идеи Динамической системы (не завершено)
1 parent f69e7fa commit 3c1432d

2 files changed

Lines changed: 127 additions & 0 deletions

File tree

MathCore/DynamicSystem.cs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#nullable enable
2+
namespace MathCore;
3+
4+
/// <summary>Кольцевой буфер истории с доступом по числу шагов назад</summary>
5+
public sealed class HistoryBuffer<T>(int capacity)
6+
{
7+
private readonly T[] _Items = capacity > 0 ? new T[capacity] : [];
8+
private int _Count;
9+
private int _Head;
10+
11+
/// <summary>Ёмкость буфера</summary>
12+
public int Capacity => _Items.Length;
13+
14+
/// <summary>Текущее число элементов в буфере</summary>
15+
public int Count => _Count;
16+
17+
/// <summary>Добавляет элемент в историю</summary>
18+
public void Enqueue(T item)
19+
{
20+
if (Capacity == 0) return;
21+
22+
_Items[_Head] = item;
23+
_Head = (_Head + 1) % Capacity;
24+
25+
if (_Count < Capacity)
26+
_Count++;
27+
}
28+
29+
/// <summary>Возвращает элемент истории k шагов назад, где 0 — последний добавленный</summary>
30+
public T this[int LastStep]
31+
{
32+
get
33+
{
34+
if (LastStep < 0 || LastStep >= _Count)
35+
throw new ArgumentOutOfRangeException(nameof(LastStep));
36+
37+
var idx = (_Head - 1 - LastStep) % Capacity;
38+
if (idx < 0)
39+
idx += Capacity;
40+
return _Items[idx];
41+
}
42+
}
43+
44+
/// <summary>Очищает буфер</summary>
45+
public void Clear() { _Count = 0; _Head = 0; }
46+
}
47+
48+
/// <summary>Дискретная динамическая система с поддержкой истории состояний</summary>
49+
public class DynamicSystem<TState, TInput>(int Order)
50+
where TState : struct
51+
where TInput : struct
52+
{
53+
private HistoryBuffer<HistoryItem>? _History = new(Order);
54+
55+
/// <summary>Элемент истории состояния во времени</summary>
56+
public readonly record struct HistoryItem(TState State, double Time)
57+
{
58+
/// <summary>Неявное приведение к типу состояния</summary>
59+
public static implicit operator TState(HistoryItem item) => item.State;
60+
}
61+
62+
/// <summary>Текущее состояние системы</summary>
63+
public HistoryItem State { get; protected set; }
64+
65+
/// <summary>Представление истории для вычисления шага</summary>
66+
public readonly record struct History(HistoryBuffer<HistoryItem>? history, double Time)
67+
{
68+
/// <summary>Доступ к элементу истории k шагов назад, где 0 — предыдущий шаг</summary>
69+
public HistoryItem this[int steps] => history?[steps] ?? throw new InvalidOperationException("History is disabled");
70+
71+
/// <summary>Число доступных элементов истории</summary>
72+
public int Count => history?.Count ?? 0;
73+
}
74+
75+
/// <summary>Набор «дифференциальных уравнений», формирующих вклады в новое состояние</summary>
76+
public required IReadOnlyList<Func<TInput, History, TState>> DiffEquations { get; init; }
77+
78+
/// <summary>Агрегатор, собирающий новое состояние из предыдущего, вкладов и времени</summary>
79+
public required Func<TState, TState[], double, TState> Aggregator { get; init; }
80+
81+
private TState[]? _DiffStates;
82+
83+
/// <summary>Выполняет один дискретный шаг обновления состояния</summary>
84+
public TState Update(double Time, TInput input)
85+
{
86+
// Сначала фиксируем предыдущее состояние в истории, чтобы s[0] был прошлым шагом
87+
_History?.Enqueue(State);
88+
89+
var states = _DiffStates ??= new TState[DiffEquations.Count];
90+
91+
var s = new History(_History, Time);
92+
for (var i = 0; i < DiffEquations.Count; i++)
93+
states[i] = DiffEquations[i](input, s);
94+
95+
var new_state = Aggregator(State, _DiffStates, Time);
96+
97+
State = new(new_state, Time);
98+
99+
return new_state;
100+
}
101+
102+
/// <summary>Сбрасывает состояние и очищает историю</summary>
103+
public void Reset(TState state = default, double time = 0)
104+
{
105+
State = new(state, time);
106+
_History = new(Order); // сохраняем настроенный объём истории
107+
// Стартовое состояние НЕ добавляем в историю, чтобы при первом Update s[0] ссылался на него один раз
108+
}
109+
}
110+
111+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using MathCore.Vectors;
2+
3+
namespace MathCore.Tests;
4+
5+
[TestClass]
6+
public class DynamicSystemTests
7+
{
8+
[TestMethod]
9+
public void CreationTest()
10+
{
11+
var system = new DynamicSystem<Vector2D, Vector2D>
12+
{
13+
14+
};
15+
}
16+
}

0 commit comments

Comments
 (0)