Yếu tố quyết định của ma trận nguyên


34

Cho một ma trận số nguyên vuông làm đầu vào, xuất ra định thức của ma trận.

Quy tắc

  • Bạn có thể giả sử rằng tất cả các phần tử trong ma trận, định thức của ma trận và tổng số phần tử trong ma trận nằm trong phạm vi số nguyên có thể biểu thị cho ngôn ngữ của bạn.
  • Xuất ra một giá trị thập phân / float với một phần phân số bằng 0 được cho phép (ví dụ 42.0thay vì 42).
  • Nội dung được cho phép, nhưng bạn được khuyến khích đưa vào một giải pháp không sử dụng nội dung.

Các trường hợp thử nghiệm

[[42]] -> 42
[[2, 3], [1, 4]] -> 5
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] -> 0
[[13, 17, 24], [19, 1, 3], [-5, 4, 0]] -> 1533
[[372, -152, 244], [-97, -191, 185], [-53, -397, -126]] -> 46548380
[[100, -200, 58, 4], [1, -90, -55, -165], [-67, -83, 239, 182], [238, -283, 384, 392]] -> 571026450
[[432, 45, 330, 284, 276], [-492, 497, 133, -289, -28], [-443, -400, 56, 150, -316], [-344, 316, 92, 205, 104], [277, 307, -464, 244, -422]] -> -51446016699154
[[416, 66, 340, 250, -436, -146], [-464, 68, 104, 471, -335, -442], [159, -407, 310, -489, -248, 370], [62, 277, 446, -325, 47, -193], [460, 460, -418, -28, 234, -374], [249, 375, 489, 172, -423, 125]] -> 39153009069988024
[[-246, -142, 378, -156, -373, 444], [186, 186, -23, 50, 349, -413], [216, 1, -418, 38, 47, -192], [109, 345, -356, -296, -47, -498], [-283, 91, 258, 66, -127, 79], [218, 465, -420, -326, -445, 19]] -> -925012040475554
[[-192, 141, -349, 447, -403, -21, 34], [260, -307, -333, -373, -324, 144, -190], [301, 277, 25, 8, -177, 180, 405], [-406, -9, -318, 337, -118, 44, -123], [-207, 33, -189, -229, -196, 58, -491], [-426, 48, -24, 72, -250, 160, 359], [-208, 120, -385, 251, 322, -349, -448]] -> -4248003140052269106
[[80, 159, 362, -30, -24, -493, 410, 249, -11, -109], [-110, -123, -461, -34, -266, 199, -437, 445, 498, 96], [175, -405, 432, -7, 157, 169, 336, -276, 337, -200], [-106, -379, -157, -199, 123, -172, 141, 329, 158, 309], [-316, -239, 327, -29, -482, 294, -86, -326, 490, -295], [64, -201, -155, 238, 131, 182, -487, -462, -312, 196], [-297, -75, -206, 471, -94, -46, -378, 334, 407, -97], [-140, -137, 297, -372, 228, 318, 251, -93, 117, 286], [-95, -300, -419, 41, -140, -205, 29, -481, -372, -49], [-140, -281, -88, -13, -128, -264, 165, 261, -469, -62]] -> 297434936630444226910432057


Có kích thước tối đa của ma trận cần được hỗ trợ hay là tùy ý?
Taylor Scott

1
@TaylorScott Quy tắc đầu tiên được liệt kê:You may assume that all elements in the matrix, the determinant of the matrix, and the total number of elements in the matrix are within the representable range of integers for your language.
Mego

4
Bạn biết rằng bạn có một thử thách thú vị khi bạn có 4 câu trả lời Jelly liên tiếp ra ngoài chơi gôn ...
hoàn toàn là

Câu trả lời:


25

Thạch , 15 byte

LŒ!ðŒcIṠ;ị"Pð€S

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

LŒ!ðŒcIṠ;ị"Pð€S   input
L                 length
 Œ!               all_permutations
   ð        ð€    for each permutation:
    Œc                take all unordered pairs
      I               calculate the difference between
                      the two integers of each pair
       Ṡ              signum of each difference
                      (positive -> 1, negative -> -1)
        ;             append:
         ị"             the list of elements generated by taking
                        each row according to the index specified
                        by each entry of the permutation
           P          product of everything
              S   sum

Tại sao nó hoạt động - phiên bản toán học

Toán tử det lấy một ma trận và trả về một vô hướng. Một n -by- n ma trận có thể được coi như một bộ sưu tập của n vectơ có độ dài n , vì vậy det thực sự là một chức năng mà mất n vectơ từ ℤ n và trả về một đại lượng vô hướng.

Do đó, tôi viết det ( v 1 , v 2 , v 3 , ..., v n ) cho det [ v 1 v 2 v 3 ... v n ].

Lưu ý rằng det là tuyến tính trong mỗi đối số, tức là det ( v 1 + w 1 , v 2 , v 3 , ..., v n ) = det ( v 1 , v 2 , v 3 , ..., v n ) + λ det ( w 1 , v 2 , v 3 , ..., v n ). Vì vậy, nó là một biến đổi tuyến tính từ (ℤ n ) n đến ℤ.

