Giải phương trình ma trận bằng phương pháp Jacobi (Sửa đổi)


11

Bối cảnh toán học

Đặt A là ma trận N theo N gồm các số thực, ba vectơ của N số thực và vectơ xa N không biết số thực. Một phương trình ma trận là Ax = b.

Phương pháp của Jacobi như sau: phân tách A = D + R, trong đó D là ma trận của các đường chéo và R là các mục còn lại.

nếu bạn thực hiện một giải pháp đoán ban đầu x0, một giải pháp cải tiến là x1 = nghịch đảo (D) * (b - Rx) trong đó tất cả các phép nhân là phép nhân vectơ ma trận và nghịch đảo (D) là nghịch đảo ma trận.


Thông số kỹ thuật

  • Đầu vào : Chương trình hoàn chỉnh của bạn sẽ chấp nhận làm đầu vào cho dữ liệu sau: ma trận A, vectơ b, dự đoán ban đầu x0 và số 'lỗi' e.
  • Đầu ra : Chương trình phải xuất ra số lần lặp tối thiểu sao cho giải pháp mới nhất khác với giải pháp thực sự, nhiều nhất là e. Điều này có nghĩa là mỗi thành phần của vectơ ở cường độ tuyệt đối khác nhau nhiều nhất là e. Bạn phải sử dụng phương pháp Jacobi cho các lần lặp.

Làm thế nào dữ liệu được nhập là lựa chọn của bạn ; nó có thể là cú pháp của riêng bạn trên một dòng lệnh, bạn có thể lấy đầu vào từ một tệp, bất cứ điều gì bạn chọn.

Làm thế nào dữ liệu được xuất ra là lựa chọn của bạn ; nó có thể được ghi vào một tệp, được hiển thị trong dòng lệnh, được viết dưới dạng nghệ thuật ASCII, bất cứ thứ gì, miễn là nó có thể đọc được bởi con người.

Biết thêm chi tiết

Bạn không được đưa ra giải pháp thực sự: cách bạn tính toán giải pháp thực sự hoàn toàn phụ thuộc vào bạn. Bạn có thể giải quyết nó theo quy tắc của Cramer chẳng hạn, hoặc tính toán nghịch đảo trực tiếp. Điều quan trọng là bạn có một giải pháp thực sự để có thể so sánh với các lần lặp.

Chính xác là một vấn đề; một số "giải pháp chính xác" của mọi người để so sánh có thể khác nhau. Đối với mục đích của mã golf này, giải pháp chính xác phải đúng đến 10 chữ số thập phân.

Để hoàn toàn rõ ràng, nếu thậm chí một thành phần của giải pháp lặp hiện tại của bạn vượt quá thành phần tương ứng của nó trong giải pháp thực sự bởi e, thì bạn cần tiếp tục lặp lại.

Giới hạn trên đối với N thay đổi dựa trên phần cứng bạn đang sử dụng và thời gian bạn sẵn sàng dành để chạy chương trình. Đối với mục đích của mã golf này, giả sử tối đa N = 50.

Điều kiện tiên quyết

Khi chương trình của bạn được gọi, bạn có thể tự do cho rằng mọi thứ sau đây luôn được giữ:

  • N> 1 và N <51, tức là bạn sẽ không bao giờ được đưa ra một phương trình vô hướng, luôn luôn là một phương trình ma trận.
  • Tất cả các đầu vào là trên lĩnh vực của số thực, và sẽ không bao giờ phức tạp.
  • Ma trận A luôn luôn sao cho phương thức hội tụ đúng với giải pháp thực, sao cho bạn luôn có thể tìm thấy một số lần lặp để giảm thiểu lỗi (như được định nghĩa ở trên) bên dưới hoặc bằng e.
  • A không bao giờ là ma trận không hoặc ma trận danh tính, tức là có một giải pháp.

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

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

Giải pháp thực sự là (0,586, 1.138). Lặp lại đầu tiên cho x1 = (5/9, 1), khác nhau hơn 0,04 so với giải pháp thực sự, bởi ít nhất một thành phần. Lấy một lần lặp khác mà chúng ta thấy, x2 = (0,555, 1.148) khác nhau ít hơn 0,04 so với (0,586, 1.138). Do đó, đầu ra là

