ทำไมกฎแห่งโคไซน์จึงเป็นที่นิยมมากกว่า Haversine เมื่อคำนวณระยะทางระหว่างจุดละติจูด - ลองจิจูดสองจุด


41

ในความเป็นจริงเมื่อ Sinnott เผยแพร่สูตร haversine ความแม่นยำในการคำนวณมี จำกัด ทุกวันนี้ JavaScript (และคอมพิวเตอร์และภาษาที่ทันสมัยที่สุด) ใช้เลขทศนิยมแบบ 64 บิตของ IEEE 754 ซึ่งให้ความแม่นยำ 15 ตัวเลขที่สำคัญ ด้วยความแม่นยำนี้กฎหมายทรงกลมเรียบง่าย ของสูตรโคไซน์ ( cos c = cos a cos b + sin a sin b cos C) ให้ผลลัพธ์ที่มีสภาพดีไปจนถึงระยะทางที่มีขนาดเล็กเพียงประมาณ 1 เมตร ในมุมมองนี้มันอาจจะคุ้มค่าในสถานการณ์ส่วนใหญ่โดยใช้กฎที่เรียบง่ายของโคไซน์หรือสูตรรูปไข่ทรงรีที่แม่นยำยิ่งขึ้นเพื่อใช้กับแฮเวอร์ซีน! (โปรดจำไว้ว่าข้อ จำกัด ด้านความแม่นยำของแบบจำลองทรงกลมด้านล่าง)
ที่มา: http://www.movable-type.co.uk/scripts/latlong.html

ทำไมกฎโคไซน์จึงเป็นที่นิยมมากกว่า?

หมายเหตุ:ข้อความที่ยกมาได้รับการปรับปรุงโดยผู้เขียนดังกล่าวข้างต้น


10
กฎแห่งโคไซน์ "เป็นที่นิยม" เป็นอย่างไร เราสามารถตอบคำถามนี้ได้สองวิธี: สำหรับคอมพิวเตอร์และโปรแกรมเมอร์ สำหรับคอมพิวเตอร์สูตร haversine ใช้ฟังก์ชั่นตรีโกณมิติน้อยลง แต่ต้องการรากที่สอง สำหรับประสิทธิภาพในการคำนวณแล้วมันคือการโยน สำหรับโปรแกรมเมอร์โปรแกรมเมอร์สูตรแฮเวอรีนนั้นยาวกว่านี้เล็กน้อย อย่างไรก็ตามกฎของสูตรโคไซน์ต้องมีการนำ ACos มาใช้ซึ่งพบได้น้อยกว่าการใช้ ATan เล็กน้อย นอกจากนี้ในการเขียนรหัส bulletproof คุณต้องตรวจสอบว่า ACos จะไม่ล้มเหลว ด้วยเหตุผลนี้เพียงอย่างเดียวเราควรเลือก haversine
whuber

2
ฉันเพิ่งใช้ haversine และ cosine ใน Python ในคอมพิวเตอร์เครื่องนี้แฮเวอรีนใช้เวลา 3.3 μsและโคไซน์ใช้เวลา 2.2 μsซึ่งค่อนข้างสำคัญหากคุณจำเป็นต้องทำมันให้มาก
gnibbler

1
ขอขอบคุณทุกคนสำหรับข้อสังเกตและข้อมูลที่ดี ฉันได้อัปเดตข้อความที่ยกมาในคำถามว่าฉันหวังว่าจะเป็นวัตถุประสงค์และเป็นประโยชน์มากกว่า
ChrisV

@ChrisV ขอบคุณสำหรับการอัปเดต! ฉันได้ย้ายสิ่งนี้ไปยังความคิดเห็นเนื่องจากมันไม่ใช่คำตอบสำหรับคำถามโดยตรงขอบคุณสำหรับเว็บไซต์ที่ยอดเยี่ยมของคุณ
scw

คำตอบ:


