การใช้ความแม่นยำสองเท่าอย่างรวดเร็วและแม่นยำของฟังก์ชันแกมมาที่ไม่สมบูรณ์


10

อะไรคือวิธีที่ทันสมัยในการใช้งานฟังก์ชั่นพิเศษที่มีความแม่นยำสองเท่า ฉันต้องการอินทิกรัลต่อไปนี้: สำหรับและซึ่งสามารถเขียนได้ในรูปของฟังก์ชันแกมม่าที่ไม่สมบูรณ์ต่ำกว่า นี่คือการใช้ Fortran และ C ของฉัน:เมตร=0,1,2, . . t>0

Fm(t)=01u2metu2du=γ(m+12,t)2tm+12
m=0,1,2,...t>0

https://gist.github.com/3764427

ซึ่งใช้การขยายตัวชุดแง่บวกขึ้นจนความถูกต้องให้แล้วใช้ความสัมพันธ์ที่เรียกซ้ำได้อย่างมีประสิทธิภาพได้รับค่าที่ต่ำกว่าม.ฉันทดสอบได้ดีและได้รับความแม่นยำ 1e-15 สำหรับค่าพารามิเตอร์ทั้งหมดที่ฉันต้องการดูความคิดเห็นของรุ่น Fortran สำหรับรายละเอียดm

มีวิธีที่ดีกว่าในการใช้หรือไม่ นี่คือการใช้ฟังก์ชั่นแกมม่าใน gfortran:

https://github.com/mirrors/gcc/blob/master/libgfortran/intrinsics/c99_functions.c#L1781

มันใช้การประมาณฟังก์ชั่นเหตุผลแทนการสรุปซีรีย์อนันต์ที่ฉันกำลังทำอยู่ ฉันคิดว่านั่นเป็นวิธีที่ดีกว่าเพราะเราควรได้ความแม่นยำที่สม่ำเสมอ มีวิธีบัญญัติวิธีบางประการหรือไม่หรือต้องคิดอัลกอริธึมพิเศษสำหรับแต่ละฟังก์ชั่นพิเศษหรือไม่?

อัปเดต 1 :

ตามความคิดเห็นนี่คือการใช้ SLATEC:

https://gist.github.com/3767621

มันจำลองค่าจากฟังก์ชั่นของฉันเองโดยประมาณในระดับความแม่นยำ 1e-15 อย่างไรก็ตามฉันสังเกตเห็นปัญหาว่าสำหรับ t = 1e-6 และ m = 50 คำว่าได้รับเท่ากับ 1e-303 และสำหรับ "m" ที่สูงขึ้นมันก็เริ่มให้คำตอบที่ไม่ถูกต้อง ฟังก์ชั่นของฉันไม่ได้มีปัญหานี้เพราะผมใช้การขยายตัวชุด / การกำเริบความสัมพันธ์โดยตรงF_mนี่คือตัวอย่างของค่าที่ถูกต้อง: Fmtm+12Fm

F100(1e-6)=4.97511945200351715E-003 ,

แต่ฉันไม่สามารถรับสิ่งนี้โดยใช้ SLATEC เพราะตัวส่วนระเบิด อย่างที่คุณเห็นค่าจริงของนั้นดีและเล็กFm

อัปเดต 2 :

เพื่อหลีกเลี่ยงปัญหาดังกล่าวข้างต้นหนึ่งสามารถใช้ฟังก์ชั่นdgamit(ไม่สมบูรณ์ฟังก์ชันแกมมา Tricomi ของ) จากนั้นF(m, t) = dgamit(m+0.5_dp, t) * gamma(m+0.5_dp) / 2จึงมีปัญหาเกี่ยวกับการไม่มีอีกต่อไป แต่โชคร้ายพัดขึ้นสำหรับ172 อย่างไรก็ตามเรื่องนี้อาจจะสูงพอเพื่อฉันm 172 mtgamma(m+0.5_dp)m172m


2
ทำไมรหัสฟังก์ชั่นของคุณเอง? GSL, cephes และ SLATEC นำไปใช้ทั้งหมด
Geoff Oxberry