2

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

Trong trường hợp này, giải pháp thực sự là (2.2, -0.8) và dự đoán ban đầu x0 đã có lỗi nhỏ hơn e = 1.0, do đó chúng tôi xuất 0. Đó là, bất cứ khi nào bạn không cần thực hiện phép lặp, bạn chỉ cần xuất ra

0

Đánh giá đệ trình

Đây là mã golf, với tất cả các sơ hở tiêu chuẩn không được phép. Chương trình hoàn thành chính xác ngắn nhất (hoặc hàm), tức là số byte thấp nhất sẽ thắng. Không khuyến khích sử dụng những thứ như Mathematica bao gồm rất nhiều bước cần thiết vào một chức năng, nhưng sử dụng bất kỳ ngôn ngữ nào bạn muốn.


2
Bạn thực sự nên chờ đợi để có thêm thông tin phản hồi cho nó, đặc biệt là cho bài viết đóng gần đây. Các thách thức PPCG thường chia sẻ cấu trúc phổ biến trong thông số kỹ thuật, những gì thường đóng góp cho chúng dễ hiểu, thay vì mệt mỏi và mơ hồ. Cố gắng xem xét một số thách thức được nêu lên một cách hợp lý và bắt chước định dạng.
Uriel

@Uriel Tôi nhận ra điều này, nhưng tôi cảm thấy mình đã thấu đáo trong đặc điểm kỹ thuật của mình và định dạng trong khi không phù hợp chính xác với phần lớn các câu hỏi, có thể được đọc tuyến tính và hướng dẫn người đọc phù hợp. Các định dạng cũng nên ghi nhớ nội dung của vấn đề.
user1997744

3
" Chương trình hoàn chỉnh chính xác ngắn nhất " có vẻ như bạn chỉ cho phép các chương trình và không hoạt động. Tôi muốn thêm "/ function".
Adám

2
Định dạng +1 làm cho hoặc phá vỡ khả năng tập trung vào một câu hỏi của bộ não của tôi
Stephen

1
@ user1997744 Yup, có ý nghĩa. Tôi tin rằng mặc định là bất kỳ mã nào khác, như các hàm nhập hoặc hàm python khác, đều được phép, nhưng cũng được bao gồm trong bytecount.
Stephen

Câu trả lời:


4

APL (Dyalog) , 78 68 65 49 byte

Chính xác là loại vấn đề APL đã được tạo cho.

-3 cảm ơn Erik the Outgolfer . -11 cảm ơn ngn .

Hàm infix ẩn danh. Đưa A là đối số bên trái và x là đối số bên phải. In kết quả thành STDOUT dưới dạng unary dọc sử dụng 1làm dấu kiểm đếm, theo sau 0là dấu chấm câu. Điều này có nghĩa là thậm chí có thể nhìn thấy kết quả 0, không có 1s trước 0.

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

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

Giải thích theo thứ tự đọc

Lưu ý cách mã đọc rất giống với đặc tả vấn đề:

{Liên kết } trên A, b và e đã cho và x đã cho,
⎕← in
∨/ xem có bất kỳ sự thật nào trong tuyên bố rằng
e< e nhỏ hơn
|⍵- giá trị tuyệt đối của x trừ
b⌹ b ma trận - chia
⊃A b e cho đầu tiên của A, b và e (tức là A)
←⍺ là đối số bên trái
: và nếu vậy,
  ⍺∇ lặp lại trên
  D+.× ma trận D lần
  b- b trừ
  ⍵+.×⍨ x, ma trận nhân với
  A- A trừ đi
  ⌹D nghịch đảo của D (các mục còn lại)
   trong đó D là
   A trong
  =/¨ đó có
   tọa độ bằng nhau cho
  ⍴A hình dạng của A (tức là đường chéo)

Giải thích từng bước

Thứ tự thực hiện từ phải sang trái:

{... } mang tính chất chức năng mà là một thể và ⍵ là x:
A b c←⍺ chia trái đối số vào A, b, e
 chọn ngày đầu tiên (A)