Nó đủ để xác định hình ảnh của cơ sở dưới bản đồ tuyến tính. Cơ sở của ( n ) n bao gồm n sản phẩm tenxơ của các phần tử cơ bản của ℤ n , ieeg e 5 ⊗ e 3 ⊗ e 1 e 5 ⊗ e 1 . Các sản phẩm tenor bao gồm các tenxơ giống hệt nhau phải được gửi về 0, vì định thức của ma trận trong đó hai cột giống hệt nhau là 0. Nó vẫn còn để kiểm tra những gì các sản phẩm tenor của các yếu tố cơ bản riêng biệt được gửi đến. Các chỉ số của vectơ trong sản phẩm tenxơ tạo thành một mệnh đề, nghĩa là hoán vị, trong đó các hoán vị thậm chí được gửi đến 1 và hoán vị lẻ được gửi đến -1.

Ví dụ: để tìm định thức của [[1, 2], [3, 4]]: lưu ý rằng các cột là [1, 3] và [2, 4]. Chúng tôi phân tách [1, 3] để cho (1 e 1 + 3 e 2 ) và (2 e 1 + 4 e 2 ). Phần tử tương ứng trong sản phẩm tenxơ là (1 e 1 2 e 1 + 1 e 1 ⊗ 4 e 2 + 3 e 2 2 e 1 + 3 e 2 4 e 2 ), chúng tôi đơn giản hóa thành (2 e 1 1 e 1 + 4 e 1 ⊗ e 2 + 6 e 2 e 1 + 12 e 2 e 2). Vì thế:

det [[1, 2], [3, 4]]
= det (1 e 1 + 3 e 2 , 2 e 1 + 4 e 2 )
= det (2 e 1 ⊗ e 1 + 4 e 1 ⊗ e 2 + 6 e 2 ⊗ e 1 + 12 e 2 e 2 )
= det (2 e 1 ⊗ e 1 ) + det (4 e 1 e 2 ) + det (6 e 2 e 1 ) + det (12 e2 ⊗ e 2 )
= 2 det (e 1 e 1 ) + 4 det (e 1 ⊗ e 2 ) + 6 det (e 2 e 1 ) + 12 det (e 2 e 2 )
= 2 (0) + 4 (1) + 6 (-1) + 12 (0)
= 4 - 6
= -2

Bây giờ vẫn còn phải chứng minh rằng công thức tìm tính chẵn lẻ của hoán vị là hợp lệ. Những gì mã của tôi làm về cơ bản là tìm số lượng đảo ngược, tức là những nơi mà một phần tử bên trái lớn hơn một phần tử bên phải (không nhất thiết phải liên tiếp).

Ví dụ, trong hoán vị 3614572, có 9 nghịch đảo (31, 32, 61, 64, 65, 62, 42, 52, 72), do đó hoán vị là số lẻ.

Sự biện minh là mỗi lần hoán vị (hoán đổi hai yếu tố) hoặc thêm một lần đảo ngược hoặc lấy đi một phép đảo ngược, hoán đổi tính chẵn lẻ của số lần đảo ngược và tính chẵn lẻ của phép hoán vị là tính chẵn lẻ của số lần hoán vị cần thiết để đạt được hoán vị.

Do đó, kết luận, công thức của chúng tôi được đưa ra bởi:

Tại sao nó hoạt động - phiên bản phi toán học

nơi σ là một hoán vị của 𝕊 n nhóm của tất cả các hoán vị trên n chữ cái, và sgn là dấu hiệu của sự hoán vị, AKA (-1) được nâng theo tính chẵn lẻ của các hoán vị, và một ij là ( ij ) thứ mục trong ma trận ( i xuống, j ngang).


17
Đó là "phiên bản phi toán học" khá là toán học.
MD XF

6
@MDXF công thức và ký hiệu và số hầu như không tạo thành toán học. Toán học là sự trừu tượng và khái quát hóa và logic đằng sau các thao tác chính thức của các biểu tượng.
Leaky Nun

7
@JAB Jelly thực hiện trang mã tùy chỉnh của riêng mình . (Một trong những ngày này, TIO sẽ bao gồm một liên kết đến trang mã ...)
hoàn toàn là

1
@Mego "tổng sản phẩm chéo" chỉ hoạt động cho ma trận 1x1, 2x2 và 3x3. Đối với ma trận lớn hơn, bạn cần xem xét tất cả các hoán vị và tính chẵn lẻ của chúng.
Leaky Nun

3
+1 thực sự bao gồm bằng chứng trong bài thay vì nói "bởi vì công thức này được liệt kê trên trang abcxyz nên nó phải đúng".
dùng202729

11

R , 3 byte

Giải pháp tầm thường

det

Hãy thử trực tuyến!

R , 94 92 byte

thực hiện lại giải pháp

vượt trội bởi Jarko Dubbeldam

d=function(m)"if"(x<-nrow(m),m[,1]%*%sapply(1:x,function(y)(-1)^(y-1)*d(m[-y,-1,drop=F])),1)

Hãy thử trực tuyến!

Sử dụng đệ quy mở rộng bởi các vị thành niên xuống cột đầu tiên của ma trận.

f <- function(m){
 x <- nrow(m)                 # number of rows of the matrix
 if(sum(x) > 1){              # when the recursion reaches a 1x1, it has 0 rows
                              # b/c [] drops attributes
  minor <- function(y){
   m[y] * (-1)^(y-1) *
   d(m[-y,-1])                # recurse with the yth row and first column dropped
   }
  minors <- sapply(1:x,minor) # call on each row
  sum(minors)                 # return the sum
 } else {
  m                           # return the 1x1 matrix
 }
}



9

Thạch , 16 15 12 10 byte

Ḣ×Zß-Ƥ$Ṛḅ-

Sử dụng mở rộng Laplace . Cảm ơn @miles đã chơi golf 3 5 byte!

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Ḣ×Zß-Ƥ$Ṛḅ-  Main link. Argument: M (matrix / 2D array)

