ความซับซ้อนของเมทริกซ์ผกผันในจำนวน


11

ฉันกำลังแก้สมการเชิงอนุพันธ์ที่ต้องสลับเมทริกซ์จตุรัสหนาแน่น เมทริกซ์ผกผันนี้ใช้เวลาในการคำนวณมากที่สุดดังนั้นฉันจึงสงสัยว่าถ้าฉันใช้อัลกอริทึมที่เร็วที่สุด

ทางเลือกในปัจจุบันของฉันคือnumpy.linalg.inv จากตัวเลขของฉันฉันเห็นว่ามันปรับขนาดเป็นโดยที่ n คือจำนวนแถวดังนั้นวิธีที่ดูเหมือนจะเป็นการกำจัดแบบเกาส์เซียนO(n3)

ตามWikipediaมีอัลกอริทึมที่เร็วกว่าใช้ได้ ไม่มีใครรู้ว่ามีห้องสมุดที่ใช้สิ่งเหล่านี้หรือไม่?

ฉันสงสัยว่าทำไม numpy จึงไม่ใช้อัลกอริธึมที่เร็วกว่านี้?


คุณต้องทำการฝึกอบรมก่อน ดู Scipy เบาบางสำหรับความช่วยเหลือของคุณ มันมีเครื่องมือมากมายที่คุณต้องการ
Tobal

@ คนจำนวนมากไม่แน่ใจว่าฉันทำตาม ... คุณจะ "แสดง" เมทริกซ์ได้อย่างไร และจะscipy.sparseช่วยได้อย่างไร
GoHokies

@ GoHokies scipy เป็นส่วนเสริมของจำนวนคน การฝึกอบรมที่หนาแน่น / กระจัดกระจายจะต้องดำเนินการอย่างดีก่อนที่จะทำการคำนวณบางอย่างมันจะปรับปรุงการคำนวณของคุณ โปรดอ่านdocs.scipy.org/doc/scipy/reference/sparse.htmlคำอธิบายนี้ดีกว่าฉันด้วยภาษาอังกฤษที่ไม่ดีของฉัน
Tobal

@Tobal คำถามหมายถึงเมทริกซ์หนาแน่นดังนั้นฉันไม่เห็นว่าscipy.sparseมีความเกี่ยวข้องที่นี่?
Christian Clason

2
@Tobal - ฉันคิดว่าฉันยังไม่เข้าใจ คุณหมายความว่าอย่างไรกับ "preform เมทริกซ์ของคุณ" และ "เมทริกซ์จะต้องนำไปใช้งานได้ดีก่อนที่จะทำการคำนวณ" เกี่ยวกับความคิดเห็นล่าสุดของคุณแน่นอนคุณจะยอมรับว่าเทคนิคที่สามารถใช้สำหรับเมทริกซ์เบาบางและหนาแน่นนั้นแตกต่างกันมาก
Wolfgang Bangerth

คำตอบ:


21

(การรับความคิดเห็นยาวเกินไป ... )

