Побудова функції кривої для плавного обмеження параметрів сигналів і не тільки в Wolfram Mathematica

Існує ряд задач, у яких діапазон вихідних значень повинен бути обмежений, в той час як вхідні дані цього гарантувати не можуть. Крім вимушених ситуацій, обмеження сигналу може бути і цілеспрямованої завданням — наприклад, при компресії сигналу або реалізації ефекту «overdrive».

Найпростіша реалізація обмеження — це примусова установка в деяке значення при перевищенні певного рівня. Наприклад, для синусоїди із зростаючою амплітудою це буде виглядати так:

У ролі обмежувача тут виступає функція Clip, в якості аргументу якій передається вхідний сигнал і параметри обмеження, а результатом функції є вихідний сигнал.

Подивимося на графік функції Clip окремо:

З нього видно, що поки ми не перевищуємо межі обмеження, вихідне значення дорівнює вхідного і сигнал не змінюється; при перевищенні ж вихідне значення від вхідного вже ніяк не залежить і залишається на одному і тому ж рівні. По суті, ми маємо кусково-неперервну функцію, складену з трьох інших: y=-1, y=x і y=1, вибираються в залежності від аргументу, і еквівалентну наступного запису:

Перехід між функціями відбувається досить різко; і виглядає заманливим зробити його більш плавним. Математично ця різкість обумовлена тим, що похідні функцій в точках стикування не збігаються. Це легко побачити, побудувавши графік похідної функції Clip:

Таким чином, щоб забезпечити гладкість функції обмеження, необхідно забезпечити рівність похідних в точках стикування. А оскільки крайні функції у нас константи, похідні від яких дорівнюють нулю, то і похідні функції обмеження в точках стикування теж повинні бути рівні нулю. Далі будуть розглянуті кілька таких функцій, забезпечують гладку стиковку.

Синус

Найпростіше — це використовувати функцію sin на інтервалі від -pi/2 до pi/2, на межах якого значення дорівнюють нулю похідної за визначенням:

Потрібно тільки масштабувати аргументи, щоб одиниця проектувалася на Pi/2. Тепер ми можемо визначити власне обмежує функцію:

І побудувати її графік:

Так як межі обмеження у нас жорстко визначені, то обмеження задається через масштабування вхідного сигналу з подальшим (у разі необхідності) зворотному масштабуванні.
Тут також вже немає ситуації, при якій вхідний сигнал передається на вихід без спотворень — чим менше рівень посилення, тим менший рівень спотворень внаслідок обмеження — але сигнал спотворюється в будь-якому випадку.
Вплив параметра посилення на спотворення сигналу можна подивитися і в динаміці:

Більше гладкості

Подивимося на похідну нашої функції:

У ній вже немає розривів у значеннях, але є розриви в похідною (другий, якщо рахувати від початкової функції). Для того, щоб її усунути, можна піти зворотним шляхом — спочатку сформувати гладку похідну, а потім її проінтегрувати для отримання шуканої функції.
Найпростіший спосіб обнулити похідну точках -1 і 1 — це просто звести функцію в квадрат — всі від’ємні значення функції стануть позитивними і, відповідно, виникнуть перегини в точках перетину функції з нулем.

Знаходимо первообразную:

Тепер залишилося масштабування по осі ординат. Для цього знайдемо її значення в точці 1:

І поділимо на неї (так, конкретно тут це елементарне множення на 2, але далеко не завжди так буває):

Таким чином, підсумкова функція обмеження прийме вигляд:

Переходимо на поліноми

Використання тригонометричних функцій у деяких випадках може виявитися кілька марнотратним. Тому спробуємо побудувати потрібну нам функцію, залишаючись в рамках елементарних математичних операцій.
Розглянемо параболу:

Так як у неї вже є перегин у точці нуль, ми можемо використовувати одну і ту ж частину на інтервалі {0,1} для стикування з константами. Для від’ємних значень її потрібно змістити вниз і ліворуч:

Читайте також  Практичний TypeScript. React + Redux

а для позитивних — відобразити по вертикалі і горизонталі:

