วันนี้เห็นมีกระทู้หนึ่งโผล่ในเว็บพันทิปเกี่ยวกับโจทย์เลขข้อหนึ่งดังแสดงในรูปข้างล่าง ในขณะที่เข้าไปดูนั้นผู้ถามก็ยังไม่ได้รับคำตอบว่าจะหาคำตอบได้อย่างไร ในกระทู้มีคนมาบอกแล้วว่าโจทย์ไม่ผิด รูปแบบสมการถูกต้องตามหลักคณิตศาสตร์ทุกอย่าง แล้วก็ให้แนวทางคร่าว ๆ ว่าควรต้องใช้วิธีการคำนวณเชิงตัวเลขในการหาคำตอบ
การแก้โจทย์ข้อนี้อยู่ในเรื่องการหาคำตอบของระบบสมการไม่เชิงเส้น ที่มี 1 สมการ 1 ตัวแปร ก็เลยจะทดลองใช้วิธีการง่าย ๆ ที่ไม่ต้องมีการคำนวณค่าอนุพันธ์ และสามารถทำการคำนวณบนโปรแกรม spreadsheet ได้ง่าย (เช่น excel หรือของ openoffice) คือระเบียบวิธีทำซ้ำแบบสืบเนื่องหรือ successive iteration
เริ่มจากจัดสมการให้อยู่ในรุป x = f(x) ก่อน
x(x+2) = 34x + 6(9(x+1))
(x + 2)ln(x) = ln(34x + 6(9(x+1)))
x = ln(34x + 6(9(x+1)))/ln(x) - 2
เนื่องจากมีพจน์ ln(x) ปรากฎ ดังนั้นค่า x ต้องมีค่ามากกว่าศูนย์
จากนั้นเดาค่าเริ่มต้น x (หรือ xtry) แทนค่าลงทางด้านขวาของเครื่องหมาย "=" ถ้าผลการคำนวณที่ได้ (คือ xcal) ตรงกับค่าที่เดา (xtry) ก็ถือว่าเจอคำตอบ แต่ถ้าพบว่าไม่ตรงกัน ก็ให้เอาค่า xcal ที่ได้นั้นมาใช้เป็น xtry แล้วทำการคำนวณต่อไปเรื่อย ๆ จนค่าทั้งที่เดากับค่าที่คำนวณได้นั้นลู่เข้าหากัน (ปล. มันอาจไม่ลู่เข้ากันก็ได้นะ ถ้าเลือกพจน์ที่จะให้เหลือเพียงแค่ x ทางด้านซ้ายของเครื่องหมาย "=" นั้นไม่เหมาะสม ถ้าเป็นเช่นนี้ก็ต้องลองเลือกพจน์ใหม่)
ตารางข้างล่างคือผลการคำนวณที่ได้ (คำนวนไปว่า 110 รอบ)
xtry |
f(xtry) = xcal |
2 |
11.4166655999 |
11.4166655999 |
18.6030505575 |
18.6030505575 |
25.9647810956 |
25.9647810956 |
33.0353033009 |
33.0353033009 |
39.5064398927 |
39.5064398927 |
45.2217478116 |
---------- |
---------- |
---------- |
---------- |
71.9197829085 |
71.9197829086 |
71.9197829086 |
71.9197829086 |
71.9197829086 |
71.9197829087 |
71.9197829087 |
71.9197829087 |
71.9197829087 |
71.9197829087 |
จากนั้นก็ทดสอบดูว่าคำตอบที่ได้นั้นถูกต้องหรือไม่ด้วยการเอาคำตอบที่ได้นั้น (71.9197829087) แทนลงไปในโจทย์ แต่การจะให้เครื่องคำนวณตัวเลขยกกำลัง ที่เลขยกกำลังมีค่ามากนั้นมันไม่เหมาะสม ก็เลยต้องขอปรับแต่งโจทย์เป็น
ln(x(x+2) - 6(9(x+1))) - ln(34x) = 0
ถ้าแทนค่า x ลงไปทางด้านซ้ายของเครื่องหมาย "=" แล้วได้คำตอบเป็นศูนย์ ค่านั้นก็เป็นค่าที่ถูกต้อง
ทีนี้จะลองหาคำตอบด้วยคำสั่ง fzero ของโปรแกรม GNU Octave ดูบ้าง
format longe กำหนดให้แสดงตัวเลขอย่างละเอียด
>> y = @(x) x^(x+2) - 6*9^(x+1) - 3^(4*x); กำหนดฟังก์ชัน
>> root = fzero(y,2) เริ่มหาจากจุด x = 2
error: fzero: zero point is not bracketed อัลกอริทึมไม่สามารถหาคำตอบได้
error: called from
fzero at line 377 column 7
>> root = fzero(y,5) ทดลองใหม่โดยเริ่มหาจากจุด x = 5
root = -2.495000000000000e+03 อัลกอริทึมให้คำตอบที่น่าสงสัย (-2495)
>> root = fzero(y,10) ทดลองใหม่โดยเริ่มหาจากจุด x = 10
root = 7.191978290886503e+01 ได้คำตอบเดียวกับระเบียบวิธีทำซ้ำแบบสืบเนื่องที่เริ่มจาก x = 2
>> root = fzero(y,15) ทดลองใหม่โดยเริ่มหาจากจุด x = 15
root = -7.350000000000000e+02 อัลกอริทึมให้คำตอบที่น่าสงสัย (-735)
>> root = fzero(y,20) ทดลองใหม่โดยเริ่มหาจากจุด x = 20
root = -9.800000000000000e+02 อัลกอริทึมให้คำตอบที่น่าสงสัย (-930)
>> root = fzero(y,25) ทดลองใหม่อีกโดยเริ่มหาจากจุด x = 25
root = 7.191978290886503e+01 ได้คำตอบเดียวกับระเบียบวิธีทำซ้ำแบบสืบเนื่องที่เริ่มจาก x = 2
>> root = fzero(y,30) ทดลองใหม่อีกโดยเริ่มหาจากจุด x = 30
root = 7.191978290886503e+01 ได้คำตอบเดียวกับระเบียบวิธีทำซ้ำแบบสืบเนื่องที่เริ่มจาก x = 2
จะเห็นว่าคำตอบที่ได้นั้นขิ้นอยู่กับจุดเริ่มต้นของการคำนวณ คำถามก็คือค่าที่น่าสงสัย (บรรดาค่าที่เป็นจำนวน "เต็ม" ที่ติดลบมาก ๆ ตรงที่ทำสีแดงเอาไว้) นั้นเป็นคำตอบที่ถูกต้องด้วยหรือไม่
ถ้าพิจารณาจากรูปแบบของสมการแล้ว ตัวเลขใดก็ตาม (ไม่ว่าจะมีค่าเป็นบวกหรือลบ) ถ้ายกกำลังด้วยเลขที่เป็นจำนวน "เต็ม" ที่มีค่ามากและติดลบ เลขนั้นจะมีค่าเข้าหาศูนย์ (พึงสังเกตว่าค่าน่าสงสัยต่าง ๆ ที่โปรแกรมคำนวณได้นั้นคำตอบออกมาเป็นจำนวนเต็ม) ดังนั้นค่าที่ทำสีแดงเอาไว้จึงไม่ควรเป็นตำแหน่งที่กราฟตัดแกน x แต่เป็นตำแหน่งที่อัลกอริทึมพบว่าค่าของสมการนั้น "เข้าใกล้" ศูนย์ในระดับที่อัลกอริทึมยอมรับได้ (แบบเดียวกับกราฟ y = 1/x ที่ไม่เคยตัดแกน x แต่จะมีค่า x ที่ทำให้ค่า y นั้นเข้าใกล้ศูนย์ไม่ว่าจะเป็นในระดับเท่าใดก็ตามที่เราต้องการ)
ในขณะที่ในบ้านเราในเต็มไปมีกระแสให้การสอนนั้นเน้นไปที่การใช้ชุดคำสั่งสำเร็จรูป แต่โดยส่วนตัวเห็นว่าการมีความรู้พื้นฐานต่าง ๆ ที่อยู่เบื้องหลังชุดคำสั่งสำเร็จรูปนั้นเป็นสิ่งสำคัญกว่า เพราะมันทำให้เราเห็นข้อจำกัดในการทำงานของชุดคำสั่งสำเร็จรูปเหล่านั้น และเมื่อได้คำตอบมาแล้วก็ควรทำการตรวจสอบความถูกต้อง (หรือความสมเหตุสมผล) ของคำตอบที่ได้มานั้นด้วยก่อนที่จะนำเอาคำตอบนั้นไปใช้งาน
หมายเหตุ
การใช้ฟังก์ชั้น fzero
ของโปรแกรม
GNU Octave
เคยเขียนไว้ในบทความเรื่อง
๑.
การคำนวณเชิงตัวเลข(๒๕)ตัวอย่างการแก้ปัญหาสมการพีชคณิตไม่เชิงเส้นด้วยFunction fzero ของGNU Octave (MOMemoir : Tuesday 4 February 2563) และ
๒.
การคำนวณเชิงตัวเลข(๒๙)เปรียบเทียบการแก้ปัญหาสมการพีชคณิตไม่เชิงเส้นด้วยsolver ของGNU Octave (MOMemoir : Tuesday 3 March 2563)
ซึ่งได้แสดงให้เห็นถึงปัญหาการหาคำตอบขอบสมการพีชคณิตไม่เชิงเส้น
ไม่มีความคิดเห็น:
แสดงความคิดเห็น