ฉันจะสมมติว่าคุณต้องคำนวณอินเวอร์สในอัลกอริทึมของคุณ 1ประการแรกสิ่งสำคัญคือต้องทราบว่าอัลกอริธึมทางเลือกเหล่านี้ไม่ได้อ้างว่าเร็วกว่าจริงเพียงเพราะมีความซับซ้อนเชิงซีมโทติคที่ดีกว่า (หมายถึงจำนวนการปฏิบัติการขั้นพื้นฐานที่ต้องการ ในความเป็นจริงในทางปฏิบัติสิ่งเหล่านี้จริง ๆ แล้วช้ากว่าวิธีมาตรฐาน (สำหรับกำหนด) ด้วยเหตุผลดังต่อไปนี้:n

  1. -notation กลองอย่างต่อเนื่องในด้านหน้าของอำนาจของซึ่งอาจมีขนาดใหญ่ astronomically - ขนาดใหญ่เพื่อให้สามารถมากมีขนาดเล็กกว่าสำหรับการใด ๆว่า สามารถจัดการกับคอมพิวเตอร์เครื่องใดก็ได้ในอนาคตอันใกล้ (นี่เป็นกรณีสำหรับอัลกอริทึม Coppersmith – Winograd) n C 1 n 3 C 2 n 2. x nOnC1n3C2n2.xn

  2. ความซับซ้อนสันนิษฐานว่าการดำเนินการทุกอย่าง (ทางคณิตศาสตร์) ใช้เวลาเดียวกัน - แต่มันก็ไม่จริงในการฝึกจริง: การคูณจำนวนตัวเลขที่มีจำนวนเท่ากันนั้นเร็วกว่าการคูณจำนวนที่แตกต่างกันจำนวนมาก นี่เป็นเพราะความจริงที่ว่าคอขวดใหญ่ในการคำนวณปัจจุบันได้รับข้อมูลเข้าสู่แคชไม่ใช่การดำเนินการเกี่ยวกับคณิตศาสตร์ที่เกิดขึ้นจริงกับข้อมูลนั้น ดังนั้นอัลกอริทึมที่สามารถจัดเรียงใหม่เพื่อให้มีสถานการณ์แรก (เรียกว่าการรับรู้แคช ) จะเร็วกว่าหนึ่งที่ไม่สามารถทำได้ (นี่เป็นกรณีของอัลกอริทึมของ Strassen)

นอกจากนี้ความเสถียรเชิงตัวเลขอย่างน้อยสำคัญเท่ากับประสิทธิภาพ และที่นี่อีกครั้งวิธีการมาตรฐานมักจะชนะ

ด้วยเหตุผลนี้ไลบรารีมาตรฐานประสิทธิภาพสูง (BLAS / LAPACK ซึ่ง Numpy เรียกใช้เมื่อคุณขอให้คำนวณอินเวิร์ส) มักใช้วิธีนี้เท่านั้น แน่นอนว่ามีการนำ Numpy มาใช้เช่นอัลกอริธึมของ Strassen ออกไป แต่อัลกอริทึมปรับด้วยมือในระดับชุดประกอบจะชนะอัลกอริทึมที่เขียนด้วยภาษาระดับสูงสำหรับขนาดเมทริกซ์ที่เหมาะสมO ( n 2. x )O(n3)O(n2.x)


1แต่ฉันผิดปกติถ้าฉันไม่ได้ชี้ให้เห็นว่านี่ไม่ค่อยจำเป็นจริงๆ: ทุกครั้งที่คุณต้องคำนวณผลิตภัณฑ์คุณควรแก้ปัญหาระบบเชิงเส้น (เช่น ใช้) และการใช้งานแทน - นี้เป็นมีเสถียรภาพมากขึ้นและสามารถทำได้ (ขึ้นอยู่กับโครงสร้างของเมทริกซ์) มากได้เร็วขึ้น หากคุณจำเป็นต้องใช้หลาย ๆ ครั้งคุณสามารถคำนวณค่าตัวประกอบของ (ซึ่งโดยปกติจะเป็นส่วนที่แพงที่สุดของการแก้ปัญหา) และนำมาใช้ใหม่ในภายหลังA x = b x A A - 1 AA1bAx=bnumpy.linalg.solvexAA1A


คำตอบที่ดีขอบคุณมากโดยเฉพาะอย่างยิ่งสำหรับการชี้ให้เห็นปีศาจในรายละเอียด (ค่าคงที่ในเครื่องหมาย O ใหญ่) ที่สร้างความแตกต่างอย่างมากระหว่างความเร็วเชิงทฤษฎีและความเร็วเชิงปฏิบัติ
gaborous

ฉันคิดว่าส่วน "การผกผันมีความจำเป็นน้อย" ควรให้ความสำคัญมากกว่านี้ หากจุดประสงค์คือการแก้ระบบสมการเชิงอนุพันธ์ดูเหมือนว่าจะไม่จำเป็นต้องมีการผกผันแบบเต็ม
Jared Goguen

@o_o อืมนั่นเป็นความคิดเห็นดั้งเดิมครั้งแรกของฉัน (ซึ่งฉันลบหลังจากรวมพวกเขาทั้งหมดไว้ในคำตอบเดียว) แต่ฉันคิดว่าเพื่อประโยชน์ของเว็บไซต์ (และผู้อ่านในภายหลัง) คำตอบควรตอบคำถามจริงในคำถาม (ซึ่งทั้งเหมาะสมและในหัวข้อ) แม้ว่าจะมีปัญหา XY อยู่ด้านหลัง นอกจากนี้ฉันไม่ต้องการที่จะฟังคำเตือนเกินไป ...
Christian Clason

1
ดังที่ฉันได้เขียนคุณสามารถเขียนอัลกอริทึมของคุณเกือบทั้งหมดเพื่อแทนที่การดำเนินการที่เกี่ยวข้องกับการแก้ปัญหาเชิงเส้นที่เกี่ยวข้อง (หรือในกรณีนี้ลำดับของระบบเชิงเส้น) - ถ้าคุณสนใจคุณสามารถถามคำถามแยกต่างหากเกี่ยวกับ ("ฉันสามารถหลีกเลี่ยงการย้อนกลับเมทริกซ์ในอัลกอริทึมนี้ได้หรือไม่") และใช่เนื่องจากจำนวนเมทริกซ์ไม่ได้ขึ้นอยู่กับความซับซ้อนยังคงเหมือนเดิม (คุณเพิ่งได้ค่าคงที่ที่ใหญ่กว่า - จากปัจจัยสี่ตัวในกรณีของคุณ) n
Christian Clason

1
@ ไฮเซนเบิร์ก: ขึ้นอยู่กับโครงสร้างของ - LU, Cholesky หรือแม้แต่การย่อยสลาย QR จุด (ซึ่งถูกสร้างขึ้นในข้อความใด ๆ บนพีชคณิตเชิงเส้นเชิงตัวเลข) คือการใช้การสลายตัวนั้นมีราคาถูกเมื่อเปรียบเทียบกับการคำนวณดังนั้นคุณทำอย่างหลังเพียงครั้งเดียวแล้วใช้หลายครั้ง A
Christian Clason

4

คุณควรทราบว่าฝังลึกลงในซอร์สโค้ด numpy (ดูhttps://github.com/numpy/numpy/blob/master/numpy/linalg/umath_linalg.c.src ) รูทีน inv พยายามเรียกฟังก์ชัน dgetrf จากแพคเกจ LAPACK ระบบของคุณซึ่งจะทำการย่อยสลาย LU ของเมทริกซ์ดั้งเดิมของคุณ สิ่งนี้เทียบเท่ากับการกำจัดแบบเกาส์ทางศีลธรรม แต่สามารถปรับให้มีความซับซ้อนลดลงเล็กน้อยโดยใช้อัลกอริทึมการคูณเมทริกซ์ที่เร็วขึ้นใน BLAS ประสิทธิภาพสูง

หากคุณติดตามเส้นทางนี้คุณควรได้รับคำเตือนว่าการบังคับให้ทั้งเครือข่ายห้องสมุดใช้ห้องสมุดใหม่แทนที่จะเป็นระบบที่มากับการแจกจ่ายของคุณนั้นค่อนข้างซับซ้อน อีกทางเลือกหนึ่งสำหรับระบบคอมพิวเตอร์ที่ทันสมัยคือการดูวิธีการแบบขนานโดยใช้แพ็คเกจเช่น scaLAPACK หรือ (ในโลกหลาม) petc4py อย่างไรก็ตามสิ่งเหล่านี้มักจะถูกใช้อย่างมีความสุขมากขึ้นในฐานะนักแก้ปัญหาซ้ำสำหรับระบบพีชคณิตเชิงเส้นมากกว่าที่ใช้กับวิธีการโดยตรงและ PETSc โดยเฉพาะอย่างยิ่งระบบ sparse เป้าหมายมากกว่าระบบหนาแน่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.