ฉันได้อัปเดตคำถามที่ว่าทำไมฉันไม่ใช้ SLATEC
OndČejČertík

@ OndřejČertíkคุณค้นพบข้อผิดพลาดอย่างเห็นได้ชัด! ลงทะเบียนคำถามของคุณ!
Ali

Ali --- ไม่ใช่ข้อผิดพลาดใน SLATEC แต่ที่จริงแล้วฉันต้องแบ่งด้วยเพื่อรับค่าt) ดังนั้นวิธีการที่เป็นตัวเลขที่ผลงานอาจจะไม่ทำงานให้ดีสำหรับ(t) t m + 1γ(z,x) Fm(t)γ(z,x)Fm(t)tm+12Fm(t)γ(z,x)Fm(t)
OndřejČertík

@ OndřejČertíkตกลงขอโทษฉันเข้าใจผิดฉันไม่ได้ตรวจสอบรหัสของคุณก่อนที่จะแสดงความคิดเห็น
Ali

คำตอบ:


9

อินทิกรัลที่เป็นที่รู้จักนั้นรู้จักกันในชื่อฟังก์ชั่น Boys หลังจากนักเคมีชาวอังกฤษซามูเอลฟรานซิสบอยซึ่งแนะนำการใช้งานในต้นปี 1950 ไม่กี่ปีที่ผ่านมาฉันต้องคำนวณฟังก์ชั่นนี้ด้วยความแม่นยำสองเท่าเร็วที่สุดเท่าที่จะเป็นไปได้ แต่แม่นยำ ฉันจัดการเพื่อให้เกิดข้อผิดพลาดแบบสัมพัทธ์ในลำดับในโดเมนอินพุตทั้งหมด1015

มันเป็นเรื่องปกติที่จะใช้ข้อได้เปรียบประการแตกต่างกันสำหรับการขัดแย้งเล็กและขนาดใหญ่ที่ดีที่สุดสวิทช์ในช่วงระหว่าง "ใหญ่" และ "เล็ก" ที่ดีที่สุดคือการพิจารณาการทดลองและอยู่ในฟังก์ชั่นทั่วไปของม.สำหรับรหัสของฉันฉันกำหนด "เล็ก" มีปากเสียงกับผู้ที่สภาพความพึงพอใจ2}a m + 1 1mam+112

สำหรับข้อโต้แย้งที่มีขนาดใหญ่ฉันคำนวณ

Fm(a)=12γ(m+12,a)×p×p,  p=a12(m+12)

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

γ(m+12,a)=Γ(m+12)Γ(m+12,a)

