МСС ресурс Freeware Open source Кафедра МСС Факультет  

Пакет
"Моделювання
Динамічних Систем"
v5.2

ПРО ПАКЕТ ПОПЕРЕДНІЙ КЛАС НАСТУПНИЙ КЛАС      

model.h
Абстрактний клас model

 

Використовує класи:
result_manager
Використовується у:
calc::Method, calc::Calculate

 


Основна мета цього класу – інкапсулювати характеристики динамічної математичної моделі типу Lx=F(t,x), де x n-вимірний вектор (n>0), F - n-вимірна вектор-функція, L - довільний n-вимірний оператор (зокрема, взяття похідних). Це є базовий клас для динамічних моделей: ним можна задавати як одну (цілісну) модель, так і складати із таких моделей комплекси, в якому кожна складова функціонує за своїми власними законами. Крім того, даний клас забезпечує режим емуляції системи (тобто замість обчислень рівнянь підставляються заздалегідь отримані значення із відповідної таблиці), а також можливість створення (динамічного запису) емуляційних таблиць.

Передбачено можливість роботи із довільним типом даних (за замовчуванням із типом double), що дозволяє проводити обчислення з підвищенною точністю. У режимі відладки (DEBUG) здійснюється автоматичний контроль допустимості операцій.

У файлі mds.h визначено наступні типи.
typedef double MDS_DEFAULT_TYPE;
typedef mds_exception_message MDS_DEFAULT_EXCEPTION;
typedef model <MDS_DEFAULT_TYPE, MDS_DEFAULT_EXCEPTION> Model;

Для включення/виключення режиму емуляції визначено наступні константи.
EMULATION_DISABLED - емуляцію виключено (за замовченням);
EMULATION_ENABLED - емуляцію включено;
EMULATION_RECORDING - запис емуляційної таблиці;


 

Члени класу
private size_t dimension
           Розмірність моделі (кількість рівнянь у правій частині системи).
protected T t
          Поточний час моделі.
protected valarray<T> x
          Поточний стан моделі (фазовий вектор).
protected valarray<T> y
          Поточний стан значень правої частини моделі.
private valarray<bool> phase
          Маска для швидкого отримання фазового вектору з розширеного фазового вектору.
protected int identify
           Ідентифікатор даної моделі.
result_manager emulation_table
           Емуляційна таблиця.
size_t emulation_order
           Порядок апроксимації, що використовується у режимі емуляції при читанні даних з емуляційної таблиці. Допустимі значення параметру визначаються класом result_manager.
private int emulation_mode
           Стан емуляції (приймає одне із значень EMULATION_DISABLED, EMULATION_ENABLED, EMULATION_RECORDING).

 

Конструктори
model <class T = MDS_DEFAULT_TYPE, class EXCEPTION = MDS_DEFAULT_EXCEPTION> (size_t dim = 0, int id = 0)
             Параметри: розмірність моделі (кількість рівнянь у правій частині системи рівнянь) та необов'язковий ідентифікатор. Типи: T - тип обчислень, EXCEPTION - тип винятків.

 

Функції-члени класу
 virtual void RightPart(valarray<T>& f)
           Чисто віртуальна функція для задання правої частини рівнянь. Результат, отриманий для поточних t, x передає у f. Дана функція має бути перевантажена згідно конкретних рівнянь моделі.
[static] valarray<T>& | T& | valarray<T>

