การคูณเมทริกซ์ MATLAB (วิธีการคำนวณที่ดีที่สุด)


10

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

วิธีที่ # 1 : ทำการคูณโดยตรงนั่นคือ

vf=R1 R2 R3 vi

วิธีที่ # 2 : แบ่งออกเป็นขั้นตอน:

  1. v3i=R3 vi
  2. v23=R2 v3i
  3. vf=R1 v23

ที่อยู่:

, R 2และ R 3มี 3 × 3เมทริกซ์R1R2R33×3

, v i , v 3 i , v 23คือ 3 × 1เวกเตอร์โวลต์โวลต์ผมโวลต์3ผมโวลต์233×1

ฉันอยากจะรู้ว่าวิธีใดมีประสิทธิภาพมากขึ้นในการคำนวณ (ใช้เวลาน้อยลง) ในการเปลี่ยนแปลง (ซึ่งจะทำหลายครั้ง)


4
ใช้quaternions
Chris Taylor

@ChrisTaylor: ขอบคุณมากสำหรับคำแนะนำของคุณ
julianfperez

2
กรุณาอย่าขวางทาง
ฉีกออก

2
หมายเหตุมีสองคำถามข้ามโพสต์ที่นี่และ StackOverflow คำถามและความคิดเห็นและคำตอบของพวกเขาถูกรวมเข้ากับคำถามนี้
Aron Ahmadia

@ Will และ AronAhmadia: ฉันขอโทษ ฉันไม่ทราบว่าเป็นสิ่งต้องห้าม ฉันโพสต์คำถามของฉันไว้ที่ StackOverflow เสมอ แต่วันนี้ฉันได้พบเว็บไซต์ใหม่นี้และฉันคิดว่าบางทีฉันก็สามารถขอความช่วยเหลือได้ที่นี่เช่นกัน
julianfperez

คำตอบ:


17

Matlab ตีความลำดับของการคูณและ / หรือดิวิชั่นจากซ้ายไปขวา ดังนั้นมีราคาแพงกว่าA ( B ( C v ) )เนื่องจากคุณมีผลิตภัณฑ์เมทริกซ์สองตัวและหนึ่งผลิตภัณฑ์เมทริกซ์ vecor แทนผลิตภัณฑ์เมทริกซ์เวกเตอร์สามตัวA* * * *B* * * ** * * *โวลต์A* * * *(B* * * *(* * * *โวลต์))

ในทางกลับกันควรจะเร็วกว่าเล็กน้อยถ้าคุณบันทึกตัวกลางในเวกเตอร์ที่แยกจากกันตามวิธีที่สองของคุณแนะนำA* * * *(B* * * *(* * * *โวลต์))

หากต้องการค้นหาโดยทั่วไปเกี่ยวกับวิธีวัดผลกระทบของความแตกต่างของการเขียนโปรแกรมขนาดเล็กในการคำนวณขนาดใหญ่ให้เขียนที่ Matlab prompt '' help profile ''


ขอบคุณสำหรับข้อมูลที่น่าสนใจที่ให้ไว้ในคำตอบของคุณ
julianfperez

ทำไมมันเร็วขึ้นถ้าคุณบันทึกคนกลาง?
Federico Poloni

@FedericoPoloni: ฉันเขียนว่ามันเร็วกว่าเล็กน้อยที่จะไม่บันทึกคนกลาง
Arnold Neumaier

@ArnoldNeumaier Ooh ขอโทษฉันอ่านผิด :)
Federico Poloni

14

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

ฉันลองสิ่งต่อไปนี้ใน Matlab:

>> N = 500;                                             
>> A = rand(N); B = rand(N); C = rand(N); v = rand(N,1);

>> tic, for k=1:100, A*B*C*v; end; toc
Elapsed time is 3.207299 seconds.

>> tic, for k=1:100, A*(B*(C*v)); end; toc
Elapsed time is 0.108095 seconds.

ฉันต้องบอกว่ามันค่อนข้างน่ากลัว ฉันคิดเสมอว่า Matlab จะฉลาดเกี่ยวกับลำดับการคูณเมทริกซ์เนื่องจากเป็นปัญหาที่ทราบด้วยวิธีแก้ปัญหาที่ง่ายและมีประสิทธิภาพ


คุณพลาดส่วนที่เมทริกซ์เป็น 3x3 หรือไม่? :)
Aron Ahmadia

2
@AronAhmadia: โอ๊ะ ... พลาดไปขอบคุณมาก ฉันเดาว่าขนาดเมทริกซ์เหล่านี้ปัญหาทั้งหมดเป็นสิ่งที่สงสัย แต่ฉันก็ยังประหลาดใจกับผลลัพธ์ของ N. ขนาดใหญ่
เปโดร

7
ฉันเดา MATLAB ทำตามกฎลำดับความสำคัญ C สำหรับการประเมินผลการแสดงออกเนื่องจากคณิตศาสตร์จุดลอยตัวไม่ได้เชื่อมโยงกันและพวกเขาต้องสมมติว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่ :)
Aron Ahmadia

2
@Pedro: ขอบคุณสำหรับคำตอบของคุณ สำหรับเมทริกซ์มิติ 3x3 ฉันได้ตรวจสอบแล้วว่าวิธีแก้ปัญหาของคุณดีกว่าการคูณเมทริกซ์ปกติ (โดยไม่ต้องวงเล็บ)
julianfperez

+1 ขอบคุณที่แสดงวิธีที่ง่ายและสะดวกในการวัดเวลารัน
Steven Magana-Zook

14

เนื่องจากเมทริกซ์มีขนาดเล็กค่าใช้จ่ายทั้งหมดจึงเป็นค่าใช้จ่ายในการโทร ถ้าคุณจะทำการเปลี่ยนแปลงหลายครั้งก็จะเร็วขึ้นเพื่อ precompute ครั้งแล้วสำหรับแต่ละเวกเตอร์ใช้D=A*B*C v_f=D*v_iคุณสามารถลองนำไฟล์นี้ไปใช้กับไฟล์ mex


ขอบคุณสำหรับคำตอบ. ในกรณีของฉันเมทริกซ์คือการหมุน (ขึ้นอยู่กับค่าเชิงมุมและการเปลี่ยนแปลงนี้) ดังนั้นผลิตภัณฑ์ A B C จะไม่เหมือนกันเสมอไป
julianfperez
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.