Ḣ           Head; pop and yield the first row of M.
      $     Combine the two links to the left into a monadic chain.
  Z         Zip/transpose the matrix (M without its first row).
   ß-Ƥ      Recursively map the main link over all outfixes of length 1, i.e., over
            the transpose without each of its rows.
            This yields an empty array if M = [[x]].
 ×          Take the elementwise product of the first row and the result on the
            right hand. Due to Jelly's vectorizer, [x] × [] yields [x].
       Ṛ    Reverse the order of the products.
        ḅ-  Convert from base -1 to integer.
                [a]          -> (-1)**0*a
                [a, b]       -> (-1)**1*a + (-1)**0*b = b - a
                [a, b, c]    -> (-1)**2*a + (-1)**1*b + (-1)**0*c = c - b + a
                etc.

8

Ngôn ngữ Wolfram (Mathicala) , từ 14 đến 42 byte

Chúng tôi đã có một giải pháp tích hợp 3 byte và một giải pháp 53 byte hoàn toàn tránh được tích hợp sẵn, vì vậy đây là một số giải pháp kỳ lạ ở đâu đó ở giữa.

Ngôn ngữ Wolfram có rất nhiều chức năng rất mãnh liệt để phân tách ma trận thành các sản phẩm của các ma trận khác có cấu trúc đơn giản hơn. Một trong những điều đơn giản hơn (có nghĩa là tôi đã nghe về nó trước đây) là phân rã Jordan. Mọi ma trận đều tương tự như ma trận tam giác trên (có thể có giá trị phức tạp) được tạo thành từ các khối đường chéo có cấu trúc cụ thể, được gọi là phân rã Jordan của ma trận đó. Độ tương tự bảo toàn các định thức và định thức của ma trận tam giác là tích của các phần tử đường chéo, vì vậy chúng ta có thể tính toán định thức với 42 byte sau:

1##&@@Diagonal@Last@JordanDecomposition@#&

Hệ số xác định cũng bằng tích của các giá trị riêng của ma trận, với bội số. May mắn thay, hàm eigenvalue của Wolfram theo dõi bội số (ngay cả đối với các ma trận không có đường chéo), vì vậy chúng tôi nhận được giải pháp 20 byte sau:

1##&@@Eigenvalues@#&

Giải pháp tiếp theo là loại gian lận và tôi không thực sự chắc chắn tại sao nó hoạt động. Wronskian của một danh sách các hàm n là định thức của ma trận của các đạo hàm n -1 đầu tiên của các hàm. Nếu chúng ta cung cấp cho Wronskianhàm một ma trận các số nguyên và nói rằng biến số của sự khác biệt là 1, bằng cách nào đó nó sẽ tạo ra định thức của ma trận. Thật lạ, nhưng nó không liên quan đến các chữ cái " Det" và nó chỉ có 14 byte .

#~Wronskian~1&