І наша функція з параболою прийме вигляд:

Трохи ускладнимо

Повернемося до нашої параболі, перевернемо її і змістимо на одиницю вгору:

Це буде похідна нашої функції. Щоб зробити її більш гладкою в точках стикування, зведемо в квадрат, обнуливши таким чином другу похідну:

Інтегруємо і масштабується:

Отримуємо ще більш гладку функцію:

Більше гладкості богу гладкості

Тут ми спробуємо добитися гладкості в точках стикування на ще більш вищих похідних. Для цього для початку визначимо функцію як поліном з невідомими коефіцієнтами, а самі коефіцієнти спробуємо знайти через рішення системи рівнянь.

Почнемо з 1-ї похідної:

2-я:

3-я:

Всі ці коефіцієнти виглядає так, як ніби у них є якась логіка. Випишемо множники, помножившпи їх на значення ступеня при х; а щоб не писати кожен раз одне і теж, автоматизуємо процес знаходження коефіцієнтів:

Схоже на биномиальные коефіцієнти. Зробимо сміливе припущення, що це вони і є, і виходячи з цього, запишемо узагальнену формулу:

Перевіримо:

Схоже на правду [1]. Залишилося тільки порахувати масштабний коефіцієнт, щоб привести краю до одиниці:

А після масштабування і спрощення ми виявимо, що наші пізнання в математиці дещо застаріли [2]:

Таким чином, ми отримали виробляє функцію порядку n, в якій n-1 перших похідних будуть дорівнюють нулю:

Подивимося, що вийшло:

І оскільки наша узагальнена формула вийшла безперервної, при бажанні можна використовувати і нецілі значення параметрів:

Також можна побудувати графіки похідних, приведених до одного масштабу:

Додаємо жорсткості

Було б заманливо, мати можливість регулювати і ступінь «жорсткості» обмеження.
Повернемося до нашої перевернутої параболі і додамо коефіцієнт при ступені x:

Чим більше n, тим більше наша похідна «квадратна», а її первісна — відповідно, різка:

Порахуємо первообразную і скорегуємо масштаб:

Спробуємо тепер визначити дробовий крок для параметра:

Як бачимо, в негативній частині не для всіх n є коректне рішення, але в правій (позитивної) частини необхідні умови як і раніше дотримуються — тому для від’ємних значень ми можемо просто використовувати її в перевернутому вигляді з реверсированным аргументом. І оскільки область визначення параметра вже не обмежена тільки позитивними цілими числами, то можна спростити формулу, замінивши на 2n n:

А замінивши n на n-1, можна зробити формулу трохи більш красивою:

Оскільки при n рівним одиниці ми отримуємо ділення на нуль, то спробуємо знайти межа:

Межа знаходиться, а значить, тепер можна довизначити [3] функцію для n рівним 1 і розглядати її для всіх n великих нуля:

Якщо ж ми спочатку зведемо нашу перевернуту параболу в квадрат, то отримаємо ще більш гладку функцію:

І можемо порівняти їх на одному графіку:

Рационализируй це

Подивимося на наступну функцію:

З’явилася вона не випадково.
Якщо прибрати з неї одиницю, x2 скоротиться і залишиться просто x, т. е похила пряма. Таким чином, чим менше значення x, тим більший вплив робить одиниця в знаменнику, створюючи необхідний нам викривлення. А розглядаючи цю функцію в різних масштабах, можна контролювати ступінь цього викривлення:

Таким чином, ми можемо переписати попередню функцію з контролем жорсткості, використовуючи тільки раціональний поліном 3-порядку:

Автоматизируй це

Щоб не ставити щораз кусково-неперервні функції, ми можемо визначити допоміжну функцію, яка зробить це самостійно, приймаючи на вхід донорську функцію як аргумент.

Читайте також  Обчислюємо «магічні квадрати» за допомогою GPU

Якщо наша функція вже має діагональної симетрією і вирівняна по центру координат (як синусоїда), то можна зробити просто

Приклад використання:

Якщо ж потрібно збирати з шматочків, як у випадку з параболою, і центр координат визначає точки стикування, то формула дещо ускладниться:

