Розв’яжіть матричне рівняння методом Якобі (переглянутий)


11

Математичні передумови

Нехай A - матриця N від реальних чисел, ba вектор N дійсних чисел і xa вектор N невідомих дійсних чисел. Матричне рівняння - Ax = b.

Метод Якобі полягає в наступному: розкласти A = D + R, де D - матриця діагоналей, а R - решта записів.

якщо зробити початковий розгадку рішення x0, вдосконаленим рішенням є x1 = зворотне (D) * (b - Rx), де всі множення є матричним векторним множенням, а зворотне (D) - матрицею, оберненою.


Специфікація проблеми

  • Введення : Ваша повна програма повинна прийняти як вхід такі дані: матриця A, вектор b, початкова здогадка x0 та число "помилки" e.
  • Вихід : Програма повинна вивести мінімальну кількість ітерацій, щоб останнє рішення відрізнялося від справжнього рішення, щонайменше e. Це означає, що кожен компонент векторів в абсолютній величині відрізняється щонайбільше e. Ви повинні використовувати метод Якобі для ітерацій.

Як вводити дані - це ваш вибір ; це може бути ваш власний синтаксис у командному рядку, ви можете брати дані з файлу, що б ви не вибрали.

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

Детальніше

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

Точність - це проблема; деякі "точні рішення" для порівняння можуть відрізнятися. Для цілей цього коду гольф точне рішення має відповідати 10 знакам після коми.

Щоб бути абсолютно зрозумілим, якщо навіть один компонент вашого теперішнього ітераційного рішення перевищує його відповідний компонент у справжньому рішенні на e, тоді вам потрібно тримати ітерацію.

Верхня межа N залежить від того, яке обладнання ви використовуєте та скільки часу ви готові витратити на виконання програми. Для цілей цього коду гольф припустимо максимум N = 50.

Передумови

Коли ви викликаєте вашу програму, ви можете припустити, що вказане в усіх випадках:

  • N> 1 і N <51, тобто вам ніколи не буде дано скалярне рівняння, завжди матричне рівняння.
  • Усі входи знаходяться над полем дійсних чисел і ніколи не будуть складними.
  • Матриця A завжди така, що метод сходить до справжнього рішення, таким чином, ви завжди можете знайти ряд ітерацій, щоб мінімізувати помилку (як визначено вище) нижче або дорівнює e.
  • A ніколи не є нульовою матрицею або матрицею ідентичності, тобто є одне рішення.

Випробування

A = ((9, -2), (1, 3)), b = (3,4), x0 = (1,1), e = 0.04

Справжнє рішення - (0,586, 1,138). Перша ітерація дає x1 = (5/9, 1), що відрізняється більш ніж на 0,04 від справжнього рішення, принаймні на одну складову. Взявши іншу ітерацію, знайдемо, x2 = (0,555, 1,148), яка відрізняється менше ніж на 0,04 від (0,586, 1,138). Таким чином, вихід є

2

A = ((2, 3), (1, 4)), b = (2, -1), x0 = (2.7, -0.7), e = 1.0

У цьому випадку істинним рішенням є (2.2, -0.8), і початкова здогадка x0 вже має помилку менше e = 1,0, таким чином ми виводимо 0. Тобто, коли вам не потрібно робити ітерацію, ви просто виведете

0

Оцінка подання

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


2
Вам дійсно слід почекати, щоб отримати більше відгуків про нього, особливо з огляду на недавню закриту посаду. Завдання PPCG зазвичай мають спільну структуру в специфікаціях, що, як правило, сприяє тому, що вони є легкими для розуміння, а не стомлюючими та неоднозначними. Спробуйте поглянути на деякі досить обґрунтовані виклики та імітуйте формат.
Уріель

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

3
"Найкоротша правильна повна програма " звучить так, що ви дозволяєте лише програми, а не функції. Я додав би "/ функцію".
Адам

2
Форматування +1 робить або порушує здатність мого мозку зосередитись на питанні
Стівен

1
@ user1997744 Так, має сенс. Я вважаю, що типовим є те, що будь-який інший код, як і інші функції або імпорт python, дозволений, але також включений у рахунок рахунку.
Стівен

Відповіді:


4

APL (Діалог) , 78 68 65 49 байт

Саме тип проблеми для APL був створений.

-3 подяки Еріку Переверху . -11 завдяки ngn .

Функція анонімного вставки. Приймає A як лівий аргумент, а x як правий аргумент. Відбитки призводять до STDOUT у вигляді вертикальних одинарних, використовуючи 1як знаки підрахунку, а потім 0як розділові знаки. Це означає, що навіть 0-результат можна побачити, не ставши 1перед s 0.

{⎕←∨/e<|⍵-b⌹⊃A b e←⍺:⍺∇D+.×b-⍵+.×⍨A-⌹D←⌹A×=/¨⍳⍴A}

Спробуйте в Інтернеті!

Пояснення в порядку читання

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