System([pM,] { [ef,] [eph] | arg_t, f })
           Обчислення значень правої чистини системи рівнянь за поточними t, x ([] - необов'язковий, {} - список альтернатив, які розділені знаком | ).
pM - (valarray<model<T, EXCEPTION> *>) - містить адреси моделей, з яких утворено комплекс;
ef
- (valarray<T>) - поточний фазовий вектор (можливо розширений, в залежності від eph) значень правої частини системи рівнянь (буфер для прийняття значень);
eph - (bool) - визначає, чи повертається звичайний n-вимірний фазовий вектор (false - за замовчуванням), чи розширений (n+1)-вимірний (перша координата - час) фазовий вектор (true);
arg_t
- (T) - поточний час (буфер для прийняття значення);
f - (valarray<T>) - поточний фазовий вектор значень правої частини системи рівнянь (буфер для прийняття значень);
Якщо заданий pM, то функція має тип static. Якщо використовується буфер, то повертається зсилка на нього, інакше повертаєтся безпосереднє значення.

[static] valarray<T>& | valarray<T>

DoSystem([pM,] [ef,] {arg_a | arg_t [, arg_x] } [, eph])
           Встановлює поточні t, x та обчислює значення правої чистини системи рівнянь ([] - необов'язковий, {} - список альтернатив, які розділені знаком | ).
pM - (valarray<model<T, EXCEPTION> *>) - містить адреси моделей, з яких утворено комплекс;
ef - (valarray<T>) - фазовий вектор (можливо розширений, в залежності від eph) значень правої частини системи рівнянь (буфер для прийняття значень);
arg_a
- (valarray<T>) - розширений фазовий вектор (перша координата - час) для задання поточних t, x;
arg_t - (T) - час для задання поточного t;
arg_x - (valarray<T>) - фазовий вектор для задання поточного x;
eph - (bool) - визначає, чи повертається звичайний n-вимірний фазовий вектор (false - за замовчуванням), чи розширений (n+1)-вимірний (перша координата - час) фазовий вектор (true);
Якщо заданий pM, то функція має тип static. Якщо використовується буфер, то повертається зсилка на нього, інакше повертаєтся безпосереднє значення.

[static] void SetStatus([pM,] {arg_a | arg_t [, arg_x] })
           Встановлює поточні t, x ([] - необов'язковий, {} - список альтернатив, які розділені знаком | ).
pM - (valarray<model<T, EXCEPTION> *> ) - містить адреси моделей, з яких утворено комплекс;
arg_a - (valarray<T>) - розширений фазовий вектор (перша координата - час) для задання поточних t, x;
arg_t - (T) - час для задання поточного t;
arg_x - (valarray<T>) - фазовий вектор для задання поточного x;
Якщо заданий pM, то функція має тип static.
[static] valarray<T>& | T& | valarray<T>

GetStatus([pM,] { [arg_a,] [eph] | arg_t [, arg_x] }) [const]
           Повертає поточні t, x ([] - необов'язковий, {} - список альтернатив, які розділені знаком | ).
pM - (valarray<model<T, EXCEPTION> *>) - містить адреси моделей, з яких утворено комплекс;
arg_a - (valarray<T>) - поточний фазовий вектор (можливо розширений, в залежності від eph) (буфер для прийняття значень);
eph - (bool) - визначає, чи повертається звичайний n-вимірний фазовий вектор (false - за замовчуванням), чи розширений (n+1)-вимірний (перша координата - час) фазовий вектор (true);
arg_t - (T) - поточний час (буфер для прийняття значення);
arg_x - (valarray<T>) - поточний фазовий вектор (буфер для прийняття значень);
Якщо заданий pM, то функція має тип static, інакше const. Якщо використовується буфер, то повертається зсилка на нього, інакше повертаєтся безпосереднє значення.

[static] valarray<T>& | T& | valarray<T>

GetSystemStatus([pM,] { [ef] [eph] | arg_t [, f] }) [const]
           Повертає поточні t, y (значення правої частини системи рівнянь) ([] - необов'язковий, {} - список альтернатив, які розділені знаком | ).
pM - (valarray<model<T, EXCEPTION> *>) - містить адреси моделей, з яких утворено комплекс;
ef - (valarray<T>) - поточний фазовий вектор (можливо розширений, в залежності від eph) значень правої чистини системи рівнянь після останнього застосування System( ) або DoSystem( ) (буфер для прийняття значень);
eph - (bool) - визначає, чи повертається звичайний n-вимірний фазовий вектор (false - за замовчуванням), чи розширений (n+1)-вимірний (перша координата - час) фазовий вектор (true);
arg_t - (T) - поточний час (буфер для прийняття значення);
f - (valarray<T>) - поточний фазовий вектор значень правої чистини системи рівнянь (буфер для прийняття значень);
Якщо заданий pM, то функція має тип static, інакше const. Якщо використовується буфер, то повертається зсилка на нього, інакше повертаєтся безпосереднє значення.

void SetTime([pM,] arg_t)
           Встановлює поточний час t згідно arg_t - (T). Необов'язковий pM - (valarray<model<T, EXCEPTION> *>) - містить адреси моделей, з яких утворено комплекс.
[static] T& | T GetTime([pM,] [arg_t]) [const]
           Повертає поточний час t. arg_t - (T) - час (буфер для прийняття значення); необов'язковий pM - (valarray<model<T, EXCEPTION> *>) - містить адреси моделей, з яких утворено комплекс. Якщо заданий pM, то функція має тип static, інакше const. Якщо використовується буфер, то повертається зсилка на нього, інакше повертаєтся безпосереднє значення.
valarray<bool> PhaseMask() const
          Маска для швидкого отримання фазового вектору з розширеного фазового вектору.
[static] size_t GetDimension([pM]) [const]
           Повертає розмірність моделі (кількість рівнянь правої частини системи). Необов'язковий pM - (valarray<model<T, EXCEPTION> *>) - містить адреси моделей, з яких утворено комплекс. Якщо заданий pM, то функція має тип static, інакше const.
int GetIdentify() const
           Повертає ідентифікатор моделі, заданий у конструкторі.
int GetEmulationStatus() const
           Повертає поточний стан режиму емуляції.
void SetEmulationStatus(int newStatus )
           Встановлює режим емуляції (можливі значення аргументу: EMULATION_DISABLED, EMULATION_ENABLED, EMULATION_RECORDING).

 

Опис

Нехай система рівнянь моделі має вигляд

В даному випадку абсолютно не важливо, що саме міститься у лівій частині системи (там могли б бути, наприклад, другі похідні). Для використання класу model нам знадобиться лише права частина системи. Найпростішим чином дану модель можна запрограмувати так:

01. class MyModel : public Model
02. {
03. public:
04. MyModel() : Model(2) {}

05. virtual void RightPart(valarray<double>& f)
06. {
07.     f[0] = 5 * x[0] + 7 * x[1] + cos(t);
08.     f[1] = sqrt(x[0] + t);
09. }

10. };

Отже:
Стрічка 01. Наслідуємося від класу model (Model - це model для типу double з консольними виключеннями mds_exception_message).
Стрічка 04. Вказуємо розмірність системи рівнянь. В нашому випадку 2.
Стрічка 05. Перевантажуємо віртуальну функцію RightPart (синтаксис шапки ні в якому разі не можна змінювати!).
Стрічки 06-09. Власне система рівнянь. Тут x - фазовий вектор (системна змінна, розмірність якої вказується у конструкторі - стрічка 04), t - часова змінна (теж системна змінна). Значення функцій системи рівнянь заносяться у f.

Певна річ, модель може містити додаткові параметри або функції-члени класу. В принципі, задання моделі на цьому завершується і тепер змінну типу MyModel можна використовувати у відповідних функціях, таких як Calculate(). Крім того, є цілий набір сервісних функцій для роботи із моделями (про них трохи нижче). Головне узагальнення наведеної схеми полягає у використанні довільного базового типу для розрахунків. Стандартним типом є double. Він швидкий, але його точність обмежується 15 знаками після коми, що не завжди прийнятно. Тому інколи доцільно замість double провести розрахунки на типах підвищеної точності (на жаль, такі типи не стандартизовані). Нехай тип обчислень має назву number. Тоді необхідно вказати
У стрічці 01: class MyModel : public model<number>
У стрічці 04: MyModel() : model<number>(2) {}
У стрічці 05: virtual void RightPart(valarray<number>& f)

Робота із моделями забезпечується цілим набором сервісних функцій, які можна поділити на такі категорії: встановлення стану моделі (набір функцій типу SetStatus(), SetTime()), опитування стану моделі (набір функцій типу GetStatus(), GetTime()), обчислення правих частин за поточним станом (набір функцій типу System()), читання кешированих значень правих частин (набір функцій типу GetSystemStatus()), гибридні функції встановлення стану та читання відповідного значення правих частин (набір функцій типу DoSystem()) та додаткові сервісні функції (GetDimension() тощо). Основна ідея полягає у наступному: значення правих частин системи рівнянь обчислюються згідно поточного стану моделі (члени класу t, x), який має бути ініціалізованим перед безпосередніми обчисленнями. Після обчислень результати кешируються (у буфері y) для можливого їхнього використання в подальшому. Така схема дозволяє розглядати декілька моделей одночасно у складі комплексу із перехресними зсилками. Тобто, для обчислення значення правих частин всього комплексу в цілому, необхідно перед цим попіклуватися про належну ініціалізацію станів кожної моделі, що входять у комплекс. Таким чином всі розглядувані моделі отримують повну інформацію як про свій стан, так і про стан всіх інших моделей, що дозволяє розглядати комплекс моделей як єдине ціле. Для підтримки комплексів моделей кожна з вищезазначених категорій сервісних функцій має аналог, в якому перший аргумент є valarray, що складається з адрес на моделі, які утворюють комплекс. Вектор фазових координат комплексу "склеюється" згідно порядку розташування моделей, адреси яких містяться у valarray. Вектор розширених фазових координат комплексу має розмірність на одиницю більше, оскільки перша координата резервується для значення поточного часу (вважається, що поточний час у всіх моделей комплексу однаковий).

Наприклад, необхідно обчислити значення 2-вимірної моделі MyModel в момент часу t_new=0 з вектором поточних фазових координат (типу valarray) x_new={1;2}, тобто отримати значення F(t_new, x_new). Спершу встановимо поточний стан MyModel.SetStatus(t_new, x_new); Після чого MyModel.System(); поверне вектор (типу valarray) значень правої частини для даного фіксованого стану (t_new, x_new). Або, що цілком аналогічно, можна замість двох функцій скористатися однією MyModel.DoSystem(t_new, x_new); Якщо тепер знадобиться знову отримати значення правої частини для даного стану, то можна скористатися MyModel.GetSystemStatus(), яка поверне останній результат застосування System() або DoSystem(). Різноманітність функцій обробки моделей викликана тим, що в різних задачах виникають різні потреби передачі даних (розширені/нерозширені фазові вектори, задання часу без задання фази тощо). Крім того, практично кожна функція має свій буферизований аналог: в даному випадку MyModel.DoSystem(f_new, t_new, x_new); де буфер f_new має тип valarray та приймає значення правої частини. Передача результатів у буфер корисна при частому використанні таких функцій (наприклад, при інтегруванні) і приводить до зростання швидкодії в середньому до 25%.

Безпосереднє використання функції RightPart() не рекомендується. По-перше, функції типу DoSystem() забезпечують достатньо повний сервіс, а, по-друге, функції System() та DoSystem() автоматично організовують роботу з емуляційними таблицями (тобто із таблицями значень, які можуть бути підставлені із заданим порядком апроксимації замість безпосередніх обчислень).

Передбачно механізм емуляції динаміки моделі (за змінною t). Режим емуляції задається функцією SetEmulationStatus(int mode) з наступними можливими значеннями параметру mode:
EMULATION_DISABLED – емуляцію виключено (стандартний режим),
EMULATION_ENABLED
– емуляцію включено (при звертанні до функції System() замість обчислень будуть підставлені значення з емуляційної таблиці),
EMULATION_RECORDING – запис таблиці емуляції (при звертанні до функції System() відбувається паралельний запис значень у відповідну таблицю).

Для того, щоб увімкнути режим емуляції, треба спочатку попіклуватися про емуляційну таблицю (тобто таблицю значень, які будуть підставлятися замість обчислень правої частини моделі). Емуляційна таблиця є об'єктом класу result_manager (основний клас для збереження результатів у пакеті MDS). Можна створити її безпосередньо та під'єднати за допомогою присвоювання змінній emulation_table, або загрузити із файлу, скориставшись властивостями класу result_manager. Або можна прогнати модель у режимі запису (наче магнітофон), встановивши SetEmulationStatus(EMULATION_RECORDING). В цьому випадку, після запису таблиці, необхідно включити SetEmulationStatus(EMULATION_ENABLED), після чого модель замість реальних обчислень правих частин буде працювати тільки із цією таблицею. Встановивши SetEmulationStatus(EMULATION_DISABLED), отримаємо знову звичайний режим роботи моделі (сама таблиця при цьому збережеться і її можна буде підключити знову). Порядок апроксимації задається безпосереднім присвоюванням відповідного значення змінній emulation_order. Допустимий порядок апроксимації визначається можливостями класу result_manager.

Приклад використання МДС знаходиться у файлі main.cpp у директорії mds_example. Додаткова інформація по використанню міститься в описі пакету.


Будь-ласка, надсилайте пропозиції, питання, зауваження: soft@unicyb.kiev.ua
Запрошуємо також до участі у самому проекті: надсилайте свої матеріали, які, по-можливості, будуть виставлені на сайті (див. Для авторів).

Кафедра Моделювання складних систем факультету кібернетики Київського університету імені Тараса Шевченка
03127, Україна, Київ, просп. Глушкова 2, корп. 6, кафедра МСС тел.: (044) 259-05-31, (044) 259-02-37, e-mail: garash@unicyb.kiev.ua
Всі права застережено.