48

ปัญหานี้เกิดจากคำว่า "มีสภาพดี" มันเป็นปัญหาของการคำนวณทางคณิตศาสตร์ไม่ใช่คณิตศาสตร์

นี่คือข้อเท็จจริงพื้นฐานที่ควรพิจารณา:

  1. หนึ่งเรเดียนบนพื้นโลกมีความยาวเกือบ 10 ^ 7 เมตร

  2. ฟังก์ชันโคไซน์สำหรับอาร์กิวเมนต์xใกล้ 0 มีค่าประมาณเท่ากับ 1 - x ^ 2/2

  3. ทศนิยมที่มีความแม่นยำสองเท่ามีความแม่นยำประมาณ 15 หลัก

คะแนน (2) และ (3) บอกเป็นนัยว่าเมื่อxประมาณหนึ่งเมตรหรือ 10 ^ -7 เรเดียน (จุด 1) ความแม่นยำเกือบทั้งหมดจะหายไป: 1 - (10 ^ -7) ^ 2 = 1 - 10 ^ - 14 คือการคำนวณที่ 14 หลักแรกของ 15 หลักสำคัญทั้งหมดยกเลิกโดยเหลือเพียงหนึ่งหลักเพื่อแสดงผลลัพธ์ พลิกสิ่งนี้ไปรอบ ๆ (ซึ่งเป็นสิ่งที่ตรงกันข้ามโคไซน์ "acos" ทำ) หมายความว่าการคำนวณ acos สำหรับมุมที่สอดคล้องกับระยะทางเมตรยาวไม่สามารถทำได้ด้วยความแม่นยำที่มีความหมายใด ๆ (ในบางกรณีที่ไม่ดีการสูญเสียความแม่นยำให้ค่าที่ไม่ได้กำหนด acos ดังนั้นโค้ดจะพังลงและไม่ให้คำตอบคำตอบไร้สาระหรือเครื่องขัดข้อง) ข้อควรพิจารณาที่คล้ายกันแนะนำให้คุณหลีกเลี่ยงการใช้ inverse cosine หากระยะทางน้อยกว่าสองสามร้อยเมตรขึ้นอยู่กับความแม่นยำที่คุณยินดีเสีย

บทบาทที่เล่นโดย acos ในสูตร law-of-cosines ที่ไร้เดียงสาคือการแปลงมุมเป็นระยะทาง บทบาทนั้นเล่นโดย atan2 ในสูตรแฮเวอรีน แทนเจนต์ของมุมเล็ก ๆxจะประมาณเท่ากับxตัวเอง ดังนั้นค่าผกผันแทนเจนต์ของตัวเลขจะอยู่ที่ประมาณนั้นโดยคำนวณโดยไม่มีการสูญเสียความแม่นยำ นี่คือเหตุผลว่าทำไมสูตรแฮเวอรีนถึงแม้ว่าคณิตศาสตร์จะเทียบเท่ากับกฎของโคไซน์สูตร แต่มันก็ยอดเยี่ยมสำหรับระยะทางขนาดเล็ก (ตามลำดับ 1 เมตรหรือน้อยกว่า)

นี่คือการเปรียบเทียบของสองสูตรโดยใช้ 100 จุดคู่แบบสุ่มบนโลก (โดยใช้การคำนวณความแม่นยำสองเท่าของ Mathematica)

ข้อความแสดงแทน

คุณสามารถเห็นได้ว่าสำหรับระยะทางน้อยกว่า 0.5 เมตรสูตรทั้งสองแตกต่างกัน สูงกว่า 0.5 เมตรพวกเขามีแนวโน้มที่จะเห็นด้วย เพื่อแสดงให้เห็นว่าพวกเขาเห็นด้วยอย่างใกล้ชิดโครงเรื่องต่อไปจะแสดงอัตราส่วนของกฎของโคไซน์: ผลของแฮเวอร์ซีนสำหรับจุดสุ่มอีก 100 คู่โดยมีละติจูดและลองจิจูดยาวแตกต่างกันถึง 5 เมตร