Приклад використання:

Перейдемо на експоненту

Абсолютно будь-яка функція може бути донором для вирішення цієї задачі, потрібно лише забезпечити їй точки перегину. Візьмемо, наприклад, зрушену вниз на одиницю експоненту:

Раніше, для забезпечення необхідного перегину в точці нуль, ми зводили функцію в квадрат. Але можна піти й іншим шляхом — наприклад, підсумувати з іншою функцією, похідна якої в точці нуль протилежна за знаком з похідною експоненти. Наприклад, -x:

В залежності від того, з якого боку ми будемо брати криву, буде залежати вид функції. Тепер, скориставшись раніше визначеної допоміжною функцією і вибравши одну з сторін, отримаємо:

Або

І тепер можемо порівняти їх на одному графіку:

Видно, що при k→0 вони прагнуть до збігу; і так як безпосередньо порахувати їх значення ми не можемо, оскільки отримаємо ділення на нуль, то скористаємося межею:

І отримали вже відому нам кусково функцію з параболи.

Порушуючи симетрію

Поки що ми розглядали винятково симетричні функції. Однак бувають випадки, коли симетрія нам не потрібна, наприклад, для імітації спотворень при звучанні лампових підсилювачів.

Візьмемо експоненту і помножимо її на перевернуту параболу в квадраті — щоб отримати перетин з віссю абсцис у точках -1 та 1, а заодно і забезпечити гладкість другої похідної; параметризацію ж здійснимо через масштабування експоненти аргументу:

Знайдемо первообразную і масштабується її:

Так як при k=0 отримаємо ділення на нуль:

То додатково знайдемо межу,

який представляє з себе вже відомий нам гладкий поліном 3-го порядку. Поєднавши всі в одну функцію, отримаємо

Замість того, щоб спочатку проектувати асиметричну функцію, можна піти й іншим шляхом — використовувати готову симетричну, але «викривляти» значення цієї функції з допомогою додаткової функції кривої, визначеної на проміжку {-1,1}.

Розглянемо, наприклад, гіперболу:

Розглядаючи її відрізок в різних масштабах, можна регулювати ступінь викривлення в обидві сторони. Як же знайти цей відрізок? Виходячи з графіка, можна було б шукати перетину гіперболи з прямою. Однак, оскільки таке перетин існує не завжди, це створює деякі складності. Тому ми підемо іншим шляхом.

Для початку додамо в гіперболу масштабуючі коефіцієнти:

потім складемо систему рівнянь, що задають умови проходження гіперболи через задані точки — і її вирішення дасть цікавлять нас коефіцієнти:

Тепер підставимо рішення у вихідну формулу і спростимо:

Подивимося, що у нас вийшло в залежності від параметра k:

Примітно, що при k=0 формула природним чином схлопывается в x і ніяких особливих ситуацій не відбувається, хоча стосовно до вихідної гіперболі це рівносильно відрізку нульової довжини, причому двом відразу. Не менш примітно, що оберненої до неї функцією є вона сама, але з негативним параметром k:

Тепер ми можемо використовувати її для модифікації довільної функції обмеження, а параметр k таким чином буде ставити точку перетину з віссю ординат:

Аналогічним чином можна будувати криві та з інших функцій, наприклад, степеневої з перемінним підставою:

Або зворотного до неї логарифмічної:

Потрібно більше точності

Ми можемо захотіти мати гарантовано лінійний проміжок у функції на деякому інтервалі. Це логічно організувати введенням прямої лінії в кусково-неперервну функцію,

порожні місця в якій необхідно заповнити який-небудь функцією. Очевидно, що для гладкої стикування з лінійним відділком її перша похідна повинна бути дорівнює одиниці; а всі наступні (по можливості) нулю. Щоб не виводити таку функцію заново, ми можемо взяти вже готову і адаптувати під цю задачу. Також можна помітити, що крайні точки знаходяться трохи далі одиниці — це необхідно, щоб зберегти нахил лінійної дільниці.

Читайте також  Співробітники Rockstar заступилися за компанію після критики за 100-годинні робочі тижні

