Чи є матриця ранговою одиницею?


21

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

 2   0  -20  10  
-3   0   30 -15
 0   0   0   0

кожен рядок кратний 1 0 -10 5.

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

 *    1   0  -10  5
    ----------------
 2 |  2   0  -20  10  
-3 | -3   0   30 -15
 0 |  0   0   0   0

Ми призначили мітки рядків r[i]та мітки стовпців, c[j]щоб кожен запис матриці M[i][j]був добутком відповідних міток як M[i][j] = r[i] * c[j].

Вхід:

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

Матриця може бути не квадратною. Він матиме принаймні один ненульовий запис - вам не доведеться мати справу з порожніми або нульовими матрицями.

Можна припустити, що цілі числа не спричинять проблем із переповненням.

Вихід:

Послідовне значення для матриць першого рангу та інше послідовне значення для інших матриць.

Вбудовані:

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

Тестові приклади:

Перший ранг:

[[2, 0, -20, 10], [-3, 0, 30, -15], [0, 0, 0, 0]]
[[0, 0, 0], [0, 3, 0], [0, 0, 0]]
[[-10]]
[[0, 0, 0], [0, 4, 11], [0, -4, -11]]

Не перший ранг:

[[-2, 1], [2, 4]]
[[0, 0, 3], [-22, 0, 0]]
[[1, 2, 3], [2, 4, 6], [3, 6, 10]]
[[0, -2, 0, 0], [0, 0, 0, 1], [0, 0, -2, 0]]

Табло:


2
Для допитливих відповідь Mathematica з використанням вбудованих файлів виглядатиме так (16 байт):MatrixRank@#==1&
JungHwan Min


2
Прекрасна теорема полягає в тому, що стовпчик стовпців дорівнює рангу рядків для кінцевих розмірних матриць.
Leaky Nun

3
Чи потрібно турбуватися про проблеми з точністю поплавця? Вони можуть зробити ранг-1 матрицю здається ранг 2, наприклад
Луїс Mendo

@LuisMendo Вам доведеться вирішувати питання точності, як власне значення 1.0000000001, але можна припустити, що матриця не є великою і спеціально не обрана для неправильної класифікації.
xnor

Відповіді:


13

Желе , 6 байт

ẸÐfÆrE

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

Як це працює

ẸÐfÆrE  Main link. Argument: M (2D array)

ẸÐf     Filter by any, removing rows of zeroes.
   Ær   Interpret each row as coefficients of a polynomial and solve it over the
        complex numbers.
     E  Test if all results are equal.

Точність

Ærвикористовує числові методи, тому його результати, як правило, неточні. Наприклад, вхідний [6, -5, 1] , який представляє собою многочлен 6 - 5x + x² , призводить до коріння 3.0000000000000004 і 1.9999999999999998 . Однак множення всіх коефіцієнтів многочлена на ту саму ненульову константу призводить до однаково неточних коренів. Наприклад, Ærотримують однакові корені для [6, -5, 1] та [6 × 10 100 , -5 × 10 100 , 10 100 ] .

Слід зазначити, що обмежена точність поплавця та складних типів може призвести до помилок. Наприклад, Ærотримали б однакові корені для [1, 1] та [10 100 , 10 100 + 1] . Оскільки ми можемо припустити, що матриця не велика і спеціально не обрана для неправильної класифікації , це повинно бути добре.


5
Помноження всіх коефіцієнтів многочлена на ту саму ненульову константу призводить до однаково неточних коренів. Це геніальний підхід
Луїс Мендо

8

Haskell , 50 байт

rприймає список списків Integers і повертається, Falseякщо матриця має ранг один, Trueінакше.

r l=or[map(x*)b<map(y*)a|a<-l,b<-l,(x,y)<-zip a b]

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

Як це працює

  • Створює всі пари рядків aі b(включаючи рівні рядки), а для кожної пари давайте пропускаємо xі yпропускаємо відповідні елементи.
  • Помножує рядок bна xі рядок aна y. Матриця матиме ранг одне тоді і лише тоді, коли результати завжди рівні.
  • Оскільки пари генеруються в обох порядках, <їх можна використовувати для перевірки наявності нерівності. Список результатів тесту комбінується із orзазначенням Trueнаявності будь-яких непропорційних рядків.

7

Математика, 51 33 байт

RowReduce@#~Count~Except@{0..}<2&

Вхідні дані

[{{2,0, -20,10}, {- 3,0,30, -15}, {0,0,0,0}}]

-14 байт від користувача202729 Ще
3 байти, збережені від junghwanmin


Я пропоную, замість того, щоб побудувати таблицю з довжиною, рівною довжині First@#, ви можете обчислити, 0First@#оскільки 0 множиться на все, що дорівнює 0, і множення є списком. Також ви можете розглянути Tr[1^<list>]можливість розрахунку довжини списку.
користувач202729

дуже приємно. Я редагую!
J42161217

Замість того 0#&@@#, {0..}буде працювати теж. А потім Infixпрацює, тож кінцевий код міг би бути RowReduce@#~Count~{0..}==Tr[1^#]-1&, економлячи 2 байти.
JungHwan Min

Насправді, Exceptможна використовувати для позбавлення від Trречей. -3 байти:RowReduce@#~Count~Except@{0..}==1&
JungHwan Min

Я думаю, що матриця з обмеженими рядками гарантовано буде ненульовою (тому що початкова матриця - ненульова), тому результат підрахунку буде цілим числом, а тому <2замість цього ==1.
користувач202729

4

JavaScript (ES6), 68 67 65 байт

Цей заснований на відповіді Ніла 05AB1E і значно ефективніший, ніж мій оригінальний підхід.

Повертається falseдо першого чину та trueіншим чином.

f=(a,R,V,X)=>a.some(r=>r.some((v,x)=>R?v*V-r[X]*R[x]:f(a,r,v,x)))

Тестові кейси


Оригінальна відповідь, 84 байти

Повертається falseдо першого чину та trueіншим чином.

a=>a.some(r=>r.some((x,i)=>(isNaN(x/=a.find(r=>r.some(x=>x))[i])?r:1/r[0]?r=x:x)-r))

Тестові кейси

Як?

a => a.some(r =>          // given a matrix a, for each row r of a:
  r.some((x, i) =>        //   for each value x of r at position i:
    (                     //
      isNaN(x /=          //     divide x by a[ref][i]
        a.find(r =>       //       where ref is the index of the first row that
          r.some(x => x)  //       contains at least one non-zero value
        )[i]              //       (guaranteed to exist by challenge rules)
      ) ?                 //     we get NaN for 0/0, in which case:
        r                 //       use r, so that this column is ignored
      :                   //     else:
        1 / r[0] ?        //       if r is still holding the current row:
          r = x           //         set it to x (either a float, +Inf or -Inf)
        :                 //       else:
          x               //         use x
    ) - r                 //     subtract r from the value set above (see table)
  )                       //   end of some()
)                         // end of every()

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

A                   | B              | A - B       | False / True
--------------------+----------------+-------------+-------------
array of 1 number   | same array     | 0           | False
array of 2+ numbers | same array     | NaN         | False
a number            | same number    | 0           | False
+Infinity           | +Infinity      | NaN         | False
-Infinity           | -Infinity      | NaN         | False
a number            | another number | <> 0        | True
+Infinity           | -Infinity      | +Infinity   | True
-Infinity           | +Infinity      | -Infinity   | True
a number            | +/-Infinity    | +/-Infinity | True
+/-Infinity         | a number       | +/-Infinity | True

Тест не пройдений , як тільки ми отримаємо значення truthy: це відбувається , коли ми стикаємося два різних коефіцієнтів (крім 0/0 ) між а (х, у) і а (I, R) в будь-якому рядку у матриці, де r - індекс ненульового рядка.


Ага, мені було просто цікаво, що я сам ...
Ніл

@Neil Чи хотіли б ви опублікувати це як нову відповідь? Просто дайте мені знати.
Арнольд


3

Желе , 12 байт

ẸÐfµ÷"ЀZE€Ẹ

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

Пояснення

ẸÐfµ÷"ЀZE€Ẹ  Main link
 Ðf           Filter; keep all elements where
Ẹ             At least one element is truthy (remove zero-rows)
      Ѐ      For each row on the right side
    ÷"        Divide it by each row in the original
        Z     Zip the array
          €   For each submatrix
         E    Are all rows equal?
           Ẹ  Is at least one of the elements from above truthy?

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

-5 байт завдяки милям


... Ваш код пристрастився до грошей. (Я отримую дежавю ...)
абсолютнолюдський

@icrieverytim Ей, принаймні кількість знаків долара цього разу менше половини довжини коду! : P
HyperNeutrino

1
@icrieverytim виправив помилку і тепер навіть менше знаків долара: P
HyperNeutrino

Я вважаю, що це також має працювати на 12 байт ẸÐfµ÷"ЀZE€Ẹ TIO
миль

@miles О, приємно! Підхід для вашого трішки інший (я думаю?), Тож ви можете розмістити це як власну відповідь, яку б вам хотілося :)
HyperNeutrino

3

05AB1E , 16 байт

2ãεø2ãε`R*`Q}W}W

Спробуйте в Інтернеті! Використовує властивість таблиці множення, що протилежні кути будь-якого прямокутника мають однаковий добуток. Пояснення:

2ãε           }     Loop over each pair of rows
   ø                Transpose the pair into a row of pairs
    2ãε     }       Loop over each pair of columns
       `R*`Q        Cross-multiply and check for equality
             W W    All results must be true

3

TI-Basic (серія TI-83), 28 27 28 байт (62 символи)

:Prompt [A]
:{0→X
:Matr►list(ref([A])ᵀ,L₁,X
:not(max(abs(ᶫX

Обчислює рядково-ешелонну форму матриці [A], зберігає її перший рядок (який слід відкинути) у L₁та другий рядок у ᶫX. Тоді max(abs(ᶫXбуде нуль, якщо ᶫXскладається тільки з нулів, і додатне значення в іншому випадку, яке not(змінюється на 1, якщо матриця є рангом один, 0 в іншому випадку.

Для 1-рядкової матриці ᶫXвстановлено значення, {0}а потім не змінюється, коли ми намагаємося подивитися на неіснуючий другий рядок матриці.


-1 байт завдяки Скотту Мілнеру

+1 байт, щоб виправити помилку розмірів для матриць 1 рядка. Виявляється, Matr►list( команда скаржиться, якщо ви намагаєтеся витягти другий рядок з матриці лише з одним рядком; однак, якщо ви спробуєте витягнути перший і другий ряд з матриці, він мовчить невдало.


1
Ви можете зберегти байт за допомогою, Prompt [A]а не Ans→[A].
Скотт Мілнер

@ScottMilner Дякую! Мабуть, є спосіб уникнути будь-якого випадку, якщо ми використаємо щось на кшталт ClrListініціалізації ᶫX, але я не зовсім сприйняв це для роботи в меншому просторі.
Міша Лавров

Позбудьтесь другого рядка, оскільки Matr►list(перезапишете список, навіть якщо його не існує, і ви збережете 5 байт.
kamoroso94

1
@ kamoroso94 Точка другого рядка полягає не у створенні списку, коли його не існує: точка другого рядка полягає у створенні значення за замовчуванням для другого ряду, коли матриця містить лише один рядок. Якщо ви позбудетесь другого рядка, код виходить з ладу для матриць 1xN.
Міша Лавров

2
@ kamoroso94 Нам доведеться замінити L1 на ᶫY, а не Y; в іншому випадку калькулятор подумає "витягнути Y-й рядок матриці до ᶫX", а не "витягнути перший рядок до ᶫY, а другий рядок - ᶫX".
Міша Лавров

3

Брахілог , 27 байт

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ

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

Використовує підхід Ніла про "продукти протилежних кутів кожного прямокутника повинні бути рівними". Перехресний продукт коштує дорого і займає 10 цілих байт, але це все-таки коротше, ніж будь-який підхід, заснований на поділі, який я намагався, головним чином, через встановлення двох послідовних результатів для truthy та falsey у питанні - зробити фальси бути лише a false., а не іноді і помилка ділення на нуль, використовує занадто багато байтів.

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ
{⊇Ċ}ᶠ                        Get each pair of rows from the matrix
                             eg.: [ [[a, b, c], [k, l, m]], ... ]
     zᵐ                      Zip each pair's elements
                                  [ [[a, k], [b, l], [c, m]], ... ]
       {                 }ᵐ  Map this over each pair of rows:
                                  [[a, k], [b, l], [c, m]]
        ↰₁ᶠ                  Get each pair of paired elements from the rows
                                  [[[a, k], [b, l]], [[b, l], [c, m]], [[a, k], [c, m]]]
           {           }ᵐ    Map this over each pair of pairs
                                  [[a, k], [b, l]]
            ⟨hz{t↔}⟩         Zip the first pair with the reverse of the second
                                  [[a, l], [k, b]]
                    ×ᵐ       Multiply within each sublist
                                  [al, kb]
                      =      The results should be equal
                             (If the results are unequal for any pair, the whole predicate fails,
                              and outputs false.)

Альтернативний підхід на основі елементарного поділу ( 30 байт ):

{≡ᵉ¬0&}ˢ\↰₁ˢ{c׬0&⟨hz∋⟩ᶠ/ᵐ²=ᵐ}

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



1

SageMath, 40 байт

lambda M:any(M.rref()[1:])*(M.nrows()>1)

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

Ця анонімна функція повертається, Falseякщо матриця є першим рангом, Trueінакше.

Функція приймає матрицю Mяк вхідний, перетворює її у зменшену ешелонну форму ( M.rref()) і тестує anyрядки, які минули за першим, що не має нуля. Потім це значення помножується на M.nrows()>1(чи має матриця більше одного рядка?).


1

Python 3 , 93 91 байт

lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))

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

Як це працює

Перевіряє, чи є у 2 другорядних ненульовий детермінант. У цьому випадку ранг повинен бути принаймні 2: "Не зникаючий p-мінор (підматриця p × p з ненульовим визначником) показує, що рядки та стовпці цієї підматриці лінійно незалежні, і, отже, ці рядки та стовпці повної матриці лінійно незалежні (у повній матриці), тому рядки рядків і стовпців принаймні такі ж великі, як і детермінантний ранг "(з Вікіпедії )

Примітка: поголений два байти завдяки коментарю user71546.


1
91 - коротше, якщо перерахувати аргументи функції і тим самим усунути необхідність f=:lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))
Шиеру Асакото

@ user71546 Дякую! Зробив це!
Лука Сіті

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.