ข้อความแสดงแทน

นี่แสดงให้เห็นว่ากฎของโคไซน์สูตรดีถึงทศนิยม 3-4 ตำแหน่งเมื่อระยะทางเกิน 5-10 เมตร จำนวนตำแหน่งทศนิยมที่แม่นยำเพิ่มขึ้นเป็นสองเท่า ดังนั้นที่ 50-100 เมตร (หนึ่งคำสั่งของขนาด) คุณจะได้รับความถูกต้อง 5-6 dp (สองคำสั่งของขนาด); ที่ 500-1,000 เมตรคุณจะได้รับ 7-8 dp เป็นต้น


มีการทดสอบราคาถูก - เช่นdelta latitude > .1 || delta longitude > .1เลือกแบบโคไซน์ (สำหรับขนาดใหญ่) หรือแบบแฮร์ซีน (แบบระยะทางขนาดเล็ก) แบบไดนามิกหรือไม่? เพื่อให้ได้ประสิทธิภาพที่ดีที่สุดและแม่นยำดี
Anony-Mousse

@ Anony-Mousse ทั้งสองสูตรสามารถปิดได้ประมาณสองในสิบของหนึ่งเปอร์เซ็นต์สำหรับระยะทางหนึ่งในสี่ของโลกดังนั้นถ้าอย่างนั้นเราจะไม่ต้องวุ่นวายกับความแม่นยำอีกต่อไป! ดังนั้นการทดสอบใด ๆ ที่สามารถแยกความแตกต่างของจุดปิด (ไม่กี่ร้อยเมตร) จากจุดที่อยู่ตรงข้ามกับแนวทแยงมุม (ประมาณ 20 ล้านเมตร) จากทุกสิ่งในระหว่างนั้นควรเพียงพอ
whuber

ไม่atan2นำเสนอผลประโยชน์ตัวเลขมากกว่าasin? ฉันเห็นเกณฑ์มาตรฐานซึ่งatan2ช้ากว่า 2-3 เท่าasinและเราก็ต้องการวินาทีsqrtเช่นกัน
Erich Schubert

@Erich ฉันไม่ได้ศึกษาความแตกต่าง แต่ทราบว่าasinเป็นสิ่งเดียวกับacosและดังนั้นจึงทนทุกข์ทรมานจากการสูญเสียความแม่นยำเดียวกันสำหรับค่าบางอย่าง - ในกรณีนี้สำหรับข้อโต้แย้งที่อยู่ใกล้ 1 และ -1 โดยหลักการแล้วatan2ไม่มีปัญหานั้น
whuber

นั่นจะอยู่ในระยะทางที่ไกลมาก ๆ ? การรวมเข้ากับคำแนะนำของ @ Anony-Mousse ด้านบนนั้นน่าสนใจ
Erich Schubert

6

เชิงประวัติศาสตร์:

haversine เป็นวิธีหนึ่งในการหลีกเลี่ยงข้อผิดพลาดในการคำนวณเช่น

1 - cos(x)

เมื่อ x เล็ก ในแง่ของ haversine เรามี

1 - cos(x) = 2*sin(x/2)^2
           = 2*haversin(x)

และ 2 * sin (x / 2) ^ 2 สามารถคำนวณได้อย่างแม่นยำแม้เมื่อ x มีขนาดเล็ก

ในสมัยก่อนสูตรแฮเวอรีนมีข้อได้เปรียบเพิ่มเติมในการหลีกเลี่ยงการเติม (ซึ่งมีการค้นหา antilog, การเพิ่มและการค้นหาบันทึก) สูตรวิชาตรีโกณมิติซึ่งกล่าวถึงการคูณหลายครั้งนั้นถูกกล่าวว่าเป็น "รูปแบบลอการิทึม"