{} На заданих A, b і e, а також на даному x
⎕← надрукуйте,
∨/ чи є у висловлюванні якась правда, що
e< e менше
|⍵- абсолютного значення
b⌹ матриці x мінус b, поділене
⊃A b e на перше з A, b і e (тобто A),
←⍺ які є лівим аргументом,
: і якщо так,
  ⍺∇ повторюйте на
  D+.× D матриці-раз
  b- b мінус
  ⍵+.×⍨ x, матриця помножена на
  A- A мінус
  ⌹D обернена D (решта записів),
   де D -
   A, де
  =/¨ є однакові
   координати
  ⍴A форми A (тобто діагональ)

Покрокове пояснення

Фактичний порядок виконання справа наліво:

{} Анонімна функція, де A, а ⍵ є x:
A b c←⍺ розділіть лівий аргумент на A, b і e,
 виберіть перший (A)
b⌹ матричний поділ з b (дає справжнє значення x)
⍵- різниці між поточними значеннями x та
| абсолютними
e< прийнятними значеннями помилка менше, ніж ті?
∨/ правда для будь-яких? (літ. АБО зменшення)
⎕← надрукуйте, що булеве значення STDOUT,
: і якщо так:
  ⍴A форма
   матриці такої форми, де кожна комірка має свої власні координати
  =/¨ для кожної комірки, чи рівні вертикальні та горизонтальні координати? (по діагоналі)
   помножте клітинки A на
   матрицю, що (витягує діагоналі), зворотну
  D← сховище в D (для D iagonal)
   зворотне (назад до нормального)
  A- віднімання від
  ⍵+.×⍨ матриці помножимо (те саме, що і крапковий добуток, звідси .), що з x
  b- віднімаємо, що від
  D+.× матриці добутку D, і
  ⍺∇ застосовуємо цю функцію з заданим A, і що як нове значення x


Вихід повинен бути кількістю повторень, необхідних для точності e.
Згарб

-1: Це не рішення. Вам потрібно x0, оскільки вся точка полягає в тому, щоб знати, скільки кроків потрібно, щоб досягти бажаної точності з певної початкової точки.
користувач1997744

@ user1997744 О, я неправильно зрозумів проблему. Вибачте.
Адам

@ user1997744 Краще?
Adám

1
@ user1997744 Не арифметична операція, а лише здатність читати одинарне , де дійсно 0 - це нічого .
Adám

1

Python 3 , 132 байти

f=lambda A,b,x,e:e<l.norm(x-dot(l.inv(A),b))and 1+f(A,b,dot(l.inv(d(d(A))),b-dot(A-d(d(A)),x)),e)
from numpy import*
l=linalg
d=diag

Спробуйте в Інтернеті!

Використовується рекурсивний розчин.


@ Adám Я не впевнений, що цілком розумію. Я інтерпретував це як fвідсутність імені в кодовому блоці, який я тепер виправив; однак, якщо це зовсім інше питання, це все ще може бути проблемою.
нояган

@ Adám Ця відповідь, схоже, підтверджує те, що я маю на даний момент; це функція з кодом помічника, який здатний працювати як одиниця після її визначення.
нежаган

А, добре. Неважливо, тоді. Я не знаю Python, тому мені було просто цікаво. Хороша робота!
Адам

Чи не є критерієм зупинки "Це означає, що кожен компонент векторів в абсолютній величині відрізняється щонайбільше e"? В основному максимальна норма, а не L2-норма.
NikoNyrh

@NikoNyrh Виправлено.
notjagan

1

R , 138 байт

function(A,x,b,e){R=A-(D=diag(diag(A)))
g=solve(A,b)
if(norm(t(x-g),"M")<e)T=0
while(norm((y=solve(D)%*%(b-R%*%x))-g,"M")>e){T=T+1;x=y}
T}

Спробуйте в Інтернеті!

дякую НікоНірху за виправлення помилки

Варто також зазначити, що є пакет R, Rlinsolveякий містить lsolve.jacobiфункцію, повертаючи список з x(рішення) та iter(необхідна кількість ітерацій), але я не впевнений, що він робить правильні обчислення.


Чи не є критерієм зупинки "Це означає, що кожен компонент векторів в абсолютній величині відрізняється щонайбільше e"? В основному максимальна норма, а не L2-норма.
NikoNyrh

@NikoNyrh ви праві! на щастя, ця normфункція передбачає і для мене відсутність додаткових байтів.
Джузеппе

1

Clojure, 212 198 196 байт

#(let[E(range)I(iterate(fn[X](map(fn[r b d](/(- b(apply +(map * r X)))d))(map assoc % E(repeat 0))%2(map nth % E)))%3)](count(for[x I :while(not-every?(fn[e](<(- %4)e %4))(map -(nth I 1e9)x))]x)))

Реалізована без матричної бібліотеки, вона повторює процес 1e9 разів, щоб отримати правильну відповідь. Це не працюватиме надто погано обумовленими входами, але на практиці має працювати добре.

Менше гольфу, я був цілком задоволений виразами Rта D:) Перший вхід %(A) повинен бути вектором, а не списком, щоб assocможна було використовувати.

(def f #(let[R(map assoc %(range)(repeat 0))
             D(map nth %(range))
             I(iterate(fn[X](map(fn[r x b d](/(- b(apply +(map * r x)))d))R(repeat X)%2 D))%3)]
          (->> I
               (take-while (fn[x](not-every?(fn[e](<(- %4)e %4))(map -(nth I 1e9)x))))
               count)))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.