b⌹ phân chia ma trận với b (cho giá trị đúng của x)
⍵- chênh lệch giữa giá trị hiện tại của x và những
| giá trị tuyệt đối
e< chấp nhận được lỗi ít hơn những gì?
∨/ Có đúng với bất kỳ? (lit. HOẶC giảm)
⎕← in Boolean thành STDOUT
: và nếu vậy:
  ⍴A hình dạng của một
   ma trận có hình dạng trong đó mỗi ô là tọa độ riêng của nó
  =/¨ cho mỗi ô, tọa độ dọc và ngang có bằng nhau không? (đường chéo)
   nhân các ô của A với
   ma trận (trích xuất đường chéo)
  D← lưu trữ nghịch đảo trong D (đối với D iagonal)
   nghịch đảo (trở lại bình thường)
  A- trừ khỏi
  ⍵+.×⍨ ma trận nhân bội (tương tự như sản phẩm chấm, do đó .) với x
  b- trừ đi từ
  D+.× sản phẩm ma trận b của D và
  ⍺∇ áp dụng hàm này với A đã cho và đó là giá trị mới của x


Đầu ra phải là số lần lặp cần thiết cho độ chính xác e.
Zgarb

-1: Đây không phải là một giải pháp. Bạn cần x0 vì toàn bộ điểm là để biết cần bao nhiêu bước để có được độ chính xác mong muốn từ một điểm bắt đầu cụ thể.
user1997744

@ user1997744 À, tôi hiểu nhầm vấn đề. Lấy làm tiếc.
Adám

@ user1997744 Tốt hơn?
Adám

1
@ user1997744 Không hoạt động số học, chỉ có khả năng đọc unary , trong đó thực sự 0 là không có gì .
Adám

1

Python 3 , 132 byte

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

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

Sử dụng một giải pháp đệ quy.


@ Adám Tôi không chắc là tôi hiểu. Tôi giải thích nó là fkhông có tên trong khối mã, mà bây giờ tôi đã sửa; tuy nhiên, nếu đó là một vấn đề hoàn toàn khác, nó vẫn có thể là một vấn đề.
notjagan

@ Adám Câu trả lời đó dường như chứng thực những gì tôi hiện đang có; nó là một hàm với mã trợ giúp có khả năng hoạt động như một đơn vị sau định nghĩa của nó.
notjagan

À, được rồi Đừng bận tâm. Tôi không biết Python, vì vậy tôi chỉ tò mò. Làm tốt lắm!
Adám

Không phải là tiêu chí dừng "Điều này có nghĩa là mỗi thành phần của vectơ ở cường độ tuyệt đối khác nhau nhiều nhất bởi e"? Về cơ bản định mức tối đa, không phải định mức L2.
NikoNyrh

@NikoNyrh Đã sửa.
notjagan

1

R , 138 byte

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}

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

cảm ơn NikoNyrh đã sửa lỗi

Cũng đáng lưu ý rằng có một gói R, Rlinsolve có chứa lsolve.jacobihàm, trả về một danh sách với x(giải pháp) và iter(số lần lặp được yêu cầu), nhưng tôi không chắc rằng nó có tính toán chính xác không.


Không phải là tiêu chí dừng "Điều này có nghĩa là mỗi thành phần của vectơ ở cường độ tuyệt đối khác nhau nhiều nhất bởi e"? Về cơ bản định mức tối đa, không phải định mức L2.
NikoNyrh

@NikoNyrh bạn đúng rồi! may mắn thay, normhàm cung cấp cho tôi cũng như không có thêm byte.
Giuseppe

1

Clojure, 212 198 196 byte

#(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)))

Được thực hiện mà không có thư viện ma trận, nó lặp lại quá trình 1e9 lần để có câu trả lời đúng. Điều này sẽ không hoạt động trên đầu vào quá điều hòa nhưng sẽ hoạt động tốt trong thực tế.

Ít chơi gôn hơn, tôi khá hài lòng với các biểu thức của RD:) Đầu vào đầu tiên %(A) phải là một vectơ, không phải là một danh sách để assoccó thể sử dụng.

(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)))
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.