(Công cụ xác định Casoratian cũng hoạt động, thêm 1 byte #~Casoratian~1&:)

Trong lĩnh vực đại số trừu tượng, yếu tố quyết định của một n  x  n ma trận (nghĩ như bản đồ k → k có nghĩa là nhân bởi yếu tố quyết định) là n thứ quyền lực bên ngoài của ma trận (sau khi chọn một đẳng cấu k → ⋀ n k n ). Trong ngôn ngữ Wolfram, chúng ta có thể làm điều này với 26 byte sau:

HodgeDual[TensorWedge@@#]&

Và đây là một giải pháp chỉ hoạt động cho các yếu tố quyết định tích cực. Nếu chúng ta lấy một n chiều hypercube đơn vị và áp dụng một biến đổi tuyến tính với nó, các n chiều "volume" của vùng kết quả là giá trị tuyệt đối của yếu tố quyết định của sự biến đổi. Áp dụng một phép biến đổi tuyến tính cho một khối lập phương cho một đường song song và chúng ta có thể lấy khối lượng của nó với 39 byte mã sau đây:

RegionMeasure@Parallelepiped[Last@#,#]&

1
Giải pháp tôi có dọc theo các dòng này là Exp@*Tr@*MatrixLog, nhưng thật không may, nó không hoạt động đối với các ma trận đơn lẻ.
Misha Lavrov

1
@MishaLavrov Ooh, thật thông minh! Tôi nghĩ bạn có thể sửa nó với Check[E^Tr@MatrixLog@#,0]&.
Không phải là một cái cây

Thật tuyệt! Tôi đã không nhận thức được Checktrước đó.
Misha Lavrov

1
Tôi đã tạo ra một thử thách cho Jordan Decysis một lúc trước. Bạn có thể quan tâm đến nó, quá. Thật là một câu trả lời tuyệt vời!
Mego

8

Haskell , 71 byte

-3 byte nhờ Lynn. Một số khác bụi nhờ có Craig Roy.

f[]=1
f(h:t)=foldr1(-)[v*f[take i l++drop(i+1)l|l<-t]|(i,v)<-zip[0..]h]

Hãy thử trực tuyến! Đã thêm -Ocờ cho mục đích tối ưu hóa. Nó không phải là cần thiết.

Giải thích (lỗi thời)

f đệ quy thực hiện mở rộng đồng yếu tố.

f[[x]]=x

Dòng này bao gồm các trường hợp cơ sở của một 1 × 1 ma trận, trong trường hợp yếu tố quyết định là mat[0, 0].

f(h:t)=

Điều này sử dụng khớp mẫu của Haskell để phá ma trận thành một đầu (hàng đầu tiên) và đuôi (phần còn lại của ma trận).

          [                                     |(i,v)<-zip[0..]h]

Liệt kê phần đầu của ma trận (bằng cách nén danh sách vô hạn của toàn bộ số và phần đầu) và lặp lại trên nó.

           (-1)*i*v

Phủ định kết quả dựa trên việc chỉ số của nó có ngay cả khi tính toán xác định liên quan đến phép cộng và phép trừ xen kẽ.

                     [take i l++drop(i+1)l|l<-t]

Điều này về cơ bản sẽ loại bỏ cột thứ i của đuôi bằng cách lấy các phần tử i và nối nó với hàng với các phần tử thứ nhất (i + 1) được thả cho mỗi hàng ở đuôi.

                   *f

Tính hệ số xác định của kết quả trên và nhân nó với kết quả của (-1)*i*v.

       sum

Tính tổng kết quả của danh sách trên và trả lại.


2
bạn có thể tiết kiệm 1 byte nếu thay thế sum[(-1)^i*...bằngfoldr(-)0[...
Craig Roy

6

Proton , 99 byte

f=m=>(l=len(m))==1?m[0][0]:sum((-1)**i*m[0][i]*f([[m[k][j]for k:1..l]for j:0..l if j-i])for i:0..l)

Hãy thử trực tuyến!

-3 byte nhờ ông Xcoder
-3 byte nhờ Erik the Outgolfer

Mở rộng trên hàng đầu tiên


Chỉ vì Proton không có nội dung xác định.
dùng202729

103 byte . ((~i%2)*2-1)->((-i%2)|1)
Ông Xcoder

Cũng 102 byte bằng cách thay thế j!=ibằng j-ihoặc i-j.
Ông Xcoder


@EriktheOutgolfer À đúng rồi, cảm ơn!
HyperNeutrino

5

Octave , 28 byte

@(x)round(prod(diag(qr(x))))

Hãy thử trực tuyến!

Điều này sử dụng phân rã QR của ma trận X thành ma trận vuông góc Q và ma trận tam giác R trên . Các yếu tố quyết định của X là sản phẩm của những người trong QR . Một ma trận trực giao có định thức đơn vị và đối với ma trận tam giác, định thức là tích của các mục chéo của nó. Octave của qrhàm được gọi với một đầu ra duy nhất cho R .

Kết quả được làm tròn đến số nguyên gần nhất. Đối với ma trận đầu vào lớn, độ không chính xác của dấu phẩy động có thể tạo ra lỗi vượt quá 0.5và do đó tạo ra kết quả sai.


1
Đó là một cách thú vị để trốn tránh detnội dung. ;)
tomsmeding

1
@tomsmeding :-) Ngoài ra, nó đã được "sử dụng" trong câu trả lời của Stewie
Luis Mendo


5

C,  176  125 byte

Cảm ơn @ceilingcat vì đã chơi golf 42 byte và cảm ơn cả @Lynn và @Jonathan Frech vì đã tiết kiệm từng byte một!

d(M,n)int*M;{int i=n--,s=*M*!n,c,T[n*n];for(;i--;s+=M[i]*(1-i%2*2)*d(T,n))for(c=n*n;c--;T[c]=M[n-~c+c/n+(c%n>=i)]);return s;}

Tính toán định thức bằng cách sử dụng khai triển Laplace dọc theo hàng đầu tiên.

Hãy thử trực tuyến!

Chưa được kiểm soát:

d(M, n)int*M;
{
    int i=n--, s=*M*!n, c, T[n*n];
    for (; i--; s+=M[i]*(1-i%2*2)*d(T,n))
        for (c=n*n; c--;)
            T[c] = M[n-~c+c/n+(c%n>=i)];
    return s;
}

(i%2*-2+1)(1-i%2*2)lưu thêm một byte.
Lynn

n+1+ccó thể n-~c.
Jonathan Frech

Đề xuất i=sthay vìreturn s
trần mèo

5

Thạch , 43 byte

Cuối cùng tôi đã viết xong giải pháp không dựng sẵn của mình bằng ngôn ngữ chơi gôn!

ḣ⁹’’¤;ṫḊ€Ç×⁸ị@⁹’¤¤ḷ/¤
çЀ⁸J‘¤µJ-*×NS
ÇḢḢ$Ṗ?

Cảm ơn HyperNeutrino vì đã tiết kiệm một byte!

Hãy thử trực tuyến! (mã khoảng cách cho rõ ràng)

Cách cực kỳ dài để loại bỏ các yếu tố thứ n khỏi danh sách, sẽ cải thiện sau


Câu trả lời này đã vượt xa câu trả lời của HyperNeutrino, Dennis và Leaky Nun. Jelly rất phổ biến như một ngôn ngữ chơi golf.

Giải thích nhanh:

ÇḢḢ$Ṗ?    Main link.
     ?    If
    Ṗ     after remove the last element, the value is not empty (truthy)
Ç         then execute the last link
 ḢḢ$      else get the element at index [1, 1].

çЀ⁸J‘¤µJ-*×NS     Helper link 1, take input as a matrix.
çЀ                Apply the previous link, thread right argument to
   ⁸J‘¤            the range [2, 3, ..., n+1]
       µ           With the result,
        J-*        generate the range [-1, 1, -1, 1, ...] with that length
           ×N      Multiply by negative
             S     Sum

ḣ⁹’’¤;ṫḊ€Ç×⁸ị@⁹’¤¤ḷ/¤    Helper link 2, take left input as a matrix, right input as a number in range [2..n+1]
ḣ
 ⁹’’¤                    Take head ρ-2 of the matrix
     ;                   concatenate with 
      ṫ                  tail ρ (that is, remove item ρ-1)
       Ḋ€                Remove first column
         Ç               Calculate determinant of remaining matrix
          ×         ¤    multiply by
                  ḷ/     the first column,
            ị@           row #
              ⁹’¤        ρ-1 (just removed in determinant calculation routine) of
           ⁸     ¤       the matrix.

4

Thạch , 24 byte

œcL’$ṚÑ€
J-*×Ḣ€×ÇSµḢḢ$Ṗ?

Hãy thử trực tuyến!

Giải trình

œcL’$ṚÑ€         Helper Link; get the next level of subdeterminants (for Laplace Expansion)
œc               Combinations without replacement of length:
  L’$            Length of input - 1 (this will get all submatrices, except it's reversed)
     Ṛ           Reverse the whole thing
      р         Get the determinant of each of these
J-*×Ḣ€×ÇSµḢḢ$Ṗ?  Main Link
              ?  If the next value is truthy
             Ṗ   Remove the last element (truthy if the matrix was at least size 2)
J-*×Ḣ€×ÇSµ       Then expand
          ḢḢ$    Otherwise, get the first element of the first element (m[0][0] in Python)
J                [1, 2, ..., len(z)]
 -*              (-1 ** z) for each z in the length range
   ×             Vectorizing multiply with
    Ḣ€           The first element of each (this gets the first column); modifies each row (makes it golfier yay)
      ×Ç         Vectorizing multiply with the subdeterminants
        S        Sum

-2 byte nhờ giải pháp của user202729


4

MATL , 3 byte / 5 byte

Với chức năng tích hợp

&0|

Hãy thử trực tuyến!

Không tích hợp

Cảm ơn Misha Lavrov đã chỉ ra một lỗi, giờ đã sửa

YvpYo

Hãy thử trực tuyến!

Điều này tính toán định thức là sản phẩm của các giá trị riêng, được làm tròn đến số nguyên gần nhất để tránh sự thiếu chính xác của dấu phẩy động.

Yv       % Implicit input. Push vector containing the eigenvalues
p        % Product
Yo       % Round. Implicit display

Không phải sản phẩm của các giá trị số ít chỉ cho bạn biết giá trị tuyệt đối của định thức?
Misha Lavrov

@MishaLavrov Bạn hoàn toàn đúng! Cảm ơn đã chú ý. Tôi đã sửa nó bằng cách sử dụng các giá trị riêng thay vì các giá trị số ít ... và điều đó đã lưu 4 byte \ o /
Luis Mendo

4

R , 32 byte

function(m)Re(prod(eigen(m)$va))

Sử dụng Không phải là thuật toán của Tree để lấy giá trị riêng của ma trận và lấy phần thực của sản phẩm của họ.

Hãy thử trực tuyến!


Rất thanh lịch! +1.
Giuseppe


3

TI-Basic, 2 byte

det(Ans

À, tốt.

Xin đừng nêu lên những câu trả lời tầm thường.

Là một học sinh trung học (người buộc phải sở hữu một trong những máy tính này), chức năng này rất hữu ích vì vậy ...


8
Nó vẫn hữu ích ở trường đại học - đại số tuyến tính không biến mất
Taylor Scott

5
@TaylorScott Trên thực tế, nó trở lại với sự báo thù trong các phương trình vi phân.
Mego

@Mego - bạn nói đúng về điều đó; mặc dù vì một số lý do, họ đã để tôi lấy hết calc và trước tuyến tính: /
Taylor Scott

1
@TaylorScott Do sự giám sát của khoa toán của trường đại học của tôi, linalg không phải là điều kiện tiên quyết cho diffeq khi tôi lấy nó. Khi giáo sư của tôi nhận ra điều đó, anh ấy đã nhanh chóng cho chúng tôi một khóa học kéo dài 3 ngày ở linalg.
Mego

3

Haskell, 62 byte

a#((b:c):r)=b*d(a++map tail r)-(a++[c])#r
_#_=0
d[]=1
d l=[]#l

Hãy thử trực tuyến! (Footer với các trường hợp thử nghiệm được lấy từ giải pháp @ hoàn toàn của con người.)

dtính toán định thức bằng cách sử dụng khai triển Laplace dọc theo cột đầu tiên. Cần ba byte nhiều hơn vĩnh viễn .



3

Ngôn ngữ Wolfram (Mathicala) , 53 52 byte

1##&@@@(t=Tuples)@#.Signature/@t[Range@Tr[1^#]&/@#]&

Hãy thử trực tuyến!

Thật không may, tính toán các yếu tố quyết định của một n bởi n ma trận này sử dụng cách O ( n n ) bộ nhớ, trong đó đặt trường hợp thử nghiệm lớn ngoài tầm với.

Làm thế nào nó hoạt động

Phần đầu tiên 1##&@@@(t=Tuples)@#, tính toán tất cả các sản phẩm có thể có của một thuật ngữ từ mỗi hàng của ma trận đã cho. t[Range@Tr[1^#]&/@#]đưa ra một danh sách có cùng độ dài mà các yếu tố của nó là những thứ như {3,2,1}hoặc{2,2,3} cho biết mục nhập nào của mỗi hàng chúng tôi đã chọn cho sản phẩm tương ứng.

Chúng tôi áp dụng Signaturecho danh sách thứ hai, ánh xạ thậm chí hoán vị 1, hoán vị lẻ -1và không hoán vị0 . Đây chính xác là hệ số mà sản phẩm tương ứng xuất hiện trong định thức.

Cuối cùng, chúng tôi lấy sản phẩm chấm của hai danh sách.


Nếu thậm chí Signaturelà quá nhiều tích hợp, ở 73 byte chúng ta có thể lấy

1##&@@@(t=Tuples)@#.(1##&@@Order@@@#~Subsets~{2}&/@t[Range@Tr[1^#]&/@#])&

thay thế nó bằng 1##&@@Order@@@#~Subsets~{2}&. Điều này tính toán Signaturemột hoán vị có thể bằng cách lấy sản phẩm Orderáp dụng cho tất cả các cặp phần tử của hoán vị. Ordersẽ đưa ra 1nếu cặp theo thứ tự tăng dần, -1nếu nó theo thứ tự giảm dần và 0nếu chúng bằng nhau.


-1 byte nhờ @ user202729


1
52 byte (trong trường hợp bạn không biết mẹo chơi gôn
Mathicala này

Tôi đã làm, nhưng bằng cách nào đó quên nó ở đây. Cảm ơn!
Misha Lavrov

3

Python 3 , 238 byte , 227 byte , 224 byte , 216 byte

from functools import*
from itertools import*
r=range;n=len;s=sum
f=lambda l:s(reduce(lambda p,m:p*m,[l[a][b]for a,b in zip(r(n(l)),j)])*(-1)**s(s(y<j[x]for y in j[x:])for x in r(n(l)))for j in permutations(r(n(l))))

Hãy thử trực tuyến!

Giải pháp của tôi sử dụng định nghĩa của một yếu tố quyết định để tính toán. Thật không may, sự phức tạp của thuật toán này là n!và tôi không thể hiển thị đoạn văn của bài kiểm tra cuối cùng, nhưng trên lý thuyết thì điều này là có thể.


3

CJam ( 50 45 byte)

{:A_,{1$_,,.=1b\)/:CAff*A@zf{\f.*1fb}..-}/;C}

Đây là một khối ẩn danh (hàm) lấy một mảng 2D trên ngăn xếp và để lại một số nguyên trên ngăn xếp.

Bộ kiểm tra trực tuyến

Mổ xẻ

Điều này thực hiện thuật toán Faddeev-LeVerrier và tôi nghĩ đó là câu trả lời đầu tiên để thực hiện phương pháp đó.

ckn×nMột

p(λ)phát hiện(λtôin-Một)= =Σk= =0nckλk
cn= =1c0= =(-1)nphát hiệnMột

M

M00cn= =1(k= =0)MkMộtMk-1+cn-k+1tôicn-k= =-1ktr(MộtMk)k= =1,Giáo dục,n .

cn-kMk(-1)kcn-k(-1)k+1MộtMk

(-1)kcn-k= =1ktr((-1)k+1MộtMk)(-1)k+2MộtMk+1= =(-1)kcn-kMột-Một((-1)k+1MộtMk)

{               e# Define a block
  :A            e#   Store the input matrix in A
  _,            e#   Take the length of a copy
  {             e#     for i = 0 to n-1
                e#       Stack: (-1)^{i+2}AM_{i+1} i
    1$_,,.=1b   e#       Calculate tr((-1)^{i+2}AM_{i+1})
    \)/:C       e#       Divide by (i+1) and store in C
    Aff*        e#       Multiply by A
    A@          e#       Push a copy of A, bring (-1)^{i+2}AM_{i+1} to the top
    zf{\f.*1fb} e#       Matrix multiplication
    ..-         e#       Matrix subtraction
  }/
  ;             e#   Pop (-1)^{n+2}AM_{n+1} (which incidentally is 0)
  C             e#   Fetch the last stored value of C
}



2

SageMath , khác nhau

Dưới đây là một loạt các phương pháp để tính toán định thức mà tôi thấy thú vị, tất cả đều được lập trình trong SageMath. Tất cả đều có thể được thử ở đây .

Nội dung, 3 byte

det

Điều này không quá thú vị. Sage cung cấp bí danh cấp toàn cầu cho nhiều hoạt động phổ biến thường là phương thức đối tượng, vì vậy thời gian này ngắn hơn lambda m:m.det().


Phần thực của sản phẩm Eigenvalues, 36 byte

lambda m:real(prod(m.eigenvalues()))

Thật không may, eigenvalueskhông phải là một trong những bí danh cấp toàn cầu. Điều đó, kết hợp với thực tế là Sage không có cách sáng tác gọn gàng, nghĩa là chúng ta bị mắc kẹt với chi phí cao lambda. Hàm này có giá trị tượng trưng được tự động chuyển đổi thành giá trị số khi được in, do đó một số điểm không chính xác có thể xuất hiện trong một số đầu ra.


Sản phẩm của đường chéo ở dạng thường Jordan, 60 byte

lambda m:prod(m.jordan_form()[x,x]for x in range(m.nrows()))

Ở dạng Jordan Bình thường, ma trận NxN được biểu diễn dưới dạng ma trận khối, với N khối trên đường chéo. Mỗi khối bao gồm một giá trị riêng hoặc ma trận MxM với giá trị riêng lặp lại trên đường chéo và1 s trên đường chéo siêu (đường chéo ở trên và bên phải của đường chéo "chính"). Điều này dẫn đến một ma trận với tất cả các giá trị riêng (có bội số) trên đường chéo chính và một số 1s trên đường chéo siêu tương ứng với các giá trị riêng lặp đi lặp lại. Điều này trả về sản phẩm của đường chéo của dạng bình thường Jordan, là sản phẩm của giá trị riêng (với bội số), vì vậy đây là cách thực hiện nhiều phép tính giống như giải pháp trước đây.

Bởi vì Sage muốn dạng bình thường của Jordan nằm trên cùng một vòng với ma trận gốc, điều này chỉ hoạt động nếu tất cả các giá trị riêng là hợp lý. Các giá trị riêng phức tạp dẫn đến một lỗi (trừ khi ma trận gốc nằm trên vòng CDF(phao đôi phức tạp) hoặc SR). Tuy nhiên, điều này có nghĩa là lấy phần thực là không cần thiết, so với giải pháp trên.


Sản phẩm của đường chéo trong phân rã Smith

lambda m:prod(m.smith_form()[0].diagonal())

Không giống như dạng bình thường của Jordan, dạng bình thường của Smith được đảm bảo nằm trên cùng một trường với ma trận gốc. Thay vì tính toán các giá trị riêng và biểu diễn chúng bằng ma trận đường chéo khối, phân tách Smith tính toán các ước số cơ bản của ma trận (một chủ đề hơi phức tạp đối với bài đăng này), đặt chúng vào một ma trận đường chéo Dvà tính hai ma trận với đơn vị xác định UVnhư vậy D = U*A*V(nơi Alà ma trận gốc). Vì định thức của sản phẩm ma trận bằng tích của các định thức của ma trận ( det(A*B*...) = det(A)*det(B)*...) UVđược xác định là có các định thức đơn vị , det(D) = det(A). Yếu tố quyết định của ma trận đường chéo đơn giản là tích của các phần tử trên đường chéo.

Mở rộng Laplace, 109 byte

lambda m:m.nrows()>1and sum((-1)**j*m[0,j]*L(m[1:,:j].augment(m[1:,j+1:]))for j in range(m.ncols()))or m[0,0]

Điều này thực hiện mở rộng Laplace dọc theo hàng đầu tiên, sử dụng phương pháp đệ quy. det([[a]]) = ađược sử dụng cho trường hợp cơ sở. Nó nên ngắn hơn để sử dụng det([[]]) = 1cho trường hợp cơ sở, nhưng nỗ lực của tôi trong quá trình thực hiện đó có một lỗi mà tôi chưa thể theo dõi được.


Công thức của Leibniz, 100 byte

L2 = lambda m:sum(sgn(p)*prod(m[k,p[k]-1]for k in range(m.ncols()))for p in Permutations(m.ncols()))

Điều này trực tiếp thực hiện công thức của Leibniz. Để giải thích rõ hơn về công thức và lý do tại sao nó hoạt động tốt hơn tôi có thể viết, xem câu trả lời tuyệt vời này .


Phần thực của e^(Tr(ln(M))) , 48 byte

lambda m:real(exp(sum(map(ln,m.eigenvalues()))))

Hàm này trả về các biểu thức tượng trưng. Để có được xấp xỉ bằng số, hãy gọi n(result)trước khi in.

Đây là một cách tiếp cận mà tôi chưa thấy ai sử dụng. Tôi sẽ đưa ra một lời giải thích dài hơn, chi tiết hơn cho cái này.

Hãy Alà một ma trận vuông trên thực tế. Theo định nghĩa, định thức của Abằng với tích của giá trị riêng của A. Dấu vết của Abằng với tổng Agiá trị bản địa. Đối với số thực r_1r_2, exp(r_1) * exp(r_2) = exp(r_1 + r_2). Do hàm số mũ của ma trận được xác định là tương tự với hàm số mũ vô hướng (đặc biệt là trong danh tính trước đó), và hàm mũ của ma trận có thể được tính bằng cách chéo hóa ma trận và áp dụng hàm số mũ vô hướng cho giá trị riêng trên đường chéo, có thể nói det(exp(A)) = exp(trace(A))(sản phẩm của exp(λ)từng eigenvalue λcủa Abằng tổng các giá trị riêng của exp(A)). Vì vậy, nếu chúng ta có thể tìm thấy một ma trận , chúng ta có thể tính toánL sao choexp(L) = Adet(A) = exp(trace(L)).

Chúng ta có thể tìm thấy một ma trận như vậy Lbằng máy tính log(A). Logarit ma trận có thể được tính theo cách tương tự như hàm mũ của ma trận: tạo thành ma trận đường chéo vuông bằng cách áp dụng hàm logarit vô hướng cho mỗi giá trị riêng A(đây là lý do tại sao chúng ta giới hạn Aở thực). Vì chúng tôi chỉ quan tâm đến dấu vết của Lchúng tôi, chúng tôi có thể bỏ qua việc xây dựng và chỉ trực tiếp tổng hợp các số mũ của giá trị bản địa. Các giá trị riêng có thể phức tạp, ngay cả khi ma trận không vượt qua vòng phức tạp, vì vậy chúng tôi lấy phần thực của tổng.


1
Phần cuối cùng là một ý tưởng hấp dẫn, nhưng tiêu đề và giải thích không khớp với mã, không lấy logarit ma trận. Nó chỉ là vô real(prod(m.eigenvalues()))dụng.
Peter Taylor

2

Java 8, 266 261 259 258 byte

long d(int[][]m){long r=0;int i=0,j,k,l=m.length,t[][]=new int[l-1][l-1],q=m[0][0];if(l<3)return l<2?q:q*m[1][1]-m[0][1]*m[1][0];for(;i<l;r+=m[0][i]*(1-i++%2*2)*d(t))for(j=0;++j<l;)for(k=l;k-->0;){q=m[j][k];if(k<i)t[j-1][k]=q;if(k>i)t[j-1][k-1]=q;}return r;}

Hãy nhìn mẹ, không có bản dựng nào .. vì Java không có ..>.>

-7 byte nhờ @ceilingcat .

Giải trình:

Hãy thử nó ở đây. (Chỉ trường hợp thử nghiệm cuối cùng quá lớn để phù hợp với longkích thước 2 63 -1.)

long d(int[][]m){             // Method with integer-matrix parameter and long return-type
  long r=0;                   //  Return-long, starting at 0
  int i=0,j,k,                //  Index-integers
      l=m.length,             //  Dimensions of the square matrix
      t[][]=new int[l-1][l-1],//  Temp-matrix, one size smaller than `m`
      q=m[0][0];              //  The first value in the matrix (to reduce bytes)
  if(l<3)                     //  If the dimensions are 1 or 2:
    return l<2?               //   If the dimensions are 1:
      q                       //    Simply return the only item in it
     :                        //   Else (the dimensions are 2):
      q*m[1][1]-m[0][1]*m[1][0];
                              //    Calculate the determinant of the 2x2 matrix
                              //  If the dimensions are 3 or larger: 
  for(;i<l;                   //  Loop (1) from 0 to `l` (exclusive)
      r+=                     //    After every iteration: add the following to the result:
         m[0][i]              //     The item in the first row and `i`'th column,
         *(1-i++%2*2)         //     multiplied by 1 if `i` is even; -1 if odd,
         *d(t))               //     multiplied by a recursive call with the temp-matrix
    for(j=0;                  //   Reset index `j` to 0
        ++j<l;)               //   Inner loop (2) from 0 to `l` (exclusive)
      for(k=l;k-->0;){        //    Inner loop (3) from `l-1` to 0 (inclusive)
        q=m[j][k];            //     Set the integer at location `j,k` to reduce bytes
        if(k<i)               //     If `k` is smaller than `i`:
          t[j-1][k]=q;        //      Set this integer at location `j-1,k`
        if(k>i)               //     Else-if `k` is larger than `i`:
          t[j-1][k-1]=q;      //      Set this integer at location `j-1,k-1`
                              //     Else: `k` and `i` are equals: do nothing (implicit)
      }                       //    End of inner loop (3)
                              //   End of inner loop (2) (implicit / single-line body)
                              //  End of loop (1) (implicit / single-line body)
  return r;                   //  Return the result-long
}                             // End of method

2

JavaScript (ES6), 91

Laplace đệ quy

q=(a,s=1)=>+a||a.reduce((v,[r],i)=>v-(s=-s)*r*q(a.map(r=>r.slice(1)).filter((r,j)=>j-i)),0)

Ít chơi gôn

q = (a,s=1) => // s used as a local variable
  a[1] // check if a is a single element array 
       // if array, recursive call expanding along 1st column
  ? a.reduce((v,[r],i) => v-(s=-s)*r*q(a.map(r=>r.slice(1)).filter((r,j)=>j-i)),0) 
  : +a // single element, convert to number

Kiểm tra

q=(a,s=1)=>+a||a.reduce((v,[r],i)=>v-(s=-s)*r*q(a.map(r=>r.slice(1)).filter((r,j)=>j-i)),0)

TestCases=`[[42]] -> 42
[[2, 3], [1, 4]] -> 5
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] -> 0
[[13, 17, 24], [19, 1, 3], [-5, 4, 0]] -> 1533
[[372, -152, 244], [-97, -191, 185], [-53, -397, -126]] -> 46548380
[[100, -200, 58, 4], [1, -90, -55, -165], [-67, -83, 239, 182], [238, -283, 384, 392]] -> 571026450
[[432, 45, 330, 284, 276], [-492, 497, 133, -289, -28], [-443, -400, 56, 150, -316], [-344, 316, 92, 205, 104], [277, 307, -464, 244, -422]] -> -51446016699154`
.split('\n')

TestCases.forEach(r=>{
  [a,k] = r.split (' -> ')
  a = eval(a)
  d = q(a)
  console.log('Test '+(k==d ? 'OK':'KO')+
    '\nMatrix '+a.join('|')+
    '\nResult '+d+
    '\nCheck  '+k)
})


83 byte với hành vi tương tự
Arnauld

Hoặc 85 byte để hỗ trợ ma trận trống (có xác định là 1 ).
Arnauld

(Tôi đã sử dụng các tối ưu hóa tương tự trong câu trả lời này , có nguồn gốc từ bạn.)
Arnauld




1

Java (OpenJDK 8) , 195 192 177 byte

long d(int[][]m){long D=0;for(int l=m.length-1,t[][]=new int[l][l],i=0,j,k;i<=l;D+=m[0][i]*(1-i++%2*2)*(l<1?1:d(t)))for(j=0;j<l*l;)t[j/l][k=j%l]=m[1+j++/l][k<i?k:k+1];return D;}

Hãy thử trực tuyến!

Giống như nhiều câu trả lời khác, điều này cũng sử dụng công thức Laplace. Một phiên bản ít chơi gôn hơn:

long d(int[][]m){
  long D=0;
  int l=m.length-1,t[][]=new int[l][l],i=0,j,k;
  for(;i<=l;)
    for(j=0;j<l*l;)
      t[j/l][k=j%l]=m[1+j++/l][k<i?k:k+1];
    D+=m[0][i]*(1-i++%2*2)*(l<1?1:d(t));
  return D;
}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.