ใช้ค่าแบบตารางของและการคำนวณตาม คำตอบนี้ในขณะที่หลีกเลี่ยงปัญหาอย่างระมัดระวัง ของการยกเลิกการลบด้วยการใช้การดำเนินการเพิ่มทวีคูณผสม เพิ่มประสิทธิภาพต่อไปที่อาจเกิดขึ้นคือการสังเกตว่าสำหรับขนาดใหญ่พอ,ภายใน ความแม่นยำจุดลอยตัวที่กำหนดΓ(m+1Γ(m+12)aγ(m+1Γ(m+12,a)aγ(m+12,a)=Γ(m+12)

สำหรับข้อโต้แย้งเล็ก ๆ ฉันเริ่มต้นด้วยการขยายอนุกรมสำหรับฟังก์ชันแกมม่าที่ไม่สมบูรณ์ต่ำกว่า

A. Erdelyi, W. Magnus, F. Oberhettinger และ FG Tricomi, "ฟังก์ชั่นยอดเยี่ยมระดับสูง, เล่ม 2" นิวยอร์ก, นิวยอร์ก: McGraw-Hill 2496

และแก้ไขเพื่อคำนวณฟังก์ชัน Boysดังต่อไปนี้ (ตัดชุดเมื่อคำมีขนาดเล็กพอสำหรับความแม่นยำที่กำหนด):Fm(a)

Fm(a)=121m+12exp(a)(1+n=1an(1+m+12)× ... ×(n+m+12))

นอกจากนี้ยังมีที่น่าสนใจและมีความสำคัญที่อาจเป็นกรณีพิเศษสำหรับการสั่งซื้อต่ำของฟังก์ชั่นบอยโดยเฉพาะอย่างยิ่ง3 อันดับแรกเรามีโดยที่เป็นฟังก์ชั่นข้อผิดพลาดที่ให้ไว้ใน Fortran ปี 2008 เป็นฟังก์ชั่นธาตุและ C / C ++ เป็นฟังก์ชั่นมาตรฐานห้องสมุดและm=0,1,2,3F0(a)=π4aerf(a)erfERFerferff

สำหรับการคำนวณอย่างรวดเร็วเมื่อฉันใช้การประมาณค่าพหุนามกำหนดเองสำหรับอาร์กิวเมนต์ขนาดเล็กพูดและเรียกซ้ำสำหรับคนที่มีขนาดใหญ่ ซึ่งปัญหาเกี่ยวกับการยกเลิกการลบออกในภายหลังจะลดลงโดยการใช้การดำเนินการเพิ่มทวีคูณm=1,2,3a<212Fm(a)=12a((2m1)Fm1(a)exp(a))

ไหนค่าฟังก์ชั่นจะต้องมีการคำนวณที่กำหนดข้ามคำสั่งซื้อหลายหนึ่งต้องการที่จะคำนวณค่าฟังก์ชั่นสำหรับค่าสูงสุดของโดยตรงคือตามที่กล่าวไว้ข้างต้นแล้วใช้มีเสถียรภาพตัวเลขย้อนหลัง recursionเพื่อคำนวณ ค่าฟังก์ชั่นอื่น ๆ ทั้งหมดammFm1=12m1(2a Fm(a)+exp(a))


ขอบคุณ @njuffa สำหรับคำตอบที่ยอดเยี่ยม หากคุณสร้างรหัสของคุณสำหรับโอเพ่นซอร์สนี้ฉันคิดว่ามันจะมีประโยชน์มากสำหรับผู้คนจำนวนมาก
OndřejČertík

1
ปัจจุบันการใช้งานอัลกอริธึมของ CUDA ที่อธิบายไว้นั้นสามารถดาวน์โหลดได้ฟรีจากเว็บไซต์นักพัฒนาของ NVIDIA (ต้องลงทะเบียนฟรีในฐานะนักพัฒนา CUDA โดยปกติจะอนุมัติภายในหนึ่งวันทำการ) รหัสอยู่ภายใต้ใบอนุญาต BSD ซึ่งควรเข้ากันได้กับโครงการประเภทใดก็ได้
njuffa


4

ฉันจะดูที่หนังสือของ Abramowicz & Stegun หรือการปรับปรุงใหม่ที่ NIST ได้ตีพิมพ์เมื่อสองสามปีที่ผ่านมาและฉันก็เชื่อว่ามีออนไลน์ พวกเขายังหารือถึงวิธีการนำสิ่งต่าง ๆ ไปใช้อย่างมั่นคง


ฉันใช้สิ่งนี้: dlmf.nist.gov/8เมื่อใช้งาน แต่นั่นอาจเป็นแหล่งข้อมูลอื่น บทที่ 5 ในสูตรตัวเลขยังมีข้อมูลที่น่าสนใจ แต่สามารถใช้ได้กับฟังก์ชั่นของตัวแปรเดียวเท่านั้น
OndřejČertík

ฉันไม่คิดว่าคุณจะพบอะไรที่เร็วกว่าการอ้างอิงปี 2001 SLATEC จะเก่ากว่านั้น
Geoff Oxberry

1

ดูเหมือนจะไม่ทันสมัยแต่SLATECที่ Netlib นำเสนอ "ขั้นตอนการคำนวณทางคณิตศาสตร์และสถิติทั่วไป 1,400 จุด" ไม่สมบูรณ์แกมมาอยู่ภายใต้ฟังก์ชั่นพิเศษที่นี่

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

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