Візьмемо виведену раніше функцію PolySoft і змістимо її так, щоб в центрі координат отримати одиницю:

З її властивостей випливає, що n-1 наступних похідних в точках 0 і 2 будуть дорівнюють нулю:

Тепер проинтегрируем її:

Функція виявилася зрушеної вниз відносно осі абсцис. Тому необхідно додати константу (дорівнює значенню функції в точці 0), щоб поєднати центри координат:

Тут у нас з’явився нуль у степені n. Він не скоротився, так як значення нуль в ступені нуль не визначено; ми можемо його видалити вручну, а можемо при спрощенні явно вказати, що n у нас більше нуля:

Перевіримо на всякий випадок. Значення в точках 0 і 2 для всіх n:

Похідні на краях інтервалу (для полінома порядку 5):

Як бачимо функція вийшла досить громіздкою. Щоб не тягати її і не переусложнять обчислення, далі будемо маніпулювати вже з конкретним поліномом, наприклад 4-го порядку:

І ось тепер нею можна заповнити вільний простір:

Перевіримо:

Йдемо в нескінченність

Іноді може виявитися потреба у функціях, які прагнуть до одиниці, але не досягають її. Вікіпедія підказує кілька відомих рішень:

Так як ці функції одиниці не досягають, їх зручніше нормувати по похідної в центрі координат.
Ми можемо модифікувати форму таких функцій через їх аргумент за допомогою якої-небудь діагонально-симетричної функції, наприклад:

Ця функція, до речі, також є зворотним до самої себе, тобто

І, стосовно до арктангенсу в якості прикладу, отримаємо

що, зокрема, з параметром k=1 дасть нам функцію Гудермана.

Як бачимо, при такому підході можна отримати небажані перегини, тому краще контролювати жорсткість обмеження безпосередньо через властивість самої функції. Розглянемо кілька таких функцій з параметром, висновок яких для стислості опустимо.

З степеневої функції:

З суми двох v-образних функцій зі зміщенням:

З узагальненої функції помилок:

Інтегруванням раціонального полінома:

Цікаво, що її окремим випадком є тангенс:

Висновок

Побудова подібного роду функцій може бути захоплюючим заняттям, в ході якого будуть виходити як прості, так і складні, як гарні, так і не дуже, формули. Може здатися, що всі вони дуже один на одного схожі, і потреби в подібному різноманітті немає. Це не обов’язково так.

Різниця може бути сильніше видно в інших масштабах — наприклад, логарифмічної. Крім того, крім позначених у заголовку завдань, подібні функції можуть використовуватися і в інших завданнях — змішування сигналів, коли плавне затухання одного сигналу поєднується з плавним наростанням іншого, або побудові акустичних фільтрів — і тоді різниця буде сприйматися на слух, або ж для побудови градієнтів — і тоді різниця буде сприйматися на око. Крім того, вони також можуть використовуватися в якості донорів для інших, більш складних функцій — наприклад, віконних.

На завершення варто уточнити ще кілька моментів.
Всі функції тут були визначені в діапазоні від -1 до 1. У разі, якщо потрібен інший діапазон (наприклад, від 0 до 1), його легко можна перерахувати або вручну:

Або використовуючи вбудовану функцію масштабування:

А для полегшення експорту отриманих формул в програмний код може знадобитися функція CForm:

Вихідний документ Mathematica можна завантажити тут.

Примітки:

[1] справжній математик напевно зможе строго довести (або спростувати) твердження.
[2] у стандартному курсі мат.аналізу гипергеометрические функції не розглядаються.
[3] ця перевантаження визначена тільки для символьного одиниці; одиниця у форматі з плаваючою крапкою (наприклад, при побудові графіка) розпізнана не буде.

Степан Лютий

Обожнюю технології в сучасному світі. Хоча частенько і замислююся над тим, як далеко вони нас заведуть. Не те, щоб я прям і знаюся на ядрах, пікселях, коллайдерах і інших парсеках. Просто приходжу в захват від того, що може в творчому пориві вигадати людський розум.

Вам також сподобається...

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *