• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Obliczanie wyznacznika macierzy kwadratowej

Object Storage Arubacloud
0 głosów
503 wizyt
pytanie zadane 20 września 2021 w JavaScript przez qax Dyskutant (8,060 p.)
edycja 20 września 2021 przez qax

No i tym razem ja mam problem. Jestem w trakcie pisania aplikacji w JavaScriptcie do wykonywania różnych obliczeń na macierzach. Oczywiście, nie ma żadnego problemu znaleźć w sieci gotowe algorytmy obliczające m.in. wyznacznik macierzy kwadratowej, które zwracają gotowy wynik i działają poprawnie. Jednak ja chciałem stworzyć coś bardziej złożonego, tzn. wyświetlający kolejne kroki obliczeń wyznacznika macierzy - jako pomoc dla studentów na egzaminach smiley. Niestety mam problem z rekursywnie wywoływaną funkcją determinant(), która choć zwraca prawidłowy końcowy wynik to nie podaje prawidłowych macierzy w przebiegu kolejnych kroków obliczeń. Gdybym był w posiadaniu (lecz nie mogłem znaleźć go w internecie) algorytmu bez rekursji (tj. w formie obliczeń iteracyjnych) takie dziwne rzeczy by się już nie działy bo wiedziałbym jak ten algorytm odpowiednio wykorzystać. Poniżej podaję fragmenty zrzutów ekranu jak ta sprawa wygląda:

Nie zamieszczam tutaj kodu, ze względu na jego obszerność - zapraszam natomiast to zapoznania się z wersją demo na JSFiddle: https://jsfiddle.net/sx4m1c7L/. Będę bardzo wdzięczny za pomoc, chciażby w przetłumaczeniu tej rekursji na obliczanie w pętli, bo ja już wymiękam. Podkreślam, że kod jest i będzie open source na GitHubie i pomożecie wielu innym osobom nie tylko w programowaniu ale w rozwiązywaniu zadań z macierzami. Dzięki.

komentarz 21 września 2021 przez qax Dyskutant (8,060 p.)

A byłby ktoś w stanie chociaż zminić tą rekursywnie wywoływaną funkcję na iterację? To by mi bardzo ułatwio sprawę:

function determinant(inputMatrix, dim) {
  var det = 0, subDet = 0, subDim = dim;
  var subMatrix = new Array(10);
  for (var loop1 = 0; loop1 < subMatrix.length; loop1++) {
    subMatrix[loop1] = new Array(10);
    for (var loop2 = 0; loop2 < subMatrix[loop1].length; loop2++) {
      subMatrix[loop1][loop2] = 0;
    }
  }
  if (dim == 1) {
    return inputMatrix[0][0];
  } else if (dim == 2) {
    return ((inputMatrix[0][0] * inputMatrix[1][1]) - (inputMatrix[1][0] * inputMatrix[0][1]));
  } else {
    for (var loop1 = 0; loop1 < dim; loop1++) {
      var subi = 0;
      for (var loop2 = 1; loop2 < dim; loop2++) {
        var subj = 0;
        for (var loop3 = 0; loop3 < dim; loop3++) {
          if (loop3 == loop1) {
            continue;
          }
          subMatrix[subi][subj] = inputMatrix[loop2][loop3];
          subj++;
        }
        subi++;
      }
      subDet = det;
      // ta poniższa rekursja utrudnia mi sprawę :-(
      det = subDet + (Math.pow(-1, loop1) * inputMatrix[0][loop1] * determinant(subMatrix, dim - 1));
    }
  }
  return det;
}

var matrix = [[3, 5, 1], [8, 0, 4], [9, 7, 1]];
alert(determinant(matrix, 3));

1 odpowiedź

+1 głos
odpowiedź 21 września 2021 przez overcq Pasjonat (21,650 p.)
wybrane 22 września 2021 przez qax
 
Najlepsza

https://jsfi­d­dle.net/84tx52bj/

Te­raz dzia­ła?

Nie wiem po co tam by­ło su­bDim zmniej­sza­ne o je­den w pę­t­li, gdy dim się nie zmie­nia­ło.

Jak jest napisane w https://en.wikipedia.org/wiki/Determinant#n_%C3%97_n_matrices do obliczenia w pętli trzeba by generować wszystkie permutacje od 1 do n (rozmiar macierzy), obliczać dla nich iloczyn wartości z tych indeksów i sumować. Więc obliczanie w pętli sprowadza się głównie do zrobienia funkcji obliczania następnej permutacji.

komentarz 22 września 2021 przez qax Dyskutant (8,060 p.)
Aha, teraz rozumiem, dzięki! No jak widać niektórzy programiści nie są dobrymi matematykami. A tak poza tym, to każdy krok obliczeń mogę rozbić na szczegółowe podkroki np. Krok 1A, 1B itd. bo dodałeś w nawiasie w kodzie wyniki det macierzy wciąż "dużych wymiarowo", których wyznaczniki też trzeba obliczyć swoją drogą, tak?
komentarz 22 września 2021 przez overcq Pasjonat (21,650 p.)

Metoda, którą stosujesz jest opisana na wymienionej stronie Wikipedii pod tytułem Laplace expansion. Z tym że dla n = 1 i n = 2 są zastosowane wzory skrócone.

Tak, wyznacznik większej tablicy oblicza się tą metodą przez mnożenie kolejnych wartości z pierwszego rzędu macierzy przez wyznaczniki mniejszych macierzy (utworzonych z pominięciem kolumny bieżącej wartości). Tworzenie tych mniejszych macierzy masz w pętlach ze zmiennymi loop2 (rząd) i loop3 (kolumna), podczas gdy pętla z loop1 (kolumna) wybiera wartość z pierwszego rzędu macierzy.

Podobne pytania

0 głosów
1 odpowiedź 622 wizyt
pytanie zadane 20 marca 2020 w C i C++ przez dominik195k Obywatel (1,030 p.)
0 głosów
1 odpowiedź 173 wizyt
pytanie zadane 22 listopada 2015 w C i C++ przez arglo Nowicjusz (140 p.)
0 głosów
1 odpowiedź 2,507 wizyt
pytanie zadane 11 października 2015 w Inne języki przez Mateep Użytkownik (850 p.)

92,555 zapytań

141,404 odpowiedzi

319,560 komentarzy

61,941 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...