ทุกวันนี้การใช้สูตรแฮเวอรีนนั้นผิดปกติเล็กน้อย มันอาจเป็นไปได้ว่ามุม x แสดงด้วยเงื่อนไขsin(x)และcos(x)(และ x อาจไม่เป็นที่รู้จักอย่างชัดเจน) ในกรณีนั้นการคำนวณ1 - cos(x)โดยใช้สูตรแฮเวซีนจะสร้างอาร์คแทนเจนต์ (เพื่อให้ได้มุม x), ลดครึ่ง (เพื่อให้ได้x/2), ไซน์ (เพื่อให้ได้sin(x/2)), สี่เหลี่ยมจัตุรัส (เพื่อให้ได้sin(x/2)^2) และการเสแสร้งครั้งสุดท้าย คุณทำได้ดีกว่ามากเมื่อใช้การประเมิน

1 - cos(x) = sin(x)^2/(1 + cos(x))

ซึ่งไม่มีการประเมินผลฟังก์ชั่นตรีโกณมิติ (เห็นได้ชัดว่าใช้ด้านขวามือเฉพาะในกรณีที่cos(x) > 0; มิฉะนั้นจะใช้ได้ 1 - cos(x)โดยตรง)


1

สูตรโคไซน์สามารถนำมาใช้ในหนึ่งบรรทัด:

  Distance = acos(SIN(lat1)*SIN(lat2)+COS(lat1)*COS(lat2)*COS(lon2-lon1))*6371

สูตรแฮเวอรีนมีหลายบรรทัด:

  dLat = (lat2-lat1)
  dLon = (lon2-lon1)
  a = sin(dLat/2) * sin(dLat/2) + cos(lat1) * cos(lat2) * sin(dLon/2) * sin(dLon/2)
  distance = 6371 * 2 * atan2(sqrt(a), sqrt(1-a))

ทางคณิตศาสตร์มีเหมือนกันดังนั้นความแตกต่างเพียงอย่างเดียวคือการปฏิบัติจริง


แม้ว่า Haversine ดั้งเดิมจะไม่ใช้atan2สูตรที่เกี่ยวข้องกับคอมพิวเตอร์แต่ก็ไม่มีสิ่งใดที่ขัดขวางไม่ให้เขียน 4 บรรทัดข้างต้นเป็นสูตรเดี่ยว
Arjan

@Arjan ทรู แต่มันจะไม่ได้ผลเพราะคุณจะต้องคำนวณสองครั้ง จำเป็นอย่างยิ่งที่สูตรจะต้องมีทั้ง Sqrt (a) และ Sqrt (1-a) เนื่องจากแม้ว่าหนึ่งในนั้นจะไม่เสถียรเชิงตัวเลขสำหรับระยะทางที่เล็กมากหรือใหญ่มาก แต่อีกวิธีหนึ่งก็ไม่ได้เป็นเช่นนั้น
whuber

เป็นจริง, @ โฮเบอร์ แต่ถึงกระนั้นฉันก็ยังสงสัยว่าจำนวนบรรทัดจะทำให้ฉันเลือกอีกอันหนึ่ง (และเหมือนคุณกำลังอธิบายอยู่แล้วในของคุณคำตอบที่มีความสำคัญมากขึ้นด้วยเหตุผลเพื่อให้ประโยชน์แก่คนหนึ่ง.)
Arjan

3
@Arjan ฉันเห็นด้วย สิ่งสำคัญอันดับแรกควรมีความเพียงพอของรหัสสำหรับงานการเขียนโปรแกรม หลังจากนั้นฉันจะวางความชัดเจน: นั่นคือเอกสารที่สามารถอ่านได้การบำรุงรักษาและความรู้ ขาดบริบทดังกล่าวการนับจำนวนบรรทัดของโค้ดนั้นไม่มีความหมาย
whuber

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