การแก้ซ้ำ ๆ ด้วย ,


12

ฉันกำลังใช้ MATLAB เพื่อแก้ปัญหาที่เกี่ยวข้องกับการแก้Ax=bทุก ๆ เวลาที่bเปลี่ยนแปลงไปตามกาลเวลา ตอนนี้ฉันกำลังทำสิ่งนี้โดยใช้ MATLAB mldivide:

x = A\b

ฉันมีความยืดหยุ่นในการทำให้เป็น precomputations มากที่สุดเท่าที่จำเป็นเพื่อให้ผมสงสัยว่าถ้ามีวิธีที่เร็วขึ้นและ / mldivideหรือความถูกต้องมากกว่า โดยทั่วไปแล้วจะทำอะไรที่นี่ ขอบคุณทุกคน!


1
คุณมีความรู้เฉพาะเกี่ยวกับโครงสร้างของAหรือไม่? ตัวอย่างเช่นมันสมมาตรไหม? แน่นอนบวก? tridiagonal? ฉาก?
Dominique

เมทริกซ์Aเป็นเมทริกซ์จตุรัสหนาแน่น
สงสัย

3
หากคุณไม่มีความรู้อื่น ๆ เกี่ยวกับการแยกตัวประกอบตามที่อธิบายไว้ในคำตอบด้านล่างคือทางออกที่ดีที่สุดของคุณ L UALU
Dominique

คำตอบ:


14

สิ่งที่ชัดเจนที่สุดที่คุณสามารถทำได้คือการคำนวณล่วงหน้า

[L,U] = lu(A) ~ O (n ^ 3)

จากนั้นคุณเพียงแค่คำนวณ

x = U \ (L \ b) ~ O (2 n ^ 2)

สิ่งนี้จะลดค่าใช้จ่ายมหาศาลและทำให้เร็วขึ้น ความแม่นยำก็จะเหมือนกัน


1
หมายเหตุจากเอกสารประกอบ L ไม่จำเป็นต้องเป็นรูปสามเหลี่ยมที่ต่ำกว่า คำตอบนี้น่าจะเร็วกว่าการแก้ไขโดยตรงอย่างไรก็ตามฉันจะต้องระมัดระวังเพื่อให้แน่ใจว่าคำสั่ง L \ b นั้นฉลาดพอที่จะรู้วิธีแก้ L ในลำดับที่ถูกต้อง (เป็นไปได้ แต่มันไม่ได้บอกอย่างแน่นอน ในเอกสารประกอบ)
Godric Seer

ใช่คุณพูดถูก L เป็นผลคูณของเมทริกซ์สามเหลี่ยมล่างและเมทริกซ์การเปลี่ยนแปลง L\bแต่ฉันจะถูกสาปถ้าไม่ได้รับรู้ว่าทั้งหมดจะได้ทำคือการเปลี่ยนตัวย้อนหลังกับ เพราะฉันเห็นบรรทัดที่แน่นอนนี้ถูกใช้ในโค้ดประสิทธิภาพสูงโดยผู้ที่ฉันพิจารณาว่าเป็นผู้เชี่ยวชาญ
Milind R

8
mldivide รู้จักเมทริกซ์รูปสามเหลี่ยมที่เปลี่ยนแปลงและทำสิ่งที่ถูกต้องในการแก้ปัญหาของระบบ อย่างไรก็ตามในการทดลองของฉันสิ่งนี้ดูเหมือนว่าจะทำให้กระบวนการแก้ปัญหาช้าลงโดยมีค่าเท่ากับ 10 หรือมากกว่าสำหรับเมทริกซ์ที่มีขนาด 2000 ถึง 2,000 ถึง 10,000 โดย 10,000 ดังนั้นคุณควรติดตามการเปลี่ยนแปลงอย่างชัดเจนโดยใช้ [L] , U, P] = Lu (P) O(n2)
Brian Borchers

1
นอกจากนี้หากเมทริกซ์ของคุณเบาบางคุณควรใช้ประโยชน์จากความกระจัดกระจายในการแก้ไขระบบ วิธีที่ง่ายที่สุดในการทำเช่นนี้คือเพื่อให้แน่ใจว่าถูกจัดเก็บในรูปแบบกระจัดกระจายโดยใช้ A = sparse (A) ก่อนคำนวณการแยกตัวประกอบ LU คุณสามารถลองเปลี่ยนแถวของ A เพื่อลดการเติมระหว่างการแยกตัวประกอบ LU A
Brian Borchers

3
@BrianBorcher เท่าที่ผมรู้ว่าวิธีที่ดีที่สุดในการติดตามการเปลี่ยนแปลงนั้นเป็นไป[L,U,p] = lu(A,'vector'); x = U\(L\b(p));ดูตัวอย่าง 3 ในเอกสารlu
Stefano M

5

เราทำแล็บคอมพิวเตอร์จำนวนมากในหลักสูตรการคำนวณทางวิทยาศาสตร์ของเราเกี่ยวกับหัวข้อนี้ สำหรับการคำนวณ "เล็ก" ที่เราทำที่นั่นเครื่องหมายแบ็กสแลชของ Matlab นั้นเร็วกว่าสิ่งอื่นเสมอแม้หลังจากที่เราปรับปรุงโค้ดให้มากที่สุดเท่าที่จะเป็นไปได้และปรับการฝึกอบรมทั้งหมดล่วงหน้าก่อน .

คุณสามารถตรวจสอบหนึ่งของเราคำแนะนำการใช้ห้องปฏิบัติการ คำตอบสำหรับคำถามของคุณครอบคลุม (ไม่นาน) ในหน้า 4

เป็นหนังสือที่ดีในหัวข้อที่เขียนเช่นโดยเชนีย์


4

สมมติว่าเป็นหนาแน่นเมทริกซ์และคุณจะต้องแก้ ,m ถ้าเป็นขนาดใหญ่พอแล้วมีอะไรผิดปกติในn × n A x i = b i i = 1 m mAn×n Axi=bii=1mm

V = inv(A);
...
x = V*b;

Flops เป็นสำหรับและสำหรับดังนั้นเพื่อกำหนดค่าจุดคุ้มทุนสำหรับจำเป็นต้องมีการทดลอง ...O ( n 2 ) mO(n3)inv(A)O(n2)V*bm

>> n = 5000;
>> A = randn(n,n);
>> x = randn(n,1);
>> b = A*x;
>> rcond(A)
ans =
   1.3837e-06
>> tic, xm = A\b; toc
Elapsed time is 1.907102 seconds.
>> tic, [L,U] = lu(A); toc
Elapsed time is 1.818247 seconds.
>> tic, xl = U\(L\b); toc
Elapsed time is 0.399051 seconds.
>> tic, [L,U,p] = lu(A,'vector'); toc
Elapsed time is 1.581756 seconds.
>> tic, xp = U\(L\b(p)); toc
Elapsed time is 0.060203 seconds.
>> tic, V=inv(A); toc
Elapsed time is 7.614582 seconds.
>> tic, xv = V*b; toc     
Elapsed time is 0.011499 seconds.
>> [norm(xm-x), norm(xp-x), norm(xl-x), norm(xv-x)] ./ norm(x)
ans =
   1.0e-11 *
    0.1912    0.1912    0.1912    0.6183

ในการนี้เล็กน้อยตัวอย่างเช่นก่อนการคำนวณจะดีกว่าไปข้างหน้าและวิธีการแก้ปัญหาย้อนหลังม.> L U m > 125A1LUm>125

บางบันทึก

สำหรับการวิเคราะห์เสถียรภาพและข้อผิดพลาดโปรดดูความคิดเห็นของคำตอบที่แตกต่างนี้โดยเฉพาะอย่างยิ่งคำตอบโดย VictorLiu

การกำหนดเวลาที่เสนอไม่ใช่ "วิทยาศาสตร์" เลย แต่มีไว้เพื่อแสดงให้เห็นว่าวิธีการที่เสนอในคำตอบของ Milind R ในขณะที่มันเหมาะสมที่จะนำไปใช้ใน C หรือ Fortran โดยการเรียกรูทีนย่อย LAPACK และ BLAS ที่เกี่ยวข้อง มีประสิทธิภาพในการ Matlab แม้สำหรับnmn

การจับเวลาทำได้ด้วย Matlab R2011b บนคอมพิวเตอร์ 12 คอร์ที่มีค่าเฉลี่ย UNIX ที่ค่อนข้างคงที่เท่ากับ 5; tic, tocเวลาที่ดีที่สุดของสามโพรบ


อันที่จริงมีความเท่าเทียมในเมทริกซ์เวกเตอร์มากกว่าตัวแก้รูปสามเหลี่ยมดังนั้นนี่ควรจะชัดเจนยิ่งขึ้นถ้าการคำนวณเสร็จในแบบขนาน (มัลติคอร์ / GPU / ฯลฯ ... ) ในทางใดทางหนึ่ง
Aron Ahmadia

@AronAhmadia ฉันเห็นด้วย: การประเมินจุดคุ้มทุนโดยพิจารณาจากจำนวนการดำเนินการเท่านั้นที่เหมาะสมสำหรับการใช้งานแบบอนุกรม
Stefano M

1
โปรดทราบว่าสิ่งต่าง ๆ จะแตกต่างกันอย่างมากหากเมทริกซ์ A นั้นห่างกัน - โดยทั่วไปแล้วอินเวอร์สจะมีความหนาแน่นค่อนข้างสูงในขณะที่ปัจจัย LU มักจะเบาบางพอสมควร
Brian Borchers

1
@ ความถูกต้องสงสัยได้รับการแก้ไขแล้วในความคิดเห็นต่อคำตอบนี้ โดยทั่วไปควรจะมีการสูญเสียเพียงเล็กน้อยของความถูกต้อง, ถ้าคุณมีพยาธิสภาพเมทริกซ์ A
Stefano M

1
@ มิลินด์แน่นอนว่าการคำนวณล่วงหน้านั้นinv(A)สมเหตุสมผลถ้าคุณต้องแก้ซ้ำ ๆสำหรับแตกต่างกันซึ่งไม่ได้รู้ทั้งหมดในเวลาเดียวกัน โดยปกติถ้าคุณมีหลายฝ่ายขวามือเพียงเก็บไว้ในเมทริกซ์และไปกับ b BAx=bbBA\B
Stefano M

2

ลองดูที่คำถามนี้คำตอบแสดงให้เห็นว่าmldivideค่อนข้างฉลาดและยังให้คำแนะนำเกี่ยวกับวิธีดูว่า Matlab ใช้แก้A\bอะไรได้บ้าง นี่อาจให้คำแนะนำเกี่ยวกับตัวเลือกการเพิ่มประสิทธิภาพ


0

การใช้แบ็กสแลชนั้นเทียบเท่าหรือมากกว่าinv(A)*Bหากคุณกำลังเขียนโค้ดไว้อย่างอิสระหลังอาจจะใช้งานง่ายกว่า พวกเขามีความคล้ายคลึงกัน (ต่างกันในการคำนวณ) แม้ว่าคุณควรตรวจสอบเอกสารประกอบของ Matlab เพื่อความกระจ่าง

ในการตอบคำถามของคุณแบ็กสแลชนั้นใช้ได้ปกติ แต่ขึ้นอยู่กับคุณสมบัติของมวลเมทริกซ์


1
Mathematically inv (A) * b เป็นเช่นเดียวกับ \ อย่างไรก็ตามตัวเลขจริง ๆ แล้วการผกผันมีประสิทธิภาพน้อยลงและแม่นยำน้อยลง หากคุณกำลังทำงานเพื่อเรียนรู้พีชคณิตเชิงเส้นนี่อาจเป็นที่ยอมรับได้ แต่ฉันจะเถียงว่าคุณต้องการเหตุผลที่ดีมากในการสร้างอินเวอร์ส
Godric Seer

แต่ทำไมคุณถึงคำนวณด้วยตัวเองinv(A)เพราะสิ่งนั้นมีค่ามากกว่าA\b?
Dominique

7
@Godric: มีกระดาษที่ผ่านมาเป็นที่กล่าวถึงว่า "ตำนาน" ที่ Inv (A) b * มีความถูกต้องน้อย: บน arXiv ไม่ได้บอกว่ามักจะมีเหตุผลในการคำนวณค่าผกผันที่เกิดขึ้นจริง แต่เพียงแค่บอกว่า
Victor Liu

3
@Dominique: ตัวแก้รูปสามเหลี่ยมมีความสามารถในการขนานได้น้อยกว่าการคูณเมทริกซ์ - เวกเตอร์และวิธีการวนซ้ำที่มีความซับซ้อนมักจะใช้วิธีการโดยตรงบนโดเมนย่อย มันมักจะมีประโยชน์ในการสร้างแบบผกผันของเมทริกซ์สามเหลี่ยมขนาดเล็กที่มีความหนาแน่นน้อยเพื่อปรับปรุงการขนาน
Jack Poulson

@VictorLiu: ขอบคุณสำหรับบทความ ฉันยืนแก้ไขคำสั่งความถูกต้องของฉัน (atleast สำหรับการใช้งานอย่างชาญฉลาดของ inv (A))
Godric Seer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.