415
คํานวณและแกปญหาทางฟสิกส ดวยโปรแกรมภาษา ซี วัชระ รอดสัมฤทธิภาควิชาฟสิกส คณะวิทยาศาสตร มหาวิทยาลัยเทคโนโลยีราชมงคล คลองหก ธัญบุรี ปทุมธานี

คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

คานวณและแกปญหาทางฟสกส ดวยโปรแกรมภาษา ซ

วชระ รอดสมฤทธ

ภาควชาฟสกส คณะวทยาศาสตร มหาวทยาลยเทคโนโลยราชมงคล

คลองหก ธญบร ปทมธาน

Page 2: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

หนงสอปรบปรงเปนใหเปน Ms Office 2003 และ pdf file format เมอ มนาคม 2548

Page 3: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

คานา ( เมอครงเผยแพรครงแรก พ.ศ. 2540)

การเรยนรและแกปญหาทางฟสกสในปจจบน เปลยนจากยคทใชไมบรรทดคานวณ

และเครองคดเลข มาเปนเครองคอมพวเตอร หนงสอเลมนจะนาภาษาคอมพวเตอรทเรยกวา ภาษา C

มาเขยนเปนโปรแกรมเพอใหคอมพวเตอรทางานตามทกาหนดไว โดยมจดประสงคหลกดงตอไปน

• นกศกษาสามารถนาโปรแกรมเหลานไปใชในการคานวณและแกปญหาทางฟสกส ทง

ภาคทฤษฎและปฏบต จะชวยลดเวลาการคานวณ มเวลาคนควาหาความรเพมเตมไดมาก

ขน สามารถศกษาปญหานนไดลกซงกวาเดม จาลองสถานการณเพมเตมในปญหานน ๆ

โจทยตาง ๆ ทนามาเปนตวอยางจะเปนปญหาทพบในการเรยนการสอนวชา ฟสกส 1 (กล

ศาสตร เทอรโมไดนามกส) ฟสกส 2 (แมเหลกไฟฟา แสง) ฟสกสยคใหม รวมทงขอมลทได

จากการทดลองในหองปฏบตการฟสกส

• เพอเปนการแนะนาวธคานวณเชงตวเลขแกนกศกษา ในแตละบทจะแทรกความร

เกยวกบการคานวณเชงตวเลขไวอยางละเอยดพอสมควร แสดงรายละเอยดของโปรแกรม

ของแตละวธ นกศกษาสามารถทาความเขาใจ เลอกใชโปรแกรม หรอนาไปแกไขดดแปลงให

เหมาะกบงานอน ๆ ในสาขาทตนเรยนอย นอกจากนยงทาใหนกศกษาไดมโอกาสนา

ความรเกยวกบการเขยนโปรแกรมคอมพวเตอรทไดเรยนมาแลว มาใชประโยชนในงาน

คานวณและประมวลผลขอมลทไมซบซอนมากนกไดอกดวย

• ตองการใหเกดการใชงานคอมพวเตอรใหไดประโยชนและคมคามากทสด และมซอฟตแวรท

สรางเองไวใชงาน คอมพวเตอรรนเกาทมหนวยประมวลผลตากวา 80386 ลงมามกจะถก

ละเลยวางไวโดยไมไดใชประโยชน สามารถนาคอมพวเตอรเหลานนมาใชในงานดาน

คานวณได โปรแกรมในหนงสอเลมนจะเปนเสมอน “คลงโปรแกรม”

ผเขยนโปรแกรมสามารถหยบไปใชในโปรแกรมของตนเองไดทนท การใชงานฟงกชนตาง

ๆ จะกลาวไวอยางละเอยดในแตละบท เปนการชวยลดขนตอนการพฒนาโปรแกรม

ผเขยนหวงเปนอยางยงวาโปรแกรมเหลานนาจะมสวนชวยใหคนไทยไดชวยเหลอตนเองใน

เบองตน ถงแมในปจจบนเรามโปรแกรมประเภทตารางคานวณ เชน Excel หรอ Lotus

โปรแกรมทางคณตศาสตร เชน MathCad Maple หรอ Mathematica ชวยในงาน

คานวณ แตนนหมายถงตองซอซอฟตแวรจากตางประเทศ คอมพวเตอรทใชงานตองเปน

คอมพวเตอรรนใหม ราคาแพง ใชกบโปรแกรมวนโดวได

เนอหาของหนงสอเลมนจะแบงเปนบทตามลกษณะวธการแกปญหาทางคณตศาสตร

เรมตนดวย ขอพงระวงในการใชคอมพวเตอรในงานคานวณ การหารากสมการแบบไมเปนเชงเสน การ

หาผลเฉลยของระบบสมการเชงเสน การหาอนพนธอนดบหนงและการอนทเกรต การประมาณคา

Page 4: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

ในชวง การประมาณคาโดยวธกาลงสองนอยทสดและการคานวณคาสถตเบองตน ถาตองการศกษา

เจาะตรงปญหาทางฟสกส สามารถดไดจากสารบญทจาแนกตามปญหาทางฟสกสไดเชนกน ในแตละ

บทจะบอกวธการนาฟงกชนไปใชงาน ตวอยางและโปรแกรม แสดงใหเหนวาการแกปญหาทาไดอยางไร

แสดงผลลพธทไดจากการคานวณของคอมพวเตอร และคาแทจรงทไดจากวธวเคราะหทางคณตศาสตร

โปรแกรมทงหมดมอยในแผนดสกทแนบตดไวกบปกหลงดานในของหนงสอน ตวอยางบางตวอยาง

ผเขยนมไดสรางเปนโปรแกรมทคอมพวเตอรสามารถนาไปทางานไดเลย หรอ Execute file นกศกษา

ตองคอมไพลดวยตนเอง ทงนเพราะถากระทาเชนนกบตวอยางทกตวอยางจะตองใชแผนดสกบรรจ

โปรแกรม 4 - 5 แผน ตวอยางใดทมโปรแกรมแสดงการคานวณอยในแผนดสก จะแสดงไวดวย

สญลกษณ ทหนาตวอยางนน ๆ

รายชอโปรแกรมทมอยในแผนดสก ดไดจากหนาทายสดของหนงสอเลมน

ในการใชโปรแกรมในหนงสอเลมน นกศกษาควรมความรพนฐานในการใชงาน

คอมพวเตอรเบองตน การใชคาสงในระบบปฏบตการ DOS สามารถคอมไพลโปรแกรม

ภาษาคอมพวเตอรใหเปน execute file ได

คอมพวเตอรทสามารถใชโปรแกรมในหนงสอนเปนคอมพวเตอรแบบ PC มหนวย

ประมวลผลตงแต 8086 ขนไป หนวยความจาเพยง 1 เมกกะไบตหรอมากกวาน ถาไมมฮารดดสก ควรม

เครองขบแผนดสกแบบ 5.25 นว หรอ 3.5 นว 2 ชด จอภาพชนดใดกได ยกเวนถาตองการแสดงผลเปน

ภาษาไทยดงในภาคผนวก 4 ตองใชจอภาพแบบ VGA เทานน มคอมไพเลอร เทอรโบ ซ (Turbo C) รน

2.0 ขนไป ผเขยนไดใชเทอรโบ ซรนนเปนตวคอมไพลโปรแกรมทงหมดและไดทดลองใช เทอรโบ ซ ++

รน 1.0 และบอรแลนด ซ รน 3.10 พบวาไมเกดปญหาแตอยางใด

โปรแกรมทกโปรแกรมในหนงสอน ผเขยนไดใชงานในดานคานวณทางดานฟสกส

สาหรบการสอนมาตงแต พ.ศ. 2530 สมยนนยงเขยนเปนภาษาเบสก ตอมาไดปรบปรงเปลยนมาเปน

ภาษา C ไดนาไปใชในหองปฏบตการฟสกสเพอคานวณขอมลทไดจากการทดลอง ของนกศกษา ได

ผานการใชงานโดยนกศกษาบางสวนทเรยนวชา Numerical Analysis และคณตศาสตรบางรายวชา ได

แกไขขอบกพรองเรอยมา คดวาความบกพรองคงจะเหลอนอยทสดหรอไมมเลย โปรแกรมเหลาน

ผเขยนขอมอบใหเปนสาธารณะประโยชนสาหรบการศกษา ผใชสามารถนาไปใชงานหรอแกไขดดแปลง

ใหเหมาะกบงานไดทนท แตถาพบขอบกพรองหรอตองการแลกเปลยนความร ความคดเหนใด กรณา

ชวยแจงใหผเขยนไดทราบดวยจะเปนพระคณอยางยง

วชระ รอดสมฤทธ ภาควชาวทยาศาสตร สถาบนเทคโนโลยราชมงคล

Page 5: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

สารบญ บทท หนา 1 ขอพงระวงเมอใชคอมพวเตอรกบงานคานวณ 1 1.1 ความคลาดเคลอน ความแมนยา และความเทยงตรง 1 1.2 การเกบตวเลขในคอมพวเตอร 8 1.3 การลดความคลาดเคลอนทเกดจากการปดเศษ 13 1.4 ขอพงระวงบางประการในการใชคาสงภาษาซ 16 2 การหารากสมการแบบไมเปนเชงเสน 23 2.1 รปแบบและรากสมการแบบไมเปนเชงเสน 23 2.2 วธแบงครงชวง 26 2.3 วธวางตาแหนงผดท 35 2.4 การกาหนดชวงตวเลขทมคารากสมการ 42 2.5 วธนวตน-ราฟสน 46 2.6 วธเซแคนต 57 2.7 การนาไปแกปญหาทางฟสกส 63 2.8 บทสรป 68 3 การหาผลเฉลยของระบบสมการเชงเสน 69 3.1 ระบบสมการเชงเสน 69 3.2 กฎของคราเมอร 70 3.3 การลดทอนของเกาส และเกาส-จดอง 71 3.4 การสลบแถวเพอลดความคลาดเคลอน 75 3.5 ลกษณะของผลเฉลยของระบบสมการเชงเสน 91 3.6 วธแยกเปนเมตรกซสามเหลยมลางและบน 94 3.7 วธเกาส-ไซเดล 106 3.8 การนาไปแกปญหาทางฟสกส 115 3.9 บทสรป 119

Page 6: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

หนา 4 การหาคาอนพนธและอนทเกรตเชงเตวเลข 121 4.1 การหาคาอนพนธอนดบหนงโดยใชตารางขอมล 121 4.2 การหาคาอนพนธอนดบหนงของฟงกชนทกาหนดให 132 4.3 การอนทเกรตโดยใชวธแบงเปนสวนเทา ๆ กน 141 4.4 การอนทเกรตแบบเกาส เลอจองด 155 4.5 การประมาณคาอนทเกรตโดยใชวธมอนตคารโล 168 4.6 การนาไปแกปญหาทางฟสกส 176 4.7 บทสรป 188 5 การหาคาตอบสมการเชงอนพนธแบบสามญ 189 5.1 วธของออยเลอร 190 5.2 วธของรงเง-คตตา 199 5.3 การหาคาตอบสมการเชงอนพนธอนดบสองโดยวธรงเง-คตตา 207 5.4 วธของอาดามส-มลตน 216 5.5 การนาไปแกปญหาทางฟสกส 223 5.6 บทสรป 231 6 การประมาณคาในชวง 233 6.1 การประมาณคาแบบลากรองจ 233 6.2 การประมาณคาโดยใชผลตางถกหาร 241 6.3 วธพหนามอนดบสาม 249 6.4 การนาไปประมาณคาปญหาทางฟสกสอน ๆ 269 6.5 บทสรป 273 7 การประมาณคาโดยวธกาลงสองนอยทสด 275 7.1 ขอมลมความสมพนธแบบเชงเสน 277 7.2 ขอมลมความสมพนธแบบพหนาม 280 7.3 ขอมลมความสมพนธแบบหลายเชง 293 7.4 การทดสอบความเหมาะสมของฟงกชน 306 7.5 บทสรป 319

Page 7: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

หนา 8 การคานวณคาสถตเบองตน 321 8.1 การเรยงลาดบตวเลข 321 8.2 การหาความถ คาเฉลย และความเบยงเบนมาตรฐานของขอมล 338 8.3 การกระจายแบบโคงปกต 346 8.4 การกาหนดระดบคะแนนดวยคา T ปกต 356 บรรณานกรม 373 ภาคผนวก 1 เรยนรภาษาซอยางสงเขป 375 ภาคผนวก 2 เมตรกซขนพนฐาน 389 ภาคผนวก 3 ฟงกชนทใชในงานคานวณ 405 ภาคผนวก 4 การแสดงผลเปนภาษาไทยบนจอภาพ 407

Page 8: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

บทท 1 ขอพงระวงเมอใชคอมพวเตอรกบงานคานวณ

1.1 ความคลาดเคลอน ความแมนยา และความเทยงตรง (Error, Accuracy and Precision) คณตศาสตรเปนเครองมอทสาคญสาหรบใชแกปญหาหรออธบายปรากฏการณทางวทยาศาสตรและวศวกรรม เราใชความรเกยวกบเรขาคณตวเคราะห พชคณต แคลคลส สมการเชงอนพนธ ฯลฯ หาผลเฉลยทแทจรง (exact mathematical resolution) ของปญหาออกมาได สามารถหาคาตอบของ ( cos )x x+ dx∫ 3 หรอ R

dqdt

qc

t+ = ε 0 sinω ไดโดยงาย สามารถแกปญหาระบบสมการเชงเสนดวยเมตรกซและตวกาหนด แตมปญหาบางปญหาซงไมสามารถใชวธวเคราะหทางคณตศาสตรหาคาตอบทแทจรงได เราไมสามารถอนทเกรตหาคาตอบทแทจรงของ

และ e x−2

sin( )x ตองกระจายฟงกชนใหเปนอนกรมแลวหาคาโดยประมาณ ในทางฟสกสสมการเชงอนพนธของอะตอมทมอเลกตรอนหลายตวกไมสามารถหาผลเฉลยทแทจรงไดเชนกน ตองใชวธประมาณคาทเรยกวา Perturbation หาคาตอบ ปญหาทประกอบดวยตวแปรและสมการเปนจานวนมาก เชน ปญหาแรงทกระทาบนโครงขายของสะพานในวชากลศาสตร อาจตองแกระบบสมการเชงเสน 30 สมการ ถงแมจะมกฎของคราเมอรหาผลเฉลยทแทจรงได แตตองใชเวลาและความพยายามในการหาคาตอบมาก การแกสมการทไมเปนเชงเสน เชน e-2x - 3 = x ไมสามารถใชวธวเคราะหใดใหสตรสาเรจหรอวธการหาผลเฉลยทแทจรงของ x ได ในการทดลองทางวทยาศาสตร ไดความสมพนธของตวแปร 2 ตว สมมตวาเปนความเรว และ เวลา ไดออกมาเปนตวเลขชดหนงโดยจบเวลาทก 1 วนาท ถาตองการทราบวาเมอเวลาผานไป 7.5 วนาท ความเรวจะมคาเทาใด เราไมสามารถใชวธวเคราะหตอบคาถามนได เพราะไมรความสมพนธทแทจรงของความเรวกบเวลา ปญหาทไมสามารถแกได หรอแกไดยากดวยวธวเคราะห สามารถใชวธคานวณเชง ตวเลขหาคาตอบได ปญหาใดทใชวธวเคราะหหาคาตอบได กสามารถใชวธคานวณเชงตวเลขหา คาตอบไดเชนเดยวกน การแกปญหาทางวทยาศาสตร วศวกรรมศาสตร จะตองใชทงวธวเคราะหและวธคานวณเชงตวเลขประกอบกน วธวเคราะหจะใหคาตอบทแทจรงและลดสนกวาวธคานวณเชงตวเลข เชนการหาคาตอบ x2 - 2x + 3 = 0 โดยวธวเคราะหจะงายและสะดวกกวาวธคานวณ เชงตวเลข ขนตอนการแกปญหาโดยวธวเคราะหหลาย ๆ วธเปนพนฐานนาไปประยกตในวธคานวณเชงตวเลข ปจจบนการแกปญหาทางวทยาศาสตรและวศวกรรมศาสตรนยมใชคอมพวเตอรเขามาชวยแกปญหา การเขยนโปรแกรมใหคอมพวเตอรชวยแกปญหานนตองใชวธคานวณเชงตวเลข

Page 9: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

2

คอมพวเตอรไดถกพฒนาใหมประสทธภาพในการคานวณและประมวลผลมากขนโดยเฉพาะไมโครคอมพวเตอร หนวยประมวลผลมความเรวสง หนวยความจามปรมาณมากขนจนทดเทยมกบมนคอมพวเตอร อกทงการคนควาเทคนคการแกปญหาโดยใชวธคานวณเชงตวเลขใหมประสทธภาพไดตอเนองและเพมขน ปจจบนอาจกลาวไดวาเราสามารถใชวธคานวณเชงตวเลขแกปญหาทางวทยาศาสตรและวศวกรรมไดทกสาขา ถาตวแปร, สมการ และจานวนขอมลนนไมมากจนลนหนวยความจา หรอเกนขดพกดชวงคาตวเลขทคอมพวเตอรจะประมวลผลได ถงแมคอมพวเตอรจะคานวณไดรวดเรวละทางานไดเปนลาน ๆ ครงโดยไมมอผดพลาด แตผลลพธทไดจากการคานวณอาจไมตรงกบคาทแทจรงดงตวอยางตอไปน ตวอยาง 1.1 คานวณหาผลเฉลยของระบบสมการเชงเสนตอไปน 0.01 x + 2y = 200.0001 200 x + y = 102 เมอใชขนตอนวธลดสมประสทธของเกาส (ในบทท 3) โดยไมมการสลบคาสมประสทธ (pivoting) และเกบตวเลขทคานวณแบบ single precision จะไดคาตอบ x = 0.0091527, y = 100.00000763 คาทแทจรง คอ x = 0.01, y = 100 ตวอยาง 1.2 การหาคาอนพนธของฟงกชนใด ๆ หาไดจาก ′ =

+ −f x

h

f x h f xh

( ) lim( ) (

0

) เมอ h มคานอย จะได ′ ≈

+ −f x

f x h f xh

( )( ) ( )

ถากาหนดให f(x) = ex อนพนธของ f (x) ท x = 1 คอ e1 = 2.71828175 คานวณหาคาอนพนธนดวยคอมพวเตอร โดยใชคา h ตาง ๆ กน จะไดดงตาราง 1.1

โปรแกรม 1.1: โปรแกรมหาคาอนพนธ ex ท x = 1 /* Find the derivative of e^x at x = 1 */ #include <stdio.h> #include <math.h> double f( double); double f(double x) { return exp(x); } main() { double dy; double h,x,e;

Page 10: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

3

int n; h = 1; e = f(1); x = 1; printf ("\n h f'(x) True value error\n"); for ( n = 1; n <=20; n++) { dy = (f(x+h) - f(x))/h; printf(" %2.1e %6.5f %6.5f %+f\n",h,dy,e,(e-dy)); h = h/10; } getch( ); return 0; } ตาราง 1.1 แสดงผลการคานวณหาอนพนธของ ex

h f'(x) True value error 1.0e+00 4.67077 2.71828 -1.952492 1.0e-01 2.85884 2.71828 -0.140560 1.0e-02 2.73192 2.71828 -0.013637 1.0e-03 2.71964 2.71828 -0.001360 1.0e-04 2.71842 2.71828 -0.000136 1.0e-05 2.71830 2.71828 -0.000014 1.0e-06 2.71828 2.71828 -0.000001 1.0e-07 2.71828 2.71828 -0.000000 1.0e-08 2.71828 2.71828 +0.000000 1.0e-09 2.71828 2.71828 -0.000000 1.0e-10 2.71828 2.71828 -0.000000 1.0e-11 2.71828 2.71828 -0.000000 1.0e-12 2.71852 2.71828 -0.000242 1.0e-13 2.71611 2.71828 +0.002171 1.0e-14 2.71612 2.71828 +0.002160 1.0e-15 3.01777 2.71828 -0.299486 1.0e-16 0.00000 2.71828 +2.718282 1.0e-17 0.00000 2.71828 +2.718282 1.0e-18 0.00000 2.71828 +2.718282 1.0e-19 0.00000 2.71828 +2.718282 ตามหลกการหาคาอนพนธ ยง h มคาเขาใกลศนยเทาใด คาอนพนธจะเขาใกลคา แทจรงยงขน แตจากตารางจะเหนวาเมอ h มคาลดลงคาอนพนธจะเขาใกลคาแทจรง แตเมอ h

Page 11: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

4

มคาลดลงถงคาหนงความคลาดเคลอนจะเรมเพมมากขนจนถงคา h = 1.0 ×1.0-16 จะไดคาอนพนธเทากบศนย ซงแสดงใหเหนขดจากดในการคานวณเชงตวเลขของคอมพวเตอร ตวอยาง 1.3 นาคา 0.000005 บวกกนแสนครง จะไดคาเทาใด เขยนโปรแกรมใหคอมพวเตอรคานวณดงโปรแกรม 1.2

โปรแกรม 1.2 โปรแกรมแสดงการบวกเลข 0.000005 แสนครง /* summation by single precision */ #include <stdio.h> main() { float x,result=0; long int n; for (n=1; n <= 100000; n++) { result = result + .000005; } printf("\nResult = %f\n",result); } เมอใหโปรแกรมทางาน จะไดผลลพธ 0.500495 ในขณะทคาทแทจรงคอ 0.5 จากตวอยางทแสดงไวขางตนจะเหนวาคาทคานวณไดจากคอมพวเตอรจะคลาดเคลอนไปจากคาทแทจรง คาทคานวณไดจากคอมพวเตอร หรอคาทไดจากการทดลองทางวทยาศาสตรแตกตางจากคาแทจรงหรอคาทฤษฎ แสดงวามความคลาดเคลอนเกดขน นนคอ คาทแทจรง = คาทคานวณได ± คาทเกดจากความคลาดเคลอน (error) นยามความคลาดเคลอนสมบรณ (Absolute error) คอ ความคลาดเคลอนสมบรณ = คาทคานวณได - คาทแทจรง และเปอรเซนตความคลาดเคลอนสมพทธ (Percent relative error) คอ = คาทคานวณได - คาทแทจรง × 100 คาทแทจรง ให x, y เปนคาทวดไดซงมคาความคลาดเคลอน ∆x และ ∆y ตามลาดบ เมอนาไปแทนคาในฟงกชน เชน z x y= +2 2 ผลกคอทาให z เกดคาความคลาดเคลอนตามไปดวย เมอ

Page 12: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

5

นาคาทมความคลาดเคลอนไปใชรวมกบคาอน ความคลาดเคลอนจะแฝงตวและแพรกระจายไปยงคาใหม กลายเปนความคลาดเคลอนสะสม (accumulation error) การแพรกระจายของความ คลาดเคลอนรวบรวมไวเปนกฎดงตอไปน 1. การบวกและลบ z = x ± y คาความคลาดเคลอนของ z คอ ∆z โดยท ∆z = ∆x + ∆y 2. การคณ z = xy จะได ∆z = ⏐z⏐ ( x

xy)y

∆ ∆+

3. การหาร z = x/y จะได ∆z = ⏐z⏐ ( x

xy)y

∆ ∆+

4. การยกกาลง z = xn

∆z = ⏐z⏐⏐n⏐ ∆xx

5. ลอกการธม z = ln x

∆z = ∆xx

6. ฟงกชน sine z = sin x (x มหนวยเปนเรเดยน) ∆z = ⏐cos x⏐∆x 7. ฟงกชน cos z = cos x (x มหนวยเปนเรเดยน) ∆z = ⏐sin x⏐∆x ตวอยาง 1.4 อนภาคเคลอนทดวยความเรงคงท a มความเรวตน u สมการความเรวของอนภาคทเวลาใด ๆ คอ v = u + a t

Page 13: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

6

จากการทดลองวดคาความเรวตน, ความเรง และเวลา ไดดงน u = 2.3 ± 0.5 เซนตเมตร/วนาท a = 3.6 ± 0.3 เซนตเมตร/วนาท t = 0.12 ± 0.04 เซนตเมตร/วนาท จงหาคาความเรวทเวลา t วธทา พจารณา z = a t = 3.6 × 0.12 = 0.43

∆z = |z| ∆ ∆aa

tt| | | |

+⎛

⎝⎜

⎠⎟

= 0.4 0 336

0 04012

.

...

+⎛⎝⎜

⎞⎠⎟

= 0.2 ดงนน v = u + a t = 2.3 + 0.43 = 2.7 เซนตเมตร/วนาท ∆v = (0.5 + 0.2) = 0.7 เซนตเมตร/วนาท จะได v = 2.7 ± 0.7 เซนตเมตร/วนาท ในการทดลองเรองหนง ๆ อาจมการวดปรมาณเดยวกนนนซา ๆ กนหลายครง คาทวดไดแตละครงอาจจะไมใชเปนตวเลขคาเดยวกน ความคลาดเคลอนทไดจากการวดสามารถอธบายไดในรปของความแมนยา (Accuracy) และความเทยงตรง (precision) คาความแมนยา หมายถง คาททดลองหรอวดไดในแตละครงมเขาใกลคาแทจรง หรอคาทฤษฎมากนอยเพยงใด สวนคาความเทยงตรงจะบอกถงการวดหรอทดลองแตละคามคาใกลเคยงกบคาอน ๆ อยางไร

Page 14: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

7

แผนภาพตอไปนแสดงถงความสมพนธระหวางความแมนยาและความเทยงตรง ↑ ความเทยงตรงเพม ความแมนยาเพมขน → เครองมอวดหรอเครองมอทใชควบคมตาง ๆ ในทางวทยาศาสตร ควรมความแมนยาและความเทยงตรงสง แตถาตองมการเลอกระหวางความแมนยากบความเทยงตรงในการวด เรามกจะเลอกเอาเครองมอทมการวดไดเทยงตรงมากกวา ถงแมจะเกดความคลาดเคลอนเรากยงสามารถชดเชยคาความคลาดเคลอนนนไดดวยคาทแนนอนคาหนง ความคลาดเคลอนทเกดขนจากการคานวณของคอมพวเตอร อาจเกดจากความผดพลาดของผใช (human error) เชน ปอนขอมลผด หรอพมพผด หรอขนตอนวธแกปญหาทใชไมสมบรณ ความผดพลาดเหลานสามารถตรวจสอบและแกไขไดงายดวยความไมประมาท หรอเลอกขนตอนวธการคานวณทเหมาะสม แตความผดพลาดทเกดจากการคานวณของเครองคอมพวเตอร (calculation error) ไมสามารถขจดใหหมดไปไดอยางสมบรณ ทงนเพราะลกษณะการเกบตวเลขในหนวยความจามขนาดจากดเฉพาะคาหนง คอมพวเตอรจงตองมการปดจด (rounding) หรอตดปลาย (truncating) เพอใหตวเลขเหมาะสมกบขนาดของหนวยความจา ถาผลจากการคานวณไดตวเลขทมคาเกนกวาหรอเลกกวาหนวยความจาจะเกบได จะทาใหเกด overflow หรอ underflow วธแกไขใหเกดความคลาดเคลอนใหนอยทสดคอ ตองรขดความสามารถในการเกบตวเลขของเครองคอมพวเตอรทใช และออกแบบขนตอนวธการคานวณททาใหเกดการปดเศษหรอตดปลายนอยทสด

Page 15: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

8

1.2 การเกบตวเลขในคอมพวเตอร เราใชเลขฐานสองเกบตวเลขในคอมพวเตอร ประกอบดวย เลข 0 และ 1 เรยกวา บต(bit) ตวอกษรซงเปนรหสอสก (ASCII) จะใช 8 บต สาหรบเกบตวอกษร 1 ตว เรยกวา 1 ไบต(byte) สวนการเกบตวเลขจะใชจานวนไบตตางกน ขนอยกบวาจะเปนจานวนเตมหรอจานวนจรง เทอรโบซ ทใชเปนคอมไพเลอรในหนงสอเลมนมชนดของขอมลทเกบตวเลข ดงน จานวนเตม (Integer)

ชนด จานวนไบต ทใชเกบ

คาตาสด - สงสด ทเกบได

int short short int long unsigned int unsigned short unsigned long

2 2 2 4 2 2 4

-32,768 ถง 32,767 -32,768 ถง 32,767 -32,768 ถง 32,767

-2,147,483,648 ถง 2,147,483,647 0 ถง 65,535 0 ถง 65,535

0 ถง 4,294,967,295 จานวนจรง (Real)

ชนด จานวนไบตทใชเกบ คาตาสด -สงสดทเกบได float (single precision) double (double precision) long double

4 8

10

± 3.4 E ± 308 (7 digit accuracy)

± 1.7 E ± 308 (15 digit accuracy)

3.4 E - 4932 ถง 1.1 E + 4932 ขนาดของตวเลขทเกบไดเพยงพอกบตวเลขทใชกนอยบอย ๆ ในทางฟสกส เชน มวลของอเลกตรอน 9.11 × 10-31 กโลกรม คาคงทของพลงค 6.625 × 10-34 จล-วนาท หรอตวเลขอะโวกาโดร 6.02 × 1026 /กโลกรม.โมล การเกบจานวนจรงในคอมพวเตอร จะใชหนวยความจาขนาด 4 ไบต (32 บต) จะเกบในรปแบบ Normalize floating point ดงน

Page 16: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

9

0 . B B B B B B B B B B × 2N

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

12

122 1

23 124 1

25 126 1

27 128 1

29 1210

0.5 0.25 0.125 0.0625 0.03125 0.015625 0.0078125 0.00390625 0.001953125 0.0009765625 ตวเลข B ทงสบตว เรยกวา แมนทสซา (mantissa) มคามากกวา 0.1 แตนอยกวา 1 N คอ ตวเลขชกาลง (exponent) ตวอยางเชน 24.96 จะเกบในรปแบบ 0.2496 × 102

7.40 จะเกบในรปแบบ 0.740 × 101

0.0057 จะเกบในรปแบบ 0.57 × 10-3

ในหนวยความจา บตตาง ๆ จะเรยงกนในลกษณะดงน S E E E E E E E M M M M M M M M M M M M M M M M M M M M M M M M

บอก เครองหมาย 1 บต สวน exponent สวน mantissa 7 บต 24 บต

Page 17: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

10

ตวอยางการเกบเลขฐานสบในหนวยความจา เลขฐานสบ Normalized Floating Point Mantissa Exponent 1 0.5 × 21 0.1 1 4 0.5 × 23 0.1 11 12.5 0.78125 × 24 0.11001 100 0.5 0.5 × 20 0.1 0 64 0.5 × 27 0.1 111 ตวอยาง 1.5 โปรแกรม Dec2Norm.C จะปลอยเลขฐานสบใหอยในรปแมนทสซา และเลขยกกาลง รายละเอยดของโปรแกรมมดงน

โปรแกรม 1.3 Dec2Norm.c /* Dec2Norm.C */ #include <stdio.h> #include <math.h> #include <stdlib.h> main() { int mantissa[26],i,l,k,index; float p, dec; char ans = ‘y’; printf("\nDecimal to Normalize Floating Point\n\n”); while ( ans == ‘Y’ || ans == ‘y’) { printf(“\n\nEntry Deciimal Number = “);scanf(“%f”, &dec); l = 0; k = 1; i = log(dec)/log(2.0) +2; do { if ( i < -200 ) exit (0); p = pow(2.0, (float)(i-1)); if (dec >= p) { matissa[k] = 1; dec = dec - p; if (l == 0) { index = i; l = 1; } } else { if ( k>1) mantissa[k] = 0; }

Page 18: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

11

if ( l > 0 ) k = k + 1; i = i -1; } while ( k < 25); printf(“---------------------------------\n”); printf("Binary\n Mantssa = . "); for (k = 1; k<=24; k++) { printf("%d",mantissa[k]); if(k/4*4 ==k ) printf(" "); } printf("\n Exponent = %d \n",index); printf("-------------------------\n"); printf("\ Continue ? (y/n) .\n"); ans = getch(); } return 0; }

เมอทดลองเกบคา 0.2 จะไดดงน 0.2 = 0.8 × 2-2

กระจาย 0.8 ใหอยในเลขฐานสองจะได 0.1100 1100 1100 1100 ..... เนองจากจานวนบตจากดแคเพยง 24 บต คาหลง ๆ จงถกตดทงไปทาใหเกดความคลาดเคลอน คา 0.8 จง มคาเพยง 0.7998046875... ในหนวยความจาของคอมพวเตอร นอกจากนน ตวเลขทเกนคา 10308 หรอตากวา 10-308 ซงเกนขดจากดของคอมพวเตอร ทาใหเกดขอผดพลาดทเรยกวา overflow คอมพวเตอรจะไมแสดงขอผดพลาดใหเหน และจะนาคาผดพลาดนไปคานวณตอไป ทาใหไดผลลพธไมตรงกบคาทแทจรง ดงตวอยางตอไปน

ตวอยาง 1.6 แสดงการเกด overflow โปรแกรม 1.4 Overflow.C

/* Test Overflow Error */ #include <stdio.h> main() { int n = 32767; int u,v,w;

Page 19: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

12

printf("\n Test Overflow #1 \n"); printf("\n n = %d \n",n); printf(" n+1 = %d \n",n+1); printf("\n Test Overflow #2 \n"); u = 800.0; v = 500.0; w = 400.0; printf("\n u = 800, v = 500, w = 400\n"); printf("\n u x (v/w) = %d \n", u*(v/w)); printf("\n (v/w) x u = %d \n", v/w*u); printf("\n (u x v)/w = %d \n", (u*v)/w); }

ผลลพธจากการใหโปรแกรมทางานเปนดงน Test overflow #1 n = 32767 n + 1 = -32768 → ผดพลาด Test overflow #2 U = 800, V = 500, W = 400 U × (V/W) = 800 (เปนการคานวณเกบเฉพาะจานวนเตม) (V/W) × U = 800 (U ×V )/W = 16 (ผดพลาดเพราะเกดจาก overflow error) จากตวอยางท 1.2 เมอ h ลดคาลง คา f(x+h) และ f(x) จะมคาใกลเคยงกนมาก เมอลดคา h ลงอกจนทาใหคอมพวเตอรไมสามารถจาแนกความแตกตางระหวาง f (x+h) และ f(x) ได ทาใหไดผลตางออกมาเปนศนย ในการคานวณของคอมพวเตอรจงมจานวนจรงทเลกทสดคาหนง เมอบวกกบ 1 แลวจะไดจานวนจรงทมคามากกวา 1 เรยกจานวนจรงคาทเลกทสดนวา machine epsilon หรอ machine constant หรอ numerical zero (ใชสญลกษณวา ∈ ) ซงจะมคาตาง ๆ กน ขนอยกบชนดของคอมพวเตอร คอมพวเตอรจะไมสามารถจาแนกจานวนเลขทมคาระหวาง 1 และ 1 + ∈ได ในเครองไมโครคอมพวเตอร PC จานวน 1 + ∝ จะถกตดปลายใหเหลอเปน 1 เมอ 0 < ∝ < ∈/2 และจะถกปดใหเปน 1 + ∈ ถา ∝ มคามากกวาหรอเทากบ ∈/2 ดงนน ∈/2 จงเปนคาคลาดเคลอนทมากทสดทเปนไปไดเนองจากการปดเศษ นนคอ เมอพบเลข 1.0 ในหนวยความจาคาเดมของมนอาจมคาระหวาง 1 − ∈/2 และ 1 + ∈/2 เมอทดลองหาคา machine epsilon โดยใชคอมไพเลอรของเทอรโบซ พบวา ∈ = 1.920920 E - 07 สาหรบ single precision

Page 20: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

13

∈ = 2.22044605 E - 16 สาหรบ double precision โปรแกรมทใช คานวณหา ∈ มรายละเอยดดงน

โปรแกรม 1.5 แสดงการหา machine epsilon /* Find the Machine Epsilon by Wachara R., 11 June 1995 */ #include <stdio.h> main() { double test,eps=1; int n = 0; do { n = n+1; eps = eps/2; test = 1 + eps; } while (test != 1); printf ("\nMachine epsilon = %16.8e\n\n",2*eps); printf("Number of N = %d \n",n); }

ถา a = 5 + 10-8 และ B = 5 คอมพวเตอรจะเหนเลขสองจานวนนมคาเทากน เมอนา A - B จะไดผลลพธเทากบศนย คาแทจรงของ A - B คอ 10-8 นอยกวา machine epsilon (ในกรณ single precision) คอมพวเตอรจงไมสามารถมองเหนความแตกตางดงกลาว ในการคานวณเชงตวเลข ถา ⏐A - B⏐มคานอยกวา ∈ ถอวามคาเปนศนยได 1.3 การลดความคลาดเคลอนทเกดจากการปดเศษ ถงแมจะหลกเลยงความคลาดเคลอนเนองจากการปดเศษและตดปลายไมพน เพราะเนอทอนจากดของการเกบตวเลขของคอมพวเตอร เราพอมวธจะลดผลกระทบทเกดจากการปดเศษเพอใหไดผลลพธใกลเคยงคาทแทจรงทสดเทาทจะทาได ดงตอไปน 1. ควรหลกเลยงสงตอไปน -หลกเลยงการบวกหรอลบระหวางเลขจานวนนอยกบเลขจานวนมาก ตวอยาง เชน A = 1030 B = 6 C = -1030 เมอนา A + B + C จะไดผลลพธเทากบศนย ถาเปลยนเปน A + C + B จงจะไดผลลพธเทากบ 6 ซงเปนผลลพธทถกตอง จะเหนวาในเรองการคานวณเชงตวเลขจะไมเปนไปตามกฎการรวมหมรวมพวก (associative law) - หลกเลยงการหาผลตางของเลขสองจานวนทมคาใกลเคยงกนมาก ดงตวอยาง 1.2 เมอ h มคาถง 1.0 × 10-16 คา f (x + h) และ f (x) มคาใกลเคยงกนมาก และ h มคานอย

Page 21: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

14

กวา machine epsilon ทาใหผลตางของ f (x + h) และ f (x) มคาเปนศนย ทาใหคาอนพนธผดไปจากความเปนจรง - หลกเลยงการนาตวหารทมคาใกลศนยหรอมคานอยๆ เมอเทยบกบตวตง จากตวอยาง 1.1 เมอนากฎการลดทอนของเกาสหาผลลพธสมการเชงเสนจะไดผลลพธคลาดเคลอนไปจากคาแทจรง 0.01 x + 2y = 200.0001 200 x + y = 102 เพราะจากสมการแรก นา −200

0.01 คณตลอด แลวนาไปบวกกบสมการท 2 เพอขจด

สมประสทธของ x เปนการนาเลขคานอยไปหารเลขคามาก จะไดผลลพธทมคามาก เกดความคลาดเคลอนจากการปดจดขน ถาจดลาดบสมการเสยใหม 200 x + y = 102 0.01 x + 2y = 200.0001 จะไดผลลพธทมคาใกลเคยงกบคาแทจรงคอ x = 0.01 , b = 100 ในการแกแกปญหาความคลาดเคลอนของระบบสมการเชงเสนทเกดจากการหารดวยเลขคานอย ๆ น ทาไดโดยเปลยนแถวหรอคอลมนมใหสมประสทธทมคานอย ๆ อยในแนวเสนทแยงมม เรยกวาการสลบสมประสทธ (Pivoting) (ดรายละเอยดในบทท 3) 2. ใชชนดขอมลเปนแบบ double precision ซงใชหนวยความจาขนาด 8 ไบตเกบตวเลข จากตวอยาง 1.3 ถาเปลยนชนดขอมลของตวแปร result จาก float เปน double ผลการคานวณจะได 0.50000 เทากบคาทแทจรง หรอในตวอยางท 1.1 ถาเปลยนชนดขอมลของตวแปรทกตวทเปน float ใหกลายเปน double กจะไดคาตอบเทากบคาทแทจรงเชนเดยวกน โดยไมตองสลบลาดบของสมการ 3. ออกแบบขนตอนวธการคานวณออกเปนสวนยอย ๆ เพอลดผลกระทบจากการ ปดเศษ จากตวอยางท 1.3 เปลยนขนตอนการคานวณใหมดงน ตวอยาง 1.7 นาปญหาจากตวอยาง 1.3 มาแกโดยใชขนตอนวธแบงการวนรอบออกเปน 2 สวน

โปรแกรม 1.6 แสดงการแบงการคานวณออกเปนสวน ๆ /* summation by single precision */ #include <stdio.h> main()

Page 22: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

15

{ float x,result=0; int i,j; for (i=1; i <= 1000; i++) {

for ( j = 1 ; j <=100; j++ ) { result = result + .000005; } } printf("\nResult = %f\n",result); }

จะไดผลลพธ 0.49999541 คาทแทจรงคอ 0.5 คาความเคลอนสมบรณคอ 4.59 ×10-6 ถาไมใชวธวนรอบซอนกนจะไดคาตอบเปน 0.5000495 คาความคลาดเคลอนสมบรณคอ 49.5 × 10-6 ตวอยาง 1.8 จงหาคา y เมอ x = 2.73 โดยท y = x3 + 2x2 - 7x + 3.78 สมมตวาหนวยความจาเกบตวเลขไดไมเกน 4 หลก พจารณาแตละเทอม

x3 2x2 7x คาแทจรง คาจากการตดปลาย คาจากการปดเศษ

20.346417 20.34 20.34

14.9058 14.90 14.91

19.11 19.11 19.11

คา y ทแทจรง คอ 19.922217 คา y ทไดจากการตดปลาย = 19.91 ความคลาดเคลอนสมพทธ 0.061% คา y ทไดจากการปดเศษ = 19.93 ความคลาดเคลอนสมพทธ 0.039% ถาเปลยนรปสมการใหม y = ((x + 2) x -7) x + 3.78 คา y ทไดจากการตดปลาย = 19.91 ความคลาดเคลอนสมพทธ 0.061% คา y ทไดจากการปดเศษ = 19.92 ความคลาดเคลอนสมพทธ 0.011% จะเหนวาคา y ทไดจาการปดเศษจะมความคลาดเคลอนนอยลงเมอมการจดรปสมการใหม

Page 23: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

16

1.4 ขอพงระวงบางประการในการใชคาสงในภาษา C โปรแกรมภาษา C บางโปรแกรมสามารถผานการแปลเปนภาษาเครอง (compile) และเชอมโยง (link) เปนแฟมเลขฐานสอง (execute file) ไดโดยไมมขอความแจงแสดงความผดพลาด แตเมอใหโปรแกรมทางาน ผลลพธทไดกลบไมตรงกบจดประสงคทตงไว เมอตรวจสอบขนตอนวธ (algorithm) กไมพบวามสวนหนงสวนใดบกพรอง ความผดพลาดในกรณเชนนมกจะเกดขนเนองจากการวางคาสงของภาษา C โดยไมไดคานงถงลาดบความสาคญกอนหลง หรอวางในตาแหนงททาใหตวแปลภาษาแปลความหมายในอกลกษณะหนงไมตรงกบความตองการของผเขยนโปรแกรม ตวอยางการวางคาสงผดพลาดตอไปน ทาใหเกดการประมวลผลทผดอยางคาดไมถงและมกจะเกดขนเปนประจา ตวอยาง 1.10 นยามมาโคร (macro) ไมชดเจน เมอนามาโครไปแทนในโปรแกรม ทาใหไดคาสงผดไปจากจดประสงค นยามมาโครไวทตนโปรแกรมดงน #define abs(x) x > 0 ? x : -x ถาในโปรแกรมมคาสงเรยกใชมาโครดงน y = abs(a - b); คาสงนจะถกแทนทดวยมาโครดงน y = a - b > 0 ? a - b : - a - b ; เทอมสดทาย -a - b นนไมถกตอง ทถกตองเปน - (a + b) หรอในตวโปรแกรมใชคาสง y = abs(a) + 1; จะถกแทนทดวยมาโคร เปน y = a > 0 ? a : -a +1 ; ความหมายจะผดไปจากจดประสงคทตองการ สามารถแกไขโดยเปลยนแปลงมาโคร เสยใหมโดยใสวงเลบ ดงน #define abs(x) ( (x) > 0 ? (x) : - (x) ) ตวอยาง 1.11 คาสงเพมคาหรอลดคามผลขางเคยงตอการประมวลผลคาสงอน ๆ เชน ตองการหาคาตาสดระหวางเลข 2 จานวนโดยเขยนเปนมาโครดงน #define min(a,b) ( (a) < (b) ? (a) : (b) )

ถาสวนหนงในโปรแกรมมการเรยกใชมาโครดงน

Page 24: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

17

int x[3] = { 4, 3, 5, 2 }; smallest = x[0]; i = 1; while ( i <= 3 ) smallest = min (smallest, x[i++]); .............. ตวอยางนจะไมมปญหาถา min เปนฟงกชน แตถา min เปนมาโครดงตวอยาง คาสงในประโยคสดทายจะถกแทนทดงน smallest = (( smallest) < (x[i++]) ? ( smallest) : (x[i++]) ); ทดลองตรวจสอบการทางาน ตอนแรก smallest จะมคาเทากบ 4 ตอมาในวงรอบของ while smallest จะเปรยบเทยบกบ x[i++] แต i = 1 x[1] = 3 ไดคาเปนเทจ เพราะผล ขางเคยงของ i++ ซงเปนการเพมคา i ทาให i = 2 ดงนน smallest = x[2] = 5 แกไขไดโดยเขยนคาสงใหมดงน smallest = x[0]; for (i =1; i<=3; i++) smallest = min(smallest, x[i]); ไมควรใชเครองหมายเพมคา (++) หรอลดคา (--) ในมาโคร ตวอยาง 1.12 เครองหมายเพมคาทาใหเกดผลขางเคยงเชนเดยวกบตวอยาง 1.11 #define toupper(c) ( (c) >= ‘a’ && (c) <= ‘z’ ? (c) + (‘A’ - ‘a’) : (c) ) จะเกดผลขางเคยงถาใชคาสงดงน toupper (*ch++); ตวอยาง 1.13 ระวงคอมเมนตทอยทายมาโครจะตดเขาไปในระหวางการแทนคาในคาสง #define tolower(c) ((c) + ‘a’ - ‘A’) /* Change Cap letter to small */ ขอความ /* Change Cap letter to small */ จะตดเขาในบรรทดทถกแทนคาดวยมาโครดวย ตวอยาง 1.14 การวางลาดบตวปฏบตการผดลาดบ ลาดบกอนหลงของตวปฏบตการในภาษา C มความสาคญมาก ตวแปลภาษาจะแปลความหมายโดยยดหลกขอกาหนดน ตารางตอไปนแสดงลาดบความสาคญกอนหลง ตวปฏบตการ

Page 25: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

18

ทอยสวนบนของตารางจะมลาดบความสาคญกวาลาดบทอยรอง ๆ ลงไปและถาตวปฏบตการมลาดบความสาคญเสมอกน จะเรมกระทาจากซายไปขวาหรอจากขวาไปซาย เชนการคณจะเรมทาจากซายไปขวา เชน x * y * z หมายถง (x * y) * z ไมใช x * ( y * z)

ตวปฏบตการ (operator) ลกษณะการกระทาเรมจาก(Associativity) ( ) [ ] -> . ซายไปขวา

! ~ ++ -- (type) * & sizeof ขวาไปซาย * / % ซายไปขวา

+ - ซายไปขวา << >> ซายไปขวา

< <= > >= ซายไปขวา == != ซายไปขวา

& ซายไปขวา ^ ซายไปขวา | ซายไปขวา

&& ซายไปขวา || ซายไปขวา

? : ขวาไปซาย = (assignment) ขวาไปซาย

, ซายไปขวา ใชตวแปร x เกบตวเลข 8 บต 2 ชด โดย 4 บตบนเกบคา 0 ถง 15 ไวใน hi และ 4 บตลางเกบคา 0 ถง 15 เชนเดยวกนไวใน lo การเกบคาไวใน x เขยนเปนคาสงไดดงน x = hi << 4 + lo; หมายความวาใหเลอนตวเลขใน hi ไปทางซายมอ 4 บตแลวนาไปบวกกบ lo เกบคาทไดไวใน x แตเนองจากลาดบความสาคญของ + สงกวา << ดงนนโปรแกรมจะทางานดงน x = hi << ( 4 + lo ); สามารถแกไขไดโดย ใสวงเลบดงน x = (hi << 4 ) + lo;

Page 26: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

19

หรอ x = hi << 4 | lo; ตวอยาง 1.15 ตองการคดลอกขอมลจากไฟลชอ fileA ไปไวยงไฟลชอ fileB while ( ch = getch(fileA) != EOF ) putc (ch, fileB); ผลทไดใน fileB จะมแตตวเลข 111111..... เพราะ != มความสาคญสงกวา = แกไขไดโดยใสวงเลบตรงสวนกาหนดคากอนดงน while ( (ch = getch(fileA)) != EOF ) putc (ch, fileB); ......... ตวอยาง 1.16 แสดงถงลาดบตวปฏบตการมผลตอการคานวณ

/* test Precedance #1 */ #include <stdio.h> main() { int i,j,k; i = 2; i *= 3+4; /** 1 **/ printf(" i = %d\n",i); /*------------------------*/ i *=j = k = 3; /** 2 **/ printf("i = %d\n",i); /* ----------------------*/ i =j == k; /** 3 **/ printf("i = %d\n",i); /* ----------------------*/ }

คาสงท 1 : i *= 3 + 4; หมายถง i = i *(3 + 4) = 2 * 7 = 14 ไมใช i = i * 3 + 4 = 10 คาสงท 2 : i = i * j = 14*3 = 42

Page 27: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

20

คาสงท 3 : i = ( j == k); โดยท k = 3 เพราะวา k ไมเทากบศนย (j == 3) จงมคาเปน 1 ดงนน i = 1 ตวอยาง 1.17 แสดงลาดบตวปฏบตการทมผลตอการคานวณเชนเดยวกน

/* test #2 */ #include <stdio.h> main() { int x,y,z; x = y = 2; z = x++ - 1 ; /** 1 **/ printf("x = %d z = %d \n", x,z); /*---------------------------------*/ z += -x++ + ++y; /** 2 **/ printf("x = %d z = %d \n", x,z); /* --------------------------------*/ z = x/++x; /** 3 **/ printf("x = %d z = %d \n", x,z); /* ---------------------------------*/ }

แสดงวธทาไดดงน ในคาสงท 1 x = 2 ดงนน z = 2 - 1 = 1 , x = x++ = 3 คาสงท 2 จะได z + = -(x++) + (++y) z + = (-3) + (3) = 0 z = 0 + 1 = 1 คาสงท 3 จะได z = x/++x = 1, x = 5 ตวอยาง 1.18 การแปลความหมายอาศยเรยงลาดบจากซายไปขวา เชน a --- b หมายถง ( a--) - b ไมใช a - (--b) a+++++ b หมายถง (( a++)++) + b n-->0 หมายถง (n--) > 0

Page 28: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

21

ตวอยาง 1.19 คาสงหารและpointer ถาวางผดทตวแปลภาษาจะมองเหนเปน comment x = a/*ptr; /* ptr = pointer */ ประโยคนควรเขยนใหมโดยเวนวรรคระหวางเครองหมาย / และ * ดงน x = a/ *ptr; /* ptr = pointer */ คอมไพเลอรบางตวรวมทง เทอรโบ ซ จะมองเหนคอมเมนตของประโยคเรมตนตรง /*ptr; /* ptr = pointer */ ตวอยาง 1.20 การลมใสเครองหมายอฒภาค (semicolon) ไวทายประโยค คอมไพเลอรอาจจะไมแสดงขอความผดพลาดแตจะสงผลใหการประมวลผดไปจากความตองการ เชน if ( x <= 0 ); <----------ใสเครองหมายอฒภาคไมถกตอง x = 1; .......... จะเหนวาตวแปร x จะถกกาหนดใหเปน 1 เสมอ ทง ๆ ทจดประสงคตองการให x = 1 เมอ x นอยกวาหรอเทากบศนยเทานน ตวอยาง 1.21 แสดงผลของการลมใสเครองหมายอฒภาค struct exam_rec { char name[30]; char major[3]; float score; } <----------- ลมใสเครองหมายอฒภาคตรงจดน main( ) ผลทไดจากการลมใสเครองหมายอฒภาค จะทาให main สงคากลบเปน struct exam_rec โดยปกตฟงกชน main จะสงคา int เมอจบโปรแกรม ตวอยาง 1.22 แสดงผลของการลมใสเครองหมายอฒภาค อกตวอยางหนง if ( x < 0) return <------ ไมไดใสเครองหมายอฒภาค x = a[0]; y = a[1]; ผลทไดคอ เมอ x < 0 จะสงคา x = a[0]; เสมอ คาสง x = a[0] จะถกมองขามไปเมอ x มากกวาหรอ เทากบศนย

Page 29: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

22

ตวอยาง 1.23 การจบค if .... else ไมถก if ( x== 2) if (y > 3) print (x,y); else { x = 2; y = 3; print(x,y); } คาสง else จะผกตดกบ if ทอยใกลตวมนมากทสด จากตวอยางดงกลาว เมอโปรแกรมทางานจะเปนดงน if ( x== 2) if (y > 3) print (x,y); else { x = 2; y = 3; print(x,y); } ความผดพลาดทเกดจากการเขยนโปรแกรมดงตวอยางทกลาวมาน จะไมแสดงขอความ ผดพลาดขณะแปลเปนภาษาเครอง แตเมอใหโปรแกรมทางาน ผลลพธจะไมตรงกบทผเขยนโปรแกรมตองการใหเปน ดงนนจงเปนเรองตองพงระมดระวงเปนอยางยง

Page 30: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

บทท 2 การหารากของสมการแบบไมเปนเชงเสน

การหารากของสมการแบบไมเปนเชงเสนเปนสงทพบกนเปนปกตในวชาฟสกส ถา

เปนสมการพหนามทมกาลงสงสดเปน 2 หรอ 3 กสามารถคานวณดวยตนเองไดไมยากนก แตถา

สมการมเทอมทเปนลอกการทม หรอเอกซโพเนนเชยลปนอยดวย ถงแมจะมเครองคดเลขชวย

คานวณกยงตองเสยเวลามากและไมสะดวกนก การใชโปรแกรมคอมพวเตอรหาผลลพธจะชวยให

การคานวณเสรจอยางรวดเรว ในบทนจะกลาวถงการหารากสมการแบบไมเปนเชงเสนโดยใช

โปรแกรมคอมพวเตอร โดยจะแบงออกเปน 2 แบบใหญ ๆ คอ แบบแรก จะเปนการหาราก

สมการโดยกาหนดคารากประมาณเปนชวง ๆ ไดแกวธแบงครงชวง และวธวางตาแหนงผดท แบบ

ทสอง จะเปนแบบทใชความชนของเสนตรงเขามาเกยวของ และกระทาซาจนไดคารากสมการท

ตองการ ไดแก วธของนวตน-ราฟสน และวธเซแคนต

2.1 รปแบบและรากสมการแบบไมเปนเชงเสน ตวอยางตอไปนจดวาเปนสมการแบบไมเปนเชงเสนทม x เปนตวแปรเพยงตวเดยว

x3 + 4x2 - x + 3 = 0

sin x + 2 = xe-3x

ln x + tanh3 x = 2x

x2 1 5+ − = 0

เขยนใหอยในรปทวไปไดเปน f(x) = 0 ....................(2.1)

f(x) อาจเปนสมการพหนาม (polynomial equation) หรอสมการเชงอดศย

(transcendental equation) ซงเปนสมการทมเทอมทเปนฟงกชนตรโกณมต หรอ เอกซโพเนน

เชยล หรอลอกการธมเขามาเกยวของ

ตวอยางสมการแบบไมเปนเชงเสนทพบในวชาฟสกส เชน

( )( )Pa

VV b nRT− − =2

เปนสมการสถานะแกสของแวน เดอร วาลล

Page 31: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

24

vgm

ce cm t= − −( )/1

เปนสมการความเรวของวตถมวล m ตกอยางอสระภายใตสนามโนมถวง g เมอ c

คอสมประสทธแรงตานอากาศ (drag coefficient)

q q e tR

L LCRt L= −−

02

2

4

1/ cos( )

เปนสมการของวงจรทประกอบดวยตวตานทาน R ขดลวด L และตวเกบประจ C

เมอ q คอประจเมอเวลาใด ๆ

รากสมการทไดจากการแกสมการแบบไมเปนเชงเสนนนมอย 4 กรณ คอ 1. ราก

สมการแตละคาเปนจานวนจรง และมคาตางกน 2. รากสมการแตละคาเปนจานวนจรงและมคา

เทากน 3. รากสมการทไดเปนจานวนเชงซอน 4. ทงขอ 1. 2. และ 3. รวมกน

จะยกตวอยางใหเหนโดยใชสมการพหนาม ดงตอไปน

x3 - 3x2 - x + 3 = 0 มรากสมการเปนจานวนจรง 3 คา คอ x = -1,1,3 ดรป 2.1

x3 - 5x2 + 8x - 4 = 0 มรากสมการเปนจานวนจรงคอ x = 1 และไดคารากทซากน

คอ 2, 2 จดสมผสทแกน x แสดงใหเหนถงคารากสมการทซากนทตาแหนงน f(x) =0และ f′(x) =

0 ดงรป 2.2

รป 2.1 รากสมการของ x3 - 3x2 - x + 3

รป 2.2 รากสมการของ x3 - 5x2 + 8x - 4

Page 32: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

25

x4 - 6x3 + 18x2 - 30x + 25 = 0 จะไดรากสมการเปนจานวนเชงซอน 4 คา คอ1 ± 2j

และ 2 ± j เสนกราฟจะไมตดแกน x เลย ดงรป 2.3

x4 + x3 - 5x2 + 23 x - 20 = 0 จะไดรากสมการคอ 1, -4 และ 1 ± 2j ดงรป 2.4

การหารากสมการทจะกลาวตอไปน รากสมการทไดจะเปนจานวนจรง ขนแรก

จะตองประมาณคารากสมการขนมาอยางหยาบ ๆ อาจประมาณคาเปนชวงตวเลขแคบ ๆ หรอคา

โดยประมาณ 1 คา จากนนจงใชวธกระทาซา (successive approximation or iteration) จะไดคา

โดยประมาณตอ ๆ มา ทเรมเขาใกลคารากสมการทแทจรง

รป 2.3 รากสมการของ x4 - 6x3 + 18x2 - 30x + 25

รป 2.4 รากสมการของ x4 + x3 - 5x2 + 23 x - 20

Page 33: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

26

2.2 วธแบงครงชวง (Bisection Method) เปนวธทงายทสด เกดความผดพลาดทคาดไมถงนอยทสดเมอทาเปนโปรแกรม

คอมพวเตอร ใชหารากสมการไดทงชนดทเปนพหนามและเชงอดศย เรมตน ดวยการระบชวง

ตวเลขทตองการหารากสมการขนมากอน สมมตวาอยในชวง a ถง b โดยทคา b มคามากกวา a

เขยนเปนสญลกษณไดเปน [a,b] a คอ ขดจากดลาง b คอ ขดจากดบน คาฟงกชน f(x) ในชวง

[a,b] นตองมคาตอเนอง เมอนา a และ b แทนคาลงในฟงกชนแลว ผลคณของคาฟงกชนจะตอง

มคาเปนลบ ( f(a).f(b) < 0 )

ขนตอนการหารากสมการมดงน

ขนท 1 เลอกคา a และ b โดยการสมแตตองทาให

f(a).f(b) นอยกวา ศนย

ขนท 2 หาคารากสมการโดยประมาณโดยแบงครงชวง

ระหวาง a กบ b ใหจดทแบงครง (ครงท 1) นคอ

m1 (m คอ midpoint) m1 = (a + b)/2

ขนท 3 ขณะนชวง a และ b จะถกแบงเปน 2 ชวง โดย

ม m1 เปนจดแบงครง ตรวจสอบดวารากสมการทแทจรง

อยชวงใด

ก. ถา f(a).f(m1) < 0 แสดงวารากสมการอยใน

ชวง [a, m1]

ข. ถา f(m1).f(b) < 0 แสดงวารากสมการอยใน

ชวง [m1 , b]

ค. ถาf(a).f(m1) = 0 หรอนอยกวาความคลาดเคลอน

ทยอมรบใหมได แสดงวา m1 คอรากสมการ

และสนสดการคานวณ

ขนท 4 ถา m1 ยงไมใชรากสมการทตองการ ใหแบง

ครงชวงอก (ยอนกลบไปขนท 2 ) จากรป 2.5(ข)

m2 = ( a + m1)/2

m1 a b

m1 m2 a

(ก)

(ข)

รป 2.5 แสดงขนตอนการแบงครงชวง

m1 m2

(ค)

m3

Page 34: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

27

กระทาซาเชนนเรอย ๆ จนถง k ครง เมอได f(mk-1).f(mk) เทากบศนยหรอนอยกวา

ความคลาดเคลอนทกาหนดแลว คา mk นคอรากสมการทตองการ

การแบงครงชวงแตละครง จะทาใหความกวางของชวงตวเลขแคบลงเรอย ๆ แตละ

ครงจด mk จะเปนคาประมาณของรากสมการ การกระทาซาจะสนสดลงเมอ mk อยในชวง

ความคลาดเคลอนทยอมรบได (given tolerance, ε)

จะตองกระทาซาหรอวนรอบกครง จงจะไดคารากสมการทตองการ สามารถคานวณ

ไดดงน หลงจากกระทาซาได k รอบ ความกวางของชวงตวเลขทมคารากสมการอยจะมคาเปน

(b-a)/2k คารากสมการทแทจรงจะตองอย ณ จดใดจดหนงในชวง (b-a)/2k ดงนน

คารากสมการทแทจรง = คารากสมการทได (xk) ± ความคลาดเคลอนทยอมรบได

= xk ± (b-a)/2k

การวนรอบครงท k ทาใหไดคารากสมการโดยประมาณ (xk) นอยกวาคาความ

คลาดเคลอนทยอมรบได ε นนคอ

(b-a)/2k < ε

ใส log ทงสองขางจะได

k

b a

=

−ln( )

lnε2

ถาชวงตวเลขเรมตนหางกนเทากบ 1 หนวย (b-a = 1) และความคลาดเคลอนทยอม

ได ε เทากบ 0.0001 จะตองวนรอบในการคานวณ (k) เทากบ 14 ครง

เพอปองกนความผดพลาดทไมคาดคดเกดขน ทาใหโปรแกรมทางานวนรอบไมสนสด

จงนยมกาหนดจานวนรอบสงสดของการกระทาซาไวดวย

การใชงานฟงกชน Bisection โปรแกรม 2.1 Bisect.C เปนโปรแกรมทใชแกสมการแบบไมเปนเชงเสนโดยวธแบง

ครงชวง จะเกบสวนทคานวณหารากสมการโดยวธนไวทฟงกชน Bisection การนาไปใชงานตอง

กาหนดสงตาง ๆ ดงน

ก. คาคงททตองนยาม #define ZERO_APPROACH 1E-16

( = 1.E-07 for single precision)

#define DEFAULT_TOL 1.E-07

#define DEFAULT_LOOP 100

ข. การผานคาอนพทและเรยกใชฟงกชน int Bisection (double a, double b, double *root, int *loop_limit, double *tol)

a คอ คาตาสดของรากสมการโดยประมาณ

Page 35: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

28

b คอ คาสงสดของรากสมการโดยประมาณ

root คอ คารากสมการทคานวณได เมอคานวณเสรจแลวจะเกบคา

รากสมการไวในตวแปรน

loop_limit คาสงสดของการกระทาซา ตงคาโดยปรยายไวเทากบ 100

เมอฟงกชนทางานเสรจจะเกบจานวนครงการวนรอบไวใน

ตวแปรน

tol หมายถง tolerance คาความคลาดเคลอนทยอมใหไมเกนคาน ตงคาไวท

10-7

ค. ฟงกชนทเกยวของ Double TF (double x) ใชในการคานวณหาคา y

ง. การสงคากลบ ฟงกชน Bisection จะสงคากลบเปนจานวนเตม ทม

ความหมายดงน

0 --- ไมมขอผดพลาดใด ๆ เกดขน

1 --- ไมสามารถหาคารากสมการได เพราะ f(a).f(b) > 0

2 --- จานวนครงการกระทาเกนกวาคาสงสดทกาหนดไว

รายละเอยดของฟงกชนและการเรยกใชไดแสดงไวในโปรแกรม 2.1

/*Program 2.1 : Bisect.C

* Purpose: An example for finding the root of equation using

* Bisection Method.

* Author : Wachara R.

* Office : Dept of Science. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Last update : 12 DEC 93

*******************************************************/

#include <stdio.h>

#include <math.h>

#define ZERO_APPROACH 1.0E-7 /* = 1.0E-16 for double precision */

#define DEFAULT_TOL 1.0E-7

#define DEFAULT_LOOP 100

double TF(double); /* Target Function -- for finding roots */

void InputValue(double*,double*,int*,double*);

Page 36: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

29

int Bisection(double,double,double*,int*,double* );

void DisplayOutput(int,int,double,double );

/* Global Variable */

double left[1000],right[1000],middle[1000],ymiddle[1000];

double yl[1000],yr[1000];

void main()

{

double a,ya,b,yb,root,tolerance;

int loop_limit, error_check;

a = b= root = tolerance=0;

loop_limit = 0;

clrscr();

printf("\n\t\tFind Root of equation using Bisection Method.\n");

printf("\t\t=====================================\n");

InputValue(&a,&b,&loop_limit,&tolerance);

left[0]=a; right[0]=b;

error_check = Bisection(a,b,&root,&loop_limit,&tolerance);

DisplayOutput(error_check,loop_limit,root,tolerance);

}

void InputValue( double* lower, double* upper, int* maxloop, double* tol)

{

char buffer[81];

printf("\nInput lower bound value : ");gets(buffer);

/* scanf("%f, lower); */

*lower=atof(buffer);

printf("Input upper bound value : " );gets(buffer);

*upper=atof(buffer);

printf("Input Limit of iteration : ");gets(buffer);

*maxloop = atoi(buffer);

printf("Tolerence (default = 1E-7): ");gets(buffer);

*tol = atof(buffer);

}

void DisplayOutput(int printflag,int iter,double root,double tolerance)

{

int i;

Page 37: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

30

switch(printflag) {

case 0 : {

if (iter) {

printf("\n Iter a middle(x) b y(a) y(x) y(b)\n");

printf( "===== ======= ========= ======= =====

===== ====");

};

for ( i =1; i <= iter; i++) {

printf("\n%3d %10.5g %10.5g %10.5g %10.5g %10.5g %10.5g",

i,left[i],middle[i],right[i],yl[i],ymiddle[i],yr[i]);

if (i%15==0){

getch();

clrscr();

printf("\n Iter a middle(x) b y(a) y(x) y(b)\n");

printf( "===== ======= ========= ======= =====

===== ====");

}

}

printf("\n\n Approximate root of eqn = % 12.8f", root);

printf("\n function of this value = % 12.8f",TF(root));

printf("\n tolerence of f(x) = %e",tolerance);

break;

} /* case 0 */

case 1 : {

printf ("\n Can't found the root of equation in this interval.\n");

printf(" ( F(a)xF(b) = positive Integer)\n"); break;

}

case 2:{

printf("\nIt must exceed the limit of iteration.\n");break;

}

} /* switch */

}

/*================================================*/

int Bisection(double a, double b, double* root,int* loop_limit,double *tol)

{

Page 38: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

31

/* Function Description: finding a root of a real continuous function

by bisection method.

User's define Constant: #define ZERO_APPROACH 1e-07

#define DEFAULT_TOL 1.0E-7

#define DEFAULT_LOOP 100

Calling Function : flaot TF(double x)

The Target Function which you want to

find the root.

Output : If no error , the root and the number of

iterations will be stored in "root" and

"loop_limit" consequently.

Return Value : 0 -- No error

1 -- Can't find any roots of this function,

since F(a)*F(b) > 0

2 -- the iteration exceed the maximum

limit.

*/

double mid,ymid,ya,yb;

int found=0,i=0;

if (*loop_limit <= 0) *loop_limit = DEFAULT_LOOP;

if (*tol <= 0) *tol = DEFAULT_TOL;

ya = TF(a);yb = TF(b);

if (fabs((double)ya) <= ZERO_APPROACH) {

*root = a; found =1;

}

if (fabs((double)yb) <= ZERO_APPROACH) {

*root = b;

found = 1;

}

if ((!found)&& ( ya*yb > 0 ))

return 1; /* not found root in this interval [a,b] */

while (!found && (i <= *loop_limit)){

i +=1;

Page 39: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

32

left[i] =a; right[i]=b; /* for display only you can delete it.*/

mid = (a+b)/2.0;

middle[i] = mid; /* for display */

yl[i] = ya; yr[i]=yb; /* for dislay */

ymid = TF(mid); ymiddle[i] = ymid; /* for display */

/* if ( fabs((double)ymid) <= ZERO_APPROACH) break; */

if (fabs(mid-a) < *tol) break;

/*if (fabs(mid-a) < abs(a*tolerance)) || ( abs(ymid) <= tolerance))) break; */

if (ya*ymid <= 0 ){

b = mid;

yb = ymid;

}

else {

a= mid; ya = ymid;

}

} /* while */

if ( i > *loop_limit) {

return 2;

} else { *loop_limit=i;}

*root = mid;

return 0;

}

double TF(double x)

/* Write your function which you want to calculate roots here. */

{

double y;

/* y = 3*pow(x,2)+2*x -1; */

/* y = exp(x)-4*x; */

y = .98-exp(-1000/x);

return(y);

}

/*====================================*/

Page 40: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

33

ตวอยาง 2.1 วงจรไฟฟาประกอบดวยตวเกบประจ C ตวตานทาน R และแหลงจายไฟตรง

ξ โวลต ถา C มขนาด 10-5 ฟารด แหลงจายไฟตรงมแรงเคลอนไฟฟา 12 โวลต Rจะตองมคา

เทาไร ตวเกบประจจงจะสามารถเกบประจได 20 %ของคาสงสดในเวลา 0.01 วนาท

วธทา สมการแรงดนไฟฟาของวงจรเขยนไดดงน

q

CIR+ = ξ

แทนคา I = dq/dt

dq

dt

q

RC R+ =

ξ แกสมการเชงอนพนธ และใชเงอนไข เมอ t = 0 q = 0 จะไดคาตอบของสมการน คอ

q C e t RC= − −ξ ( )/1

กาหนดให q0 = εC คอประจคาสงสดทตวเกบประจสามารถเกบไวได แทนคาตาง ๆ

ลงในสมการ

q

qe R

0

0 01 100 02 15

= = − − −

. ( ). /

จดรปสมการใหอยในรป f(R) = 0

098 01000

. − =−

e R ประมาณคารากสมการพบวาอยในชวง 49400 ถง 49500 (ประมาณไดโดยใช

โปรแกรม ScanRoot.C ซงจะกลาวตอไปในหวขอ 2.4 ) จากนนใชโปรแกรม 2.1 Bisection.C หา

คารากสมการในชวงดงกลาวโดยใหความถกตองถงทศนยมตาแหนงทสอง จะไดคาความ

ตานทานทใชในวงจรนคอ 49498.32 โอหม หรอ ประมาณ 49 กโลโอหม

ผลลพธทไดจากการคานวณแตละขนตอน แสดงไวในรปท 2.7

รป 2.6 วงจร RC

CR

ξ

Page 41: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

34

รป 2.7 แสดงผลลพธทไดจากการใชโปรแกรม Bisection.C หารากสมการ

Find Root of equation using Bisection Method.

===================================

Input lower bound value : 49400

Input upper bound value : 49500

Input Limit of iteration :

Tolerance (default = 1E-7): 0.0001

Iter a middle(x) b y(a) y(x) y(b)

===== ==== ====== ======= ===== ===== =======

1 49400 49450 49500 3.9403e-05 1.9345e-05 -6.7337e-07

2 49450 49475 49500 19345e-05 9.3306e-06 -6.7337e-07

3 49475 49488 49500 9.3306e-06 4.3274e-06 -6.7337e-07

4 49488 49494 49500 4.3274e-06 1.8267e-06 -6.7337e-07

5 49494 49497 49500 1.8267e-06 5.7658e-07 -6.7337e-07

6 49497 49498 49500 5.7658e-07 -4.8417e-08 -6.7337e-07

7 49497 49498 49498 5.7658e-07 2.6408e-07 -4.8417e-08

8 49498 49498 49498 2.6408e-07 1.0783e-07 -4.8417e-08

9 49498 49498 49498 1.0783e-07 2.9705e-08 -4.8417e-08

10 49498 49498 49498 2.9705e-08 -9.3562e-09 -4.8417e-08

11 49498 49498 49498 2.9705e-08 1.0956e-08 -9.3562e-09

12 49498 49498 49498 1.0956e-08 1.581e-09 -9.3562e-09

13 49498 49498 49498 1.581e-09 -4.6688e-09 -9.3562e-09

14 49498 49498 49498 1.581e-09 -1.5439e-09 -4.6688e-09

Approximate root of equation = 49498.32031250

function of this value = -0.00000000

tolerance of f(x) = 1.00000e-02

Page 42: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

35

2.3 วธวางตาแหนงคาตอบผดท (Method of False Position) วธนคลายกบวธแบงครงชวง สงทตางกนคอแทนทจะประมาณคารากสมการเรมตน

ดวยจดกงกลาง กลบใชวธลากเสนตรงผานจด f(a) และ f(b) เสนตรงนตดผานแกน x ทจดใดจะใช

คานเปนคาประมาณเรมตน

เงอนไขทจะใชวธนได คอ f(x) จะตองเปนฟงกชนทมคาตอเนองในชวง [a,b] ผลคณ

ของ f(a) และ f(b) มคาเปนลบ เมอลากเสนตรงจากจด (a,f(a)) ไปยงจด (b,f(b)) ผานแกน x ท

จด (x1, 0) x1 จะเปนคาประมาณคาแรก (ดรป 2.8)

สมการของเสนตรงนคอ

y f(a)f(b) f(a)

(b a)(x a)− =

−−

ท x = x1 y = 0

− =−−

−f(a)f(b) f(a)

(b a)(x a)1

xa f(b) b f(a)

f(b) f(a)1 =−−

จากนนตรวจสอบตอไปวาระหวาง [a,x1] และ [x1,b] คารากสมการทแทจรงจะตก

อยชวงใด จะเหนไดชดวา ถา f(a) มคานอยกวา f(b) คา x1 จะเยองมาทางปลายจด a มากกวา

จด b การตรวจสอบทาไดโดยดเครองหมายของผลคณระหวาง f(a)f(x1) และ f(x1)f(b) เปลยน

คาชวง a และ b แลวหาคา x2 โดยวธเดยวกน กระทาซาเชนนเพอหาคา x3, x4, .... จนกระทงได

คา xk ซงมคานอยกวาคาความคลาดเคลอนทยอมใหได จงหยดการทางาน

การใชงานฟงกชน FalsePosition โปรแกรม 2.2 FalsePos.C เปนตวอยางการหารากสมการโดยวธวางตาแหนง

คาตอบผดท ฟงกชนทเปนสวนคานวณสาหรบขนตอนวธนคอ FalsePosition การนาไปใชม

เงอนไขดงน

ก. คาคงททตองนยาม #define ZERO_APPROACH 1.E-16

#define DEFAULT_TOL 1.E-07

#define DEFAULT_LOOP 100

ข. การผานคาอนพทและเรยกใชฟงกชน int FalsePosition (double a, double b, double *root, int *loop_limit, double *tol)

a คอ คาตาสดของรากสมการโดยประมาณ

รป 2.8 วธวางตาแหนงผดท

x1

b,f(b)

a

Page 43: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

36

b คอ คาสงสดของรากสมการโดยประมาณ

root คอ คารากสมการทคานวณได เมอคานวณเสรจแลวจะเกบคารากสมการ

ไวในตวแปรน

loop_limit คาสงสดของการกระทาซา ตงคาโดยปรยายไวเทากบ 100 เมอฟงกชน

ทางานเสรจจะเกบจานวนครงการวนรอบไวในตวแปรน

tol หมายถง tolerance คาความคลาดเคลอนทยอมใหไมเกนคาน ตงคาไวท 10-7

ค. ฟงกชนทเกยวของ Double TF (double x) ใชในการคานวณหาคา y

ง. การสงคากลบ ฟงกชน FalsePosition จะสงคากลบเปนจานวนเตม ทม

ความหมายดงน

0 --- ไมมขอผดพลาดใด ๆ เกดขน

1 --- ไมมคารากสมการในชวง [a,b]

2 --- จานวนครงการกระทาเกนกวาคาสงสดทกาหนดไว

รายละเอยดของฟงกชนและการเรยกใชไดแสดงไวในโปรแกรม 2.2

/*Program 2.2 : FalsePos.C

* Purpose: Show how to find the root of equation by

* Method of False Position.

* Author : Wachara R.

* Office : Dept of Science. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Last update : 23 March 94

**************************************************************/

#include <stdio.h>

#include <math.h>

#define ZERO_APPROACH 1.0E-7

#define DEFAULT_TOL 1.0E-7

#define DEFAULT_LOOP 100

double TF(double); /* Target Function -- for finding roots */

void InputValue(double*,double*,int*,double*);

int FalsePosition(double,double,double*,int*,double* );

void DisplayOutput(int,int,double,double );

Page 44: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

37

/* Global Variable */

double left[1000],right[1000],xx[1000],yy[1000];

double yl[1000],yr[1000];

void main()

{

double a,ya,b,yb,root,tolerance;

int loop_limit,error;

a = b= root = tolerance=0; loop_limit = 0;

clrscr();

printf("\n\t\tFind Root of equation by False Position

method\n");printf("\t\t=============================================\n");

InputValue(&a,&b,&loop_limit,&tolerance);

left[0]=a; right[0]=b;

error = FalsePosition(a,b,&root,&loop_limit,&tolerance);

DisplayOutput(error,loop_limit,root,tolerance);

}

void InputValue( double* lower, double* upper, int* maxloop, double* tol)

{

char buffer[81];

printf("\nInput lower bound value : ");gets(buffer);

*lower=atof(buffer);

printf("Input upper bound value : " );gets(buffer);

*upper=atof(buffer);

printf("Input Limit of iteration : ");gets(buffer);

*maxloop = atoi(buffer);

printf("Tolerence (default = 1E-7): ");gets(buffer);

*tol = atof(buffer);

}

void DisplayOutput(int printflag,int iter,double root,double tolerance)

{

int i;

switch(printflag) {

case 0 : {

if (iter) {

printf("\n Iter a Approx(x) b y(a) y(x) y(b)\n");

Page 45: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

38

printf( "===== ===== ====== ====== ===== =====

====");

};

for ( i =1; i <= iter; i++) {

printf("\n%3d %g %g %g %g %g ",i,left[i],xx[i],right[i],yl[i],yy[i],yr[i]);

if (i%15==0){

getch(); clrscr();

printf("\n Iter a middle(x) b y(a) y(x) y(b)\n");

printf( "===== ======= ========= = ===== =====

====");

}

}

printf("\n\n Approximate root of eqn = % g", root);

printf("\n function of this value = % 12.8f",TF(root));

printf("\n tolerence of f(x) = %e",tolerance); break;

} /* case 0 */

case 1 : {

printf ("\n Can't found the root of equation in this interval.\n");

printf(" ( F(a)xF(b) = positive Integer)\n");break;

}

case 2:{

printf("\nIt must exceed the limit of iteration.\n"); break;

}

} /* switch */

}

/*==============================================*/

int FalsePosition(double a, double b, double* root,int* loop_limit,double *tol)

{ /* Function Description : Finding the root of non-linear eqn using

method of false position

User's difine Constant:

#define ZERO_APPROACH 1.0E-7

#define DEFAULT_TOL 1.0E-7

#define DEFAULT_LOOP 100

Calling Function : double TF(double x)

Output : store a root of eqn in "root".

store number of loop in "loop_limit"

Page 46: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

39

Return Value : 0 -- No error occure

1 -- No root because F(a)*F(b) > 0

2 -- It must exceed loop limitation.

*/

double x,y,ya,yb;

int found=0,i=0;

if (*loop_limit <= 0) *loop_limit = DEFAULT_LOOP;

if (*tol <=0) *tol = DEFAULT_TOL;

ya = TF(a); yb = TF(b);

if (fabs((double)ya) <= ZERO_APPROACH) {

*root = a;found =1;

}

if (fabs((double)yb) <= ZERO_APPROACH) {

*root = b; found = 1;

}

if ((!found)&& ( ya*yb > 0 ))

return 1; /* not found root in this interval [a,b] */

while (!found && (i <= *loop_limit)){

i +=1;

left[i] =a; right[i]=b; /* for display */

x= (a*TF(b)-b*TF(a))/(TF(b)-TF(a));

xx[i] = x; /* for display */

yl[i] = ya; yr[i]=yb; /* for dislay */

y = TF(x); yy[i] = y; /* for display */

/* if ( fabs((double)ymid) <= ZERO_APPROACH) break; */

if (fabs(x-a) < *tol) break;

if (ya*y <= 0 ){

b = x; yb = y;

}

else { a= x; ya =y; }

} /* while */

if ( i > *loop_limit ) {

return 2; /* more than maximum limit */

} else { *loop_limit = i ;}

*root = x;

return 0;

Page 47: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

40

}

double TF(double x)

{ /* Your Target Function is here */

double y;

y= sqrt(1-x*x/(3.0e08*3.0e08)) -0.5;

return(y);

}

�/*===========================================*/

ตวอยาง 2.2 ทฤษฎสมพทธภาพของไอนสไตนกลาวไววา มวลของวตถจะเปลยนไป

ตามความเรว v ให m0 เปนมวลของวตถขณะอยนง m เปนมวลของวตถทความเรวใด ๆ

เปนไปตามสมการดงน

mm

1v

c

0

2

2

=

เมอ c คอความเรวของแสง = 3 × 108 เมตร/วนาท

ถาตองการใหวตถมมวลเปนสองเทาของมวลเดม วตถจะตองมความเรวเทาใด

วธทา 12

1

2

2

20− = =

v

c

m

m

1 05 02

2− − =v

c.

ใชโปรแกรม 2.3 ScanRoot.C ตรวจหารากสมการพบวาอยระหวางชวง 2.5E08 ถง

3.0E08 จากนนใชโปรแกรม 2.2 FalsePos.C หารากสมการ ตองการทศนยม 4 ตาแหนง

ผลลพธจะได 2.59808 × 108 เมตร/วนาท ผลของการคานวณของคอมพวเตอรแสดงไวในรป 2.9

หมายเหต ตองเปลยนแปลงฟงกชน TF ดงน

c = 3.0E08;

y = sqrt(1-x*x/(c*c)) - 0.5;

ถามขอผดพลาดระหวางการทางานของโปรแกรม แสดงขอความวา Float point :

domain error ใหกลบไปดความถกตองของฟงกชนอกครง

Page 48: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

41

รป 2.9 ผลลพธทไดจากโปรแกรม FalsePos.C

Find Root of equation by False Position method

====================================

Input lower bound value : 2.5e08

Input upper bound value : 3.0e08

Input Limit of iteration :

Tolerence (default = 1E-7):

Iter a Approx(x) b y(a) y(x) y(b)

===== ======= ========= ======= ===== ===== ====

1 2.5e+08 2.54773e+08 3e+08 0.0527708 0.0280001 -0.5

2 2.54773e+08 2.57172e+08 3e+08 0.0280001 0.0149188 -0.5

3 2.57172e+08 2.58413e+08 3e+08 0.0149188 0.00796926 -0.5

4 2.58413e+08 2.59065e+08 3e+08 0.00796926 0.00426318 -0.5

5 2.59065e+08 2.59411e+08 3e+08 0.00426318 0.00228243 -0.5

6 2.59411e+08 2.59596e+08 3e+08 0.00228243 0.00122248 -0.5

7 2.59596e+08 2.59694e+08 3e+08 0.00122248 0.000654958 -0.5

8 2.59694e+08 2.59747e+08 3e+08 0.00065495 0.000350894 -0.5

9 2.59747e+08 2.59775e+08 3e+08 0.00035089 0.00018806 -0.5

10 2.59775e+08 2.5979e+08 3e+08 0.00018806 0.000100798 -0.5

11 2.5979e+08 2.59798e+08 3e+08 0.00010079 5.39734e-05 -0.5

12 2.59798e+08 2.59803e+08 3e+08 5.39734e-05 2.89422e-05 -0.5

13 2.59803e+08 2.59805e+08 3e+08 2.89422e-05 1.55485e-05 -0.5

14 2.59805e+08 2.59806e+08 3e+08 1.55485e-05 8.3434e-06 -0.5

15 2.59806e+08 2.59807e+08 3e+08 8.3434e-06 4.46367e-06 -0.5

16 2.59807e+08 2.59807e+08 3e+08 4.46367e-06 2.43142e-06 -0.5

17 2.59807e+08 2.59807e+08 3e+08 2.43142e-06 1.32291e-06 -0.5

18 2.59807e+08 2.59808e+08 3e+08 1.32291e-06 6.76281e-07 -0.5

19 2.59808e+08 2.59808e+08 3e+08 6.76281e-07 3.99153e-07 -0.5

20 2.59808e+08 2.59808e+08 3e+08 3.99153e-07 2.14401e-07 -0.5

21 2.59808e+08 2.59808e+08 3e+08 2.14401e-07 1.22025e-07 -0.5

22 2.59808e+08 2.59808e+08 3e+08 1.22025e-07 2.96489e-08 -0.5

23 2.59808e+08 2.59808e+08 3e+08 2.96489e-08 2.96489e-08 -0.5

Approximate root of eqn = 2.59808e+08

function of this value = 0.00000003

tolerance of f(x) = 1.00000e-07

Page 49: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

42

2.4 การกาหนดชวงตวเลขทมคารากสมการ ทงวธแบงครงชวงและวธวางตาแหนงคาตอบผดท จะตองกาหนดชวงตวเลข [a,b]

ซงมรากสมการอยในชวงดงกลาว โดยจากการตรวจสอบวา f(a).f(b) ตองมคาตดลบ

คารากสมการในชวงทกาหนดให อาจเปนไปไดดงน

จากรป 2.10 ก. และ ข. ผลคณของ f(a).f(b)

จะไดคาตดลบ จานวนรากสมการในชวง [a,b] อาจม

เพยง 1 คา หรอเปนจานวนค

รป 2.10 ค. ผลคณของ f(a).f(b) มคาเปน

บวก

แสดงวาไมมคารากสมการในชวงน หรออาจมเปน

จานวนค ดงภาพ ง.

รป 2.10 จ. เสนกราฟสมผสกบแกน x ทจด c

แสดงวาตรงจดนมคารากสมการซากนอย 2 คา

รป 2.10 ฉ. เปนฟงกชนทมคาไมตอเนองใน

ชวง[a,b] ผดเงอนไขกบทกาหนดไว ถงแมวา f(a).f(b)

จะมคาตดลบกตาม การหารากสมการทมคาไมตอเนอง

อาจเกดผลทไมคาดคดได

b a

(ก)

b a

(ข)

b a

(ค)

b a

(ง)

c a b

รป 2.10 ลกษณะตาง ๆ ทอาจจะพบไดในชวง [a,b]

b

(จ)

a

(ฉ)

Page 50: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

43

ทดลองใชโปรแกรม Bisect.C (หรอ FalsePos.C) คานวณหารากสมการของฟงกชน

y = ex - 4x คารากสมการทแทจรงคอ 0.357 และ 2.153 ครงแรกใหชวงตวเลขทตองการหา

รากสมการคอ [0,2] คาความคลาดเคลอนไมเกน 0.0001 จะไดคาตอบคอ 0.35736 ครงท 2

กาหนดชวงตวเลขเปน [2,4] จะไดคารากสมการเทากบ 2.15326 ครงท 3 เปลยนชวงตวเลขท

ตองการหารากสมการเปน [0,3] โปรแกรมจะแสดงผลลพธดงรป 2.12

รป 2.12 เมอเลอกชวงตวเลขไมเหมาะสม จะไมสามารถหารากสมการได

Find Root of equation using Bisection Method.

==================================

Input lower bound value : 0

Input upper bound value : 3

Input Limit of iteration :

Tolerance (default = 1E-7): .0001

Can't found the root of equation in this interval.

( F(a)xF(b) = positive Integer)

โปรแกรมไมสามารถหาคารากสมการได ทง ๆ ทชวง [0,3] มรากสมการอยถง 2 คา

การมรากสมการอยในชวง [a,b] เปนจานวนคไมสามารถใชวธแบงครงชวงและวธวางตาแหนงผด

ทหาคารากสมการได เพราะเมอหาคา f(a).f(b) จะไดคาตดลบเชนกน กรณเชนนเรยกวาเกดขว

(pole) ขนในชวงตวเลขน

การกาหนดชวง [a,b] ทสามารถหาคารากสมการไดนน ทาไดโดยกาหนดคา a และ

b ใหมชวงกวาง จากนนแบงครงชวง [a,b] ออกเปนสวนเลก ๆ จานวนมาก แตละสวนมขนาด h

รป 2.11 เสนกราฟ y = ex - 4x

Page 51: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

44

แลวทดสอบวาในชวงแตละ h ใด ๆ คา f(x) และ f(x+h) มการเปลยนเครองหมายหรอไม ถาม

การเปลยนเครองหมายแสดงวามรากสมการอยในชวง [x, x+h] น ความกวางของ h ควรมคา

นอย ๆ มฉะนนจะเกดกรณรากสมการเปนจานวนคเกดขน

โปรแกรม 2.3 ScanRoot.C เปนโปรแกรมสน ๆ ใชในการหาชวงตวเลขทมคาราก

สมการปรากฏอย รายละเอยดของโปรแกรมมดงน

/* Program 2.3 : ScanRoot.c

Purpose: Search for intervals that containing one or an odd number

of roots, or poles, or both.

Author : Wachara Rodsumrid. Last update : 07 MAR 94

*******************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

double tf(float); /* Target Function */

void main()

{

double a ,b, /* starting and ending value of x */

h, /* constant increment of interval */ x, y, yb;

char buffer[255];

int i,found;

clrscr(); printf("\n\t\tSearch for Interval that containing roots.");

printf("\n\t\t===================================");

printf("\nStarting value of x : ");gets(buffer); a =atof(buffer);

printf("Ending value of x : ");gets(buffer); b = atof(buffer);

printf("Increment of x : ");gets(buffer);h = atof(buffer);

if ( a > b) { x = b; b= a; a= x; }

i = 0; x = a; found=0;

while ( x < b) {

y = tf(x); yb = tf(x+h); i+=1;

if ( y*yb < 0 ) {

printf("\nInterval that contain root(s) : [%g, %g]",x,x+h);

found +=1;

} x += h;

}

Page 52: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

45

printf("\n\n Found %d interval !!\n",found); exit(0);

}

double tf(float x) {

double y, tmp, c = 3.0e08;

tmp = 1-x*x/(c*c); y = sqrt(tmp) -0.5; return(y);

}

ทดสอบโปรแกรมโดยการหาชวง [a,b] ทมคารากของสมการ y = ex - 4x ครงแรกกาหนดให a =

0, b = 5 แบงชวงระหวาง a และ b ขนาดเทากบ 1 ( h = 1) ผลลพธแสดงไวในรป 2.13

ครงท 2 กาหนดให a = 0, b = 9 แตคา h มคากวางมากเทากบ 3 ผลลพธทไดแสดงไวในรป 2.14

รป 2.13 การหาชวงตวเลขทมรากสมการ เมอกาหนดขนาดชวงกวางเทากบ 1

Search for Interval that containing roots.

==============================

Starting value of x : 0

Ending value of x : 5

Increment of x : 1

Interval that contain root(s) : [0, 1]

Interval that contain root(s) : [2, 3]

Found 2 interval !!

รป 2.14 เมอกาหนดชวงกวางเทากบ 3

Search for Interval that containing roots.

================================

Starting value of x : 0

Ending value of x : 9

Increment of x : 3

Found 0 interval !!

Page 53: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

46

2.5 วธนวตน-ราฟสน (Newton - Raphson Method) ถากาหนด x0 เปนคาแรกของการประมาณคารากสมการ คารากสมการทแทจรง

คอ α h เปนคาความคลาดเคลอน รากสมการของฟงกชน f(x) = 0 คอ α = x0 + h

กระจายฟงกชน f(x) เปนอนกรมเทเลอร รอบจด x0 จะได

f(x) = f( x0 + h ) = f(x0) + h f′(x0) + h2 f′′(x0) + ..........

2!

ความคลาดเคลอน h มคานอย ๆ จนสามารถตด h2, h3 .... ทงได จะเหลอ

f(x0) + h f′(x0) = 0

h ≈ - f(x0) / f′(x0)

แทนคา h จะไดคารากสมการทใกลเคยงคาจรงมากกวา x0 คอ

x1 = x h xf(x )

f (x )0 00

0

+ = −′

กระทาซา x2, x3 ..... จนไดคาทมความคลาดเคลอนนอยลงจนถงครงท xi+1

สามารถเขยนเปนสตรทวไปไดดงน

xi+1 = xf(x )

f (x )ii

i

−′

...................(2.2)

เมอ i = 0,1,2,3......

สมการ (2.2) เปนสมการของนวตน-ราฟสน ใชสาหรบหารากสมการของฟงกชน

f(x) สามารถนาสมการนไปใชถอดรากและหาคาสวนกลบของเลขจานวนจรงได ดงตวอยาง

ตอไปน

ตวอยาง 2.3 จงหาคา ck เมอ k เปนจานวนเตมบวก c เปนจานวนจรงมคามากกวาศนย

วธทา โจทยตองการหาคา x ท x = ck

จดรปสมการใหม xk - c = 0

นนคอ f(x) = xk - c

f'(x) = kxk-1

แทนคา f(x), f′(x) ลงในสมการ 2.2

x i 1+ = ( )11 1− + −

kx

c

kxi i

k ...................(2.3)

สมการนจะลเขาสคา ck ทก ๆ คาเรมตน x0 โดยท x0 > 0

ถา k = 2 จะได x = c เปนการหารากท 2 ของ c นนเอง จะไดเปนสตรเฉพาะกรณ

คอ

Page 54: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

47

x i 1+ = 1

2( )x

c

xii

+ ...................(2.4)

----------------------------------------

ตวอยาง 2.4 จงหารากสวนกลบท k ของ c (reciprocal kth root of c)

วธทา x = 1

ck

xc

k −1

= 0

เปลยนรปสมการใหมจะได c - x-k = 0 = f(x)

f ′(x) = k x-k-1

แทนคา f(x), f′(x) ลงในสมการ 2.2 จะได

x i 1+ = xi

(c1

xk )

i(k 1)

kx−

− + .................... (2.5)

ถา k = 1 และ x = 1/c จะได

x i 1+ = x cxi i− −( )2 .................... (2.6)

----------------------------------------

ตวอยาง 2.5 จงแกสมการ 1

m x1 02 − =

วธทา ให f(x) = 1

m x 12 − f′(x) = -1/m2x2

xi+1 = xi - f(xi) = 2xi - m2xi เมอ i = 0,1,2,......

f′(xi)

----------------------------------------

การลเขาหาคาตอบของวธนวตน-ราฟสน เราสามารถแสดงการหารากสมการของวธนวตน-ราฟสนได โดยใชเรขาคณตวเคราะหดงน

α คอคารากทแทจรงของ y = f(x) x0 คอ คาประมาณเรมตน

ทจด A (x0,y0) ลากเสนสมผสทจด A ตดกบแกน x ทจด x1 สมการเสนสมผสทจด A คอ

y - y0 = f′(x0) (x-x0)

แทนคา x = x1 , y = 0 จะได x1 = x0 - f(x0)/ f′(x0) ซงเปนสมการท (2.2)

นนเอง

Page 55: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

48

รป 2.15 แสดงการใชเสนสมผสหาสตรของนวตน-ราฟสน

ตอไปหาคา x2 ซงใกลเคยงคารากทแทจรงมากกวา x1 ทจด B (x1, y1) ลากเสนสมผส

ตดแกน x ทจด x2 จะได x2 = x1 - f(x1) / f′(x1)

คา x2 จะอยใกลคา α มากกวา x1 แตละครงการประมาณคา คา xi จะลเขาหาคา

รากทแทจรง α อยางรวดเรว วธของนวตน-ราฟสนใชเสนสมผสของคารากสมการคาเกา หาคา

รากสมการถดไป บางครงเรยกวธนวาเปนวธลากเสนสมผสเพอหาคาตอบ ( method of tangent)

อตราเรวของการลเขาหาคาตอบของวธนวตน-ราฟสน หาไดดงน

ให en+1 เปนความคลาดเคลอนครงท n+1

en+1 = α - xn+1 = α - ( xn - f(xn) / f′(xn)

= ( α - xn) + f(xn) / f′(xn)

= en - f ( α - en)

f′(α- en)

กระจาย f(α- en) เปนอนกรมเทเลอร โดยท f(α) = 0

f(α-en) = f(α) - en f′(xn) + en2 f′′(α) - .......

2!

en+1 = en + f(α) - en f′(α) + en2 f′′(α)/2!

f′(α) - enf′′(α) + en2 f′′′(α)/2!

≈ - en2 f′′(α)

2 f′(α)

A

x1 x2 x0

B

Page 56: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

49

ความคลาดเคลอนครงถดไป (n+1) เปนปฏภาคตรงกบกาลงสองของความผดพลาด

ของคาปจจบน (n) เรยกวาเปนการลเขาแบบกาลงสอง ( quadratic) อตราการลเขาจะเรวกวาวธ

แบงครงชวงและวธวางตาแหนงคาตอบผดท

การใชงานฟงกชน Newton_Raphson โปรแกรม 2.4 Raphson.C เปนตวอยางการนาฟงกชน Newton_Raphson ไปหาราก

สมการ การนาไปใชรวมกบโปรแกรมอน ๆ ทาไดดงน

ก. คาคงททตองนยาม #define ZERO_APPROACH 1.E-16

#define DEFAULT_TOL 1.E-07

#define DEFAULT_LOOP 100

ข. การผานคาอนพทและเรยกใชฟงกชน int Newton_Raphson (double *guess, double *tol, int *loop_limit,double *root)

guess คอ คาประมาณของรากสมการตอนเรมตน

tol หมายถง tolerance คาความคลาดเคลอนทยอมใหไมเกนคาน ตง

คาไวท 10-7

root คอ คารากสมการทคานวณได

loop_limit คาสงสดของการกระทาซา ตงคาโดยปรยายไวเทากบ 100

เมอฟงกชนทางานเสรจจะเกบจานวนครงการวนรอบไวใน

ตวแปรน

ค. ฟงกชนทเกยวของ Float TF (float x) ใชในการคานวณหาคา y

Float Diff_TF(float x) คานวณคาอนพนธของฟงกชน

ง. การสงคากลบ จะสงคากลบเปนจานวนเตม ทมความหมายดงน

0 --- ไมมขอผดพลาดใด ๆ เกดขน

1 --- ไมสามารถหารากสมการได เพราะคาอนพนธของ f(x) เทากบศนย

2 --- จานวนครงการกระทาซาเกนกวาคาสงสดทกาหนดไว

รายละเอยดของฟงกชนและการเรยกใชไดแสดงไวในโปรแกรม 2.4

/*Program 2.4: Raphson.C (Newton_Raphson.C)

* Purpose: An example for Finding a real root of a given function

* using Newton-Raphson's algorithm.

* Author : Wachara R.

* Last update : 13 MAR 94

Page 57: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

50

**************************************************************/

#define DEFAULT_LOOP 100

#define DEFAULT_TOL 1.0E-07

#define ZERO_APPROACH 1.0E-16

#include <stdio.h>

#include <math.h>

double TF(double); /* Target Function declaration */

double Diff_TF(double); /* Derivative of Target function */

void UserInput(double*,double*,int*);

int Newton_Raphson(double*,double*,int*,double*);

void ShowResult(int,int,double,double );

/* Global Variable */

double ax[1000],afx[1000],adfx[1000],anewx[1000];

void main()

{

double first_guess,root,tolerance;

int loop_limit,error;

first_guess = root = tolerance=0; loop_limit = 0; error = 0;

clrscr();

printf("\n\t\tFind the Root of equation using Newton-Raphson

Method.\n");

printf("\t\t============================================\n");

UserInput(&first_guess,&tolerance,&loop_limit);

error = Newton_Raphson(&first_guess,&tolerance,&loop_limit,&root);

ShowResult(error,loop_limit,root,tolerance);

}

void UserInput( double* guess, double* tol, int* maxloop)

{

char buffer[81];

printf("\nInput approximated value of the root : ");gets(buffer);

*guess=atof(buffer);

printf("Input Limit of iteration : ");gets(buffer);

*maxloop = atoi(buffer);

printf("Tolerence (default = 1E-7): ");gets(buffer);

Page 58: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

51

*tol = atof(buffer);

}

void ShowResult(int printflag,int iter,double root,double tolerance)

{

int i;

switch(printflag) {

case 0 : {

if (iter) {

printf("\n Iter x f(x) f'(x) xn = x-f(x)/f'(x) \n");

printf( "===== ======= ========= =======

==================");

};

for ( i =1; i <= iter; i++) {

printf("\n%3d %10.5f %10.5f %10.5f \t%10.5f

",i,ax[i],afx[i],adfx[i],anewx[i]);

if (i%15==0){

getch();

clrscr();

}

}

printf("\n\n An Approximated root of eqn = % 12.8f", root);

printf("\n function of this value = %12.8f",TF(root));

printf("\n tolerence of f(x) = %e",tolerance);

break;

} /* case 1 */

case 1 : {

printf ("\n Can't found the root of equation .\n");

printf(" ( Derivative of F(x) = 0)\n");

break;

}

case 2:{

printf("\nIt must exceed the limit of iteration.\n");

break;

}

} /* switch */

}

Page 59: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

52

/*=============Function Start here ============*/

int Newton_Raphson(double*guess,double

*tol,int*loop_limit,double* ans)

{/*Function Description: Solving eqn using Newton_Raphson Method

User's Define Constant:

#define DEFAULT_LOOP 100

#define DEFAULT_TOL 1.0E-07

#define ZERO_APPROACH 1.0E-7

Calling Function: double TF(double x);

double Diff_TF(double x);

Output : root of eqn. kept in 'ans'

number of iteration kept in 'loop_limit'

Return value : 0 -- No error occure.

1 -- Can't find solution. f'(x) = 0

2 -- Exceed the limit of iteration.

*/

int i=1, found = 0;

double x, newx, y , dy=1;

x = *guess;

newx = *ans = 0;

if ( *loop_limit <= 0) *loop_limit = DEFAULT_LOOP;

if ( *tol <= 0 ) *tol = DEFAULT_TOL;

while (!found && (i <= *loop_limit)&& dy != 0){

y = TF(x);

dy = Diff_TF(x);

ax[i] = x; afx[i] = y;

adfx[i] = dy; /* keep them for displaying */

newx = x - y/dy;

anewx[i] = newx;

if ( fabs(newx-x) < *tol) {

found = 1;

*ans = newx;

}

Page 60: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

53

x = newx;

i+=1;

}

*loop_limit = i-1;

if (dy == 0)

return(1);

if (i >= *loop_limit && !found)

return (2);

return 0;

}

double TF(double x)

{

/* return( cos(x)-x); */

/* return(15.73-45.73*exp(-0.2142*x));*/

/* return(tan(x)-0.5*x);*/

return(10*tan(x));

}

double Diff_TF(double x)

{

/* return(-sin(x)-1); */

/* return (45.73*0.2142*exp(-0.2142*x)); */

/* return (1/(cos(x)*cos(x)) -0.5); */

return(1/(cos(x)*cos(x)));

}

/*========================================*/

Page 61: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

54

ขอควรระวงเมอใชวธนวตน-ราฟสน คารากสมการโดยประมาณซงใชเปนคาเรมตน ถามคาใกลเคยงกบคารากทแทจรง

อตราการลเขาสคารากทแทจรงจะเกดขนอยางรวดเรว หรอกระทาซาไมกครงกจะไดคารากท

ตองการ การกาหนดคาเรมตนของรากสมการไมเหมาะสมอาจเกดเหตการณทไมพงประสงค

ดงตวอยางตอไปน

- เกดการยอนกลบไปกลบมา (Oscillation) รอบ ๆ คารากสมการ ดงรป 2.13 เมอ

กาหนดคาเรมตน x0 จะไดคา x1 และคา x1 จะทาใหไดคา x2 ซงมคาเทากบคา x0 ซากนอกครง

คาทไดจะยอนกลบไปกลบมาไมสนสด

รป 2.16 แสดงคารากวนซากลบไปกลบมา

- เกดการลเขาไปสคารากสมการทไมตองการ หรอเขาสคาอนนต จากรป 2.14

กาหนดคาเรมตน x0 คารากโดยประมาณตอไปคอ x1, x2 และ x3 จะเหนวาจะไดคารากสมการเปน

α‘ แทนทจะเปน α ซงอยใกลจด x0 มากกวา เหตการณเชนนมกจะเกดขนกบฟงกชนทมคาราก

หลายคา แตละคาอยไมหางกนนก

รป 2.17 ก. การลเขาสคารากทไมตองการ ข. การลสคาอนนต

x0= x2 = x4 = .. x1= x3 = x5 = ..

x0 x1

x0 α′ αx2 x3 x1

Page 62: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

55

ตวอยาง 2.6 สมการการเคลอนทแบบ Simple Harmonic Motion y = 10cos x เขยนเปนกราฟ

ไดดงรป เมอกาหนดคาเรมตนตาง ๆ กน ผลลพธจะไดคารากสมการดงน

คาเรมตน x ลไปสคาราก

1.5 1.570

3 -4.712

3.5 -1.570

5 -4.172

6 1.570

แสดงใหเหนวาถากาหนดคาเรมตนของรากสมการไมเหมาะสม การลเขาจะไปสคา

รากทไมตองการ

วธของนวตน-ราฟสนยงไมเหมาะสมกบฟงกชนทมลกษณะซบซอนมาก หาคา

อนพนธของฟงกชนไดลาบาก ตวอยางเชน y x x e ex x x= + − −sin( sec )/cot4 3 2

ตวอยาง 2.7 วตถมวล m ตกอยางอสระภายใตแรงโนมถวงของโลก แรงตานของอากาศแปร

ผนตรงกบความเรวของวตถนน จะไดสมการความเรงของวตถนคอ ma = mg - cv เมอ a และ

v คอความเรงและความเรวของวตถทเวลาใด ๆ c เปนคาสมประสทธแรงตานอากาศ

กาหนดให m = 70 กก. c = 15 กโลกรม/วนาท เปนเวลานานเทาใดวตถจงจะม

ความเรว เปน 30 เมตร/วนาท g = 9.81 เมตร/วนาท 2

วธทา หาสมการความเรวของวตถ โดยอนทเกรตสมการความเรง แลวใชเงอนไขเมอ

t = 0, v = 0 จะไดสมการความเรว a = dv

dt = g

cv

m−

รป 2.18 เสนกราฟ y = 10 cos x

Page 63: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

56

dv

gcv

m

dt−

= ∫∫

− − = +m

cg

cv

mt cln( ) 1

เมอ t = 0 v = 0 จะไดคา c1 = - m ln g / c

แทนคา c1 จะได

vmg

ce c m t= − −( )( / )1

แทนคา m = 70 กโลกรม c = 15 กโลกรม/เมตร v = 30 เมตร/วนาท g = 9.81

เมตร/วนาท2

1573 4573 00 2142. . .− =−e t ใชโปรแกรม 2.3 ScanRoot .C ตรวจสอบรากสมการพบวาอยระหวาง [4,5] ใช

โปรแกรม 2.4 Raphson.C หารากสมการโดยตองการทศนยม 4 ตาแหนง กาหนดใหคาเรมตนของ

รากสมการ คอ 4.5 ผลลพธดงแสดงไวในรป 2.19

รป 2.19 ผลลพธทไดจากการคานวณโดยใชฟงกชน Newton_Raphson

Find the Root of equation using Newton-Raphson Method.

============================================

Input approximated value of the root : 4.5

Input Limit of iteration : 500

Tolerance (default = 1E-7): 0.0001

Iter x f(x) f'(x) xn = x-f(x)/f'(x)

===== ===== ====== ===== ==========

1 4.50000 -1.71154 3.73598 4.95812

2 4.95812 -0.08130 3.38678 4.98213

3 4.98213 -0.00021 3.36941 4.98219

An Approximated root of eqn = 4.98218870

function of this value = -0.00000001

tolerance of f(x) = 1.00000e-04

หมายเหต ใหแกไขฟงกชน TF(x) และ Diff_TF(x) เปนดงน

y = 15.73 -45.73*exp(-0.2142*x);

dy = 45.73*0.2142*exp(-0.2124*x);

ma cv

mg

รป 2.19 วตถตกอยางอสระ มแรงตานอากาศ

Page 64: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

57

2.6 วธเซแคนต ( Secant Method ) กรณทฟงกชนมคาซบซอน การอนพนธของฟงกชนทาไดไมสะดวก ใชเวลาในการ

คานวณมาก อาจเลยงไปใชวธเซแคนต วธนเรมตนดวยการประมาณคารากสมการเรมตน

2 คา และจะใชคารากทงสองนคานวณหาคาฟงกชนและคารากครงตอ ๆ ไป โดยไมจาเปนตอง

หาคาอนพนธของฟงกชน ไมตองทดสอบวาคาฟงกชนของคาประมาณทงสองมคาตดลบหรอไม

เรมตนดวยการประมาณคาราก

สมการ ใหมคาเปน x1 และ x2 ลากเสนตรงเชอม

ระหวางจด (x1,f(x1) ) และ ( x2 , f(x2) ) เสน

ตรงนตดแกน x ทจด x3

ความชนของเสนตรง AB หาไดจาก

f(x ) f(x )

x x2 1

2 1

−−

= f(x ) 0

x x1

1 3

−−

จะได x3 = x f(x ) x f(x )

f(x ) f(x )1 2 2 1

2 1

−−

รป 2.18 แสดงการหารากสมการโดยวธเซแคนต

จากนนลากเสนตรงเชอมระหวางจด (x3, f(x3)) และ ( x2 , f(x2)) เสนตรงนไปตดแกน

x ทจด x4 โดยท

x4 = x f(x ) x f(x )

f(x ) f(x )2 3 3 2

3 2

−−

ในทานองเดยวกนกบ x5, x6, ... , xn สามารถเขยนเปนสตรทวไปไดดงน

xn = x f(x ) x f(x )

f(x ) f(x )n-2 n-1 n-1 n-2

n-1 n-2

−−

.................(2.7)

เราสามารถหาสตรการประมาณคา xn ใด ๆ ไดอกวธหนงดงน

สมการทใชแทนเสนตรง AB คอ

y - f(x1) = f(x ) f(x )

x x2 1

2 1

−−

ทจด x3 จะไดคา y = 0

x3 = x(x x )f(x )

f(x ) f(x )22 1 2

2 1

−−−

x4 x3 x2 x1

A

B

Page 65: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

58

เขยนใหอยในรปทวไปไดดงน

xn = xf(x )

f(x ) f(x )

(x x )

n 1n 1

n 1 n 2

n 1 n 2

−−

− −

− −

− −−

...............(2.8)

สมการ (2.8) มสวนคลายกบสตรของนวตน-ราฟสนในสมการ (2.2) แตกตางกนตรง

สวน แทนทจะเปนคาอนพนธ สตรของวธเซแคนตจะเปนการหาความชนของเสนตรงทลากผาน

จด xn ในฟงกชน Secant( ) จะใชสมการ (2.8) หาคารากสมการ

ขอควรระวงของการใชวธนคอ ถาคา xn-1 และ xn มคาใกลกนมาก นนคอ yn-1 และ yn

จะมคาเขาใกลกนมากตามไปดวย ผลตางของ yn-1 และ yn จะมคานอย จะเกดความ

คลาดเคลอนเนองจากการปดเศษ ยงกระทาซาหลายครง ความคลาดเคลอนนจะถกสะสมเพมขน

เรอย ๆ จนไดคารากสมการทผดไปจากคาทแทจรงมาก การกาหนดคาเรมตนทไมเหมาะสม อาจ

ทาใหเกดการลเขาสคารากทไมตองการ หรอไมลเขาเลยเชนเดยวกนกบวธของนวตน-ราฟสน

การใชงานฟงกชน Secant โปรแกรม 2.5 Secant.C เปนตวอยางการนาฟงกชน Secant( ) ไปหารากสมการ

การนาไปใชรวมกบโปรแกรมอน ๆ ทาไดดงน

ก. คาคงททตองนยาม #define ZERO_APPROACH 1.E-16

#define DEFAULT_TOL 1.E-07

#define DEFAULT_LOOP 100

ข. การผานคาอนพทและเรยกใชฟงกชน int Secant (double x1, double x2, double *root, int *max_loop, double *tol)

x1,x2 คอ คาประมาณของรากสมการตอนเรมตน

tol หมายถง tolerance ตงคาไวท 10-7

root คอ คารากสมการทคานวณได

max_loop คาสงสดของการกระทาซา ตงคาโดยปรยายไวเทากบ 100

ค. ฟงกชนทเกยวของ Double TF (double x) ใชในการคานวณหาคา y

ง. การสงคากลบ จะสงคากลบเปนจานวนเตม ทมความหมายดงน

0 --- ไมมขอผดพลาดใด ๆ เกดขน

1 --- เกดกรณทความชนเทากบศนย

2 --- จานวนครงการกระทาซาเกนกวาคาสงสดทกาหนดไว

Page 66: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

59

รายละเอยดของฟงกชนและการเรยกใชไดแสดงไวในโปรแกรม 2.5

/*Program 2.5: Secant.C

* Purpose: Example for finding a real root of a function by Secant method.

* Author : Wachara R.

* Last update : 24 March 94

**************************************************************/

#define DEFAULT_LOOP 100

#define DEFAULT_TOL 1.0E-07

#define ZERO_APPROACH 1.0E-07

#include <stdio.h>

#include <math.h>

double TF(double); /* Target Function -- for finding roots */

void InputValue(double*,double*,int*,double*);

int Secant(double,double,double*,int*,double* );

void DisplayOutput(int,int,double,double );

/* Global Variable */

/* keeping the results in array for display */

double first[1000],second[1000],xx[1000],yy[1000];

void main()

{

double guess1, /* first initial guess */

guess2, /* second guess */

root,tolerance;

int loop_limit, /* Maximum of Iteration */

error; /* Flag for printing output */

guess1 = guess2 = root = tolerance=0;

loop_limit = 0; error = 0;

clrscr();

printf("\n\t\tFind Root of equation by Secant method\n");

printf("\t\t===========================================\n");

InputValue(&guess1,&guess2,&loop_limit,&tolerance);

error = Secant(guess1,guess2,&root,&loop_limit,&tolerance);

Page 67: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

60

DisplayOutput(error,loop_limit,root,tolerance);

}

void InputValue( double* lower, double* upper, int* maxloop, double* tol)

{

char buffer[81];

printf("\nInput First initial estimated root : ");gets(buffer);

*lower=atof(buffer);

printf("Input Second initial estimated root : " );gets(buffer);

*upper=atof(buffer);

printf("Input Limit of iteration : ");gets(buffer);

*maxloop = atoi(buffer);

printf("Tolerance (default = 1E-7): ");gets(buffer);

*tol = atof(buffer);

}

void DisplayOutput(int printflag,int iter,double root,double tolerance)

{

int i;

switch(printflag) {

case 0 : {

if (iter) {

printf("\n Iter Guess 1 Guess 2 x y(x) \n");

printf( "===== ======= ========= =======

========");

};

for ( i =1; i <= iter; i++) {

printf("\n%3d %10.5f %10.5f %10.5f %10.5f ",

i,first[i],second[i],xx[i],yy[i]);

if (i%15==0){

getch();

clrscr();

printf("\n Iter Guess 1 Guess 2 x y(x) \n");

printf( "===== ======= ========= =======

========");

}

}

Page 68: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

61

printf("\n\n Approximate root of eqn = % 12.8f", root);

printf("\n tolerance of f(x) = %e",tolerance);

break;

} /* case 0 */

case 1 : {

printf ("\n The slope is nearly zero. Choose a new Guess!!.\n");

break;

case 2:{

printf("\nIt must exceed the limit of iteration.\n");

break;

}

}

} /* switch */

}

/*==========================================*/

int Secant(double x1, double x2, double* root,int* maxloop,double *tol)

{

/* Function Description: Solving eqn using Secant Method.

User's define Constant: #define DEFAULT_LOOP 100

#define DEFAULT_TOL 1.0E-07

#define ZERO_APPROACH 1.0E-07

Calling Function : double TF(double x);

Output : root of equation in 'root'

no. of iteration in 'maxloop'

Return Value : 0 -- everything's ok.

1 -- The slope approach to zero

2 -- no. of iteration exceed the limit.

*/

double x3,y1,y2,y3;

int found=0,i=0;

if (*maxloop <= 0 ) *maxloop = DEFAULT_LOOP;

if (*tol <= 0) *tol = DEFAULT_TOL;

y1 = TF(x1);

y2 = TF(x2);

if (fabs(y1) <= ZERO_APPROACH) {

Page 69: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

62

found = 1;

}else{

if (fabs(y2) <= ZERO_APPROACH) {

found = 1;

}else{

if (fabs(y2-y1) <= ZERO_APPROACH)

return(1);

}

}

while (!found && (i < *maxloop)){

i+=1;

first[i] =x1; second[i]=x2; /* for display */

x3 = x2-y2*(x2-x1)/(y2-y1); /* secant formula */

xx[i] = x3; /* for display */

y3 = TF(x3);

yy[i] = y3; /* for display */

if (fabs(x2-x1) < *tol) {

found = 1; break;

}

y1 = y2; x1 = x2;

x2 = x3; y2 = y3;

} /* while loop */

*root = x2;

if (i >= *maxloop && !found)

return 2;

else

*maxloop = i;

return 0;

}

double TF(double x)

{

double y;

y = 15.73-45.73*exp(-0.2142*x);

return(y);

}

/*===============================================*/

Page 70: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

63

2.7 การนาไปแก ปญหาทางฟสกส ตวอยาง 2.8 อดแกสไฮโดรเจนจานวน n กโลโมล ทอณหภมคงทท 300 เคลวน ปรมาตรของ

แกสเปลยนจาก V1 = 10 ลกบาศกเมตร เปน V2 = 0.1 ลกบาศกเมตร ใหแกสนมคณสมบต

เปนไปตามกฎสถานะแกสของแวน เดอร วาลล พบวางานทใชในการอดแกสนเทากบ 1153 กโล

จล จงหาปรมาณของแกสไฮโดรเจน (n)

วธทา จากกฎสถานะแกสของแวนเดอร วาลล จะไดสมการความดนของแกสดงน

PnRT

V nb

an

V=

−−

2

2

เมอ R คอคาคงทของแกส = 8.314 kJ/kmol.K

a,b คอคาคงทของแกสขนอยกบชนดของแกส สาหรบแกสไฮโดรเจน a = 24.8

kPa.m6/kmol2 b = 0.0266 m3/kmol

T คอ อณหภมสมบรณ

งานทใหแกระบบจนปรมาตรแกสเปลยนจาก V1 ไปเปน V2 คอ

W PdV nRTV nb

V nban

V V

V VV

V

= =−−

+−∫

1

2

2

1

2 1 2

1 2

ln( ) ( )

แทนคาตาง ๆ ลงในสมการจะได

9 9 24 8 2494 210 0 0266

01 002661153 02. . . ln(

.

. .)× +

−−

− =n nn

n

หารากสมการ n โดยวธเซแคนต ใชโปรแกรม 2.5 Secant.C เปลยนคาฟงกชนใน

โปรแกรมยอย TF( ) เปนดงน

double TF(x)

{ return(9.9*24.8*x*x + 2494.2*x*log((10-0.0266*x)/(0.1-0.0266*x))-1153 );}

ผลทคานวณไดจะปรากฏดงรป 2.21

Page 71: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

64

รป 2.21 ผลการคานวณจากตวอยาง 2.8 โดยใชโปรแกรม Secant.C

Find Root of equation by Secant method

===============================

Input First initial estimated root : 0

Input Second initial estimated root : 1

Input Limit of iteration :

Tolerance (default = 1E-7): 0.0001

Iter Guess 1 Guess 2 x y(x)

===== ===== ====== ==== ====

1 0.00000 1.00000 0.09227 -85.45525

2 1.00000 0.09227 0.09905 -6.30690

3 0.09227 0.09905 0.09959 0.00367

4 0.09905 0.09959 0.09959 0.00001

5 0.09959 0.09959 0.09959 0.00001

Approximate root of eqn = 0.09959424

tolerance of f(x) = 1.00000e-04

ตวอยาง 2.9 ความเรวของจรวดทเวลา t ใด ๆ พงขนไปในแนวดงหาไดจากสตร

v um

m ftgt=

−−ln( )0

0

เมอ u คอ ความเรวของจรวด ขณะทพนเชอเพลงดวยอตรา f

m0 คอ มวลของจรวดเมอ t = 0

f คอ อตราการพนเชอเพลง

g = 9.81 เมตร/วนาท2

กาหนดให u = 2200 เมตร/วนาท m0 = 1.6 × 105 กโลกรม f = 2.68 × 103 กโลกรม/

วนาท จงหาเวลาทจรวดมความเรว 1 กโลเมตร/วนาท (ใหคา t เรมตนอยระหวาง 10 และ 50

วนาท)

วธทา 1) แทนคาตาง ๆ ทโจทยกาหนดใหลงในสมการความเรว

1000 220016 10

16 10 2 68 109 81

5

5 3=×

× − ×−( ) ln(

.

. .) .

tt

หรอ

9 81 220016 10

16 10 2 68 101000 0

5

5 3. ln(.

. .)t

t−

×× − ×

+ = (ก)

2) เรยกใชโปรแกรม Secant.C นาสมการ (ก) ใสลงในฟงกชน TF ดงน

double TF (double t){ return (9.81*t - 2200*log ((1.6e5)/(1.6e5 - 2.64e3*t)) + 1000 ); }

Page 72: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

65

จากนนคอมไพลโปรแกรม Secant.Cใหโปรแกรมทางานแลวปอนขอมลเขาไปดงรป 2.22

Find Root of equation by Secant method

=============================

Input First initial estimated root :10

Input Second initial estimated root :50

Input Limit of iteration :

Tolerance (default = 1E-7):

Iter Guess 1 Guess 2 x y(x)

===== ======= ========= ======= ========

1 10.00000 50.00000 18.67984 357.68368

2 50.00000 18.67984 22.59038 175.64261

3 18.67984 22.59038 26.36346 -23.22226

4 22.59038 26.36346 25.92286 1.34039

5 26.36346 25.92286 25.94690 0.00975

6 25.92286 25.94690 25.94708 -0.00000

7 25.94690 25.94708 25.94708 0.00000

8 25.94708 25.94708 25.94708 0.00000

Approximate root of eqn = 25.94707893

tolerance of f(x) = 1.000000e-07

รป 2.22 ผลลพธในตวอยาง 2.9

ตวอยาง 2.10 กระแสไฟฟาในวงจรหนงเขยนไดเปน I = 10 e-t sin 2πt จงหาคา t มหนวยเปน

วนาท จงหาคา t ทก ๆ คาทเปนไปไดททาให I = 2 แอมแปร

วธทา 1) แทนคา I = 2 A ลงในสมการทโจทยกาหนดให จดรปสมการใหมจะได

10 e-t sin 2πt - 2 = 0

2) ใชโปรแกรม Scanroot.C (อยาลมแกไขฟงกชน TF ดวย) ตรวจสอบชวงตวเลขทจะพบ

รากสมการ โดยเรมตงแต t = 0 ถง t = 10 วนาท ระยะหางชวงละ 0.1 จะพบคารากสมการอย

ระหวางชวงตอไปน [0,0.1] [0.4,0.5] [1.1,1.2] และ [1.3,1.4]

3) ใชโปรแกรม Secant.C หารากสมการแตละชวง จะไดรากสมการ t = 0.03309541,

0.44867283, 1.10120789 และ t = 1.35660141 วนาท

Page 73: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

66

ตวอยาง 2.11 แกสคารบอนมอนนอกไซด 1 กโลโมล บรรจอยในภาชนะทอณหภม 215 เคลวน

ความดน 7000 กโลปาสคาล จงคานวณหาปรมาตรของแกสโดยใชสมการสถานะแกสของ

แวน เดอร วาลล (Pa

V)(V b) RT2− − =

เมอ R = 8.314 kPa.m3 / kmole K

a = 143.3 kPa.m6 /kmole2

b = 0.0394 m3 /kg

วธทา 1) แทนคาปรมาณตาง ๆ ลงในสมการ จดรปใหมจะไดเปน

(.

)( . ) .70001433

0 0394 8 314 215 02− − − × =V

V

2) ใชโปรแกรม ScanRoot.C โดยเปลยนแปลงฟงกชน TF ดงน

double TF(double V)

/* Write your function which you want to calculate roots here. */

{

return((7000 - 143.3/(V*V))*(V-0.0394) - 8.314*215);

}

ฟงกชน ScanRoot จะตรวจสอบรากสมการ โดยใสคา V ตงแต 0.01 ถง 10 พบวา

รากสมการจะมคาระหวาง [0.01,0.11], [0.31, 0.41] จะเรมตนท V = 0 ไมไดเพราะ 143.3/V2 จะ

ทาใหเกดการหารดวยศนย

3) ใชโปรแกรม Bisect.C หารากสมการ โดยทาการหาสองครง จะได V = 0.0287

และ V = 0.3470 ลกบาศกเมตร โดยใชคาเรมตนทไดจากโปรแกรม ScanRoot.C

4) เมอใชโปรแกรม FalsePos.C พบวาใชจานวนรอบในการทางานถง 2861 รอบเพอ

คานวณหาคารากสมการ คาเรมตนทใชไดมาจากขอ 2) ความคลาดเคลอนของผลลพธไมเกน

ทศนยม 3 ตาแหนง จะเหนวาโปรแกรมใชเวลาทางานมากกวาโปรแกรมอน ๆ

สาเหตทไมเลอกใชโปรแกรม Newton_Raphson.C เพราะตองการหลกเลยงการหา

อนพนธของฟงกชนกทกาหนดมาใหในโจทย

เมอทดลองใช Secant.C คาเรมตนทงสองคาทไดจาก ขอ 2) จะทาใหไดคาตอบเพยง

คาตอบเดยวคอ V = 0.3470 ลกบาศกเมตร เพราะเกดการลเขาหาคาตอบนเพยงคาตอบเดยว

ตองเปลยนคาเรมตนชดแรกเปน 0.02 และ 0.03 จงจะไดคาตอบ V = 0.0287 ลกบาศกเมตร

Page 74: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

67

ตวอยาง 2.12 แรงเสยดทานของของไหลทประกอบดวยอนภาคแขวนลอยหาไดจากสมการ

1

f

1

kln(R f ) (14

5.6

k)= + −

เมอ R คอ ตวเลขเรโนลด

k คอคาคงทขนอยกบความเขมขนของสารแขวนลอย

เมอของไหลมอนภาคแขวนลอยผสมอย 0.08 % พบวา k = 0.28 ตวเลขเรโนลด

เทากบ 3750 จงหาแรงเสยดทาน f ของของไหลน

วธทา 1) แทนคาแลวจดรปสมการใหม ดงน

1

f

1

0.28ln(3750 f ) (14

5.6

0.28) = 0− + −

2) เปลยนแปลงฟงกชนTF ดงน

double TF(double f)

{ /* Your Target Function is here */

return(1/sqrt(f) -(1/0.28*log (3750*sqrt(f))) -(14-5.6/0.28));

}

3) ใชโปรแกรม ScanRoot .C ตรวจสอบคารากสมการตงแต f = 0.001 ถง 10 (หาม

เรมตงแต f = 0 เพราะจะเกด ln 0 ) เพมคาครงละ 0.001 คารากจะอยระหวาง 0.004 และ 0.005

4) ใชโปรแกรม Secant.C หรอ Bisect.C หรอ FalsePos.C หารากสมการจะได

คาตอบ f = 0.00466033 มความคลาดเคลอนนอยกวา 10-7

ตวอยาง 2.13 ความดนบรรยากาศแปรผนตามความสงดงน

P 3.284e-(h 36089)/20806)= − Psi

h มหนวยเปน ฟต วดจากระดบนาทะเล จงหาความสงททาให P = 7.35 Psi

วธทา 1) แทนคา P = 7.35 Psi จดรปสมการใหมจะได

3284 7 35 036089 20806. .( ) / )e h− − − = 2) ใชโปรแกรม ScanRoot.C โดยเปลยนคาฟงกชนใน TF เปนดงน

double TF (double h) { return (3.284*exp(-(h-36089)/20806) - 7.35 ); }

สมหารากสมการตงแต 10,000 จนถง 60,000 ฟต เพมคาครงละ 10 พบคารากอย

ระหวาง [19320, 19330]

3) ใชโปรแกรม Secant.C หาคารากสมการ จะไดรากสมการ h = 19326.8932 ฟต เมอ

ใชโปรแกรม Bisect.C กจะใหผลลพธคาเดยวกน

Page 75: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

68

2.8 บทสรป การหารากสมการแบบไมเปนเชงเสนมหลายวธ ทกลาวไวในบทนไดแก วธแบงครง

ชวง วธวางตาแหนงผดท วธของนวตน-ราฟสน และวธเซแคนต ไมมวธใดดทสดและแกปญหาได

ทกปญหา แตละวธมขอดขอเสยแตกตางกนไป

วธแบงครงชวงและวธวางตาแหนงผดทจะลเขาสคารากสมการเสมอ เมอแทนคา

เรมตนทงสองจดลงไปในฟงกชนแลวไดคาทมเครองหมายตางกน แตขนตอนการหารากสมการ

ของวธนคอนขางชา

วธของนวตน-ราฟสน จะลเขาสคาตอบไดเรวกวาวธอน แตจะตองหาอนพนธของ

สมการทเราตองการหารากนน ถารปสมการมลกษณะซบซอนและยงยาก การหาอนพนธทาได

ลาบากวธนจงไมคอยเหมาะสม วธเซแคนตไมจาเปนตองหาอนพนธของสมการ คอนขางยดหยน

มากกวา แตลเขาหารากสมการไดชากวาวธของนวตน-ราฟสน ขอเสยประการหนงของทงสองวธน

คอถาเลอกจดเรมตนไมเหมาะสมอาจเกดการลเขาสอนนต หรอลเขาสคาตอบอนทไมตองการ

โปรแกรม ScanRoot.C จะชวยใหสามารถประมาณคารากสมการไดในชวงแคบ ๆ

และมคารากสมการอยกคาในชวงทเราตรวจสอบ ทาใหการกาหนดคาเรมตนไดใกลคารากสมการ

ทแทจรงมากยงขน

ระเบยบวธทกวธทเสนอไวในบทนใชหารากสมการของฟงกชนทมคาตอเนองในชวงท

จะหารากสมการ รากสมการทไดจะเปนคาจรงเทานน ไมสามารถนาไปใชหารากสมการทมคา

จนตภาพได

Page 76: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

69

บทท 3 การหาผลเฉลยของระบบสมการเชงเสน

3.1 ระบบสมการเชงเสน การหาผลเฉลยของระบบสมการเชงเสนมกจะพบในเรองวงจรไฟฟา การคานวณทาง

พลศาสตรโดยอาศยกฎนวตน หรอคานวณหาแรงในโครงขายแบบตาง ๆ ถาปญหาทจะตองแกม

ตวแปรและสมการเปนจานวนมาก ปญหาเหลานเหมาะทจะใชคอมพวเตอรชวยในการคานวณ

รปทวไปของระบบสมการเชงเสน หาสมการมตวไมรคา n ตว เขยนไดดงน

............... (3.1)

เขยนใหอยในรปเมทรกซ โดยกาหนดให

A =

a11 a12 . . . a1na21 a22 . . . a2n

a m1 a m2 . . . a mn

M M M M

⎢⎢⎢⎢

⎥⎥⎥⎥

x

x1x2

xn

b

b1b2

bm

=

⎢⎢⎢

⎥⎥⎥

=

⎢⎢⎢

⎥⎥⎥

M M

จะได

Ax = br r (3.2)

A เปนเมทรกซของสมประสทธ rx เปนเวกเตอรของตวแปร

rb เปนเวกเตอรของคาคงท

ถาคาคงททางดานขวามอเปนศนยหมดทกตว (b 0)r= จะเรยกสมการแบบนวาเปน

สมการเอกพนธ (Homogeneous Equation) จะไดผลเฉลยทเหนไดชดคอ ตวแปรทกตว ( rx ) ม

คาเทากบศนย จดเปนผลเฉลยทมความสาคญนอย (trivial solution)

a11x1 a12x2 . . . . a1nxn b1a21x1 a22x2 . . . . a2nxn b2

a m1x1 a m2x2 . . . . a mnxn bm

+ + =

+ + =

+ + =

M

M

M

Page 77: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

70

ถาจานวนสมการไมเทากบจานวนตวแปร m ≠ n ผลเฉลยสาหรบระบบสมการชดน

เปนไปไดหลายกรณคอ อาจจะมคาตอบเพยง 1 ชด (unique solution) หรออาจไมมคาตอบท

สอดคลองกบสมการชดนเลย หรอสมการหนงสมการใดหรอหลาย ๆ สมการอาจมผลเฉลยหลาย

คา (redundant) หรอผลเฉลยของสมการหนงขนอยกบผลเฉลยของอกสมการหนง

ในทนจะกลาวเฉพาะกรณทมจานวนสมการเทากบจานวนตวแปรเทานน และเปนระบบ

สมการไมเอกพนธ (Inhomogeneous equation)

3.2 กฎของคราเมอร (Cramer’s Rule) การหาผลเฉลยของระบบสมการเชงเสน ซงม 3 ตวแปร เขยนสมการไดดงน

เมอใชกฎของคราเมอรจะไดผลเฉลยของตวแปรแตละตวดงน

x1

b1 a12 a13b2 a22 a23b3 a32 a33a11 a12 a13a21 a22 a23a31 a32 a33

, x2

a11 b1 a13a21 b2 a23a31 b3 a33a11 a12 a13a21 a22 a23a31 a32 a33

, x3

a11 a12 b1a21 a22 b2a31 a32 b3a11 a12 a13a21 a22 a23a31 a32 a33

= = =

เขยนเปนสมการทวไปไดดงน

x jiAjA

=

เมอ A เปนเมตรกซของสมประสทธของตวแปร โดยท |A| เทากบศนย Aj เปนเมตรกซขนาด n n× เมอ n เปนจานวนสมการ โดยแทนทแถวตง (column) ท j

ดวยคาคงท sb

a11x1 a12x2 a13x3 b1a21x1 a22 x2 a23x3 b2a31x1 a32 x2 a33x3 b3

+ + =

+ + =

+ + =

Page 78: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

71

A j

a11 a12 b1 a1na12 a22 b2 a2n

a1n a2n bn a3n

=

K KK K

M M M M M MK K

↑ แทนคา แถวตงท j ดวยคาคงท

กฎของคราเมอรเปนวธทงายไมซบซอน แตถาจานวนสมการมากจานวนครงของการคณ

เลขเพอหาขนาดเมตรกซจะมคามากตามไปดวย ระบบสมการเชงเสน n สมการ ตองหา

ตวกาหนด (Determinant) n+1 ครง (หา |Aj| = n ครง และ |A| อก 1 ครง) ตองหารอก n ครง แต

ละตวกาหนดตองคณเลขอก (n-1)(n!) ครง ตองใชการคณและการหารถง (n+1)(n-1) n! + n ครง

ความคลาดเคลอนทเกดจากการปดเศษจงสะสมเปนจานวนมาก เราจงนยมใชกฎของคราเมอร

แกปญหาในกรณทจานวนสมการมไมเกน 4 สมการ ตารางตอไปนแสดงใหเหนถงจานวนครงของ

การคณและหารของระบบสมการเชงเสนเมอมจานวนสมการตาง ๆ กน

n (n+1)(n-1)n!+ n

3 51

4 364

5 2,885

6 25,206

7 241,927

8 2,540,168

9 29,030,409

10 359,251,210

3.3 การลดทอนของเกาสและเกาส-จดอง (Gauss and Gauss-Jordan Elimination) การหาผลเฉลยของระบบสมการเชงเสน โดยใชการลดทอนของเกาสเปนทนยมใชกน

อยางกวางขวาง จะยกตวอยางประกอบพรอมแสดงขนตอนวธ (Algorithm) การลดทอนของเกาส

ไปดวย ดงน

Page 79: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

72

ตวอยาง 3.1 จงหาผลเฉลยของระบบสมการเชงเสนโดยใชการลดทอนของเกาส

2x - 2y + z = 1

4x - 2y + z = 3

x + y - z = 0

วธทา

ขนท 1 นาเมตรกซของสมประสทธและเวกเตอรคาคงทมาเขยนใหอยในรปของเมตรกซ

แตงเตมแลว (augmented matrix) (A|B)

A2 2 14 2 11 1 1

=−−

⎢⎢⎢⎢

⎥⎥⎥⎥

(A B)2 2 14 2 11 1 1

130

r=

−−

⎢⎢⎢⎢

⎥⎥⎥⎥

ขนท 2 เรมลดทอนตวแปรโดยวธของเกาส ในทนจะใชวธลดทอนไปขางหนา

- ใชแถวนอนแถวท 1 เปนหลกนา 2 คณสมาชกทกตวของแกนนอนท 1 แลว

นาไปลบกบแถวท 2 (เขยนเปนสญลกษณไดเปน R2 ← R2 - 2 × R1)

2 2 10 2 11 1 1

+1 + 1 0

−−−

⎥⎥⎥⎥

⎢⎢⎢⎢

- นา 0.5 คณสมาชกทกตวของแถวนอนแถวแรก แลวไปลบแถวนอนท 3

(R3 ← R3 - 0.5 × R1)

2 2 10 2 10 2 1.5

110.5

− −−− −

⎢⎢⎢⎢

⎥⎥⎥⎥

B→=

⎢⎢⎢

⎥⎥⎥

1

3

0

Page 80: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

73

ขนท 3 ใชแถวนอนท 2 เปนหลก

- นาแถวนอนท 3 ตงลบดวยแถวนอนท 2

2 2 10 2 10 0 0.5

111.5

− −−− −

⎢⎢⎢⎢

⎥⎥⎥⎥

ขนท 4 ใชวธแทนคาปอนกลบ จะได

-0.5z = -1.5

z = 3

แทนคา Z ในแถวนอนท 2 จะไดคา y

2y - 1 × 3 = 1

y = 2

แทนคา y, z ลงในแถวนอนท 1 จะได

2x - 2 × 2 - 1 × 3 = 1

x = 1

ผลเฉลยของสมการชดนคอ x =1, y = 2, z = 3

---------------------------------

การลดทอนของเกาส-จดอง มขนตอนเหมอนกบการลดทอนของเกาสทกประการ ตางกน

ตรงทไมใชวธแทนคายอนกลบ แตจะใชการลดทอนยอนกลบแทน (backward elimination)

จากตวอยาง 3.1 ถาใชการลดทอนของเกาส-จดอง มขนตอนเพมดงตอไปน

ตวอยาง 3.2 จากตวอยาง 3.1 จะใชขนตอนวธการลดทอนของเกาส-จดองหาผลเฉลย

วธทา

- เมอลดทอนตวแปรแบบไปขางหนา เชนเดยวกบการลดทอนของเกาสแลว จะได

ผลลพธเหมอนขนท 4 ของตวอยาง 3.1

2 2 10 2 10 0 0.5

11

1.5

−−

⎢⎢⎢⎢

⎥⎥⎥⎥

Page 81: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

74

ขนท 5 ใชการลดทอนตวแปรแบบยอนหลง

- ใชแถวนอนท 3 เปนหลก นา 2 คณสมาชกทกตว ไดผลลพธเปน

2 2 10 2 10 0 1

113

−−

⎢⎢⎢⎢

⎥⎥⎥⎥

- นา (-1) คณสมาชกของแถวนอนท 3 ทกตว นาแถวนอนท 2 ตง ลบดวยแถว

นอนท 3 (R2 ← R2 - (-1)R3)

2 2 10 2 00 0 1

143

−⎡

⎢⎢⎢

⎥⎥⎥

- นาแถวท 1 ตง ลบดวยแถวนอนท 3

2 2 00 2 00 0 1

243

− −⎡

⎢⎢⎢

⎥⎥⎥

ขนท 6 ใชแถวนอนท 2 เปนหลก คณสมาชกทกตวของแถวนอนท 2 ดวย (-1) จากนน

นาไปหกออกจากแถวนอนท 1 (R1 ← R1 + R2)

2 0 00 2 00 0 1

243

⎢⎢⎢

⎥⎥⎥

Page 82: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

75

ขนท 7 นาสมาชกทอยในแนวเสนทแยงมมของแตละแถวหารตลอดแตละแถว เพอทาให

เมตรกซของสมประสทธเปนเมตรกซเอกลกษณ (Identity matrix คอเมตรกซทมสมาชกทมไดอย

บนเสนทแยงมมเปนศนยหมด สมาชกทอยในแนวเสนทแยงมมทกตวมคาเปน 1)

1 0 00 1 00 0 1

123

⎢⎢⎢

⎥⎥⎥

แถวตงสดทายจะเปนผลเฉลยของระบบสมการเชงเสนชดน

3.4 การสลบแถวเพอลดความคลาดเคลอน (Pivoting) การทาใหสมประสทธของตวแปรเปนศนยโดยใชการลดทอนดงทกลาวมา มขอควรระวง

คอ ถาสมาชกของเมตรกซสมประสทธในแนวเสนทแยงมมตวใดตวหนงมคาเปนศนยกจะไม

สามารถใชวธนได หรอถามคาเขาใกลศนยมาก ๆ หรอมคานอยมากเมอเทยบกบสมาชกอน ๆ ท

อยในแถวตงเดยวกน เพราะจะนาคาในแนวเสนทแยงมมนไปเปนตวหาร ผลลพธทไดจากการหาร

ทมตวหารมคานอยมาก ๆ จะทาใหผลลพธมคามาก อาจเกนขดจากดของคอมพวเตอรทจะเกบไว

ได หรออาจทาใหเกดความคลาดเคลอนจากการปดเศษ วธการแกไขคอ สลบแถวนอน (หรอแถว

ตงกได) เมอสลบแลวสมาชกของเมตรกซสมประสทธทมคามากทสดจะอยในแนวเสนทแยงมม

ตวอยาง 3.3 จะแสดงใหเหนขอแตกตางเมอมการสลบแถว และหรอไมมการสลบแถว คาความ

แมนตรงทไดจะตางกน

3x + 11y = 25

7x + 87y = 181

วธทา ก. เมอไมมการสลบแถว เมตรกซแตงเตมแลวจะไดดงน

3 117 87

25181

⎣⎢⎤

⎦⎥

นา 2.33333 คณแถวนอนท 1 แลวนาไปหกออกจากแถวนอนท 2

Page 83: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

76

3 110 61.33337

25122.66675

⎣⎢⎤

⎦⎥

จะได y = 2.0000016 x = 0. 999994

ข. เมอมการสลบแถว

พจารณาแถวตงท 1 จะเหนวา 7 มคามากกวา 3 จงสลบแถวเพอให 7 มาอยในแนว

เสนทแยงมม

7 873 11

18125

⎣⎢⎤

⎦⎥

- นา 0.42857 คณแถวท 1 ตลอด แลวหกออกจากแถวท 2

7 870 26.28559

18152.57118− −

⎣⎢⎤

⎦⎥

y = 2, x = 1

จะเหนวาในกรณ (ก.) คา y = 2.0000016 นาไปแทนคาเพอหา x ความคลาดเคลอนจะ

ถกขยายใหมากขน (เมอคณดวย 11) จะไดคา x = 0.999994 ดงนน จงควรมการตรวจสอบวา

สมาชกในแนวเสนทแยงมมมคาเปนศนยหรอมคานอยกวาสมาชกตวอน ๆ ในแถวตงเดยวกน

หรอไม ถาใชควรสลบแถวทมสมาชกทมคามากเสยกอน

ขนตอนวธการลดทอนแบบเกาส โดยรวมการสลบแถวเพอลดความคลาดเคลอนเขาไป

ดวย จะเปนการเพมความแมนตรงมากขนดงตวอยาง 3.4

ตวอยาง 3.4 จงแกสมการ

x1 + x2 + x3 + x4 = 4

2x1 + 2x2 + 3x3 + 4x4 = 11

3x1 + 3x2 + 3x3 + 4x4 = 13

x1 + 2x2 + 3x3 + 4x4 = 10

(คาตอบของ x1, x2, x3 และ x4 คอ 1)

Page 84: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

77

วธทา เมตรกซทตกแตงแลวจะเปนดงน

1 1 1 12 2 3 43 3 3 41 2 3 4

4111310

⎢⎢⎢

⎥⎥⎥

ตวหลกทใชเปนตวหารแถวอน ๆ คอ a11 เมอเปรยบเทยบกบสมาชกอน ๆ ในแถวตงท 1

จะเหนวา a31 มคามากทสด (a31 = 3) สลบแถวท 3 กบแถวท 1 จะได

3 3 3 42 2 3 41 1 1 11 2 3 4

13114

10

⎢⎢⎢

⎥⎥⎥

- นา 2/3 คณแถวนอนท 1 แลวนาไปหกออกจากแถวนอนท 2

- นา 1/3 คณแถวนอนท 1 แลวนาไปหกออกจากแถวนอนท 3

- นา 1/3 คณแถวนอนท 1 แลวนาไปหกออกจากแถวนอนท 4

3 3 3 40 0 1 4 30 0 0 1 30 1 2 8 3

137 31 3

17 3− −

⎢⎢⎢

⎥⎥⎥

เมอใชแถวนอนท 2 เปนหลก a22 มคาเปนศนย ตองสลบกบแถวนอนท 4

3 3 3 40 1 2 8 30 0 0 1 30 0 1 4 3

1317 3

1 37 3

− −

⎢⎢⎢

⎥⎥⎥

a33 มคาเปนศนย จงตองสลบแถวนอนท 3 กบ 4

Page 85: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

78

3 3 3 40 1 2 8 30 0 1 4 30 0 0 1 3

1317 3

1 37 3−−

⎢⎢⎢

⎥⎥⎥

สมาชกทอยใตเสนทแยงมมมคาเปนศนยหมดทกตวแลว จงใชวธแทนคายอนกลบ

x 1

x 73

43 1

x 173

83 1

x 13 4 3 33 1

4

3

2

1

=

= − =

= − =

=− − −

=

บางครงอาจตองมการสลบแถวตง ซงลาดบตวแปรจะตองเปลยนไปดวย การสลบทงแถว

นอนและแถวตงเพอหาผลเฉลย เรยกการสลบแบบนวาเปน Total Pivoting ถาสลบเฉพาะแถวตง

หรอแถวนอนอยางใดอยางหนงเรยกวาเปน Partial Pivoting

การใชงานโปรแกรม Gauss Elimination C และ Gauss JD.C ก. คาทตองนยาม #define ARRAY_SIZE 51 เปนตวกาหนดจานวนสมการ โปรแกรมนใชกบระบบสมการเชงเสน

ไมเกน 50 สมการ อาจเปลยนคาใหมากนอยกวานไดตามใจชอบ

#define ZERO_APPROACH 2.02E-16 ข. การเรยกใชฟงกชน int GaussElimination (int dimension, double aug [ ][ARRAY_SIZE]

int GaussJordan (int dimension, double aug [ ][ARRAY_SIZE]

เมอ dimension = จานวนของสมการ

aug = เมตรกซแตงเตมแลว ขนาด dimension x dimension + 1

ค. ฟงกชนอนทเกยวของ - ง. ผลลพธ : ผลเฉลยของสมการเชงเสนทคานวณจะเกบไวแถวตงท 2

dimension + 1

จ. การสงคากลบ : สงคาเปนจานวนเตมตอไปน

Page 86: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

79

0 ไมมขอผดพลาดใด

1 จานวนสมการเชงเสนนอยกวา 1

2 ไมสามารถหาผลเฉลยได เนองจากตวกาหนดของเมตรกซ-

สมประสทธมคาเปนศนย

ฉ. ขอสงเกต ในสวนทแสดงผลการคานวณแตละขนตอนวธนน สามารถตดทงได

ผเขยนใสไวสาหรบนกศกษาทตองการดผลลพธแตละขนตอน และสาหรบการ debug โปรแกรม

เทานน

รายละเอยดของโปรแกรม 3.1

/* Program 3.1 - GuassEli.C (GaussElimination.C)

* Purpose: Demonstate how to find the solution of a set of linear

* equation by Gauss Elimination method with partial pivot.

* Author : Wachara Rodsumrid.

* Office : Dept of Science. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Last update : 9 Apr 94

**************************************************************/

#include <stdio.h>

#include <math.h>

#define ARRAY_SIZE 51

#define ZERO_APPROACH 2.20E-16 /* for double precision */

/* Global Variable */

int GetData(double augment[][ARRAY_SIZE]);

int GaussElimination(int , double aug[][ARRAY_SIZE]);

void DisplaySolution(int,int, double aug[][ARRAY_SIZE]);

void ShowAugMatrix(int, double aug[][ARRAY_SIZE]);

void main()

{

double agm[ARRAY_SIZE][ARRAY_SIZE]; /* Augmented matrix */

int size=0,error;

int i,j;

clrscr();

size = GetData(agm);

ShowAugMatrix(size,agm);

error = GaussElimination(size,agm);

Page 87: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

80

DisplaySolution(error,size,agm);

}

int GetData(double a[][ARRAY_SIZE])

{

int i,j,dim;

char buffer[225];

printf("\tSolving a linear set of Equation with Gauss Elimination Method\n");

printf("\t=================================================\n");

do {

printf("Input Number of equation. (1 - %d ) ",ARRAY_SIZE-1);

gets(buffer);

dim=atoi(buffer);

} while ( dim < 1 || dim > ARRAY_SIZE-1);

for (i =1 ; i <= dim; i++) {

printf("\n<<Equation # %d>>\n",i);

for (j = 1; j <= dim; j++) {

printf("\tInput Coefficent (%d,%d) = ",i,j);gets(buffer);

a[i][j] = atof(buffer);

}

printf("\n\tInput Constant # %d = ",i );

a[i][dim+1] = atof(gets(buffer));

}

return(dim);

}

void DisplaySolution(int err,int dim, double aug[][ARRAY_SIZE])

{

int i,j;

switch (err) {

case 0 : {

for (i=1; i<= dim; i++) {

printf( "\tX%d = %13.5f\n",i,aug[i][dim+1]);

}

break;

}

case 1 : {

printf("\nThe dimension must be greater than 1\n");

Page 88: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

81

printf(" and less than 50\n");

break;

}

case 2 : {

printf ("Matrix is singular. Cann't find any solution\n");

break;

}

} /* switch (err) */

}

void ShowAugMatrix(int dim, double aug[][ARRAY_SIZE])

{

int ir,jc;

printf("\nThis is your Augmented Matrix..\n");

for (ir =1 ; ir <= dim; ir++) {

for(jc=1; jc <= dim; jc++) {

printf (" %10.5f ",aug[ir][jc]);

}

printf("| %10.5f\n",aug[ir][dim+1]);

}

}

/*========================================================*/

int GaussElimination(int dim, double aug[][ARRAY_SIZE])

/* Function Description : finding a set of linear eqn using

Gauss Elimination with partial pivoting

User's define: ARRAY_AIZE = 51

ZERO_APPROACH = 2.20E-16 (for double precision)

Input: aug -- Augmented Matrix.

dim -- Dimension of Coefficeint Matrix

Output: The solutions of eqn. keep in augmented Matrix column dim+1

Return :

0 -- No error detected.

1 -- Dimension < 1

2 -- Coefficient Matrix is singular.

*/

Page 89: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

82

{

int i,j,row,col,pivot;

int ir,jc;

double temp=0,multiplier=0,det=1.0;

if (dim < 1 || dim > ARRAY_SIZE-1) return 1;

if ( dim == 1) {

if (aug[1][1] != 0 ) {

aug[1][2] = aug[1][2]/aug[1][1];

return 0;

} else { return 2;} /* Can't find solution */

}

for (i=1; i <= (dim-1); i++) {

pivot = i;

/* Check the maximum element in the same column */

for (j = i+1; j <= dim; j++)

if (fabs(aug[pivot][i]) < fabs(aug[j][i])) pivot=j;

/* Pivoting */

if (pivot != i) {

for (j =1;j <= (dim+1); j++) {

temp = aug[i][j];

aug[i][j] = aug[pivot][j];

aug[pivot][j] = temp;

}

det = -det;

}

if (aug[i][i] == 0) return 2; /* singular matrix */

/* make an upper triangular matrix */

for ( row = i+1;row <= dim; row++) {

if(aug[row][i] != 0 ) {

multiplier= aug[row][i]/aug[i][i];

/* if you mind in SPEED, this line is better than next.

for ( col= i+1;col <= (dim+1); col++) {

*/

for(col = 1;col<=(dim+1);col++) {

aug[row][col] = aug[row][col]-multiplier*aug[i][col];

if (fabs(aug[row][col]) <= 2*ZERO_APPROACH)

Page 90: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

83

aug[row][col] = 0;

}

} /* if */

} /* for ( row....) */

/*** In case of learning, you can see the results step by step *****/

printf("\nStep # %d\n",i);

printf("============\n");

ShowAugMatrix(dim,aug);

puts("Press any key .....");getch();

/*******************/

} /* for ( i....) */

for (i = 1; i <= dim; i++ )

det = det *aug[i][i];

printf("\nYour det = %f\n",det);

if (det !=0 ) {

/* Backward Substitution */

aug[dim][dim+1] = aug[dim][dim+1]/aug[dim][dim];

for ( row = dim-1; row >=1; row--){

temp = aug[row][dim+1];

for ( col= row+1; col <= dim; col++) {

temp = temp - aug[row][col]*aug[col][dim+1];

}

aug[row][dim+1] = temp/aug[row][row];

}

return 0;

}else{ return 2; /* singular matrix */ }

}

/*========================================================*/

รายละเอยดโปรแกรม 3.2 /* Program 3.2 - GuassJD.C (Gauss_Jordan.C)

* Purpose: How to find the solution of a set of linear equation by

* Gauss-Jordan Reduction method with partial pivot.

* Author : Wachara R.

* Last update : 7 Apr 94

Page 91: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

84

**************************************************************/

#include <stdio.h>

#include <math.h>

#define ARRAY_SIZE 51

#define ZERO_APPROACH 2.20E-16

int GetData(double augment[][ARRAY_SIZE]);

int GaussJordan(int , double aug[][ARRAY_SIZE]);

void DisplaySolution(int,int, double aug[][ARRAY_SIZE]);

void ShowAugMatrix(int, double aug[][ARRAY_SIZE]);

void main()

{

double agm[ARRAY_SIZE][ARRAY_SIZE]; /* Augmented matrix */

int size=0,error;

int i,j;

clrscr();

size = GetData(agm);

ShowAugMatrix(size,agm);

error = GaussJordan(size,agm);

DisplaySolution(error,size,agm);

}

int GetData( double a[][ARRAY_SIZE])

{

int i,j,dim;

char buffer[225];

printf("\tSolving a linear set of Equation with Gauss-Jordan Reduction.\n");

printf("\t=============================================================\n");

do {

printf("Input Number of equation. (1 - %d ) ",ARRAY_SIZE-1);

gets(buffer);

dim=atoi(buffer);

} while ( dim < 1 || dim > ARRAY_SIZE-1);

Page 92: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

85

for (i =1 ; i <= dim; i++) {

printf("\n<<Equation # %d>>\n",i);

for (j = 1; j <= dim; j++) {

printf("\tCoefficent (%d,%d) = ",i,j);gets(buffer);

a[i][j] = atof(buffer);

}

printf("\n\t Constant # %d = ",i );

a[i][dim+1] = atof(gets(buffer));

}

return(dim);

}

void DisplaySolution(int err,int dim, double aug[][ARRAY_SIZE])

{

int i,j;

switch (err) {

case 0 : {

for (i=1; i<= dim; i++) {

printf( "\tX%d = %13.5f\n",i,aug[i][dim+1]);

}

break;

}

case 1 : {

printf("\nThe dimension must be greater than 1\n");

printf(" and less than 50\n");

break;

}

case 2 : {

printf ("Matrix is singular. Cann't find any solution\n");

break;

}

} /* switch (err) */

}

void ShowAugMatrix(int dim, double aug[][ARRAY_SIZE])

{

int ir,jc;

Page 93: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

86

printf("\nThis is your Augmented Matrix..\n");

for (ir =1 ; ir <= dim; ir++) {

for(jc=1; jc <= dim; jc++) {

printf (" %10.5f ",aug[ir][jc]);

}

printf("| %10.5f\n",aug[ir][dim+1]);

}

}

/*========================================================*/

int GaussJordan(int dim, double aug[][ARRAY_SIZE])

/* Function Description: Find the solution of a set of a linear equation using Gauss-

Jordan reduction.

User's define: ARRAY_SIZE = 51

ZERO_APPROACH = 2.2E-16 (for double precision)

Input : aug -- Augmented matrix

dim -- dimension of augmented matrix.

Output: if error = 0 , the solution will be stored in column dim+1

Return: 0 -- if no error.

1 -- dimension < 1

2 -- coefficient matrix is singular.

*/

{

int i,j,row,col,pivot;

int ir,jc;

double temp=0,multiplier=0,det=1.0;

if (dim < 1 || dim > ARRAY_SIZE-1) return 1;

if ( dim == 1) {

if (aug[1][1] != 0 ) {

aug[1][2] = aug[1][2]/aug[1][1];

return 0;

} else { return 2;} /* Cann't find solution */

}

for (i=1; i <= (dim-1); i++) {

pivot = i;

Page 94: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

87

/* Check the maximum element in the same column */

for (j = i+1; j <= dim; j++)

if (fabs(aug[pivot][i]) < fabs(aug[j][i])) pivot=j;

/* Pivoting */

if (pivot != i) {

for (j =1;j <= (dim+1); j++) {

temp = aug[i][j];

aug[i][j] = aug[pivot][j];

aug[pivot][j] = temp;

}

det = -det;

}

if (aug[i][i] == 0) return 2; /* singular matrix */

/* make an upper triangular matrix */

for ( row = i+1;row <= dim; row++) {

if(aug[row][i] != 0 ) {

multiplier= aug[row][i]/aug[i][i];

/* if you mind in SPEED, this line is better than next.

for ( col= i+1;col <= (dim+1); col++) {

*/

for(col = 1;col<=(dim+1);col++) {

aug[row][col] = aug[row][col]-multiplier*aug[i][col];

if (fabs(aug[row][col]) <= 2*ZERO_APPROACH)

aug[row][col] = 0;

}

} /* if */

} /* for ( row....) */

/*** In case of learning, you can see the results step by step ****

printf("\nStep # %d\n",i);

printf("============\n");

ShowAugMatrix(dim,aug);

puts("Press any key .....");getch();

*****************************************************************/

} /* for ( i....) */

/* Find Determinant */

for (i = 1; i <= dim; i++ )

Page 95: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

88

det = det *aug[i][i];

printf("\nYour det = %f\n",det);

if (det !=0 ) {

/* Make a Matrix lower triangular */

for (i=dim; i >= 1; i--) {

for ( row = i-1;row >= 1; row--) {

if(aug[row][i] != 0 ) {

multiplier= aug[row][i]/aug[i][i];

for(col = i;col<=(dim+1);col++) {

aug[row][col] = aug[row][col]-multiplier*aug[i][col];

if (fabs(aug[row][col]) <= ZERO_APPROACH)

aug[row][col] = 0;

}

} /* if */

} /* for ( row....) */

/*** In case of learning, you can see the results step by step *****

printf ("\n make a matrix lower Triangular, Step # %d\n",(dim-i+1));

ShowAugMatrix(dim,aug);

puts("Press any key .....");getch();

*******************/

} /* for ( i....) */

/* Create Identity Matrix */

for ( i= dim ; i >=1; i--) {

temp = aug[i][i];

for (j = i; j <= dim+1; j++) {

aug[i][j] = aug[i][j]/temp;

}

}

/* printf("\nAfter make a matrix identity\n");

ShowAugMatrix(dim,aug);

*/

return 0;

}else{ return 2; /* singular matrix */ }

}

/*======================================================*/

Page 96: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

89

ตวอยาง 3.5 โครงขายอยในสภาพสมดล จงหาแรงทเกดขนในโครงขาย จด c เปนลอเลอน

ไมคดแรงเสยดทานทพน

รป 3.1 แสดงแรงทกระทาบนโครงขาย

วธทา ให F, F2 , F3 , F4 , F5 เปนแรงทเกดขนในโครงขาย QA , RA และ R3 เปนแรงปฏกรยา

ภายนอก

เขยน Free body diagram ท node ตางของโครงขายไดดงรป

รป 3.2 แสดง Free body diagram ทจดตาง ๆ

ท node A Σ Fx = 0 : RA + F1 sin 30 = 0

Σ Fy = 0 : QA + F4 = 0

ท node B Σ Fx = 0 : F5 = 0

Σ Fy = 0 : F3 - F4 = 0

ท node C Σ Fx = 0 : RC + F2 sin 60 = 0

Σ Fy = 0 : F3 + F2 cos 60 = 0

ท node D Σ Fx = 0 : -F5 + F1 cos 60 - F2cos 30 = 1000

Σ Fy = 0 : -F1 sin 60 + F2 sin 30 = 0

มสมการทงหมด 8 สมการ ( 8 ตวแปร) เขยนระบบสมการเชงเสนใหอยในรปเมตรกซจะได

Page 97: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

90

1 0 0 0.5 0 0 0 00 1 0 0 0 0 1 00 0 0 0 0 0 0 10 0 0 0 0 1 1 00 0 1 0 0.866 0 0 00 0 0 0 0.5 1 0 00 0 0 0.5 0.866 0 0 10 0 0 0.866 0.5 0 0 0

RQRFFFFF

00000010000

A

A

C

1

2

3

4

5

− − −−

⎢⎢⎢⎢⎢⎢⎢

⎥⎥⎥⎥⎥⎥⎥

⎢⎢⎢⎢⎢⎢⎢

⎥⎥⎥⎥⎥⎥⎥

=

⎢⎢⎢⎢⎢⎢⎢

⎥⎥⎥⎥⎥⎥⎥

ใชโปรแกรม GaussEli.C หาผลเฉลยระบบสมการเชงเสนดงภาพ

รป 3.3 แสดงผลลพธทไดจากโปรแกรม GaussEli.C

Solving a linear set of Equation with Gauss Elimination Method

================================================

Your det = -0.999956

X1 (RA) = 250.01100

X2 (QA) = -433.01905

X3 (Rc) = 749.98900

X4 (F1) = -500.02200

X5 (F2) = -866.03811

X6 (F3) = 433.01905

X7 (F4) = 433.01905

X8 (F5) = 0.00000

QA , F1 , F2 เปนลบ แสดงวาทศทางของแรงตองกลบทศเสยใหม

นกศกษาอาจทดลองคดตอไปวา ถาถอดโครง BD ออกจากระบบ แรงทเกดขนนนจะ

เปลยนไปหรอไมอยางไร

Page 98: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

91

3.5. ลกษณะของผลเฉลยของระบบสมการเชงเสน ในการหาผลเฉลยของระบบสมการเชงเสนทไมเปนเอกพนธ (non-homogenous

equation หมายถง ระบบสมการเชงเสนทคาคงทดานขวามอไมเปนศนยทกตว) อาจไดผลเฉลยซง

ไมใชเปนคาตอบเพยงชดเดยว หรอไมสามารถหาไดเลย ซงจะยกตวอยางระบบสมการเชงเสนท

เกดปญหาในการหาผลเฉลยดงตอไปน

1. เมอมบางสมการในระบบสมการนนมลกษณะองอยกบอกสมการหนงในระบบเดยวกน

ซงเรยกวา Linearly dependent สมการหนงอาจเกดจากการนาคาคงทคณอกสมการหนง หรอ

เกดจากการบวกลบกบอกสมการหนง จานวนผลเฉลยทไดจะมมากมายไมสนสด ดงตวอยาง

x + y = 3

4x + 4y = 12

รป 3.4 แสดงกราฟเสนตรงทเกดจากสมการทงสอง

สมการท 2 เกดจากการนา 4 คณกบสมการท 1 อนทจรงแลวสมการทงสองคอสมการ

เดยวกนนนเอง ผลเฉลยทไดมมากมายไมสนสด เชน x = 0, y = 3; x = 1, y = 2 หรอ x = 1.5, y

= 1.5, ฯลฯ

2. เมอสมการของระบบเปนเสนขนานไมมจดตดกน ผลเฉลยของระบบสมการนจะไมม

เรยกลกษณะนวาเปนระบบขดแยง (inconsistent system) สามารถทาใหสมาชกของเมตรกซ

สมประสทธอยางนอย 1 แถว เปนศนยทงหมด โดยการบวกลบกบแถวอน ๆ โดยทตวทางขวามอ

ไมเปนศนย ตวอยางเชน

2x + 6Y = 9

x + 3y = 1

รป 3.5 กราฟเสนตรง 2 เสนทมความชนเทากน

Page 99: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

92

เมตรกซแตงเตมแลวจะไดเปน

1 32 6

19

⎡⎣⎢

⎤⎦⎥

นา 2 คณสมาชกทกตวในแถวนอนท 1 แลวไปหกออกจากแถวนอนท 2

1 30 0

17

⎡⎣⎢

⎤⎦⎥

ขนาดเมตรกซสมประสทธมคาเปนศนย จงไมมผลเฉลยสาหรบระบบสมการชดน

3. ถาจานวนสมการมากกวาจานวนตวแปร สมการแตละสมการเปนอสระแกกน จะไม

สามารถหาคาตอบทสอดคลองกบสมการทกสมการในระบบสมการชดนไดเลย ตวอยางเชน

3x - y = 0

3x - 2y = -6

4x + y = -8

-

รป 3.6 กราฟเสนตรงแทนสมการทงสามสมการ

Page 100: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

93

ตวอยาง 3.6 ระบบสมการชดนสามารถหาคาตอบไดหรอไม

4x + 4y + 8z = 8

2x + 2y + 4z = -6

x + y + 2z = 2

วธทา

4 4 82 2 41 1 2

862

−⎡

⎣⎢⎢

⎦⎥⎥

row 2 - ½ x row 1

4 4 80 0 01 1 2

810

6−

⎣⎢⎢

⎦⎥⎥

row 3 - ¼ x row 1

4 4 80 0 00 0 0

810

0−

⎣⎢⎢

⎦⎥⎥

แถวนอนท 2 จะบอกใหรวาระบบสมการนมลกษณะขดแยง (inconsistent) ดงนน จงไม

สามารถหาผลเฉลยไดทง ๆ ทสมการ 1 และ 2 เปน linearly dependent ควรทจะไดผลเฉลย

จานวนไมสนสด

ตวอยาง 3.7 หาคาตอบของระบบสมการเชงเสนตอไปน

r + 2s + 3t - 3u = 3

2r + 3s + t - 6u = -6

-3r + s + t + 9u = 8

5r + 2s + 7t - 15u = -1

วธทา จะได augment matrix

Page 101: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

94

1 2 3 32 3 1 63 1 1 95 2 7 15

3681

−− −

−−

⎢⎢⎢

⎥⎥⎥

ผลเฉลยของระบบสมการชดนคอ ทกตวแปรมคา = 1 เมอใชโปรแกรม GaussEli.C หรอ

GaussJD.C คานวณผลลพธทไดดงรปขางลางน เพราะแถวตงท 4 มคาเปน 3 เทาของแถวตงท 1

ดงนน คาตวกาหนดของเมตรกซสมประสทธจงมคาเปนศนย ไมสามารถหาผลเฉลยของสมการชด

นได

รป 3.7 ผลลพธทไดจากโปรแกรม GaussEli.C

Solving a linear set of Equation with Gauss Elimination Method

=================================================

This is your Augmented Matrix..

1.00000 2.00000 3.00000 -3.00000 | 3.00000

2.00000 -3.00000 1.00000 -6.00000 | -6.00000

-3.00000 1.00000 1.00000 9.00000 | 8.00000

5.00000 2.00000 7.00000 -15.00000 | -1.00000

Your det = 0.000000

Matrix is singular. Can’t � find any solution

3.6 วธแยกเปนเมตรกซสามเหลยมลางและบน (LU Decomposition) เมตรกซของสมประสทธ (A) จะถกแยกออกเปนสามเหลยมลาง (L, Lower triangular

matrix) และเมตรกซสามเหลยมบน (U- Upper triangular matrix) โดยท

A = LU ............... (3.4)

เรานยมใชวธนกบระบบสมการเชงเสนหลาย ๆ ชด แตละชดมสมประสทธของสมการ

เหมอนกน แตคาคงทดานขวามอมคาตางกน วธนมประสทธภาพมากกวาวธการลดทอนของเกาส

การแยกเมตรกซ A ใหอยในรป L และ U สามารถทาไดเสมอ ถาเมตรกซนนไมเปน

เมตรกซเอกฐาน (singular matrix - ขนาดของตวกาหนด (determinant) ไมเปนศนย) สามารถทา

ใหเขาใจไดงาย โดยจะยกตวอยางเมตรกซ A ซงมขนาด 3 x3

Page 102: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

95

a a aa a aa a a

1 0 0l 1 0l l 1

u u u0 u u0 0 u

11 12 13

21 22 23

31 32 33

21

31 32

11 12 13

22 23

33

⎢⎢⎢

⎥⎥⎥=

⎢⎢⎢

⎥⎥⎥=

⎢⎢⎢

⎥⎥⎥

เมตรกซ L จะมสมาชกในแนวเสนทแยงมม มคาเปน 1 ทงหมด จะหาคา lij และ uij โดย

การคณเมตรกซ L และ U เขาดวยกน

a a aa a aa a a

u u ul u l u u l u ul u l u l u l u l u u

11 12 13

21 22 23

31 32 33

11 12 13

21 11 21 12 22 21 13 23

31 11 31 12 32 22 31 13 32 23 33

⎢⎢⎢

⎥⎥⎥= + +

+ + +

⎢⎢⎢

⎥⎥⎥

เปรยบเทยบกนระหวางเทอมตอเทอมทสมนยกน

u11 = a11 , u12 = a12 , u13 = a13

หรอ uij = aij เมอ j = 1 ถง 3

a21 = l21u11 และ a31 = l31u11

นนคอ l21 =a 21u11

และ l31 = a 31u11

a22 = l21u12 + u22 , a23 = l21u13 + u23

จะได u22 = a22 - l21u12 , u23 = a23 - l21u13

a32 = l31u12 + l32u22

หรอ l32 = (a 32 l 31u12 )

u22

a33 = l31u13 + l32u23 + u33

หรอ u33 = a33 - l31u13 - l32u23

Page 103: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

96

ตวอยาง 3.8 จงแยกเมตรกซตอไปนใหอยในรปผลคณของ LU

A2 2 14 2 11 1 1

=−−

⎢⎢

⎥⎥

วธทา u11 = 2 u12 = -2 u13 = 1

l 21a 21u11

42

2, l 31a 21u11

12

0.5= = = = = =

u22 = a22 - l21u12 = -2 - 2(-2) = 2

u23 = a23 - l21u13 = 1 - 2*1 = -1

l32 = (a32 - l31u12) / u12 = (1 - 0.5(-2) )/ 2 = 1

u33 = a33 - l31u13 - l32u23 = -1 - (0.5)(1) - 1(-1) = -0.5

จะได

l1 0 02 1 0

0.5 1 1u

2 2 10 2 10 0 0.5

=

⎢⎢

⎥⎥ =

−−−

⎢⎢

⎥⎥

เมอขยายผลไปจนถงลาดบท N

1. แถวนอนแถวแรกของ U คอ u1, j เมอ j = 1 ถง N หาไดจาก

u1j = a1j j = 1 ถง N

2. แถวตงแถวแรกของ L คอ li, 1 เมอ i = 2 ถง N หาไดจาก

li, 1 = au

i1

11

เมอ i = 2 ถง N

3. แถวนอนท 2 ของ U หาไดจาก

u2j = a2j - l21u1j เมอ j = 2 ถง N

4. แถวตงท 2 ของ l คอ li, 2 หาไดจาก

li, 2 = (a l u )

ui2 i1 12

22

− i = 3 ถง N

Page 104: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

97

5. แถวนอนท n ของ U หาไดจาก

unj = a nj l nk u kjk 1n 1

− =−∑ j = n ถง N

6. แถวตงท n ของ L หาไดจาก

l in(a in l ik u kn )k 1

n 1

unn=

− =−∑

เมอ i = n + 1 ถง N

เมอแยกเมตรกซ A ออกเปนเมตรกซ L และ U แลว ขนตอนวธหาผลเฉลยตอไปทาได

ดงน

จากสมการ 3.2 Ax br r=

แทนคา A LU= จะได

LUx br r=

กาหนดให Ux Wr r= สมการจะกลายเปน

Lw br r=

เนองจากสมาชกในแนวเสนทแยงมมของ L มคาเปน 1 ทกตว จงใชวธแทนคาไป

ขางหนา หาคา rw ได

ในกรณทเมตรกซของสมประสทธมขนาด 3 x 3 ขนตอนวธหาผลเฉลยจะเปนดงตอไปน

1 0 0l21 1 0l31 l32 1

w1w2w3

b1b2b3

⎣⎢⎢

⎦⎥⎥

⎣⎢⎢

⎦⎥⎥=⎡

⎣⎢⎢

⎦⎥⎥

ใชวธแทนคาไปขางหนา

w1 = b1

w2 = b2 - w1l21

w3 = b3 - w1l31 - w2l32

แทนคา rw เหลาน เพอหาคา

rx จะได

Page 105: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

98

u11 u12 u130 u22 u230 0 u33

x1x2x3

w1w2w3

⎣⎢⎢

⎦⎥⎥

⎣⎢⎢

⎦⎥⎥=⎡

⎣⎢⎢

⎦⎥⎥

เมอแทนคายอนกลบจะไดคา rx ตามทตองการ เมตรกซ U ทไดตอนนจะเหมอนกบ

เมตรกซสมประสทธทไดจากการลดทอนแบบเกาส

การใชงานโปรแกรม LU_Decompose สามารถนาฟงกชน LU_Decompose ไปใชงานตามเงอนไขดงตอไปน

ก. คาคงททตองกาหนด #define ARRAY_SIZE 51

#define ZERO_APPROACH 2.20 E-16

ข. การเรยกใชฟงกชน int LU_Decompose (int dimension)

double LU [ ][ARRAY_SIZE)

double a [ ][ARRAY_SIZE)

double b [ ][ARRAY_SIZE)

dimension คอ จานวนสมการ

LU คอ เมตรกซสามเหลยมลางและบน เพอประหยดหนวยความจา

จงเกบคาไวในตวแปร ARRAY LU เพยงตวแปรเดยว ดงน

u11 u12 u13 u1nl21 u22 u23 u2nl31 l32 u33 u3n

l n1 l n2 l n3 unj

LLL

M M M M ML

⎢⎢⎢⎢

⎥⎥⎥⎥

a คอ เมตรกซสมประสทธ

b คอ เวกเตอรคาคงท

ค. ฟงกชนอนทเกยวของ Void Pivot (int demension, double LU [ ][ARRAY_SIZE)

double a [ ][ARRAY_SIZE)

double b [ ][ARRAY_SIZE)

Page 106: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

99

ง. ผลลพธ ถาไมมขอผดพลาดใด ๆ ผลเฉลยทไดจะถกเกบไวในเวกเตอร b

จ. การสงคากลบ 0 ถาไมมขอผดพลาด

1 ถาจานวนสมการนอยกวา 1 หรอมากกวา 50

2 ตวกาหนดของเมตรกซสมประสทธมคาเปนศนย

รายละเอยดของโปรแกรม 3.3 LU_METHOD.C มดงน

รายละเอยดโปรแกรม 3.3 /* Program 3.3 - LU-Decomposition.C

* Purpose: An example for finding the solution of a set of linear

* equation using LU Decomposition.

* Author : Wachara R.

* Last update : 10 Apr 94

**************************************************************/

#include <stdio.h>

#include <math.h>

#define ARRAY_SIZE 51

#define ZERO_APPROACH 2.20E-16

int GetData(double a[][ARRAY_SIZE],double b[ARRAY_SIZE]);

int LU_Decompose(int ,double lu[][ARRAY_SIZE],

double a[][ARRAY_SIZE],double b[ARRAY_SIZE]);

void Pivot(int,int, double lu[][ARRAY_SIZE],

double a[][ARRAY_SIZE],double b[ARRAY_SIZE]);

void ShowUMatrix(int,int,double lu[][ARRAY_SIZE]);

void ShowLMatrix(int,int,double lu[][ARRAY_SIZE]);

void DisplaySolution(int,int, double b[ARRAY_SIZE]);

void ShowCoeffMatrix(int , double a[][ARRAY_SIZE]);

void ShowConstant(int, double b[ARRAY_SIZE]);

void main()

{

double a[ARRAY_SIZE][ARRAY_SIZE]; /* coefficeint matrix */

double b[ARRAY_SIZE]; /* Constant Matrix */

Page 107: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

100

double LU[ARRAY_SIZE][ARRAY_SIZE]; /* LU Matrix in compact form */

int size=0,error;

int i,j;

clrscr();

printf("\tSolving a linear set of Equation with LU-Decomposition.\n");

printf("\t=======================================================\n");

size = GetData(a,b);

ShowCoeffMatrix(size,a);

ShowConstant(size,b);

error= LU_Decompose(size,LU,a,b);

ShowUMatrix(error,size,LU);

getch();

ShowLMatrix(error,size,LU);

getch();

DisplaySolution(error,size,b);

getch();

}

int GetData(double a[][ARRAY_SIZE], double c[ARRAY_SIZE])

{

int i,j,dimen;

char buffer[225];

do {

printf("\nInput Number of equation. (1 - %d ) ",ARRAY_SIZE-1);

gets(buffer);

dimen=atoi(buffer);

} while ( dimen < 1 || dimen > ARRAY_SIZE-1);

for (i =1 ; i <= dimen; i++) {

printf("\n<<Equation # %d>>\n",i);

for (j = 1; j <= dimen; j++) {

printf("\tCoefficent (%d,%d) = ",i,j);gets(buffer);

a[i][j] = atof(buffer);

}

printf("\t Constant #%d = ",i); gets(buffer);

c[i] = atof(buffer);

Page 108: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

101

}

return(dimen);

}

void DisplaySolution(int err,int dim, double c[ARRAY_SIZE])

{

int i;

switch (err) {

case 0 : {

printf("\n");

for (i=1; i<= dim; i++) {

printf( "\tX%d = %13.5f\n",i,c[i]);

}

break;

}

case 1 : {

printf("\nThe dimension must be greater than 1\n");

printf(" and less than 50\n");

break;

}

case 2 : {

printf ("\nMatrix is singular.\n");

printf("Cann't find any solution by this Method.\n");

break;

}

} /* switch (err) */

}

void ShowLMatrix(int err,int dim,double lm[][ARRAY_SIZE])

{

int ir,jc;

double zero=0, one=1;

if (err==0) {

printf("\nThis is your Lower Triangular Matrix..\n");

for (ir =1 ; ir <= dim; ir++) {

Page 109: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

102

for(jc=1; jc <= dim; jc++) {

if (jc >ir){

printf("%10.5f ",zero);

}else {

if(jc==ir)

printf("%10.5f ",one);

else

printf ("%10.5f ",lm[ir][jc]);

}

}

printf("\n");

}

} else {

printf ("\nCann't find L- Matrix\n");

}

}

void ShowUMatrix(int err,int dim,double um[][ARRAY_SIZE])

{

int ir,jc;

double zero=0;

if (err ==0) {

printf("\nThis is your Upper Triangular Matrix..\n");

for (ir =1 ; ir <= dim; ir++) {

for(jc=1; jc <= dim; jc++) {

if (jc >=ir)

printf("%10.5f ",um[ir][jc]);

else

printf ("%10.5f ",zero);

}

printf("\n");

}

}else { printf("\nCann't find U - Matrix \n"); }

}

void ShowCoeffMatrix(int dim, double a[][ARRAY_SIZE])

{

int ir,jc;

Page 110: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

103

printf("This is your Coefficeint Matrix..\n");

for (ir =1 ; ir <= dim; ir++) {

for(jc=1; jc <= dim; jc++) {

printf("%10.5f ",a[ir][jc]);

}

printf("\n");

}

}

void ShowConstant(int dim, double c[ARRAY_SIZE])

{

int i;

for(i=1;i<=dim;i++) printf(" Const[%d] = %f ",i,c[i]);

}

/*========= Function LU-Decompostion start here =================*/

int LU_Decompose(int dim, double LU[][ARRAY_SIZE],

double a[][ARRAY_SIZE],double b[ARRAY_SIZE])

/* Function Description: Finding solution of linear eqn by factorize

coefficeint matrix to Lower and Upper triangular matrix

Function call : Pivot(int, int, double lu[][ARRAY_SIZE]

user's define : ARRAY_SIZE = 51

ZERO_APPROACH = 2.02E-16

Input : dim -- dimension of matrix

LU -- Lower and Upper triangular matrix

in compacted

a -- Coefficeint matrix

b -- constant vector.

Output : store the solution in b vector.

Return : 0 -- if no error.

1 -- dimension < 1 or > 50

2 -- Coefficeint matrix is singular

*/

{

int i,j,k,row,col,m,n;

int flag_zero=0;

if (dim <1 || dim > ARRAY_SIZE -1) return 1;

Page 111: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

104

for ( i= 1 ; i<=dim; i++ ){

for (j=1; j <=dim; j++)

LU[i][j]=0;

}

n=1;

Pivot(dim,n,LU,a,b);

for (col=1; col <=dim; col++)

LU[1][col]= a[1][col]; /* first row of U-matrix */

if (LU[1][1] == 0 )

return (2); /* singular Matrix */

for(row=2; row<=dim; row++)

LU[row][1] = a[row][1]/LU[1][1]; /* first col of L-matrix*/

for (i= 2; i <=dim; i++) {

Pivot(dim,i,LU,a,b);

for(j=i; j<=dim; j++) { /* for n th row */

LU[i][j] = a[i][j];

for (k=1; k<=(i-1);k++)

LU[i][j] =LU[i][j] -LU[i][k]*LU[k][j];

}

for (m=i+1;m<=dim;m++) { /* for n th column */

LU[m][i] = a[m][i];

for (k=1; k<=i-1;k++)

LU[m][i]=LU[m][i] - LU[m][k]*LU[k][i];

if (fabs(LU[i][i]) < 2*ZERO_APPROACH ) {

LU[i][i] = 0;

flag_zero =1;

} else

LU[m][i] = LU[m][i]/LU[i][i];

}

if (flag_zero ) return 2;

} /* for i... */

/* Forward Substitution */

for (i=2; i<=dim; i++)

for(j=1; j<=i-1;j++) {

b[i]= b[i]- LU[i][j]*b[j];

}

Page 112: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

105

/* Backward Substitution */

b[dim] = b[dim]/LU[dim][dim];

for ( i=dim-1; i >=1; i--) {

for(j= i+1; j <=dim; j++) {

b[i] = b[i]-LU[i][j]*b[j];

}

b[i] =b[i]/LU[i][i];

}

return(0);

}

void Pivot(int dim,int n, double lu[][ARRAY_SIZE],

double a[][ARRAY_SIZE],double b[ARRAY_SIZE])

{

int row,col,k,row_check;

double temp=0;

for (row = n; row <=dim; row++){

if (fabs(a[row][n]) > temp) {

row_check = row;

temp = fabs(a[row][n]);

}

}

if (row_check != n) {

for (col=1; col <=dim; col++) {

temp = a[n][col];

a[n][col]= a[row_check][col];

a[row_check][col] =temp;

temp = lu[n][col];

lu[n][col]= lu[row_check][col];

lu[row_check][col] =temp;

}

temp = b[n]; b[n] = b[row_check];

b[row_check]= temp;

} /* if (row...*/

}

/*======================================================*/

Page 113: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

106

3.7 วธของเกาส-ไซเดล (Gauss-Sedel Method) เมอเรามระบบสมการเชงเสน n สมการ จะกาหนดผลเฉลยโดยประมาณ x1 ขนมากอน

แลวใช x1 แทนคาหา x2 และนา x1, x2 แทนคาหา x3 ไปเรอย ๆ จนถง xn นาคา x2, ... , xn ทได

ยอนกลบไปหาคา x1 ใหมอกครง นาคา x1 ทไดนหาคา x2, x3, ... xm วนซาไปเรอย ๆ จนคาทได

แตกตางจากคาทแลว อยในชวงความคลาดเคลอนทยอมรบไดจงหยดการวนรอบ

จากสมการ (3.1)

a11x1 + a12x2 + ... a1nxn = b1

a21x1 + a22x2 + ... a2nxn = b2

:

an1x1 + an2x2 + ... annxn = bn

สามารถเขยนสมการนไดใหมเปน

x11

a11(b1 a12x2 a13x3 . . . a1nxn )

x21

a22(b2 a21x1 a23x3 . . . a2nxn )

xn1

a nn(bn a n1x1 a n2x2 . . . a nn 1xn 1)

= − − − −

= − − − −

= − − − − − −

M

หรอ

xi

[b1 a ijx j ]j 1j 1

n

a ij=

−=≠

............... (3.5)

i = 1, 2, .... n

j = 1, .... n

ตวอยาง 3.9 หาคาตอบของระบบสมการเชงเสนโดยวธของเกาส-ไซเดล

2x + 3y - z = 0

x + 5y - 4z = -7

3x - y + 7z = 14

คาตอบทแทจรงของระบบสมการ คอ x = 2, y = -1, z = 1

Page 114: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

107

วธทา เขยนระบบสมการชดนไดใหมเปน

x = (0 - 3y + z)/2 ...........................(1)

y = (-7 - x + 4z)/5 ...........................(2)

z = (14 - 3x + y)/7 ...........................(3)

เรมตนดวยกาหนดคา y = z = o จะได

x(1) = 0 นาคา x ไปแทนลงในสมการ (2) จะได

y(1) = -1.4 นาคา x, y ทไดไปแทนลงในสมการ (3) จะได

z(1) = 1.8

ในรอบท 2 นาคา y(1), z(1) ทไดไปแทนคาลงในสมการ (1) จะได

x(2) = 0.3 นาคา x(2 )= 0.3, z(1) = 1.8แทนลงในสมการ (2) จะได

y(1) = -0.56 นาคา x(2), z(1) แทนลงในสมการ (3) จะได

z(2) = 0.634

ทาเชนนตอไปจนผลลพธทไดครงท n และ n-1 ตางกนนอยกวาความคลาดเคลอนท

กาหนดไว จงจะไดคาตอบทตองการ ดงรปขางลางน

รป 3. 8 แสดงผลลพธทไดจากโปรแกรม Gauss-Seidel

Solving a linear set of Equation using Gauss-Seidel Iteration

==============================================

Input Number of equation. (1 - 50 ) 3

Tolrelance [Default = 1E-07] : 0.0001

Maximum of Iteration [Default = 100] : 100

This is your Coefficeint & constant Matrix..

2.00000 3.00000 -1.00000 | 0.00000

1.00000 5.00000 -4.00000 | -7.00000

3.00000 -1.00000 7.00000 | 14.00000

The solution of this equation....

X1 = 1.99326

X2 = -0.99333

X3 = 1.00384

WARNING !!! Convergence maybe failed.

because matrix is not diagonal dominance

Page 115: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

108

การใชวธของเกาส-ไซเดล หาผลเฉลยของระบบสมการเชงเสนนนจะลเขาหาผลเฉลยไดไว

ถาจดใหสมาชกของเมตรกซของสมประสทธในแนวเสนทะแยงมมมคามากกวาผลบวกของคา

สมบรณของสมาชกทเหลออยในแถวเดยวกน เมตรกซทมคณสมบตเชนนเรยกวาเปน diagonally

dominant จากตวอยาง 3.8 เปนระบบสมการเชงเสนทไมเปน diagonally dominant เพราะวา

สมการท 1 จะเหนวา ⏐2⏐ มคานอยกวา ⏐3⏐+⏐1⏐ การใชวธเกาส-ไซเดลกบระบบสมการท

ไมเปน diagonally dominant อาจลเขาหาคาตอบไดเชนกน หรออาจะเกดกรณการลออกจนไมได

คาตอบทตองการ ถาเรากระจายสมการ 3.5 จะมองเหนคากลาวนไดอยางชดเจน ดงน

x ib ia ii

a i1x1a ii

a i2 x2a ii

. . .a i(i 1) x i 1

a ii= − − − −

− −

ผลเฉลย xi จะคลาดเคลอนมากนอยเพยงใดขนอยกบผลรวมของความคลาดเคลอนของ

x1, x2 จนถง xi-1 คณดวยสมประสทธของแตละตวแปร ถาสมประสทธทอยในแนวเสนทแยงมม

(aii) มคามากกวาสมประสทธตวอนๆ ในแถวเดยวกน (aij) คา aij/aiiจะมคานอยกวาหนง ความ

คลาดเคลอนของผลเฉลย xi จะมคานอยลง ๆ เมอการวนรอบมจานวนครงมากขน

การนาโปรแกรม Gauss_Seidel ไปใชงาน การนาไปใชงานมลกษณะดงตอไปน

ก. คาคงททตองกาหนด #define ARRAY_SIZE 51

#define ZERO_APPROACH 2.20E_16

ข. การเรยกใชฟงกชน

int Gauss_Seidel (int dimension, int* loop_limit)

float *tol, double a [ ][ARRAY_SIZE]

dimension ขนาดของเมตรกซสมประสทธ

loop_limit จานวนครงสงสดของการวนรอบ

tol คาความคลาดเคลอนทยอมรบได ตงไวททศนยม 7 ตาแหนง

a เมตรกซของสมประสทธและตวคงท

ค. ผลลพธ ถาไมมขอผดพลาดใด ๆ ผลเฉลยของระบบสมการจะถกเกบไวในคอลมน

n + 1 ของเมตรกซ a

ง. การสงคากลบ

0 ..... ไมมขอผดพลาดใด

Page 116: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

109

1 ..... เมตรกซสมประสทธขาดคณสมบต diagonally dominant

ผลเฉลยทไดอาจมความคลาดเคลอนสง

2 ..... ขนาดของเมตรกซนอยกวาหนง หรอมากกวาคาทกาหนดไวใน

ARRAY_SIZE

3 ..... ไมสามารถหาผลเฉลยได เพราะมสมประสทธทอยในแนวทะแยงมม

บางตวมคาเปนศนย

4 ..... จานวนครงการวนรอบมากกวาคาสงสดทกาหนดไว

รายละเอยดโปรแกรม 3.4 GaussSidl.C

/* Program 3.4 - GuasSeid.C (Gauss-Seidel.C)

* Purpose: Demonstrate how to solving a linear system

* using Gauss-Seidel Iteration.

* Author : Wachara R.

* Last update : 12 Apr 94

**************************************************************/

#include <stdio.h>

#include <math.h>

#define ARRAY_SIZE 51

#define ZERO_APPROACH 2.20E-16

int GetData(int*,float*,double a[][ARRAY_SIZE]);

int GaussSeidel(int ,int*,float*, double a[][ARRAY_SIZE]);

void DisplaySolution(int,int, double a[][ARRAY_SIZE]);

void ShowCoeff_constantMatrix(int, double a[][ARRAY_SIZE]);

void main()

{

double a[ARRAY_SIZE][ARRAY_SIZE]; /* Augmented matrix */

int size=0,error;

int maxiter=0;

float tolerance = 0;

int i,j;

clrscr();

printf("\tSolving a linear set of Equation using Gauss-Seidel Iteration \n");

Page 117: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

110

printf("\t===================================================

=========\n");

size = GetData(&maxiter,&tolerance,a);

ShowCoeff_constantMatrix(size,a);

error = GaussSeidel(size,&maxiter,&tolerance,a);

DisplaySolution(error,size,a);

}

int GetData(int *maxloop, float *tol,double a[][ARRAY_SIZE])

{

int i,j,dim;

char buffer[225];

do {

printf("Input Number of equation. (1 - %d ) ",ARRAY_SIZE-1);

gets(buffer);

dim=atoi(buffer);

} while ( dim < 1 || dim > ARRAY_SIZE-1);

printf("Tolrelance [Default = 1E-07] : ");gets(buffer);

*tol=atof(buffer);

printf("Maximum of Iteration [Default = 100] : ");gets(buffer);

*maxloop =atof(buffer);

for (i =1 ; i <= dim; i++) {

printf("\n<<Equation # %d>>\n",i);

for (j = 1; j <= dim; j++) {

printf("\tCoefficent (%d,%d) = ",i,j);gets(buffer);

a[i][j] = atof(buffer);

}

printf("\n\tConstant # %d = ",i );

a[i][dim+1] = atof(gets(buffer));

}

return(dim);

}

void DisplaySolution(int err,int dim, double a[][ARRAY_SIZE])

{

int i,j;

switch (err) {

Page 118: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

111

case 0 :

case 1 : {

printf("\nThe solution of this equation....\n");

for (i=1; i<= dim; i++) {

printf( "\tX%d = %13.5f\n",i,a[i][dim+1]);

}

if (err==1) {

printf("\n WARNING !!! Convergence maybe failed.\n");

printf("because matrix is not diagonal dominance\n");

}

break;

}

case 2 : {

printf("\nThe dimension must be greater than 1\n");

printf(" and less than 50\n");

break;

}

case 3 : {

printf ("\nSome element of Matrix on diagonal is zero\n");

break;

}

case 4 : {

printf (" More than iteration limit. May be divergence?\n");

break;

}

} /* switch (err) */

}

void ShowCoeff_constantMatrix(int dim, double a[][ARRAY_SIZE])

{

int ir,jc;

printf("\nThis is your Coefficeint & constant Matrix..\n");

for (ir =1 ; ir <= dim; ir++) {

for(jc=1; jc <= dim; jc++) {

printf (" %10.5f ",a[ir][jc]);

Page 119: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

112

}

printf("| %10.5f\n",a[ir][dim+1]);

}

}

/*======================================================*/

int GaussSeidel(int dim, int*loop_limit, float*tol,double a[][ARRAY_SIZE])

/* Function Description : solving a set of linear eqn using

Gauss-Seidel Iteration.

define: ARRAY_AIZE = 51

ZERO_APPROACH = 2.20E-16 (for double precision)

Input: a -- coefficeint & constant Matrix.

dim -- Dimension of Coefficeint Matrix

loop_limit -- maximum iteration.

tol -- tolerance

Output: The solutions of eqn. keep in Matrix column dim+1

Return :

0 -- No error detected.

1 -- not diagonal dominant matrix.

2 -- Dimension < 1 or > ARRAY_SIZE-1

3 -- Found zero on diagonal element of coeff matrix.

4 -- Iteration > loop_limit

*/

{

int i,j,k,row,count=0,error=0,finish=0;

double sum,temp;

double oldx[ARRAY_SIZE],currentx[ARRAY_SIZE];

int col_id[ARRAY_SIZE];

if (dim < 1 || dim > ARRAY_SIZE-1) return 1;

if (*tol <=0 ) *tol = 1E-7;

if (*loop_limit <=0 ) *loop_limit = 100;

if ( dim == 1) {

if (a[1][1] != 0 ) {

a[1][2] = a[1][2]/a[1][1];

return 0;

Page 120: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

113

} else { return 3;} /* Can't find solution */

}

/* exchange row for a largest value on diagonal line */

for (i=1;i<=dim;i++){

temp = fabs(a[i][1]);

col_id[i] =1;

for (j=1; j<=dim; j++) {

if ( fabs(a[i][j]) > temp) {

temp = fabs(a[i][j]);

col_id[i] = j;

}

}

}

/* Now begin to exchange rows. */

for (i =1; i < dim; i++) {

k=0;

if(col_id[i] != i) {

for (row=i; row <=dim; row++) {

if (col_id[row] == i) {

k = row;

}

}

if ( k != 0) {

for ( j= 1; j<= dim+1; j++) {

temp = a[k][j];

a[k][j] = a[i][j];

a[i][j] = temp;

}

col_id[k] = col_id[i]; /* reset largest value col */

}

} /* if (col_id.. */

} /* for (i.. */

/* Test diagonal dominance */

i = 0;

while ( i < dim && error ==0) {

i+=1;

Page 121: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

114

sum = 0;

for ( j=1; j<=dim; j++) {

if (j != i)

sum = sum+ fabs(a[i][j]);

}

if (sum > fabs(a[i][i]))

error = 1;

}

i=0;

while ( i < dim && (error <2)) {

i+=1;

if (fabs(a[i][i]) <= ZERO_APPROACH ) {

a[i][i] =0;

error = 3;

}

}

for ( i= 1; i<=dim;i++ ) {

oldx[i] = rand()/100; /* generate random number 0-99 */

currentx[i] = 0;

}

while ( !finish && (error < 2) && (count <= *loop_limit)) {

count +=1;

for (i=1; i<=dim;i++) {

sum=0;

for (j=1; j<=dim; j++)

if (j != i)

sum = sum+a[i][j]*currentx[j];

currentx[i] = (a[i][dim+1]- sum)/a[i][i];

if (fabs(currentx[i]-oldx[i]) <= *tol) {

finish =1;

}

oldx[i]=currentx[i];

}

/* In case of learning or debugging

printf("loop %d : ",count);

Page 122: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

115

for(k=1;k<=dim;k++) printf("x[%d] = %10.5f ",k,currentx[k]);

printf("\n"); getch();

*/

}

for (i= 1;i<=dim; i++)

a[i][dim+1] = currentx[i];

if (count > *loop_limit) error = 4;

return error;

}

/*===============================================*/

3.8 การไปใชแกปญหาทางฟสกส ตวอยาง 3.10 วงจรไฟฟาประกอบดวยตวตานทานและแหลงจายไฟ ดงรป

จงคานวณหากระแสไฟฟา I1, I2 และ I3

รป 3.9 วงจรไฟฟาทประกอบดวยตวตานทาน

วธทา 1) ใชกฎเคอรชอฟวนรอบวงจรไฟฟาแตละวง จะไดเปนระบบสมการเชงเสน ดงน

10.3 I1 - 4.7 I2 = 10

-4.7 I1 + 11.2 I2 - 1.8 I3 = 0

- 18 I2 + 5.1 I3 = 5

2) หาผลเฉลยโดยใช GaussSidl.C จะไดดงน

Page 123: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

116

รป 3.10 ผลลพธทไดจากโปรแกรม GaussSidl.C

Solving a linear set of Equation using Gauss-Seidel Iteration

=============================================

Input Number of equation. (1 - 50 )

Tolrelance [Default = 1E-07] :

Maximum of Iteration [Default = 100] :

This is your Coefficeint & constant Matrix..

10.30000 -4.70000 0.00000 | 10.00000

-4.70000 11.20000 -1.80000 | 0.00000

0.00000 -1.80000 5.10000 | 5.00000

The solution of this equation....

x1 = 1.31320 → (I1)

x2 = 0.75119 → (I2)

x3 = 1.24552 → (I3)

ตวอยาง 3.11 ระบบหนงประกอบดวยสปรง 4 ตว ดงภาพ ถาไมคดแรงเสยดทานใด ๆ และ

ระบบอยในภาวะสมดล จะได

k1y1 = k2(y2 - y1)

k2 (y2 - y1) = k3 (y3 - y2)

k3 (y3 - y2) = k4 (y4 - y)

P = k4 (y4 - y3)

รป 3.10 รปสาหรบตวอยาง 3.11

เมอ k คอคาคงทของสปรง มคาเปน k1, k2, k3 และ k4 มคาเปน 50, 25, 40, และ

100 N/มม. P = 1000 B จงคานวณหาระยะ y1, y2, y3, y4 ในหนวย มม.

Page 124: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

117

วธทา 1) แทนคาตามทโจทยกาหนดให แลวจดรปสมการใหมจะได

3y1 + y2 = 0

-5y1 + 13y2 - 8y3 = 0

- 2y2 + 7y3 - 5y4 = 0

-y3 + y4 = 10

เขยนใหอยในรปเมตรกซแตงเตมแลว จะไดเปน

+ −− −

− + −− +

⎢⎢⎢

⎥⎥⎥

3 1 0 0 05 13 8 0 0

0 2 7 5 00 0 1 1 10

2) ใชโปรแกรม GaussEli.C ปอนขอมลแลวใหโปรแกรมทางาน จะได

y1 = 20 มม.

y2 = 60 มม

y3 = 85 มม

y4 = 95 มม

ตวอยาง 3.12 แรง F ขนาด 20 นวตน ทาใหวตถ 3 ชน เคลอนทขนไป

ในแนวดงดวยความเรง (a) เทาใด ไมคดแรงตานทานอากาศ

พรอมทงหาแรงตงเชอก T และ P

( กาหนดให g = 9.8 m/s2 )

รป 3.11 รปสาหรบตวอยาง 3.12

T

P

F

0.2

0.8

1

Page 125: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

118

วธทา

1) เขยน Free body diagram ทวตถแตละชนแลวใชกฎขอท 2 ของนวตน หาสมการการ

เคลอนท จะได

a - P = -9.8

0.8a - T + P = -7.84

0.2a + T = 18.04

2) ใชโปรแกรม GaussEli.C หาคาตอบจะไดผลลพธดงน

Solving a linear set of Equation with Gauss Elimination Method

===============================================

Input Number of equation. (1 - 50 ) 3

This is your Augmented Matrix..

1.00000 0.00000 -1.00000 | -9.80000

0.80000 -1.00000 1.00000 | -7.84000

0.20000 1.00000 0.00000 | 18.04000

Your det = -2.000000

X1 = 0.20000 ------------> a

X2 = 18.00000 ------------> T

X3 = 10.00000 ------------> P

ตวอยาง 3.13 วงจรบรดจแบบวตสโตน (Wheatstone Bridge) มตวตานทานทกตวมหนวยเปน

กโลโอหม จงหากระแสไฟฟา I1 I2 และ I3

รป 3.11 รปสาหรบตวอยาง 3.13

Page 126: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

119

วธทา 1) อาศยกฎเคอรชอฟคานวณจะไดระบบสมการเชงเสนของกระแสไฟฟา ดงน

3I1 - I2 - I3 = 0

-I1 + 3I2 - I3 = 0

-I1 - I2 + 12I3 = 12

2) ใชโปรแกรม GausEli.C หรอ GausSidl.C หรอ GaussJd.C จะไดคาตอบดงน

I1 = 0.54545 A

I2 = 0.54545 A

I3 = 1.0909 A

3.9 บทสรป ถาตองการจะหาผลเฉลยของระบบสมการเชงเสนสกชดหนงดวยคอมพวเตอร วธการ

ลดทอนของเกาสควรเปนวธแรกทเลอกใช เพราะจะไดคาตอบเรวทสดและใกลหรอเทากบคา

แทจรงมากทสด แตถาใชวธการลดทอนของเกาสแลวพบปญหาขนาดของตวกาหนด

(determinant)มคาเปนศนย ควรเลยงมาใชวธเกาส-ไซเดล อาจจะตองจดรปสมการเสยใหมใหม

ลกษณะทเรยกวา diagonally dominant (ดหวขอ 3.7)

ถาระบบสมการเชงเสนทตองการหาผลเฉลยมหลายชด ทกชดมสมประสทธดานซายมอ

เหมอนกน แตคาคงทดานขวามอตางกน ควรเลอกใชวธแยกเปนเมตรกซสามเหลยมลางและบน

จะใหประสทธภาพมากทสด วธนจะไมไปยงกบคาคงททางดานขวามอของระบบสมการแตละชด

Page 127: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

120

This page left blank intentionally. By Wachara

Page 128: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

121

บทท 4 การหาคาอนพนธและอนทเกรตเชงตวเลข

4.1 การหาคาอนพนธอนดบหนงโดยใชตารางขอมล การหาคาอนพนธเปนการคานวณหาอตราการเปลยนแปลงของฟงกชนทกาหนดให เชน จากการจบเวลาและวดระยะทางของรถยนตคนหนง ไดขอมลดงตอไปน

เวลา (ชม.) 1 1.2 1.4 1.6 1.8 2 ระยะทาง (กม.) 50 62.3 78.5 82.2 99.6 120.1

เมอเวลาผานไป 1 ชม. รถยนตจะอยหางจากจดเรมตน 50 กม. เมอเวลาผานไป 1 ชม. 12 นาท รถยนตจะอยหางจากจดเรมตน 62.3 กม. และเมอเวลาผานไป 2 ชม. รถยนตจะอยหางจากจดเรมตน 120.1 กม. การหาคาการเปลยนแปลงของระยะทางเทยบกบเวลา จะไดเปนความเรวเฉลยของ รถยนตทชวงเวลานน เชน ในชวงแรกความเรวเฉลยของรถยนต คอ (62.3-550)/(12.-1) = 61.5 กม./ชม. ถาชวงเวลาทใชในการหาความเรวเฉลยมคาสนมาก (∆t → 0) จงเปนการหาความเรวทขณะใดขณะหนง เรยกวาเปนการหาอนพนธของระยะทางเทยบกบเวลา การหาอนพนธจงเปนการลบกนของขอมล 2 คาทมคาใกลเคยงกน แลวหารดวยจานวนทมคานอย ๆ ความแมนตรง (accuracy) ขนอยกบขอมลทไดมาและความละเอยดของตวเลขทเครองคอมพวเตอรนน และขนอยกบคาระยะหางของขอมลเพราะการหารดวยตวเลขมคานอย ๆ โอกาสทจะเกดความคลาดเคลอนเนองจากการปดเศษจงเปนไปไดมาก ถามขอมลชดหนง ตวแปรตามของขอมลชดน (x) มระยะหางเทา ๆ กน เทากบ h การหาอนพนธของฟงกชน f(x) ทจด x0 หาไดจาก

f’ (x0) = lim f(x h) f(x )

h0 0+ −

..................... (4.1) ถาพจารณาขอมลเพยง 2 จด คอ x0 , x1 ตองการหาอนพนธของฟงกชนทจด x ใด ๆ สามารถประมาณฟงกชนในชวง x0 ถง x1 โดยใชพหนามของลากรองจไดดงน

f (x) ≅ (x - x1)f(x )

(x x )(x - x o )f(x )

(x x )0

0 11

1 0−+

− .................... (4.2)

ดฟเฟอเรนชเอทสมการ (4.2) เทยบกบ x จะได

h → 0

Page 129: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

122

f’(x) ≅ f(x )

(x x )f(x )

(x x )0

0 11

1 0− + −

เพราะ x1 -x0 = h

f’(x) ≅ f(x h) f(x )

h0 0+ −

.................... (4.3) เปนการหาคาอนพนธทตาแหนง x = x0 ถา h > 0 เรยกวา เปนสตรผลตางแบบเดนหนา (forward difference formula) ถา h < 0 เรยกวาผลตางแบบถอยหลง (backward difference formula)

รป 4.1 ก. แบบเดนหนา ข. แบบถอยหลง เมอพจารณาฟงกชนทจด x0, x1, x2 (3 จด) พหนามลากรองจทใชแทนฟงกชนทผานจด 3 จดนคอ

f (x) ≅ y (x x )(x - x )(x x )(x x )

y (x x )(x x )(x x )(x x )

0 1 2

0 1 0 21 0 2

1 0 1 2

− − + − − +− −

y (x x )(x x )(x x )(x x )

2 0 1

2 0 2 1

− −

− − .................... (4.4)

หาคาอนพนธจะได

f’ (x) = y (2x x x )(x x )(x x )

y (2x x x )(x x )(x x )

0 1 2

0 1 0 2

1 0 2

0 1 2

− −− − +

− −− −

− −− −+

y (2x x x )(x x )(x x )

2 0 1

2 0 2 1

.................... (4.5)

Page 130: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

123

ใหระยะหางระหวางขอมล (h) มคาคงท โดยท x1 = x0 + h , x2 = x0 + 2h เมอจดทตองการหาอนพนธคอ จด x0 แทนคา x0 ลงในสมการ (4.5)

f’(x0) ≅ [ ]1h

32 f(x ) 2f(x h) 1

2 f(x 2h)0 0 0− + + − + .................... (4.6) เมอจดทตองการหาอนพนธคอ จด x1

f’(x0+h) = [ ]1h

12 f(x ) 1

2 f(x 2h)0 0− + + .................... (4.7) เมอจดทตองการหาอนพนธคอ จด x2

f’(x0+2h) = [ ]1h

12 f(x ) 2f(x ) 3

2 f(x )0 1 2− − + .................... (4.8) จากสมการ (4.7) และ (4.8) เปลยนคา x0+ h ใหอยในรป x0 และ x0+2h ใหอย ในรป x0 จากสมการ (4.6)

f’(x0) ≅ [ ]12h 3f(x ) 4f(x h) f(x 2h0 0 0− + + − + .................... (4.9)

จากสมการ (4.7)

f’(x0) ≅ [ ]12h f(x h) f(x h0 0− − + + .................... (4.10)

จากสมการ (4.8)

f’(x0) ≅ [ ]12h f(x 2h) 4f(x h) 3f(x )0 0 0− − − + .................... (4.11)

สมการ (4.9), (4.10) และ (4.11) ตองการขอมลเพยง 3 จด กสามารถหาคาอนพนธทจด x0 ได เรยกสมการทงสามนวาเปน สตรการหาอนพนธแบบ 3 จด (three point formula) สมการ (4.10) จดทตองการหาอนพนธ x0 จะอยตรงกลางของชดขอมล สมการ (4.9) และ (4.11) ใชหาอนพนธของจดทปลายดานใดดานหนงของชดขอมล เมอแทนคา h ในสมการ (4.9) ดวย -h สมการทงสองคอ สมการเดยวกนนนเอง

Page 131: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

124

เมอพจารณาฟงกชนเพยง 5 จด เราสามารถสรางสตรการหาอนพนธสาหรบ 5 จดไดโดยใชคาเรมตนดวยพหนามของลากรองจ เหมอนการหาอนพนธแบบ 3 จด จะไดสตรการหาอนพนธทจด x0 ดงน

f’(x0) ≅ [ ]112h f(x 2h) 8f(x h) 8f(x h) f(x 2h)0 0 0− − − + + − +

..................... (4.12) การหาอนพนธในโปรแกรม 4.1 Deriv_TB.C นน จะใชสมการ 4.1 ถาขอมลมอยเพยง 2 จด ใชสมการ (4.9), (4.10) และ (4.11) เมอตรวจสอบพบวาขอมลม 3 จด และถาพบวาจานวนจดเพยงพอทจะใชสมการ (4.12) โปรแกรมกจะเลอกใชสมการน ตวอยาง 4.1 ขอมลตอไปนไดมาจากฟงกชน y = xex ตองการหาคาอนพนธอนดบหนงทคา x แตละคา วธทา คาแทจรงของอนพนธอนดบหนงของ y คอ y’ = (1+ x)ex เปรยบเทยบคาทได จากโปรแกรม และคา y’ ทแทจรงดงตาราง

x f(x) f’ คาแทจรง f’ จาก program คาผดพลาด 1.0 2.71828 5.43656 5.39670 0.03986 1.1 3.30458 6.30875 6.26370 0.04505 1.2 3.98414 7.30426 7.30417 9×10-5 1.3 4.77008 8.43938 8.39130 0.04808 1.4 5.677280 9.73248 9.677830 0.05418

การหาอนพนธของ x ตรงขอบตารางจะใชสตรการหาอนพนธแบบ 3 จด ตรงบรเวณกลางตาราง (x = 1.2) จะใชสตรการหาอนพนธแบบ 5 จด ซงจะใหคาความคลาดเคลอนนอยกวาจดอน ๆ

Page 132: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

125

ตวอยาง 4.2 นาเครองบนจาลองไปทดสอบแรงตานอากาศในอโมงคลม วดตาแหนงของ เครองบนเปนฟงกชนกบเวลา ดงน

t (วนาท) 0 0.5 1 1.5 2 2.5 3 3.5 4 x (มม.) 0 475 800 1,225 1,425 1,700 1,875 2,000 2,100

จงหาความเรว(v) และความเรง(a) เมอเวลาผานไป 2 วนาท วธทา ใชโปรแกรม Deriv_TB.C ปอนขอมลเวลาและระยะทางรวม 9 คาเขาไปในโปรแกรม การหาอนพนธครงท 1 จะเปนการหาความเรว ณ เวลาทกาหนดในตารางขอมล จะไดผลลพธดงน

t (วนาท) 0 0.5 1 1.5 2 2.5 3 3.5 4 v (mm./s) 1100 550 762.5 629.167 454.167 470.833 287.5 200 175

ใหโปรแกรม Deriv_TB.C อกครงหนง แลวปอนขอมลระหวาง v และ t เพอหาความเรง หาคาความเรงเมอ t = 2 วนาท จะได a = -131.945 mm./ s2 การใชงานฟงกชน FirstDerive_tabular การนาไปใชรวมกบโปรแกรมอน ๆ ทาไดดงน ก. คาคงททตองนยาม # define ZERO_APPROACH 2.2E-16 # define ARRAY_SIZE 51 ข. การผานคาอนพท และเรยกใชฟงกชน int First Derive_tabular (int n, double xdata [ARRAY_SIZE] double ydata [ARRAY_SIZE], double xual,double derive) n คอ จานวนขอมล xdatta, ydata คอ ขอมล x, y ทกาหนดให xval คอ คา x เปนจดทตองการหาคาอนพนธ derive_x คอ ตวแปรทเตรยมไวสาหรบเกบคาอนพนธทจด xval ค. ฟงกชนทเกยวของ - ง. การสงคากลบ 0 ไมมคาผดพลาด 1 คา x คาเดยวมคา y มากกวา 1 คา

Page 133: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

126

2 คา x มไดเรยงลาดบจากนอยไปมาก 3 จานวนขอมลนอยกวา 2 4 ระยะระหวางขอมล x มคาไมเทากน 5 คา x ไมมอยในขอมลชดน รายละเอยดของฟงกชนและการเรยกใชแสดงไวในโปรแกรม 4.1

รายละเอยดโปรแกรม 4.1 Deriv_TB.C /* * Program 4.1 Deriv_Tb.C * Purpose: Demonstrate how to find the first derivative of function * which given in tabular data * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 9 July 94 **************************************************************/ #include <stdio.h> #include <math.h> #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E-16 /* for double precision */ /* Global Variable */ void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]); int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE]); double GetXValue( void ); int FirstDerive_tabular(int,double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE],\ double ,double*); void DisplayResult(int, double ,double ); void main() { double x[ARRAY_SIZE]; double y[ARRAY_SIZE]; double xval,diff_val=0; int n=0, /* Number of data pairs */

Page 134: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

127

error=0; int i,j,done=0; char msg[150],ans[1]; clrscr(); printf("\t\tFinding the First Derivative of Function.\n"); printf ("\t\t=====================================\n"); Initialize(x,y); n = GetData(x,y); while ( !done ) { xval = GetXValue(); error = FirstDerive_tabular(n,x,y,xval,&diff_val); DisplayResult(error,xval,diff_val); if (error==0 || error > 4) { printf("\nDo you want to find the f'(x) of another point? (Y/N) : "); *ans=getch(); if (*ans == 'n' || *ans == 'N') done = 1; } else { done =1; } } printf("\n Program stop normally.\n"); } void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]) { int i =0; for (i=0; i < ARRAY_SIZE; i++) { x[i]=0; y[i]=0; } } int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE]) { /* BE CAREFUL: data store in array from 0 to n-1 */ int i,j,numdata=0; char buffer[225]; do { printf("\nNumber of data ( 1 - %d) :",ARRAY_SIZE-1);

Page 135: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

128

gets(buffer); numdata = atoi(buffer); }while (numdata < 1 || numdata >= ARRAY_SIZE); for (i=1; i <= numdata; i++) { printf("\tX[%2d] = ",i);gets(buffer); xdata[i-1]= atof(buffer); printf("\tY[%2d] = ",i);gets(buffer); ydata[i-1]= atof(buffer); printf("\n"); } return numdata; } double GetXValue( ) { char buffer[250]; double x; printf("\n\tFind the first Derivative at X = ");gets(buffer); x=atof(buffer); return x; } void DisplayResult(int err, double xval,double yval) { switch (err) { case 0 : { printf( "\n\tX = %13.5f ",xval); printf( " Differentiat of X = %13.5f\n",yval); break; } case 1 : { printf("\nX data must be unique.\n"); printf("Some data of x have the same value\n"); break; } case 2 : {

Page 136: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

129

printf("\n data are not in increasing order.\n"); break; } case 3 : { printf("\n Data must more than 2....!!!\n"); break; } case 4 : { printf("\n X data are not equal range. \n"); break; } case 5 : { printf("\n X value is out of data. \n"); break; } } /* switch (err) */ } /*================== Function Start here. ==========================*/ int FirstDerive_tabular(int n,double xdata[ARRAY_SIZE], double ydata[ARRAY_SIZE],double xval,double *deriv_x) /* Function Description: Determine the first derivative of function at point "xval".The function must be given in the set of points (x,y) . User's Define : #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20e-16 Input : n -- number of data pair (x,y) xdata,ydata -- given data. begin from 0 to n-1. xval -- x value which we want to know the first derivative. Output : deriv_x -- the derivative of f(x) at xval Return : 0 -- if no error. 1 -- Some data of x have the same value.

Page 137: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

130

(x not unique). 2 -- x data are not in ascending order 3 -- n < 2 4 -- x data don't have the same pace 5 -- x value is out of range. ************************************************************************/ { int i,j,index,flag; int l_flag,r_flag; double h,ex_h; if ( n < 2) return 3; ex_h = 0; for (i=0; i<n-1; i++) { h = xdata[i+1]-xdata[i]; /* if (i > 0 && !(h == ex_h) ) There is some probelm in this line */ if ( (i>0) && !(h - ex_h < 1e-15)) /* may be 1e-07 is ok */ return 4; ex_h = h; if ( h < 0) return 2 ; if (fabs(h) <= ZERO_APPROACH) return 1; } i=0; while ( (xval != xdata[i]) && (i < n)) { i+=1; } if ( i == n) { return 5; } l_flag = r_flag = 0; if (n > 2 && i+2 <= n-1) r_flag=1; if (n > 2 && i-2 >= 0 ) l_flag=1; flag = r_flag+l_flag; if ( n == 2) { /* 2 point formula */ if (i == 0 )

Page 138: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

131

*deriv_x = (ydata[i+1]-ydata[i])/h; /* (xdata[i+1]-xdata[i]); */ else *deriv_x = (ydata[i]-ydata[i-1])/(-h); /* (-(xdata[i]-xdata[i-1])); */ } else { switch(flag) { case 0 : { /* 3 point formula at mid point*/ *deriv_x = (-ydata[i-1] + ydata[i+1])/(2*h); break; } case 1 : { if (r_flag ) { /* 3 point at left most */ *deriv_x = (-3*ydata[i]+4*ydata[i+1]-ydata[i+2])/(2*h); }else { /* 3 point at rightmost */ *deriv_x = (ydata[i-2]-4*ydata[i-1]+3*ydata[i])/(2*h); } break; } /* case 1 */ case 2 : { *deriv_x = (ydata[i-2]-8*ydata[i-1]+8*ydata[i+1]-ydata[i+2])/(12*h); break; } } /* switch */ } /* else */ return 0; } /*=======================================================*/

Page 139: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

132

4.2 การหาคาอนพนธอนดบหนงของฟงกชนทกาหนดให เมอตองการหาอนพนธอนดบหนงของฟงกชน f(x) โดยกาหนดจดทตองการหาอนพนธมาให (x) เราอาจนาคา x ไปแทนคาลงในฟงกชน จะไดคา x, f(x) ในรปตาราง แลวใชวธการในหวขอ 4.1 หาอนพนธทจดนน ๆ ได ในทนตองการเสนอการหาอนพนธอกวธหนง โดยใชคา ทไดจากฟงกชนนนโดยตรงหาอนพนธอนดบหนง จากนนใชการประมาณคาแบบรชารดสน (Richardson extrapolation) หาคาอนพนธจนไดใกลเคยงหรอมคาเทากบคาแทจรง หลกการประมาณคาแบบรชารดสน มดงน ถา f(x) เปนฟงกชนทมคาอนพนธตอเนองถงอนดบ 5 กระจาย f(x) เปนอนกรม โดยอาศยทฤษฏบทของเทเลอร จะได

f(x0+h) = f(x ) f (x )h f (x )h2 f (x )

h2 f (x )

h24 f (x )

h120 O(h0 0

(2)0

2(3)

0

3(4)

0

4(5)

0

56+ + + + + +′ )

....................... (4.13)

f(x0+h) = f(x ) f (x )h f (x )h2 f (x )

h2 f (x )

h24 f (x )

h120 O(h0 0

(2)0

2(3)

0

3(4)

0

4(5)

0

56− + − + − +′ )

....................... (4.14) นาสมการ (4.13) ลบกบสมการ (4.14) เทอมทประกอบดวย f(2) , f(4) จะหายไป จดรปสมการใหม จะไดเปน

( )′ ′= = + − − − −y f (x) 12h f(x h) f(x h) f (x ) h

6 f (x ) h1200 0

(3)0

2(5)

0

4

...................... (4.15) เมอ O(h6 ) คอ เทอม ๆ หลงจาก f(5) โดยปกตจะตดทงไป ทาใหเกดความคลาดเคลอนเนองจากการตดปลาย เขยนสมการ (4.15) ใหงาย เพอทจะนาไปใชกบการประมาณคาแบบรชารดสน ′ += + +y A (h) a h a h O(h )0 2

24

4 6 ...................... (4.16)

( )A (h) 12h f(x h) f(x h)0 0 + 0= − −

a คอ - f (x ) / 6 a คอ f ) (x ) / 1202

(3)0 4

(50

Page 140: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

133

เนองจากการประมาณคาตองกระทาซากนหลายครง หรอหลายระดบ จงใสตวเลขหอยทตวอกษร A ไว เพอมใหสบสนกอนการประมาณคา y’ = A0(h) เรมประมาณคาครงท 1 โดยใหเปลยนคา h เปน h/2 จากสมการ (4.16) จะได

′ = + + +y A (h2 ) a

h4 a h

16 ...0 2

2

4

4 ..................... (4.17)

นา 4 คณสมการ (4.17) แลวนาสมการ (4.16) มาลบออก เทอม h2 จะหมดไป ตดเทอม h4 ทง จะไดเปนคาประมาณคาใหม คอ ′

−+= +y

4A (h / 2) A (h)3

34

a h .. .0 04

4 ..................... (4.18)

′−

==y4A (h / 2) A (h)

3 A (h)0 01

คา ′y จะเปนคาใหม เนองจากเปนการประมาณคาครงท 1 และ y’ = A0(h) คาเดม จงใหคา ′y ใหมนเปน A1 (h) หาผลตางระหวาง A1(h) กบ A0(h) ถายงมากกวาคาความคลาดเคลอนทยอมรบได ใหประมาณคาครงท 2 ตอไป จากสมการ (4.18)

′ − +=y A (h) 34 a h O(h )1 4

4 6 ...................... (4.19) แทนคา h ดวย h

2 แลวแทนสมประสทธของ h4 ดวย b1

′ += +y A (h / 2) b h O(h )1 1

4 6 ...................... (4.20) แทนคา h ดวย h/2 ลงในสมการ (4.20)

′ += +y A ( h4) b h

16 O(h )1 1

46 ...................... (4.21)

นาสมการ (4.21) × 16 แลวนาสมการ (4.20) มาลบออก ตดเทอม O(h6) ทง

Page 141: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

134

( ) ( )

′ =−

y16 A h

2 A h2

151 1

...................... (4.22) = A (h)2 จะได A2(h) เปนคาประมาณคาใหมของ y’ ถาผลตางของ A2(h) และ A1(h) ยงมากกวาคาความคลาดเคลอนทยอมรบได ใหประมาณคาครงท 3 ตอไป ทาเชนนเรอย ๆ จน ผลตางของคาประมาณนอยกวาคาความคลาดเคลอนทยอมรบได ถาการประมาณคาทาไปเรอย ๆ จนถงครงท n จะไดสตรการประมาณคาทวไปดงน

( )

A (h)4 A h

2 A (h)4 1n

nn 1 n 1

n=− − −

− ....................... (4.23) เพอใหดงาย จงใสคาตาง ๆ เปนตารางดงน

อนดบทคานวณ ระดบ

0 A0(h) 1 A0(h/2) A1(h) 2 A0(h/4) A1(h/2) A2(h) 3 A0(h/8) A1(h/4) A2(h/2) A3(h) 4 A0(h/16) ... ... ...

ตวอยาง 4.2 อนภาคเคลอนทเปนฮารมอนกแบบธรรมดา การขจดของอนภาคเปนไปดงสมการ เมอ x = wt y = 0.2 sin x (ม.) จงหาความเรวของอนภาค เมอ t = 1/3 วนาท วธทา ความเรวของอนภาคหาไดจาก การหาอนพนธอนดบหนงของสมการการขจดท t = 1/3 วนาท หรอท x = π/3 ประมาณคาเรมตน โดยให h = π = 3.1415926

A (h) A ( )0.2 sin( 3 ) sin( 3 )

2 00 0= =

⎛⎝⎜ ⎞

⎠⎟

=+ − −

ππ π π π

π

O(h2) O(h4) O(h6) O(h8)

Page 142: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

135

ประมาณคาระดบท 1

( )

A (h2 ) A ( 2 )

0.2 sin( 2 2 ) sin( 3 2 )p0 0= =

+ − −ππ π π π

= 0.06357414

A (h)4 A (h

2 ) A (h)4 11

0 0=

− = 0.0848114 ประมาณคาระดบท 2

A (h4) A ( p

4 ) 0.2sin( 3 4 ) sin( 3 4 )

20 0= =

+ − −⎛

⎝⎜⎜

π π π π

π

= 0.09000497

A ( h2)

4 A (h2 ) A (h

4)4 11

0 0=

− = 0.09881525

A (h)16 A (h

2 ) A (h)152

1 1=

− = 0.099974884

เมอนาคาไปใสในตารางจะได ระดบ A0 A1 A2 A3 A4

0 h 0 1 h/2 0.06357414 h 0.0848114 2 h/4 0.09000497 h/2 0.0988152 h 0.09974884 3 h/8 0.09744256 h/4 0.09992175 h/2 0.0999552 h 0.09999944 4 h/16 0.09935693 h/8 0.09999505 h/4 0.09999994 h/2 0.10000 0.1000

คาอนพนธของ y = 0.2 sin x คอ A4 = 0.10 คาทแทจรงคอ 0.1 ม./วนาท เมอดดแปลงโปรแกรม deriv_fn.C ใหสอดคลองกบตวอยาง 4.2 จะไดผลลพธออกมาเชนเดยวกบทคานวณดวยตนเอง

Page 143: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

136

Finding the First Derivative of Function. ===================================== Number of data ( 1 - 50) : 1 X[ 1] = 1.0471975 Tolerance ( default 0.001) :0.0000001 Data no. 1 -0.00013774 , 0.06357414 , 0.08481144 , 0.09000497 , 0.09881525 , 0.09974884 , 0.09744256 , 0.09992175 , 0.09999552 , 0.09999944 , 0.09935693 , 0.09999505 , 0.09999994 , 0.10000001 , 0.10000001 , X[ 1] = 1.047198 1 st Derivative = 0.1000000 การใชงานฟงกชน FirstDerive_function การนาฟงกชน First Derive-function ไปใชกบโปรแกรม มดงน ก. คาคงททตองนยาม # define ARRAY_SIZE 51 # define ZERO_APPROACH 2.20 c -16 ข. การผานคาอนพทและเรยกใชฟงกชน int First Derive-Function (int n, double xdata [ARRAY_SIZE] double result [array_size], double tol) n คอ จานวนจดทตองการหาคาอนพนธ xdata คอ คาจดตาง ๆ ทจะหาคาอนพนธเกบไว ARRAY เรมตงแต 0 ถง n-1 result คอ ตวแปรมไวเพอเกบผลลพธหลงจากคานวณหาคาอนพนธ tol คอ คาความคลาดเคลอนทยอมรบได ค. ฟงกชนทเกยวของ double Your Func (double x) ใสฟงกชนคณตศาสตรทตองการหาคาอนพนธ ง. การสงคากลบ 0 ไมมขอผดพลาด 1 ความคลาดเคลอนทยอมรบไดนอยกวา 0

Page 144: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

137

รายละเอยดของฟงกชนและการเรยกใชแสดงไวในโปรแกรม 4.2 /* * Program 4.2 FirstDeriv_Function.C * Purpose: Demonstrate how to find the first derivative of function. * Using Richardson Extrapolation to approximate the result. * Author : Wachara Rodsumrid. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 10 July 95 **************************************************************/ #include <stdio.h> #include <math.h> #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E-16 /* for double precision */ /* Global Variable */ double YourFunc(double); void Initialize(double x[ARRAY_SIZE],double derive_y[ARRAY_SIZE]); int GetData(double xdata[ARRAY_SIZE],double* ); int FirstDerive_Function(int,double xdata[ARRAY_SIZE],\ double result[ARRAY_SIZE],double); void ShowResult(int,int, double x[ARRAY_SIZE],double y[ARRAY_SIZE]); void main() { double x[ARRAY_SIZE]; double derive_y [ARRAY_SIZE]; double tolerance; int n=0, /* Number of data */ error=0; int i,j; char msg[150],ans[1]; clrscr(); printf("\t\tFinding the First Derivative of Function.\n"); printf ("\t\t=====================================\n"); Initialize(x,derive_y);

Page 145: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

138

n = GetData(x,&tolerance); error = FirstDerive_Function(n,x,derive_y,tolerance); ShowResult(error,n,x,derive_y); printf("\nProgram stop normally. Good bye.\n"); } void Initialize(double x[ARRAY_SIZE],double val[ARRAY_SIZE]) { int i =0; for (i=0; i < ARRAY_SIZE; i++) { x[i]=0; val[i]=0; } } int GetData(double xdata[ARRAY_SIZE],double *tol) { /* BE CAREFUL: data store in array from 0 to n-1 */ int i,j,numdata=0; char buffer[225]; do { printf("\nNumber of data ( 1 - %d) :",ARRAY_SIZE-1); gets(buffer); numdata = atoi(buffer); }while (numdata < 1 || numdata >= ARRAY_SIZE); for (i=1; i <= numdata; i++) { printf("\tX[%2d] = ",i);gets(buffer); xdata[i-1]= atof(buffer); } printf("\nTolerance ( default 0.001) :"); gets(buffer); *tol = atof(buffer); if (*tol < 0 || *tol < ZERO_APPROACH) *tol = 0.001; return numdata; } void ShowResult(int err,int n,double xval[ARRAY_SIZE],double yval[ARRAY_SIZE]) { int i;

Page 146: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

139

switch (err) { case 0 : { printf("\n"); for(i =0 ; i < n; i++ ){ printf("X[%2d] = %f ",i+1,xval[i]); /* printf("Y[%2d] = %f ",i+1,YourFunc(xval[i]));*/ printf(" 1 st Derivative = %13.7f \n",yval[i]); } break; } case 1 : { printf("\nTolerance must greater than zero\n"); break; } } /* switch (err) */ } /*================== Function Start here. ==========================*/ int FirstDerive_Function(int n,double xdata[ARRAY_SIZE],double result[ARRAY_SIZE],double tol) /* Function Description: Determine the first derivative of function at xdata[i]. The function must be given,the result of function stored in result[i]. User's Define : #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20e-16 Input : n -- number of x data xdata -- given data. begin from 0 to n-1. tol -- Tolerance result -- Area for keeping the result Output : the derivative of f(x) in result[i] Return : 0 -- if no error. 1 -- if tolerance < 0 *************************************************************************/ { double temp_x,h,num4; double r[ARRAY_SIZE][ARRAY_SIZE]; int i,j,k,row,col;

Page 147: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

140

if (tol < 0 ) return 1; for (i = 0 ; i < n; i++) { temp_x = xdata[i]; if ( fabs(temp_x) < ZERO_APPROACH ) h = sqrt(tol); else h = fabs(temp_x * sqrt(tol)); r[0][0] = (YourFunc(temp_x+h)-YourFunc(temp_x-h))/(2*h); row = 0; col = 0; /* Richardson Extrapolation starts here */ do { row += 1; h = h/2; r[row][col] = (YourFunc(temp_x+h)-YourFunc(temp_x-h))/(2*h); num4=1; for (j = 1; j<=row; j++) { num4 = num4*4; r[row][j] = (num4*r[row][j-1]-r[row-1][j-1])/(num4-1); } } while( (fabs(h) > ZERO_APPROACH) && (fabs(r[row][row]\ - r[row][row-1]) > tol)); result[i] = r[row][row]; /******** Richardson Extrapolation print out ************* printf(" Data no. %d\n",i+1); for(k = 0; k <=row; k++){ for (j = 0; j<=k; j++){ printf("r[%d][%d] = %e ,",k,j,r[k][j]); } printf("\n"); } *****************************************/ } return 0; } double YourFunc(double t)

Page 148: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

141

/* Write your function in here */ { return((9.81/0.3)*(t+exp(-0.3*t)/0.3 - (1/0.3))); } /*=======================================================*/ 4.3 การอนทเกรทโดยวธแบงเปนสวนเทา ๆ กน การอนพนธเปนการหาอตราการเปลยนแปลงของฟงกชน เชน y = f(x) dy/dx เปนการหาการเปลยนแปลงของ y เมอ ∆x มคาเขาใกลศนย การอนทเกรทเปนการทาตรงกนขามกบการหาอนพนธ เปนการรวมคาการเปลยนแปลงนอย ๆ เหลานเพอกลบไปสฟงกชนรปเดม

เมออนทเกรท f(x) ab

dx∫ เราอาจอธบายการอนทเกรทดงกลาว อยในรปของการหาพนทใตเสนโคง

y = f(x) ในชวง x = a ถง x = b วธการหาคาอนทเกรทโดยการประมาณทงายทสดคอพลอต กราฟ y = f(x) ตเปนตารางแลวนบจานวนตารางทอยใตเสนกราฟ พนททไดจะเปนคาโดย ประมาณของการอนทเกรทนน ถาขอมลทไดเปนตาราง คอบอกคา x, y มาหลาย ๆ คา มไดบอกฟงกชนอนมาให ตองการหาคาอนทกรลของขอมลชดนในชวงทกาหนดให เราตองนาขอมลเหลานไปหาฟงกชน พหนาม โดยใชวธหาพหนามของลากรองจ หรอของนวตนเสยกอน (ดบทท 4) แลวจงทาการ อนทเกรท ในหวขอการอนทเกรทเชงตวเลข 4.3 และ 4.4 น จะมงเฉพาะการอนทเกรททบอกคาฟงกชน และมขดจากดในการอนทเกรท (บอกคาขดจากดบนและลาง) ฟงกชนมคาตอเนองในชวงทจะอนทเกรท

Page 149: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

142

4.3.1 กฎสเหลยมคางหม (Trapezoidal rule)

รป 4.2 การอนทเกรททาไดโดยรวมพนทสเหลยคางหมเลก ๆ เมอจะอนทเกรทฟงกชน f(x) ในชวง x0 ถง xn ทาไดโดยการแบงชวงตงแต x0 ออกเปน ชวงเทา ๆ กน จานวน n ชวง ใหแตละชวงมความกวางเทากบ h แตละชวงของ h ลากเปนเสนตรงเชอมเพอแทนคาฟงกชนทแทจรง f(x) จะเกดเปนสเหลยมคางหมขนในแตละชวง h เมอรวมพนทสเหลยมคางหมทงหมด จะไดคาประมาณของการอนทเกรทฟงกชน f(x) เราแทนคาฟงกชนทแทจรงดวยเสนตรง ระยะ h ควรมคานอย ๆ เพอทจะทาใหเสนตรงนนทบกบเสนกราฟของฟงกชนทแทจรงมากทสดเทาทจะเปนไปได ใหเสนตรงทใชแทนเสนกราฟทแทจรง เขยนไดเปน F(x) ไดแก F(x) = A + Bx ....................(4.24) พจารณาเฉพาะชวง x0 ถง x1

f(x)dxx

x

0

1∫ ≅ F(x)dxx

x

0

1∫ = (A Bx)dxx

x

0

1+∫

= A(x x ) 12 B(x x )1 0 1

202− + − .................. (4.25)

ทจด x0 และ x1 เสนตรงตดกบเสนกราฟของ f(x) ดงนน A+Bx0 = F(x0) = f(x0) = y0 ....................(ข) และ A+Bx1 = F(x+1) = f(x1) = y1 ....................(ค) แกสมการ (ข) และ (ค) หาคา A, B จะได

A = x y x y

x x1 0 0 1

1 0

Page 150: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

143

= -y yx x

0 11 0

+

x1 - x0 คอระยะหางของแตละชวง = h แทนคา A, B ลงในสมการ (4.25) จะได

f(x)dxx

x h2 [y y ]

0

10 1∫ ≅ + = พนทสเหลยมคางหมในชวง x0 ถง x1

เมอคดพนทชวง x1 ถง x2 หาไดในทานองเดยวกน

f(x)dxx

x h2 [y y ]

0

12 1∫ ≅ +

นาพนททงหมดมารวมกนจะได

f(x)dxx

xn

0

∫ = [ ]h2 y 2y 2y ... y0 1 2 n+ + + ....................(4.26)

4.3.2 กฎของซมปสน 1

3 (Simpson’s 1

3 rule)

รป 4.3 แสดงการลากเสนโคงพาราโบลาเชอมแตละชวง การเชอมแตละชวงดวยเสนตรง โอกาสทเสนตรงจะทบกบเสนกราฟทแทจรงเปนไปไดนอย ถาเปลยนจากเสนตรงเปนเสนโคงพาราโบลา โอกาสทเสนโคงนจะซอนทบกบเสนกราฟทแทจรงจะมมากกวาเสนตรง เราจะใชสมการพาราโบลา F(x) = A+Bx+Cx2 เชอมโดยเสนกราฟ

Page 151: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

144

เสนหนงคลมสวนแบง 2 ชวง ขอเสยของวธนคอตองแบงชวง x0 ถง xn ออกเปน n ชวง โดยท n จะตองเปนจานวนค พจารณาชวงแรกระหวาง x0 ถง x2

f(x)dx F(x)dxx

x

x

x

0

2

0

2≅ ∫∫

≅ (A Bx Cx2 ) dxx

x

0

2+ +∫

ถาใหเสนตรงทลากผานจด x1 เปนเสนททาใหรปพาราโบลามลกษณะสมมาตร นนคอ ขดจากดของการอนทเกรทจะเปลยนเปน

(A Bx Cx2 )dxhh

+ +−∫ = 2hA

23 h3C+ ...................(ก)

จด x0 , x1 , x2 เปนจดบนเสนกราฟทแทจรงดงนน f(x0) = A - hB + h2C = y0 f(x1) = A + (O)B + O2C = y1 f(x2) = A + hB + h2C = y2 แกสมการหาคา A และ B แลวนาไปแทนคาลงในสมการ (ก) โดยท A = y1 จะได

C = 12h (y 2y 2y )2 0 1 2− +

f(x) dxx

x

0

2∫ = h

3 (y 4y y )0 1 2+ +

Page 152: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

145

เมอพจารณาทกชวงตงแต x0 ถง xn จะได

f(x)dxx

x

0

n∫ = h

3 (y 4y 2y 4y ... 2y 4y y )0 1 2 3 n 2 n 1 n+ + + + + − + − +

....................(4.27) 4.3.3 กฎของซมปสน 3

8 (Simpson’s 38 rule)

ถาใหเสนทเชอมระหวางจดเปนพหนามมองศาเทากบสาม (F(x) = A+Bx+Cx2+ Dx3) โดยเสนนผานจด x0, x1, x2, x3 คลมพนททแบงออกเปนสวน ๆ 3 ชองดวยกน ดงนน จานวนชองเลก ๆ ตงแต x0 ถง xn จงตองเปนจานวนท 3 หารไดลงตว เมออนทเกรท ตงแต x0 ถง x3 จะได

f(x) dxx

x

0

3∫ = 3

8 h (y 3y 3y y3)0 1 2 ++ +

อนทเกรทตงแต x3 ถง x6 จะได

f(x) dxx

x

0

3∫ =

38

(y3 + 3y4 + 3y5 + y6)

เมอรวมพนททกชวงตงแต x0 ถง xn จะไดเปนผลลพธของการอนทเกรท

f(x) dxx

x

0

n∫ =

38

h [(y0 + yn) + 3(y1 + y2 + y4 + y5 +...yn-1)

+ 2(y3 + y6 +... +yn-3) ................... (4.28) การนาฟงกชนเกยวกบอนทเกรทแบบแบงเปนชวงเทากนไปใชงาน จะมฟงกชนเกยวกบอนทเกรทแบบน 3 วธ สามารถเลอกใชฟงกชนใดฟงกชนหนง ในโปรแกรม 4.3 จะรวมฟงกชนทงสามอยในโปรแกรมเดยวกน และแสดงผลลพธทไดของแตละวธ ฟงกชน Trapezoidal ก. คาคงททตองนยาม : - ข. การผานคาอนพท และเรยกใชฟงกชน int Traperzoidal (int n, double lower, double upper, double* integration) n คอ จานวนชองเลก ๆ ทแบงในชวง x0 ถง x3

Page 153: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

146

lower คอ ขดจากดลางของการอนทเกรท upper คอ ขดจากดบนของการอนทเกรท integration คอ ผลลพธการอนทเกรทเกบไวในตวแปรน ค. ฟงกชนทเกยวของ double YourFunc (double x) ใสฟงกชนทตองการหาคาอนทเกรทไวทน ง. การสงคากลบ 0 ไมมขอผดพลาดใด ๆ เกดขน 1 เมอจานวนชวงเลก ๆ มคานอยกวาหรอเทากบศนย หรอขด จากดบนเทากบขดจากดลาง ฟงกชน Simpson 1/3 ก. คาคงททตองนยาม ข. การผานคาอนพท และเรยกใชฟงกชน int Simpson1_3 (int n, double lower, double upper double* integration) n คอ จานวนชวงซงแบงเปนพนทเลก ๆ lower คอ ขดจากดลางของการอนทเกรท upper คอ ขดจากดบนของการอนทเกรท integration คอ ผลลพธทไดจากการอนทเกรท ค. ฟงกชนทเกยวของ double YourFunc (double x) ง. การสงคากลบ 0 ไมมขอผดพลาดใด ๆ 1 เมอ n นอยกวาหรอเทากบศนย หรอ lower limit เทากบ upper limit ฟงกชน Simpson3_8 ก. คาคงททตองนยาม ข. การผานคาอนพท และเรยกใชฟงกชน

Page 154: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

147

int Simpson 3-8 (int n, double lower, double upper double* integration) n คอ จานวนชวงซงแบงเปนพนทเลก ๆ lower คอ ขดจากดลางของการอนทเกรท upper คอ ขดจากดบนของการอนทเกรท integration คอ ผลลพธทไดจากการอนทเกรท ค. ฟงกชนทเกยวของ double Your Func (double x) ง. การสงคากลบ 0 ไมมขอผดพลาดใด ๆ 1 เมอ n นอยกวาหรอเทากบศนย หรอ lower limit เทากบ upper limit ตวอยาง 4.3 โอกาสทจะพบอนภาคซงเคลอนท ณ ตาแหนง x ใด ๆ บรเวณหนง (ตงแต x= -α ถง x = +α) ซงม density function เปนเสนโคงปกต ดงน

f(x) 12 e

12 (

x)2

=−

π

µσ

เมอ µ คอ คาเฉลยของการกระจาย σ คอ คาความเบยงเบนมาตรฐาน จงหาความนาจะเปนจะพบอนภาคในตาแหนง 2 ≤ x≤ 5 เมอคาเฉลยคอ 4 และความเบยงเบนมาตรฐาน = 0.5 วธทา หาความนาจะเปนทจะพบอนภาคในชวง 2 ≤ x≤ 5 ทาไดโดยอนทเกรท

P = f(x) dxx 2

x 5

=

=∫ = 1

0 5 22

5 2 40.5

2

. ×∫ −−⎛

⎝⎜⎜

⎠⎟⎟

π e dxx

ผลลพธจากโปรแกรม Integrat.C จะเปนดงน

Page 155: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

148

Finding the Integration using Several Methods. ================================== Input the Lower Limit of integration : 2 Input the Upper Limit of integration : 5 Input the number of Interval : 100 The Result of integration by Trapezoidal rule = 0.977186 The Result of integration by Simpson's 1/3 rule = 0.977218 The Result of integration by Simpson's 3/8 rule = 0.977218 Program stop normally. Good bye. ในโปรแกรมยอย YourFunc ตองเพมประโยคดงตอไปน double YourFunc (double x) { double c; c = 0.5*sqrt(2*3.1415926); return( exp(-0.5*pow(((x-4)/0.5),2))/c); } รายละเอยดโปรแกรม Integrat.C /* * Program 4.3 Integrat.C * Purpose: Demonstrate how to find the Integration of given function * Using Trapezoidal Rule, Simpson's Rule. * Author : Wachara Rodsumrid. * Office : Dept of Physics. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 24 October 95 **************************************************************/ #include <stdio.h> #include <math.h> double YourFunc(double); double GetLowerLimit(void); double GetUpperLimit(void); int GetSubinterval(void);

Page 156: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

149

int Trapezoidal(int,double,double,double*); int Simpson1_3(int,double,double,double*); int Simpson3_8(int,double,double,double*); void TrapezoidalResult(int,double*); void Simpson1_3Result(int,double*); void Simpson3_8Result(int,double*); void main() { double *result1,*result2,*result3; double lower_limit, upper_limit; int n=0 /* number of subinterval */; int error; char msg[150],ans[1]; clrscr(); printf("\t\tFinding the Integration using Several Methods.\n"); printf ("\t\t============================================\n"); lower_limit = GetLowerLimit(); upper_limit = GetUpperLimit(); n = GetSubinterval(); error = Trapezoidal(n,lower_limit,upper_limit,result1); TrapezoidalResult(error,result1); error = Simpson1_3(n,lower_limit,upper_limit,result2); Simpson1_3Result(error,result2); error = Simpson3_8(n,lower_limit,upper_limit,result3); Simpson3_8Result(error,result3); printf("\nProgram stop normally. Goodbye.\n"); /* There is something that I should remark here. If you assign a variable for keeping the result (e.g. assign 'result' instead of result1,result2,result3) I faced with 'Null assign pointer'problem. */ } double GetLowerLimit() {

Page 157: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

150

char buffer[255]; printf("\n\tInput the Lower Limit of integration : "); gets(buffer); return(atof(buffer)); } double GetUpperLimit() { char buffer[255]; printf("\n\tInput the Upper Limit of integration : "); gets(buffer); return(atof(buffer)); } int GetSubinterval() { char buffer[255]; printf("\n\tInput the number of Interval : "); gets(buffer); return(atoi(buffer)); } void TrapezoidalResult(int err,double *result) { int i; switch (err) { case 0 : { printf("\nThe Result of integration by Trapezoidal rule = %f\n",*result); break; } case 1 : { printf("\nThe number of interval must greater than zero\n"); printf("or Lower limit equals to upper limit.\n"); break; } } /* switch (err) */ } void Simpson1_3Result(int err,double *result) {

Page 158: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

151

int i; switch (err) { case 0 : { printf("\nThe Result of integration by Simpson's 1/3 rule = %f\n",*result); break; } case 1 : { printf("\nThe number of interval must greater than zero\n"); printf("or Lower limit equals to upper limit.\n"); break; } } /* switch (err) */ } void Simpson3_8Result(int err,double *result) { int i; switch (err) { case 0 : { printf("\nThe Result of integration by Simpson's 3/8 rule = %f\n",*result); break; } case 1 : { printf("\nThe number of interval must equal or greater than 1\n"); printf("or Lower limit equals to upper limit.\n"); break; } } /* switch (err) */ } /*================== Function Start here. ==========================*/ int Trapezoidal(int n,double lower, double upper,double *integration) /* Function Description: Compute the integral of given function from lower limit to upper limit using the trapezoidal rule. User's Define Variable : None User's Define Function : double YourFunc( double ); Input : n -- number of interval for integration lower -- lower limit. upper -- upper limit.

Page 159: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

152

integration -- variable for keeping the result Output : the integration of f(x) in integration. Return : 0 -- if no error. 1 -- if n < 1 or lower limit = upper limit ***********************************************************************/ { double h,x,sum,SumAtEnd; int i; if (n < 1 ) return 1; h = (upper - lower)/n; if ( h ==0 ) return 1; x = lower; sum = 0; for ( i =1; i <= n-1; i++) { x = x + h; sum = sum + YourFunc(x); } SumAtEnd = YourFunc(upper)+YourFunc(lower); *integration = h*(SumAtEnd + 2* sum)/2; return 0; } /* =============== The End of Trapezoidal rule =============*/ int Simpson1_3(int n,double lower, double upper,double *integration) /* Function Description: Compute the integral of given function from lower limit to upper limit using the Simpson's 1/3 rule. User's Define Variable : None User's Define Function : double YourFunc( double ); Input : n -- number of interval for integration lower -- lower limit. upper -- upper limit. integration -- variable for keeping the result Output : the integration of f(x) in the "integration". Return : 0 -- if no error. 1 -- if n < 0 or lower limit = upper limit ***********************************************************************/

Page 160: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

153

{ double h,x,sum,SumAtEnd,OddSum,EvenSum; int i,EvenN; if (n <= 0 ) return 1; EvenN = 2*n; h = (upper - lower)/EvenN; if ( h ==0 ) return 1; x = lower; OddSum = EvenSum = 0; for ( i =1; i < EvenN; i++) { x = x + h; if ( i%2) OddSum += YourFunc(x); else EvenSum += YourFunc(x); } SumAtEnd = YourFunc(upper) + YourFunc(lower); *integration = h*(SumAtEnd + 2*EvenSum +4*OddSum)/3; return 0; } /* =============== The End of Simpson's 1/3 rule =============*/ int Simpson3_8(int n,double lower, double upper,double *integration) /* Function Description: Compute the integral of given function from lower limit to upper limit using the Simpson's 3/8 rule. User's Define Variable : None User's Define Function : double YourFunc( double ); Input : n -- number of interval for integration lower -- lower limit. upper -- upper limit. integration -- variable for keeping the result Output : the integration of f(x) in the "integration". Return : 0 -- if no error. 1 -- if n < 0 or lower limit = upper limit ************************************************************************/

Page 161: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

154

{ double h,x,sum,SumAtEnd,Mulby3Sum,OtherSum; int i,ThreeXN; if (n <= 0 ) return 1; ThreeXN = 3*n; h = (upper - lower)/ThreeXN; if ( h ==0 ) return 1; x = lower; Mulby3Sum = OtherSum = 0; for ( i =1; i < ThreeXN; i++) { x = x + h; if ( i%3) OtherSum += YourFunc(x); else Mulby3Sum += YourFunc(x); } SumAtEnd = YourFunc(upper) + YourFunc(lower); *integration = 3*h*(SumAtEnd + 3*OtherSum +2*Mulby3Sum)/8; return 0; } /* =============== The End of Simpson's 3/8 rule =============*/ double YourFunc(double x) /* Write your function which you want to intergrate in here */ { return(sqrt((6.38e6+x)/(6.38e6-x))) ; } /*=======================================================*/

Page 162: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

155

4.4 การอนทเกรทแบบเกาส-เลอจองด (Legendre-Gaurs Quadrrature) วธนมลกษณะซบซอนกวาการอนทเกรทโดยวธใชกฎสเหลยมคางหม หรอวธของซมปสน แตใหผลลพธใกลเคยงคาจรงมากกวา และไมตองแบงชวงของการอนทเกรทใหเปนสวนเลก ๆ ทมขนาดเทากน แตขนกบการกระจายของคาแอบซสซา (x) ในชวงขดจากดบนและลาง เราจงตองกาหนดจานวนแอบซสซาในการอนทเกรท วธนใช orthogonal polynomial ทเรยกวา Legendre polynomial ใชประมาณคาในการอนทเกรท โดยทวไปยงใชโพลโนเมยลทมองศาสงมากขนเทาใด ผลลพธทไดกจะใกลคา แทจรงมากขนเพยงนน แตคอมพวเตอรจะตองใชเวลาในการคานวณมาก

เมอจะอนทเกรท f(x) dx Iab

=∫ กาหนดใหผลลพธของการอนทเกรทไดคาประมาณอยในรปของผลบวกของฟงกชน I = c1 f(x1) + c2 f(x2) + c3 f(x3) + ... + cn f(xn) .................... (4.29) เรยก c1 , c2 ... cn วาเปนสมประสทธของฟงกชน, x1 , x2 ... xn คอตาแหนงทจะใชหาคาการ อนทเกรท เรยกวา node การอนทเกรททหาคาโดยประมาณทงายทสด I ≅ c1 f(x1) .................... (4.30) จากสมการท (4.30) จะมตวแปรเกยวของ 2 ตว คอ c1 และ x1 ถงแมฟงกชน f(x) จะมรปรางอยางไรกตาม เราสามารถอนทเกรทดวยวธนไดเสมอ ฟงกชนทงายทสดสาหรบ f(x) คอ f(x) = 1 และ f(x) = x เมอ f(x) = 1

1dxab∫ = b - a = c1 (1) .................... (ก)

เมอ f(x) = x

xdxab∫ = b a

22 2− = c1 x1 .................... (ข)

จากสมการ (ก) และ (ข) จะไดคา c1 และ x1 ดงน c1 = b - a

x1 = b a2+

Page 163: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

156

แทนคา c1 และ x1 ลงในสมการ (2) จะไดเปนสตรทงายทสดของการอนทเกรทโดยวธของเกาส คอ

f(x) dxab∫ = (b - a) f ( )b a

2+ .................... (4.31)

สามารถเขยนเปนภาพไดดงรป

รป 4.5 แสดงการอนทเกรทโดยใชวธของเกาส-เลอจองด การหาอนทเกรทวธนไมไดเกยวของกบคาฟงกชนท x = a หรอ x = b เลย แตจะใชคาฟงกชนตรงตาแหนงทเปนคาเฉลยของ a และ b และถาอนทเกรทโดยประมาณคาใหถงเทอมท 2 หรอสงกวา จะไดระบบสมการทไมเปนเชงเสน ตาแหนงทจะใชหาฟงกชนอาจจะกระจายไปอยนอกเขตของขดจากด จงตองทาการจากดเขตของขดจากดบนและลางของการอนทเกรทใหอยในชวง -1 ถง 1 เรมตนดวยเปลยนตวแปร x ใหอยในรปตวแปรตวใหม สมมตวาเปน x โดยท x = A + Bu .................... (4.32) กาหนดให x = a แลว u = -1 x = b แลว u = +1 แทนคา x และ u ลงในสมการ (4.32) จะได

a = A-B หรอ A = 12 (b+a)

b = A+B หรอ B = 12 (b-a)

แทนคา A และ B จะได

x = 12 (b-a) + 1

2 (b+a) .................... (4.33)

Page 164: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

157

ดฟเฟอเรนเชยลสมการ (4.33) จะได

dx = (b a)2 du− .................... (4.34)

ดงนน เมอเปลยนตวแปรแลว รปรางการอนทเกรทจะเปลยนไป ดงน

I = f(x) dxab∫ =

= [ ](b a)2 f (b a)

2(b a)

2 u du1

1− +

+−

−∫

.................... (4.35) ถาประมาณคาการอนทเกรทแบบเกาส-เลอจองด จนถงเทอมท 2

I = f(u) du1

1

−∫ = c1 f(u1) + c2 f(u2) .................... (4.36)

จะมตวแปรไมทราบคาอย 4 ตวคอ c1, c2, u1 และ u2 เราสามารถลดตวแปรทไมทราบคาใหเหลอเพยง 3 ตวได โดยการกาหนดคา u1, u2 ใหมคาเทากน แตตางเครองหมายกน กาหนดให u1 = -H u2 = H

รป 4.6 การอนทเกรทแบบเกาส-เลอจองดโดยประมาณคาถงเทอมท 2

Page 165: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

158

สมการ (4.36) ใชไดเสมอไมวา f(u) จะมรปอยางไร พจารณา f(u) มคาเปน 1, u และ u2 เมอ f(u) = 1

du1

1

−∫ = 2 = c1 + c2 .................... (ก)

เมอ f(u) = u

u du1

1

−∫ = 0 = c1 (-H) + c2 (H) .................... (ข)

เมอ f(u) = u2

u2 du1

1

−∫ = 2

3 = c1 H2 + c2 H2 .................... (ค)

จากสมการ (ก), (ข) และ (ค) แกสมการหาคา c1 , c2 และ H จะได

H = 13

= c1 = c2 = 1

ในกรณทใชการประมาณคาถงเทอมท 2 ผลลพธของการอนทเกรทแบบเกาส-เลอจองดคอ

I = f(u) du1

1

−∫ = ( ) ( )f 1

3 f 13

−+ + .................... (4.37)

สมการนหมายความวา ไมวาเราจะอนทเกรทฟงกชนใดกตาม (f(u)) ในชวงขดจากด

ตงแต -1 ถง +1 จะมคา (โดยประมาณ) เทากบนาฟงกชนนนมาแทนคาท u = -13

และ

u = +13

แลวนามาบวกกน

Page 166: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

159

ตวอยาง 4.4 จงหาผลลพธของการอนทเกรท

I = −∫1

1

(x2+1) dx

วธทา f(x) = x2+1 จากสมการ (4.37)

I = ( ) ( )−+ + +

13 1 1

3 12 2

= 13 1 1

3 1+ + + = 72

คาทแทจรง คอ

−∫1

1

(x2+1) dx = x33 x+

+

1

1

= ( ) ( )( )13

13 1 - -1+ + = 7

2 ซงผลลพธทไดตรงกบการประมาณคาของสมการ (4.37) ถาเปลยนตวแปร u ใหกลบเปนตวแปร x เหมอนเดม

I = ab∫ f(x) dx = (b-a)[0.5 f(x1) + 0.5 f(x2)]

x1 = 12 (b+a) - (b a)

213

−×

= 0.2113248654 b + 0.7886751346 a

x2 = (b a)2

(b a)2

13

++

−×

= 0.7886751346 b + 0.2113248654 a ถาตองการประมาณคาการอนทเกรทแบบเกาส-เลอจองด จนถงเทอมท 3 กใชวธการเชนเดยวกน คอหาคาสมประสทธ c1, c2 และ c3 โดยกาหนด node ทใชหาคาฟงกชนทตาแหนง -H, O, และ H

I = f(u) du−∫

1

1

= c1 f(-H) + c2 f(O) +c3 f(H) .................... (4.38)

เมอ f(u) = I

du−∫

1

1

= 2 = c1 + c2 + c3 .................... (ก)

Page 167: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

160

เมอ f(u) = u

u du−∫1

1

= 0 = -c1H + c2(O) + c3H .................... (ข)

เมอ f(u) = u2

u2 du−∫1

1

= 23 = -c1H2 + c2(O) + c3H2 .................... (ค)

เมอ f(u) = u3

u3 du−∫

1

1

= 0 = -c1H3 + c2(O) + c3H3 .................... (ง)

เมอ f(u) = u4

u4 du−∫

1

1

= 25 = -c1H4 + c2(O) + c3H4 .................... (จ)

จากสมการ (ก), (ข), (ค),(ง) และ (จ) จะได

H = 35 , c1 = 5

9 , c2 = 89 , c3 = 5

9 แทนคาลงในสมการ (4.38) จะได

I = f(u)du−∫1

1

= 59 f 3

589 f(0) 5

9 f 35− + +

⎛⎝⎜ ⎞

⎠⎟ ⎛

⎝⎜ ⎞

⎠⎟

.................... (4.39) เมอเปลยนตวแปร u ใหเปนตวแปร x

I = f(x) dxa

b

∫ = (b-a) [ ]518 f(x1) 4

9 f(x2 ) 518 f(x3)+ +

โดยท x1 = 0.1127016654 b + 0.8872983345 a x2 = 0.5 b + 0.5 a x3 = 0.8872983345 b + 0.1127016654 a

Page 168: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

161

ถาตองการประมาณคาการอนทเกรทจนถงเทอมท 4 หรอสงกวา กสามารถทาไดโดยวธการเดยวกน นนคอ ตองหาคาสมประสทธ c1, C2 ... และหาตาแหนง node ทจะใชแทนคาฟงกชน โดยขดจากดของการอนทเกรทอยในชวง -1 ถง 1 ให N เปนจานวนเทอมของฟงกชน คาสมประสทธและตาแหนงทจะใชแทนคาฟงกชน (x1) เพอจะประมาณคาอนทเกรท จะเปนดงน

ตาราง 4.1 แสดงตาแหนงและคาสมประสทธสาหรบการอนทเกรทท N ใด ๆ

N ui ci 2 0.5773502691 1 3 0 0.8888888888 0.7745966692 0.5555555555 4 0.3399810435 0.6521451548 0.8611363115 0.3478548451 5 0 0.5688888888 0.5384693101 0.4786286704 0.9061798459 0.2369268850 6 0.2386191860 0.4679139345 0.6612093864 0.3607615730 0.9324695142 0.1713244923 8 0.183434642 0.362683783 0.525532410 0.313706646 0.796666478 0.222381034 0.960289857 0.101228536

10 0.148874339 0.295524225 0.433395394 0.269266719 0.679409568 0.219086363 0.865063367 0.149451349 0.973906528 0.066671344

Page 169: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

162

การเปลยนตวแปร x ใหเปน u และจากดขอบเขตของการอนทเกรทอยในชวง -1 ถง 1 นน เราสามารถใชพหนามเลอจองด (Legendre’s Polynomial) หาตาแหนง node สาหรบการ อนทเกรท พหนามของเลอจองด เปนพหนามทเปนคาตอบของสมการดฟเฟอเรนเชยลทรจกกนดในทางฟสกส คอ (1-x2) ′′y -2xy′′+ l (l+1) y = 0 จะพบสมการนเมอเรยนวชากลศาสตรควอนตม ในเรองอเลกตรอนโคจรรอบ ๆ อะตอม และในวชาแมเหลกไฟฟาในบททกลาวถงคลนแมเหลกไฟฟาในระบบโคออรดเนตแบบทรงกลม พหนามเลอจองดอนดบท n เขยนแทนไดดวยสญลกษณ Pn(x) สามารถหาพหนามเลอจองดอนดบท n ไดจากสตรของโรดรเกส (Rodrigues’s formula)

Pn(x) = 12 n!

d (x 1)dxn

n 2 nn− .................... (4.40)

คาจากสมการของพหนามเลอจองดจะอยระหวาง -1 ถง 1 โดยสมมาตรทจด x = 0 พหนามเลอจองด อนดบท 1 : P1(x) = x

พหนามเลอจองด อนดบท 2 : P2(x) = 32 x2 1

2−

จะไดรากสมการคอ ± 13

พหนามเลอจองด อนดบท 3 : P3(x) = 5x3 3x2−

จะไดรากสมการคอ 0, ± 0.77459667

พหนามเลอจองด อนดบท 4 : P4(x) = 358 x4 15

4 x2 38− +

จะไดรากสมการคอ ± 0.33998104 และ ± 0.86113631 ซงเปนทมาของตาราง 4.1 นนเอง

ตวอยาง 4.5 จงอนทเกรท e dxx20.2

1.5

−∫ โดยวธของเกาส แบบ 3 จด

วธทา เปลยนตวแปร x และขดจากดใหอยในชวง -1 ถง1

x = (1.5 0.2)u (1.5 0.2)2

− + + = 0.65u + 0.85 รปการอนทเกรทจะเปน

Page 170: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

163

I = 1.5 0.22 e (0.65u 0.85) du

2

1

1− − +

−∫ .............(ก)

จากตาราง การอนทเกรทแบบเกาส c1 = c3 = 0.55555555, c2 = 0.88888889 ตาแหนง node ทจะใชแทนคาในฟงกชน คอ u1 = -0.77459667, u2 = 0 u3 = +0.77459667 แทนคาลงในการ (ก) I = [ ] [ ]{0.55. . . e− + − ++ −0 65 0 774 0 85 0 65 0 0 852 2. ( . . . . ) . . ( ) .0.888. . . e + [ ] }0.555. . . e− +0 65 0 774 0 85

2. ( . . . . ) . = 0.6586 คาทแทจรงของปญหาขอนคอ 0.65882 การนาฟงกชน GaussQuadrature ไปใชงาน ก. คาคงททตองนยาม : ไมม ข. การผานคาอนพท และเรยกใชฟงกชน int GaussQuadrature(int n,double lower, double upper,double *integration) n คอ จานวน node ของการอนทเกรทมคาตงแต 2 ถง 6 lower คอ ขดจากดลางของการอนทเกรท upper คอ ขดจากดบนของการอนทเกรท integration คอ ผลลพธการอนทเกรทเกบไวในตวแปรน ค. ฟงกชนทเกยวของ double YourFunc (double x) ใสฟงกชนทตองการหาคาอนทเกรทไวทน ง. การสงคากลบ 0 ไมมขอผดพลาดใด ๆ เกดขน 1 เมอจานวน node นอยกวา 2 หรอมากกวา 6 หรอ ขดจากดบน เทากบขดจากดลาง

Page 171: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

164

รายละเอยดโปรแกรม Gauss_QD.C /* * Program 4.4 Gauss_QD.C * Purpose: Demonstrate how to find the Integration of given function * by Using Gauss-Legendre Quadrature. * Author : Wachara Rodsumrid. * Office : Dept of Physics. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 6 November 95 **************************************************************/ #include <stdio.h> #include <math.h> double YourFunc(double); double GetLowerLimit(void); double GetUpperLimit(void); int GetNumberofNode(void); int GaussQuadrature(int,double,double,double*); void IntegrationResult(int,double*); void main() { double *result; double lower_limit, upper_limit; int n=0 /* number of point to be used for integrate */; int error; clrscr(); printf("\t\tFinding the Integration using Gauss Quadrature.\n"); printf ("\t\t==============================================\n"); lower_limit = GetLowerLimit(); upper_limit = GetUpperLimit(); n = GetNumberofNode(); error = GaussQuadrature(n,lower_limit,upper_limit,result);

Page 172: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

165

IntegrationResult(error,result); printf("\n\nYour work was done. Goodbye.\n"); } double GetLowerLimit() { char buffer[255]; printf("\n\tInput the Lower Limit of Integration : "); gets(buffer); return(atof(buffer)); } double GetUpperLimit() { char buffer[255]; printf("\n\tInput the Upper Limit of Integration : "); gets(buffer); return(atof(buffer)); } int GetNumberofNode() { char buffer[255]; printf("\n\tInput the number of Gauss point to be used (from 2 to 6) : "); gets(buffer); return(atoi(buffer)); } void IntegrationResult(int err,double *result) { int i; switch (err) { case 0 : { printf("\nThe Result of Integration using Gauss Quadrature = %f",*result); break; } case 1 : { printf("\nThe number of node is not between 2 to 6.\n"); printf("or Lower limit equals to upper limit.\n"); break;

Page 173: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

166

} } /* switch (err) */ } /*================== Function Start here. ==========================*/ int GaussQuadrature(int n,double lower, double upper,double *integration) /* Function Description: Compute the integral of given function from lower limit to upper limit using the Gauss Quadrature method. User's Define Variable : None User's Define Function : double YourFunc( double ); Input : n -- number of node for integration from 1 to 6 lower -- lower limit. upper -- upper limit. integration -- variable for keeping the result Output : the integration of f(x) in integration. Return : 0 -- if no error. 1 -- if 6 < n < 2 or lower limit = upper limit ************************************************************************/ { double c[7] ; /* Coefficient of function */ double x[7],u[7] ; /* node point of function */ double fvalue; int i,j; if (n < 2 || n > 6 ) return 1; if ((upper - lower) == 0) return 1; switch (n) { case 1 : break; case 2 : { u[2] = 0.5773502691; c[1] = c[2] = 1; u[1] = -u[2]; break; } case 3 : { u[2] = 0; u[3] = 0.7745966692; u[1] = -u[3]; c[2] = 0.8888888888;

Page 174: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

167

c[1] = c[3] = 0.5555555555; break; } case 4 : { u[3] = 0.3399810435; u[2] = -u[3]; u[4] = 0.8611363115; u[1] = -u[4]; c[3] = 0.6521451548; c[4] = 0.3478548451; c[1] = c[4]; c[2] = c[3]; break; } case 5 : { u[3] = 0; u[4] = 0.5384693101; u[5] = 0.9061798459; u[1] = -u[5]; u[2] = -u[4]; c[3] = 0.5688888888; c[2] = c[4] = 0.4786286704; c[1] = c[5] = 0.2369268850; break; } case 6 : { u[4] = 0.2386191860; u[5] = 0.6612093864; u[6] = 0.9324695142; u[1] = -u[6]; u[2] = - u[5]; u[3] = -u[4]; c[4] = 0.4679139345; c[5] = 0.3607615730; c[6] = 0.1713244923; c[1] = c[6]; c[2] = c[5]; c[3] = c[4]; break; } } /* switch (n) */ /* ******* Used for studying or debuging program ******* printf( "------------------------------------------------------------------ \n" ); printf( " Term Coef node x f(x) \n" ); printf( "------------------------------------------------------------------ \n" ); ********************************************************/ for( i = 1; i <= n; i++ ){ x[i] = 0.5*( (upper + lower) + (upper - lower)*u[i]);

Page 175: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

168

} *integration = 0; for( i = 1; i <= n; i++ ){ fvalue = YourFunc(x[i]); /* Calculate functional values */ *integration += fvalue*c[i]; /* printf( " %3d %12.5e %12.5e %12.5e %12.5e\n",i,c[i],u[i], x[i], fvalue); */ } *integration *= (upper - lower)/2; /* Don't forget dx = (b-a)du/2 */ return 0; } /* =============== The End of Gauss Quadrature =============*/ double YourFunc(double x) /* Write your function which you want to intergrate in here */ { return(2*sqrt(1-(x-1)*(x-1))); } /*=======================================================*/ 4.5 การประมาณคาอนทเกรทโดยใชวธมอนตคารโล มอนตคารโล (Monte Carlo) เปนวธการทางคณตศาสตรทอาศยตวเลขแบบสม (Random number) มาใชในการแกปญหาทไมสามารถใชวธการทว ๆ ไปมาใชได คาตอบของปญหาตองไมแปรเปลยนตามเวลา (deterministic) ความถกตองของคาทไดจะมากนอยเพยงใดขนอยกบจานวนครงทสมตวเลข จานวนครงยงมากเทาใดคาทไดกจะเขาใกลคาแทจรงมากขนเทานน วธนเหมาะทจะใชคอมพวเตอรชวยในการแกปญหา เพราะภาษาทใชในคอมพวเตอรทวไปจะมฟงกชนสมตวเลขเตรยมพรอมสาหรบเรา การคานวณซาหรอเลอกสมตวเลขหลาย ๆ ครง จะกระทาไดสะดวกและเรวกวาแกปญหาดวยมอ วอน นอยมานน (Von Neumann) และอลาม (Ulam) ไดนาวธการนมาใชและตงชอวา มอนตคารโล (ตามชอเมองทอยทางใตของประเทศฝรงเศส ซงมชอเสยงในดานการพนน) ใชชอนเปนรหสลบในการสรางระเบดปรมาณครงแรกทลอสอลามอส (Los Alamos) สหรฐอเมรกา ในการออกแบบเตาปฏกรณปรมาณนนจะตองรลกษณะการเคลอนทของนวตรอนทเกดจาก fission

Page 176: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

169

ในตวกลางทเปนของแขงชนดตาง ๆ เสยกอน ถาจะหาคาตอบนโดยวธทดลองจะเปนอนตรายและเสยคาใชจายสงมาก และถาใชวธวเคราะหกยากทจะหาคาตอบ จงนาปญหานมาแกโดยเลยนแบบสถานการณจรงๆ (simulation) ในคอมพวเตอรอาศยเลขสมชวยหาคาตอบ ตอมาไดนาวธมอนตคารโลไปใชแกปญหาทางฟสกสอยางแพรหลาย โดยเฉพาะในกลศาสตรสถต เชน ปญหาการกระจายของแมกซเวล โบลทซมนน การกระจายของเฟอรม-ดแรก การกระจายของ โบส-ไอนสไตน นาไปแกปญหาการหาปรมาตรหรอพนททมรปทรงแปลก ๆ แตในทนจะนาวธมอนตคารโลมาหาผลลพธของอนทกรลจากดเขตของ y = f(x) ในชวงขดจากด a กบ b ตวเลขสมทจะใชวธมอนตคารโลตองมการแจกแจงเปนแบบเสมอภาค (uniform) ตวเลขทกตวมโอกาสจะไดรบการสมเทา ๆ กน มคาอยไมตากวา 0 และไมเกน 1 เมอตองการหาพนทใตเสนโคง y =f(x) ในชวง a กบ b ใหทาตามขนตอนดงน

รป 4.7 แสดงวธการอนทเกรทโดยใชวธมอนตคารโล 1) สรางสเหลยมผนผา สง h กวาง (b-a) สเหลยมผนผานคลมพนทใตเสนโคงทตองการจะหา ให A เปนพนทใตเสนโคง B เปนพนทสเหลยมผนผา โดยท B = (b-a) f(a) เมอ f(a) > f(b) = (b-a) f(b) เมอ f(b) > f(a) และ N เปนจานวนจดในสเหลยมผนผา M เปนจานวนจดทอยภายในพนทใตเสนโคง 2) กาหนดจานวนครงในการสมตวเลข สมมตใหเปน N ครง จานวนตวเลข N คานจะอยในพนทรปสเหลยมผนผา

Page 177: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

170

3) เลอกตวเลขสมมาครงละ 2 คา เพอสรางจดในสเหลยมผนผา โดยคาแรกใชหาวาจดนอยหางจากแกน x เทาใด และคาทสองใชหาวาจดเดยวกนนอยหางจากแกน y เทาใด ให p เปนตวเลขสมคาแรก q เปนตวเลขสมคาทสอง ตาแหนงของจดครงท I ใด ๆ หาไดจาก xi = a + (b-a) p yi = q f(a) เมอ f(a) > f(b) = q f(b) เมอ f(b) > f(a) 4) นาคา xi ไปแทนคาในสมการ y = f(x) ถาไดคา y มคามากกวา yi ทไดจาก ขอ 3 แสดงวาจดนอยนอกพนทใตเสนโคง (ไมตองเพมคา M) ถา y มคานอยกวาหรอเทากบ yi แสดงวาจดนอยใตพนทเสนโคง ใหเพมคา M อก 1 คา 5) สมตวเลข (ครงละ 2 คา) จนครบ N ครง ตามทตองการ นาไปคานวณหาพนทใตเสนโคง (A) จากสตร

A = BMN ................... (4.41)

การนาฟงกชน Monte Carlo Integration ไปใชงาน ก. คาคงททตองนยาม ไมม

ข. ไฟล Include ทใช Stdio.h, stdlib.h, math.h , time.h

ค. การผานคาอนพท และเรยกใชฟงกชน int MonteCarloIntegration (long n, double lower double upper double* integration) n คอ จานวนจดทเกดจากการสม lower คอ ขดจากดลางของการอนทเกรท upper คอ ขดจากดบนของการอนทเกรท integration คอ ผลลพธทไดจากการอนทเกรท

ง. ฟงกชนทเกยวของ double YourFunc (double x)

Page 178: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

171

จ. การสงคากลบ 0 ไมมขอผดพลาดใด ๆ 1 ขดจากดลางมากกวาหรอเทากบขดจากดบน รายละเอยดของโปรแกรม Monte.C มดงน /* * Program 4.5 Monte.C -- Monte Carlo Integration * Purpose: Demonstrate how to find the Integration of given function * by Using Monte Carlo method. * Author : Wachara Rodsumrid. * Office : Dept of Physics. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 5 December 95 **************************************************************/ #include <stdio.h> #include <math.h> #include <stdlib.h> double YourFunc(double); double GetLowerLimit(void); double GetUpperLimit(void); int MonteCarloIntegration( long, double,double,double*); long GetNumberofRandomPoint(void); void IntegrationResult(int,double*); void main() { double *result; double lower_limit, upper_limit; long n; /* Number of times for randomizing */ int error; clrscr(); *result = 0;

Page 179: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

172

printf("\t\tFinding the Integration using Monte Carlo Method.\n"); printf ("\t\t==============================================\n"); lower_limit = GetLowerLimit(); upper_limit = GetUpperLimit(); /* printf("result = %f\n",*result); */ n = GetNumberofRandomPoint(); error = MonteCarloIntegration(n,lower_limit,upper_limit,result); IntegrationResult(error,result); printf("\n\nYour work was done. Good bye.\n"); } double GetLowerLimit() { char buffer[255]; printf("\n\tInput the Lower Limit of Integraiton : "); gets(buffer); return(atof(buffer)); } double GetUpperLimit() { char buffer[255]; printf("\n\tInput the Upper Limit of Integraiton : "); gets(buffer); return(atof(buffer)); } long GetNumberofRandomPoint() { char buffer[255]; printf("\n\tInput the number of random point : "); gets(buffer); return(atol(buffer)); } void IntegrationResult(int err,double *result) { int i; switch (err) {

Page 180: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

173

case 0 : { printf("\nThe Result of Integraiton using Monte Carlo Method = %f\n",*result); break; } case 1 : { printf("\n Can't find the answer.\n The lower limit is greater than or equal to the upper limit\n"); break; } } /* switch (err) */ } /*================== Function Start here. ==========================*/ int MonteCarloIntegration(long n,double lower, double upper,double *integration) /* Function Description: Compute the integral of given function from lower limit to upper limit using Monte Carlo Method. Include File : Stdio.h, stdlib.h, math.h, time.h User's Define Variable : None User's Define Function : double YourFunc( double ); Input : n -- number of random point. lower -- lower limit. upper -- upper limit. integration -- variable for keeping the result Output : the integration of f(x) in integration. Return : 0 -- if no error. 1 -- lower limit greater or equal to upper limit ************************************************************************/ { long i,j; double h,h1,h2,x,y,tempy; double fraction; long PointUnderCurve; if ( lower >= upper) return 1; h1 = YourFunc(lower); h2 = YourFunc(upper); if ( h2 > h1)

Page 181: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

174

h = h2; else h = h1; PointUnderCurve = 0; randomize(); for (i = 1 ; i <= n; i++) { x = lower +(upper - lower)*random(10)/10; tempy = h*random(10)/10; y = YourFunc(x); if (tempy <= y ) PointUnderCurve +=1; } fraction = (double) PointUnderCurve/(double)n; /* printf("%f \n",fraction); */ *integration = fraction * (upper - lower) * h; printf(" %f\n",*integration); return 0; } /* =============== The End of Monte Calo Integration=============*/ double YourFunc(double x) /* Write your function which you want to intergrate in here */ { return(x*x*x/(exp(x)-1)); } /*=======================================================*/

Page 182: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

175

ตวอยาง 4.6 จงหาคา tan(x) dx∂

π / 4∫

วธทา คาทแทจรงคอ

= tan(x) dx∂

π / 4∫

π/4 = ln sec x 0 = ln sec รป 4.8 ตวอยาง 4.6 = ln 2

= 0.34657 เมอใชวธมอนตคารโล โดยใหคานวณจดทเกดจากตวเลขสมตาง ๆ กนจะไดผลลพธดงน

จานวนจดทเกดจากการสม ผลลพธทได 100 0.314161 500 0.362856 1000 0.356576 5,000 0.54374 10,000 0.355395 50,000 0.348782 100,000 0.347981

π4

Page 183: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

176

4.6 การประยกตการหาอนพนธและการอนทเกรทเชงตวเลขแกปญหาทางฟสกส ตวอยาง 4.7 กฎการเยนตวของนวตน เขยนเปนสมการไดดงน

dTdt = -k (T-Ta)

เมอ T คอ อณหภมของวตถในหนวยองศาเซลเซยส Ta คอ อณหภมของสงแวดลอม k คอ คาคงท (ตอวนาท) นาทรงกลมโลหะอณหภม 90o C จมลงไปในนาอณหภม 20o C อณหภมของ ทรงกลมโลหะเปลยนไปตามตารางดงน

เวลา (นาท) 0 5 10 15 20 25 อณหภม (o C) 90 62.5 45.8 35.6 29.5 25.8

จงหาคา dTdt ททกคาของ t

วธทา 1. คอมไพลโปรแกรม Deriv_TB.C ใหโปรแกรมนทางาน ปอนขอมลทโจทย

กาหนดให ใสคาเวลาทตองการหา dTdt

2. คาตอบของ dTdt ทเวลา t ตาง ๆ กน จะเปนดงน

เวลา (นาท) 0 5 10 15 20 25

dTdt

-6.580 -3.990 -2.578 -1.562 -0.810 -0.5

Page 184: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

177

ตวอยาง 4.8 จากการจดขอมลของการเคลอนทของอนภาคซงเคลอนทเปนเสนตรงไดขอมลดงน

การขจด (s) ม. 25 30 35 40 45 50 55 ความเรว (v) m/s 4 8 11 14 21 26 35

จงหาความเรงของอนภาค เมออนภาคเคลอนทได 40 ม. วธทา ความเรงของอนภาค (a) ทเวลา t ใด ๆ หาไดจาก

a = dvdt

ใชกฎลกโซเปลยนรปสมการเสยใหม

a = dvdt

dsdt =

vdvds

ดงนน จงหา dvds ทตาแหนงตาง ๆ กน โดยใชโปรแกรม Deriv_TB.C นาคา dv

ds คณกบ v จะไดเปนความเรงทตาแหนงนน ๆ ผลการรนโปรแกรมจะไดดงน

dvds

ความเรงของอนภาค เมออนภาคเคลอนทได 40 ม. คอ 14.47 m/s2

avdv

ds=

s (m) 25 30 35 40 45 50 55

0.9 0.6 0.51667 1.03333 1.20000 0.80000 2.2000

3.60 4.80 5.80 14.47 25.20 20.80 77.00

Page 185: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

178

ตวอยาง 4.9 รถจาลองคนหนงเคลอนทในอโมงคลม เพอทดสอบแรงตานทานอากาศ วดตาแหนงของรถเปนฟงกชนกบเวลาดงน

จงหาความเรวและความเรงเมอเวลาผานไป 2 วนาท

วธทา 1) ใชโปรแกรม Deriv_TB.C ปอนขอมลทง 11 ชด หาคา dxdt จะไดผลลพธดงน

เมอเวลา t = 2 วนาท รถมควาามเรว = 454.167 mm/s

2) รนโปรแรม Derriv_TB.C อกครง ปอนขอมลระหวาง t กบ v เพอหาความเรง dxdt จะไดผลลพธดงน

เมอเวลา t = 2 วนาท รถมความเรงเทากบ -131.950 mm/s2

t (วนาท) 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5

x (มม.) 0 475 800 1225 1425 1700 1875 2000 2100 2075 2050

t 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5

v = dx/dt 1100 550 762.50 629.167 454.167 470.83 287.50 237.50 70.83 -175.00 -50

t 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5

dv/dt -1862.50 770.833 213.195 -397.916 -131.950 -156.945 -247.217 -181.255 -493.750 -570.820 620.830

Page 186: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

179

ตวอยาง 4.10 แรงเคลอนไฟฟาเหนยวนาทเกดขนบนลวดตวนาขณะทมการเปลยนแปลง กระแสไฟฟา หาไดจาก

E = L didt

เมอ E คอ แรงเคลอนไฟฟาเหนยวนา มหนวยเปนโวลต L คอ คาการเหนยวนาตนเอง มหนวยเปนเฮนร i คอ กระแส มหนวยเปนแอมแปร t คอ เวลา เปนวนาท จงหา E ทเวลา t ใด ๆ จากขอมลตอไปน เมอ L = 5 H

t 0 0.1 0.2 0.4 0.6 0.8 i 0 0.1 0.2 0.6 1.3 2.7

วธทา ใชโปรแกรม Deriv_TB.C หา didt โดยตดขอมลท t = 0.1 ทง เพราะจะทาให

ชวงหางระหวางขอมล = 0.2 วนาท เทา ๆ กน นาคา didt คณกบ L จะไดเปนคา

E ในแถวท 3

ถาปอนขอมลท t = 0.1 เขาไปในโปรแกรม โปรแกรมจะหยดทางานแลวฟองวา ชวงหางของขอมลมคาไมเทากน

t 0 0.2 0.4 0.6 0.8 di/dt 0.50 1.25 2.54 4.25 8.75 E (v) 2.50 6.25 12.70 21.25 43.75

Page 187: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

180

ตวอยาง 4.11 วตถมวล m ตกลงในแนวดงอยางอสระ มแรงตานอากาศเปนปฏภาคตรงกบ ความเรว การขจดของวตถทเวลาใด ๆ หาไดจาก

x = ( )mgk t m

k e mk+ −

ktm

จงหาความเรวของอนภาคหลงจากปลอยวตถลงมา 0.5 วนาท กาหนดให m = 1 กก. g = 9.81 m/s2 k = 0.3 วธทา 1) ใชโปรแกรม Deriv_fn.C ชวยในการคานวณ โดยแกไขทฟงกชน YourFunc ดงน double YourFunc (double t) { return ((1*9.8)/0.3*(t + exp(-0.3*t)/0.3 - (1/0.3)); } 2) คอมไพลโปรแกรม Deriv_fn.C ปอนขอมลตามทโจทยกาหนดให ผลการ คานวณจะเปนดงน Finding the First Derivative of Function. =============================== Number of data ( 1 - 50) : 1 X[ 1] = 0.5 Tolerance ( default 0.001) : 0.001 X[ 1] = 0.500000 1 st Derivative = 4.5548492

3) นาไปเปรยบเทยบกบคาทแทจรง คาทแทจรงหาไดจากคาอนพนธ dxdt จะได

dxdt = v = mg

k (e e )−−ktm

= 1 9.810.3 (1 e )×

− − ×0 3 0 5. . = 4.5548 ม./วนาท

Page 188: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

181

ตวอยาง 4.12 แทง AB ยาว a = 2 ม. เคลอนทในรางเลอน ดงรป 4.9 การขจดทปลาย B

มคาเปน x = 4 sin 3t ทเวลา t = 0 x = 0 และ dxdt = 0 จงหาความเรว

ของปลาย A เมอ t = 0.2 วนาท และ t = 2.1 วนาท A O

รป 4.9 วธทา 1) หาความสมพนธระหวาง x และ y โดยอาศยทฤษฏบทสามเหลยมมมฉาก จะได y = a x2 2− = a 16 sin 3t2 2− 2) ใชโปรแกรม Deriv_fn.C แกตรงสวนฟงกชน Your Func ดงน double YourFunc (double t) { retrun (sqrt (4-16*(sin3*t)*(sin(3*t)))); } 3) ใหโปรแกรมทางาน แลวปอนขอมล t = 2 วนาท จะไดความเรวทปลาย A เมอ t = 0.2 วนาท เทากบ เมตร/วนาท เมอ t = 2.1 วนาท = เมตร/วนาท 4) เปรยบเทยบกบคาทแทจรง จะได

dydt =

48 sin 3t2 16 sin 3t2 2

เมอ t = 0.2 วนาท ความเรวทปลาย A = 0.251 m./s เมอ t = 2.1 วนาท ความเรวทปลาย A = 2.6994 m/s

y

xB

Page 189: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

182

ตวอยาง 4.13 งานทใชในการเคลอนวตถจากตาแหนง x = a ถง x = 2a หาไดจาก

W = kdx(x a )2 2

32

2

+∫a

a

จงหาคาของงานน เมอ a = 1, k = 0.5 วธทา 1) ใชโปรแกรม integrat.C เปลยนฟงกชน YourFunc เปนดงน double Your Func (double x) { retrun (0.5/pow ((x*x+1),1.5)); } 2) คอมไพลและรนโปรแกรม ปอนขอมลดงตอไปน Finding the Integration using Several Methods. =================================== Input the Lower Limit of integration : 1 Input the Upper Limit of integration : 2 Input the number of Interval :100 The Result of integration by Trapezoidal rule = 0.093662 The Result of integration by Simpson's 1/3 rule = 0.093660 The Result of integration by Simpson's 3/8 rule = 0.093660

3) คาทแทจรงจะได W = ka sin tan x

921−

⎡⎣⎢

⎤⎦⎥

เมอแทนคาขดจากดบนและลางแลว จะได

W = ( )0.5 25

12−

= 0.093660

Page 190: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

183

ตวอยาง 4.14 รถยนตมวล 5,400 กโลกรมวงดวยความเรว 30 ม./วนาท เรมจบเวลาเมอดบ เครองยนต ปลอยใหรถเคลอนทอยางอสระ สมการการเคลอนทของรถยนต หลงจากดบเครอง

แลว คอ m vdvdx = - cv2 - R

เมอ m คอ มวลของรถ v คอ ความเรวทเวลาใดๆ R คอ แรงตานทานทมตอลอขณะหมน = 2,000 N cv2 คอแรงตานทานอากาศ = 8.276 N จงหาระยะทางทรถเคลอนทได เมอความเรวลดเหลอ 15 ม./วนาท วธทา 1) เมอจดรปสมการใหมจะได

x = − +∫

5,400 vdv8.276 v 2,0002

30

15

2) ใชโปรแกรม Integrat.C แกไขตรงฟงกชน YourFunc ดงน double Your Func (double x) { return (5,400*x/(5.276*x*x+2,000)); } 3) คอมไพลและใหโปรแกรมทางาน จะไดผลลพธดงน Finding the Integration using Several Methods. ============================== Input the Lower Limit of integration : 30 Input the Upper Limit of integration : 15 Input the number of Interval : 100 The Result of integration by Trapezoidal rule = -291.868877 The Result of integration by Simpson's 1/3 rule = -291.869588 The Result of integration by Simpson's 3/8 rule = -291.869588 4) เปรยบเทยบกบคาทแทจรง คอ

x = −2,7008.276 ln (8.276 v2 + 2,0000

= 291.8695883 ม.

15

30

Page 191: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

184

ตวอยาง 4.15 สะพานโคงรปทรงพาราโบลา y = 2x - 0.1x2 เมตร เมอ y คอ ความสงของสะพาน วดจากพนดน x คอ ระยะทวดในแนวราบ เรมตงแน x = 0 ถง x = 20 จงหาความยาวของสวนโคงของสะพาน

รป 4.10 แสดงวธหาความยาวเสนโคง AB วธทา 1) การหาความยาวของเสนโคง (perimeter) ของเสนโคงใด ๆ มหลกดงน ตองการหาความยาวสวนโคง AB ทเกดจาก y = f(x) แบง AB ออกเปนสวนเลก ๆ = ds จะได ds2 = dx2 + dy2

dsdx = ( )1 dy

dx+2

ความยาวของเสน AB คอ

dsA

B

∫ = dsdx dx

a

b

= ( )1 dydx dx+∫

2

a

b

จากโจทย สวนโคงของสะพาน คอ y = 2x - 0.1 x2

dydx = 2 - 0.2 x

ความยาวของสวนโคงของสะพาน = 1 (2 0.2x) dx+ −∫ 2

0

20

Page 192: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

185

2) ใชโปรแกรม Gauss_QD.C เปลยนคาในฟงกชน YourFunc ดงน double Your Func (double x) { return (sqrt (1 + pow ((2-0.2*x), 2))); } ผลลพธทไดจะเปนดงน Finding the Integration using Gauss Quadrature. ================================= Input the Lower Limit of Integration : 0 Input the Upper Limit of Integration : 20 Input the number of Gauss point to be used (from 2 to 6) : 4 The Result of Integration using Gauss Quadrature = 29.627791 Your work was done. Goodbye. 3) คานวณคาแทจรง โดยวธวเคราะห แทนคา (2 - 0.2 x) ดวย z จะได dz = - 0.2 dx

1 (2 0.2x) dx+ −∫ 2

0

20

= 10.2 1 z dz+

−∫ 2

2

2

= = 29.57885715 ม.

( )( )10.2

12 z z 1 ln z z 1× + + + +2 2

2

-2

Page 193: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

186

ตวอยาง 4.16 จงหาคาแรงดนไฟฟารากทสองเฉลย (root mean square) ในรปท 4.11

รป 4.11 แรงดนไฟฟาคาไมสมาเสมอ วธทา 1) คาแรงดนไฟฟารากทสองเฉลยทวไป หาไดจาก

Vrms = ( )[ ]1T f t dt2

0

T

แทนคา f(t) = V = 4t2 + 20

Vrms = ( )15 4t 20 dt2 2

0

5

+∫

2) ใชโปรแกรม Gauss_QD.C หาคาการอนทเกรทของ ( )15 4t 20 dt2 2

0

5

+∫

โดยแกไขฟงกชน Your Func ดงน double Your Func (double y) { return ((4*t*t+20)*(4*t*t+20)/5); } จะไดผลลพธเปน 3733.333332 เมอหารากทสองของ 3733.333332 จะไดเปน 61.10100926 โวลต 3) เปรยบเทยบกบคาทแทจรง

( )165 t 5 dt2 2

0

5

+∫ = ( )165 t 10t 25 dt4 2

0

5

+ +∫

= 3733.33344 นาคาทไดนไปหารากทสองจะได 61.1010 โวลต

Page 194: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

187

ตวอยาง 4.17 จงหาปรมาตรของนามนในถงรปทรงกระบอก เมอไมบรรทด (dipstick) วด ความสงของนามนได 0.5 เมตร

รป 4.12 ถงนามนรปทรงกระบอก

วธทา 1) จากโจทยสามารถเขยนเปนรปใหดงายขนดงน y = ( )1 x 1− −

2 1 2 ความสง (x)

พนทตรงบรเวณทแรเงา = ( )2 1 x 1 dx− −∫ 2

0

0 5.

เมอนาไปคณกบความยาวของถงนามน 5 เมตร จะไดเปนปรมาตรของนามนในถง 2) ใชโปรแกรม Gauss_QD.C หาผลลพธการอนทเกรท โดยเปลยนฟงกชน YourFunc เปนดงน double YourFunc (double x) { return (2*sqrt (1-(x-1)*(x-1))); } เมอปอนขอมลใหโปรแกรมทางาน จะไดพนทแรเงามคาเทากบ 0.614566 ปรมาตรของนามนในถงคอ 3.070935 ลกบาศกเมตร 3) คาทแทจรงของปญหาขอน โดยเรมตนจากหาพนทตรงบรเวณทแรเงา จากสตรการอนทเกรท

a u du2 2−∫ = ( )12 u a u a sin u

a2 2 2 1− + −

1

Page 195: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

188

( )2 1 x 1 dx− −∫ 2

0

0 5.

= (x - 1) ( ) ( )1 − − + −−x 1 sin x 12 1

= 0.614187 ตารางเมตร ปรมาตรของนามนในถงคอ 0.61487 × 5 = 3.07 ลกบาศกเมตร 4.7 บทสรป การหาอนพนธอนดบหนงสามารถใชฟงกชน FirstDerive_Tabular หาไดในกรณทขอมลทไดมาเปนแบบตาราง แตถาอยในรปของฟงกชน สามารถใช FirstDeriv_Function หาอนพนธได แตตองอยางลมใสฟงกชนทตองการหาอนพนธลงในสวนของโปรแกรมตรง YourFunc ดวย สวนการอนทเกรทนนไดเสนอวธการอนทเกรทหลายวธ วธทงายและธรรมดาทสดคอ ใชกฎสเหลยมคางหม จะมความถกตองใกลเคยงคาแทจรงมากทสดเมอแบงสวนเลก ๆ ของการอนทเกรท (∆x) ใหเลกทสดเทาทจะทาได แตนนหมายถงตองใชเวลาในการคานวณมากขน โปรแกรมอาจทางานชาลง การใชกฎของซมปสน จะใหความถกตองมากกวา แตวธของเกาส-เลอจองดจะใหความถกตองมากทสดและใชเวลาในการคานวณนอยทสด แตขนตอนวธการคานวณทาความเขาใจไดยากกวาวธอน ๆ เพราะตองไปเกยวของกบพหนามของเลอจองด การแกไขปรบปรงโปรแกรมอาจทาไดลาบาก วธมอนตคารโล เปนวธทชใหเหนวาการใชตวเลขสม สามารถนามาแกปญหาทางฟสกสได การทดลองบางอยางไมจาเปนตองลงมอปฏบตจรง อาจใชเลขสมจาลองสถานการณทเกดขน เชนในบทนจะแสดงใหเหนการนาตวเลขสมมาใชแกปญหาการอนทเกรท การสมตวเลขยงสมเปนจานวนมากครงเทาใด ผลลพธยงเขาใกลคาแทจรงมากขนเทานน

0.5

0

Page 196: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

189

บทท 5 การหาคาตอบสมการอนพนธแบบสามญ

การจาลองปรากฏการณทางวทยาศาสตรดวยตวแบบทางคณตศาสตร มกจะอยในรป สมการเชงอนพนธ เราสามารถหาคาตอบของสมการเชงอนพนธดวยวธวเคราะห คาตอบทไดจะตดตวคงท ซงจะมคาไมเฉพาะเจาะจง ทาใหจานวนคาตอบทไดมหลายคา ตวอยางเชน การแกวงของลกตมนาฬกา มวล m ยาว l เคลอนทแบบซมเปลฮารมอนก ไมคดแรงตานอากาศ และเชอกเบา จะไดสมการเชงอนพนธ เปน

2

2

dt

Ld θ + q sin θ = 0

เมอการแกวงทาใหมม θ มคานอย ๆ และกาหนดความเรวเชงมม w = gL จะได

2

2

dt

d θ + w2 = 0 คาตอบของสมการเชงอนพนธจะไดเปน θ = c1 cos wt + c2 sin wt c1, c2 เปนคาคงททไมเฉพาะเจาะจง เมอ c1, c2 มคาตาง ๆ กนไป จะไดชดคาตอบของสมการเชงอนพนธนไดมากมายไมสนสด แตเมอกาหนดเงอนไขเรมตน เชน เมอ t = 0 θ = π

2 0และ w = 10 π เรเดยน จะไดคาตอบของสมการอนพนธเพยงคาตอบเดยวคอ

θ = π2 0

cos wt + 10π sin wt โปรแกรมทจะใชหาคาตอบของสมการเชงอนพนธในบทนสามารถใชกบสมการ เชงอนพนธทมตวแปรอสระเพยงตวเดยว หรอทเรยกวา ordinary differential equation คาอนพนธทปรากฏในสมการจงเปนคาทหาเทยบกบตวแปรเพยงตวเดยว ไมใชเปนแบบ partial derivative และมลกษณะเปนเชงเสนอนดบหนง เขยนใหอยในรปทวไปไดดงน ′y = (x, y) .................... (5.1) โดยมเงอนไขทจดเรมตน (Initial condition) คอ y (x0) = y0

Page 197: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

190

การหาคาตอบของสมการอนพนธทนยมใชมอย 2 วธ ไดแก วธแบบขนเดยว (one step techniques) โดยประมาณคาตวแปรอสระ (x) ทจด mesh point และนาคาทหาไดนไปคานวณหาคาจดตอไปบนโคงของ f(x) ไดแก วธของออยเลอร (Euler’s Method) วธของ รงเง-คตตา (Runge-Kuta Method) อกวธหนงคอวธแบบหลายขน (multi step techniques) เปนวธทหาจดถดไปบนเสนโคง f(x) โดยใชขอมลจากการคานวณทผานมาหลายจด จะมการวนรอบจนกระทงไดคาความคลาดเคลอนไมเกนทกาหนดไว ไดแก วธของ อาดม-แบชฟอรท (Adam-Bashforth’s Method) 5.1 วธของออยเลอร (Forward Euler and Modified Euler Method) เปนวธทงายและธรรมดาทสด สะดวกทจะใชเขยนโปรแกรมใหคอมพวเตอรทางาน และพนฐานสาคญในการนาไปหาคาตอบสมการอนพนธแบบ partial จากบทท 4 เรานยามการประมาณคาการหาอนพนธ (สมการ 4.3) ไวดงน

′y ≅ y yh

n n+ −1 หรอ yn+1 ≅ y hyn + ′ แทนคา ′y จากสมการ (5.1) จะได yn+1 ≅ y hf (x, y)n + .................... (5.2) เมอกาหนดเงอนไขเรมตนมาให y(x0) = y0 เราสามารถนาเงอนไขนมาหาคา y ครง ตอ ๆ ไปได y1 = y0 + hf (x0, y0) y2 = y1 + hf (x1, y1) M M yn = yn+1 + hf (xn-1, yn-1)

Page 198: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

191

x1 x2 x3 x4

รป 5.1 เงอนไขเรมตน x0 นาไปหาคา y ทจด x1,x2,... ได ตวอยาง 5.1 การสลายตวของสารกมมนตภาพรงส เปนไปตามสมการ

dydt = -λy

เมอ λ คอ คาคงทของการสลายตว (disintegration constant) y เปนจานวนอะตอมของสารกมมนตรงส เมอเวลา t ใด ๆ กาหนดใหสารหนงมจานวนอะตอม 10,000 อะตอม เมอ t = 0 คาคงทการสลายตว = 0.2 s-1 จงหาจานวนอะตอมทเวลา 0 ≤ t ≤ 0.6 กาหนดให ∆t = 0.1 และเปรยบเทยบกบคาทแทจรง วธทา คาทแทจรงของ y(t) = y0 e-λt เมอกาหนดให ∆t หรอ h = 0.1

คาทไดจากการประมาณ (∆t = 0.1)

คาความแตกตาง

t0 0 y0 = 104 104 0 t1 0.1 y1 = y0-h(λy0) = 9800 9801.9 1.99 t2 0.2 y2 = y1-hλy1 = 9604 9607.89 3.89 t3 0.3 y3 = y2-hλy2 = 9411.92 9417.65 5.73 t4 0.4 y4 = y3-hλy3 = 9223.68 9231.17 7.49 t5 0.5 y5 = y4-hλy4 = 9039.21 9048.38 9.17 t6 0.6 y6 = y5-hλy5 = 8858.42 8869.21 10.79

y0eλt t (s)

Page 199: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

192

ตวอยางขางบนเปนการคานวณดวยมอเพอใหเหนขนตอนวธคดแบบออยเลอร จะเหนวาเมอคานวณมากครงเทาใด ความคลาดเคลอนทเกดขนจะเพมมากขนตามไปดวย เมอทดลองกาหนดให ∆t = 0.01 โดยเขยนโปรแกรมใหคอมพวเตอรคานวณ ดงในโปรแกรม Euler. C ผลลพธจะไดดงน

คาทไดจากการประมาณ ∆t = 0.01

0 10000 10000 0 0.1 9801.79 9801.99 0.20 0.2 9607.51 9607.89 0.38 0.3 9417.08 9417.65 0.57 0.4 9230.42 9231.17 0.75 0.5 9047.47 9048.38 0.91 0.6 8868.14 8869.21 1.07

จะเหนวาเมอใช ∆t หรอ h มคานอยลง คาทไดจะใกลเคยงคาจรงมากกวาเมอตอนทใช ∆t นอย ๆ แตความคลาดเคลอนทเกดเมอคานวณมากครงยงไมสามารถแกไขได ดวยเหตนจงจาเปนตองปรบปรงขนตอนวธของออยเลอร เพอใหไดผลลพธทใกลเคยงความจรงมากขน โปรแกรม 5.1 การใชวธออยเลอรคานวณในตวอยาง 5.1 h = 0.01 /* * Program 5.1: Euler's Method * Language: Turbo C v.2.0 * Last update : 31 DEC 95 * Warning : This subrutine is not general use, it specifies to this problem ( Ex 5.1) only. **************************************************************/ #include <stdio.h> #include <math.h> #include <dos.h> void main() { double cur_y, ex_y;

y0 e-λt คาความแตกตาง t (s)

Page 200: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

193

double h,t,delta_t,lambda; int i,j; clrscr(); printf("\t\tFinding the Solution of 1st order D.E. by Euler's method.\n"); printf ("\t\t======================================================\n"); delta_t = 0.01; lambda = 0.2; t = 0; cur_y = 10000; for ( i = 0; i <= 6; i++) { printf(" t = %f , y = %f \n", t,cur_y); for (j = 0; j < 10; j++) { ex_y = cur_y; cur_y = ex_y - delta_t*lambda*ex_y; } t += 0.1; } } วธออยเลอรแบบปรบปรงแลว (Modified Euler Method) เปนการนาเอากฎสเหลยมคางหมมาชวยหาคาตอบสมการดฟเฟอเรนเชยล สมการ (5.2) จะกลายเปน

yn +1 = [ ]y h2 f (x y ) f (x y )n n n n n+ + +1 1, , .................... (5.3)

รป 5.2 แสดงวธของออยเลอรแบบปรบปรงแลว

Page 201: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

194

จากรปจะเหนวา y0+ hf (x0, y0) คอเสน x1B ซงจะไดตากวาคาทเปนจรง (ตากวาจด E) และ y0 + hf (x1, y1) คอเสน x1D มคาสงกวาคาจรง เมอใชคาเฉลยของคาทงสองกจะไดคาประมาณทใกลคาจรงคอ x1E จงเปนทมาของสมการ (5.3) ปญหาอกประการหนงของสมการ (5.3) คอ yn+1 เปนตวไมทราบคา ซงจะพบวามอยทางดานขวามอของสมการ (5.3) ดวย การนาสมการ (5.3) ไปใชจงตองประมาณคา yn+1 ทางดานขวามอกอน เรยกวาเปนคาพยากรณได (predict) แลวจงนาไปหาคา yn+1 ทถกตองมากยงขนในสมการ (5.3) (correct) การพยากรณคา yn+1 หาไดจากสมการ (5.2)

ตวอยาง 5.2 จงหาคาตอบของสมการ dydx y+ = x เมอ x = 0, y = 1

เมอ x = 0.1, 0.2, 0.3, 0.4 และ 0.5 วธทา คาตอบทแทจรงของสมการดฟเฟอเรนเชยล คอ y = x + 2e-x - 1

จดรปสมการใหอยในรป dydx = x - y

เมอใชสมการ (5.2) คานวณจะไดคาตอบและความคลาดเคลอนดงน

x0 x1 x2 x3 x4 x5 x 0 0.1 0.2 0.3 0.4 0.5

y (จากการคานวณ) 1 0.99 0.82 0.758 0.7122 0.6810 y (คาแทจรง) 1 0.9097 0.8375 0.7816 0.7406 0.7131 คาความแตกตาง 0 0.0097 0.0175 0.0236 0.0284 0.0321

เมอทดลองใชขนตอนวธของออยเลอรทปรบปรงแลว การคานวณจะเปนดงน f (x, y ) = x - y จากตารางขางบน เมอ x0 = 0, y0 = 1 จะได f(x0, y0) = -1 x1 = 0, y1 = 0.9 f(x1, y1) = 0.1-0.9 = -0.8

y1 ทไดปรบปรงแลว = 1 + 0.12 (-1-0.8) = 0.91

จะไดคาใกลเคยง 0.9097 มากกวา 0.9 ใชคา y1 นไปหาคาประมาณของ y2 ตอไป เมอ x1 = 0.1, y1 = 0.91 f(x1, y1) = -0.81

Page 202: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

195

คาประมาณของ y2 y2 = y1 + hf (x1 ,y1) = 0.91 + 0.1 (-0.81) = 0.829 f (x2, y2) = f(0.2, 0.829) = -0.629

y2 ทปรบปรงแลว = 0.91 + 0.12 (-0.8 - 0.629)

= 0.83805 ซงใกลเคยง 0.8375 มากกวา 0.82 หาคาประมาณของ y3 ตอไป เมอ x2 = 0.2 , y2 = 0.83805 f (x2, y2) = - 0.63805 คาประมาณของ y3 y3 = 0.83805 + 0.1 ( -0.63805) = 0.77425 f (x3, y3) = f(0.3, 0.77425) = -0.47425

y3 ทปรบปรงแลว = 0.838005 + 0.12 (-0.63805 - 0.47425)

= 0.78244 จะไดผลลพธดงตารางตอไปน

x 0 0.1 0.2 0.3 0.4 0.5 y (จากการคานวณ) 1 0.91 0.8380 0.7824 0.7416 0.7142 y (คาแทจรง) 1 0.9097 0.8375 0.7816 0.7406 0.7131 คาความแตกตาง 0 -0.0003 -0.0005 -0.0008 -0.0010 -0.0011

เมอจานวนครงในการหามากขน คาความแตกตางจากคาทแทจรงยงคงมการสะสมมากขนเหมอนกบวธของออยเลอร

Page 203: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

196

การนาฟงกชน Modified Euler ไปใชงาน ก. คาคงททตองนยาม ข. การเรยกใชฟงกชน int Modified Euler (double init_x, double init_y, double x, double h, double * solution) เมอ int_x, init_y เปนเงอนไขเรมตนของสมการอนพนธ x คอ จดทตองการหาคาตอบจากสมการอนพนธ h คอ ระยะหางของแตละชองเลก ๆ มคามากกวาศนย solution คอ ตวแปรทเกบคาตอบทหาได ค. ฟงกชนอนทเกยวของ double Your Func (double x, double y) ใชกาหนดฟงกชน f(x, y) ง. การสงคากลบ 0 ไมมขอผดพลาดใด ๆ 1 ระยะของคา x ( interval) มคาเปนศนย โปรแกรม 5.2 Mod_Euler.C /* * Program 5.2 Modified_Euler.C * Purpose: Demonstrate how to find the Solution of the first differntial eqn by * by using modified Euler's method. * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 31 Dec 95 **************************************************************/ #include <stdio.h> #include <math.h> /* Global Variable */ void GetInitialCondition(double*, double* ,double* ); double GetXValue( void );

Page 204: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

197

int ModifiedEuler(double init_x, double init_y,double x, double h, double *solution); void DisplaySolution(int, double ,double ); double YourFunc(double, double); void main() { double h,init_x,init_y,x,y; double solv ; int i,j,error; clrscr(); printf("\t\tCalculating the Solution of the 1st Differential Eqn.\n"); printf ("\t\t ==============================================\n"); GetInitialCondition(&h,&init_x,&init_y); x = GetXValue(); error = ModifiedEuler(init_x, init_y,x,h, &solv); DisplaySolution(error,x,solv); printf("\n Program stop completely. Good bye.\n"); } void GetInitialCondition (double *interval, double *x_point, double *y_point) { char buffer[225]; printf("\nSelect the interval (default = 0.001) :"); gets(buffer); *interval = atof(buffer); if (*interval == 0 ) *x_point = 0.001; printf("\n X at initial condition = "); gets(buffer); *x_point = atof(buffer); printf("\n Y at initial condition = "); gets(buffer); *y_point = atof(buffer); } double GetXValue( ) { char buffer[250]; double x; printf("\n\tFind the Solution at X = ");gets(buffer); x=atof(buffer); return x; }

Page 205: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

198

void DisplaySolution(int err, double xval,double solution) { switch (err) { case 0 : { printf( "\n\tX = %13.5f ",xval); printf( " The Solution of DE. = %13.5f\n",solution); break; } case 1 : { printf("\nThe interval of x must greater than zero.\n"); break; } } /* switch (err) */ } double YourFunc(double x, double y) { return(x+y); } /*================== Function Start here. ==========================*/ int ModifiedEuler(double init_x, double init_y,double x,double h,double *solution) /* Function Description: Determine the solution of the first order differential equation that giving the initial value conditon. User's Define : None Input : init_x, init_y -- initial value of x,y x -- where to find the solution. h -- interval of x Output : solution -- the solution of 1st order DE. Return : 0 -- if no error. 1 -- h <= 0 *************************************************************************/ { int i,j; double current_y,new_current_y,current_x, ex_y,ex_x; if ( h <=0 ) return 1; /* if ( h<=0) h = 0.001; */ current_y = init_y;

Page 206: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

199

current_x = init_x; while ( current_x < x ) { ex_x = current_x; ex_y = current_y; current_x = ex_x + h; current_y = ex_y + h*YourFunc(ex_x,ex_y); new_current_y = ex_y+h*(YourFunc(ex_x,ex_y)+YourFunc(current_x,current_y))/2; current_y = new_current_y; } ; *solution = current_y; return 0; } /*=======================================================*/ 5.2 วธของรงเง-คตตา (Runge - Kutta method) ถงแมวาวธของออยเลอรทถกปรบปรงแลวจะใหผลลพธใกลเคยงกบคาทแทจรงมากขน แตความคลาดเคลอนเมอหาคาตอบของสมการอนพนธทจดตางๆ ซงหางจากจดเรมตนมาก ๆ ยงคงปรากฏใหเหนอยางชดเจน นกคณตศาสตรชาวเยอรมน 2 คน คอ รงเง (Runge) และคตตา (Kutta) ไดเสนอวธหาคาตอบสมการอนพนธทมประสทธภาพใหความเทยงตรงมากกวา ทง ๆ ทใชเวลาในการคานวณนอยกวา หลกการของรงเง - คตตา อาศยการเพมจานวนเทอมซงปกตจะถกตดทง เปนการหาคาประมาณของอนพนธอนดบสองในเทอมของอนพนธอนดบท 1 ตรงจด xi และ xi+1 ซงจาเปนจะตองหาคาฟงกชน ณ ตรงจด xi + αh โดยท α เปนคาใด ๆ ถาเราเพมจานวนเทอมซงเปนอนพนธอนดบสงกวาสอง ซงกตองหาคาการเปลยนแปลงของฟงกชนทคา α ตาง ๆ กน เราจะไดสตรสาหรบวธของรงเง -คตตา มากมาย ขนอยวาเราตองการความละเอยดและตดเทอมตาง ๆ ทงตรงตาแหนงใด เพอทจะแสดงใหเหนถงวธของรงเง-คตตา วามาไดอยางไร จะยกตวอยางการตดปลายตรงเทอมหลงจากอนพนธอนดบสองทง เรยกวา วธของรงเง-คตตา อนดบสอง กาหนดใหการประมาณคาคาตอบของสมการอนพนธอนดบ 1 ของรงเง-คตตามคาเปน yn+1 = yn + ak1 + bk2 .................... (5.4) โดยท k1 = h f (xn, yn) k2 = h f (xn + αh, yn + βk1)

Page 207: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

200

อาจคดไดวา k1 , k2 เปนการประมาณคาการเปลยนแปลงของ y เมอ x เปลยนคาไป h ซงมคาเทากบผลคณการเปลยนแปลง h กบคาความชนของเสนโคง จะเหนวา k1 เปนการประมาณคาเหมอนกบวธของออยเลอร แลวจงประมาณคาเทอมตอไปโดยอาศยคา x และ y เดม โดยเพมคาเขาไปอกครงละ α ของ h และ β เทาของคาประมาณครงแรก (k1) เราตองเลอกคาพารามเตอร a, b, α, β ทเหมาะสม โดยอาศยอนกรมของเลเลอร

เมอ dydx = f(x, y) = f

yn+1 = yn + h f(xn ,yn) + h2 f2

′(xn, yn) + ...

เพราะวา dydx = fx + f dy

dxy = fx + fyf จะได

yn+1 = yn + hfn + h2 12 f 1

2 f fx yn

+⎛⎝⎜ ⎞

⎠⎟ .................... (5.5)

เมอแทนคา k1, k2 สมการ (5.4) จะไดเปน yn+1 = yn + ah f(xn, yn) + bh f [(xn + αh, yn + βh f(xn,yn) ] .................... (5.6) เพอทจะเปรยบเทยบกบสมการ (5.5) จงกระจาย f(x, y) ใหอยในรปอนกรมเทเลอร 2 ตวแปร เทอมทเปนอนพนธอนดบสองตดทงไป f [xn + αh, yn + βh f(xn, yn)] = (f + fxαh + fyβh f)n .................... (5.7) แทนคาสมการ (5.7) ลงในสมการ (5.6) yn+1 = yn + ah fn + bh (f + fxαh + fyβh f)n จดรปใหมจะได yn+1 = yn + (a+b) h fn + h2(α bfx + βb fyf)n .................... (5.8) สมการ (5.8) ยอมเทากบสมการ (5.5) นนคอ

a+b = 1, αb = 12 , βb = 1

2

Page 208: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

201

จะไดสมการ 3 สมการ มตวแปร 4 ตวแปร เราอาจกาหนดใหตวแปรใดตวแปรหนงมคาตามใจชอบ เชน

กาหนดให a = 23 จะได b = 1

3 , α = 32 , β = 3

2

หรอ กาหนดให a = 12 จะได b = 1

2 , α = β = 1 กรณนจะตรงกบวธของออยเลอรแบบปรงปรงแลวในสมการ (5.3) โดยทวไปแลวเรานยมใชวธรงเง-คตตา อนดบ 4 ซงไดมาจากการประมาณคาถงเทอม h4 จะไดตวแปร 13 ตวแปร จานวนสมการ 11 สมการ มตวแปร 2 ตว ซงตองถกกาหนดคาไดตามใจชอบ สมการทใชกนอยางแพรหลายสาหรบวธรงเง-คตตาอนดบ 4 คอ

yn+1 = yn + 16 (k1 + 2k2 + 2k3 + k4)

k1 = h f(xn,yn)

k2 = h f(xn + h2 , yn + k

21 ) .................... (5.9)

k3 = h f(xn + h2 , yn + k

22 )

k4 = h f(xn + h, yn + k3)

การนาฟงกชน Runge 4. C ไปใชงาน จะมลกษณะการใชงานคลายกบ Modified Euler.C ก. คาคงททตองนยาม ข. การเรยกใชฟงกชน int Runge_Kutta 4(double init_x, double init_y, double x, double h, double*solution) เมอ int_x, init_y เปนเงอนไขเรมตนของสมการอนพนธ x คอ จดทตองการหาคาตอบจากสมการอนพนธ h คอ ระยะหางของแตละชองเลก ๆ มคาไมเปนศนย solution คอ ตวแปรทเกบคาตอบทคานวณได ค. ฟงกชนอนทเกยวของ double Your Func (double x, double y) ใชคานวณหาคาฟงกชน f(x, y)

Page 209: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

202

ง. การสงคากลบ 0 ไมมขอผดพลาดใด ๆ เกดขน 1 ระยะหาง h มคาเปนศนย จากตวอยางท 5.2 เมอใชวธของรงเง-คตตาอนดบ 4

x 0 0.1 0.2 0.3 0.4 0.5 y (จากการคานวณ) 1 0.9097 0.8375 0.7816 0.7406 0.7131 y (คาแทจรง) 1 0.9097 0.8375 0.7816 0.7406 0.7131 คาความแตกตาง 0 0 0 0 0 0

ตวอยางการคานวณเมอ h = 0.1 เมอ dydx

= x-y , y(0) = 1 k1 = 0.1(0 - 1) k2 = 0.1(0.05 - (1 + (-0.05)) = -0.099 k3 = 0.1 (0.05 - (1 + (-0.045)) = -0.0905 k4 = 0.1(0.1 - (1 - 0.0905)) = -0.08095

y(0.1) = 1+ 12

[-0.1 + 2 (0.09)+ 2(-0.0905) + (-0.08095)] = 0.909675 ตวอยาง 5.3 วงจร RLC มคาการเหนยวนาตนเอง L = 10H ความตานทานในวงจร (R) = 20 โอหม แหลงจายไฟมคา 12 โวลต เรมจากไมมกระแสไหลในวงจร เมอเชอมตอ สวทซใหกระแสไหล จงหาคากระแสไฟฟา เมอ t = 0.5 วนาท วธทา 1) อาศยกฎเคอรชอฟ จะไดสมการแรงดนไฟฟาในวงจร ดงน

รป 5.3 แสดงวงจร RL ในตวอยาง 5.3

Page 210: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

203

L dIdt RI+ = E

โดยท I = 0 เมอ t = 0 ตองการหาคาตอบโดยสมการดฟเฟอเรนเชยล โดยใชวธรงเง-คตตา อนดบ 4 จงจดรปสมการใหมดงน

dIdt = E

LRIL− = f(I, t)

แทนคา R, L และ E

dIdt = 1.2 - 2I

2) เขยนเทอมดานขวามอลงในฟงกชน Your Func ดงน double Your Func (double x, double y) { retrun (1.2 - 2*y) } 3) ในโปรแกรม Runge 4 ทางานจะไดคาตอบ เมอ t = 0.5 วนาท จะมกระแสไหล = 0.379927 4) เปรยบเทยบกบคาตอบทแทจรง แกสมการดฟเฟอเรนเชยน จะไดคาตอบ

I = ER (1 e )- /− Rt L

แทนคาเมอ t = 0.5 จะได

I = 1220 1 1( )− −e

= 0.37927 A จะเหนวาคาตอบทไดจากการคานวณเชงตวเลขโดยใชวธรงเง-คตตาอนดบ 4 จะตรงกบคาตอบทแทจรงซงหาไดจากวธวเคราะห

Page 211: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

204

ตวอยาง 5.4 จงหาคาตอบของสมการอนพนธแบบ Bernoulli ท x = 10

′y = 4 4

1 2

xy x yx

++

มเงอนไขเรมตน x = 0, y = 1 วธทา 1) เขยนสมการดานขวามอลงในฟงกชน Your Func ดงน double YouFunc (double x, double y) { return (4*x*(y + sqrt (y))/1+x*x)); } 2) คอมไพลโปรแกรม Runge 4. C จะไดคาตอบดงน

h = 0.1 h = 0.01 h = 0.001 h = 0.0001 h = 0.00001 y 42030.62 40562.04 40417.08 40402.61 40401.16

3) คาตอบของสมการอนพนธ คอ y = (2x2 + 1)2 เมอ x = 10 จะได y = 40401 คาทไดจากการคานวณเชงตวเลขจะใกลคาแทจรง เมอ h มคานอย ๆ โปรแกรม 5.3 โปรแกรม Runge4.C /* * Program 5.3 Runge-Kutta.C * Purpose: Demonstrate how to find the Solution of the first differntial eqn by * by using 4th order Runge-Kutta's method. * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 25 Feb 96 **************************************************************/ #include <stdio.h> #include <math.h> /* Global Variable */ void GetInitialCondition(double*, double* ,double* ); double GetXValue( void ); int RungeKutta4(double init_x, double init_y,double x, double h, double *solution); void DisplaySolution(int, double ,double );

Page 212: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

205

double YourFunc(double, double); void main() { double h,init_x,init_y,x,y; double solv ; int i,j,error; clrscr(); printf("\t\tCalculating the Solution of the 1st Differential Eqn.\n"); printf ("\t\t====================================================\n"); printf("\t\t\t Using Runge-Kutta 's Method.\n"); printf("\t\t\t=============================\n"); GetInitialCondition(&h,&init_x,&init_y); x = GetXValue(); error = RungeKutta4(init_x, init_y,x,h, &solv); DisplaySolution(error,x,solv); printf("\n Program stop completely. Good bye.\n"); } void GetInitialCondition (double *interval, double *x_point, double *y_point) { char buffer[225]; printf("\nSelect the interval (default = 0.01) :"); gets(buffer); *interval = atof(buffer); if (*interval == 0 ) *interval = 0.01; printf("\n X at initial condition = "); gets(buffer); *x_point = atof(buffer); printf("\n Y at initial condition = "); gets(buffer); *y_point = atof(buffer); } double GetXValue( ) { char buffer[250];

Page 213: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

206

double x; printf("\n\tFind the Solution at X = ");gets(buffer); x=atof(buffer); return x; } void DisplaySolution(int err, double xval,double solution) { switch (err) { case 0 : { printf( "\n\tX = %13.5f ",xval); printf( " The Solution of DE. = %13.5f\n",solution); break; } case 1 : { printf("\nThe interval of x must greater than zero.\n"); break; } } /* switch (err) */ } double YourFunc(double x, double y) { return(4*x*(y+sqrt(y))/(1+x*x)); } /*================== Function Start here. ==========================*/ int RungeKutta4(double init_x, double init_y,double x,double h, double *solution) /* Function Description: Determine the solution of the first order differential equation that giving the initial value conditon. by using 4th order Runge-Kutta's method. User's Define : None Calling Function : double YourFunc(double x, double y) Input : init_x, init_y -- initial value of x,y x -- where to find the solution. h -- interval of x Output : solution -- the solution of 1st order DE.

Page 214: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

207

Return : 0 -- if no error. 1 -- h <= 0 *************************************************************************/ { int i,j; double current_y,current_x, ex_y,ex_x,k1,k2,k3,k4; if ( h <=0 ) return 1; /* if ( h<=0) h = 0.001; */ current_y = init_y; current_x = init_x; while ( current_x < x ) { ex_x = current_x; ex_y = current_y; current_x = ex_x + h; k1 = h* YourFunc(ex_x, ex_y); k2 = h*YourFunc(ex_x+h/2, ex_y+k1/2); k3 = h*YourFunc(ex_x+h/2, ex_y +k2/2); k4 = h*YourFunc(ex_x+h, ex_y + k3); current_y = ex_y + (k1+2*k2+2*k3+k4)/6; } ; *solution = current_y; return 0; } /*=======================================================*/ 5.3 การหาอนพนธอนดบสองโดยใชวธรงเง-คตตา การหาคาตอบของสมการอนพนธทผานมาจะเปนการหาคาตอบของสมการอนพนธอนดบหนง อยางไรกตาม เราสามารถประยกตขนตอนวธของรงเง-คตตาอนดบสนไปหาคาตอบของสมการอนพนธอนดบสอง โดยเพมเตมขนตอนบางขนตอน สมการอนพนธอนดบสองมรปสมการทวไปเขยนไดเปน

d ydx P(x) dy

dx Q(x)2

2 + + = R(x) จดรปใหมจะได

d ydx

2

2 = R(x) - Q(x)y - P(x) dydx

Page 215: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

208

เขยนใหสนลงจะได

d ydx

2

2 = f(x1, y, dydx ) .................... (5.10)

กาหนดให dydx = z สมการ (5.10) จะกลายเปน

dzdx = f(x, y, z) .................... (5.11)

วธรงเง-คตตาอนดบส สาหรบสมการอนพนธทมรปดงสมการ (5.11) คอ

yn+1 = yn + 16 (k 2k 2k k )

1y 2y 3y 4y+ + +

Zn+1 = Zn + 16 (k 2k 2k k )1z 2z 3z 4z+ + +

โดยท k1y = h z k1z = h f (x, y, z)

k2y = h zk z21

+⎛⎝

⎞⎠

k2z = ( )hf x h2 , y k y

2 ,z k z2

1 1+ + + ................... (5.12)

k3y = ( )h z k z22

+

k3z = ( )hf x h2 , y k y

2 , z k z2

2 2+ + +

k4y = h(z+k3z) k4z = hf (x + h, y + k3y, z + k3z) การนาฟงกชน Runge-Kutta 4_2 ไปใชงาน ก. คาคงททตองนยาม - ข. การเรยกใชฟงกชน int Runge-Kutta 4_2 (double init_x, double init_y, double init_z, double x, double h, double*solution 1, double*solution 2) เมอ int_x, init_y , init_z เปนเงอนไขเรมตนของสมการอนพนธ x คอ จดทตองการหาคาตอบจากสมการอนพนธ h คอ ระยะหางของแตละชองเลก ๆ solution1, solution2 คอคาตอบทคานวณไดจะเกบไวในตวแปรน

Page 216: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

209

ค. ฟงกชนอนทเกยวของ double Your Func (double x, double y, double z) ใชกาหนดฟงกชน f(x, y) ง. การสงคากลบ 0 ไมมขอผดพลาดใด ๆ เกดขน 1 h มคาเปนศนย ตวอยาง 5.4 กลองมวล (m) = 2 กก. วางบนพนไมมแรงเสยดทาน ถกกระทาดวยแรงซงมลกษณะเปนคาบ (F sin ωt) เมอ ω คอความเรวเชงมมของแรง สปรงมคาคงท (k) = 32 นวตน/ม. จงหาตาแหนงและความเรวของกลองตงแต t = 0 ถง t = 2 วนาท กาหนดให ω = 5 รอบ/

วนาท F =9 นวตน x(0) = 0 และ ddt (x 0)= = -2.5 m/s

รปท 5.3 แสดงแรงกระทาบนมวล m

วธทา 1) อาศยกฎของนวตนจะไดสมการการเคลอนทของมวล m คอ F (ω) - kx = ma หรอเขยนอยในรปสมการดฟเฟอเรนเชยล จะได

d xdt

2

2 = F sin t

−km x

โดยมเงอนไขเรมตน คอ t = 0 จะได x = 0, dxdt = -2.5 m/s

2) เปลยนรปสมการอนพนธอนดบสอง ใหอยในรปสมการอนพนธอนดบหนง

Page 217: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

210

โดยให v = dxdt ดงนน d v

d td xd t

2

2= แทนคา d xdt

2

2 จะได

dvdt =

F sin tmω

−km x

3) ใสคาดานขวามอของสมการอนพนธลงในโปรแกรม ดงน double Your Func (double t, double x)

{ return ( 92 *sin(5*t) - 32/2*x)

4) คอมไพลโปรแกรม Runge-Kutta 4_2 C. แลวปอนขอมลใหโปรแกรมทางาน จะไดผลลพธ

t (เวลา) x (ตาแหนง) ความเรว 0 0 -2.5

0.2 -0.4238 -1.3942 0.4 -0.47355 0.93288 0.6 -0.10963 2.40481 0.8 0.34041 1.72985 1.0 0.47874 -0.44879 1.2 0.19336 -2.15802 1.4 -0.24816 -1.89077 1.6 -0.44781 0.04745 1.8 -0.23828 1.85575 2.0 0.17308 1.90502

5) เปรยบเทยบกบคาแทจรง เมอหาคาตอบสมการอนพนธจะไดดงน

x = ( )F sin tω

ωm km 2−

dxdt = ( )

ω ω

ω

Fcos t

m km

2−

ให km = ω0

2 = ความถธรรมชาตของระบบ

Page 218: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

211

คาบของการสนของมวล คอ

T = 2πω

= 25π = 1.257 วนาท

ทเวลา t ใด ๆ ตาแหนงและความเรวจะมคาดงน

t ตาแหนง (m) ความเรว (m/s) 0 0 -2.5

0.2 -0.420 -1.350 0.4 -0.455 1.040 0.6 -0.070 2.475 0.8 0.378 1.634 1.0 0.480 -0.709 1.2 0.140 -2.400 1.4 -0.328 -1.885 1.6 -0.495 0.364 1.8 -0.206 2.278 2.0 0.272 2.098

ตวอยาง 5.5 จงหาคา x ท t = 0.6 h = 0.05 จากสมการอนพนธตอไปน

d xdt

2dxdt 100x 0

2

2 + + =

เงอนไขเรมตน x = 1 dxdt = 1 เมอ t = 0

วธทา 1) กาหนดให dxdt = z จดรปสมการใหมจะได

dzdt = -100x - 2z = f (t, x, z)

2) ใสเทอมดานขวามอลงในฟงกชน Your Func ดงน double Your Func (double t, double x, double z) { return (-100*x - 2*z); }

Page 219: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

212

3) คอมไพลโปรแกรม Runge-Kutta 4_2.C แลวปอนขอมลตามโจทย จะไดคาตอบจากโปรแกรม ท t = 0.6 x = 0.48735 โปแกรมจะแสดงผลลพธดงน Calculating the Solution of the 2st Differential Eqn. Using Runge-Kutta 's Method. Select the interval (default = 0.01) :0.1 X at initial condition = 0 (ในโจทยน คอ t) Y at initial condition = 1 (ในโจทยน คอ x) Z = dy/dx at initial condition = 1 (ในโจทย คอ dx/dt ) Find the Solution at X = 0.6 X = 0.60000 The Solution of DE.(Y) = 0.48735 dY/dx = 2.25608 Program stop completely. Goodbye. 4) คาตอบทแทจรงของสมการนคอ x = 0.469379 โปรแกรม 5.4 รายละเอยดของโปรแกรม Rungekutta4_2.C มดงตอไปน/* * Program 5.4 Runge-Kutta4_2.C * Purpose: Demonstrate how to find the Solution of the second differntial eqn by * by using 4th order Runge-Kutta's method. * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 29 Feb 96 **************************************************************/ #include <stdio.h> #include <math.h> /* Global Variable */ void GetInitialCondition(double*, double* ,double*,double* ); double GetXValue( void ); int RungKutta4_2(double init_x, double init_y,double init_z,\ double x, double h, double *solution1, double *solution2); void DisplaySolution(int, double ,double,double );

Page 220: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

213

double YourFunc(double, double, double); void main() { double h,init_x,init_y,init_z,x,y,z; double solvy,solvz ; int i,j,error; clrscr(); printf("\t\tCalculating the Solution of the 2st Differential Eqn.\n"); printf ("\t\t================================================\n"); printf("\t\t\t Using Runge-Kutta 's Method.\n"); printf("\t\t\t=============================\n"); GetInitialCondition(&h,&init_x,&init_y,&init_z); x = GetXValue(); error = RungeKutta4_2(init_x, init_y,init_z,x,h, &solvy,&solvz); DisplaySolution(error,x,solvy, solvz); printf("\n Program stop completely. Goodbye.\n"); } void GetInitialCondition (double *interval, double *x_point,\ double *y_point,double *z_point) { char buffer[225]; printf("\nSelect the interval (default = 0.01) :"); gets(buffer); *interval = atof(buffer); if (*interval == 0 ) *interval = 0.01; printf("\n X at initial condition = "); gets(buffer); *x_point = atof(buffer); printf("\n Y at initial condition = "); gets(buffer); *y_point = atof(buffer); printf("\n Z = dy/dx at initial condition = "); gets(buffer); *z_point = atof(buffer); } double GetXValue( ) {

Page 221: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

214

char buffer[250]; double x; printf("\n\tFind the Solution at X = ");gets(buffer); x=atof(buffer); return x; } void DisplaySolution(int err, double xval,double solution1, double solution2) { switch (err) { case 0 : { printf( "\n\tX = %13.5f \n ",xval); printf( " The Solution of DE.(Y) = %13.5f\n",solution1); printf( " dY/dx = %13.5f\n",solution2); break; } case 1 : { printf("\nThe interval of x mustn't be zero.\n"); break; } } /* switch (err) */ } double YourFunc(double t, double x, double y) { return(9/2*sin(5*t) - 32/2*x); } /*================== Function Start here. ==========================*/ int RungeKutta4_2(double init_x, double init_y,double init_z,double x,double h, double *solution1, double *solution2) /* Function Description: Determine the solution of the first order differential equation that giving the initial value conditon. by using 4th order Runge-Kutta's method. User's Define : None Calling Function : double YourFunc(double x, double y) Input : init_x, init_y, init_z -- initial value of x,y and dy/dx x -- where to find the solution.

Page 222: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

215

h -- interval of x Output : solution -- the solution of 1st order DE. Return : 0 -- if no error. 1 -- h = 0 *************************************************************************/ { int i,j; double current_y,current_x,current_z, ex_y,ex_x,ex_z; double k1y,k1z,k2y,k2z,k3y,k3z,k4y,k4z; if ( h <=0 ) return 1; current_y = init_y; current_x = init_x; current_z = init_z; while ( current_x < x ) { ex_x = current_x; ex_y = current_y; ex_z = current_z; current_x = ex_x + h; k1y = h*ex_z; k1z = h* YourFunc(ex_x, ex_y, ex_z); k2y = h* (ex_z + k1z/2); k2z = h*YourFunc(ex_x+h/2, ex_y+k1y/2, ex_z+k1z/2); k3y = h* (ex_z + k2z/2); k3z = h*YourFunc(ex_x+h/2, ex_y +k2y/2, ex_z + k2z/2); k4y = h* (ex_z + k3z); k4z = h*YourFunc(ex_x+h, ex_y + k3y, ex_z + k3z); current_y = ex_y + (k1y+2*k2y+2*k3y+k4y)/6; current_z = ex_z + (k1z + 2*k2z + 2*k3z + k4z)/6; } ; *solution1 = current_y; *solution2 = current_z; return 0; } /*=======================================================*/

Page 223: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

216

5.4 วธของอาดามส-มลตน การหาคาตอบคาถดไปของสมการอนพนธโดยวธรงเง-คตตาจะใชคาตอบจากคาทคานวณไดไวแลวกอนหนานนเพยง 1 คา เรยกวธแบบนวาเปนวธคานวณขนตอนเดยว (one step method) วธของอาดามส-มลตน เปนวธทหาคาตอบโดยใช 2 สตรควบคกน สตรแรกจะใชเปนตวทานาย (predict) คาตอบทได แลวจงใชสตรท 2 ปรบคา (corrrect) ทไดจากสตรท 1 จนไดคาความคลาดเคลอนนอยกวาทกาหนดไว ทงสตรท 1 และสตรท 2 ตองใชคาทไดจากขนตอนกอนหนานถง 4 จดมาชวยในการคานวณ เรยกวธนวาเปนวธคานวณหลายขนตอน (multi step method) หรอวธใชตวทานาย-ตวแกไข (predictor - corrector method) วธของอาดามส-มลตน ใชกบสมการอนพนธอนดบ 1 ซงมรปทวไปดงสมการ (5.1) คอ

dydx = f (x, y)

โดยทวไปฟงกชน f (x, y) สามารถแทนไดดวยพหนาม พหนามนจะแทนคา f(x,y) ไดใกลเคยงเมอกระจายให x มอนดบสงเทาทจะทาได วธนจะประมาณคาฟงกชนเปนพหนามถง x3 นนหมายถง ตองใชจด 4 จดในการพจารณา f (x, y) = f (x) = a+ bx + cx2 + dx3 แทนลงในสมการอนพนธ แลวอนทเกรทหาคา y จะได

dyy

yi

i

+

∫1

= (a bx cx dx )dx2 3+ + ++

∫xi

xi 1

.................... (5.12)

รป 5.4 แสดงการหาคาตอบโดยวธของอาดามส-มลตน

Page 224: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

217

เมอใหระยะหางของ xi และ xi+1 มคาเทากน คอเทากบ h อนทเกรทสมการ (5.12) แลวจะได

yi+1+ = y ah bh2

ch3

dh4i

2 3 4

+ + + + เขยนอยในรปเมทรกซ จะได

yi+1 = y h12 12 6 4 3

abhchdh

i 2

3

+ .................... (5.13)

คา a, b, c, d เปนตวทไมทราบคา เราสามารถหาคาคงทเหลานใหสมพนธกบคาฟงกชนทแตละจดไดดงน fi = a (x = 0) หรอ จด x1 fi+1 = a - hb + h2c (x = -h) หรอ จด xi-1 fi-2 = a - 2hb + 4h2c (x = -2h) หรอ จด xi-2 fi-3 = a -3hb + ah2c- 27 h3d (x = -3h) หรอ จด xi-3 เขยนอยในรปเมทรกซผกผน

abhchdh

ffff

2

3

i 3

i 2

i 1

i

=− −

− −

− −

16

0 0 0 62 9 18 113 12 15 61 3 3 1

.................... (5.14)

แทนคาสมการ (5.14) ลงในสมการ (5.13) จะได

yi+1 = y h24 (55f 59f 37f 9f )i i i 1 i 2 i 3+ + + −− − − ....................(5.15)

สมการ (5.15) ใชเปนตวทานายเพอทจะไดคาทใกลเคยงคาแทจรง จงหาสตรสาหรบใชปรบคาสมการ (5.15) อกสตรหนง สตรนไดจากการอนทเกรทโดยอาศยจด 4 จดของฟงกชน เชนเดยวกบทไดในสมการ (5.15) แตเลอนลาไปขางหนาอยหนงจด คอจด xi+1 , xi , xi-1 , xi-2 เมอแทนจดเหลานจะได

Page 225: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

218

ffff

abhchdh

i 2

i 1

i

i 1

2

3

+

=

− −− −

1 2 4 81 1 1 11 0 0 01 0 1 1

.................... (5.16)

เปลยนสมการ (5.17) ใหอยในรปเมทรกซผกผน แลวนาไปแทนคาในสมการ (5.13) จะได

yi+1 = y h24 (f 5f 19f 9f )i i 2 i 1 i i 1+ − + +− − + .................... (5.17)

เปนสตรทใชแกไขคาทานายใหไดใกลเคยงคาทแทจรงมากยงขน ตวอยาง 5.6 จากสมการอนพนธ

dydx - 0.5 y = 0 เงอนไขเรมตน y(0) = 1

จงหาคา y เมอ x = 0.4 กาหนดให h = 0.1 วธทา เมอใชวธออยเลอรทปรบปรงแลว หรอวธรงเง-คตตา หาคา y ทจด x ตาง ๆ จะได

i xi yi f(xi, yi) = 0.5y 0 0 1.0000000 0.5000000 f0 1 0.1 1.0512500 0.5256250 f1 2 0.2 1.1051267 0.5525634 f2 3 0.3 1.1617644 0.5808822 f3 4 0.4 ตองการหาคา y ทจดน f4

หาคาทานายจากสมการ (5.15)

y4 = y 0.124 ( 9f 37f 59f 55f )3 0 1 2 3+ − + − +

= 1.22133286

หาคา f4 = 12 y (คาทานาย)

= 12× 1.2213286

= 0.6106643 นาคาตาง ๆ ไปแทนลงในสมการ (5.17) เพอหาคาทแกไขปรบปรง

Page 226: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

219

y (ทปรบปรงแลว) = y 0.124 (f 5f 19f 9f )3 1 2 3 4+ − + +

= 1.2213292 คาทแทจรงของ y4 ท x = 0.4 ของสมการอนพนธนคอ 1.2214027 จะเหนวาคา y ทผานการปรบคาและแกไขแลวจะมคาใกลเคยงคาแทจรงมากกวาคาทานาย การนาฟงกชน Adams_Moulton ไปใชงาน ก. คาคงททตองนยาม - ข. การเรยกใชฟงกชน int Adams_Moulton (double init_x, double init_y, double x, double h, double*solution ) เมอ int_x, init_y เปนเงอนไขเรมตนของสมการอนพนธ x คอ จดทตองการหาคาตอบจากสมการอนพนธ h คอ ระยะหางของแตละชองเลก ๆ ของคา x solution คอ ตวแปรใชเกบคาตอบทคานวณได ค. ฟงกชนอนทเกยวของ double YourFunc (double x, double y, double z) ใชกาหนดฟงกชน f(x, y) ง. การสงคากลบ 0 ไมมขอผดพลาดใด ๆ เกดขน 1 h มคาเปนศนย 2 h มคามากเกนไปทาใหจานวนการวนรอบมากกวา 1 ลานครง หรอมคานอยเกนไปทาใหการวนรอบนอยกวา 4 ครง

Page 227: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

220

/* * Program 5.5 Adams-Moulton.C * Purpose: Demonstrate how to find the Solution of the first differntial eqn by * by using Predictor-corrector Method. * (Adams-Moulton's Method) * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 21 Apr 96 **************************************************************/ #include <stdio.h> #include <math.h> /* Global Variable */ void GetInitialCondition(double*, double* ,double* ); double GetXValue( void ); int Adams_Moulton(double init_x, double init_y,double x, double h, double *solution); void DisplaySolution(int, double ,double ); double YourFunc(double, double); void main() { double h,init_x,init_y,x,y; double solv ; int error; clrscr(); printf("\t\tCalculating the Solution of the 1st Differential Eqn.\n"); printf ("\t\t==================================================\n"); printf("\t\t\t Using Adams-Moulton's Method.\n"); printf("\t\t\t=============================\n"); GetInitialCondition(&h,&init_x,&init_y); x = GetXValue(); error = Adams_Moulton(init_x, init_y,x,h, &solv); DisplaySolution(error,x,solv); printf("\n Program stop completely. \n"); } void GetInitialCondition (double *interval, double *x_point, double *y_point) { char buffer[225];

Page 228: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

221

printf("\nSelect the interval (default = 0.01) :"); gets(buffer); *interval = atof(buffer); if (*interval == 0 ) *interval = 0.01; printf("\n X at initial condition = "); gets(buffer);*x_point = atof(buffer); printf("\n Y at initial condition = "); gets(buffer);*y_point = atof(buffer); } double GetXValue( ) {char buffer[250]; double x; printf("\n\tFind the Solution at X = ");gets(buffer); x=atof(buffer);return x; } void DisplaySolution(int err, double xval,double solution) { switch (err) { case 0 : { printf( "\n\tX = %13.5f ",xval); printf( " The Solution of DE. = %13.5f\n",solution); break; } case 1 : { printf("\nThe interval of x must greater than zero.\n"); break; } case 2 : { printf("\n Please change the value of 'h'. It's not fit to the program .\n"); break; } } /* switch (err) */ } /*================== Function Start here. ==========================*/ int Adams_Moulton(double init_x, double init_y,double x,double h, double *solution) /*

Page 229: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

222

Function Description: Determine the solution of the first order differential equation that giving the initial value conditon. by using Predictor-corrector method(Adams-Moulton) Using Runge-Kutta method to find the predictor value. User's Define : None Calling Function : double YourFunc(double x, double y) Input : init_x, init_y -- initial value of x,y x -- where to find the solution. h -- interval of x Output : solution -- the solution of 1st order DE. Return : 0 -- if no error. 1 -- h <= 0 2 -- h shoud be less or greater than this value, h must divide the interval between init_x and x into 4 (at least) to 1000000 (maximum). *************************************************************************/ { double f[5]; long int i,loop; double ex_y,ex_x,k1,k2,k3,k4; double predict_y, correct_y,tmp_y; if ( h <=0 ) return 1; ex_y = init_y; ex_x = init_x; loop = (x - init_x)/h; if (loop < 4 || loop > 1000000) return 2; for(i = 0 ; i < 5; i ++) f[i] = 0.0; for ( i = 0; i < loop; i++) { if ( i == loop-4) f[0] = YourFunc(ex_x,ex_y); if ( i == loop-3) f[1] = YourFunc(ex_x,ex_y); if ( i == loop-2) f[2] = YourFunc(ex_x,ex_y); if ( i == loop-1) f[3] = YourFunc(ex_x,ex_y); k1 = h* YourFunc(ex_x, ex_y); k2 = h*YourFunc(ex_x+h/2, ex_y+k1/2);

Page 230: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

223

k3 = h*YourFunc(ex_x+h/2, ex_y +k2/2); k4 = h*YourFunc(ex_x+h, ex_y + k3); tmp_y = ex_y; ex_y = ex_y + (k1+2*k2+2*k3+k4)/6; ex_x = ex_x + h; } /* for i */ predict_y = tmp_y +h*(55*f[3]-59*f[2]+37*f[1] -9*f[0])/24; f[4] = YourFunc(ex_x,predict_y); correct_y = tmp_y + h*(f[1] - 5*f[2] + 19*f[3] + 9*f[4])/24; *solution = correct_y; return 0; } /*=======================================================*/ double YourFunc(double t, double Q) { return(0.3*10*100*(20-2.5)*(20-t)/(100-2.5*t));} /********* End of the Program ***********/ 5.5 การนาไปแกปญหาทางฟสกส ตวอยาง 5.7 สมการการเคลอนทของนกกระโดดรมมวล m กก. มดงน

dvdt g

cm v= −

เมอ c คอสมประสทธแรงตานอากาศ = 12.5 กก/วนาท t คอเวลาเปนวนาท g = 9.81 ม./วนาท2 v คอ ความเรวของนกกระโดดรมทเวลา t ใด ๆ มหนวยเปน ม./วนาท ถานกกระโดดรมกระโดดจากบอลลนทลอยอยนง จงหาความเรวของนกกระโดดรม ซงมมวล(คน+รม) เทากบ 75 กก. ในชวง 0 ถง 20 วนาท วธทา 1) ใชโปรแกรม Runge4.C แกไขฟงกชน YourFunc ดงน double YourFunc (double t, double v) { return (9.81 -12.75/75*v); } 2) คอมไพลโปรแกรม Runge4.C ปอนขอมลโดยกาหนดให h = 0.01 เงอนไขเรมตนคอ เมอ t = 0, v = 0 ผลการคานวณจากโปรแกรมจะไดดงน

Page 231: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

224

3) ตรวจสอบคาตอบดวยวธวเคราะห สามารถหาความเรวของนกกระโดดรมโดยหาคาตอบของสมการอนพนธโดยวธแยกตวแปร

dv

gcm v

dt−

= ∫∫

จากเงอนไข t = 0 v = 0 จะได v = gm ( 1 - e-(c/m)t ) /c แทนคา t = 0 ถง t = 20 วนาท โดยเวนชวงละ 2 วนาท จะไดผลลพธดงตารางในขอ 2) เราอาจเขยนโปรแกรมใหคอมพวเตอรชวยคานวณไดดงน #include <stdio.h> #include <math.h> void main() { double t,v; for ( t = 0; t <=20; t=t+2){ v =9.81*75/12.5 - exp(-(12.4/75*t)); printf ( "t = %f -----> v = %f \n",t,v); } }

t v(from program) v(exact value ผลตาง0 0 0 02 16.68497 16.57235 -0.112624 28.69059 28.47867 -0.211926 37.24268 37.03269 -0.209998 43.37051 43.17829 -0.1922210 47.7613 47.59356 -0.1677412 50.90743 50.76569 -0.1417414 53.16173 53.04468 -0.1170516 54.77701 54.68202 -0.0949918 55.92963 55.85835 -0.0712820 56.76023 56.70348 -0.05675

Page 232: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

225

เมอใหเวลาผานไปนาน ๆ ความเรวจะมคาคงทท 58.86 ม./วนาท ทความเรวนทาใหแรงดงดดของโลกมคาเทากบแรงตานทานของอากาศ ตวอยาง 5.8 อตราการไหลของปรมาณความรอนในโลหะตวนารปทรงกระบอกอนหนงระหวางจด 2 จดใด ๆ หาไดจาก

dQdt kA

dTdx=

เมอ k คอคาสภาพการนาความรอน = 0.3 cal.cm/s C A คอพนทหนาตดของทรงกระบอก ในทน เทากบ 10 ตารางเซนตเมตร L คอความยาวของแทงโลหะ เทากบ 20 เซนตเมตร x คอระยะระหวางจด 2 จดทใชวดปรมาณความรอน = 2.5 เซนตเมตร dT/dx คอความลาดชนของอณหภมหาไดจาก

dTdt

L x txt=

− −−

100 20100

( )( )

เมอเรมตน t = 0 ปรมาณความรอน(Q) = 0 จงหาปรมาณความรอนทไหลผานแทงโลหะในชวง t = 0 ถง t = 10 วนาท วธทา 1) ใชโปรแกรม Runge4.C โดยเปลยนฟงกชน YourFunc ดงน double YourFunc (double t, double v) { return (0.3*10*100*(20-2.5)*(20-t)/(100 -2.5*t)); } 2) คอมไพลโปรแกรม Runge4.C ใหโปรแกรมทางานโดยกาหนดให h = 0.01 วนาทเงอนไขเรมตน เมอ t = 0 Q = 0 ปอนคา t ตาง ๆ กน จะไดผลลพธดงน

t 0 2 4 6 8 10 Q(จากโปรแกรม) 0 2045.68 3984.19 5782.85 7435.84 8924.35 Q (จากการวเคราะห 0 2045.68 3974.76 5774.20 7427.97 8917.35 3) หาความสมพนธของ Q และ t โดยหาคาตอบของสมการอนพนธโดยวธแยกตวแปร

dQ kA Ltt dt= −

−−∫∫ 100 2 5 20

100 2 5( . ) ( )( . )

แยกเปนเศษสวนยอย แลวจงอนทเกรตจะได

Q kA Lt

t C= − + − +100 2 5 2 5 8 40( . )( . ln( )) หาคาคงท C โดยแทนคา t = 0 จะได Q = 0 จะได C = -4200 ln 40

Page 233: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

226

Q = 100 (21t + 420 ln (40-t) - 420 ln 40) แทนคา t = 2,4,6,8 และ 10 วนาท จะได Q จากการคานวณดงตารางในขอ 2) ตวอยาง 5.9 วตถทรงกลมผวเรยบ มคาสมประสทธแรงตานอากาศ (c) 0.46 ตกลงอยางอสระ สมการความเรงของวตถมดงน

dvdt g c

rm v= −

12

22ρπ

เมอ g คอความเรงเนองจากแรงดงดดของโลก 9.81 m/s2 ρ คอ ความหนาแนนของอากาศ 12 kg/m3 v คอความเรวของวตถ r คอ รศมของทรงกลม 0.01 m. m คอ มวลของทรงกลม 0.01 kg เมอเรมตน t = 0 ความเรวตนของทรงกลม เทากบ 0 จงหาความเรวของทรงกลมเมอเวลาผานไป 0.2, 0.4, 0.6, 0.8 และ 1 วนาท วธทา 1) สมการอนพนธแบบสามญ ของโจทยขอนคอ

dvdt v= −9 81 0 0867 2. .

2) เลอกใชโปรแกรม Runge4.C เปลยนฟงกชนในโปรแกรมยอย YourFunc ดงน double YourFunc (double t, double v) { return ( 9.81 - 0.0867*v*v); } 3) คอมไพลโปรแกรม แลวใหโปรแกรมทางาน ปอนเงอนไขเรมตนและจด t ทตองการหาคาตอบ จะไดผลลพธดงน

t (second) v ( m/s) v(m/s) คาทแทจรง 0.2 1.94005 1.939974 0.4 3.75517 3.754631 0.6 5.35067 5.349070 0.8 7.23829 6.674722 1.0 8.16491 7.727358

Page 234: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

227

4) คาทแทจรงของ v หาไดจาก

dv

vdt9 81 0 0867 2. .− = ∫∫

แยกเทอมทางซายมอออกเปนเศษสวนยอยแลวจงอนทเกรต

12 9 81 0 0867

9 81 0 08679 81 0 0867. * . ln . .. .+−

⎛⎝⎜ ⎞

⎠⎟+ =v

vA t

เมอ A คอคาคงท แทนคา t = 0 , v = 0 จะได A = 0 จดรปสมการใหมจะไดเปน

ve

e

t

t=−−

⎛⎝⎜ ⎞

⎠⎟9 81

0 086711

2 9 81 0 08672 9 81 0 0867

..

. * .

. * .

แทนคา t = 0.2, 0.4, 0.6, 0.8 และ 1 จะไดคาความเรวจากการคานวณเปรยบเทยบกบคาทไดจากโปรแกรมดงตารางในขอ 3) ตวอยาง 5.10 วงจรประกอบดวยตวตานทาน R = 2 โอหม ขดลวดเหนยวนา L = 0.1 เฮนร และตวเกบประจไฟฟา C = 0.02 ฟารด ความตางศกยตกครอมปลาย AB มคา 10 โวลต จงหากระแสไฟฟาทไหลในวงจรในชวง t = 0 จนถง t = 0.6 วนาท กาหนดให t=0 , I = 1, dI/dt = 0 ให ∆t = 0.01 วนาท และแสดงคาทก t = 0.1 วธทา 1) สมการความตางศกยไฟฟาของวงจรหาไดจาก .................. (A) ตองการหากระแสไฟฟาในวงจร เพราะวา I = dq/dt หาอนพนธสมการความตางศกยไฟฟาอกครงจะได ................(B) ให dI/dt = z สมการ (B) จะเปลยนรปเปนสมการอนพนธอนดบหนง

dzdt

ILC

RL z f x I z= − − = ( , , )

2) ใชโปรแกรม Runge4_2.C แกไขฟงกชน YourFunc ดงน

LdIdt RI

qC VAB+ + =

Ld I

dtRdIdt

IC

2

2 0+ + =

Page 235: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

228

double YourFunc (double t, double I, double z ) { return (-I/(0.1*0.02)-2*z/0.1); } 3) คอมไพลแลวใหโปรแกรมทางาน ปอนเงอนไขเรมตน และคา t แตละคา เพอความสะดวกไมตองปอนคา t หลาย ๆ ครง เราอาจแกไข main program และสวนทใชแสดงผลของโปรแกรม Runge4_2.C ใหมดงน /* * Program 5.6 P5_10.C * Purpose: Runge4_2.C was modified specific for problem 5.10 * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 28 Apr 96 **************************************************************/ #include <stdio.h> #include <math.h> /* Global Variable */ void GetInitialCondition(double*, double* ,double*,double* ); double GetXValue( void ); int RungKutta4_2(double init_x, double init_y,double init_z,\ double x, double h, double *solution1, double *solution2); void DisplaySolution(int, double ,double,double ); double YourFunc(double, double, double); void main() { double h,init_x,init_y,init_z,x,y,z; double solvy,solvz ; int i,j,error; clrscr(); printf("\t\tCalculating the Solution of the 2nd Differential Eqn.\n"); printf ("\t\t====================================================\n"); printf("\t\t\t Using Runge-Kutta 's Method.\n"); printf("\t\t\t=============================\n"); /* GetInitialCondition(&h,&init_x,&init_y,&init_z); */ h = 0.01; init_x = 0; init_y = 1; init_z = 0;

Page 236: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

229

/* x = GetXValue(); */ j =0; for (x = 0.01; x <= 0.6 ; x= x+h) { j =j+1 error = RungeKutta4_2(init_x, init_y,init_z,x,h, &solvy,&solvz); if (j == 5) { DisplaySolution(error,x,solvy, solvz); j = 0; } } } void DisplaySolution(int err, double xval,double solution1, double solution2) { switch (err) { case 0 : { printf( "\n\tt = %13.5f ",xval); printf( " I = %13.5f",solution1); break; } case 1 : { printf("\nThe interval of x mustn't be zero.\n"); break; } } /* switch (err) */ }

Page 237: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

230

ผลลพธจากโปรแกรมจะเปนดงน เวลา กระแสทไดจากโปรแกรม คากระแสทแทจรง 0.05000 0.58291 0.582899 0.10000 0.01415 0.014164 0.15000 -0.20517 -0.205153 0.20000 -0.13968 -0.139672 0.25000 -0.01607 -0.016072 0.30000 0.04086 0.040848 0.35000 0.03269 0.032686 0.40000 0.00639 0.006395 0.45000 -0.00784 -0.007833 0.50000 -0.00749 -0.007486 0.55000 -0.00203 -0.002025 0.60000 0.00143 0.001427 4) ทดลองตรวจสอบหาคาทแทจรง เมอแทนคา R,L และ C ลงในสมการ (B) จะได

0 1 2 0 02 02

2. .d I

dt

dIdt

I+ + =

สมการ characteristic คอ 0.1k2 + 2k + 1/0.02 = 0 k = -10 ±20i คาตอบทวไปของสมการนคอ I e A t B tt= +−10 20 20( cos sin ) หาคาคงท A และ B โดยอาศยเงอนไขเรมตน เมอ t = 0, I = 1, dI/dt = 0 จะได A = 1 และ B = 0.5 คาตอบเฉพาะของสมการ (B) ทสอดคลองกบโจทยขอน คอ I e t tt= +−10 20 0 5 20(cos . sin ) แทนคา t = 0.1 จนถง t = 0.6 วนาท จะไดคาแทจรงเปรยบเทยบกบคาทไดจากคอมพวเตอรดงตารางในขอ 3)

Page 238: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

231

เมอนาผลลพธทไดมาวเคราะหจะเหนวาเมอเวลาผานไปนาน ๆ กระแสทไหลในวงจรจะมคาเปนศนย โดยการลดลงของกระแสจะแกวงไปมาเปนฟงกชนของผลรวมของคา sine และ cosine ดงรป 5.5

รป 5.5 แสดงการลดลงของกระแสในวงจร RLC ในตวอยาง 5.10 5.6 บทสรป ในบทนมฟงกชนยอย 4 ฟงกชน ใชสาหรบหาคาตอบสมการอนพนธแบบสามญและมลกษณะเชงเสน บอกเงอนไขเรมตนของสมการมาให วธของออยเลอรแบบปรบปรงแลว วธรงเง-คตตา และวธอาดมส-มลตน ใชกบสมการอนพนธทมอนดบเทากบหนง วธรงเง-คตตาแบบท 2 (RungeKutta4_2) ใชกบสมการอนพนธทมอนดบเทากบสอง วธของออยเลอรแบบปรบปรงแลว เปนวธทอาศยกฎสเหลยมคางหมมาชวยคานวณ ถาฟงกชน f(x,y) ของสมการอนพนธไมเปนสมการเสนตรง โอกาสทจะเกดความคลาดเคลอนมมาก ความเทยงตรงของวธนคอนขางตา เมอเปรยบเทยบกบวธอน แตขนตอนวธงายตอการทาความเขาใจและงายสาหรบการเขยนเปนโปรแกรมคอมพวเตอร โดยทวไปเราจะนยมใชวธของรงเง-คตตาอนดบสแกปญหาสมการอนพนธแบบสามญ เพราะมความเทยงตรงสง ขนตอนวธการคานวณไววางใจได ไมทาใหเกดอาการวนรอบจนคอมพวเตอร “แฮงค” ได เราสามารถเปลยนรปสมการอนพนธอนดบสองใหกลายเปนอนพนธอนดบหนง แลวใชวธรงเง-คตตาหาคาตอบได วธของอาดมส-มลตนจดเปนวธหลายขนตอน ตองหาคาทานาย(โดยใชวธออยเลอรหรอวธรงเง-คตตา)แลวจงนาคาทานายนนไปแกไขใหถกตองยงขน จงเปนวธคอนขางซบซอน เพราะเกยวโยงกบวธอน ๆ ซงเปนผลใหการเขยนโปรแกรมทาไดลาบาก ทกวธทกลาวมาใชหาคาตอบของสมการอนพนธแบบสามญเทานน ไมสามารถนาไปใชหาคาตอบสมการอนพนธยอยได (Partial Differential Equation)

Page 239: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

232

This is a blank page.

Page 240: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

233

บทท 6 การประมาณคาในชวง(Interpolation)

บางครงขอมลทางฟสกสทไดมา เราไมสามารถหาสตรหรอสมการทางคณตศาสตรมาอธบายขอมลชดนได เชน จากการจบเวลาและวดระยะทางจากจดเรมตนของการเคลอนทของวตถชนหนง ไดขอมลดงน เวลาผานไป (วนาท)(x) 1 2 3.5 ระยะทาง (เมตร) f(x) 25.1 40.4 50 เราตองการทราบวาเมอเวลาผานไป 2.5 วนาท วตถจะเคลอนทไดระยะทางเทาใด สมการการเคลอนทของวตถเราไมสามารถหาได การหาระยะทางเมอเวลาผานไป 2.5 วนาทจงตองใชการประมาณคาในชวง โดยการนาขอมลทมอยไปสรางเปนสมการพหนาม และใชเปนตวแทนของ สมการการเคลอนท f(x) ทเวลาใด ๆ จากนน จงแทนคา x = 2.5 วนาท ลงไป จะไดระยะทาง (โดยประมาณ) ของวตถชนนน ขอมลทจะใชในการประมาณคาจะตองมคา x ไมซากน ชวงหางของคา x ไมจาเปนตองเทากน หรอจะเทากนกได คา x ทตองการหาคา f(x) ตองอยในชวงของขอมลทเกบได คา x ทเกนขอบเขตของขอมลอาจจะไดคาประมาณทคลาดเคลอนจากความเปนจรงมาก ถามขอมล N คา จะไดสมการพหนามทใชเปนตวแทนของขอมลมดกรสงสด N - 1 เสมอ 6.1 การประมาณคาแบบลากรองจ (Lagrange’s Interpolation) ถาเราเกบขอมลได n + 1 คา คอ (x0, y0), (x1, y1) ... (xn, yn) เราสามารถกาหนดฟงกชนพหนามทเปนตวแทนของขอมลชดนไดดงน P(x) = a0 (x - x1)(x - x2) ... (x - xn) + a1 (x - x0)(x - x2)(x - x3) ... (x - xn) + a2 (x - x0)(x - x1)(x - x3) ... (x - xn) + .... + an (x - x0)(x - x1)(x - x3) ... (x - xn -1) ............... (6.1) จะตองหาคาสมประสทธ a0, a1, a2, ... an วามคาเทาใด เมอแทนคา x = x0 ลงในสมการ (6.1) จะได

Page 241: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

234

a0P(x0 )

(x0 x1)(x0 x2 ). . . (x0 xn )= − − −

เมอแทนคา x = x1 ลงในสมการ (6.1) จะได

a1P(x1)

(x1 x0 )(x1 x2 ). . . (x1 xn )= − − −

ในทานองเดยวกน เมอแทนคา x = xn จะได

a nP(xn )

(xn x0 )(xn x1)(xn x2 ). . . (xn xn 1)= − − − − −

แทนคาสมประสทธ a1, a2, ... an ทไดลงในสมการ (6.1) จะไดฟงกชนทเปนโพลโนเมยล ดงน

P(x)P(x0 )(x - x1 )(x x2 ). . . (x xn )(x0 x1)(x0 x2 ). . . (x0 xn )

P(x1 )(x x0 )(x x2 ). . . (x - x n )(x1 xn )(x1 x2 ). . . (x1 xn )

. . .P(x n )(x x0 )(x x1 )(x x2 ). . . (x x n 1 )

(xn x0 )(x n x1 ). . . (x n x n 1)

=− −

− − −+

− −

− − −

+ +− − − − −− − − −

...............(6.2) กาหนดให

L i (x)(x x0 )(x x1)(x x2 ). . . (x xn )

(x i x0 )(x i x1)(x i x2 ). . . (x i xn )=− − − −− − − −

L i (x)(x x j )

(x i x j)i 0j 0โดยทi j

n=

−−=

=≠

∏ ............... (6.3)

จงสามารถเขยนสมการ 6.2 ใหสนลงไดดงน

P(x) P(x) L i (x)i 0n

= =∑ ...............(6.4)

Page 242: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

235

ตวอยาง 6.1 ขอมลจากการทดลองวดระยะทางของวตถทเวลาตาง ๆ กน บนทกไดดงน เวลา (วนาท) การขจด (ม.) 1 25.1 2 40.4 3.5 50.0 เมอเวลาผานไป 2.5 วนาท วตถมการขจดเทาใด วธทา ตองการหาวา f(x = 2.5) มคาเทาใด โดยอาศยสมการ (6.4) สามารถเขยนฟงกชนพหนามเปนตวแทนของสมการการเคลอนทไดดงน

P(x)

P(x0 )(x x1)(x x2 )(x0 x1)(x0 x2 )

P(x1)(x x0 )(x x2 )(x1 x0 )(x1 x2 )

P(x2 )(x x0 )(x x1)(x2 x0 )(x2 x1)

=− −

− − +− −

− −

+− −

− −

แทนคา x0 = 1, x1 = 2, x2 = 3.5 และแทนคาฟงกชนจากขอมลทได

P(x) 25.1(x 2)(x 3.5)(1 2)(1 3.5)

40.4(x 1)(x 3.5)(2 1)(2 3.5)

50(x 1)(x 2)(3.5 1)(3.5 2)=

− −− − +

− −− − +

− −− −

แทนคา x = 2.5 P(x) = 45.38 ม. ขอมลของตวอยางนไดมาจากสตร f(x) = 30x - 4.8x2 คาทแทจรงของ f(x) เมอ x = 2.5 วนาท คอ 45.00 ม. การใชวธของลากรองจประมาณคามขอสงเกตดงน - สมการพหนามทมอนดบ n ไดมาจากขอมล n + 1 ชด จะมไดเพยงสมการเดยว นนคอเราไมสามารถหาสมการพหนามอกสมการหนงทมอนดบ n เทากน สอดคลองกบขอมล n + 1 ชดเดยวกนน - คาความคลาดเคลอนทเกดจากการประมาณคานจะมากนอยเพยงใดขนอยกบ 1. การกระจายของคา xi วธของลากรองจนใชไดทงกรณทคา xi หางเปนระยะเทา ๆกน หรอไมเทากน คาสมบรณของความคลาดเคลอนจะมคานอยทสดตรงบรเวณชวงกลาง ๆ ของขอมล xi และมแนวโนมมคามากขนอยางรวดเรวตรงบรเวณขอบหรอตอนรมของขอมล 2. ขนาดของชวงกวางของขอมลแตละคา (xi - xi-1) มผลตอขนาดและการกระจาย (distribution) ของความคลาดเคลอน คาสงสดของความคลาดเคลอนจะเขาใกลศนยเมอขนาด

Page 243: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

236

ชวงกวางมคาลดลง ในทางกลบกน ถาขนาดของชวงกวางของขอมลกวางขน คาสงสดของความคลาดเคลอนจะเพมขนตามไปดวย ถาขนาดชวงกวางคงท แตเพมจานวนขอมลเขาไป คาความคลาดเคลอนสงสดม แนวโนมจะลดลงจนถงคา n คาหนง จากนน คาความคลาดเคลอนสงสดจะคอย ๆ เพมคาขน นนเปนการบอกวา การเพมจานวนขอมลเขาไปมาก ๆ มใชวาจะทาใหสมการพหนามทไดจากการประมาณคาเขาใกลเคยงกบฟงกชนจรง ๆ ของมน โดยทว ๆ ไปถา n มคามาก ๆ ควรหลกเลยงหรอทาดวยความระมดระวง 3. ถงแมจะไมมเกณฑใด ๆ บอกวาอนดบ n เทาใดจงจะเกดความคลาดเคลอนนอยทสด แตมขอแนะนาทวไปคอ ควรใชพหนามทมอนดบตา ๆ กบชดขอมล x ทมชวงกวางแคบ ๆ การใชฟงกชน Lagrange interpolation ผใชตองกาหนดตวคงทและตวแปร ดงน ก. คาคงททตองกาหนด #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E_16 ข. การเรยกใชฟงกชน int LagrangeInterpolation (int n, double xdata [ARRAY_SIZE), double ydata [ARRAY_SIZE],double xval, double * yval) n คอ จานวนขอมลของชด (x data, y data) x data, y data เปนอะเรยเกบขอมลทได โดยจะเกบไวท x data [0], ..... x data [n-1] และ y data [0], ... y data [n-1] xval คอ คา x ทตองการหาคาประมาณของฟงกชน vval คอ คาประมาณของฟงกชน ค. ผลลพธ คาประมาณทไดจากการคานวรจะถกเกบไวใน yval ง. การสงคากลบ 0 - ไมมขอผดพลาด 1 - ขอมล x มคาซากน

Page 244: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

237

รายละเอยดของโปรแกรม 6.1 Lagran1.C มดงน /* Program 6.1 - Lagrange1.C * Purpose: Demonstate Lagrangian Interpolation. * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 4 May 94 **************************************************************/ #include <stdio.h> #include <math.h> #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E-16 /* for double precision */ /* Global Variable */ void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]); int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE]); double GetXValue( void ); int LagrangeInterpolation(int,double xdata[ARRAY_SIZE], double ydata[ARRAY_SIZE],double ,double*); void DisplayResult(int, double ,double ); void main() { double x[ARRAY_SIZE],y[ARRAY_SIZE]; double xval,yval; int n=0, /* Number of data pairs */ error=0; int i,j,done=0; char msg[150],ans[1]; clrscr(); printf("\t\tLagrangian Interpolation\n"); printf ("\t\t========================\n"); Initialize(x,y); n = GetData(x,y);

Page 245: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

238

while ( !done && error==0) { xval = GetXValue(); yval =0; error = LagrangeInterpolation(n,x,y,xval,&yval); DisplayResult(error,xval,yval); printf("\nDo you want to interpolate any value ? (Y/N) : "); *ans=getch(); if (*ans == 'n' || *ans == 'N') done = 1; } printf("\nProgram Stop.\n"); } void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]) { int i =0; for (i=0; i < ARRAY_SIZE; i++) { x[i]=0; y[i]=0; } } int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE]) { int i,j,numdata=0; char buffer[225]; do { printf("\nNumber of data ( 1 - %d) :",ARRAY_SIZE-1); gets(buffer); numdata = atoi(buffer); }while (numdata < 1 || numdata >= ARRAY_SIZE); for (i=1; i <= numdata; i++) { printf("\tX[%2d] = ",i);gets(buffer); xdata[i-1]= atof(buffer); printf("\tY[%2d] = ",i);gets(buffer); ydata[i-1]= atof(buffer); printf("\n"); } return numdata;

Page 246: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

239

} double GetXValue( ) { char buffer[250]; double x; printf("\n\tEnter X valude to interpolate = ");gets(buffer); x=atof(buffer); return x; } void DisplayResult(int err, double xval,double yval) { switch (err) { case 0 : { printf( "\tX = %13.5f ",xval); printf( " Interpolated Y = %13.5f\n",yval); break; } case 1 : { printf("\nX data must be unique.\n"); printf("Some data of x have the same value\n"); break; } } /* switch (err) */ } /*=============== Function Start here. ======================*/ int LagrangeInterpolation(int n, double xdata[ARRAY_SIZE], double ydata[ARRAY_SIZE],double xval,double *yval) { /* Function Description: Evaluate f(x) by Lagrange Interpolation. User's Define : #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20e-16 Input : n -- number of data pair (x,y) xdata,ydata -- given data. xval -- x value for interpolation. Output : yval -- interpolated result,F(x),

Page 247: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

240

will be store here. Return : 0 -- if no error. 1 -- Some data of x have the same value. */ int i,j; double temp; for (i =0; i < n;i++) { temp=1.0; for (j=0; j < n; j++ ){ if (i!=j) { if (fabs(xdata[i]-xdata[j]) <= ZERO_APPROACH) return 1; /* x data must be unique */ temp = temp*(xval-xdata[j])/(xdata[i]-xdata[j]); } } *yval = *yval + temp*ydata[i]; } return 0; } /*==========================================================*/ ตวอยาง 6.2 จะใชวธการประมาณคาของลากรองจหาคา sin 35๐ เมอรคา sin ของมมตาง ๆ ดงน

x sin x 30 0.5 45 0.7071 60 0.8660 90 1

วธทา จากสมการ (6.4) ฟงกชนพหนามทใชแทนฟงกชน sin คอ

P(x) sinx0.5(x 45)(x 60)(x 90)(30 45)(30 60)(30 90)

0.7071(x 30)(x 60)(x 90)(45 30)(45 60)(45 90)

0.8660(x 30)(x 45)(x 90)(60 30)(60 45)(60 90)

1.0(x 30)(x 45)(x 60)(90 30)(90 45)(90 60)

= =− − −

− − −+

− − −− − −

+− − −

− − −+

− − −− − −

แทนคา x = 35 จะได sin 35๐ = 0.57737 คาจรง ๆ ของ sin 35๐ คอ 0.5735764

Page 248: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

241

หมายเหต ฟงกชน sin x สามารถเขยนฟงกชนพหนามไดดงน

sinx x x43!

x55!

x77! . . .= − + − +

เมอใชโปรแกรม 6.1 Lagrange.C ชวยในการคานวณในตวอยาง 6.2 จะไดผลลพธ ดงรป 6.1 รป 6.1 ผลลพธการประมาณคาจากตวอยาง 6.2 Lagrangian Interpolation ================== Number of data ( 1 - 50) :4 X[ 1] = 30 Y[ 1] = 0.5 X[ 2] = 45 Y[ 2] = 0.7071 X[ 3] = 60 Y[ 3] = 0.8660 X[ 4] = 90 Y[ 4] = 1 Enter X valude to interpolate = 35 X = 35.00000 Interpolated Y = 0.57378 Do you want to interpolate any value ? (Y/N) :n Program Stop. 6.2 การประมาณคาโดยใชผลตางถกหาร (Method of divided difference) ขอเสยของการประมาณคาโดยใชวธของลากรองจ คอ ตองคณและหารซา ๆ กนหลาย ขนตอน เมอมการเพมขอมลเขาหรอลบขอมลออกเพยงคาเดยวกตองเรมตนคานวณใหมซาเดม อกครง ถามขอมล n + 1 ชด คอ (x0, y0), (x1, y1) ... (xn, yn) ฟงกชนพหนามทเปนตวแทนของขอมลชดนเขยนไดเปน

P(x) a0 (x x0 )a1 (x x0 )(x - x1 a2 ...

(x x0 )(x x1)... (x x n-1)a n= + − + − ++ − − −

) ...............(6.5)

กาหนดสญลกษณเพอใหการเขยนงายและกะทดรดขน ดงน

f0 f[x1, x0 ]f(x1) f(x0 )

x1 x0f[x0 , x1]= =

−− =

เรยกวา ผลตางถกหารระหวาง x0 และ x1

Page 249: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

242

ผลตางถกหารอนดบทสองของขอมล x0, x1, x2 คอ

2 f0 f[x2 , x1, x0 ]f[x2 , x1] f[x1, x0 ]

x2 x0f(x0 )

(x0 x1)(x0 x2 )f(x1)

(x1 x0 )(x1 x2 )f(x2 )

(x2 x0 )(x2 x1)

= =−−

= − − + − − + − − ผลตางถกหารอนดบท n คอ

n f0 f[xn , xn 1, . . . x0 ]

f[xn , xn 1, . . . x1] f[xn 1, xn 2 , . . . x0 ]xn x0

= −

= − − − −−

เพอใหดงายขน นามาสรางเปนตารางจะเปนดงน

xi f[xi] f[xi, xi-1] f[xi, xi-1, xi-2] f[xi, xi-1, xi-2, xi-3] x0 f0 f[x1, x0] x1 f1 f[x2, x1, x0] f[x2, x1] f[x3, x2, x1, x0] x2 f2 f[x3, x2, x1] f[x3, x2] f [x4, x3, x2, x1] x3 f3 f[x4, x3, x2] f[x4, x3] x4 f4 หาสมประสทธ a0, a1, ...an ในสมการ (6.5) โดยการแทนคา x = x0, x = x1, x = xn เมอ x = x0 จะได a0 = P(x0) = f[x0] x = x1 จะได P(x1) = a0 +(x1 - x0) a1 = f(x0) + (x1 - x0) a1

a1 = f(x1) f(x0 )x1 x0

−−

= f[x1, x0]

x = x2 จะได P(x2) = a0 + (x2 - x0) a1 + (x2 - x0)(x2 - x1) a2 = f(x0) + (x2 - x0) f[x1 - x0] + (x2- x0)(x2 - x1) a2

a2 = f(x2 ) f(x0 ) (x2 x0 ) f[x1, x0 ](x2 x0 )(x2 x1)

− − −− −

Page 250: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

243

= f[x2 , x0 ] f[x1, x0 ]x2 x1

−−

= f[x2, x1, x0] เมอแทนคา x = xn an = f[xn, xn-1, ..., x2, x1, x0] แทนคา a0, a1, ... an ในสมการ (6.5) จะไดพงกชนพหนามใชประมาณคาขอมลในชวง x0, x1, ...xn ไดดงน P(x) = f[x0] + (x - x0) f[x1, x0] + (x - x0)(x - x1) f[x2, x1, x0] + (x - x0)(x - x1)(x - x2) f[x3, x2, x1, x0] + ... + (x - x0)(x - x1) ... (x - xn) f[xn, xn-1, ... x0] ...............(6.6) การนาฟงกชน Divided Difference ไปใช ผใชตองกาหนดคาคงทและตวแปรดงน ก. คาคงททตองกาหนด #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E-16 ข. การเรยกใชฟงกชน int Divided Difference (int n, double xdata [ARRAY_SIZE), double ydata [ARRAY_SIZE], double xval, double *yval) n คอ จานวนขอมล xdata, ydata คอ อะเรยเกบขอมล (x, y) ทไดจากการทดลอง โดยจะเรมตนทคา 0 ถง n -1 xval คอ คา x ทตองการทราบคาประมาณของ y yval คอ คาประมาณของฟงกชนทไดจากการคานวณ ค. ผลลพธ คาประมาณทไดจะถกเกบไวใน yval ง. การสงคากลบ 0 - ไมมขอผดพลาด 1 - คา x มคาซากน รายละเอยดของโปรแกรม 6.2 Divdif.C มดงน

Page 251: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

244

/* Program 6.2 - DivDif.c * Purpose: Demonstate Interpolation using divided difference. * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 9 May 94 **************************************************************/ #include <stdio.h> #include <math.h> #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E-16 /* for double precision */ /* Global Variable */ void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]); int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE]); double GetXValue( void ); int DividedDifference(int,double xdata[ARRAY_SIZE], double ydata[ARRAY_SIZE],double ,double*); void DisplayResult(int, double ,double ); void main() { double x[ARRAY_SIZE],y[ARRAY_SIZE]; double xval,yval; int n=0, /* Number of data pairs */ error=0; int i,j,done=0; char msg[150],ans[1]; clrscr(); printf("\t\tInterpolation using Divided Difference.\n"); printf ("\t\t=====================================\n"); Initialize(x,y); n = GetData(x,y); while ( !done && error==0) {

Page 252: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

245

xval = GetXValue(); yval =0; error = DividedDifference(n,x,y,xval,&yval); DisplayResult(error,xval,yval); printf("\nDo you want to interpolate any value ? (Y/N) : "); *ans=getch(); if (*ans == 'n' || *ans == 'N') done = 1; } printf("\nProgram Stop Normally.\n"); } void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]) { int i =0; for (i=0; i < ARRAY_SIZE; i++) { x[i]=0; y[i]=0; } } int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE]) { /* Keep out: data store in array from 0 to n-1 */ int i,j,numdata=0; char buffer[225]; do { printf("\nNumber of data ( 1 - %d) :",ARRAY_SIZE-1); gets(buffer); numdata = atoi(buffer); }while (numdata < 1 || numdata >= ARRAY_SIZE); for (i=1; i <= numdata; i++) { printf("\tX[%2d] = ",i);gets(buffer); xdata[i-1]= atof(buffer); printf("\tY[%2d] = ",i);gets(buffer); ydata[i-1]= atof(buffer); printf("\n"); } return numdata;

Page 253: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

246

} double GetXValue( ) { char buffer[250]; double x; printf("\n\tEnter X valude to interpolate = ");gets(buffer); x=atof(buffer); return x; } void DisplayResult(int err, double xval,double yval) { switch (err) { case 0 : { printf( "\tX = %13.5f ",xval); printf( " Interpolated Y = %13.5f\n",yval); break; } case 1 : { printf("\nX data must be unique.\n"); printf("Some data of x have the same value\n"); break; } } /* switch (err) */ } /*================== Function Start here.=====================*/ int DividedDifference(int n,double xdata[ARRAY_SIZE], double ydata[ARRAY_SIZE],double xval,double*yval) { /* Function Description: Evaluate f(x) by Divided Difference method. User's Define : #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20e-16 Input : n -- number of data pair (x,y) xdata,ydata -- given data.

Page 254: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

247

xval -- x value for interpolation. Output : yval -- interpolated result,F(x), will be store here. Return : 0 -- if no error. 1 -- Some data of x have the same value. (x not unique). */ double dif_table[ARRAY_SIZE][ARRAY_SIZE]; int i,j; int err =0; double denum,temp,factor; for (i =0; i < n;i++) dif_table[i][0] = ydata[i]; for (j=1; j < n; j++ ){ for( i=j; i<n; i++) { denum = xdata[i]-xdata[i-j]; if (fabs(denum) <= ZERO_APPROACH) { err = 1; } else { dif_table[i][j] =(dif_table[i][j-1] - dif_table[i-1][j-1])/denum; } } /* for i */ } /* for j */ /* display table for inspection */ for (i =0; i<n; i++) { printf("%7.5f ",xdata[i]); for(j=0; j<=i ; j++) { printf( "%7.5f ", dif_table[i][j]); } printf("\n"); } /***************************/ temp = xval; *yval=0; for(i=0; i<n; i++) {

Page 255: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

248

if (i==0) { factor=1; } else { factor =factor*(temp-xdata[i-1]); } *yval=*yval+factor*dif_table[i][i]; } return err; } /*============================================*/ ตวอยาง 6.3 จากการทดลองแกวงลกตมนาฬกาทมความยาวของเสนเชอก (x) ตาง ๆ กน พบวา คาบการแกวง (y) มคาดงน

x 01 0.3 0.4 0.7 0.9 y 0.63 1.09 1.27 1.68 1.90

จงหาคาบการแกวงของลกตมนาฬกาทความยาวของเสนเชอก 0.35 ม. วธทา นาไปเขยนเปนตาราง

i xi f[xi] f[xi, xi-1] f[xi, xi-1, xi-2] f[xi, xi-1, xi-2, xi-3] 0 0.1 0.63 1 0.3 1.09 2.3 2 0.4 1.27 1.8 -1.67 3 0.7 1.68 1.37 -1.08 0.98 4 0.9 1.90 1.1 -0.54 0.9

ฟงกชนพหนามทเปนตวแทนขอมลชดน หาไดจากสมการ (6.6) จะได f(x = 0.35) = 0.63 + 0.25 ×2.3 + 0.25 ×0.05 (-1.67) + 0.25 ×0.05 ×(-0.05)(0.98) = 1.1835125 วนาท ใชโปรแกรม 6.2 DivDif.C คานวณ จะไดผลลพธดงรป 6.2

Page 256: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

249

รป 6.2 ผลลพธของตวอยาง 6.3 Interpolation using Divided Difference. =============================== Number of data ( 1 - 50) :5 X[ 1] = 0.1 Y[ 1] =0.63 X[ 2] = 0.3 Y[ 2] =1.09 X[ 3] = 0.4 Y[ 3] =1.27 X[ 4] = 0.7 Y[ 4] =1.68 X[ 5] = 0.9 Y[ 5] =1.90 Enter X valude to interpolate = 0.35 0.10000 0.63000 0.30000 1.09000 2.30000 0.40000 1.27000 1.80000 -1.66667 0.70000 1.68000 1.36667 -1.08333 0.97222 0.90000 1.90000 1.10000 -0.53333 0.91667 -0.06944 X = 0.35000 Interpolated Y = 1.18354 Do you want to interpolate any value ? (Y/N) :N Program Stop Normally. การใชผลตางถกหารประมาณคาจะสะดวกตรงท ถาเดมมขอมลอยจานวนหนง เมอคานวณไดพงกชนพหนามแลว ตอมามขอมลเพมเขามาอก 1 คา สามารถทาตอไดโดยใชตารางเดม โดยเพมคาผลตางถกหารอกแถวหนง การคานวณจะทาตอจากเดมไมตองเรมตนคานวณใหม 6.3 วธพหนามดกรสาม (Culbic Spline Interpolation) การใชวธของลากรองจ และวธผลตางถกหารประมาณคาของฟงกชนทจดใด ๆ ถามขอมล n + 1 จด พหนามทใชประมาณคาจะมดกรนอยกวาหรอเทากบ n เสมอ จะไดสมการพหนาม 1 สมการ ผานจดขอมลทกจด ทจดอน ๆ พหนามอนนจะไมสอดคลองกบคาฟงกชนทแทจรง ยง n มคามากยงจะเกดการแกวงของฟงกชนมากตามไปดวย เพอทจะใหพหนามทไดสอดคลองกบคาฟงกชนทแทจรง สามารถทาไดโดยใชพหนามทมดกรตามาประมาณคา โดยแบงชวงของขอมลออกเปนชวง แตละชวงจะไดพหนามดกรตาแตละชด นาพหนามเหลานมาเรยงตอกนกจะไดพหนามทเปนตวแทนของขอมลชดน เรยกฟงกชนพหนามนวา Spline function

Page 257: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

250

การประมาณคาโดยแบงขอมลออกเปนชวง ๆ วธทงายทสดคอ ลากเสนตรงเชอมระหวางจดขอมล 2 จด ตอกนไปเรอย ๆ ขอเสยของวธนคอ เสนกราฟจะมลกษณะไมเรยบ ซงผดเพยนไป จากเสนกราฟทแทจรง พหนามทใชเชอมเปนเสนตรงระหวางจด 2 จด x0 x1 x2 . . . . . . xn รป 6.3 แสดงการลากเสนตรงเชอมระหวางจด เราอาจใชพหนามดกรสอง ซงเปนกราฟพาราโบลาเชอมระหวางจดเหลาน ตรงจดตอจะตองมความชนเทากน เสนกราฟจงจะเรยบไมมจดหกมม เราเรยกวธนวา Spline of degree 2 หรอ quatratic spline) x0 x1 . .... xn รป 6.4 แสดงการใชเสนกราฟพาราโบลาเชอมระหวางจด พหนามทนยมใชกนมาคอพหนามดกรสาม เพราะจะไดกราฟมลกษณะเปนเสนโคงเรยบเปนธรรมชาตดกวาพหนามดกรสอง เรยกวธนวา Cubic Spline Interpolation ในแตละชวงขอมลจะไดพหนามอนดบสาม นาพหนามแตละชวงมาตอกนจะไดเปนพหนามซงสอดคลองกบขอมล ชดน ถามขอมล n + 1 ชด คอ x0, x1, ...xn คา x จะตองเรยงลาดบจากนอยไปมาก จะไดขอมล n ชวง ใหพหนาม (xi, yi) ถง (xi+1, yi+1) มรปสมการทวไปดงน

Page 258: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

251

รป 6.5 การใชสมการกาลงสามเชอมจดแตละชวง Pi(x) = ai + bi (x - x1) + ci (x - xi)2 + di (x - xi)3

เมอ i = 0, 1, .... n ............... (6.7) xi คอ ขอมลคาท i x คอ จดทตองการหาคาประมาณ f (x) โดยท xi < x< xi+1 จากสมการ (6.7) จะเหนวาแตละชวงมตวไมทราบคาคอ ai, bi, ci และ di ชวงละ 4 คา กาหนดใหระยะหางระหวางชวง (hi) คอ hi = xi+1 - xi

การหาคา ai, bi, ci และ di ทาไดโดยอาศยเงอนไขตอไปน ก. Pi(x) เปนพหนามในชวง [xi, xi+1] เมอ i = 0, 1, ... n-1 ข. เมอแทนคา xi ลงใน Pi(x) จะตองไดคาเทากบ f(xi) เสมอ Pi(x) = f(x1) ค. ตรงจดทบรรจบกนของขอมลของพหนามแตละชวงทพบกนจดนจะตองเทากน Pi+1(xi+1) = Pi(xi+1)

ง. อนพนธอนดบหนงทจดเชอมตอภายในแตละชวงจะตองมคาเทากน Pi+1 (xi+1) = Pi (xi+1) จ. อนพนธอนดบสองทจดเชอมตอภายในแตละชวงจะตองมคาเทากน Pi+1 (xi+1) = Pi (xi+1) ฉ. อนพนธทจดเรมตน อาจเปนกรณใดกรณหนงดงตอไปน 1. Free boundary Condition กาหนดใหอนพนธอนดบสอบทจดปลายทงสองมคาเปน ศนย

Page 259: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

252

P′ (x0) = P′ (xn) = 0 2. Clamped boundary Condition กาหนดใหอนพนธอนดบหนงมคาดงน P′(x0) = f′ (x0) P′(xn) = f′(xn) จากสมการ (6.7) แทนคา x = xi และอาศยเงอนไขขอ ข. จะได P(xi) = ai = f(xi) = yi ............... (6.8) จากสมการ (6.7) แทนคา x = xi+1 และอาศยเงอนไขขอ ค. จะได ai+1 = yi+1 = ai + bihi + cihi

2 + dihi3 ............... (6.9)

เมอหาอนพนธอนดบหนงและสองของสมการ (6.7) จะได ′P (x) = bi + 2ci (x - xi) + 3di (x - xi)2 .............. (6.10) ′′P (x) = 2ci + 6di (x - xi) .............. (6.11) จากสมการ (6.10) และ (6.11) แทนคา x = xi จะได bi = P (xi) .............. (6.12)

ci = ′′P (x i )2 = S(i)

2 .............. (6.13) เมอ S เปนอนพนธอนดบสอง จากเงอนไขขอ 4 ′ +Pi+1(x i 1) = ′ +Pi (x i 1) = bi+1 จากสมการ แทนคา x = xi+1 อาศยเงอนไขขอ ง. และสมการ จะได ′ + = + = + +Pi (x i 1) b i 1 bi 2ci h i 3di h i2 .............. (6.14) i = 0, 1, ...., n-1 จากสมการ แทนคา x = xi+1 อาศยเงอนไขขอ จ. และสมการ จะได ′′ + = + = +Pi (x i 1) 2ci 6d i h i 2ci 1 .............. (6.15) i = 0, 1, ..., n-1

จะได d ici 1 ci

3h i= + −

.............. (6.16)

แทนคา di ลงในสมการ (6.9)

a i 1 a i b i h ih i

2

3 (2ci ci 1)+ = + + + + .............. (6.17)

Page 260: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

253

แทนคา di ลงในสมการ (6.14) b i 1 b i h i (c i c i 1)+ = + + + .............. (6.18) จากสมการ (6.17) หาคา bi โดยการยายขาง จะได

b i1

h i(a i 1 a i )

h i3 (2ci ci 1)= + − − + + ............. (6.19)

เปลยนคา i เปน i - 1

b i 11

hi 1(a i a i 1)

h i 13 (2ci 1 ci )− =

−− − − −

− + .............. (6.20)

จากสมการ (6.18) เปลยนจาก i+1 เปน i b i b i 1 h i 1(ci 1 ci )= − + − − + .............. (6.21) แทนคา bi จากสมการ (6.19) และ bi-1 จากสมการ (6.20) จะได

hi-1ci-1 + 2(hi-1 + hi) cc + hici+1 = 3h i

(ai+1 - ai) - 3

h i -1(ai - ai-1) .............. (6.22)

เมอ i = 1 ถง n-1 เขยนสมการ (6.22) ใหอยในรปอนพนธอนดบสอง โดยอาศยสมการ (6.13) จะได

hi-1si + 2(hi-1 + hi) Si + hiSi+1 = ba i 1 a i

h i(a i a i 1)

h i 1+ −

−− −−

⎡⎣⎢

⎤⎦⎥

เพอใหดงาย แทนคา (hi-1 + hi) ดวย ui และ ในวงเลบดานขวามอดวย vi hi-1Si + 2uiSi + hiSi+1 = 6 Vi .............. (6.23) ใชไดกบทก ๆ จด ยกเวนทจดปลายทงสอง อาศยเงอนไข ขอ ฉ. 1 เรยกวาเปนการสไปลนแบบธรรมชาต เปนการกาหนดวาเสนกราฟทจดปลายมลกษณะเปนเชงเสน ′′ = ′′ =P0 Pu 0 เขยนสมการ (6.23) ใหอยในรปของเมตรกซไดดงน

Page 261: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

254

สาหรบขอมล n + 1 คา

1 0 0 0h u1 h1 00 h1 u2 h2

hn 2 un 1 h n 10 0 1

s0s1s2

sn 1sn

6

0v1v2

vn 10

... ... ...

... ... ...

... ... ...... ... ... ... ... ... ...... ... ... ...... ... ... ...

... ...

− − −

⎢⎢⎢⎢⎢⎢⎢

⎥⎥⎥⎥⎥⎥⎥

⎢⎢⎢⎢⎢⎢⎢

⎥⎥⎥⎥⎥⎥⎥

=

⎢⎢⎢⎢⎢⎢⎢

⎥⎥⎥⎥⎥⎥⎥

เมอใชเงอนไข ขอ ฉ. 2 เปนการสไปลนแบบบงคบทจดปลาย กาหนดใหคาอนพนธอนดบแรกทจดปลายทงสองมคาดงน ′ = ′ =f (x0 ) A , f (xn ) B ทจดเรมตน จะได

2h0s0 h1s1 6a1 a 0

h06M+ =

−− =

⎝⎜

⎠⎟A

ทจดปลาย จะได

h n 1sn 1 2hnsn 6 Ba n a n 1

hn 16N− − + = −

− −

−=

⎝⎜

⎠⎟

⎣⎢

⎦⎥

เขยนใหอยในรปเมตรกซ จะไดเปน

2h0 h1 0 0h0 u1 h1 00 h1 u2 h2

hn 2 un 2 hn 10 hn 1 2hn 1

s0s1s2

sn 1sn

... ... ... ...

... ... ... ...

... ... ... ...... ... ... ... ... ... ... ...... ... ... ... ...... ... ... ... ...

...

− − −− −

⎢⎢⎢⎢⎢⎢⎢

⎥⎥⎥⎥⎥⎥⎥

⎢⎢⎢⎢⎢⎢⎢

⎥⎥⎥⎥⎥⎥⎥

=

⎢⎢⎢⎢⎢⎢⎢

⎥⎥⎥⎥⎥⎥⎥

6

MV1V2

Vn 1N

...

Page 262: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

255

ตวอยาง 6.4 ทดสอบการประมาณคา โดยใชวธพหนามดกรสามทงสองแบบกบขอมลททราบคาฟงกชนทแทจรง x 0 1 2 3 4 y -8 -7 0 19 56 จงหาคา y เมอ x = 2.5 วธทา ขอมลชดนไดมาจากสมการ y = x3-8 เมอ x = 2.5 ควรได คา y = 7.625 และจะ ตรวจสอบคาอนพนธอนดบสอง (si) ของแตละวธดวยวาใกลเคยงความจรงเพยงใด ก. ใชวธสไปลนแบบธรรมชาต

1 0 0 00 4 1 01 1 4 10 0 1 40 0 0 1

s0s1s2s3s4

03672

1080

⎢⎢⎢

⎥⎥⎥

⎢⎢⎢⎢

⎥⎥⎥⎥

⎢⎢⎢⎢

⎥⎥⎥⎥

=

ใชโปรแกรม 3.1 Gauss Eli.C หาคา S0, ... Sn โดยตดสมการสดทายทง เพราะรวา S4 = 0 จะไดคา S0 = 0, S1 = 6.4285, S2 = 10.2857, S3 = 24.4285, S4 = 0 เมอ x = 2.5 จะไดคา y = 7.33036 ข. วธสไปลนแบบบงคบ โดยใชเงอนไข ′ = ′ =f (0) 0 , f (4) 48

2 1 0 0 01 4 1 0 00 1 4 1 00 0 1 4 10 0 0 1 2

S0S1S2S3S4

63672

10866

⎢⎢⎢⎢

⎥⎥⎥⎥

⎢⎢⎢⎢

⎥⎥⎥⎥

=

⎢⎢⎢⎢

⎥⎥⎥⎥

จะไดคา S0 = 0, S1 = 6, S2 = 12, S3 = 18, S4 = 24 พบวาคา Si ตรงกบคาทแทจรง เมอ x = 2.5 โดยใชวธนจะไดคา y = 7.625 การใชฟงกชน FreeCubicSpline ผใชตองกาหนดตวคงทและตวแปร ดงน ก. คาคงททตองกาหนด #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E_16

Page 263: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

256

ข. การเรยกใชฟงกชน int FreeCubicSpline (int n, double xdata [ARRAY_SIZE), double ydata [ARRAY_SIZE],double xval, double * yval) n คอ จานวนขอมลของชด (x data, y data) xdata, ydata เปนอะเรยเกบขอมลทได โดยจะเกบไวท xdata [0], ..... xdata [n-1] และ ydata [0], ... ydata [n-1] xval คอ คา x ทตองการหาคาประมาณของฟงกชน vval คอ คาประมาณของฟงกชนทไดจากการคานวณ ค. ผลลพธ คาประมาณทไดจากการคานวณจะถกเกบไวใน yval ง. การสงคากลบ 0 - ไมมขอผดพลาด 1 - ขอมล x มคาซากน 2 - ขอมล x ไมเรยงลาดบจากนอยไปมาก 3. - จานวนขอมลนอยกวา 2 4. - คา x ทใชประมาณคา y อยนอกขอบเขตของขอมล รายละเอยดของโปรแกรม 6.3 Free_Spline.C /* Program 6.3 - Fre_Spli.C * Purpose: Demonstrate how to create a cubic spline interpolant to * a set of n-1 point. * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 26 May 94 **************************************************************/ #include <stdio.h> #include <math.h> #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E-16 /* for double precision */ /* Global Variable */ void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]);

Page 264: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

257

int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE]); double GetXValue( void ); int FreeCubicSpline(int,double xdata[ARRAY_SIZE], double ydata[ARRAY_SIZE],double ,double*); void DisplayResult(int, double ,double ); void main() { double x[ARRAY_SIZE]; double y[ARRAY_SIZE]; double xval,yval; int n=0, /* Number of data pairs */ error=0; int i,j,done=0; char msg[150],ans[1]; clrscr(); printf("\t\tInterpolation using Free Cubic Spline.\n"); printf ("\t\t=====================================\n"); Initialize(x,y); n = GetData(x,y); while ( !done ) { xval = GetXValue(); yval =0; error = FreeCubicSpline(n,x,y,xval,&yval); DisplayResult(error,xval,yval); if (error == 0 || error > 3){ printf("\nDo you want to interpolate any value ? (Y/N) : "); *ans=getch(); if (*ans == 'n' || *ans == 'N') done = 1; else done=0; } else { done=1; } } printf("\n\nProgram Stop Normally.\n"); }

Page 265: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

258

void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]) { int i =0; for (i=0; i < ARRAY_SIZE; i++) { x[i]=0; y[i]=0; } } int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE]) { /* Keep out: data store in array from 0 to n-1 */ int i,j,numdata=0; char buffer[225]; do { printf("\nNumber of data ( 1 - %d) :",ARRAY_SIZE-1); gets(buffer); numdata = atoi(buffer); }while (numdata < 1 || numdata >= ARRAY_SIZE); for (i=1; i <= numdata; i++) { printf("\tX[%2d] = ",i);gets(buffer); xdata[i-1]= atof(buffer); printf("\tY[%2d] = ",i);gets(buffer); ydata[i-1]= atof(buffer); printf("\n"); } return numdata; } double GetXValue( ) { char buffer[250]; double x; printf("\n\tEnter X value to interpolate = ");gets(buffer); x=atof(buffer); return x; }

Page 266: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

259

void DisplayResult(int err, double xval,double yval) { switch (err) { case 0 : { printf( "\n\tX = %13.5f ",xval); printf( " Interpolated Y = %13.5f\n",yval); break; } case 1 : { printf("\nX data must be unique.\n"); printf("Some data of x have the same value\n"); break; } case 2 : { printf("\n data are not in increasing order.\n"); break; } case 3 : { printf("\n Data must more than 2....!!!\n"); break; } case 4 : { printf("\n X value is out of data. \n"); break; } } /* switch (err) */ } /*================== Function Start here. ==========================*/ int FreeCubicSpline(int n,double xdata[ARRAY_SIZE], double ydata[ARRAY_SIZE],double xval,double*yval) { /* Ref: 'Numerical Analysis', Richar L. Burden, J. Douglas Faires PWS Publishing Company,USA, 1993. */ /* Function Description: Construct a cubic spline interpolant to a set of n-1 points. The second derivative

Page 267: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

260

is assume to be zero at the end points. User's Define : #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20e-16 Input : n -- number of data pair (x,y) xdata,ydata -- given data. begin from 0 to n-1. xval -- x value for interpolation. Output : yval -- interpolated result,F(x), will be store here. Return : 0 -- if no error. 1 -- Some data of x have the same value. (x not unique). 2 -- x data are not in ascending order 3 -- n < 2 4 -- x value is out of range. */ int i,j; int done =0; double a[ARRAY_SIZE],b[ARRAY_SIZE],c[ARRAY_SIZE],d[ARRAY_SIZE]; double h[ARRAY_SIZE],v[ARRAY_SIZE],l[ARRAY_SIZE]; double m[ARRAY_SIZE],s[ARRAY_SIZE]; double diff_x; if ( n < 2) return 3; for (i =0; i < n;i++) a[i] = ydata[i]; for (i=0; i<n-1; i++) { h[i] = xdata[i+1]-xdata[i]; if ( h[i] < 0) return 2 ; if (fabs(h[i]) <= ZERO_APPROACH) return 1; } for (i=1; i<n-1; i++) v[i] = 3*(a[i+1]-a[i])/h[i] -3*(a[i]-a[i-1])/h[i-1]; l[0]=0; m[0]=0; s[0]=0; for (i=1; i< n-1; i++) { l[i] = 2*(xdata[i+1]-xdata[i-1]) - h[i-1]*m[i-1];

Page 268: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

261

m[i] = h[i]/l[i]; s[i] = (v[i] - h[i-1]*s[i-1])/l[i]; } l[n-1]=1; s[n-1]=0; c[n-1] =0; for (i = n-2 ; i >= 0; i--) { c[i] = s[i]-m[i]*c[i+1]; b[i] = (a[i+1]-a[i])/h[i] - h[i]*(c[i+1]+2*c[i])/3; d[i] = (c[i+1] -c[i])/(3*h[i]); } /* for debug or studying only */ printf("\n\t\t\ta(i)\t\tb(i)\t\tc(i)\t\td(i)\n"); for (i = 0 ; i<n-1; i++) printf(" Spline %2d\t %10.5f\t%10.5f\t%10.5f\t%10.5f\n",i+1,a[i],b[i],c[i],d[i]); /******************************/ i=0; while (!done && i < n) { if ( xval < xdata[0] || xval > xdata[n-1] ) return 4; if (xdata[i] > xval) done=1; i+=1; } if (i > n) return 4; j=i-2; diff_x = xval-xdata[j]; *yval = a[j]+b[j]*diff_x +(c[j]*diff_x+ d[j]*diff_x*diff_x)*diff_x; return 0; } การใชฟงกชน ClampedCubicSpline ผใชตองกาหนดตวคงทและตวแปร ดงน ก. คาคงททตองกาหนด #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E_16 ข. การเรยกใชฟงกชน int ClampedCubicSpline (int n, double xdata [ARRAY_SIZE), double ydata [ARRAY_SIZE], double deriv_start, double deriv_end, double xval, double * yval)

Page 269: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

262

n คอ จานวนขอมลของชด (x data, y data) xdata, ydata เปนอะเรยเกบขอมลทได โดยจะเกบไวท xdata [0], ..... xdata [n-1] และ ydata [0], ... ydata [n-1] deriv_start, deriv_end คาอนพนธอนดบแรกทจดเรมตนและจดปลาย xval คอ คา x ทตองการหาคาประมาณของฟงกชน vval คอ คาประมาณของฟงกชนทไดจากการคานวณ ค. ผลลพธ คาประมาณทไดจากการคานวณจะถกเกบไวใน yval ง. การสงคากลบ 0 - ไมมขอผดพลาด 1 - ขอมล x มคาซากน 2 - ขอมล x ไมเรยงลาดบจากนอยไปมาก 3. - จานวนขอมลนอยกวา 2 4. - คา x ทใชประมาณคา y อยนอกขอบเขตของขอมล รายละเอยดของโปรแกรม 6.4 Clp_spli.C /* Program 6.4 - Clp_Spli.c * Purpose: Demonstate how to create the clamped cubic spline interpolant * to a set of n-1 point. * Author : Wachara R. * Office : Dept of Science. Rajamangala Institute of Technology. * Language: Turbo C v.2.0 * Last update : 1 June 94 **************************************************************/ #include <stdio.h> #include <math.h> #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20E-16 /* for double precision */ /* Global Variable */ void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]); int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE],double*,double*); double GetXValue( void ); int ClampedCubicSpline(int,double xdata[ARRAY_SIZE],

Page 270: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

263

double ydata[ARRAY_SIZE],double,double,double ,double*); void DisplayResult(int, double ,double ); void main() { double x[ARRAY_SIZE]; double y[ARRAY_SIZE]; double xval,yval; int n=0, /* Number of data pairs */ error=0; int i,j,done=0; char msg[150],ans[1]; double deriv_left,deriv_right; clrscr(); printf("\t\tInterpolation using Clamped Cubic Spline.\n"); printf ("\t\t=====================================\n"); deriv_left = deriv_right = 0; Initialize(x,y); n = GetData(x,y,&deriv_left,&deriv_right); while ( !done ) { xval = GetXValue(); yval =0; error = ClampedCubicSpline(n,x,y,deriv_left,deriv_right,xval,&yval); DisplayResult(error,xval,yval); if (error==0 || error > 3) { printf("\nDo you want to interpolate any value ? (Y/N) : "); *ans=getch(); if (*ans == 'n' || *ans == 'N') done = 1; } else { done =1; } } printf("\n Good Bye.\n"); } void Initialize(double x[ARRAY_SIZE],double y[ARRAY_SIZE]) { int i =0; for (i=0; i < ARRAY_SIZE; i++) {

Page 271: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

264

x[i]=0; y[i]=0; } } int GetData(double xdata[ARRAY_SIZE],double ydata[ARRAY_SIZE],double* dl ,double* dr) { /* Keep out: data store in array from 0 to n-1 */ int i,j,numdata=0; char buffer[225]; do { printf("\nNumber of data ( 1 - %d) :",ARRAY_SIZE-1); gets(buffer); numdata = atoi(buffer); }while (numdata < 1 || numdata >= ARRAY_SIZE); for (i=1; i <= numdata; i++) { printf("\tX[%2d] = ",i);gets(buffer); xdata[i-1]= atof(buffer); printf("\tY[%2d] = ",i);gets(buffer); ydata[i-1]= atof(buffer); printf("\n"); } printf("\nThe first derivative of the start point : ");gets(buffer); *dl = atof(buffer); printf("\nThe first derivative of the end point : ");gets(buffer); *dr = atof(buffer); return numdata; } double GetXValue( ) { char buffer[250]; double x; printf("\n\tEnter X valude to interpolate = ");gets(buffer); x=atof(buffer);

Page 272: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

265

return x; } void DisplayResult(int err, double xval,double yval) { switch (err) { case 0 : { printf( "\n\tX = %13.5f ",xval); printf( " Interpolated Y = %13.5f\n",yval); break; } case 1 : { printf("\nX data must be unique.\n"); printf("Some data of x have the same value\n"); break; } case 2 : { printf("\n data are not in increasing order.\n"); break; } case 3 : { printf("\n Data must more than 2....!!!\n"); break; } case 4 : { printf("\n X value is out of data. \n"); break; } } /* switch (err) */ } /*================== Function Start here. ==========================*/ int ClampedCubicSpline(int n,double xdata[ARRAY_SIZE], double ydata[ARRAY_SIZE],double deriv_start, double deriv_end,double xval,double*yval) { /* Ref: 'Numerical Analysis', Richar L. Burden, J. Douglas Faires PWS Publishing Company,USA, 1993. */

Page 273: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

266

/* Function Description: Construct a cubic spline interpolant to a set of n-1 points. The second derivative is assume to be zero at the end points. User's Define : #define ARRAY_SIZE 51 #define ZERO_APPROACH 2.20e-16 Input : n -- number of data pair (x,y) xdata,ydata -- given data. begin from 0 to n-1. deriv_start ,deriv_end -- The first derivative of the start point and the end point. xval -- x value for interpolation. Output : yval -- interpolated result,F(x), will be store here. Return : 0 -- if no error. 1 -- Some data of x have the same value. (x not unique). 2 -- x data are not in ascending order 3 -- n < 2 4 -- x value is out of range. */ int i,j; int done =0; double a[ARRAY_SIZE],b[ARRAY_SIZE],c[ARRAY_SIZE],d[ARRAY_SIZE]; double h[ARRAY_SIZE],v[ARRAY_SIZE],l[ARRAY_SIZE]; double m[ARRAY_SIZE],s[ARRAY_SIZE]; double diff_x; if ( n < 2) return 3; for (i =0; i < n;i++) a[i] = ydata[i]; for (i=0; i<n-1; i++) { h[i] = xdata[i+1]-xdata[i]; if ( h[i] < 0) return 2 ; if (fabs(h[i]) <= ZERO_APPROACH) return 1; } v[0]= 3*(a[1]-a[0])/h[0]-3*deriv_start; v[n-1] = 3*deriv_end-3*(a[n-1]-a[n-2])/h[n-2];

Page 274: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

267

for (i=1; i<n-1; i++) v[i] = 3*(a[i+1]-a[i])/h[i] -3*(a[i]-a[i-1])/h[i-1]; l[0]=2*h[0]; m[0]=0.5; s[0]=v[0]/l[0]; for (i=1; i< n-1; i++) { l[i] = 2*(xdata[i+1]-xdata[i-1]) - h[i-1]*m[i-1]; m[i] = h[i]/l[i]; s[i] = (v[i] - h[i-1]*s[i-1])/l[i]; } l[n-1]=h[n-2]*(2-m[n-2]); s[n-1]=(v[n-1]-h[n-2]*s[n-2])/l[n-1]; c[n-1] = s[n-1]; for (i = n-2 ; i >= 0; i--) { c[i] = s[i]-m[i]*c[i+1]; b[i] = (a[i+1]-a[i])/h[i] - h[i]*(c[i+1]+2*c[i])/3; d[i] = (c[i+1] -c[i])/(3*h[i]); } /* for debug or studying only */ printf("\n\t\ta(i)\t\tb(i)\t\tc(i)\t\td(i)\n"); for (i = 0 ; i<n-1; i++) printf(" Spline %2d\t %10.5f\t%10.5f\t%10.5f\t%10.5f\n",i+1,a[i],b[i],c[i],d[i]); /******************************/ i=0; while (!done && i < n) { if ( xval < xdata[0] || xval > xdata[n-1] ) return 4; if (xdata[i] > xval) done=1; i+=1; } if (i > n) return 4; j=i-2; diff_x = xval-xdata[j]; *yval = a[j]+b[j]*diff_x +(c[j]*diff_x+ d[j]*diff_x*diff_x)*diff_x; return 0; } /*====================End of program =====================*/

Page 275: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

268

ตวอยาง 6.5 จากการทดลองวดคาสมประสทธของการทะลผาน (transmittance) ของกระจกชนดหนง ทความยาวคลนของแสงตาง ๆ กน ไดผลการทดลองดงน ความยาวคลน (nm)

400 430 470 510 520 550 590 650

transmittance .192 0.224 0.247 0.232 0.229 0.228 0.196 0.162

จงประมาณคา transimittance ของกระจก เมอความยาวคลน = 450 และ 600 nm โดยใชวธการสไปลนแบบธรรมชาต (จากการทดลองไดคา 0.228 และ 0.190) วธทา ใชโปรแกรม 6.3 Fre_spli.C คานวณจะไดผลลพธดงรป 6.6 จะไดคา 0.23719, 0.18708 รป 6.6 แสดงผลการคานวณทไดจากโปรแกรม Fre_spli.C Interpolation using Free Cubic Spline. ============================ Number of data ( 1 - 50) :8 X[ 1] =400 Y[ 1] =0.192 X[ 2] =430 Y[ 2] =0.224 X[ 3] =470 Y[ 3] =0.247 X[ 4] =510 Y[ 4] =0.232 X[ 5] =520 Y[ 5] =0.229 X[ 6] =550 Y[ 6] =0.228 X[ 7] =590 Y[ 7] =0.196 X[ 8] =650 Y[ 8] =0.162 Enter X value to interpolate =450 a(i) b(i) c(i) d(i) Spline 1 0.19200 0.00112 0.00000 -0.00000 Spline 2 0.22400 0.00096 -0.00001 -0.00000 Spline 3 0.24700 0.00001 -0.00002 0.00000 Spline 4 0.23200 -0.00041 0.00001 0.00000 Spline 5 0.22900 -0.00016 0.00002 -0.00000 Spline 6 0.22800 -0.00031 -0.00002 0.00000 Spline 7 0.19600 -0.00089 0.00001 -0.00000

Page 276: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

269

X = 450.00000 Interpolated Y = 0.24025 Do you want to interpolate any value ? (Y/N) :y Enter X value to interpolate = 600 a(i) b(i) c(i) d(i) Spline 1 0.19200 0.00112 0.00000 -0.00000 Spline 2 0.22400 0.00096 -0.00001 -0.00000 Spline 3 0.24700 0.00001 -0.00002 0.00000 Spline 4 0.23200 -0.00041 0.00001 0.00000 Spline 5 0.22900 -0.00016 0.00002 -0.00000 Spline 6 0.22800 -0.00031 -0.00002 0.00000 Spline 7 0.19600 -0.00089 0.00001 -0.00000 X = 600.00000 Interpolated Y = 0.18789 Do you want to interpolate any value ? (Y/N) :n Program Stop Normally. -------------------------------------- 6.4 การนาไปประมาณคาปญหาฟสกสอน ๆ ตวอยาง 6.6 กระแสไฟฟาในวงจรหนงมความสมพนธกบเวลาดงน

t 0 0.1250 0.2500 0.3750 0.5000 i 0 6.2402 7.7880 4.8599 0.0000

จงหากระแสไฟฟาทเวลา t = 0.40 วนาท วธทา ใชการประมาณคาแบบลากรองจ (โปรแกรม Langran1.C) ผลลพธจะไดดงน

Page 277: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

270

Lagrangian Interpolation =================== Number of data ( 1 - 50) :5 X[ 1] = 0 Y[ 1] = 0 X[ 2] = 0.1250 Y[ 2] = 6.240 X[ 3] = 0.2500 Y[ 3] = 7.7880 X[ 4] = 0.3750 Y[ 4] = 4.8599 X[ 5] = 0.5000 Y[ 5] = 0.0 Enter X valude to interpolate = 0.4 X = 0.40000 Interpolated Y = 3.92009 รป 6.7 ผลการคานวณโดยอาศยการประมาณคาแบบลากรองจ ตวอยาง 6.6 ตวอยาง 6.7 ความเรงเนองจากแรงโนมถวงของโลก (g) ทความสงตาง ๆ กนโดยวดจากพนโลก มดงน

y(n) 0 20,000 40,000 60,000 80,000 g(m/s) 9.8100 9.7487 9.6879 9.6278 9.5682

จงคานวณหาคา g ทความสง 55,000 ม. ความถกตองถงทศนยม 4 ตาแหนง วธทา ใชการประมาณคาแบบผลตางถกหาร (DivDif.C) หาคา g ทความสง 50000 ฟต จะไดคาตอบดงน Interpolation using Divided Difference. ============================== Number of data ( 1 - 50) :5 X[ 1] = 0 ------------> y (ความสง) Y[ 1] = 9.81 ----------------------> g X[ 2] = 20000 Y[ 2] = 9.7487 X[ 3] = 40000 Y[ 3] = 9.6879 X[ 4] = 60000 Y[ 4] = 9.6278 X[ 5] = 80000 Y[ 5] = 9.5682

Page 278: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

271

Enter X valude to interpolate =55000 0.0 9.81000 20000.00000 9.74870 -0.00000 40000.00000 9.68790 -0.00000 0.00000 60000.00000 9.62780 -0.00000 0.00000 0.00000 80000.00000 9.56820 -0.00000 0.00000 -0.00000 -0.00000 X = 55000.00000 Interpolated Y = 9.64276 รป 6.8 ผลการประมาณคาดวยวธผลตางถกหาร ตวอยาง 6.8 วดความหนดของนาทอณหภมตาง ๆ กนไดขอมลดงน

อณหภม ๐ C 0 10 30 50 70 90 100 ความหนดของนา (Ns/m2) × 10-3

1.792 1.308 0.801 0.549 0.406 0.317 0.284

จงคานวณหาความหนดของนาท 25๐ C วธทา ใชโปรแกรม Fr_Spli.C ซงเปน cubic spline แบบธรรมชาต คาอนพนธทจดปลายทงสองขางมคาเปนศนย ผลลพธจะไดดงน Interpolation using Free Cubic Spline. ======================== Number of data ( 1 - 50) : 7 X[ 1] = 0 Y[ 1] = 1.792 X[ 2] = 10 Y[ 2] = 1.308 X[ 3] = 30 Y[ 3] = 0.801 X[ 4] = 50 Y[ 4] = 0.549 X[ 5] = 70 Y[ 5] = 0.406 X[ 6] = 90 Y[ 6] = 0.317 X[ 7] = 100 Y[ 7] = 0.284

Page 279: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

272

Enter X value to interpolate = 25 a(i) b(i) c(i) d(i) Spline 1 1.79200 -0.05206 0.00000 0.00004 Spline 2 1.30800 -0.04109 0.00110 -0.00002 Spline 3 0.80100 -0.01582 0.00017 -0.00000 Spline 4 0.54900 -0.00950 0.00015 -0.00000 Spline 5 0.40600 -0.00543 0.00005 -0.00000 Spline 6 0.31700 -0.00356 0.00004 -0.00000 X = 25.00000 Interpolated Y = 0.88618 รป 6.9 ผลลพธจากการใช cubic spline แบบธรรมชาต ในตวอยาง 6.8 ตวอยาง 6.9 เรมจบเวลารถคนหนงขณะทกาลงเคลอนทเปนเสนตรงดวยความเรว 28 ม./วนาท ไดขอมล ดงตอไปน

เวลา (วนาท) 0 3 5 8 13 ระยะทาง (ม.) 0 75 125 208 - ความเรว (ม./วนาท) 28 30 33 31 25

จงหาระยะทางและความเรวของรถเมอเวลาผานไป 10 วนาท วธทา 1) ใชการประมาณคาแบบลากรองจหรอแบบผลตางถกหารหรอแบบ Free cubic spline หาระยะทาง เมอเวลาผานไป 10 วนาท โดยใชขอมลทมอยเพยง 4 คา 2) ใชการประมาณคาแบบลากรองจหรอแบบผลตางถกหารหรอแบบ Free cubic spline หาความเรว เมอเวลาผานไป 10 วนาท โดยใชขอมลทมอยทง 5 คา เปรยบเทยบผลลพธทไดแตละวธดงน t = 10 วนาท แบบลากรองจ แบบผลตางถกหาร Free cubic spline ระยะทาง (m) 273.3333 273.3333 ไมสามารถหาได ความเรว (m/s) 26.0961 26.0961 28.4752

Page 280: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

273

ตวอยาง 6.10 จากการทดลองวดขนาดของประจบนแผนของตวเกบประจแบบแผนขนานซงมพนท 400 ตาราง ซ.ม ระยะหางระหวางแผน 4 มม. ทแรงดนตกครอมแผนขนาดคาตาง ๆ กน ไดผลดงน

แรงดน (V) 20 40 60 80 100 ประจ (q) x10-8 Coulomb 0.16 0.32 0.50 0.67 0.82

ทแรงดน 50 โวลต จะมประจทแผนขนานขนาดเทาใด วธทา 1) เมอใชการประมาณคาแบบลากรองจ (Lagran1.C) จะไดผลลพธ q = 0.4090 × 10-8 คลอมบ ท V = 50 โวลต 2) เมอใชการประมาณคาแบบผลตางถกหาร (DivDif.C) จะไดผลลพธ q = 0.40984 × 10-8 คลอมบ ท V = 50 โวลต 3) เมอใชการประมาณคาแบบ Free Cubic Spline (Fre_Spli.C) จะไดผลลพธ q = 0.40893 × 10-8 คลอมบ ท V = 50 โวลต 6.5 บทสรป การเรยนรวาการกระจายของขอมลทไดมลกษณะอยางไร ชวยใหเขาใจความสมพนธระหวางตวแปร ชวยในการทานายหรอคาดคะเนคาตาง ๆ ทไมปรากฎในตารางขอมลไดโดยไมตองไปทาการทดลองจรง ๆ การประมาณคาแบบลากรองจและแบบผลตางถกหาร จะใชฟงกชนพหนามลากผานจดตาง ๆ ของขอมล ฟงกชนพหนามจะมอนดบสงมากนอยเพยงใดขนอยกบปรมาณของขอมลทใหมา ถา N เปนจานวนขอมล ฟงกชนพหนามจะมอนดบสงสดเทากบ N-1 เสมอ ฟงกชนพหนามทมอนดบสง ๆ จะใหผลลพธการประมาณคาใกลเคยงความจรง แตกควรระมดระวงสาหรบขอมลบางชด ถาใชพหนามอนดบสงมากเกนไปอาจทาใหเกดความคลาดเคลอนเนองจากการปดเศษไดมาก ทงสองวธนใชกบขอมลทไมจาเปนตองมเวนชวงหางเทากนและไมจาเปนตองเรยงลาดบ ถาขอมลมจานวนมาก วธผลตางถกหารจะใหความคลาดเคลอนนอยกวาวธของลากรองจ วธพหนามอนดบสามจะลากเสนเชอมระหวางจดแตละจดดวยเสนโคง เปนการลดความคลาดเคลอนและเสนกราฟทไดมลกษณะโคงใกลเคยงกบความเปนจรงมากขน วธนใชกบขอมลทเรยงลาดบจากนอยไปมาก ดงนนจงตองจดลาดบของขอมลกอนทกครงทจะใชวธ cubic spline น ถารคาความชนทจดปลายของขอมล เราจะใชวธ Clamp cubic spline ซงใหความคลาดเคลอนนอยกวาวธ Free cubic spline ทสาคญ วธพหนามอนดบสามนไมสามารถใชประมาณคาขอมลทอยนอกชวง (extrapolation) ของขอมลทมอยได

Page 281: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

274

This page intentionally left blank

Page 282: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

275

บทท 7 การประมาณคาโดยวธกาลงสองนอยทสด

การสรางแบบจาลองทางคณตศาสตรเพออธบายปรากฏการณทางวทยาศาสตรวธหนง

กคอ นาขอมลจากการทดลองมาหาความสมพนธระหวางตวแปรทปรากฏในการทดลอง แลว

เขยนเปนฟงกชนหรอสมการทางคณตศาสตร เพอเปนตวแทนใชในการอธบายปรากฏการณนน

การประมาณคาฟงกชนโดยวธกาลงสองนอยทสดจะไดฟงกชนทเปนตวแทนทดทสด

ของขอมล เพราะไดจากการเกลยคาความคลาดเคลอนของขอมลใหเหลอนอยทสด ดงนน เมอ

เขยนกราฟของฟงกชน เสนกราฟจะผานไปในบรเวณจดตาง ๆ ของขอมล โดยจะตดผานจดของ

ขอมลบางจด การประมาณคาโดยวธนตางจากการประมาณคาในชวง (interpolution) ดงได

กลาวไวในบทท 6 ดงน

1. ฟงกชนทไดจากการประมาณคาในชวงซงเปนฟงกชนพหนาม จะตองผานจดทกจด

ของขอมล เมอเขยนเสนกราฟจะเหนเปนรอยหยกของเสน เสนกราฟจรงๆ โดยธรรมชาตมลกษณะ

ราบเรยบหรอโคงเปนแนวตอเนอง การประมาณคาโดยวธกาลงสองนอยทสดจะไดเสนกราฟผาน

ไปในบรเวณจดตาง ๆ ของขอมล อาจผานขอมลบางจดและไมผานบางจด เสนกราฟจะม

ลกษณะราบเรยบ (smooth) ใกลเคยงความเปนจรงมากกวา

2. ถามขอมลอย n จด พหนามทไดจากวธประมาณคาในชวงจะมองศาเทากบ n - 1

ถาn มคามาก ๆ พหนามจะมองศามากตามไปดวย พหนามจะมลกษณะซบซอน สวนการ

ประมาณคาดวยวธกาลงสองนอยทสด จะไดสมการเสนกระทดรด ไมขนอยกบจานวนของขอมล

สามารถนามาหาอนพนธหรออนทเกรต เพอใหไดคาทตองการไดงาย

หลกการของวธกาลงสองนอยทสด มดงน ถามขอมล x, y ทงสน n ชด ใหฟงกชนท

ประมาณคาขอมลชดนเปน G(x) โดยท G(x) อยในรป

G(x) = a1g1(x) + a2g2(x) + ... amgm(x) ................... (7.1)

โดยท m ≤ n g1(x), ...gm(n) เปนฟงกชนซงขนอยกบคา x อาจจะอยในรปพหนาม

(polynomial) รปลอกการทม หรอเอกซโพเนนเชยล สมการ (7.1) จะสมบรณไดกตอเมอทราบคา

a, a2, ...am โดยหาคาสมประสทธเหลานไดจากการทาใหคาเบยงเบนของขอมลกบคาประมาณท

ไดจากฟงกชน G(x) มคานอยทสด

Page 283: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

276

yi

xi

รป 7.1 แสดงการหาคาเบยงเบนของวธกาลงสองนอยทสด

จากรป 7.1 คาแตกตางของขอมลชดท i คอ

yi - G(xi) เมอหาคาแตกตางของขอมลทกชดแลว นาคาแตกตางเหลานมารวมกน แลว

ยกกาลงสอง เพอขจดเครองหมายลบ จะได

D = [ ]y G(x )i 1n

i i

2−∑

= ................... (7.2)

คาสมประสทธ a1, a2, ... am จะเปนตวแปร เพราะเมอคาเหลานมคาตาง ๆ กน ฟงกชน

G(x) จะเปนฟงกชนทแตกตางกนออกไป แตตองการหาคา a1, a2, ... am ทมเงอนไขทาใหเกดคา

D มคานอยทสด จากแคลคลสเราจงได

∂∂∂∂

∂∂

Da 0

Da 0

Da 0

1

2

m

=

=

=

⎪⎪⎪⎪

⎪⎪⎪⎪

M .................... (7.3)

จะไดสมการออกมา m ชด สามารถหาคา ai, ... am ได โดยใชระบบสมการเชงเสน

การหาฟงกชนเพอประมาณคาชดขอมลโดยวธกาลงสองนอยทสดนเรยกชออกอยาง

หนงวา การถดถอย (Regression)

Gi

G(x)

D

Page 284: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

277

7.1 ขอมลมความสมพนธแบบเชงเสน (Linear Regression) ถาขอมลทง n ชด มความสมพนธกนในลกษณะเชงเสนตรง สมการเสนตรงทหาไดจาก

วธนเรยกวา การถดถอยแบบเชงเสน ใหฟงกชนทจะใชเปนตวแทนขอมลชดนมรปสมการเปน

G(y) = A + Bx ................... (7.4)

เมอเปรยบเทยบกบสมการ (7.1) นนคอ g1(x) = 1 , g2(x) = x เทอมตอ ๆ ไปเปนศนย

ทงหมด

ผลรวมกาลงสองของคาเบยงเบนจากสมการ (7.2) คอ

D = (yi 1n

A Bx )i i2

=∑ − −

A, B คอคาคงททตองการหา โดยทาให D มคานอยทสด นนคอ

∂∂

DA = − − −

=∑2 (y A Bx )i 1n

i i = 0

∂∂

DB = − − −

=∑2 (y A Bx )i 1n

i i ( )x i = 0

จดรปใหมจะได

nA + BΣxi = Σyi

AΣxi + BΣx i2 = Σxiyi

แกสมการหาคา A, B จะได

( )

( )

A y x x x yn x x

B n x y x yn x x

i i2

i i i

i2

i

2

i i i i

i2

i

2

=−

=−

∑∑∑∑∑∑

∑∑∑∑∑

⎪⎪

⎪⎪

.................... (7.5)

Page 285: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

278

ตวอยาง 7.1 ตมนาหนกขนาด x แขวนบนสปรงซงมการยดเปนเชงเสน ไดขอมลดงตอไปน

ตมนาหนก (x) 2 4 6 8 10 12

ระยะทยด (y) 7.32 8.24 9.20 10.1

9

11.0

1

12.0

5

จงหาสมการเชงเสนทใชแทนขอมลชดน

วธทา จากขอมล จะได n = 6

Σxi = 42

Σx i2 = 364

Σyi = 58.01

Σy i2 = 576.3787

Σxiyi = 439.02

แทนคาลงไปในสมการ (7.5) จะได

A = 6.3733333

B = 0.4707143 x

สมการเชงเสนทเหมาะสมทจะใชเปนตวแทนขอมลชดน คอ

6(x) = 6.3733 + 0.4707 x

เราสามารถประยกตวธถดถอยแบบเชงเสนไปใชกบขอมลทมความสมพนธแบบไมเปน

เชงเสนได ขอมลทมความสมพนธแบบไมเปนเชงเสนอาจอยในรปลอกการธม, เอกโพเนนเชยล

หรอในรปยกกาลงสองขนไป

Page 286: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

279

รป 7.2 ขอมลทมลกษณะไมเปนเชงเสนแบบตาง ๆ

ลกษณะทไมเปนเชงเสนเหลานสามารถดดแปลงใหอยในรปสมการเชงเสนได ดงน

ก. เมอ G(x) = A + B ln x

กาหนดให X = ln x

Y = G(x)

สมการจะกลายเปน

Y = A + Bx

สมการจะกลายเปนสมการเสนตรง สามารถหา A และ B จากสมการ (7.5) ได

ข. เมอ G(x) = y = aebx

ใส log ทงสองขาง

ln y = ln a + bx

กาหนดให Y = ln y , A = ln a

Page 287: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

280

จะไดสมการเชงเสน ดงน

Y = A + bx

ค. เมอ G(x) = y = axb

ใส log ทงสองขาง

ln y = ln a + b ln x

กาหนดให Y = ln y , A = ln a X = ln x

จะไดสมการเชงเสน ดงน

Y = A + bx

ง. เมอ G(x) = y = a

b x+

จดรปสมการใหม

y = ab

1b (xy)+−

ให Y = y, X = xy, A = ab และ B = −

1b

จะไดสมการเชงเสน

Y = A + Bx

จ. เมอ G(x) = y = ax

b x+

จดรปสมการใหม จะได

y = ( )a b yx−

ให Y = y , A = a, B = -b, X = yx

จะไดสมการเชงเสน

Y = A + Bx

7.2 ขอมลมความสมพนธแบบพหนาม (Polynomial Regression) ขอมล n ชด มความสมพนธกนแบบพหนามอนดบ m เขยนเปนสมการไดดงน

G(x) = a0 + a1x + a2x2 + ..... amxm

ผลรวมกาลงสองของความเบยงเบนของขอมลกบ G(x) คอ

D = ( )y G(x)i

2−∑

หาคา a0, a1, a2, ..... am โดยใชเงอนไข D ตองมคานอยทสด

Page 288: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

281

∂∂

Da 1

= 0 I = 0, 1, ..... m

จะไดเปนระบบสมการเชงเสน m+1 สมการ ไดคาตอบของสมการ

ให xi 1n

xi=∑ = ∑ ละเวนพสยของการหาผลรวมเพอใหดงาย

................... (7.6)

จะเหนวาสมการ (7.5) เปนสวนหนงของสมการ (7.6) เมอ m = 1 นนเอง

ถาฟงกชนไมเปนพหนาม มเทอมอน ๆ เขามาปนอยดวย เชน y = A+ Bx + c/x2 เปน

ตน ฟงกชนเหลาสสามารถเขยนใหอยในรปทวไปไดเปน

G(x) = a00 + a1f(x) + a2g(x) ...................

(7.7)

เมอ f(x) = x

g(x) = 1x2

เราสามารถใชหวขอ 7.3 ขอมลมความสมพนธแบบหลายเชงชวยแกปญหาได

การนาฟงกชน Polynomial_Regrression ไปใชงาน กาหนดไวในโปรแกรมวาใหฟงกชนนใชกบตวแปรอสระไมเกนกาลง 10 มเงอนไขการ

นาไปใชงานดงน

ก. คาคงททตองกาหนด #define ARRAY_SIZE 51

#define ZERO_APPROACH 2.20E-16

ข. การเรยกใชฟงกชน

int Polynomial_Regression (int coeff_term, int n, double x [ ],

double y [ ], double result [ ] )

n x x xx x x x

x x x x

a0a

a m

yxy

x y

2 m

2 3 m 1

m m 2 m 2 2m

1

mi

∑ ∑ ∑∑ ∑ ∑ ∑

∑ ∑ ∑ ∑=

∑∑

+

+ +

L

LM M M L M

L

M M

Page 289: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

282

coeff_term คอ จานวนเทอมของสมประสทธ = อนดบของพหนาม + 1

n คอ จานวนขอมล

x, y คอ ขอมลของตวแปรอสระ และตวแปรตาม

result คอ คาสมประสทธทคานวณได

ค. ฟงกชนอนทเกยวของ มการเรยกใชฟงกชน GaussElimination จากบทท 4

ง. ผลลพธ สมประสทธทคานวณไดจะถกเกบไวใน result [ ]

จ. การสงคากลบ

0 ไมมขอผดพลาดใด ๆ เกดขน

1 คาสมประสทธนอยกวา 1 หรอมากกวา 10

2 จานวนขอมลนอยกวา 2 คา

3 จานวนสมประสทธมากกวาจานวนขอมล

4 ไมสามารถหาคาตอบได

โปรแกรม 7.1 รายละเอยดโปรแกรมการหาการถดถอยแบบพหนาม P_Regress.C

/*

* Program 7.1 P_Regression.C

* Purpose: Demonstrate how to fitting curve

* with polynomial regression.

* Author : Wachara Rodsumrid.

* Office : Dept of Physics. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Last update : 19 Mar 96

**************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#define ARRAY_SIZE 51

#define ZERO_APPROACH 2.20E-16 /* for double precision */

Page 290: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

283

int GaussElimination(int , double aug[][ARRAY_SIZE]);

int Polynomial_Regression(int, int, double x[],double y[],double coeff[]);

int DataEntry( double x[],double y[]);

void DisplayCoeff(int, int , double a[]);

int StandardErrorofEstimate(int n_term, int n_data, double x[],

double y[], double coeff[],double *);

int CoefficientofDetermination(int n_term, int n_data, double x[],

double y[], double coeff[],double *);

main()

{

int error;

double x_temp;

double x[ARRAY_SIZE], y[ARRAY_SIZE],coeff[ARRAY_SIZE];

int n_term,n_data,n_power;

double std_err;

double cd; /* coeff of determination */

printf("\n\tCurve Fitting by least square method\n");

printf("\t======================================\n");

printf("\tNumber of polynomial power ");scanf("%d",&n_power);

n_term = n_power+1;

n_data = DataEntry(x,y);

error = Polynomial_Regression(n_term,n_data,x,y,coeff);

DisplayCoeff(error,n_term,coeff);

error = StandardErrorofEstimate(n_term,n_data,x,y,coeff,&std_err);

if (error ==0) {

printf("\nStandard error of the estimate = %10.5f\n", std_err);

}

error = CoefficientofDetermination(n_term,n_data,x,y,coeff,&cd);

if (error ==0) {

printf("\nThe Coefficient of Determination = %10.5f\n", cd);

}

return(0);

}

int DataEntry (double x[],double y[])

Page 291: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

284

{

int i,j,n;

printf("\n How many data do you have (in pair) ? :");scanf("%d",&n);

printf (" Input your data...\n");

for (i=1; i<=n; i++) {

printf ("X[%d] = ",i); scanf("%lf",&x[i]);

printf ("Y[%d] = ",i); scanf("%lf",&y[i]);

}

return n;

}

void DisplayCoeff(int err,int n, double result[])

{

int i;

switch(err) {

case 0 : {

printf("\nPower coefficient determined\n");

printf("----------------------------------\n");

for (i=1; i<=n; i++ ) {

printf(" %3d %12.5e \n",i-1,result[i]);

}

printf("----------------------------------\n");

break;

}

case 1: {

printf("\nNumber of term must be greater than 1 and less than 10\n");

break;

}

case 2 : {

printf("\nNumber of data must be greater than 2\n");

break;

}

case 3: {

printf("\nThe number of data must be greater than the number of terms.\n");

break;

}

Page 292: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

285

case 4: {

printf("\nNo solution possible\n");

break;

}

}

}

/*=======================================================*/

int GaussElimination(int dim, double aug[][ARRAY_SIZE])

/* Function Description : finding a set of linear eqn using

Gauss Elimination with partial pivoting

User's define: ARRAY_AIZE = 51

ZERO_APPROACH = 2.20E-16 (for double precision)

Input: aug -- Augmented Matrix.

dim -- Dimension of Coefficeint Matrix

Output: The solutions of eqn. keep in augmented Matrix column dim+1

Return :

0 -- No error detected.

1 -- Dimension < 1

2 -- Coefficeint Matrix is singular.

*/

{

int i,j,row,col,pivot;

int ir,jc;

double temp=0,multiplier=0,det=1.0;

if (dim < 1 || dim > ARRAY_SIZE-1) return 1;

if ( dim == 1) {

if (aug[1][1] != 0 ) {

aug[1][2] = aug[1][2]/aug[1][1];

return 0;

} else { return 2;} /* Can't find solution */

}

for (i=1; i <= (dim-1); i++) {

pivot = i;

/* Check the maximum element in the same column */

for (j = i+1; j <= dim; j++)

if (fabs(aug[pivot][i]) < fabs(aug[j][i])) pivot=j;

Page 293: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

286

/* Pivoting */

if (pivot != i) {

for (j =1;j <= (dim+1); j++) {

temp = aug[i][j];

aug[i][j] = aug[pivot][j];

aug[pivot][j] = temp;

}

det = -det;

}

if (aug[i][i] == 0) return 2; /* singular matrix */

/* make an upper triangular matrix */

for ( row = i+1;row <= dim; row++) {

if(aug[row][i] != 0 ) {

multiplier= aug[row][i]/aug[i][i];

/* if you mind in SPEED, this line is better than next.

for ( col= i+1;col <= (dim+1); col++) {

*/

for(col = 1;col<=(dim+1);col++) {

aug[row][col] = aug[row][col]-multiplier*aug[i][col];

if (fabs(aug[row][col]) <= 2*ZERO_APPROACH)

aug[row][col] = 0;

}

} /* if */

} /* for ( row....) */

#if(0)

/*** In case of learning, you can see the results step by step *****/

printf("\nStep # %d\n",i);

printf("============\n");

ShowAugMatrix(dim,aug);

puts("Press any key .....");getch();

/*******************/

#endif

} /* for ( i....) */

for (i = 1; i <= dim; i++ )

det = det *aug[i][i];

Page 294: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

287

printf("\nYour det = %f\n",det);

if (det !=0 ) {

/* Backward Substitution */

aug[dim][dim+1] = aug[dim][dim+1]/aug[dim][dim];

for ( row = dim-1; row >=1; row--){

temp = aug[row][dim+1];

for ( col= row+1; col <= dim; col++) {

temp = temp - aug[row][col]*aug[col][dim+1];

}

aug[row][dim+1] = temp/aug[row][row];

}

return 0;

}else{ return 2; /* singular matrix */ }

}

/*=========================================================*/

int Polynomial_Regression(int coeff_term,int n,double x[],double y[],double result[])

/* Function Description : finding coefficients of polynomail regression.

User's define: ARRAY_AIZE = 51

ZERO_APPROACH = 2.20E-16 (for double precision)

Input:

coeff_term -- the number of coefficients = power of polynomial+1

n -- Number of data.

x,y -- Your data.

result -- keep the coefficient in here.

Calling Function: GaussElimination (see GaussElimination function)

Output: The coefficient results are kept in result.

Return :

0 -- No error detected.

1 -- The number of coefficient terms < 1 or greater than 10

2 -- The number of data < 2

3 -- The number of coefficient terms > n

4 -- No possible solution.

Page 295: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

288

*/

{

int row,col,power,i,j,err;

double x_temp;

double a[ARRAY_SIZE][ARRAY_SIZE];

if (coeff_term < 1 || coeff_term > 10) return 1;

if (n < 1 ) return 2; /* number of data < 2 */

if ( coeff_term > n) return 3;

for (row=1; row<= coeff_term; row++)

for (col =1; col<=coeff_term+1; col++)

a[row][col]=0.0;

for (row=1; row<=coeff_term; row++) {

for (col=1; col<=coeff_term; col++ ){

power = row+col-2;

/* Note : If you use builtin function, pow(x,n),. you will

face with DOMAIN ERROR when it calculate pow(0,0)

*/

for ( i=1; i<=n; i++) {

x_temp = 1;

for (j =1; j<=power; j++) {

x_temp = x_temp*x[i];

}

a[row][col] +=x_temp;

} /* for i */

} /* for col */

for( i =1; i <=n; i++) {

x_temp = 1;

for (j=1; j < row ; j++) {

x_temp = x_temp*x[i];

}

a[row][coeff_term+1] += y[i]*x_temp;

}

} /*row*/

/* print matrix for debugging */

for (i=1;i<=coeff_term; i++) {

for(j=1; j<= (coeff_term+1); j++) {

Page 296: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

289

printf(" %11.4e ", a[i][j]);

}

printf ("\n");

}

err = GaussElimination(coeff_term,a);

for (i = 1; i <=coeff_term; i++)

result[i] = a[i][coeff_term+1];

if (err == 0 ) return (0); else return (4);

}

/****** end of Polynomial Regression function ******/

int StandardErrorofEstimate(int n_term, int n_data, double x[],

double y[], double coeff[],double *SEE)

/* Function Description :

Calculating the Standard error of the estimate between

y (from your data) and prdicted polynomial function.

Input:

n_term -- the number of coefficients = power of polynomial+1

n_data -- Number of data.

x,y -- Your data.

coeff -- the coefficients of polynomial function.

SEE -- The standard error of the estimate.

Calling Function: You must use 'Polnomial_Regression' determine the

coefficient of function before using this function.

Output: The result is kept in SEE.

Return :

0 -- No error detected.

1 -- The number of coefficient terms > the number of data

*/

{

int i,j,k;

double SSofResidual,DegreeofFreedom;

double y_est,temp;

if ( n_term >= n_data) return 1;

DegreeofFreedom = n_data - n_term;

SSofResidual = 0;

Page 297: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

290

for (i = 1; i<= n_data; i++) {

y_est = coeff[1];

for (j = 1; j <= n_term-1; j++) {

temp = 1;

for (k=1; k<=j; k++) {

temp = temp*x[i];

}

y_est += coeff[j+1]*temp;

}

SSofResidual = SSofResidual + (y[i] - y_est)*(y[i] - y_est);

}

*SEE = sqrt(SSofResidual/DegreeofFreedom);

return(0);

}

int CoefficientofDetermination(int n_term, int n_data, double x[],

double y[], double coeff[],double *R2)

/* Function Description :

Calculating the coefficient of the determination for

y (from your data) and prdicted polynomial function.

Input:

n_term -- the number of coefficients = power of polynomial+1

n_data -- Number of data.

x,y -- Your data.

coeff -- the coefficients of polynomial function.

R2 -- The coefficient of determination.

Calling Function: You must use 'Polnomial_Regression' determine the

coefficient of function before using this function.

Output: The result is kept in R2.

Return :

0 -- No error detected.

1 -- The number of coefficient terms > the number of data

*/

{

int i,j,k;

double SSofResidual,SSofRegress;

double y_est,temp,sumy,ybar;

Page 298: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

291

if ( n_term >= n_data) return 1;

SSofResidual = 0;

for (i = 1; i<= n_data; i++) {

y_est = coeff[1];

for (j = 1; j <= n_term-1; j++) {

temp = 1;

for (k=1; k<=j; k++) {

temp = temp*x[i];

}

y_est += coeff[j+1]*temp;

}

SSofResidual = SSofResidual + (y[i] - y_est)*(y[i] - y_est);

}

/* Find average value of y */

sumy = 0;

for ( i = 1; i <=n_data; i++) {

sumy = sumy + y[i];

}

ybar = sumy/n_data;

SSofRegress = 0;

for (i = 1; i<=n_data; i++ ) {

SSofRegress = SSofRegress + (y[i] - ybar)*(y[i]-ybar);

}

*R2 = 1 - SSofResidual/SSofRegress;

return 0;

}

/************** end of CoefficientDetermination function ***/

ตวอยาง 7.2 กอนหนเคลอนทแบบโปรเจกไตล ความสมพนธระหวางความสงซงวดจากพนดน

(y) และระยะทางทเคลอนทไดในแนวราบ (x) มดงน

x 0 1 2 4 5 6 7 8

y 0 0.512

1

0.893

6

1.264

8

1.254

5

1.113

6

0.842

1

0.440

0

Page 299: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

292

จงหาสมการซงแสดงความสมพนธระหวาง x และ y

วธทา กอนหนเคลอนทเปนรปพาราโบลา ซงมรปสมการทวไปดงน

x x2 x3 x4 y xy x2y

0 0 0 0 0 0 0

1 1 1 1 0.5121 0.5121 0.5121

2 4 8 16 0.8936 1.7872 3.5744

4 16 64 256 1.2648 5.00592 20.2368

5 25 125 625 1.2545 6.2725 31.3625

6 36 216 1296 1.1136 6.6816 40.0896

7 49 343 2401 0.8421 5.8947 41.2629

8 64 512 4096 0.4400 3.5200 28.1600

33 195 1269 8691 6.3207 29.7273 165.1983

แทนคา Σx, Σx2, Σx3, ...ลงในดเทอรมแนนท จะไดคาคงท A, B, C ดงน โดยใช

โปรแกรม P_Regress.C

A = 0

B = 0.5774

C = - 0.0653

ขอมลชดนไดจากโจทยกลาวถงการขวางกอนหนเปนมม 30o กบพนโลกดวยความ

เรวตน 10 ม./วนาท ไมคดแรงตานของอากาศ จะไดสมการแสดงตาแหนงตาง ๆ ของกอนหนเปน

y = 0.5774x - 0.0653x2

คาคงท A, B และ C ทไดจะตรงกบคาทแทจรงทไดมาจากการวเคราะหทกประการ

n x xx x xx x x

ABC

yxyx y

2

2 3

2 3 4 2

∑ ∑∑ ∑ ∑∑ ∑ ∑

=∑∑∑

ผลรวม

Page 300: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

293

7.3 ขอมลมความสมพนธแบบหลายเชง (Multiple Regression) ขอมลทไดจากการทดลองทางวทยาศาสตรอาจขนอยกบตวแปรหลาย ๆ ตวแปร เชน

กระแสไฟฟาในวงจร RC ถาตวตานทานมการเปลยนคาได กระแสไฟฟาทวดไดขนอยกบคาความ

ตานทานและเวลาทเปลยนไป ความดนของอากาศในกระบอกสบขนอยกบอณหภมของอากาศ

และปรมาตรของกระบอกสบทเปลยนไปเมอลกสบเคลอนท อนทจรงแลวความดนของอากาศ

ยงคงขนอยกบความสงจากระดบนาทะเลเและไอนาในอากาศ จะเหนวาความดนอากาศขนอยกบ

ตวแปรหลาย ๆ ตวแปร

เราสามารถเขยนตวแปรตามทขนอยกบตวแปรอสระหลาย ๆ ตว ใหอยในรปทวไปได

เปน

y = f(x1, x2, x3, ...xj) ................... (7.8)

เมอ j คอจานวนตวแปรอสระทงหมด

ถาตวแปรตามมการเปลยนแปลงตามตวแปร x แตละตวในลกษณะเชงเสน เรา

สามารถเขยนฟงกชนเชงเสนตรงทใชแทนขอมลชดน ดงน

G(x1, ...xj) = a0 + a1x1 + a2x2 + .....ajxj ................... (7.9)

ผลรวมกาลงสองของความเบยงเบนของขอมล n ชด กบ G(xj) คอ

D = ( )y G(x , x ,... x )i 1n

i 1 2 j

2

−∑=

................... (7.10)

หาคา a0, a1, ... aj โดยทความคลาดเคลอนทเกดขนตองมคาตาสด นนคอ

∂∂∂∂

∂∂

DaDa

Da

0

1

j

=

=

=

⎪⎪⎪⎪

⎪⎪⎪⎪

0

0

0

M ................... (7.11)

สมการ (7.11) จะประกอบดวยสมการยอย (j + 1) สมการ เขยนใหอยในรปเมทรกซ

ดงน

Page 301: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

294

n xi 1n

xi 1n

x jii 1n

xi 1n

xi 1n

x1i xi 1n

x i x jii 1n

x ii 1n

x1i x ii 1n

x ii 1n

x i x jii 1n

xi 1n

x1i x jii 1n

x i x jii 1n

x ji

aaa

a

y ii 1n

x i yii 1n

x i yii 1n

x ji y ii 11

1i i

1i 1i2

1

2 2 2

22

ji 22

0

1

2

j

1

2

2

2i

= = =

= = = =

= = =

= = =

=

=

=

=

=

∑ ∑ ∑

∑ ∑ ∑ ∑

∑ ∑ ∑=∑

∑ ∑ ∑ ∑

L

L

L

M M M L ML

MM

................... (7.12)

การนาฟงกชน Linear_Multi_Regression ไปใชงาน การนาฟงกชน Linear_Multi_Regression ไปใชงาน มเงอนไขคอ ใชกบขอมลไมเกน

150 คา ตวแปรอสระไมเกน 10 ตว

ก. คาคงททตองนยาม #define ARRAY_SIZE 51

#define ZERO_APPROACH 2.20E-16

ข. การผานคาอนพทและการเรยกใชฟงกชน

int Linear_Multi_Regression (int num_x, int num_data

double x [ ] ARRAR_SIZE, double y [ ], double result [ ] )

เมอ num_x คอ จานวนตวแปรอสระ มไดไมเกน 10 ตว

num_data คอ จานวนขอมล

x คอ ขอมลของตวแปรอสระ จดเกบในอะเรยแบบ

x[num_data][num_x]

y คอ ขอมลตวแปรตาม

result คอ คาสมประสทธทคานวณได

ค. ฟงกชนอนทเกยวของ มการเรยกใชฟงกชน Gauss Elinination และใชฟงกชน

M_standard Error of Estimate และ M_coefficient of Detemination ถาตองการ

ตรวจสอบความนาเชอถอของสมการทได

ง. ผลลพธ เกบคาสมประสทธทคานวณไดทงหมดไวในอะเรยชอ result [ ]

จ. การสงคากลบ

Page 302: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

295

0 ไมมขอผดพลาดใด ๆ เกดขน

1 คาสมประสทธนอยกวา 1 หรอมากกวา 10

2 จานวนตวแปรอสระมากกวาจานวนขอมล

3 ไมสามารถหาคาตอบได

โปรแกรม 7.2 รายละเอยดโปรแกรม M_Regress.C ใชหาการถดถอย

/*

* Program 5.2 M_Regress.C

* Purpose: Demonstrate how to fitting curve with multiple regression.

* Author : Wachara Rodsumrid.

* Office : Dept of Physics. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Last update : 12 Apr 96

**************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#define ARRAY_SIZE 51

#define ROW_SIZE 151

#define ZERO_APPROACH 2.20E-16 /* for double precision */

int GaussElimination(int , double aug[][ARRAY_SIZE]);

int Linear_Multi_Regression(int, int, double x[][ARRAY_SIZE],

double y[],double coeff[]);

int DataInput( int,double x[][ARRAY_SIZE],double y[]);

void PrintData(int,int, double x[][ARRAY_SIZE], double y[]);

void ShowCoeff(int, int , double a[]);

int M_StandardErrorofEstimate(int n_term, int n_data, double x[][ARRAY_SIZE],

double y[], double coeff[],double *);

/*

int M_CoefficientofDetermination(int n_term, int n_data, double x[][ARRAY_SIZE],

double y[], double coeff[],double *);

*/

Page 303: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

296

main()

{

int error,i,j;

double x[ROW_SIZE][ARRAY_SIZE], y[ARRAY_SIZE],coeff[ARRAY_SIZE];

int n_data,nx;

int n_coeff; /* number of coefficient = num of x + 1 */

double std_err;

double cd; /* coeff of determination */

printf("\n\tCurve Fitting by Linear Multiple Regression.\n");

printf("\t======================================\n");

printf("\tNumber of independent Variable(X) : ");scanf("%d",&nx);

n_coeff = nx + 1;

n_data = DataInput(nx,x,y);

/* for checking your data */

/* PrintData(nx,n_data,x,y); */

error = Linear_Multi_Regression(nx,n_data,x,y,coeff);

ShowCoeff(error,n_coeff,coeff);

error =M_StandardErrorofEstimate(n_coeff,n_data,x,y,coeff,&std_err);

if (error ==0) {

printf("\nStandard error of the estimate = %10.5f\n", std_err);

}

error = M_CoefficientofDetermination(nx+1,n_data,x,y,coeff,&cd);

if (error ==0) {

printf("\nThe Coefficient of Determination = %10.5f\n", cd);

}

return(0);

}

int DataInput (int n_var,double x[][ARRAY_SIZE],double y[])

/* Your data should be in this format

X1 X2 X3 .... Y

1.2 2.5 3.0 ... 1

2 3.1 2.6 ... 2.7

3.6 4.5 2.0 .. 4.0

... ... ... ... ...

*/

Page 304: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

297

{

int r,c,n;

printf("\n How many DATA ? :");scanf("%d",&n);

printf (" Input your data...\n");

for (c=1; c<=n_var; c++) {

printf("\n Independent Variable # %d\n",c);

for (r = 1; r<=n; r++) {

printf ("X%d[%d] = ",c,r); scanf("%lf",&x[r][c]);

}

}

printf("\nInput Dependent Variable ....\n");

for ( c=1; c<=n;c++){

printf ("Y[%d] = ",c); scanf("%lf",&y[c]);

}

return n;

}

void PrintData(int nx, int n_data, double x[][ARRAY_SIZE], double y[])

{

int i,j;

for (i = 1; i <= nx; i++) {

printf("X%d = ",i);

for (j = 1; j <= n_data; j++){

printf(" %f ",x[j][i]);

}

printf("\n");

}

printf("Y = ");

for ( j = 1; j <= n_data; j++)

printf( "%f ",y[j]);

printf("\n");

}

void ShowCoeff(int err,int n, double result[])

{

int i;

switch(err) {

case 0 : {

Page 305: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

298

printf("\nOrder coefficient determined\n");

printf("----------------------------------\n");

for (i=1; i<=n; i++ ) {

printf(" %3d %12.5e \n",i-1,result[i]);

}

printf("----------------------------------\n");

break;

}

case 1: {

printf("\nNumber of Independent Var must be greater than 1 and less than 10\n");

break;

}

case 2: {

printf("\nThe number of data must be greater than the number of Variables.\n");

printf("and less than 150 items.\n");

break;

}

case 3: {

printf("\nNo solution possible\n");

break;

}

}

}

/*===========================================================*/

int GaussElimination(int dim, double aug[][ARRAY_SIZE])

/* Function Description : finding a set of linear eqn using

Gauss Elimination with partial pivoting

User's define: ARRAY_AIZE = 51

ZERO_APPROACH = 2.20E-16 (for double precision)

Input: aug -- Augmented Matrix.

dim -- Dimension of Coefficeint Matrix

Output: The solutions of eqn. keep in augmented Matrix column dim+1

Return :

0 -- No error detected.

Page 306: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

299

1 -- Dimension < 1

2 -- Coefficeint Matrix is singular.

*/

{

int i,j,row,col,pivot;

int ir,jc;

double temp=0,multiplier=0,det=1.0;

if (dim < 1 || dim > ARRAY_SIZE-1) return 1;

if ( dim == 1) {

if (aug[1][1] != 0 ) {

aug[1][2] = aug[1][2]/aug[1][1];

return 0;

} else { return 2;} /* Can't find solution */

}

for (i=1; i <= (dim-1); i++) {

pivot = i;

/* Check the maximum element in the same column */

for (j = i+1; j <= dim; j++)

if (fabs(aug[pivot][i]) < fabs(aug[j][i])) pivot=j;

/* Pivoting */

if (pivot != i) {

for (j =1;j <= (dim+1); j++) {

temp = aug[i][j];

aug[i][j] = aug[pivot][j];

aug[pivot][j] = temp;

}

det = -det;

}

if (aug[i][i] == 0) return 2; /* singular matrix */

/* make an upper triangular matrix */

for ( row = i+1;row <= dim; row++) {

if(aug[row][i] != 0 ) {

multiplier= aug[row][i]/aug[i][i];

/* if you mind in SPEED, this line is better than next.

for ( col= i+1;col <= (dim+1); col++) {

*/

Page 307: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

300

for(col = 1;col<=(dim+1);col++) {

aug[row][col] = aug[row][col]-multiplier*aug[i][col];

if (fabs(aug[row][col]) <= 2*ZERO_APPROACH)

aug[row][col] = 0;

}

} /* if */

} /* for ( row....) */

#if(0)

/*** In case of learning, you can see the results step by step *****/

/* Please don't forget to include ShowAugmentMatrix function */

printf("\nStep # %d\n",i);

printf("============\n");

ShowAugMatrix(dim,aug);

puts("Press any key .....");getch();

/*******************/

#endif

} /* for ( i....) */

for (i = 1; i <= dim; i++ )

det = det *aug[i][i];

printf("\nYour det = %f\n",det);

if (det !=0 ) {

/* Backward Substitution */

aug[dim][dim+1] = aug[dim][dim+1]/aug[dim][dim];

for ( row = dim-1; row >=1; row--){

temp = aug[row][dim+1];

for ( col= row+1; col <= dim; col++) {

temp = temp - aug[row][col]*aug[col][dim+1];

}

aug[row][dim+1] = temp/aug[row][row];

}

return 0;

}else{ return 2; /* singular matrix */ }

}

Page 308: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

301

/*============================================================*/

int Linear_Multi_Regression(int num_x,int num_data,double x[][ARRAY_SIZE]

,double y[],double result[])

/* Function Description : finding coefficients of multiple regression.

User's define: ARRAY_AIZE = 51

ZERO_APPROACH = 2.20E-16 (for double precision)

Input:

num_x -- the number of independent variable x (max = 10)

n_data -- Number of data.

x,y -- Your data.

result -- keep the coefficient in here.

Calling Function: GaussElimination (see GaussElimination function)

Output: The coefficient results are stored in result.

Return :

0 -- No error detected.

1 -- The number of independent variable < 1 or greater than 10

2 -- The number of independent variable > number of data.

3 -- No possible solution.

*/

{

int row,col,power,i,j,err,coeff_term;

double row_temp,col_temp;

double a[ARRAY_SIZE][ARRAY_SIZE];

if (num_x < 1 || num_x > 10) return 1;

if ( num_x > num_data) return 2;

if ( num_data > 150 ) return 2;

coeff_term = num_x+1;

for (row=1; row<= coeff_term; row++)

for (col =1; col<=coeff_term+1; col++)

a[row][col]=0.0;

for (i=1; i<=num_data; i++) {

for (row=1; row<=coeff_term; row++) {

if (row == 1 ) row_temp =1;

Page 309: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

302

if (row >1) row_temp = x[i][row-1];

for (col=1; col<=coeff_term; col++ ){

if( col ==1) col_temp =1;

if (col>1) col_temp = x[i][col-1];

a[row][col] += (row_temp*col_temp);

}

a[row][coeff_term+1] += row_temp*y[i];

} /* row */

}

/* print matrix for debugging */

printf("\n This is your matrix......\n");

for (i=1;i<=coeff_term; i++) {

for(j=1; j<= (coeff_term+1); j++) {

printf(" %11.4e ", a[i][j]);

}

printf ("\n");

}

err = GaussElimination(coeff_term,a);

for (i = 1; i <=coeff_term; i++)

result[i] = a[i][coeff_term+1];

if (err == 0 ) return (0); else return (3);

}

/****** end of Linear Multiple Regression function ******/

int M_StandardErrorofEstimate(int n_term, int n_data, double x[][ARRAY_SIZE],

double y[], double coeff[],double *SEE)

/* Function Description :

Calculating the Standard error of the estimate between

y (from your data) and predicted linear multiple regression.

Input:

n_term -- the number of coefficients = number of var+1

n_data -- Number of data.

x,y -- Your data.

coeff -- the coefficients of polynomial function.

Page 310: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

303

SEE -- The standard error of the estimate.

Calling Function: You must use 'Linear_Multi_Regression' determine the

coefficient of function before using this function.

Output: The result is kept in SEE.

Return :

0 -- No error detected.

1 -- The number of coefficient terms > the number of data

*/

{

int i,j,k;

double SSofResidual,DegreeofFreedom;

double y_est,temp;

if ( n_term >= n_data) return 1;

DegreeofFreedom = n_data - n_term;

SSofResidual = 0;

for (i = 1; i<= n_data; i++) {

y_est = coeff[1];

for (j = 1; j <= n_term-1; j++) {

y_est += coeff[j+1]*x[i][j];

}

SSofResidual = SSofResidual + (y[i] - y_est)*(y[i] - y_est);

}

*SEE = sqrt(SSofResidual/DegreeofFreedom);

return(0);

}

int M_CoefficientofDetermination(int n_term, int n_data,

double x[][ARRAY_SIZE],

double y[], double coeff[],double *R2)

/* Function Description :

Calculating the coefficient of the determination for

y (from your data) and predicted linear multiple regressuin.

Page 311: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

304

Input:

n_term -- the number of coefficients

= (number of independent x)+1

n_data -- Number of data.

x,y -- Your data.

coeff -- the coefficients of multiple regression.

R2 -- The coefficient of determination.

Calling Function: You must use 'Linear_Multi_Regression' determine the

coefficient of function before using this function.

Output: The result is kept in R2.

Return :

0 -- No error detected.

1 -- The number of coefficient terms > the number of data

*/

{

int i,j,k;

double SSofResidual,SSofRegress;

double y_est,temp,sumy,ybar;

if ( n_term >= n_data) return 1;

SSofResidual = 0;

for (i = 1; i<= n_data; i++) {

y_est = coeff[1];

for (j = 1; j <= n_term-1; j++) {

y_est += coeff[j+1]*x[i][j];

}

SSofResidual = SSofResidual + (y[i] - y_est)*(y[i] - y_est);

}

/* Find average value of y */

sumy = 0;

for ( i = 1; i <=n_data; i++) {

sumy = sumy + y[i];

}

ybar = sumy/n_data;

Page 312: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

305

SSofRegress = 0;

for (i = 1; i<=n_data; i++ ) {

SSofRegress = SSofRegress + (y[i] - ybar)*(y[i]-ybar);

}

*R2 = 1 - SSofResidual/SSofRegress;

return 0;

}

/************** end of M_CoefficientDetermination function ***/

ตวอยาง 7.3 ความรอนจาเพาะของแกสออกซเจนเมอความดนคงท (Cp) จะแปรเปลยนไปตาม

อณหภมสมบรณ (T) ดงน

Cp = A + BT + CT 2

จงหาคา A, B และ C จากผลการทดลองตอไปน

T (k) 300 400 500 600 700 800 900 1000 1100 1200

CP cal/degree mole) 7.02 7.20 7.43 7.67 7.88 8.06 8.21 8.34 8.44 8.53

วธทา 1) จดรปสมการใหม ดงน

CP = A + BX + CZ

เมอ X = T และ Z = 1

T 2

จะไดคา CP, X และ Z เปนตารางใหมดงน

300 400 500 600 700 800 900 1000 1100 120011.11 E - 6 6.25 E - 6 4.0 E -6 2.78 E - 6 2.04 E - 6 1.56 E - 6 1.23 E - 6 1.0 E - 6 0.83 E - 6 0.70 E - 6

7.02 7.20 7.43 7.67 7.88 8.06 8.21 8.34 8.44 8.53

2) ใชโปรแกรม M_Regress.C หาคา A, B และ C จะได

A = 6.90498

B = 1.4341 × 10-3

C = -32631.7

Cp Z X

Page 313: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

306

คา xstandard Eror of Estimatte = 0.06112

The Coefficient of Determination = 0.98970

3) ความรอนจาเพาะของแกสออกซเจนเมอความดนคงท ซงนกฟสกสทดลองไว มคา

ดงน

CP = 6.9 + 0.00143 T - 32610

T 2

คาทไดจากโปรแกรมมคาใกลเคยงกบทนกฟสกสคานวณไว

7.4 การตรวจสอบความเหมาะสมของฟงกชน ปญหาทสาคญประการหนงคอจะรไดอยางไรวาขอมลทไดมานนสอดคลองกบสมการ

เสนตรงหรอสมการพหนาม หรอสมการเอกซโพเนนเชยล วธตรวจสอบทงายคอการพลอตกราฟ

สมการนนเปรยบเทยบกบกราฟทไดจากขอมล แตวธนกจะทาไดลาบากถามตวแปรในสมการ

มากกวา 2 ตวขนไป ดวยเหตน จงมการคานวณทางสถต เชน สมประสทธของการกาหนด

(Coefficient of determination) จะใชวดความสมพนธกนหรอสหสมพนธระหวางตวแปรอสระ

ทงหลายกบตวแปรตาม สามารถบอกไดวาสอดคลองกบสมการทไดหรอไม

หลกการเบองตนของสมประสทธการกาหนดสามารถอธบายไดดงน ขอมลทไดจากการ

ทดลอง (xi, yi) และคาทไดจากการคานวณของ G(xi) ความแตกตางทไดคอ yi - G(xi) เมอหา

ความแตกตางของทก ๆ จด ยกกาลงสองทกคาเพอขจดคาทเปนลบ ผลรวมกาลงสองของความ

แตกตางของ yi (จากขอมล) กบ G(xi) (ทไดจากการคานวณ) เรยกวา ผลรวมกาลงสองของเศษ

เหลอ (The sum square of the residuals)

SSE = ( )y G(x )i 1n

i i

2

−∑=

................... (7.13)

ถานาคา yi จากขอมลทไดลบออกจากคาเฉลยของ y (y) ผลรวมกาลงสองของความ

แตกตาง yi และ y ทกคาเรยกวา ผลรวมกาลงสองของความถดถอย (The sum of the square of

the regression)

SSR = (y y)i 1n

i2−

=∑ ................... (7.14)

สมประสทธการกาหนดจะบอกวาขอมลกบฟงกชนมความเหมาะสมสอดคลองกนด

หรอไม หาไดจาก

Page 314: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

307

R2 = 1SS ESS R− ................... (7.15)

ในกรณทเปนระบบสมการเชงเสน สมการ R2 สามารถเขยนไดเปน

R2 = ( )

( ) ( )n xi yi ( y i )2i 1

ni 1n

xi ( x i )i 1n

i 1n

n yi ( y i )i 1n

i 1n

2

2 22

2 2

−==

−==

−==

∑∑

∑∑ ∑∑ ................... (7.16)

คา R2 จะมคาอยระหวาง 0 ถง 1 ถาคา yi และ y(xi) มความแตกตางกนนอยหรอไมม

ความแตกตาง จะไดคา R2 ใกลเคยง 1 เสนกราฟทไดจะสอดคลองและเหมาะสมกบขอมล ควร

จะไดคา R2 มากกวา 0.9

คาทางสถตอกคาหนงคอคาความคลาดเคลอนมาตรฐานของการประมาณคา y

(Standard error of the estimate) จะเปนการหาคาความคลาดเคลอนของคา y ทไดจากการ

คานวณ และคา y ของขอมล ซงหาไดจากสตรตอไปน

Syx = ( )y G(x )

(n m)i i

2−−

∑ ................... (7.17)

เมอ n คอจานวนขอมล และ m คอจานวนสมประสทธในสมการถดถอย เรยก (n - m)

วาเปนองศาของความเปนอสระ (number of degree of freedom) ถาฟงกชนทใชในการ

ประมาณเปนสมการเสนตรง องศาแหงความเปนอสระ คอ n - 2

คา Syx ยงนอย และ R2 ใกลเคยง 1 มากเทาใด แสดงวาฟงกชนทไดสอดคลองและ

เหมาะสมกบขอมลทมอยมากขนเพยงนน

ในโปรแกรม P_Regress.C สาหรบขอมลทเปนแบบพหนามและ M_Regress.C

สาหรบขอมลทมความสมพนธกบแบบมตวแปรอสระหลายตวแปร จะมฟงกชนสาหรบหา

สมประสทธของการกาหนดและความคลาดเคลอนมาตรฐานของการประมาณคา y ดวย กอนท

จะหาคาปรมาณเหลานตองเรยกใชฟงกชนทใชหาคาสมประสทธของสมการเสยกอน และตอง

เลอกใชใหถกกบลกษณะขอมลดวย ถาเปนขอมลทสมพนธกนแบบพหนามตองใชฟงกชน

P_StandardErrorof Estimation และ P_CoefficientDetermination ขอมลทมความสมพนธกน

แบบหลายเชงตองใชฟงกชน M_StandardErrrorofEstimation และ

M_CoefficientofDetermination ขนตอนวธคานวณจะเหมอนกน จะตางกนตรงการผานคาตว

Page 315: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

308

แปร จะมการผานคาตวแปรอะเรย (arrray) แบบมตเดยวสาหรบขอมลแบบพหนาม และแบบ 2

มตสาหรบขอมลมความสมพนธแบบหลายเชง

ตวอยาง 7.4 การเปลยนแปลงของแกสแบบอะเดยบาตก (Adiabatic) วดความดน (p) และ

ปรมาตรแกส(v)ไดดงน

v 10 12 14 16 18 20 22 24

p 39.7 300.

9

24.9 20.5 17.5 15.1 13.1 11.6

ขอมลดงกลาวเปนตามสมการสถานะแกส pvγ = c

วธทา จากสมการ pvγ = c ใส log ทงสองขาง จะได

log p + γ log v = log c

กาหนดให P = log p, V = log v, C = log c

สมการจะกลายเปน

P + γV = C

หรอ P = C - γV

ขอมลจากตารางจะกลายเปน

ใชโปรแกรม P_Regress.C ชวยในการคานวณจะได

C = 3.008, γ = 1.407 หรอ c = 1019

สมการสถานะแกสแบบอะเดยบาตกจะไดเปน

pv1.407 = 1019

V 1 1.0792 1.1461 1.2041 1.2553 1.3010 1.3424 1.3802

P 1.5988 1.4900 1.3962 1.3118 1.2430 1.1790 1.1173 1.0645

Page 316: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

309

ตวอยาง 7.5 จากการทดสอบการหยดของรถทความเรวตาง ๆ กน (v) ระยะทางทรถหยด (x) ม

ดงน

v (กม./ชม.) 30 40 50 60 70

x (ม.) 90 138 206 292 396

จงหาฟงกชนทเหมาะสมเพอใชเปนตวแทนขอมลชดน อยในรป

x = A + Bx + Cx2

วธทา 1) อาจใชวธการดงตวอยาง 7.2 เนองจากระยะหางของ v แตละคามคาเทากน

จงกาหนดให V = v - 50 ตารางจะเปลยนไปดงน

v (กม./ชม.) -20 -10 0 10 20

x (ม.) 90 138 206 292 396

ฟงกชนทตองการหาอยในรป x = a + bV + cV2 ให vi 1n

vi==∑ ∑

หาคา a, b, c จากสมการ (7.6) ซงอยในรปเมทรกซ ดงน

n V VV V VV V V

abc

xVxV x

2

2 3

2 3 4 2

∑ ∑∑ ∑ ∑∑ ∑ ∑

=∑∑∑

ในทน n = 5, ΣV = Σv3 = 0, ΣV2 = 1,000, ΣV4 = 340,000

Σx = 1,122, ΣVx = 7,660, ΣV2x = 237,400

จะได a = 205.83, b = 7.66, c = 0.09286 ฟงกชนทตองการคอ

x = 205.83 + 7.66 V + 0.09286 V2

แทนคา V = V - 50

x = 54.98 - 1.626 v + 0.09286 v2

เมอวเคราะหดฟงกชนทไดจะเหนวานาจะมความคลาดเคลอนจากความเปนจรง

เพราะเมอความเรวเปนศนย (V = 0) ระยะทางทรถหยดไดควรมคาเปนศนย แตในทนจะได x =

Page 317: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

310

54.98 เมตร. ทเปนเชนนเพราะขอมลทมอยนนไมไดเกบคาท v = 0 หรอ v = 0 อยนอกขอบเขต

ขอมลชดน จงเกดความคลาดเคลอนดงกลาวขน

2) ผลลพธทไดจาก P_regress.C มดงน

Curve Fitting by least square method

===========================

Number of polynomial power 2

How many data do you have (in pair) ? :5

Input your data...

X[1] =30 Y[1] =90

X[2] =40 Y[2] =138

X[3] =50 Y[3] =206

X[4] =60 Y[4] =292

X[5] =70 Y[5] =396

Power coefficient determined

----------------------------------

0 5.49714e+01

1 -1.62571e+00

2 9.28571e-02

Standard error of the estimate = 0.47809

The Coefficient of Determination = 0.99999

ตวอยาง 7.6 ขอมลในตารางตอไปน เสนกราฟแบบใดทจะเหมาะกบขอมลมากทสด

x 1 2 3 4 5 6

y 3.2 4.4 4.8 5.2 5.1 5.0

กาหนดใหเสนกราฟมลกษณะแบบใดแบบหนงดงตอไปน

ก) แบบเชงเสน y = a + bx

ข) แบบ log y = a + b ln(x)

ค) แบบเอกซโพเนนเชยล y = aebx

ง) แบบยกกาลง y = axb

วธทา 1) เสนกราฟในขอ ข, ค, ง สามารถเปลยนรปใหอยในรปสมการเชงเสนดงกลาวไวใน

หวขอ (7.1) แลวจงหาคาสมประสทธ a และ b เสนกราฟในขอใดจะเหมาะสมนนใหดจากคา

สมประสทธการกาหนดคา (R2) ถาขอใดมคาเขาใกล 1 ขอนนจะเหมาะสมทสด

Page 318: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

311

ก. y = 3.467 + 0.329 x R2 = 0.673

ข. y = 3.456 + 1.059 ln x R2 = 0.876

ค. y = 3.460 e0.0787 x R2 = 0.647

ง. y = 3.441 x0.256 R2 = 0.859

จะเหนวาเสนกราฟในขอ ข. เหมาะสมทสดสาหรบขอมลชดน

2) ใชโปรแกรม P_regress.C ชวยคานวณ ผลลพธจะไดดงน

ก. แบบเชงเสน จะได

a = 3.46667

b = 0.328571

ความคลาดเคลอนมาตรฐานของการประมาณคา y = 0.47933

สมประสทธการกาหนดคา (R2) = 0.67274

ข. แบบ log กาหนดให X = ln (x) จะไดตารางขอมลใหมดงน

x 0 0.693 1.098 1.386 1.609 1.792

y 3.2 4.4 4.8 5.2 5.1 5.0

ใหโปรแกรม P_regress.C ทางานแลวปอนขอมลใหมอกครง จะได

a = 3.45593

b = 1.05874

ความคลาดเคลอนมาตรฐานของการประมาณคา y = 0.29476

สมประสทธการกาหนดคา = 0.87625

ค. แบบเอกซโพเนนเชยล y = aebx

ใส log ทงสองขาง

ln x = ln a + bx

ให A = ln a , Y = ln y

จะไดตารางใหมดงน

x 1 2 3 4 5 6

y 1.163 1.482 1.569 1.649 1.629 1.609

Page 319: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

312

จะได A = 1.24173 หรอ a = 3.46160

b = 0.0786

ความคลาดเคลอนมาตรฐานของการประมาณคา y = 0.12203

สมประสทธการกาหนดคา = 0.64478

ง. แบบยกกาลง y = axb

ใส log ทงสองขาง

ln x = ln a + b ln x

ให Y = ln y , A = ln a และ X = ln x

จะไดสมการ

Y = A + bX

ตารางขอมลจะกลายเปน

x 0 0.693 1.098 1.386 1.609 1.792

y 1.163 1.482 1.569 1.649 1.629 1.609

ผลลพธจากการใหโปรแกรม P_regress คานวณจะได

จะได A = 1.23619 หรอ a = 3.44247

b = 0.25982

ความคลาดเคลอนมาตรฐานของการประมาณคา = 0.07718

สมประสทธการกาหนดคา = 0.85791

ตวอยาง 7.7 เมอแกสอยในภาวะสมดลโดยอยรวมกนกบสถานะของแขงหรอของเหลว แกสหรอ

ไอนจะอยในภาวะอมตว ความดนอมตวของแกส (P) จะขนอยกบอณหภม (องศาสมบรณ, T)

เพยงอยางเดยว สมการทแสดงคาความดนอมตวของแกสกบอณหภมอมตวมดงน

ln P = A + BT + C ln T

ขอมลตอไปนเปนความดนของไอตะกวซงอยรวมกบตะกวเหลวจงหาคา A, B และ C

Page 320: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

313

T P(torr) T P(torr)

700 1 × 10-9 1200 6.067 × 10-4

800 5.598 × 10-8 1300 2.512 × 10-3

900 1.234 × 10-6 1400 8.337 × 10-3

1000 1.507 × 10-5 1500 2.371 × 10-2

1100 1.138 × 10-4 1600 5.875 × 10-2

วธทา ความสมพนธของ P และ T ไมไดอยในรปพหนาม

เราสามารถจดรปสมการใหม โดยกาหนดให

y = ln P , x =1P , z = ln T

จะไดรปสมการเปน

y = A + Bx + Cz

y จะเปนตวแปรตาม x และ z (มตวแปรอสระ 2 ตวแปร) เขยนตารางขอมลไดใหม

ดงน

x 1.429 1.250 1.111 1 0.909 0.833 0.769 0.714 0.667 0.625

z 6.551 6.685 6.802 6.908 7.03 7.090 7.170 7.244 7.313 7.378

y -

20.723

-

16.698

-

13.6005

-

11.103

-9.081 -7.407 -5.987 -4.787 -3.742 -

2.8344

การแปลงตารางอาจเขยนโปรแกรมใหคอมพวเตอรชวยแปลงให ดงน

โปรแกรม 7.3 แสดงการแปลงตารางในตวอยาง 7.7 โดยดดแปลงโปรแกรม

M_Regress.C ในสวนของ main program จะสะดวกตรงทโปรแกรมจะคานวณคา x, y และ z

โดยทไมตองเสยเวลากดเครองคดเลข รายละเอยดทแสดงตอไปนจะแสดงเฉพาะสวน main ทม

การเปลยนแปลงเทานน รายละเอยดทเหลอจะเหมอนกบโปรแกรม M_Regress.C ทกประการ

โปรแกรมนจะตองคอมไพลแบบ LARGE เทานน

/*

* Program 7.3 Test7_7.C

* Purpose: Use multiple regression to solve the promblem 5.7

* Author : Wachara Rodsumrid.

* Office : Dept of Physics. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

Page 321: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

314

* Last update : 14 Apr 96

* Warning !!! : This promgram must be compiled in LARGE MODEL .

**************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#define ARRAY_SIZE 51

#define ROW_SIZE 151

#define ZERO_APPROACH 2.20E-16 /* for double precision */

int GaussElimination(int , double aug[][ARRAY_SIZE]);

int Linear_Multi_Regression(int, int, double x[][ARRAY_SIZE],

double y[],double coeff[]);

int DataInput( int,double x[][ARRAY_SIZE],double y[]);

void PrintData(int,int, double x[][ARRAY_SIZE], double y[]);

void ShowCoeff(int, int , double a[]);

int M_StandardErrorofEstimate(int n_term, int n_data, double x[][ARRAY_SIZE],

double y[], double coeff[],double *);

int M_CoefficientofDetermination(int n_term, int n_data, double x[][ARRAY_SIZE],

double y[], double coeff[],double *);

main()

{

int error,i,j;

double x[ROW_SIZE][ARRAY_SIZE], y[ROW_SIZE],coeff[ROW_SIZE+1];

int n_data,nx;

int n_coeff; /* number of coefficient = num of x + 1 */

double std_err;

double cd; /* coeff of determination */

double T[ROW_SIZE],P[ROW_SIZE],xx[ROW_SIZE],zz[ROW_SIZE];

printf("\n\tChange data in table 5.7\n");

printf("\t==========================\n");

Page 322: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

315

T[1] =700;

for(i=2; i<=10; i++)

T[i]= T[i-1]+100;

for (i =1; i<=10;i++){

xx[i] = 1/T[i];

zz[i] = log(T[i]);

}

P[1] = 1e-9; P[2] = 5.598e-8; P[3] = 1.234e-6;

P[4] = 1.507e-5; P[5] = 1.138e-4; P[6] = 6.067e-4;

P[7] = 2.512e-3; P[8] = 8.337e-3; P[9] = 2.371e-2;

P[10] = 5.875e-2;

for (i=1; i<=10;i++)

y[i] = log(P[i]);

printf("\n\tCurve Fitting by Linear Multiple Regression.\n");

printf("\t======================================\n");

/* printf("\tNumber of independent Variable(X) : ");scanf("%d",&nx);*/

nx = 2;

n_coeff = nx + 1;

/* n_data = DataInput(nx,x,y); */

n_data = 10;

for (j=1; j<=10;j++){

x[j][1] = xx[j];

x[j][2] = zz[j];

}

/* for checking your data */

PrintData(nx,n_data,x,y);

error = Linear_Multi_Regression(nx,n_data,x,y,coeff);

ShowCoeff(error,n_coeff,coeff);

error =M_StandardErrorofEstimate(n_coeff,n_data,x,y,coeff,&std_err);

if (error ==0) {

printf("\nStandard error of the estimate = %10.5f\n", std_err);

}

error = M_CoefficientofDetermination(nx+1,n_data,x,y,coeff,&cd);

if (error ==0) {

printf("\nThe Coefficient of Determination = %10.5f\n", cd);

Page 323: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

316

}

return(0);

}

โปรแกรม Test 7.7.C ทางานไดผลลพธ ดงน

A = 18.1712

B = -2.31736 × 1004

C = -0.883842

คาความคลาดเคลอนมาตรฐานของ y = 0.00720

สมประสทธการกาหนดคา = 1

แสดงวาขอมลทไดมานสอดคลองกบสมการ

ln P = 18.1712 - 23173.6

T - 0.883842 ln T

ตวอยาง 7.8 ในการทดลองเรอง photoelectric effect ไอนสไตนไดหาความสมพนธระหวาง

threshold Voltage (V0), work function (w) ของโลหะและความถของแสง (f) ไวดงน

eV0 = hf - w

เมอ e ขนาดประจของอเลกตรอน = 1.60219 × 10-19 คลอมบ

h คอคาคงทของแพลงค (Planck’s constant)

เราสามารถจดการทดลองหาคาคงทของแพลงคโดยการวด V0 และ f แลวจดรปสมการ

ใหม ดงน

V0 = ( ) ( )he f w

e+ −

ผลการทดลองมดงน

f (1013 Hz) 56 70 79 83 102 120

V0 (volt) 0.05 1.0 1.4 1.74 2.43 3.0

จงหาคา h จากผลการทดลองดงกลาว

Page 324: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

317

วธทา 1) รปสมการเปนสมการเชงเสน เพราะ w มคาคงทสาหรบโลหะแตละชนด สามารถ

เลอกใชไดทง P_Regress.C หรอ M_Regress.C ในทนจะเลอกโปรแกรม M_Regress.C

เมอใหโปรแกรมทางานพรอมปอนขอมลจากตาราง จะไดคาตอบเปน

V0 = .0450305 × 10-13 f - 2.224266 Hz

ความชนของสมการคอ .045035 × 10-13 = h/e

แทนคา e จะได h = 7.21474 × 10-34 จล⋅วนาท คาคงทของแพลงคตามทฤษฎคอ 6.625 × 10-34 J⋅s

คาทไดจากผลการทดลองตามขอมลทไดมาคลาดเคลอนไป = 0.59 × 10-34 J⋅s

หรอความคลาดเคลอนสมพทธ = 8.9%

ความคลาดเคลอนมาตรฐานของการประมาณคา V0 = 0.19889

สมประสทธการกาหนดคา (R2) = 0.97108

ตวอยาง 7.9 ความตานทานของขดลวดความรอน (R) ในเตาไฟฟาแปรผนตามสมการ ดงน

R = R0 + CI2

เมอ I คอกระแสไไฟามหนวยเปนแอมแปร

R มหนวยเปนโอหม

จงหาคาคงท R0 และ C จากขอมลตอไปน

I 1 2 4 6 9 12

R 0.141 0.234 1.055 2.273 5.015 8.854

วธทา กาหนดให X = I2 ตารางจะเปลยนใหมเปน

I 1 4 16 36 81 144

R 0.141 0.234 1.055 2.273 5.015 8.854

ใชโปรแกรม M_Regress. C หรอ P_Regress.C หาคา R0 และ C จะไดผลลพธดงน

R0 = 0.0533577

C = 0.0611768

ความคลาดเคลอนมาตรฐานของการประมาณคา R = 0.03789

สมประสทธของการกาหนดคา (R2) = 0.99990

Page 325: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

318

ตวอยาง 7.10 อตราการสลายของนวเคลยสของธาตกมมนตรงสขณะใดขณะหนงจะแปรผนตรง

กบจานวนนวเคลยสของธาตกมมนตรงสทมอยในขณะนน

ให N0 เปนจานวนนวเคลยสของธาตกมมนตรงสเมอเรมตนวด

N เปนจานวนนวเคลยสของธาตกมมนตรงสทเหลออยเมอเวลาผานไป t วนาท

λ คอคาคงทการสลายตว (Decay Constant)

ความสมพนธระหวาง N กบ t คอ

N = N0e-λt

ถาให N = N2

0 จะได t = T2

1 = ครงชวตของธาตกมมนตรงสนน ๆ โดยท T2

1 =

0.693/λ

ผลการทดลองตอไปนไดจากการใชเครองนบไกเกอร (Geiger Counter) นบจานวนครง

การสลายตวของธาตอนเดยม (In116) โดยจบเวลาทก ๆ ชวง 10 นาท ตองการหา λ และ T2

1

ของธาต In จากผลการทดลองน

t - interval [0, 10] [10, 20] [20, 30] [30, 40] [40, 50] [50, 60]

จานวนครง 19,879 15,542 13,272 11,882 10,143 8937

วธทา แปลงสมการการสลายตวของธาตกมมนตรงสใหอยในรปสมการเชงเสน โดยใส log

ทงสองขาง

ln N = ln N0 - λt

ให Y = ln n , A = ln N0 และ B = -λ

จะได Y = A + Bt

เราสามารถเลอกใชคา t ตรงสวนทเปนจดปลายซายสด หรอขวาสด หรอจดกงกลาง

(mid point) อยางใดอยางหนง ตารางขอมลจะเปลยนไปดงน

t 10 20 30 40 50 60

Y 9.8974 9.6513 9.4934 9.3826 9.2245 9.0980

ใชโปรแกรม M_Regress.C หาคา A, B จะได

A = 9.99669 B = λ = -1.53949 × 10-2

คาสมประสทธของการกาหนดคา = 0.98400

Page 326: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

319

ความคลาดเคลอนมาตรฐานของการประมาณคา Y = 0.004106

คานวณหาคา T2

1 = 0.693λ = 45.014 นาท

เมอทดลองใชคา t = 0, 10, 20, 30, 40, 50 ซงเปนจดปลายดานซายมอ หรอ t = 5, 15,

25, 35, 45, 55 จะไดคา λ เทากนทกกรณ

7.5 บทสรป ในบทนใชระเบยบวธกาลงสองนอยทสดหาสมการทเปนตวแทนทดทสดของขอมล ม

ฟงกชนสามารถนาไปใชงาน 2 ฟงกชน คอ Polynomial_Regression ใชกบขอมลทมตวแปรตาม

และตวแปรอสระ 1 ตวแปร มความสมพนธกนแบบพหนาม โดยจากดตวแปรอสระไวใหมอนดบได

ไมเกน 10 (x10) และ Linear_Multi_Regression ใชกบขอมลทมตวแปรตามสมพนธกบ

ตวแปรอสระมากกวา 1 ตวในลกษณะเชงเสน จานวนตวแปรอสระกาหนดไวไมเกน 10 ตวแปร

ฟงกชนทงสองสามารถใชหาความสมพนธของขอมลแบบเชงเสนทมตวแปรอสระเพยง 1 ตว ได

ผลลพธเทากนทงค

มฟงกชนเสรมสาหรบใชตรวจสอบความเหมาะสมของสมการทไดจากระเบยบกาลง

สองนอยทสด คอตรวจสอบความคลาดเคลอนมาตรฐานของการประมาณคา y และสมประสทธ

ของการกาหนด (R2) ซงจะเปนตวชใหเหนวาขอมลทไดมความสมพนธสอดคลองกบสมการทได

และเบยงเบนไปจากสมการทไดมากนอยเพยงใด ในกรณทเปนงานวจยจะตองนาคาสมประสทธ

ของการกาหนดนไปทดสอบหาความเชอมนดวยคาสถต F (F-test) เสยกอน เพอใหไดหลกประกน

วาคาทไดมานมใชมาจากความบงเอญของขอมลมาสอดคลองกบสมการทไดมาพอด

ถาขอมลทไดมความสมพนธกนในลกษณะลอกการทม หรอแบบเอกซโพเนนเชยล เรา

สามารถเปลยนรปสมการใหอยในแบบสมการเชงเสนไดเสมอ (Linearization) แลวจงเลอกใช

ฟงกชนทมอย 2 ฟงกชน หาสมการทานายทตองการได

Page 327: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

320

This page also left blank intentionally

Page 328: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

321

บทท 8 การคานวณคาสถตเบองตน

เมอเกบขอมลทางฟสกสทไดจากการทดลอง ขอมลเหลานนอยในรปตวเลขหรอเชง

ปรมาณ เชน ใชไมโครมเตอรวดเสนผาศนยกลางของเสนลวดเสนหนงหลาย ๆ ครง หรอวดคา g

ในหองเรยนโดยใหวตถตกจากตาแหนงทสงจากพนตาง ๆ กน แลวจบเวลาการเคลอนท เราจะได

เสนผาศนยกลางของเสนลวด หรอคา g หลาย ๆ คา เมอนาขอมลทรวบรวมไดเหลานมาสรปผล

การทดลอง โดยใชสถตเชงพรรณนา (Descriptive Statistic) หาความถ คาเฉลย ความ

เบยงเบนจากคาเฉลยของขอมล แลวนาเสนอเปนรายงานการทดลอง

ในบทนจงประกอบโปรแกรมเรยงลาดบขอมล เพอใชประกอบในการหาความถของ

ขอมล การหาคาเฉลย และความเบยงเบนมาตรฐานของขอมล ถาขอมลทไดมลกษณะกระจาย

แบบโคงปกต จะมโปรแกรมสาหรบหาความนาจะเปนของขอมลคาตาง ๆ สามารถนาโปรแกรม

เหลานไปประกอบการวเคราะหขอมลทไดจากการทดลอง

8.1 การเรยงลาดบขอมล การจดเรยงลาดบขอมลมประโยชนคอ ทาใหเกดความสะดวกในการคนหา แกไข

เปลยนแปลงขอมล หรองายตอการนาไปคานวณคาตาง ๆ การเรยงลาดบขอมลอาจเรยงลาดบ

จากคานอยไปสคามาก (ascending) หรอจากคามากไปสคานอย (descending) โปรแกรม

เรยงลาดบขอมลมผเขยนไวเปนโปรแกรมสาเรจรปมากมาย สามารถดงมาใชในโปรแกรมของเรา

ไดทนท แตโปรแกรมเหลานอาจเขยนไวใชกบขอมลประเภทตวอกษร หรอขอมลทมทงตวเลขและ

ตวอกษรรวมกนเปนระเบยน (record) ถาตองการเรยงลาดบขอมลทเปนตวเลขเพยงอยางเดยว

โปรแกรมสาเรจรปอาจมขนาดใหญเกนความจาเปน หรอทางานไดชาเมอนามาใชกบขอมลท

ตวเลข ดงนน ในหวขอนจงนาการเรยงลาดบขอมลมาเขยนเปนโปรแกรมไวใชงานทาง

วทยาศาสตร โดยจะเรยงลาดบตวเลขจากนอยไปมากหรอมากไปนอยกได ขนตอนวธทจะเสนอ

ตอไปนจะนาขอมลทงหมดมาเกบไวในหนวยความจาหลก แลวจะเรยงลาดบภายใน

หนวยความจา เพราะโปรแกรมเรยงลาดบบางโปรแกรมตองอาศยเกบขอมลบางสวนลงในแผน

บนทกขอมลดวย

ขนตอนวธการจดเรยงลาดบตวเลขมหลายวธไดแก วธ Bubble Sort, shaker Sort,

Heap Sort , Quick Sort, Shell Sort, Binary insertion Sort ฯลฯ ถงจะมมากมายหลายแบบก

ตาม ทงหมดนสามารถแบงออกไดเปน 3 แบบใหญ ๆ ดงน

Page 329: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

322

ก) วธสลบเปลยน (exchange)

ข) วธเลอกคาทตองการ (Selection)

ค) วธแทรกตรงตาแหนงทตองการ (insertion)

แตละวธสามารถอธบายใหเขาใจไดงาย ๆ ดงน สมมตวาจะเรยงไพสารบหนงจาก

นอยไปมาก การเรยงลาดบโดยวธสลบททาไดโดยหงายไพลงบนโตะทกใบ แลวสลบเปลยนไพทยง

ไมอยในลาดบใหอยในลาดบ

การเรยงลาดบโดยวธเลอกคา ทาไดโดยหงายไพทกใบบนโตะ หยบไพใบทมคานอย

ทสดมาถอไวในมอ จากนนเลอกไพใบทนอยทสดทอยบนโตะขณะนนมาถอไวในมอในลาดบถดไป

ทาเชนนเรอย ๆ ไพในมอจะถกเรยงลาดบจากนอยไปมากเมอไพถกเลอกจากบนโตะทกใบ

วธแทรกตาแหนง ทาไดโดยถอไพไวในมอบางสวน แลวเลอกมาครงละ 1 ใบ ดงไพ

จากทเหลอในกองมาวางเรยงใหมบนโตะ แลวนาไพในมอไปแทรกตรงตาแหนงทถกตอง เมอหมด

ไพในมอและบนกอง ไพทถกเรยงใหมจะถกเรยงเปนไปตามลาดบ

การตดสนใจทจะเลอกใชขนตอนวธการเรยงลาดบขอมลแบบใดจงจะมประสทธภาพ

มากทสด ประการแรกใหพจารณาจากความเรวของการเรยงลาดบขอมลโดยเฉลยของวธนน

ความเรวของการเรยงลาดบจะขนอยกบจานวนครงของการเปรยบเทยบและการสลบเปลยน

ขอมล การเรยงลาดบแบบใดทใชจานวนครงของการเปรยบเทยบและการสลบเปลยนขอมลมาก

ความเรวในการเรยงลาดบขอมลจะยงชาลง ๆ ถาขอมลมจานวนมาก ๆ ประการทสองให

พจารณาจากการเรยงลาดบขอมลในกรณทขอมลมลกษณะเรยงตวทไมเปนระเบยบมากทสด

ขนตอนวธการเรยงลาดบบางวธจะมความเรวในการเรยงลาดบขอมลชาทสด ถาพบขอมลในกรณ

เชนน หรอกรณทขอมลถกเรยงลาดบจากมากไปนอยแลวตองการเปลยนใหมใหเรยงลาดบจาก

นอยไปมาก การเรยงลาดบจะทาไดเรวหรอชาเพยงใด ประการทสาม ถาการเรยงลาดบเกยวของ

กบขอมลทเปนระเบยน (record) ใชฟลด (field) มากกวา 1 ฟลดเปนคย (key) ในการจดลาดบ

ตองตรวจสอบดวาถาคยหลกมคาเทากน การเรยงลาดบคยรอง (sub key) ทาไดถกตองหรอไม

ขนตอนวธการเรยงลาดบบางครงทคยหลกมคาเทากน จะกระโดดขามไปเปรยบเทยบระเบยน

ตอไปเลย โดยไมสนใจทจะสลบคาคยรอง ทาเชนนเพอความเรวในการเรยงลาดบ

เมอตองการจะเลอกใชการเรยงลาดบขอมลแบบเปนตวเลข จากการทดสอบขนตอน

วธของการเรยงลาดบตาง ๆ ไดรายงานผลไวในวารสาร Computer Language ฉบบเดอนมนาคม

พ.ศ. 2531 ไวดงน ถาขอมลมลกษณะสม (random) แลว การเรยงลาดบแบบ Quick Sort จะ

ใชไดเรวทสด แตถาตองการเปลยนลาดบขอมลทเรยงลาดบจากนอยไปมากอยแลว เปนเรยงจาก

มากไปสคานอย heap sort จะทางานไดดทสด

Page 330: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

323

ในทนจะเสนอวธการเรยงลาดบตวเลข 2 วธ คอแบบควกซอรต และแบบเชลล ซอรต

ซงเหมาะสมทจะใชลาดบขอมลทเปนตวเลขทางวทยาศาสตร วธอน ๆ ทไมไดกลาวถงอาจหาอาน

ไดจากหนงสอทเกยวกบคอมพวเตอรทว ๆ ไป หรอหนงสออางองทไดอางไวในทายเลมของหนงสอ

8.1.1 การจดเรยงลาดบขอมลแบบควก ซอรต (Quick sort) ผคนคดขนตอนวธการเรยงลาดบแบบนคอ ฮอร (C.A.R. Hoare) เมอป พ.ศ. 2504

กลาวกนวาเปนการเรยงลาดบขอมลทเรวทสดเทาทคนพบ โดยเฉพาะขอมลทมเปนจานวนมาก

การเรยงตวของขอมลเปนแบบไมเปนระเบยบ

ควก ซอรต อาศยหลกการแบงขอมลออกเปนสวน ๆ ขนแรกตองเลอกขอมลท

เหมาะสมขนมาตวหนงเอาไวเปรยบเทยบ เรยกวา comparand ใชขอมลตวนเปนหลก ขอมลท

เหลอถามคานอยกวาใหอยดานหนง ขอมลทมคามากกวาใหอยอกดานหนง กระทาเชนนกบ

ขอมลแตละดาน ขอมลแตละดานจะถกแบงเปนสวนยอย ๆ ลงไปอก หาตวเปรยบเทยบของแตละ

สวนยอย กระทาซาจนขอมลของแตละสวนยอย ๆ ถกเรยงลาดบหมดทกตว

เพอใหงายตอความเขาใจจะยกตวอยางขอมล 12 ตว ทยงไมถกเรยงลาดบ จะ

เรยงลาดบใหมจากคานอยไปคามาก โดยวธควก ซอรต ดงน

54, 12, 83, 21, 68, 73, 98, 77, 90, 61, 23, 7

ขนท 1 ขอมลชดนมอย 12 ตว ตาแหนงแรก (left) = 0 ตาแหนงสดทาย (right) = 11

กาหนดตวชขนมา 2 ตวคอ i และ j ให i ชไปทตวซายมอสด j ชไปทตวขวามอสด เลอกตว

เปรยบเทยบ (comparand) ขนมาตวหนง ในทนคอ 73 โดยหาจาก item ((0 + 11)/2) = item

(5)

ขนท 2 เรมจากทางซายมอ นาขอมลตงแตตวท 1 เปรยบเทยบกบ 73 ถาพบขอมลทมคานอย

กวาใหเพมคา i อก 1 ถาพบขอมลทมคามากกวา 73 ใหหยดตวชไวทจดน จากนนเรมจากทาง

ขวามอ นาขอมลตวสดทายเปรยบเทยบกบ 73 ถาขอมลมคามากกวาใหลดคา j ลง 1 ถานอย

กวาหรอเทากบ 73 ใหหยดตวชไวทจดน ตวชจะชอยทขอมลดงน

Page 331: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

324

ขนท 3 สลบขอมลตรงตาแหนงทตวชชอย จากนนเพมคา i และลดคา j อก 1

ขนท 4 ตรวจดวา i < j หรอไม ถา i ยงนอยกวา j ยอนทาขนท 2 อกครง แตเรมทขอมล item

(3) ถาขอมลมคานอยกวา 73 ใหเพมคา i อก 1 ทางขวามอกเชนเดยวกน ตวชจะมาหยดท

item(10) เพราะ 23 มคานอยกวา 73

ขนท 5 สลบขอมลตรงตาแหนงทตวชชอย เพมคา i อก 1 และลดคา j ลง 1

ขนท 6 ตวช i มาหยดท 96 (เพราะ 96 มากกวา 73) และตวช j หยดท 61 เพราะ 61 นอยกวา

73 สาหรบขอมลระหวาง item (6) คอ 98 และ item(9) คอ 61

ขนท 7 i ยงคงนอยกวา j ตวช i จะหยดท 77 ตวช j จะลดคาลงอก 1 เพราะ 90 > 73 เมอ

i = j ตอนนจะเหนวาขอมลจะถกแบงเปน 2 สวนยอย ทางดานซายมอจะเปนขอมลทมคานอย

กวา 73 ทางดานขวามอจะเปนขอมลทมคามากกวาหรอเทากบ 73

(54, 12, 7, 21, 68, 23, 61) (77, 90, 98, 73, 83)

ขนท 8 ทาเชนเดยวกนนกบขอมลชดดานซายมอ โดยมจานวนขอมล 7 ตว left = 0 right = 6

ตวเปรยบเทยบของขอมลชดนคอ item ((6+10)/2) = item (3) = 21

Page 332: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

325

จะไดขอมลดานซายมอออกเปน 2 ชดยอยอก ดานซายมอจะมคานอยกวา 21 และ

ดานขวามอจะมากกวา 21

(21, 12, 7) (54, 68, 23, 61)

ขนท 9 เรยงลาดบขอมลชดซายมอ คอ (21, 12, 7) มขอมลอย 3 ตว i = 0 และ j = 3 ตว

เปรยบเทยบคอ 12 เรยงลาดบแลวจะได

(7, 12, 21) เมอสนสดรอบนจะได j = 0, i = 2

ขนท 10 เมอ j นอยกวา i จงเรมทาชดขวามอ คอ

(54, 68, 23, 61)

ตวเปรยบเทยบขอมลชดนคอ 68

เรยงลาดบจะได

(54, 61, 23) (68)

ขอมลจะถกแบงเปน 2 ชดยอย เรยงลาดบขอมลทางดานซายมอจะได

(23, 54, 61) (68)

ขนท 11 ตอนนขอมลทมคานอยกวา 73 จะถกเรยงลาดบจากนอยไปมากเรยบรอยแลว ดงน

7, 12, 21, 23, 54, 68, (77, 90, 98, 73, 83)

จงยอนกลบมาเรยงลาดบขอมลทางดานขวามอ โดยขนตอนวธแบบเดยวกน จนได

ขอมลเรยงลาดบจากนอยไปมากครบทกตว

ขอมลทยกเปนตวอยางน เมอเขยนโปรแกรมใหคอมพวเตอรเรยงลาดบโดยวธควก

ซอรต จะไดดงน

Page 333: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

326

/* Program 8.1 QS.C

* Purpose: Show how to sort the numbers in an array by quick sort method.

* Author : Wachara R.

* Office : Dept of Science. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Last update : 13 May 96

**************************************************************/

#include <stdio.h>

#include <math.h>

void quick_sort(double item[], int left,int right, int ascending);

void main()

{

/* input your unsorted number in here */

double dat[15]= { 54,12,83,21,68,73,98,77,90,61,23,7};

int i; clrscr();

printf("Before Sort...\n");

for ( i =0; i < 12; i++) {

printf("%f ",dat[i]);

}

printf("\n");

quick_sort(dat,0,11,1);

printf("After sort....\n");

for ( i =0; i < 12; i++) {

printf("%f ",dat[i]);

}

printf("\n");

}

/********* Quick_Sort function starts here ********************/

void quick_sort(double item[], int left,int right,int ascending)

{

/* Function Description : Sort the numbers in array using Quick Sort.

User's difine Constant: none

Input : item[] an array which numbers are stored in.

The first number begin at item[0] (not

item[1]) and the last number is in item[n-1].

Page 334: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

327

left the first number will be sorted.

right the last number will be sorted.

ascending in ascending order = 1

in decending order = 0

Calling Function : none

Output : The sorted numbers are stored in item[].

Return Value : none

*/

int i,j;

int k = 0;

double comparand,temp;

i = left; j = right;

comparand = item[(left+right)/2];

do { if (ascending) {

while(item[i] < comparand && i < right) i++;

while (comparand < item[j] && j > left) j--;

} else {

while(item[i] > comparand && i < right) i++;

while (comparand > item[j] && j > left) j--;

}

if ( i <= j) {

temp = item[i];

item[i] = item[j];

item[j] = temp;

i++; j--;

}

for(k=left;k<=right;k++) printf("%3.1f ",item[k]);

printf("\n");

} while (i <=j);

/* printf("Between Sorting....\n");

printf("Comparand = %f\n",comparand);

for ( k =left; k <= right; k++) {

printf("%f ",item[k]);

}

printf("\n");

*/

Page 335: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

328

if (left <j ) quick_sort(item,left,j,ascending);

if (i < right) quick_sort(item,i,right,ascending);

}

/********* End of Quick_Sort function ********************/

การนาฟงกชนควก ซอรต ไปใชงาน ก. คาคงททตองนยาม -

ข. การผานคาอนพทและเรยงใชฟงกชน -

quick sort (double item [ ], int left, int right, int ascending)

item คอ ขอมลทเปนจานวนเลขทตองการจะเรยงลาดบขอมล

left คอ ขอมลตวแรกทจะเรยงลาดบ

right คอ ขอมลตวสดทาย

ascending เปนตวกาหนดวาจะเรยงจากคามากไปหาคานอย หรอเรยงจากคา

นอยไปหาคามาก

0 จะเรยงจากคามากไปยงคานอย

1 จะเรยงจากคานอยไปหาคามาก

ขอควรระวง การสงผานขอมล n ตว มายงอะเรย item ขอมลตวแรกจะอยท item [0]

ขอมลตวสดทายจะอย item [n-1] เสมอ

ค. ฟงกชนทเกยวของ -

ง. การสงคากลบ -

ฟงกชนควก ซอรต ถาเขยนดวยภาษาคอมพวเตอรอน ๆ เชน เบสก หรอฟอรแทรน จะ

ยาวมาก แตถาเขยนดวยภาษาซจะใชคาสงเพยงไมกบรรทด เพราะฟงกชนในภาษาซสามารถ

เรยกใชตวมนเองได (recursion) จงทาใหโปรแกรมมขนาดกระทดรดกวาใชภาษาคอมพวเตอรอน

โปรแกรมนสามารถตรวจสอบการเรยงลาดบแตละขนตอนไดจากคาสง printf ทแทรกอยใน

โปรแกรมน โดยทตองถอดเอา comment ระหวางคาสงนออกเสยกอน

ควก ซอรต มขนตอนวธแบบอาศยการสลบเปลยนของขอมล กรณทเลวรายทสด

ของควก ซอรตเกดขนเมอมขอมลอย n ตว และขอมลถกแบงออกเปน 2 ตว และอกดานหนง n - 2

ตว ถาขอมลในแตละดานถกเรยงลาดบเรยบรอยแลว ควก ซอรตจะทางานไดชาสด การปองกนม

ใหกรณนเกดขนคอ ใสคาสง while ใหวนรอบตรงสวนเรมตนของโปรแกรมเพอขามการสลบคา

(by pass) ในกรณทขอมลถกเรยงลาดบไวแลว

Page 336: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

329

ตวเปรยบเทยบ (comparand) ทใชในโปรแกรมนจะเลอกคาทเปนมธยฐานของขอมล

แตละชด ในบางโปรแกรมจะเลอกเอาขอมลตวท 1 หรอขอมลทเปนคาเฉลยหรอใกลคาเฉลยของ

ขอมลทสด หรอบางโปรแกรมใชวธสมแบบ random ถาตวเปรยบเทยบเปนขอมลทมคามากทสด

(กรณเรยงจากนอยไปมาก) จะเปนกรณควก ซอรตทางานไดชาทสด

8-1.2 การเรยงลาดบแบบเชลล ซอรต (Shell sort) ผทคดคนวธการเรยงลาดบแบบนคอ D.L. Sheell เมอ พ.ศ. 2502 หลกการทวไปของ

วธนมดงน สมมตวาขอมลม 6 ตว ดงตอไปนจะทาการเรยงลาดบจากนอยไปมาก

3, 8, 7, 1, 5, 2

นาขอมลตวท 1 เปรยบเทยบกบขอมลทอยถดไป 2 ตว ดงแผนภาพ

3, 8, 7, 1, 5, 2

สลบขอมล ถาขอมลทอยซายมอมคามากกวาขอมลดานขวามอ

1, 5, 2, 3, 8, 7

นาขอมลทมอยดานซายมอเปรยบเทยบกบขอมลทอยถดตวมนเองไป 1 ตว

1, 5, 2, 3, 8, 7

จะไดเปน

1, 3, 2, 5, 8, 7

นาขอมลแตละตวเปรยบเทยบกบขอมลทอยถดไป

1, 3, 2, 5, 8, 7

จะไดผลลพธสดทายเปน

1, 2, 3, 5, 8, 7

หลกการโดยทวไปของเชลล ซอรต คอนาขอมลไปแทรกตรงตาแหนงทถกตองทมนควร

จะอย โดยลดชวงหางของการเปรยบเทยบลงในแตละเทยวของการเรยงลาดบ ชวงหางของการ

เปรยบเทยบขอมลในเทยวสดทายคอ 1 เทยวกอนหนานนคอ 2 และเทยวแรกคอ 3 ชวงหางของ

Page 337: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

330

ขอมลทจะใชในการเปรยบเทยบในแตละเทยวควรเปนอยางไรนน โดนล นช (Donald E. Knuth)

ไดแนะนาไวในหนงสอ The Art of Computer Programming) ดงน

1, 4, 13, 40, 121, .....

เปนอนกรมของ

xi+1 = 3 × xi + 1 เมอ i = 1, 2, .... n เมอ n คอขนาดของอะเรย

ชวงหางของขอมลอาจจะเปน

1, 3, 7, 15, 31, 63, 127

เปนอนกรมของ xi+1 = 2 × xi + 1 เมอ i = 1, 2, 3, ... n

ชวงหางของการเปรยบเทยบขอมลไมควรเปนอนกรม 1, 2, 4, 6, 8, ..... ถงแม

โปรแกรมจะยงคงทางานได แตอนกรมแบบนจะลดประสทธภาพการทางานของเชลล ซอรตมาก

ทสด

ในโปรแกรมนจะคานวณหาชวงหางของขอมล(d)เพอใชในการเปรยบเทยบจากสตร

d = 2log nlog2 1−

จากนน จงลดชวงหางลงมาครงละ d/2 ในแตละเทยวจะหยดทางานเมอ d = 1

การนาโปรแกรมเชลล ซอรต ไปใชงาน การนาโปรแกรมเชลล ซอรต ไปเรยงลาดบจานวนเลขจะตองอยในเงอนไขตอไปน

ก. คาคงททตองนยาม

ข. การผานคาอนพทและเรยงใชฟงกชน

Void Shell_sort (double item [ ], int ndata, int ascending)

item คอ ขอมลทเปนจานวนเลขทตองการจะเรยงลาดบขอมล

ndata คอ จานวนขอมลทงหมดทจะเรยงลาดบ

ascending 0 - จะเรยงจากคามากไปสคานอย

1 - จะเรยงจากคานอยไปสคามาก

ขอมลตวแรกจะอยใน item [0] ขอมลตวสดทายจะอยใน item [ndata-1]

ค. ฟงกชนทเกยวของ

ง. การสงคากลบ

Page 338: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

331

รายละเอยดของโปรแกรมเชลล ซอรต มดงน

/* Program 8.2 Shell_S.C

* Purpose: Show how to sort the numbers in an array by qShell's method.

* Author : Wachara R.

* Office : Dept of Science. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Last update : 20 May 96

**************************************************************/

#include <stdio.h>

#include <math.h>

void Shell_sort(double *item, int ndata, int ascending);

void main()

{

/* input your unsorted number in here */

double dat[15]= { 54,12,83,21,68,73,98,77,90,61,23,7};

int i; clrscr();

printf("Before Sort...\n");

for ( i =0; i < 12; i++) {

printf("%f ",dat[i]);

}

printf("\n");

Shell_sort(dat,12,1);

printf("After sort....\n");

for ( i =0; i < 12; i++) {

printf("%f ",dat[i]);

}

printf("\n");

}

/********* SHELL_Sort function starts here ********************/

void Shell_sort(double *item, int ndata,int ascending)

{

/* Function Description : Sort the numbers in array using Quick Sort.

User's difine Constant: none

Input : item a poiter point to numbers which are stored in memmory.

The first number begin at item[0] (not

item[1]) and the last number is in item[n-1].

Page 339: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

332

ndata the number of data.

ascending in ascending order = 1

in decending order = 0

Calling Function : none

Output : The sorted numbers are stored in item[].

Return Value : none

*/

float d;

int i,j,k,temp;

d = log((float)ndata)/log(2.0);

k = (int)pow(2.0,d) -1;

while ( k > 0) {

for ( i = 0; i <= (ndata-k-1); i++) {

for (j = i; j >=0; j -= k) {

switch(ascending) {

case 0 : { /* decending case */

if (*(item+j) < *(item+j+k)) {

temp = *(item+j);

*(item+j) = *(item+j+k);

*(item+j+k) = temp;

}

break;

} /* case 0 */

case 1 : { if (*(item+j) > *(item+j+k) ) {

temp = *(item+j); *(item+j) = *(item+j+k);

*(item+j+k) = temp;

}

break; } /* case 1 */

} /* switch */

}

}

k = k/2; } /* end while */

}

/********* End of Shell_Sort function ********************/

ทดลองเปรยบเทยบเวลาการทางานของฟงกชนเชลล ซอรต และควก ซอรต โดยใช

นาฬกาของระบบคอมพวเตอรเปนตวจบเวลา เวลาทวดไดจะวดไดละเอยดถง 1/100 วนาท

Page 340: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

333

ฟงกชนทใชจบเวลา และวดเวลาทโปรแกรมทางานคอ get_system_time และ time_diff ในเทอร

โบซมฟงกชนสาหรบจบเวลาใหมาเชนกน แตจะวดไดละเอยดเปนวนาทเทานน

หลกการนาเวลาของระบบมาใชงานคอเรยกใชบรการอนเตอรรพทหมายเลข 21 h

(เลขฐานสบหก) ฟงกชน 2ch จะไดเวลามาเกบไวในรจสเตอร DX และ CX นาเวลาในรจนเตอร

มาใชโปรแกรมโดยเกบไวในตวแปรแบบโครงสราง (structure) ชอ system_time นามาเวลาทวด

ไดกอนโปรแกรมทางาน และหลงโปรแกรมทางานมาเปรยบเทยบกน ผลตางทไดจากการคานวณ

ของฟงกชน time_diff คอเวลาทโปรแกรมนนใชทางาน

รายละเอยดของฟงกชน get_system_time และ time_diff ดไดจากโปรแกรม

Test_sort.C จากการเปรยบเทยบการเรยงลาดบของเชลล ซอรต และควก ซอรต โดยอาศย

ขอมลทไดจากการสมตวเลขของฟงกชน random_num เมอใหจานวนขอมลตางกนเรยงลาดบ

จากนอยไปมาก เวลาทใชในการเรยงลาดบวดไดดงน

n

(ชด)

Shell sort

(วนาท)

Quick sort

(วนาท)

500 0.17 0.05

1000 0.77 0.06

1500 1.93 0.05

2000 3.46 0.05

2500 5.55 0.06

3000 7.97 0.05

3500 9.06 0.05

4000 11.97 0.06

4500 15.21 0.11

5000 18.84 0.11

5500 22.90 0.11

6000 27.35 0.11

6500 32.19 0.11

7000 37.46 0.11

Page 341: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

334

รายละเอยดของโปรแกรมทใชในการทดสอบ

/*

* Program 8.3 Sort_Test.C

* Purpose: Speed Comparison of sort.

* Author : Wachara Rodsumrid.

* Office : Dept of Physics. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Date : 29 May 96

**************************************************************/

#include <stdio.h>

#include <dos.h>

#define N 8000

struct system_time {

unsigned char h; /* hour */

unsigned char m;

unsigned char s;

unsigned char hs; /* hundred of secdonds */

};

void quick_sort(float item[], long left,long right,int ascending);

void Shell_sort(float item[], long ndata,int ascending);

float random_num(void);

void get_system_time( struct system_time *mytime);

void time_diff( struct system_time *t_on, struct system_time *t_off,\

struct system_time *t_diff);

void main()

{

long i,j;

float dat1[N],dat[N];

struct system_time t1,t2,t_diff;

long n = 7500;

clrscr();

for (i = 0 ; i < n; i ++) {

dat[i] = random_num()*100;

Page 342: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

335

dat1[i] = dat[i];

}

get_system_time(&t1);

printf("start at %2d:%02d:%02d.%02d\n",t1.h,t1.m,t1.s,t1.hs);

Shell_sort(dat,n,1);

get_system_time(&t2);

printf("stop Shell sort at %2d:%02d:%02d.%02d\n",t2.h,t2.m,t2.s,t2.hs);

time_diff(&t1,&t2,&t_diff);

printf("Time difference = %2d:%02d:%02d.%02d\n",t_diff.h,t_diff.m,\

t_diff.s,t_diff.hs);

get_system_time(&t1);

printf("start at %2d:%02d:%02d.%02d\n",t1.h,t1.m,t1.s,t1.hs);

quick_sort(dat1,0,n-1, 1); /* ascending sort */

get_system_time(&t2);

printf("stop quick sort at %2d:%02d:%02d.%02d\n",t2.h,t2.m,t2.s,t2.hs);

time_diff(&t1,&t2,&t_diff);

printf("Time difference = %2d:%02d:%02d.%02d\n",t_diff.h,t_diff.m,\

t_diff.s,t_diff.hs);

}

float random_num( )

{

/* random number between 0 to 1 */

static long int a = 1;

a = ( a*32719+3)%32749;

return (float) a/32749;

}

union REGS regs;

void get_system_time(struct system_time *ti)

{

regs.x.ax = 0x2c00; /* get time interrupt */

int86(0x21, &regs, &regs);

ti->h = regs.h.ch; /* hour */

ti->m = regs.h.cl; /* min */

ti->s = regs.h.dh; /* second */

ti->hs = regs.h.dl; /* hundreds of second */

Page 343: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

336

}

void time_diff( struct system_time *t_on, struct system_time *t_off,\

struct system_time *t_diff)

{

struct system_time *temp;

if (t_off->h < t_on->h) {

temp = t_off;

t_off = t_on;

t_on = temp;

}

if ( t_off->hs < t_on->hs ) {

if (t_off->s == 0) {

t_off->m--;

t_off->s = 60;

t_off->s--;

t_diff->hs = t_off->hs +100 - t_on->hs;

} else {

t_off->s--;

t_diff->hs = t_off->hs +100 - t_on->hs;

}

} else{ t_diff->hs = t_off->hs - t_on->hs; }

if ( t_off->s < t_on->s ) {

if (t_off->m == 0) {

t_off->h--;

t_off->m = 59;

t_diff->s = t_off->s+60 - t_on->s;

} else {

t_off->m--;

t_diff->s = t_off->s +60 - t_on->s;

}

} else{ t_diff->s = t_off->s - t_on->s; }

if ( t_off->m < t_on->m ) {

t_off->h--;

t_diff->m = t_off->m +60 - t_on->m;

} else{ t_diff->m = t_off->m - t_on->m; }

Page 344: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

337

t_diff->h = t_off->h - t_on->h;

}

/* DON’T FORGET TO INSERT FUNCTION ‘QUICK SORT’ & ‘SHELL SORT’ IN HERE. */

/****** end of program ***********/

ขอมลทไดมาจากการสมตวอยางจานวนขอมล n ชด การวดเวลาการทางานอาจจะได

แตกตางจากตาราง ทงน เพราะขอมลทไดจากการสมแตละครงจะตางกน แตขอมลทใชในการ

เรยงลาดบครงหนง ๆ ของวธเชลล ซอรตและควก ซอรต จะเปนขอมลชดเดยวกน เวลาทวดได

อาจแตกตางกนไปขนอยกบชนดของคอมพวเตอรทใช จากตารางนใชคอมพวเตอรทมหนวย

ประมวลผลกลางหมายเลข 80486 DX ทางานทความถ 100 MHz เมอใชเครองคอมพวเตอรทม

ความสามารถในการทางานตาหรอสงกวานจะไดความเรวในการเรยงลาดบชาหรอเรวกวาคาทได

ในตารางน

จากตารางจะเหนวาขนตอนวธการเรยงลาดบโดยวธควก ซอรต จะเรวกวาวธเชลล ซอรต

ทก ๆ กรณ ถาจานวนขอมลมากขนวธเชลล ซอรตจะใชเวลามากขนตามจานวนของขอมล การ

เรยงลาดบแบบควก ซอรตจะใชเวลาคงททจานวนขอมลอยในชวงหนง ๆ เชน ใชเวลาเพยง 0.5-

0.6 วนาท เมอขอมลนอยกวา 5,000 ชด ถาขอมล 5,000 ถง 7,000 ชด จะใชเวลา 0.11 วนาท

การทดสอบความเรวในการเรยงลาดบในทนใชตวแปรแบบอะเรยเกบจานวนจรงท

เหมอนกน 2 ชด โดยเกบแบบ float (ไมใช double) เพราะจะเปลองหนวยความจานอยกวาและ

เกบไดไมเกน 7,000 ชด สาหรบการคอมไพลแบบ small ถาตองการเกบขอมลทมจานวน

มากกวานควรมการตรวจสอบและจองเนอทหนวยความจาเสยกอน อาจเปลยนไปใชการคอมไพล

แบบ mediam หรอ large ถาปรมาณขอมลมคามากกวา 64 กโลไบต

Page 345: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

338

8.2 การหาความถ, คาเฉลย และความเบยงเบนมาตรฐานของขอมล จะยกตวอยางการหาความถ, คาเฉลย และความเบยงเบนมาตรฐานของขอมลทไดจาก

การวดเสนผาศนยกลางของลกปนทผลตจากเครองจกร จานวน 110 ลก วดไดละเอยดถงทศนยม

ตาแหนงท 3 ดงน

* Ball bearing measurment.

3.510 3.515 3.519 3.517 3.517 3.518 3.522 3.521 3.520 3.524

3.523 3.522 3.522 3.519 3.526 3.521 3.526 3.522 3.523 3.520

3.522 3.509 3.524 3.525 3.510 3.515 3.521 3.522 3.519 3.516

3.521 3.522 3.519 3.520 3.522 3.518 3.519 3.519 3.521 3.515

3.516 3.518 3.521 3.521 3.519 3.517 3.523 3.525 3.522 3.522

3.521 3.520 3.516 3.522 3.521 3.525 3.520 3.521 3.520 3.524

3.523 3.520 3.519 3.525 3.525 3.527 3.528 3.519 3.525 3.520

3.517 3.516 3.518 3.520 3.520 3.516 3.521 3.520 3.519 3.521

3.517 3.523 3.524 3.517 3.518 3.518 3.520 3.520 3.521 3.524

3.520 3.523 3.519 3.518 3.517 3.517 3.524 3.523 3.519 3.518

3.523 3.524 3.523 3.524 3.519 3.518 3.519 3.518 3.520 3.520

รปท 8.1 แสดงขอมลของลกปนทวดได

โปรแกรมทจะใชในการคานวณหาคาสถตเหลานคอ stat.C นาขอมลเหลานเกบลงใน

แผนดสก โดยใชโปรแกรมประมวลคา อาจเปนเวรดจฬา เวรดราชวถ หรอ editor ของเทอรโบซ

กได ขอมลเหลานจะถกเกบในรปของตวอกษร ตงชอแฟมขอมลนคอ ball.dat

การพมพขอมลใหเวนชองวางระหวางขอมลแตละคาหรอคนดวยแทป (tab) จะตองไมม

ตวอกษรปนอยกบตวเลข เมอจะขนบรรทดใหมใหกดปนเอนเทอร (enter) ตองการจะเขยน

หมายเหตหรอขอสงเกตใด ๆ ทาไดโดยพมพเครองหมายดอกจน (*) ไวทหนาบรรทดนน

ฟงกชน get_data_from_file จะเรยกขอมลจากแฟมขอมลชอ ball.dat แปลงตวอกษร

ใหเปนเลขจานวนจรงแลวจดเกบไวในตวแปร item[ ] ในขณะเดยวกนกจะนบจานวนขอมลทอาน

ไดจากแฟมขอมล และสงคานกลบมายงโปรแกรมหลก ถาพบวาขอมลมขอผดพลาดซงเกดจาก

การพมพผด เชน 3.2a3 หรอ 3.2.3 จะสงคา -1 ถาไมสามารถเปดแฟมขอมล ball.dat ได จะสง

คา -2 มายงโปรแกรมหลก

การหาคาเฉลยและความเบยงเบนมาตรฐานจะใชฟงกชน mean_deviation ชวย

คานวณคาเฉลยเลขคณตของขอมลไดจาก

mean = xii 1

n

n=∑

.................... (8.1)

เมอ n คอจานวนขอมลทงหมด

Page 346: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

339

xi คอขอมลตวท i เมอ i = 1, 2, ..... n

ความเบยงเบนมาตรฐานของขอมล (standard deviation) ชดน คานวณไดจาก

Sd = (x mean)i 1

n

ni

2−=∑

.................... (8.2)

ฟงกชนนจะตรวจสอบวา n = 0 หรอไม ถาพบวา n = 0 จะสงคา (-1) เพอแสดง

ขอความผดพลาด การหาความถของขอมลแตละคาจะตองนาขอมลเหลานไปเรยงลาดบเสยกอน

ในทนใชการเรยงลาดบจากคามากไปสคานอย โดยใชวธ quick sort เมอเรยงลาดบแลวสงขอมล

เหลานใหฟงกชน find_frequency ทางาน ฟงกชนนจะหาความถของขอมลแตละคา แลวจดกลม

นาขอมลทมคาเดยวกนมาแสดงเพยงครงเดยว เกบความถของขอมลไวในตวแปร Frequency [ ]

ฟงกชนนจะสงคากลบเปนจานวนขอมลทถกจดความถเรยบรอยแลว เมอคอมไพลโปรแกรม

stat.C แลว ใหโปรแกรมทางานจะไดผลลพธดงรป 8.2

Calculate MEAN, STARD DEVIATION and FREQUENCY of data

Mean = 3.520245 , standard deviation = 0.003298

Number of data = 110

3.528 1

3.527 1

3.526 2

3.525 6

3.524 8

3.523 9

3.522 11

3.521 13

3.520 16

3.519 14

3.518 10

3.517 8

3.516 5

3.515 3

3.510 2

3.509 1

รป 8.2 ผลลพธทไดจากโปรแกรม stat.C

Page 347: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

340

การนาฟงกชน mean_deviation ไปใชงาน

ก. คาคงททตองนยาม -

ข. การผานคาอนพทและการเรยกใชฟงกชน

int mean_deviation (int n, double item [ ] double*mean, double*sd.)

n คอ จานวนขอมล

item [ ] คอ ตวแปรสาหรบเกบขอมลทเปนจานวนจรง

Frequency [ ] คอ ตวแปรเกบความถทนบได

manageditan [ ] คอ ตวแปรเกบขอมลแตละคาหลงจากถกหาความถแลว

ค. ฟงกชนทเกยวของ

ง. การสงคากลบ จะสงจานวนขอมลหลงจากถกจดกลมเมอนบความถแลว

รายละเอยดของโปรแกรม stat.C มดงน

/* Program 8.4 Stat.C

* Purpose: Find the frquency,mean and standard deviation of data.

* Author : Wachara R.

* Office : Dept of Science. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Last update : 1 June 96

**************************************************************/

#include <stdio.h>

#include <math.h>

int get_data_from_file(char *filename,double dat[],int *err_line);

int find_frequency(int number,double item[],\

int Frequency[],double Manageitem[]);

void quick_sort(double item[], int left,int right,int ascending);

int mean_deviation(int n_item, double item[],double*mean,double*sd);

int main()

{

char filename[8]="ball.dat";

double item[500],f_item[500];

int i,num_data;

int error;

Page 348: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

341

int freq[500];

int nf; /* number of interval of frequency */

double mean,sd; /* mean and standard deviation */

clrscr();

num_data = get_data_from_file(filename,item,&error);

if (num_data == -1) {

printf("There is some error(s) in line %d\n",error);

exit(1);

}

if (num_data == -2) {

printf("Cannot open %s\n",filename);

exit(1);

}

error = mean_deviation(num_data,item,&mean,&sd);

quick_sort(item, 0,num_data-1,0); /* decending sort */

nf = find_frequency( num_data,item,freq,f_item);

printf("\n\tCalculate MEAN, STARD DEVIATION and FREQUENCY of data\n");

if (error == 0 )

printf("\n\t Mean = %f , standard deviation = %f\n",mean,sd);

else {

printf ("\n Error : number of data = 0\n");

exit(1);

}

printf("\t\tNumber of data = %d\n ",num_data);

for ( i = 0; i < nf;i++) {

printf("\t%4.3f %d \n ",f_item[i],freq[i]);

}

return(0);

}

int get_data_from_file(char *filename,double dat[],int* err_line)

{

/* Function Description : get data (real number) from specified file.

User's define Constant: none

Page 349: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

342

Input : *filename -- pointer which point to filename.

data[] -- an array which real numbers are stored in.

The first number begin at item[0] (not

item[1]) and the last number is in item[n-1].

*err_line -- pointer to line number that error happened.

Calling Function : none

Return Value : the number of data -- if everything's ok.

-1 -- there is some error in data.

-2 -- cannot open file.

*/

FILE *fp;

int line = 1;

char ch,temp[20]= "";

int point=0, n=0,i=0, IN_DIGIT =0, IN_COMMENT = 0;

int ERR_FLAG = 0;

double t;

if ((fp = fopen( filename,"r") ) == NULL) {

/* printf("Cannot open %s\n",*filename); */

return(-2);

}

while ( (ch = fgetc(fp)) != EOF && !ERR_FLAG) {

if (ch == '*' ){

IN_COMMENT = 1;

}

if (ch == '\n') {

line++;

IN_COMMENT = 0;

}

if (isalpha(ch) && !IN_COMMENT) {

ERR_FLAG = 1;

*err_line = line;

}

if (isdigit(ch)|| ch == '.' && !IN_COMMENT) {

Page 350: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

343

IN_DIGIT = 1;

if ( ch == '.')

point = point+1;

temp[i] = ch;

i = i +1;

if (point > 1 ) {

ERR_FLAG =1;

*err_line = line;

}

}

if (isspace(ch) && IN_DIGIT && !IN_COMMENT) {

IN_DIGIT = 0;

point = 0;

i = 0;

dat[n] = atof(temp);

n++;

}

}

fclose(fp);

if (ERR_FLAG) return -1 ;else return(n);

}

void quick_sort(double item[], int left,int right,int ascending)

{

int i,j;

double comparand,temp;

i = left; j = right;

comparand = item[(left+right)/2];

do { if (ascending) {

while(item[i] < comparand && i < right) i++;

while (comparand < item[j] && j > left) j--;

} else {

while(item[i] > comparand && i < right) i++;

while (comparand > item[j] && j > left) j--;

}

if ( i <= j) {

temp = item[i];

Page 351: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

344

item[i] = item[j];

item[j] = temp;

i++; j--;

}

} while (i <=j);

if (left <j ) quick_sort(item,left,j,ascending);

if (i < right) quick_sort(item,i,right,ascending);

}

/********* End of Quick_Sort function ********************/

int find_frequency(int number,double item[],\

int Frequency[],double Manageitem[])

/* Function Description : Collect frequency of each value.

User's difine Constant: none

Input : number -- number of data.

item[] an array which numbers are stored in.

The first number begin at item[0] (not

item[1]) and the last number is in item[n-1].

Frequency[] an array that keeps the frequecy of

each value of data.

Manageditem[] an array which classified data are kept.

Calling Function : none

Output : Frequency of each value stored in Frequency[]

Return Value : number of classified data.

Remark : Lookout ! The data in item[] must be sorted

before using this function */

{ int n_freq = 0;

int i,j;

for (i = 0; i < number ; i++) {

if (item[i] == -1 ) continue;

Frequency[n_freq] = 1;

Manageitem[n_freq] = item[i];

for (j = i ; item[j+1] == item[i]; j++) {

Frequency[n_freq] +=1;

item[j+1] = -1;

}

n_freq += 1;

Page 352: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

345

}

return(n_freq);

}

int mean_deviation(int n_item, double item[],double *average,double* deviation)

{

/* Function Description : Calculate arithmatic mean and standard deviation.

User's difine Constant: none

Input : n_itemd -- number of data.

item[] an array which numbers are stored in.

The first number begin at item[0] (not

item[1]) and the last number is in item[n-1].

*average -- mean of data.

*deviation -- standard deviation.

Calling Function : none

Output : mean and standard deviation are stored in 'mean' and 'deviation'.

Return Value : 0 -- No error.

1 -- number of data = 0

*/

int i;

double total;

if (n_item == 0 ) return 1;

total = 0;

for ( i =0; i< n_item; i++)

total = total+ item[i];

*average = total/ n_item;

total = 0;

for (i = 0; i < n_item; i++ )

total = total + (item[i] - *average)*(item[i]-*average);

*deviation = sqrt(total/n_item);

return(0);

}

Page 353: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

346

8.3 การกระจายแบบโคงปกต (Normal Distribution or Gausian Distribution)

เมอวดความสงหรอนาหนกของคนโดยสมจากกลมคนจานวนมาก ๆ การกระจายของ

ความสงและนาหนกจะมลกษณะเปนรประฆงควาหรอโคงปกต ชนสวนเครองจกรทถกออกแบบ

ใหมขนาดคงทคาหนง เมอผลตจากเครองจกรพบวาเกดความคลาดเคลอนไปจากทแบบทออกไว

ความคลาดเคลอนขนาดชนสวนเมอวดแบบสมจะมลกษณะการกระจายเปนแบบโคงปกต เชนกน

ลกษณะของโคงปกต จะมลกษณะดงรป 8.3

รป 8.3 รปโคงปกต

เมอสมตวอยางจากประชากรใด ๆ ซงมคาเฉลยเปน µ และความเบยงเบนมาตรฐาน

เปน σ สามารถประมาณการกระจายไดดวยการกระจายแบบปกต โดยกลมทสมตวอยางม

ขนาดใหญ เราสามารถเขยนเปนฟงกชนทบอกถงความนาจะเปนของตวแปรสม (x) ในรปของ

Probability Density Function ไดดงน

y = 12 e

x 2

π

µσ

−⎡

⎢⎢

⎥⎥ .................... (8.3)

x จะมคาอยระหวาง -∞ และ +∞ จากรปจะเหนวาเสนโคงจะมลกษณะสมมาตรท

จด x = µ และจะลดคาอยางรวดเรวเมอ x เพมหรอลดคาไปดานซายมอหรอขวามอ

การกระจายแบบโคงปกตทมคาเฉลย µ ความแปรปรวนเปน σ2 สามารถเขยนใหอย

ในรปสน ๆ ไดดงน

x ∼ N(µ, σ) .................... (8.4)

Page 354: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

347

เมอกาหนดให z = (x-µ)/σ แลวนาไปแทนคาลงในสมการ (8.1) เพอใหอยในรป

มาตรฐาน (standard normal distribution) นนคอ คาเฉลยจะมคาเปนศนย และความแปรปรวน

มคาเทากบ 1

x ∼ N (0, 1) .................... (8.5)

สมการ (8.1) จะเปลยนรปเปน

y = 12 e z /22

π− .................... (8.6)

พนทใตเสนโคงของสมการ (8.6) จะมคาเทากบ 1 หรอความนาจะเปนของ z ในชวง

-∞ ถง ∞ มคาเปน 100% ความนาจะเปนของ z ในชวง a ถง b คอพนทใตเสนโคงซงอยระหวาง

a และ b นน และจะเหนวา y มคาเปนบวกเสมอ

การหาความนาจะเปนเมอกาหนดคา z ในชวงใด ๆ สามารถทาไดจากการเปดตาราง

คาสถต z จากหนงสอคณตศาสตรทวไป หรออาจเขยนโปรแกรมใหคอมพวเตอรหาพนทใตเสนโคง

ในชวง z1 ถง z2 ไดดงน

พนทใตเสนโคง = 12 e z /2dzz

z2

1

−∫

ความนาจะเปนของตวแปรสมทอยระหวางชวง (µ -σ, µ + σ) มคาประมาณ 68%

ความนาจะเปนระหวาง (µ - 2σ, µ + 2σ) ประมาณ 95% และอยระหวาง (µ + 3σ) ประมาณ

99.7%

โปรแกรม Area.C เปนโปรแกรมหาพนทใตเสนโคงเมอกาหนดคา z มาให ฟงกชน

Normal probability Integral ทางานโดยอาศยหลกการอนทเกรตแบบสเหลยมคางหม โดย

กาหนดความกวางของสเหลยมคางหม = 0.0001 อาจจะกาหนดความกวางใหนอยกวาน

เพอทจะไดคาพนทใตโคงใกลเคยงกบคาแทจรง แตคอมพวเตอรจะใชเวลาในการประมวลผลมาก

ขน

การนาฟงกชน mean_deviation ไปใชงาน ก. คาคงททตองนยาม -

ข. การผานคาอนพทและการเรยกใชฟงกชน

double NormalProbabilityIntegral (double low_z, double upperz)

Page 355: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

348

low_z คอ ขดจากดลางของการอนทเกรตหาพนท

upper_z คอ ขดจากดบนของการอนทเกรตหาพนท

ค. การเรยกใชฟงกชน -

ง. การสงคากลบ จะสงคาซงเปนพนทระหวาง low_z และ upper_z

รายละเอยดของโปรแกรม Area.C มดงน

/* Program 8.5 Area.C

* Purpose: Calculate the area under the normal curve.

* Author : Wachara Rodsumrid.

* Office : Dept of Physics. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Date : Apr 1987.

* Last update : 26 May 1996.

**************************************************************/

#include <stdio.h>

#include <math.h>

double NormalProbabilityIntegral ( double lower_z, double upper_z);

void main()

{

double z1, z2,area;

char buffer[100];

printf("Find the Area under Normal curve between z1 and z2.\n");

printf("The values of z should be between -6 to +6\n");

printf("input your lower z values..... "); gets(buffer); z1 = atof(buffer);

printf("input your upper z values...."); gets(buffer); z2 = atof(buffer);

area = NormalProbabilityIntegral(z1,z2);

printf("Area under normal curve between %3.2f to %3.2f = %4.4f\n",z1,z2,area);

}

double NormalProbabilityIntegral( double lower_z, double upper_z)

{/* Function Description: Compute the area between 2 statistic z values.

User's Define Variable : None

Input : lower_z -- lower limit.

upper_upper -- upper limit.

Return : area between z's.

Remark : The z values should line between -6 to +6.

Page 356: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

349

************************************************************************/

double area,h,x,areaAtEnd,result;

int i;

if (upper_z - lower_z < 0 ) { x = upper_z; upper_z = lower_z;}

h = 0.0001; x = lower_z; area = 0;

while (x < upper_z) {

x = x+h; area = area + exp(-(x*x)/2)/(sqrt(2*M_PI));

}

areaAtEnd = 1/(sqrt(2*M_PI))* (exp(-(lower_z*lower_z)/2)+

exp(-(upper_z*upper_z)/2));

result = h*(areaAtEnd + 2* area)/2;

return result;

}

ฟงกชน NomalProbabilityIntegral สามารถนาไปสรางตารางคาสถต z ดงทปรากฎอย

ในหนงสอคณตศาสตรทวไปได โดยเปลยนคาสงบางคาสงใน main เสยใหม โปรแกรม

Z_table.C จะหาคาความนาจะเปนเมอ z = 0 ถง z = 2 อาจจะขยายใหมากกวานกได แตในทน

ตองการแสดงผลลพธใหปรากฎบนหนาจอเดยว พนทใตโคงกรณทคา z นอยกวาศนย สามารถใช

คณลกษณะความเปนสมมาตร หาไดเพยงแตทราบคา z ทมคามากกวาศนยขนไปเทานน

สวนทเปน main โปรแกรมของ Z_table.C มดงน

/*

* Program 8.6 Z_table.C

* Purpose: Calculate the area under the normal curve at various z.

* Author : Wachara Rodsumrid.

* Office : Dept of Physics. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Date : Apr 1987.

* Last update : 26 May 96

**************************************************************/

#include <stdio.h>

#include <math.h>

double NormalProbabilityIntegral ( double lower_z, double upper_z);

void main()

{

Page 357: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

350

double z,area, step;

/* double da,old_z, old_area; */

int i;

step = 0.01;

clrscr();

printf("\n\t Find the Area under Normal curve between 0 to 1.99 step 0.01.\n\n");

printf(" 0 1 2 3 4 5 6 7\

8 9");

i = 0;

area = 0;

for( z = 0; z<= 2; z = z+step) {

if ( i % 10 ==0)

{ printf("\n%2.1f ",z); i =0; }

i +=1;

area = NormalProbabilityIntegral(0,z);

printf(" %4.4f",area);

}

/**** The algorithm below here is very quick but there is some accumulated

error in it. Wachara R.

for( z = 0; z<= 2; z = z+step) {

if ( i % 10 ==0)

{ printf("\n%2.1f ",z); i =0; }

i +=1;

da = NormalProbabilityIntegral(old_z,z);

area += da;

printf(" %4.4f",area);

old_z = z;

}

*/

}

Page 358: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

351

รายละเอยดของโปรแกรม 8.6 แสดงเฉพาะสวนทเปน main ของโปรแกรมเทานน ตอง

แทรกฟงกชน NormalProbabilityIntegral ตรงสวนทายของโปรแกรมดวย ตารางคาสถต z ทได

จากโปรแกรม Z_table.C จะเปนดงน

Find the Area under Normal curve between 0 to 1.99 step 0.01.

0 1 2 3 4 5 6 7 8 9

0.0 0.0000 0.0041 0.0081 0.0120 0.0160 0.0200 0.0240 0.0279 0.0319 0.0359

0.1 0.0399 0.0438 0.0478 0.0518 0.0557 0.0597 0.0636 0.0676 0.0715 0.0754

0.2 0.0793 0.0832 0.0871 0.0910 0.0949 0.0988 0.1026 0.1065 0.1103 0.1142

0.3 0.1180 0.1218 0.1256 0.1294 0.1331 0.1369 0.1407 0.1444 0.1481 0.1518

0.4 0.1555 0.1592 0.1628 0.1665 0.1701 0.1737 0.1773 0.1809 0.1845 0.1880

0.5 0.1915 0.1950 0.1985 0.2020 0.2055 0.2089 0.2123 0.2157 0.2191 0.2225

0.6 0.2258 0.2291 0.2324 0.2357 0.2390 0.2422 0.2454 0.2486 0.2518 0.2550

0.7 0.2581 0.2612 0.2643 0.2674 0.2704 0.2734 0.2764 0.2794 0.2824 0.2853

0.8 0.2882 0.2911 0.2939 0.2968 0.2996 0.3024 0.3052 0.3079 0.3106 0.3133

0.9 0.3160 0.3186 0.3213 0.3239 0.3264 0.3290 0.3315 0.3340 0.3365 0.3390

1.0 0.3414 0.3438 0.3462 0.3485 0.3509 0.3532 0.3555 0.3577 0.3600 0.3622

1.1 0.3644 0.3665 0.3687 0.3708 0.3729 0.3750 0.3770 0.3790 0.3810 0.3830

1.2 0.3850 0.3869 0.3888 0.3907 0.3925 0.3944 0.3962 0.3980 0.3998 0.4015

1.3 0.4032 0.4049 0.4066 0.4083 0.4099 0.4115 0.4131 0.4147 0.4162 0.4178

1.4 0.4193 0.4208 0.4222 0.4237 0.4251 0.4265 0.4279 0.4292 0.4306 0.4319

1.5 0.4332 0.4345 0.4358 0.4370 0.4382 0.4395 0.4406 0.4418 0.4430 0.4441

1.6 0.4452 0.4463 0.4474 0.4485 0.4495 0.4505 0.4516 0.4526 0.4535 0.4545

1.7 0.4555 0.4564 0.4573 0.4582 0.4591 0.4600 0.4608 0.4617 0.4625 0.4633

1.8 0.4641 0.4649 0.4656 0.4664 0.4671 0.4679 0.4686 0.4693 0.4700 0.4706

1.9 0.4713 0.4719 0.4726 0.4732 0.4738 0.4744 0.4750 0.4756 0.4762 0.4767

รป 8.4 ตารางคาสถต z ทไดจาก Z_table.C

ในทางกลบกน ถาทราบความนาจะเปนหรอพนทใตโคง ตองการหาวา z จะตองมคา

เทาใดจงจะทาใหเกดพนทใตโคงขนาดเทานน โปรแกรม Find_z.C จะชวยหาคาตอบของปญหา

น เมอกาหนดพนทใตโคงมาให โดยเรมจากดานซายมอ (Z -= -∞) จนถงตาแหนงทตองการหา z

โปรแกรมจะคานวณโดยเรมจากตรวจสอบดวาพนทใหมานนมคามากกวา 0.5 หรอไม ถามคา

มากกวา 0.5 จะนาคาพนทนนเปนตวตง นา 0.5 มาหกออก พนททเหลอจะเปนพนททเรมจาก z

= 0 ถง z ทตองการจะหาคา แตถาพนทนอยกวา 0.5 จะนาพนทไปหกออกจาก 0.5 นน ผลลพธ

จะเปนพนทตงแต z = 0 ถง z ทจะหาคาเชนกน แต z ทไดในกรณนจะเปนคาลบ การคนหาคา z

Page 359: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

352

ททาใหไดพนทเทากบคาทกาหนดทาไดโดยเพมคา z ครงละ 0.01 โดยเรมจาก z เทากบศนย

คานวณหาพนทเพมขนมาน รวมพนททเพมขนมากบพนทเดม เปรยบเทยบกบพนททกาหนดให

ถายงนอยกวาใหเพมคา z (ครงละ 0.01) ไปเรอย ๆ จนไดคาพนทเทากบพนททกาหนดให z ตรวจ

จดนคอ คา z ทตองการ

การนาฟงกชน mean_deviation ไปใชงาน ก. คาคงททตองนยาม -

ข. การผานคาอนพทและการเรยกใชฟงกชน -

double Find_z (double area)

area คอ พนทใตเสนโคงปกตตงแตศนย (ดานซายมอ) จนถงตาแหนง z

ค. การเรยกใชฟงกชนอน -

ง. การสงคากลบ ฟงกชนนจะสงผลลพธซงเปนคา z

พนทตงแต z = 0 จนถง z ทกาหนดใหนจะมคาเทากบคาพนทในตวแปร

area ฟงกชนนจะสงคา (-99) ถาพนททกาหนดใหมคามากกวา 1

หรอนอยกวาศนย

จ. ขอควรระวง การผานคา area ใหฟงกชน Find_z ทางาน จะตองมคาตงแตศนย

และไมเกน 1

รายละเอยดของโปรแกรม Find_z.C มดงน

/* Program 8.7 Find_z.C

* Purpose: Calculate the the statistic z corresponding to specific area.

* Author : Wachara Rodsumrid.

* Office : Dept of Physics. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Date : May 1987.

* Last update : 26 May 1996.

**************************************************************/

#include <stdio.h>

#include <math.h>

double Find_z( double );

void main()

{

Page 360: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

353

double area,z;

char buffer[100];

printf("\nFind z that corresponding to the area...\n");

printf("\nInput your area (from 0 to 1) = ");

gets(buffer); area = atof(buffer);

z = Find_z(area);

if ( z != -99)

printf(" z = %3.2f corresponding to area = %4.4f\n",z,area);

else

printf(" Invalid area !!!\n");

getch();

}

double Find_z( double area)

{/* Function Description: Finding z value at known area under normal curve.

User's Define Variable : None

Input : area -- area under normal cuvre

Return : statistic z value.

-99 -- if area >1 or < 0

Remark : The area should be between 0 to 1.

*************************************************************************/

int i,flag,lowerlimit;

double new_area,da,z,sum;

if ( area < 0 || area > 1 ) return -99;

flag = 0;

if (area > 0.5) {

new_area = area - 0.5;

flag = 1;

}

else {

new_area = 0.5 - area;

}

sum = 0.0; lowerlimit = 0;

if (new_area >= 0.3412944) {

lowerlimit = 1; sum = 0.3412944;

}

Page 361: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

354

if (new_area >= 0.4771599) {

lowerlimit = 2; sum = 0.4771599;

}

if (new_area >= 0.4986253) {

lowerlimit = 3; sum = 0.4986253;

}

/* Integrate by Trapezoidal Rule */

z = lowerlimit;

while (new_area - sum > 0.001) {

da = (exp(-0.5*z*z)+exp(-0.5*(z+0.01)*(z+0.01)))*1.994712e-03;

sum = sum + da;

z += 0.01;

}

if (flag ==1)

return(z);

else

return(-z);

}

ตวอยาง 8.1 การผลตแทงโลหะซงมเสนผาศนยกลาง 10 มม. มความเบยงเบนมาตรฐาน 0.05

มม. สมตวอยางวดเสนผาศนยกลางพบวามลกษณะการกระจายแบบโคงปกต

ก. จงหาความนาจะเปนทจะพบแทงโลหะทมเสนผาศนยกลาง 10 มม. ถง 10.08

มม.

ข. ความนาจะเปนทจะพบแทงโลหะทมเสนผาศนยกลาง 9.92 มม. ถง 10 มม.

ค. ความนาจะเปนทจะพบแทงโลหะทมเสนผาศนยกลาง 10.02 มม. ถง 10.10 มม.

ง. ถาแทงโลหะทมเสนผาศนยกลางนอยกวา 9.90 มม. และมากกวา 10.10 มม. ตอง

ถกคดทง จานวนแทงโลหะทมโอกาสถกคดทงมก %

จ. ถากาหนดคาเสนผาศนยกลางไวคาหนง พบวา 30% ของแทงโลหะมคาตากวา

คาทกาหนดไว จงหาคาทกาหนดใหน

วธทา เสนผาศนยกลางของแทงโลหะเฉลยเทากบ 10 มม. นนคอ z = 0 ทจดน

ก. เสนผาศนยกลาง 10.06 มม. คดเปนคา z คอ

z = 10.06 10

0.05−

= 1.2

Page 362: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

355

ใชโปรแกรม Area.C หาพนทตงแต z = 0 ถง z = 1.2 จะไดความนาจะปน = 0.3850 หรอโอกาส

ทจะพบแทงโลหะทมเสนผาศนยกลาง 10 ถง 10.06 มม. มคา 38.50% หรอ 10.06 มม.

รป 8.5 แสดงพนท z = 0 ถง z = 1.2 มความเบยงเบนมาตรฐานจากคาเฉลยเทากบ 1.2

ข. ขนาดเสนผาศนยกลาง 9.92 มม. คดเปนคา z = (9.92-10)/0.05 = -1.6

ใชโปรแกรม Area.C หาพนทใตเสนโคงตงแต z = -1.6 ถง z = 0 จะไดเทากบ 0.4453 หรอ

44.52% คอความนาจะเปนทพบแทงโลหะทมเสนผาศนยกลางตงแต 9.92 ถง 10 มม.

รป 8.6 พนทใตเสนโคงปกต ตงแต z =-1.6 ถง 0

ค. แปลงเสนผาศนยกลางใหอยในรปของคา z

ขนาด 10.02 มม. คา z = (10.02-10)/0.05 = 0.4

ขนาด 10.10 มม. คา z = (10.10-10)/0.05 = 2

ใชโปรแกรม Area.C จะไดความนาจะเปนทจะพบแทงโลหะซงมเสนผาศนยกลาง

ระหวาง 10.02 มม. ถง 10.10 มม. คอ 0.3218 หรอ 32.18%

ง. เสนผาศนยกลาง 9.90 ตรงกบคา z = (9.90-10)/0.05 = -2

เสนผาศนยกลาง 10.10 ตรงกบคา z = (10.10-10)/0.05 = +2

ความนาจะเปนจะเปนทพบแทงโลหะในชวงดงกลาว หาไดจากโปรแกรม Area.C

คอ 0.9545

จานวนแทงโลหะทมโอกาสถกคดทงคอ 1-0.9545 หรอ 4.55%

Page 363: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

356

จ. เมอกาหนดคาเสนผาศนยกลางใหคาหนง พบวามแทงโลหะ 30% หรอ 0.30 มคา

นอยกวาคาน

ใชโปรแกรม Find_z.C หาคา z ททาใหเกดพนทใตเสนโคง = 0.3 พบวา z = -0.53 คานวณหา

เสนผาศนยกลาง

x = µ - 0.53σ

= 10 - 0.53 × 0.05

รป 8.7 แสดงพนทนอยกวาคา z = 9.97 มม.ทกาหนดให

การคานวณในตวอยางนใชโปรแกรมคอมพวเตอรคานวณทงสน ไมตองเปดตาราง

คาสถต z ใหเสยเวลาแมแตนอย

8.4 การกาหนดระดบคะแนนดวยคะแนน T ปกต ถานาฟงกชนทกลาวมาแลวในหวขอกอน ๆ ไดแกฟงกชนทใชหาความถ คาเฉลยของ

ขอมล ฟงกชนหาคาสถต z ของขอมล แลวเพมเตมฟงกชนการหาความถสะสม และคานวณ

คะแนน T กจะสามารถสรางโปรแกรมทใชหาระดบคะแนนหรอโปรแกรมตดเกรดได

วธการตดเกรดดวยคะแนน ทปกต โดยใชโปรแกรม grade.exe มขนตอนดงน

1. นาคะแนนรวมของนกศกษาแตละคน มาปอนเขาสคอมพวเตอร โดยใช

โปรแกรมประเภทประมวลผลคา เชนเวรดจฬา ฯ เวรดราชวถ โปรแกรม edit ทตดมากบ DOS

หลกเกณฑในการพมพคะแนนมดงน

- การพมพคะแนนนกศกษาแตละคน ใหเวนดวยชองวาง บรรทดหนงจะพมพกคาก

ได เมอจบบรรทดใหกดปม Enter ปดทายเสมอ

- คะแนนตองเปนจานวนเตม ไมมเครองหมายบวก ลบ จลภาค หรอทศนยม

- จานวนนกศกษาตองไมเกน 1,000 คน

- สามารถเขยน comment ไดโดยพมพ * ทคอลมนแรกของบรรทดนน ๆ

Page 364: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

357

ตวอยางนเปนการนาคะแนนนกศกษาจานวน 38 คน พมพโดยใชเวรดจฬาฯ

* Total Score

* Subject: Physics II

* Group Plastic Engineering

* Symester 2/35

50 55 53 52 50 74 47 55 56 49 46 62 46 58 51 50 44 55

56 44 58 56 50 54 42 46 63 48 58 64 52 61 70 51 72 73 44 58

- บนทกแฟมขอมลลงในดสก จากตวอยาง ชอแฟมขอมลทเกบคอ Physics2

2. เปดเครองพมพ ใสกระดาษแบบตอเนองใหเรยบรอย เรยกใชโปรแกรมตดเกรด

โดยใชคาสงตอไปน

grade <drive:><filename>

ตวอยาง เชน

A>grade b:physic2 (กดปม Enter)

โปรแกรมจะทางานโดยมขอความปรากฎทหนาจอดงน

Normalized T-Score Calculation Version 1.5

Dept of Science

Rajamangala Institute of Technology

I am reading your file, physics2

Sorting......

Calculating....

Output to (S)creen, (P)rinter or (Q)uit ?

(กด S ถาตองการแสดงผลบนจอภาพ กด Q ถาตองการพมพบนกระดาษ )

ในทนกด P โปรแกรมจะนาผลการคานวณ พมพออกทางเครองพมพดงรป

NORMALIZED T-SCORE CALCULATION

Dept of Science, Rajamangala Institute of Technology.

Data from file : physics2 Date of printing: Mon Mar 29 20:50:27 1993

Average Score = 54.55

Page 365: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

358

Score Freq Cumulate Freq Percentile Normal-T Grade

========================================================

74 1 38 98.68 72.60 A

73 1 37 96.05 68.60 A

72 1 36 93.42 65.60 A

70 1 35 90.79 63.60 A

64 1 34 88.16 62.00 B

63 1 33 85.53 60.70 B

62 1 32 82.89 59.80 B

61 1 31 80.26 58.80 B

58 4 30 73.68 56.50 B

56 3 26 64.47 53.80 C

55 3 23 56.58 51.70 C

54 1 20 51.32 50.40 C

53 1 19 48.68 49.60 C

52 2 18 44.74 48.60 C

51 2 16 39.47 47.30 C

50 4 14 31.58 45.10 D

49 1 10 25.00 43.10 D

48 1 9 22.37 42.20 D

47 1 8 19.74 41.20 D

46 3 7 14.47 39.30 D

44 3 4 6.58 34.40 F

42 1 1 1.32 27.40 F

เมอพมพเสรจจะปรากฎขอความทหนาจอ วา

Output to (S)creen, (P)rinter or (Q)uit ?

ถาตองการพมพขอมลชดเดมซาอกใหกด P ถากด Q โปรแกรมจะสนสดการทางาน

ออกมาสดอส

หลกการทางานของโปรแกรมคอจะอานขอมลซงเปนคะแนนจากแฟมขอมลจากแผนดสก

เขาสหนวยความจา เกบไวในตวแปร RawScore เรยงลาดบคะแนนจากมากไปนอยโดยใชวธควก

ซอรต หาความถของคะแนนแตละคา จากนนหาความถสะสมและพนทใตโคงปกตทคะแนน�

นนอย โดยใชฟงกชน find_cumulate_frequency การหาพนทใตโคงของคะแนนใด ๆ หาไดจาก

Page 366: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

359

พนทใตโคง = ความถสะสมของคะแนนชนทอยตากวา 1 ชน + 0.5ของความถคะแนนในชนนน

จานวนนกศกษาทงหมด

พนทใตโคงจะบอกตาแหนงของผทไดคะแนนนนวาอยเหนอกวาผอนอยเทาใด เปนการบอก

เปอรเซนไทลนนเอง

นาพนทใตโคงไปคานวณหาคาสถต z โดยใชฟงกชน evoluate_Tscore ในฟงกชนนมการ

เรยกใชฟงกชน find_z นาคาสถต z ทไดไปคานวณหาคะแนน T จากสตร

คะแนน T = คะแนน z * 10 + 50

เมอไดคะแนน ท ของนกศกษาครบทกคนแลว ขนตอไปคอกาหนดระดบคะแนน โดยใฟงก

ชนassign_grade แบงระดบคะแนนออกเปน 5 ระดบ คอ A B C D และ F แตละระดบจะมชวง

หางของคะแนนทชวงละเทา ๆ กน ชวงของคะแนนทแตละชวงหาไดจาก นาคะแนนทคาสงสดลบ

ดวยคะแนนทตาสดแลวหารดวยจานวนระดบคะแนนทจะตด(ในทนคอ 5) การแบงคะแนนทแต

ละชวงไดใชคะแนนทท 50 เปนจดกงกลางของการแบงชวงดงรป

รป 8.6 แสดงชวงการแบงระดบคะแนน

ฟงกชน output_to_screen จะนาผลลพธทไดแสดงบนจอภาพ output_to_printer จะนา

ผลลพธทไดออกทางเครองพมพ จะตรวจสอบความเรยบรอยของเครองพมพโดยใชฟงกชน

print_ready ในฟงกชนนบางสวนของโปรแกรมจะเปนภาษาแอสเซมบล (Assembly ) ในการ

คอมไพลโปรแกรม grade.C จะตองมตวแปลภาษาแอสเซมบล (Assembler) อยในแผนดสกทใช

คอมไพลดวย เพราะขณะทเทอรโบ ซ คอมไพลโปรแกรมถงตรงสวนทเปนภาษาแอสเซมบล จะ

ผานตรงจดนใหตวแปลภาษาแอสเซมบลทาหนาทคอมไพลแทน ซงคอนขางจะยงยากกวา

โปรแกรมทผาน ๆ มา

Page 367: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

360

การกาหนดระดบคะแนนดวยคะแนน ทปกต มขอสงเกตดงน

1. คะแนน T ปกต เปนคะแนนทบอกตาแหนงทสอบได ไมขนอยกบคะแนนดบ

หรอคะแนนเตม ตาแหนงทไดไดมาจากการเปรยบเทยบกบพนทใตเสนโคงปกต ในการวดผล

ประเมนผลทางการศกษาเชอกนวา คะแนน T ทไดจากการทดสอบมลกษณะการแจกแจงเปนโคง

ปกตเสมอ

2. เนองจากขอสอบทใชสอบนกศกษาอาจไมเปนขอสอบมาตรฐาน อาจจะยาก

หรองายเกนไป หรอไมสามารถจาแนกคนเกง คนออนได เสนโคงการแจกแจงของคะแนนทดสอบ

จงมลกษณะไมเปนโคงปกต ดวยเหตนจงไมสามารถแปลงคะแนนดบใหเปนคะแนน z โดยตรงได

จากสตร

คะแนน z = คะแนนดบ - คาเฉลยของคะแนน

สวนเบยงเบนมารตฐานของคะแนน

การใชสตรนจะทาใหลกษณะไมปกตของการแจกแจงทงหมดถกถายทอดมายง

คะแนน z ดวย นนคอถาโคงมลกษณะเบอยางไร การแจกแจงของคะแนน z กจะมลกษณะเบ

อยางนนดวย เรยกการแปลงอยางนวาเปนการแปลงเชงเสนตรง เรยก คะแนน T (ไมมคาวาปกต)

3. โปรแกรมนจะเปลยนคะแนนดบทมการแจกแจงของคะแนนเปนโคงไมปกต

โดยการเกลาพนทใตเสนโคงของคะแนนดบใหสอดคลองกบพนทโคงปกต แลวจงเปลยนจาก

คะแนน z เปนคะแนน T คะแนน T ทไดจากการแปลงแบบนเรยกวา คะแนน T ปกต

(Normalized T-score)

4. ไดทดสอบโปรแกรมโดยกาหนดใหคะแนนของนกศกษาแตละคนมคาเทากน

(เชนมนกศกษา 30 คน แตละคนไดคะแนน 100 คะแนนเทากนหมด ซงคงไมมวนเปนจรงได

ในทางปฏบต) ตามขนตอนวธของโปรแกรมน นกศกษาทกคนจะได F ในทางทฤษฎแลว กรณ

เชนนเกรดนกศกษาควรเปนอยางไร ยงไมสามารถคนหาคาตอบได

รายละเอยดของโปรแกรม Grade.C มดงน

Page 368: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

361

/* Program 8.8 Grade.C

* Purpose: Grade Assignment using Normal T Score.

* Author : Wachara Rodsumrid.

* Office : Dept of Physics. Rajamangala Institute of Technology.

* Language: Turbo C v.2.0

* Date : OCT 1992. (in BASIC version)

* Last update : 26 May 1996.

* What 's new : 1. Data could be real numbers.

* 2. More accuracy in calculating area under normal curve.

3. Decrease global variables, more structure programming.

4. Show output on screen before printing.

**************************************************************/

#include <stdio.h>

#include <ctype.h>

#include <math.h>

#include <string.h>

#include <dos.h>

#include <time.h>

/* maximum number of students = 1000 */

#define MAX_STUDENT 1000

/* Global variable */

char *str_time;

char *filename;

/* function declare */

int get_data_from_file(char *filename,double dat[],int* err_line);

double average(int, double item[]);

void quick_sort(double item[], int ,int ,int );

int find_frequency(int,double item[], int Frequency[],double MScore[]);

void find_cumulate_frequency(int, int, int Frequency[],\

int cf[],double ZArea[]);

void evaluate_Tscore( int,double item[],double Tresult[]);

double Find_z(double);

void assign_grade(int,double TScore[],char *grade[]);

void output_to_printer(int,double ManagedScore[],\

Page 369: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

362

int Frequency[],int cf[], double TScore[],double ZArea[],\

double mean, double sd,char* grade[]);

int printer_ready(void);

void output_to_screen(int,double ManagedScore[],int Frequency[] \

,int cf[], double TScore[],double ZArea[], double mean,\

double sd,char *grade[]);

void main(int argc, char *argv[])

{

double RawScore[MAX_STUDENT],ManagedScore[MAX_STUDENT];

int Frequency[MAX_STUDENT],cf[MAX_STUDENT];

double TScore[MAX_STUDENT];

double ZArea[MAX_STUDENT];

char *grade[MAX_STUDENT];

long time_now;

double mean,sd;

int n, nf;

int err_line,error;

char c = 'S';

time(&time_now);

str_time = ctime(&time_now);

if (argc < 2) {

puts ("Input your data filename");

puts (" grade [drive:][path] filename\n");

exit(1);

}

filename = argv[1];

puts("Normalized T-Score Calculation Version 1.6");

puts(" Dept of Physics.");

puts ("Last update 31 MAY 1996");

puts("Rajamangala Institute of Technology.");

printf("\nNow I am reading your file, %s\n",argv[1]);

n = get_data_from_file(filename,RawScore,&err_line);

if ( n == -1) {

printf( "Detect some mistake(s) in your Data file,'%s'\n",argv[1]);

printf( "Found error(s) in line %d\n",err_line);

Page 370: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

363

exit(1);

}

if (n == -2 ) {

printf("Cannot open %s\n",argv[1]);

exit(1);

}

puts("Find average and standard deviation.....");

error = mean_deviation(n,RawScore,&mean,&sd);

if (error == -1) {

printf("The number of data = 0 \n");

exit(1);

}

puts("Sorting...");

quick_sort(RawScore,0,n-1,0);

puts("Find cumulated frequency ...");

nf = find_frequency(n,RawScore,Frequency,ManagedScore);

find_cumulate_frequency(nf,n,Frequency,cf,ZArea);

puts("Calculating T-score...");

evaluate_Tscore(nf,ZArea,TScore);

puts("Assigning grade...");

assign_grade(nf,TScore,grade);

while ( c != 'Q') {

printf("\nOutput to (S)creen, (P)rinter or (Q)uit ?");

c = toupper(getche());

if ( c == 'P') {

puts("\nand printing....");

output_to_printer(nf,ManagedScore,Frequency,cf,\

TScore,ZArea,mean,sd,grade);

}

if ( c == 'S') {

clrscr();

output_to_screen(nf,ManagedScore,Frequency,cf,\

TScore,ZArea,mean,sd,grade);

}

if ( c== 'Q') {

puts("\n\nThank for using this Software..from Wachara .R.\n");

Page 371: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

364

}

} /* while */

}

int get_data_from_file(char *filename,double dat[],int* err_line)

{

/* Function Description : get data (real number) from specified file.

User's define Constant: none

Input : *filename -- pointer which point to filename.

data[] -- an array which real numbers are stored in.

The first number begin at item[0] (not

item[1]) and the last number is in item[n-1].

*err_line -- pointer to line number that error happened.

Calling Function : none

Return Value : the number of data -- if everything's ok.

-1 -- there is some error in data.

-2 -- cannot open file.

*/

FILE *fp;

int line = 1;

char ch,temp[20]= "";

int point=0, n=0,i=0, IN_DIGIT =0, IN_COMMENT = 0;

int ERR_FLAG = 0;

double t;

if ((fp = fopen( filename,"r") ) == NULL) {

return(-2);

}

while ( (ch = fgetc(fp)) != EOF && !ERR_FLAG) {

if (ch == '*' ){

IN_COMMENT = 1;

}

if (ch == '\n') {

line++;

IN_COMMENT = 0;

Page 372: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

365

}

if (isalpha(ch) && !IN_COMMENT) {

ERR_FLAG = 1;

*err_line = line;

}

if (isdigit(ch)|| ch == '.' && !IN_COMMENT) {

IN_DIGIT = 1;

if ( ch == '.')

point = point+1;

temp[i] = ch;

i = i +1;

if (point > 1 ) {

ERR_FLAG =1;

*err_line = line;

}

}

if (isspace(ch) && IN_DIGIT && !IN_COMMENT) {

IN_DIGIT = 0;

point = 0;

i = 0;

dat[n] = atof(temp);

n++;

}

}

fclose(fp);

if (ERR_FLAG) return -1 ;else return(n);

}

int find_frequency(int number,double item[],\

int Frequency[],double Manageitem[])

/* Function Description : Collect frequency of each value.

User's difine Constant: none

Input : number -- number of data.

item[] an array which numbers are stored in.

The first number begin at item[0] (not

item[1]) and the last number is in item[n-1].

Page 373: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

366

Frequency[] an array that keeps the frequecy of

each value of data.

Manageditem[] an array which classified data

are kept.

Calling Function : none

Output : Frequency of each value stored in Frequency[]

Return Value : number of classified data.

Remark : Lookout ! The data in item[] must be sorted

before using this function */

{ int n_freq = 0;

int i,j;

for (i = 0; i < number ; i++) {

if (item[i] == -1 ) continue;

Frequency[n_freq] = 1;

Manageitem[n_freq] = item[i];

for (j = i ; item[j+1] == item[i]; j++) {

Frequency[n_freq] +=1;

item[j+1] = -1;

}

n_freq += 1;

}

return(n_freq);

}

int mean_deviation(int n_item, double item[],double *average,double* deviation)

{/* Function Description : Calculate arithmatic mean and standard deviation.

User's difine Constant: none

Input : n_itemd -- number of data.

item[] an array which numbers are stored in.

The first number begin at item[0] (not

item[1]) and the last number is in item

[n-1].

*average -- mean of data.

*deviation -- standard deviation.

Calling Function : none

Output : mean and standard deviation are stored in 'mean' and 'deviation'.

Return Value : 0 -- No error.

Page 374: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

367

1 -- number of data = 0

*/

int i;

double total;

if (n_item == 0 ) return 1;

total = 0;

for ( i =0; i< n_item; i++)

total = total+ item[i];

*average = total/ n_item;

total = 0;

for (i = 0; i < n_item; i++ )

total = total + (item[i] - *average)*(item[i]-*average);

*deviation = sqrt(total/n_item);

return(0);

}

void quick_sort(double item[], int left,int right,int ascending)

{

int i,j;

double comparand,temp;

i = left; j = right;

comparand = item[(left+right)/2];

do { if (ascending) {

while(item[i] < comparand && i < right) i++;

while (comparand < item[j] && j > left) j--;

} else {

while(item[i] > comparand && i < right) i++;

while (comparand > item[j] && j > left) j--;

}

if ( i <= j) {

temp = item[i];

item[i] = item[j];

item[j] = temp;

i++; j--;

}

} while (i <=j);

Page 375: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

368

if (left <j ) quick_sort(item,left,j,ascending);

if (i < right) quick_sort(item,i,right,ascending);

}

void find_cumulate_frequency(int n_freq, int n_item,\

int Frequency[], int cf[],double ZArea[])

{ int i;

for ( i = 0; i <= n_freq;i++)

{ cf[i] = 0; ZArea[i] = 0; }

Frequency[n_freq + 1] =0;

for (i = n_freq-1; i >= 0; i--) {

cf[i] = cf[i+1] +Frequency[i];

ZArea[i]=(cf[i+1]+0.5*Frequency[i])/n_item;

}

}

double Find_z( double area)

{

/*

Function Description: Finding z value at known area under normal curve.

User's Define Variable : None

Input :

area -- area under normal cuvre

Return : statistic z value.

-99 -- if area >1 or < 0

Remark : The area should be between 0 to 1.

*************************************************************************/

int i,flag,lowerlimit;

double new_area,da,z,sum;

if ( area < 0 || area > 1 ) return -99;

flag = 0;

if (area > 0.5) {

new_area = area - 0.5;

flag = 1;

}

else {

new_area = 0.5 - area;

Page 376: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

369

}

sum = 0.0; lowerlimit = 0;

if (new_area >= 0.3412944) {

lowerlimit = 1; sum = 0.3412944;

}

if (new_area >= 0.4771599) {

lowerlimit = 2; sum = 0.4771599;

}

if (new_area >= 0.4986253) {

lowerlimit = 3; sum = 0.4986253;

}

/* Integrate by Trapezoidal Rule */

z = lowerlimit;

while (new_area - sum > 0.001) {

da = (exp(-0.5*z*z)+exp(-0.5*(z+0.01)*(z+0.01)))*1.994712e-03;

sum = sum + da;

z += 0.01;

}

if (flag ==1)

return(z);

else

return(-z);

}

void evaluate_Tscore( int n_freq,double item[],double TScore[])

{

int i;

double temp_z;

for(i = 0 ; i < n_freq;i++) {

temp_z = Find_z(item[i]);

TScore[i] = (temp_z*10.0 + 50.0);

}

}

void assign_grade(int n_freq,double TScore[],char *grade[])

Page 377: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

370

{ int i;

double range;

range = (TScore[0] - TScore[n_freq-1])/5.0 ;

if (range < 0 ) range = -range;

for (i = 0; i < n_freq; i++) {

grade[i] = "F";

if (TScore[i] > (50.0 - 1.5*range)) grade[i] = "D";

if (TScore[i] > (50.0 - 0.5*range)) grade[i] = "C";

if (TScore[i] > (50.0 + 0.5*range)) grade[i] = "B";

if (TScore[i] > (50.0 + 1.5*range)) grade[i] = "A";

}

}

void output_to_printer(int n_freq,double ManagedScore[],int Frequency[]\

,int cf[], double TScore[],double ZArea[],double mean,double sd,char* grade[])

{ int i;

if (printer_ready()) {

fprintf(stdprn,"\t\t NORMALIZED T-SCORE CALCULATION. \n");

fprintf(stdprn,"\t\tDept of Physics., Rajamangala Institute of Technology.\n");

fprintf(stdprn," Data from file : %s \tDate of printing: %s \n\n",filename,str_time);

fprintf(stdprn," Average Score = %6.2f. Std deviation = %f.2f\n",mean,sd);

fprintf(stdprn,"Score Freq Cumulate Freq Percentile Normal-T \

Grade\n");

fprintf(stdprn,"===========================================================

===\

========\n");

for(i=0; i < n_freq; i++ ) {

fprintf(stdprn,"%6.3f %3i %3i %5.2f %5.2f

%s\n",ManagedScore[i],\

Frequency[i],cf[i],ZArea[i]*100.0,TScore[i],grade[i]);

}

fprintf(stdprn,"\n\n\t\t---------------------------------------\n");

} else {

puts( "\n\n printer not ready !!!!!!\n");

Page 378: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

371

}

}

int printer_ready()

{

int p1;

asm { mov ax,40h

mov es,ax

mov dx,es:[8]

inc dx

in al,dx

mov bl,1 /* TRUE */

test al,1000b /* check out any printer ready */

jnz p1 /* jump if bit set */

mov bl,0

}

p1:

asm { xor ax,ax

mov al,bl

}

return (_AX);

}

void output_to_screen(int n_freq,double ManagedScore[],int Frequency[] \

,int cf[], double TScore[],double ZArea[], double mean,\

double sd,char *grade[])

{

int i;

fprintf(stdout,"\t\t NORMALIZED T-SCORE CALCULATION. \n");

fprintf(stdout,"\t\tDept of Physics., Rajamangala Institute of Technology.\n");

fprintf(stdout," Data from file : %s Date of printing: %s \n",filename,str_time);

fprintf(stdout," Average Score = %6.3f. Std deviation = %6.3f\n",mean,sd);

fprintf(stdout,"Score Freq Cumulate Freq Percentile Normal-T \

Grade\n");

fprintf(stdout,"===============================================\

========\n");

for(i=0; i < n_freq; i++ ) {

Page 379: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

372

fprintf(stdout,"%6.3f %3i %3i %5.2f %5.2f

%s\n",ManagedScore[i],\

Frequency[i],cf[i],ZArea[i]*100.0,TScore[i],grade[i]);

if (wherey() == 24) {

printf("Press any key to continue ...");getch();

clrscr();

}

}/* for loop */

fprintf(stdout,"\n\t\t---------------------------------------\n");

}

Page 380: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

373

บรรณานกรม

1. จเร สรวฒนปญญา. Numerical Computation ดวยโปรแกรมภาษาเบสก. กรงเทพ ฯ :

สถาบนเทคโนโลยพระจอมเกลา ลาดกระบง, 2528.

2. ศรพงษ ศรพพฒน. คณตศาสตรเชงตวเลข. สงขลา : มหาวทยาลยสงขลานครนทร, 2530.

3. สวรรณ ถงมณ. การวเคราะหเชงตวเลข 1. กรงเทพ ฯ : มหาวทยาลยเกษตรศาสตร, 2531.

4. Al-Khafaji Amir W. and Tooley Hohn R. Numerical Methods in Engineering Pracitce.

New York : CBS Collage, 1986.

5. Bajpai, A.C. and others. Engineering Mathematics. 2nd edition. Singapore : John

Willey & Sons,Inc., 1990.

6. Bechwith, Thomas G. and others. Mechanical Measurement. New York: Addison-

Wesley., 1993.

7. Berry, John T. Advance C Programming. New York : Prentice-Hall,Inc., 1986.

8. Burden, Richard L. and Faires, Douglas J. Numerical Analysis. 5 th edition.

Massachusetts : PWS Publishing., 1993.

9. Chapra, Steven C. Introduction to Computing for Engineers. Singapore: McGraw-

Hill., 1986.

10. Constantinides, A. Applied Numerical Methods with Personal Computer. Singapore:

McGraw-Hill., 1987.

11. Daconta, Michael C. C++ Pointer and Dynamic Memory Management. New York:

John Willy & Sons, Inc., 1995.

12. Dejong, Marvin L. Introduction to Computational Physics. New York: Addison-

Wesley., 1991.

13. Ehrlich, R. Physics and Computers. Boston: Houghton Muffin. 1973.

14. Henrici,P. Elements of Numerical Analysis. New York: John Willey & Sons,Inc.,

1964.

15. Holzner, Steven C Programming. New York: Brady Publishing.,1991.

16. Kahaner,David. and others. Numerical Methods and Software. London: Prentice-

Hall,Inc., 1989.

Page 381: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

374

17. Khafaji, AL and Wadi Amir Computerize Numerical Analysis. New York: CBS

Collage, 1986.

18. Knuth, D.E. The Art of Computer Programming. Vol. 1, New York : Addison -

Wesley, 1973.

19. Kreyszig, Erwin Advance Engineering Mathematics. New York: John Willey &

Sons,Inc., 1988.

20. Miller, Alan R. Turbo Basic Programs for Scientists and Engineers. SanFrancisco:

Sybex., 1987.

21. Nakamura, S. Applied Numerical Methods in C. New York: Prentice-Hall, Inc.,

1993.

22. Plantz, Alan C. and others. Turbo C Programming. New York: Que Corporation.,

1989.

23. Scheid, Francis. Numerical Analysis,Schaum's Outline series., Singapore: McGraw-

Hill., 1983.

24. Schildt, H. C Power User's Guide. California: McGraw-Hill,Inc., 1988.

25. Shoup, Terry E. A Practical Guide to Computer Methods for Engineers. London:

Prentice-Hall, Inc., 1979.

26. Spiegel, R.M. Finite Differences and Difference Equation. New York: McGraw-Hill,

1971.

27. Staff of Research and Education Association. The Numerical Analysis Problem Solver. New York: Research and Education Association, 1984.

28. Walker, Robert D. Numerical Methods for Engineers and Scientists. New York: Tab

Book Inc., 1987.

29. Wolfe, Phillip M. Basic Engineering Science and Business Programming for the Apple II and IIC. New York: Brady Co, Inc., 1984.

Page 382: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

ภาคผนวก 1 เรยนรภาษา ซ อยางสงเขป

เคอรนงแฮน และ รชช (Kerninghan and Richie) ไดสรางภาษาซ ขนเมอ พ.ศ. 2521

และไดยดถอเปนมาตรฐาน ทเรยกวา K & R C ตอมามบรษทซอฟแวรสรางคอมไพเลอรภาษาซ

ออกมาวางจาหนาย ทาใหภาษาซมลกษณะแตกตางกนออกไป ขาดลกษณะทสามารถโอนยาย

ขามเครองคอมพวเตอรทแตกตางกนได ในป พ.ศ. 2532 สถาบนมาตรฐานแหงชาตของ

สหรฐอเมรกา เรยกยอ ๆ วา ANSI (American National Standard Institute) ไดปรบปรงและ

กาหนดมาตรฐานภาษาซ โดยสรางเปนมาตรฐานโดยใชหมายเลขรหสเปน ANSI X3.159 1989

ไดกาหนดสวนหวของโปรแกรม (head file) ไลบราล (Library) และ พรโพรเซสเซอร

(Preprocessor) ทเปนมาตรฐาน คาอธบายตอไปนจะยดถอภาษาซ ของ ANSI C เปนหลก

โครงสรางของโปรแกรมภาษาซ โปรแกรมภาษาซโดยทวไปประกอบดวยโปรแกรมทมแฟมตนฉบบหรอ โมดล (module)

มากกวา 1 ไฟลขนไป แตละแฟมตนฉบบจะมโครงสรางคลาย ๆ กน ประกอบดวย สวนหมายเหต

ของโปรแกรม (comment) สวนกากบในการคอมไพล (preprocessor directive) การประกาศ

และการนยามตวแปรและฟงกชน

Header file เปนแฟมขอมลทมนามสกลเปน .h ใชประกาศคาตวแปร หรอฟงกชนสาหรบ

ใชในแฟมตนฉบบอน ๆ จากตวอยาง ในแฟมตนฉบบ Area .h จะประกอบดวย คาคงท PI และ

ฟงกชนทใชในการคานวณหาพนทใน Area .C

/* Area . h */

#define PI 3.1415926

float FindCircleArea(float );

float FindRectangularArea(float, float);

/* Area.C */

float FindCircleArea(float radius)

{ return(PI*radius*radius); }

float FinRectangularArea(float width, float length)

{ return( width * length); }

Page 383: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

376

/* Areatest.C */

#include <stdio.h>

#include “area.h”

void main()

{

char buffer[100];

int choice;

float r,w,len,area = 0 ;

do {

printf(“ To find the area of .........\n”);

printf(“ 1. Circle\n”);

printf(“ 2. Rectangular\n”);

gets(buffer); choice = atoi(buffer);

} while ( choice < 0 || choice >2);

switch(choice) {

case 1 : { printf(“Input the radius\n”);

gets(buffer); r = atof(buffer);

area =FindCircleArea(r);

break;

}

case 2 : { printf(“Input the width\n”);

gets(buffer); w = atof(buffer);

printf(“Input the length\n”);

gets(buffer); len = atof(buffer);

area =FindRectangularArea(r);

break;

}

} /* switch */

printf(“An area = %f \n”, area );

}

ในแฟมตนฉบบชอ Area.C จะแสดงรายละเอยดของฟงกชน ซงในทนแสดงให

เหน เพยง 2 ฟงกชน โดยทวไปจะประกอบดวยฟงกชนหลาย ๆ ฟงกชน สวนแฟมตนฉบบชอ

AreaTest.C จะเปนสวนทโปรแกรมเรมตนทางาน โดยจะเรมตนตรงตาแหนง main( ) ไฟลเหลาน

จะมนามสกลเปน .C

Page 384: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

377

เราตองคอมไพลและลงค โปรแกรมตนฉบบเหลานเขาดวยกนเปน excute file

ขนตอนการสรางแฟมนามสกล .Exe ขนอยกบตวคอมไพเลอร และระบบปฏบตการ ซงจะสามารถ

หาอานไดจากคมอคอมไพเลอรทใชงานอย

สวนประกอบของโปรแกรมตนฉบบ จะมลกษณะทเหมอนกนดงตอไปน

1. หมายเหตของโปรแกรม (comment) บอกจดประสงคของโปรแกรม รายละเอยด

เกยวกบโปรแกรม เชน ชอผเขยนโปรแกรม วนทปรบปรง ขอพงระวงการนาโปรแกรมไปใช หมาย

เหตของโปรแกรมจะเรมตน ดวย /* และสนสดดวย */ เสมอ

2. สวนกากบในการคอมไพล (Preprocessor Directive) จะอยถดจากหมายเหตของ

โปรแกรม โดยทวไปจะนาแฟมทมนามสกล .h มาอางใชงานตรงจดน และนยามคาคงทตาง ๆ

3. การประกาศตวแปรและฟงกชน (Declaration of variable and function) จะประกาศ

คาตวแปรและฟงกชนททก ๆ แฟมตนฉบบสามารถใชได จะใช คาสงวน static เมอตองการให

คาทเกบในตวแปรนนยงคงอยหลงจากเลกใชฟงกชนนนแลว การใชคาสงวน extern จะบอกวาตว

แปรนอยในแฟมขอมลแฟมอน

4. การนยามฟงกชน (Definition of a function) จะแสดงรายละเอยดของฟงกชนแตละ

ฟงกชน

คาสงวน (Reserve Keyword) เปนคาทเราไมสามารถนาไปใชตงชอตวแปร คาคงทหรอ

ฟงกชนได คาเหลานไดแก

auto break case char const

continue default do double else

enum extern float for goto

if int long register retrun

short signed sizeof static struct

switch typedef union unsigned void

volatite while

สวนกากบในการคอมไพล Preprocessing หมายถงขนตอนแรกสดกอนทตวคอมไพลจะแปลภาษาซ ใหอย

ในรปภาษาเครอง ตวคอมไพลจะรบรไดจาก สวนทกากบไวในตอนตนของโปรแกรมตนฉบบ ซง

Page 385: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

378

จะขนตนดวยเครองหมาย # (pound sign) การใช preprocessor ทาใหโปรแกรมมลกษณะเปน

สวน ๆ นาอาน และงายทจะทาความเขาใจ โดยทวไปเรานามาใชงานในลกษณะดงตอไปน

1. ใชตวกากบ #include เพอเพมหรอแทรกสวนตาง ๆ ของโปรแกรม เราอาจนา

ตวแปรตาง ๆ ไปประกาศไวในแฟม include เพยงทเดยว เพอลดความเสยงทฟงกชนในแฟม

ตนฉบบอน ๆ จะหาตวแปรไมพบ ถาประกาศตวแปรไวในแฟมยอยแฟมใดแฟมหนง อาจทาให

ฟงกชนซงใสไวในแฟมอกแฟมหนงไมสามารถมองเหนตวแปรเหลานได ตวอยางการใช include

file ไดแก

ตวอยาง ท 1 #include <stdio.h>

เปนการนา header file ทอยในไดเรกทอรยอยทตงไวโดยปรยาย ในไดเรกทอร

ยอยนจะประกอบดวยแฟมขอมลทนามสกลเปน .h ทงหมด

ตวอยางท 2 #include “area.h”

เปนการนา แฟมขอมล area.h มารวมในโปรแกรม โดยท area.h นจะอยในไดเรก

ทอรทกาลงใชงานอย

ตวอยางท 3 #ifdef WINDOW

#define PLATEFORM “window.h”

#else

#define PLATEFORM “dosdef.h”

#endif

#include PLATEFORM

เปนการนา include file เขามาใชอยางมเงอนไข ถานยามคาวา WINDOW ตว

คอมไพลจะนาแฟม window.h เขามารวมในการแปลภาษา ถาไมนยามจะนาแฟม dosdef.h เขา

มารวมแทน

2. ใชตวกากบ #define กาหนดคาคงทหรอแมโคร (macro) ชวยทาใหโปรแกรม

นาอานและทาความเขาใจไดงาย

ตวอยางท 4 #define AVOGADRO 6.02e23

#define PI 3.1415926

Page 386: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

379

เราสามารถใช AVOGADRO, PI แทนตวเลขทกาหนดไวไดทงโปรแกรม

ความสามารถของแมโคร นอกจากจะแทนคาตวเลขตาง ๆ ดวยตวคงททเรากาหนดแลว

ยงสามารถรบคาพารามเตอร แทนคาพารามเตอรดวย คาคงททกาหนดไวในแมโครดวย

ตวอยางท 5 #define cubic(x) ((x)*(x)*(x))

ถาเราเขยน cubic(y) ในโปรแกรม จะถกแทนทดวย ((y)*(y)*(y)) ทนท ขณะท

ทาการพรโพรเซส จะเหนวาแมโครมลกษณะเหมอนฟงกชน ตางกน ท มไดเรยกใชแมโคร

เหมอนกบทเราเรยกใชฟงกชน แมโครจะนาขอความหรอประโยคมาแทนลงตรงจดนนโดยตรง

3. ตวกากบทมเงอนไข (Conditional Directives)

เราสามารถใชตวกากบทมเงอนไข เชน #if, #ifdef, #ifndef, #else, #elseif และ

#endif ควบคมการแปลโปรแกรมตนฉบบใหอยภายใตเงอนไขตาง ๆ เชน อาจแปลเพยงบางสวน

ของโปรแกรมหรอคอมไพล ในกรณทใชคอมไพเลอรตางกน หรอ สงแวดลอมตางกน เชนนา

โปรแกรมทเขยนอยในระบบปฏบตการดอส ไปใชกบระบบปฏบตการยนกซ เปนตน ทใชกนอย

ทวไปคอสอดแทรกคาสง printf เพอตรวจสอบหรอแกไขการทางานของโปรแกรม โดยนยาม

DEBUG ไวตรงสวนหวของโปรแกรม

ตวอยางท 6 ตองการใหคอมไพเลอรนา header file ชอ myinc.h มารวมในการคอมไพลเพยง

ครงเดยว #ifndef __myinc.h

#define __myinc.h

#include “myinc.h”

#endif

ตวอยางท 7 ตรวจสอบคาตวแปร โดยการพมพบนหนาจอเมอนยามคาวา DEBUG

#ifdef DEBUG

printf(“ X = %f “ , x);

#endif

ตวอยางท 8 ใชเลอก header file ทมลกษณะตางกน

#if CPU_TYPE == 8086

#include <real_mode.h>

Page 387: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

380

#elfif CPU_TYPE == 8386

#include <prot_mode.h>

#else

#error Unkonw CPU_TYPE

#endif

การประกาศตวแปรและฟงกชน การประกาศตวแปรและฟงกชนจะตองกระทากอนเสมอ กอนทจะนาไปใชใน

โปรแกรมนน เพอบอกวาตวแปรนมขอบเขตการนาไปใชแคไหน และเปนแบบใด

ภาษาซแบงชนดของตวแปรออกเปน 4 แบบใหญ ๆ คอ แบบตวอกษร

(character) แบบจานวนเตม (integer) แบบจานวนจรง(double, float) แบบไบต (byte) จานวน

หนวยความจาทใชในการเกบตวแปรแตละแบบขนอยกบคอมไพเลอร เชน คอมไพเลอรภาษา ซ

ใน MS. DOS ใชหนวยความจาในเกบจานวนเตมเพยง 2 ไบต ขณะทคอมไพเลอร ในระบบยนกซ

ใชถง 4 ไบต การนยามตวแปรแตละชนดทาไดดงน

ตวอยางท 9 char ch;

int i,j,k, total;

flaot result, multiplier;

double coeff , mean;

เราสามารถขยายชนดของตวแปรพนฐาน 4 แบบนนาไปใชใหตรงจดประสงคโดย

เพม prefix ไดแก long, short และ unsigned ซงจะชวยในการเปลยนขนาดหนวยความจาทใช

เกบตวแปร

ตวอยางท 10 unsigned char input_status; /* เกบเฉพาะคาบวก */

short rec_num; /* มความหมายเดยวกบ short int */

long total_num; /* จานวนเตมขนาด 4 ไบต */

unsigned id; /* มความหมายเดยวกบ unsigned int */

unsigned long k; /* มความหมายเดยวกบ unsigned long int */

long double divider; /* จานวนจรงขนาด 8 byte */

Page 388: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

381

ชนดตวแปรแบบ Enumeration

ใน ANSI C เราสามารถนยามคาคงท ซงถกกาหนดคาเปนจานวนเตมใหอยในแบบ

enum ได มประโยชนคอทาใหโปรแกรมอานงายสอความหมายในตวของมนเอง

ตวอยางท 11 การประกาศตวแปรชนด enum

enum BOOLEAN { false = 0, true = 1, off = 0, on = 1 }

การนยามตวแปรทเปนแบบ enum ทาไดดงน

enum BOOLEAN status = off;

ตวอยางนจะประกาศ BOOLEAN ใหเปนตวแบบ enum โดยประกอบดวยคาคงททเปน

จานวนเตมเปนคาสอดคลองกบตวแปร BOOLEAN ซงนยามไวในชอ status กาหนดคาเบองตน

ของ status คอ ศนย (เพราะ off = 0 )

ชนดตวแปรแบบโครงสราง และ ยเนยน (Structure and union ) เราสามารถรวบรวมตวแปรตางชนดกนนามาไวในทเดยวกน แลวกาหนดชอใหมโดย

อาศย ชนดตวแปรแบบโครงสราง เชน ขอมลของนกศกษาแตละคนประกอบดวย รหสนกศกษา

(id) ชอ(name) และสาขาทเรยน (major) จดเปนกลมขอมลแลวใชตวแปรแบบโครงสรางชอ

student ไดดงน

ตวอยางท 12 /* Declare a student */

struct student {

int id;

char name[60];

char major[60];

};

/* define two student */

struct student student1, student2;

ตวแปรแบบยเนยน มลกษณะคลายกบแบบโครงสราง จะรวบรวมตวแปรแบบตาง ๆ ไวใน

ชอเดยวกน สงทแตกตางกนคอ ตวแปรแบบยเนยนจะจดสรรเนอทหนวยความจาไวเพยงทเดยว

โดยจะจดเนอทตามขนาดของขอมลทมขนาดใหญทสดทมอยในยเนยนนน

ตวอยางท 13 union {

int cdeff;

Page 389: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

382

long multiply;

double result;

char name[3];

} solution;

ตวแปรแบบยเนยน ชอ solution จะประกอบดวยตวแปรแบบตาง ๆ ไดแก int , long,

double และ char ตวแปรแบบ double จะใชเนอทเกบมากทสด คอ 8 ไบต คอมไพเลอรจะจอง

เนอทเกบตวแปรแบบยเนยนเพยง 8 ไบต ตาแหนงหนวยความจาทเกบตวแปรแบบ double นจะ

เปนคาแรกของ name [0] ดวยเชนกน

ตวแปรแบบอะเรย อะเรยจะเกบขอมลทเปนแบบเดยวกนไวในชอเดยวกน

ตวอยางท 14 x เปนตวแปรแบบ float มคา 5 คา สามารถประกาศและนยาม ตวแปร x ดงน

float x[5] = { 0.02, 0.7, 1.2 , 3.1, 4.0 };

ตวอยางท 15 จอภาพม 25 บรรทด 80 คอลมนสามารถเกบตวอกษรได 25 × 80 ตวอกษร

ตวอกษรทปรากฎบนจอภาพ สามารถเขยนเปนตวแปรชนดอะเรยดงน

char text_screen[25][80];

การใชคาสง typedef กาหนดแบบตวแปร ภาษา C ยอมใหผใชกาหนดแบบของตวแปรขนเองตามใจชอบโดยใช typedef เปน

ตวกาหนด

ตวอยางท 16 จดบนจอภาพ(pixel) ประกอบดวยตาแหนง x,y ตาง ๆ กน เราสามารถกาหนด

เปนขอมลชนด pixel ไดดงน

typedef struct PIXEL {

int x;

int y;

int color;

}

สามารถนาไปใชในโปรแกรมดงน

PIXEL p1,p2;

Page 390: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

383

กระทงความในภาษาซ (Expression)

กระทงความในภาษาซประกอบดวยตวแปร ฟงกชนทถกเรยกใช และปฏบตการตาง ๆ

กระทงความหนง ๆ จะใหผลลพธเพยง 1 คา ตวอยางเชน ตองการทราบจานวนไบตทจะใชเกบคา

สตรง สามารถเขยนเปนกระทงความไดดงน

(strlen(str)*sizeof(char) + 1 )

strlen(str) เปนฟงกชนหาความยาวของตวแปร str การ คณ (*) การบวก(+) และ sizeof

เปนตวปฏบตการ ผลลพธทไดเปนจานวนเลข ซงบอกจานวนไบตทใชเกบคาสตรงใน

หนวยความจา

ตวปฏบตการในภาษา ANSI C มดงน

ชอตวปฏบตการ วธใช ผลลพธ เกยวกบคณตศาสตร

การบวก x+y คา x บวกกบคา y

การลบ x-y x ตงลบดวย y

การคณ x*y คณ x ดวย y

การหาร x/y หาร x ดวย y

การหาเศษเหลอ x%y เศษทไดจาก x ตงหารดวยy

การเพมคากอนหนา ++x เพมคา x กอนนา x ไปใช

การเพมคาภายหลง x++ เพมคา x หลงจากนา x ไปใช

การลดคากอนหนา --x ลดคา x กอนนา x ไปใช

การลดคาภายหลง x-- ลดคา x หลงจากนา x ไปใช

เกยวกบตรรกะ

มากกวา x > y จะไดคา 1 ถา x มากกวา y นอกจากนเปน 0

มากกวาหรอเทากบ x >= y จะไดคา 1 ถา x มากกวาหรอเทากบ y นอกจากน

จะไดคาเปน 0

นอยกวา x < y จะไดคา 1 ถา x นอยกวา y นอกจากนเปน 0

นอยกวาหรอเทากบ x <= y จะไดคา 1 ถา x นอยกวาหรอเทากบ y นอกจากน

จะไดคาเปน 0

เทากบ x==y จะไดคา 1 ถา x เทากบ y นอกจากนเปน 0

ไมเทากบ x!=y จะไดคา 1 ถา x ไมเทากบ y นอกจากนเปน 0

Logical not !x จะไดคา 1 ถา x เทากบ 0 นอกจากนเปน 0

Page 391: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

384

ชอตวปฏบตการ วธใช ผลลพธ เกยวกบการกาหนดคา

Logical AND x && y จะไดคา 0 ถา x หรอ y มคาเปน 0

Logical OR x || y จะไดคา 0 ถา x และ y มคาเปน 0

กาหนดคา x = y ใสคาy ลงในตวแปร x

กาหนดคาผสม x o=y มคาเทากบ x = x o y เมอ o คอตวปฏบตการตว

ใดตวหนงดงตอไปน + ,- ,* , /, % , <<, >>, &, ^

และ |

การเขาถงขอมลและหาขนาด

ระบสมาชก x[y] เลอกคา x ซงเปนตวแปรแบบอะเรยอนดบท y

เลอกสมาชก x.y เลอกตวแปร y ในขอมลชนดโครงสราง (หรอ

ยเนยน) ชอ x

x->y เลอกตวแปร y ในขอมลชนดโครงสราง (หรอ

ยเนยน) ตรงตาแหนงทอยของ x

เขาถงขอมลทางออม *x เรยกใชคาทเกบไวทตาแหนงทอยของ x

หาตาแหนงทอย &x ตาแหนงทอยของ x

หาขนาด sizeof(x) ขนาดเปนไบตของตวแปร x

เกยวกบบต

Bitwise NOT -x เปลยน 1 ทกตวเปนศนย และเปลยนศนยทกตว

เปน 1

Bitwise AND x & y ผลลพธคอการ AND ระหวาง x และ y

Bitwise OR x | y ผลลพธคอการ OR ระหวาง x และ y

Bitwise exclusive OR x ^ y ผลลพธจะไดบตตรงนนเปน 1 ถาบตของ x และ y

ตรงตาแหนงทตรงกนนนตางกน

เลอนไปทางซาย x << y เลอนบตของ x ทกตวไปทางซาย y ตาแหนง

เลอนไปทางขวา x >> y เลอนบตของ x ทกตวไปทางขวา y ตาแหนง

ขอความ (Statement)

Page 392: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

385

ขอความประกอบดวย คาสงวน กระทงความ ซงจะปดทายดวยเครองหมายอฒภาคเสมอ

ขอความผสมจะประกอบดวยกลมของขอความหลาย ๆ ขอความอยดวยกน เรมตนดวยวงเลบปก

กา เปด( { ) แลวจบดวยวงเลบปกกาปด ( } ) ลกษณะขอความใน ANSI C มหลายแบบ ดงน

For loop เปนการวนรอบทรจดสนสดทแนนอน

ตวอยางท 17 ตองการบวกเลขตงแต 1 ถง 100

for(i = 0, sum =0; i <=100; sum +=i, i++);

While loop เปนการวนรอบโดยอาศยเงอนไข ถาเงอนไขนนยงคงเปนจรงการวนรอบยงคง

มอยตอไป

ตวอยางท 18 การวนรอบในตวอยางนยงคงมตอไป จนกวาเราจะกดปม enter

#include <stdio.h>

main()

{ char ch;

int len=0;

puts(“Type your message and press enter.....”);

while((ch = getch()) != ‘\n’) {

putch(ch); len++;

}

printf(“\n Your sentence was %d characters long.\n”,len);

}

Do.....While loop จะคลายกบ while loop ตางกนตรงทจะมการตรวจสอบเงอนไขเมอ

โปรแกรมไดทางานตามคาสงทตามหลง Do เรยบรอยแลว

ตวอยางท 19 .........

do {

ch = getch();

putch(ch); len++;

} while ( ch != ‘\n’);

Break เปนการออกจากการวนรอบในคาสง do, for , while และ switch เมอโปรแกรม

พบขอความ break จะหยดการวนรอบกระโดดไปทาคาสงในขอความถดไปทนท

Page 393: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

386

ตวอยางท 20 for (i = 0; i < max_n; i ++ ) {

if (strcmp(input, buffer[i] == 0)

break;

}

If.....Else ใชในการตรวจสอบเงอนไข แลวใหโปรแกรมทางานตามคาสงทเงอนไขนน

กาหนด

ตวอยางท 21 เปนการหาคาทนอยทสดระหวางตวเลข 2 จานวน

if ( a <= b)

smaller = a;

else

smaller = b;

Switch....Case ใชตรวจสอบเงอนไขในกรณทมทางเลอกมากกวา 2 เงอนไข

ตวอยางท 22 switch(choice) {

case 1 : { area =FindCircleArea(r);

break;

}

case 2 : { area =FindRectangularArea(r);

break;

}

case 3 : { area = FindTriangleArea(hi, base);

break;

}

} /* switch */

Goto เปนคาสงใหกระโดดขามไปทางานทคาสงอนโดยไมมเงอนไข จะตองกาหนด

ตาแหนง (label) ทจะใหโปรแกรมกระโดดไปทางานดวยเสมอ

ตวอยางท 23 ...................

start : printf(“Enter your number “);

scanf(“%d”, &n);

Page 394: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

387

if ( n < 0 || n > max_number) {

printf(“Invalid integer\n”);

goto start;

}

................

ฟงกชน ฟงกชนเปนโปรแกรมขนาดเลก ทางานเฉพาะอยาง โดยทวไปมกจะใหฟงกชนทางาน

เพยงหนาทเดยว เชนในโปรแกรม Area.C ประกอบดวยฟงกชน 2 ฟงกชน คอ FindCircleArea( )

และ FindRectangularArea( ) ทาหนาทหาพนทของวงกลม และพนทของสเหลยมผนผา ในตว

ฟงกชนอาจมการนาขอมลจากภายนอกเขามาคานวณหรอประมวลผล แลวสงผลลพธคนกลบ

โปรแกรมภาษาซทกโปรแกรมจะตองประกอบดวยฟงกชนเสมอ อยางนอย ๆ กตองมฟงกชน main

( ) ซงเปนจดเรมตนและสนสดของโปรแกรม

กอนจะใชฟงกชนตองมการประกาศฟงกชน เพอใหโปรแกรมรจกกอนเสมอ

ตวอยางท 24 double FindCircleArea ( float radius)

ชนดและชอของพารามเตอรทใชผานคา

ชอฟงกชน

บอกชนดของขอมลทฟงกชนสงคากลบ

การสงผานขอมลของฟงกชนทาไดโดยผานทางพารามเตอร เมอฟงกชนรบคา แลวนามา

ประมวลผลโดยทไมทาใหคาตวแปรทใชในฟงกชนผเรยกเปลยนแปลง เรยกการผานคาแบบนวา

Call by value ถาจะใหมการเปลยนแปลงคาในตวแปรนน ผเรยกจะตองสงตาแหนงทอยของ

ตวแปรนนมาใหฟงกชน เรยกวา Call by reference มกจะใชกบฟงกชนทมการสงคากลบ

มากกวา 1 คา

ฟงกชนในภาษา ซ มศกดศรเทากน ตางสามารถเรยกใชซงกนและกนไดโดยไมมลาดบชน

และยงสามารถเรยกตวมนเองไดดวย เรยกวา recursion

ตวอยางท 25 หาคาแฟกทอเรยล โดยใหฟงกชนเรยกใชตวมนเอง

#include <stdio.h>

int factorial (int);

void main()

Page 395: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

388

{ int i = 6;

printf(“%d ! = %d \n”,factorial(i));

}

int factorial (int n)

{ if ( n == 1)

return 1;

else return (n * factorial(n-1));

}

ในภาษาซ เราสามารถนาฟงกชนตาง ๆ ทเขยนไว มาคอมไพลแลวเกบรวบรวมไวในคลง

โปรแกรม (Library) สามารถนามาเรยกใชไดเลย โดยไมจาเปนตองเขยนโปรแกรมฟงกชนนนใหม

ทกครง

Page 396: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

ภาคผนวก 2 เมตรกซขนพนฐาน

เมอนาตวเลขหรอตวแปรเกบไวเปนแถวเปนสดมภ ทเรยกวา อะเรย (array) ขอมลหรอ

สมาชกแตละตวจะมตาแหนงทแนนอนและแตกตางกน อะเรยทกลาวถงนทางคณตศาสตรเรยกวา

เมตรกซ (matrix) การกระทาทางคณตศาสตร ไมวาจะเปนการบวก ลบ คณ และหารหรออน ๆ

จะมวธเฉพาะของมนเอง ผทพฒนาทฤษฎเมตรกซ คอ แฮมลตน (Hamilton) มชวตอยในชวงป

ค.ศ. 1805-1865

ลกษณะการเกบขอมลแบบเมตรกซ แสดงไดดงตวอยางตอไปน

1 4 4

3 2 1

2 1 2

−− − เปนเมตรกซขนาด 3 × 3 เพราะม 3 แถว 3 สดมภ

7

12

5

− เปนเมตรกซขนาด 3 × 1 เพราะม 3 แถว 1 สดมภ

เมตรกซ A ขนาด m × n จะม จานวน m แถว และ n สดมภ

A =

a a a ... ... a

a a a ... ... a

... ... ... ... ... ...

a a a ... ... a

11 12 13 1n

21 22 23 2n

m1 m2 m3 mn

เมตรกซใดท จานวนแถวเทากบจานวนสดมภเรยกวา เมตรกซจตรส(square matrix)

ถา m = 1 เรยกเมตรกซนวา เปน เวกเตอรแถว (row vector)

เชน [ 2 3 5 -7 ]

ถา n = 1 เรยกเมตรกซนวาเปน เวกเตอรสดมภ (column vector)

เชน −2

1

0

Page 397: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

390

ถา m = n = 1 เมตรกซนจะเปนจานวนเลขธรรมดาทเราใชกน

เมตรกซทมสมาชกทกตวเปนศนย เรยกวา null matrix เชน

0 0

0 0 [ 0 0 0 ] [0]

เมตรกซทมสมาชกในแนวทะแยงมมจากดานบนซายมายงดานลางขวาไมเปนศนยทกตว

สวนสมาชกตวอน ๆ เปนศนยทงหมด เรยกวา เปนเมตรกซทะแยงมม (diagonal matrix) เชน

−5 0 0

0 0 0

0 0 3

เมตรกซทเปน diagonal matrix ทสมาชกทกตวในแนวเสนทะแยงมมมคาเปนหนง

เรยกวา เมตรกซหนวย (unit matrix)

การบวกลบเมตรกซ เมตรกซ 2 เมตรกซ จะบวกลบกนไดกตอเมอมขนาดเทากน การบวกลบใหนาสมาชกท

ตาแหนงเดยวกนบวกลบกนแบบพชคณต ตวอยางการบวกเมตรกซ เชน

3 1 0

2 5 3

2 1 3

4 1 1

5 0 3

6 6 2−+

−=

ตวอยางการลบเมตรกซ

3 1 0

2 5 3

2 1 3

4 1 1

1 2 3

2 4 4−−

−=

−− −

Page 398: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

391

การคณเมตรกซดวยเมตรกซ เมตรกซ A คณกบเมตรกซ B (AB) ไดกตอเมอจานวนสดมภของเมตรกซ A เทากบ

จานวนแถวของเมตรกซ B

ถา A เปนเมตรกซขนาด m × n และ B เปนเมตรกซขนาด n × p เมตรกซทเกดจากผล

คณของ A คณ B จะมขนาดเทากบ m × p

ตวอยางการคณเมตรกซ

1 1 2

0 3 4

2 5 1

2 0

1 3

1 1

2 1 2 0 3 2

0 3 4 0 9 4

4 5 1 0 15 1

5 1

1 13

10 14

− −− =

+ + − +− + + +

− − − + −=

จากตวอยางน ถาสลบทการคณเมตรกซ จะไมมความหมาย เพราะไมสามารถคณ

เมตรกซขนาด 3 × 2 กบ 3 × 3 ได ถาเมตรกซทงสองเปนเมตรกซจตรส ผลลพธของ AB จะไม

เทากบ BA

การทรานสโพส เมตรกซ ถาเปลยนแถวของเมตรกซ A ใหเปนสดมภ และเปลยนสดมภของเมตรกซ A ใหเปนแถว

เรยกวธการเชนนวา ทรานโพสเมตรกซ ใชสญลกษณ AT

ตวอยางเชน

A =−3 6 1

2 0 5 A

3 2

6 0

1 5

T =−

ตวกาหนดหรอดเทอรมแนนต (Determinant)

ประกอบดวยขอมลหรอสมาชกทอยในรปตารางจตรส การหาดเทอรมแนนทมวธการ

เฉพาะ ดเทอรมแนนททมอนดบ (order) เทากบสอง เขยนไดดงน

a a

a a11 12

21 22

= a11 a22 - a12 a21

Page 399: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

392

คาดเทอรมแนนต คอ a11 a22 - a12 a21 เมตรกซทสอดคลองกบดเทอรมแนนตดงกลาว

เขยนไดเปน

Aa a

a a11 12

21 22

=

ดเทอรมแนนตของเมตรกซ A ปกตจะเขยนเปน |A| อานวา det A

สมบตของดเทอรมแนนตมดงตอไปน

1. ถาสลบแถว (หรอสดมภ) 2 แถว (สดมภ) คาดเทอรมแนนตจะเปลยนจาก |A|

เปน -|A|

2. ถาทรานสโพสเมตรกซจตรส คาดเทอรมแนนตจะไมเปลยน

3. ถามสมาชก 2 แถว (หรอสดมภ) เหมอนกนทกประการ หรอเปนจานวนเทา

ของอกแถว(สดมภ)หนง จะไดดเทอรมแนนตของเมตรกซนมคาเปนศนย

4. ถาสมาชกในแถวใด (หรอสดมภใด) มตวประกอบรวม สามารถนาตวประกอบ

รวมออกนอกดเทอรมแนนตนนได

a b c

ka kb kc

a b c

k

a b c

a b c

a b c

1 1 1

2 2 3

3 3 3

1 1 1

2 2 3

3 3 3

=

5. สามารถนาสมาชกในแถวหนงไปบวกหรอลบกบสมาชกอกแถวหนงได โดยท

คาดเทอรมแนนตจะไมเปลยนแปลง (สามาถทาเชนเดยวกนนกบสดมภ)

a b c

a b c

a b c

a ka b kb c kc

a b c

a b c

1 1 1

2 2 3

3 3 3

1 2 1 2 1 2

2 2 3

3 3 3

=+ + +

การหาดเทอรมแนนตในโปรแกรม matrix.c จะใชสมบตขอท 5 น โดยจะเปลยน

ดเทอรมแนนตใหอยในรปสามเหลยมดานบน (upper triangular) เรยกวธนวาเปนวธลดทอนของ

เกาส สามารถนาวธนไปหาคาตอบระบบสมการเชงเสนไดอกดวย (ดบทท 3 )

Page 400: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

393

ตวอยาง จงหาดเทอรมแนนตของเมตรกซตอไปน

1 1 3

0 2 5

2 1 6

วธทา ใชวธลดทอนของเกาส

1. นา 2 คณแถวท 1 แลวนาไปบวกกบแถวท 3

1 1 3

0 2 5

0 1 12

2. นา 1/2 คณแถวท 2 แลวนาไปบวกกบแถวท 3

1 1 3

0 2 5

0 0 29 / 2

3. ขณะนเมตรกซเปนเมตรกซสามเหลยมบน ดเทอรมแนนตหาไดจากการนาสมาชกใน

แนวเสนทะแยงมมทงหมดคณกน จะไดคาตอบเทากบ 1 × 2 × 29/2 = 29

การหาเมตรกซผกผน ถา A เปนเมตรกซจตรส สามารถหาเมตรกซ B ททาให

AB = I = BA

เมอ I คอเมตรกซหนวย เราเรยกวา B เปนเมตรกซผกผนของ A เขยนเปนสญลกษณ A-1

ตวอยาง จงหาเมตรกซผกผนของเมตรกซตอไปน

2 3 1

0 1 1

1 2 1

Page 401: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

394

วธทา 1. เขยนเมตรกซหนวยไวดานขวามอของเมตรกซทตองการหาเมตรกซผกผน

2 3 1

0 1 1

1 2 1

1 0 0

0 1 0

0 0 1

2. ใชวธลดทอนของเกาส ทาเมตรกซดานซายมอใหอยในรปเมตรกซหนวย ผลลพธทเกด

ขนกบเมตรกซหนวยดานขวามอจะเปนเมตรกซผกผน

นา 1/2 คณแถวท 1 แลวนาไปบวกกบแถวท 3

2 3 1

0 1 1

0 7 / 2 1 / 2

1 0 0

0 1 0

1 / 2 0 1

นา 7/2 คณแถวท 2 แลวนาไปบวกกบแถวท 3

2 3 1

0 1 1

0 0 3

1 0 0

0 1 0

1 / 2 7 / 2 1

− −

ทาเมตรกซดานซายมอใหเปนเมตรกซทะแยงมม (diagonal matrix)

นา -1/3 คณแถวท 3 แลวนาไปบวกกบแถวท 1

นา 1/3 คณแถวท 3 แลวนาไปบวกกบแถวท 2

2 3 0

0 1 0

0 0 3

5 6 7 6 1 3

1 6 1 6 1 3

1 2 7 2 1−

−−−

/ / /

/ / /

/ /

นา -3 คณแถวท 2 แลวนาไปบวกกบแถวท 1

2 0 0

0 1 0

0 0 3

2 6 10 6 8 3

1 6 1 6 1 3

1 2 7 2 1−

−−−

/ / /

/ / /

/ /

Page 402: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

395

ทาเมตรกซดานซายมอใหเปนเมตรกซหนวย โดยนา 2 หารสมาชกในแถวท 1 ทกตวและ

นา -3 หารสมาชกในแถวท 3 ทกตว

1 3 0

0 1 0

0 0 1

1 6 5 6 4 6

1 6 1 6 2 6

1 6 7 6 2 6

/ / /

/ / /

/ / /

−−

− −

เมตรกซดานขวามอจะปนเมตรกซผกผนทตองการ ในโปรแกรม Matrix.C ตรงสวนการ

หาเมตรกซผกผน สามารถแสดงผลแตละขนตอนบนจอภาพ โดยตดสวนทเปน comment ออก

จากตรงจดทตองการจะแสดงผลบนจอภาพ

รายละเอยดของโปรแกรม Matrix.C มดงน

/** Program Matrix.C

* Purpose: Subroutine for matrix operation.

* Author : Wachara Rodsumrid.

* Language: Turbo C v.2.0 * Date : Sept 1996.

**************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <alloc.h>

#include <math.h>

#include <conio.h>

typedef struct {

int row;

int col;

double *element;

} matrix_type;

typedef matrix_type* MATRIX; /* address of matrix */

MATRIX matrix_initialize( int,int);

int matrix_free( MATRIX );

int matrix_kbd_input(MATRIX);

MATRIX matrix_add( MATRIX , MATRIX );

MATRIX matrix_substraction( MATRIX , MATRIX );

MATRIX matrix_mul(MATRIX, MATRIX);

MATRIX matrix_transpose(MATRIX);

double matrix_determinant(MATRIX );

Page 403: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

396

MATRIX matrix_inverse(MATRIX );

void matrix_print(MATRIX);

int matrix_kbd_input(MATRIX A)

{

int i,j;

char *buffer;

if(A->row == 0 || A->row > 50 || A->col == 0 || A->col >50){

fprintf(stderr, "Your matrix is out of limit.\n");

return 1;

}

for(i=0; i < A->row; i++) {

for (j=0; j < A->col; j++) {

printf("Element[%d,%d] = ",i+1,j+1);gets(buffer);

A->element[i*A->col+j] = atof(buffer);

} printf("\n");

} return 0;

}

void matrix_print(MATRIX a)

{

int i,j;

for(i = 0; i < a->row; i++){

for (j = 0; j < a->col; j++) {

printf("%8.3f",a->element[i*(a->col)+j]);

} printf("\n");

}

}

MATRIX matrix_initialize( int row, int col)

{ /* Allocate memory for a matrix, and fill zero to all of elements.

Normally, return address of matrix_type.

return NULL if insufficient memory. */

int i,j;

MATRIX mat;

if (( mat = (matrix_type*)malloc(sizeof(matrix_type)))==NULL)

return(NULL);

for (i=0; i < row; i++){

if((*((&mat->element)+i)=(double*)malloc(sizeof(double)*col))== NULL)

Page 404: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

397

return(NULL);

}

mat->row = row; mat->col = col;

for(i = 0; i < row ; i++ )

for (j = 0; j <col ;j++)

mat->element[i*col +j] = 0.0;

return mat;

}

int matrix_free( MATRIX A)

{int i,j,r,c;

if (A == NULL) {

fprintf(stderr,"This Matrix has been freed already.\n");return(1);

}free ((char*)A);

return(0);

}

MATRIX matrix_add( MATRIX a, MATRIX b)

{ /* Matrix addition, a and b are compatable matrice.

Return Null if there is something error. Return address of matrix c, if ok. */

MATRIX temp;

int i,j, row,col;

row = a->row; col = a->col;

if (row != b->row || col != b->col){

fprintf(stderr,"It must be square matrice\n");return NULL;}

if((temp = matrix_initialize(row,col))==NULL) {

fprintf(stderr,"Insufficient memory\n");return NULL; }

for( i= 0; i <row; i++)

for (j =0; j <col; j++)

temp->element[i*col+j] = a->element[i*col+j] + b->element[i*col+j];

return temp;

}

MATRIX matrix_substraction( MATRIX a, MATRIX b)

{ /* Matrix substraction, a and b are compatable matrice.

Return Null if there is something error. Return address of matrix c, if ok. */

MATRIX temp;

int i,j, row,col;

row = a->row; col = a->col;

Page 405: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

398

if ((row != b->row)||(col!=b->col)){

fprintf(stderr,"It must be square matrice.\n");return NULL;

}

if((temp = matrix_initialize(row,col))==NULL) {

fprintf(stderr,"Insufficient memory\n");return NULL;}

for( i= 0; i <row; i++)

for (j =0; j <col; j++)

temp->element[i*col+j] = a->element[i*col+j] - b->element[i*col+j];

return temp;

}

MATRIX matrix_mul( MATRIX A, MATRIX B)

{ /* Matrix multiplication, The column of matrix A must equal to

the row of matrix B . Return Null if there is something error.

Return address of matrix c, if ok. */

MATRIX temp;

int i,j,k;

int rowA,rowB,colB,colA;

rowA = A->row; colA = A->col;rowB = B->row;colB = B->col;

if (colA != rowB) return NULL;

if((temp = matrix_initialize(rowA,colB))==NULL) {

fprintf(stderr,"Insufficient Memory\n");return NULL;}

for( i= 0; i <rowA; i++)

for (j =0; j <colB; j++)

for (k = 0; k < colA;k++)

temp->element[i*colB+j] += A->element[i*colA+k] * B-

>element[k*colB +j];

return temp;

}

MATRIX matrix_transpose( MATRIX A)

{ /* Matrix A is a matrix to be tranposed.

Return an address of transposed matrix. */

int i,j;

MATRIX temp;

if((temp = matrix_initialize(A->col,A->row))== NULL){

fprintf(stderr,"Memory not enough\n");return NULL;

}

Page 406: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

399

for (i = 0; i < A->row; i++)

for (j=0; j < A->col; j++)

temp->element[j*A->row +i] = A->element[i*A->col+j];

return temp;

}

double matrix_determinant(MATRIX A)

{/* Return :

0 -- No error detected.

1 -- not square matrix.

2 -- Coefficeint Matrix is singular.*/

int dim;

int i,j, row,col,pivot;

int ir,jc;

double tmp = 0, det = 1.0, multiplier =0.0;

if (A->row != A->col) {fprintf(stderr," They're not square matrice.\n");

return (double)NULL;}

dim = A->row;

for (i=0; i < dim-1; i++) {

pivot = i;

/* Check the maximum element in the same column */

for (j = i+1; j < dim; j++)

if (fabs(A->element[pivot*dim+i]) < fabs(A->element[j*dim+i]))

pivot=j;

/* Pivoting */

if (pivot != i) {

for (j =0;j < dim; j++) {

tmp = A->element[i*dim+j];

A->element[i*dim+j] = A->element[pivot*dim+j];

A->element[pivot*dim+j] = tmp;

}

det = -det;

}

if (A->element[i*dim+i] == 0) {

fprintf(stderr,"Singular matrix\n");

return (double)NULL; /* singular matrix */

}

Page 407: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

400

/* make an upper triangular matrix */

for ( row = i+1;row < dim; row++) {

if(A->element[row*dim+i] != 0 ) {

multiplier= A->element[row*dim+i]/(A->element[i*dim+i]);

for ( col= 0;col < dim; col++) {

A->element[row*dim+col] = A->element[row*dim+col]-\

multiplier*A->element[i*dim+col];

if (fabs(A->element[row*dim+col]) <= 2*2.0e-16)

A->element[row*dim+col] = 0;

}

} /* if */

} /* for ( row....) */

matrix_print(A); getch(); printf("\n");

} /* for ( i....) */

for (i = 0; i < dim; i++ )

det *= A->element[i*dim+i];

return det;

}

MATRIX matrix_inverse(MATRIX A)

{

int i,j,row,col,pivot,dim,twodim;

double temp=0,multiplier=0;

double *dummy;

MATRIX t;

/* Return: 0 -- if no error.

1 -- dimension < 1

2 -- coefficeint matrix is singular.*/

if (A->row != A->col) {

fprintf(stderr," Matrice must be the same size.\n"); return NULL;

}

dim = A->row; twodim = 2*dim;

/* allocate memory for dummy matrix */

if((dummy = (double*)calloc(dim*twodim,sizeof(double)))==NULL)

{

fprintf(stderr,"Insufficient memory\n");return NULL;}

for( i = 0; i < dim; i++){

Page 408: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

401

for (j=0; j < dim; j++) {

dummy[i*twodim+j] = A->element[i*dim+j];

}

}

for( i= 0; i < dim; i++) {

for (j=dim; j < twodim; j++){

if ( (j - i) == dim) dummy[i*twodim+j] = 1.0;

else dummy[i*dim*2+j]= 0;

}

}

/* print dummy matrix size dim x 2dim */

for (i = 0; i < dim; i++ ) {

for (j = 0; j < twodim ; j++ ){

printf (" %8.3f ", dummy[i*twodim+j]);

if ( j == dim-1) printf("|");

}

printf("\n");

}

if ( dim < 1 || dim > 51) {

fprintf(stderr,"Marix size must greater than 1 and less than 50\n");

return NULL;

}

for (i=0; i < (dim-1); i++) {

pivot = i;

/* Check the maximum element in the same column */

for (j = i+1; j < dim; j++)

if (fabs(dummy[pivot*twodim+i]) < fabs(dummy[j*twodim+i])) pivot=j;

/* Pivoting */

if (pivot != i) {

for (j =0;j < (twodim); j++) {

temp = dummy[i*twodim+j];

dummy[i*twodim+j] = dummy[pivot*twodim+j];

dummy[pivot*twodim+j] = temp;

}

}

if (dummy[i*twodim+i] == 0) {

Page 409: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

402

fprintf(stderr, "Singular matrix\n"); return NULL; }

/* make an upper triangular matrix */

for ( row = i+1;row < dim; row++) {

if(dummy[row*twodim+i] != 0 ) {

multiplier= dummy[row*twodim+i]/dummy[i*twodim+i];

for(col = 0;col < (twodim);col++) {

dummy[row*twodim+col] =

dummy[row*twodim+col]- multiplier*dummy[i*twodim+col];

if (fabs(dummy[row*twodim+col]) <= 2*2.2e-16)

dummy[row*twodim+col] = 0;

}

} /* if */

} /* for ( row....) */

/*** In case of learning, you cas see the results step by step ****

printf("\nStep # %d\n",i);

printf("============\n");

for (row = 0; row < dim; row++) {

for (col = 0 ; col < twodim; col++) {

printf("%8.3f ",dummy[row*twodim+col]);

if( col == dim-1) printf("|");

}

printf("\n");

}

puts("Press any key .....");getch();

/* ****************************************************/

} /* for ( i....) */

/* Make a Matrix lower triangular */

for (i = dim-1; i > 0; i--) {

for ( row = i-1;row >= 0; row--) {

if(dummy[row*twodim+i] != 0 ) {

multiplier= dummy[row*twodim+i]/dummy[i*twodim+i];

for(col = i;col< (twodim);col++) {

dummy[row*twodim+col] =

dummy[row*twodim+col]-multiplier*dummy[i*twodim+col];

if (fabs(dummy[row*twodim+col]) <= 2*2.2e-16)

dummy[row*twodim+col] = 0;

Page 410: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

403

}

} /* if */

} /* for ( row....) */

/*** In case of learning, you can see the results step by step *****

printf ("\n make a matrix lower Triangular.");

printf("============\n");

for (row = 0; row < dim; row++) {

for (col = 0 ; col < twodim; col++) {

printf("%8.3f ",dummy[row*twodim+col]);

}

printf("\n");

}

puts("Press any key .....");getch();

/* *******************/

} /* for ( i....) */

/* Create Identity Matrix */

for ( i= dim-1 ; i >=0; i--) {

temp = dummy[i*twodim+i];

for (j = i; j < twodim; j++) {

dummy[i*twodim+j] /= temp;

}

printf ("\n make a Unit matrix .");

printf("============\n");

for (row = 0; row < dim; row++) {

for (col = 0 ; col < twodim; col++) {

printf("%8.3f ",dummy[row*twodim+col]);

}

printf("\n");

}

puts("Press any key .....");getch();

}/* for i */

if((t = matrix_initialize(dim,dim))== NULL){

fprintf(stderr,"Memory not enough\n");return NULL; }

for (i = 0; i < dim; i++)

for (j=0; j < dim; j++)

t->element[i*dim+j] = dummy[i*twodim+(j+dim)];

Page 411: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

404

free((char*)dummy);return t;

}

void main()

{

MATRIX a,b,c,d;

int i,j,err, row,col ;

char *buffer;

double det;

clrscr(); printf("Matrix A :\n");

row = 3; col = 3;

if ((a= matrix_initialize(row,col)) == NULL) exit(1);

a->element[0]=1; a->element[1]=-1; a->element[2]=3;

a->element[3]=0; a->element[4]=2; a->element[5]=5;

a->element[6]=-2; a->element[7]=1; a->element[8]=6;

matrix_print(a);

if((b=matrix_initialize(row,col))== NULL) exit(1);

b->element[0]=2; b->element[1]=3; b->element[2]=-1;

b->element[3]=0; b->element[4]=1; b->element[5]=1;

b->element[6]=-1; b->element[7]=2; b->element[8]=1;

if((c=matrix_initialize(row,col))== NULL) exit(1);

printf("\n\nAdding matrix A and B......\n");

c = matrix_add(a,b);

matrix_print(c);

printf("\n\nMatrix Multiplication, A and B...\n");

c = matrix_mul(a,b);

matrix_print(c);

printf ("\n\nNow inverse matrix B\n");

c = matrix_inverse(b);

if( c != NULL) { matrix_print(c); }

printf("\n\nFind determinant of matrix A..\n");

det = matrix_determinant(a);

if (det != (double)NULL)

printf ("Determinant of A = %8.3f\n ",det);

}

Page 412: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

ภาคผนวก 3 ฟงกชนทใชในงานคานวณเรยงตามลาดบตวอกษร

ฟงกชนเหลานเขยนดวยภาษา ซ วธการนาไปใชงาน และรายละเอยดของโปรแกรมดไดจากหนา

ทปรากฏในสารบญน

ชอฟงกชน การนาไปใชงาน หนา

Adams_Moulton หาคาตอบของสมการอนพนธโดยวธของอาดามส-มลตน 216

Bisection หารากสมการแบบไมเปนเชงเสนโดยวธแบงครงชวง 27

ClampedCubicSpline ประมาณคาในชวงโดยใชการสไปลนแบบบงคบทจดปลาย 277

DividedDifference ประมาณคาในชวงโดยใชผลตางถกหาร 36

FalsePosition หารากสมการแบบไมเปนเชงเสนโดยวธวางตาแหนงผดท 243

Find_z หาคา Z เมอบอกพนทใตเสนโคงปกต 352

FirstDerive_function หาอนพนธอนดบหนงของฟงกชนทกาหนดให 134

FirstDerive_tabular หาอนพนธอนดบหนงเมอบอกขอมลเปนตาราง 122

FreeCubicSpline ประมาณคาในชวงโดยใชการสไปลนแบบธรรมชาต 256

Gauss_Seidel หาผลเฉลยของระบบสมการเชงเสนโดยวธเกาส-ไซเดล 106

GaussElimination หาผลเฉลยของระบบสมการเชงเสนโดยวธลดทอนของเกาส 76

GaussJordan หาผลเฉลยของระบบสมการเชงเสนโดยวธเกาส-จดอง 80

GaussQuadrature อนทเกรตโดยวธของเกาส 155

get_system_time แสดงวน และเวลาของระบบคอมพวเตอร 334

LagrangeInterpolation ประมาณคาในชวงโดยใชพหนามลากรานจ 233

Linear_Multi_Regression หาสมการถดถอยแบบหลายเชง 280

LU_Decompose หาผลเฉลยของระบบสมการเชงเสนโดยวธทาใหเปนเมตรกซสามเหลยมลาง และบน

94

mean_deviation หาคาเฉลย และความเบยงเบนมาตรฐาน 338

ModifiedEuler หาคาตอบของสมการอนพนธโดยวธออยเลอรทปรบปรงแลว 195

MonteCarloIntegration อนทเกรตโดยวธมอนตคารโล 169

Newton_Raphson หารากสมการแบบไมเปนเชงเสนโดยวธนวตน-ราฟสน 46

NormalProbabilityIntegration หาพนทใตเสนโคงปกต 348

Page 413: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

406

ชอฟงกชน การนาไปใชงาน หนาPolynomial_Regression หาสมการถดถอยแบบเชงเสนและพหนาม 295

quick_sort เรยงลาดบตวเลขโดยวธควก ซอรต 323

Runge_Kutta4 หาคาตอบของสมการอนพนธอนดบหนงโดยวธรงเง-คตตา 201

Runge_Kutta4_2 หาคาตอบของสมการอนพนธอนดบสองโดยวธรงเง-คตตา 204

Scanroot ประมาณชวงของรากสมการแบบไมเปนเชงเสน 43

Secant หารากสมการแบบไมเปนเชงเสนโดยวธเซแคนต 57

Shell_sort เรยงลาดบตวเลขโดยวธของเชลล 326

Simpson1_3 อนทเกรตโดยวธซมพสน 1/3 146

Simpson3_8 อนทเกรตโดยวธซมพสน 3/8 146

time_diff จบเวลาการทางานของโปรแกรม 334

Trapezoidal อนทเกรตโดยแบงเปนพนทสเหลยมคางหม 145

Page 414: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

ภาคผนวก 4 การแสดงผลเปนภาษาไทยบนจอภาพ

ในการกรณทตองการแสดงผลเปนภาษาไทยบนจอภาพ จะตองสรางรปแบบตวอกษรไทย

(font)ขนเปนพเศษและเขยนโปรแกรมยอยหรอฟงกชนเพอนารปแบบตวอกษรนนไปแสดงผลบนจ

อภาพโปรแกรมแสดงผลภาษาไทยทเขยนไวนใชไดกบคอมพวเตอรทมจอภาพและการดแสดงผล

เปนแบบ VGA ใน mode กราฟก ระบบปฏบตการ DOS เทานน ไมสามารถใชกบจอโมโนโครม

หรอจอสชนด CGA

รปแบบตวอกษรจะมขนาด 8 × 20 จด หรอใชเนอท 20ไบตตอ1ตวอกษรอยในรปบตแมพ

(bitmap)มลกษณะรปแบบตวอกษรเหมอนเวรดจฬาเพอไมใหหนงสอเลมนหนาเกนไปผสนใจในร

ายละเอยดของรปแบบตวอกษรภาษาไทยและโปรแกรมยอยสามารถเปดดไดจากแผนดสกไดเรกท

อรยอยชอ mythai ฟงกชนทเกยวของกบการแสดงผลภาษาไทยมดงน

opengraph(void)ใชเปลยนmodeตวอกษรของจอภาพใหเปนกราฟก

จะตองใชฟงกชนนในตอนเรมตนของโปรแกรมการแสดงผลภาษาไทยเสมอ

set_location (int x, int y) กาหนดตาแหนงทจะเขยนตวอกษร x

คอตาแหนงในแนวแกน x y คอตาแหนงในแนวนอนหรอ แกน y

set_scalefactor (int MultX, int MultY) กาหนดขนาดตวอกษรทจะพมพ

โดยปกตจะมขนาด 8 × 20 จด สามารถขยายการแสดงผลใหเปนจานวนเทาของคาปกตนได

write_char (int x, int y,unsigned char ch) แสดงผลตวอกษร 1 ตว ตรงตาแหนง

x,y

write_str (char *str) แสดงขอความตรงตาแหนงทเคอเซอรกระพรบอย

write_str_xy (int x, int y, char *str) แสดงขอความบนจอภาพตรงตาแหนง x,y

get_str_xy (int x, int y, char buffer[ ]) เปน line editor

สามารถพมพและลบขอความภาษาไทยและองกฤษ ขอความทพมพจะถกเกบไวในตวแปร buffer

สามารถใชคาสง write_str_xy แสดงขอความใน buffer ได ปมทใชเปลยนตวอกษรไทย-องกฤษ

คอปม ` เหมอนกบทใชในระบบวนโดวภาษาไทย

ตวอยางโปรแกรมทเรยกใชฟงกชนทกลาวมาเพอแสดงผลภาษาไทย มดงน

/* TestThai.C

* Demonstrate how to display thai message on VGA monitor

* Author : Wachara Rodsumrid.

* Language: Turbo C. 2.0

Page 415: คํานวณและแก ป ญหาทางฟ สิกส ด วยโปรแกรมภาษา ซี · คํานํา ( เมื่อครั้งเผยแพร

408

* Notice : Use with VGA monitor only !!!

* Memor : I wrote this program in Edmonton city, Canada.

September 1994.

***********************************************/

#include <graphics.h>

#include <conio.h>

#include <stdio.h>

#include <stdlib.h>

#include <dos.h>

#include <ctype.h>

#include "thai.h"

void main (void) {

int i;

char buff[255];

opengraph();

set_scalefactor(3,3);

setcolor(5);

write_str_xy(10,40,"แสดงผลภาษาไทยและ English");

set_scalefactor(1,1);

setcolor(9);

write_str_xy(10,130, "โปรดปอนขอความ ใชปม ` เปลยน mode

ไทย- องกฤษ");

setcolor(3);

get_str_xy(10,150,buff);

set_scalefactor(2,2);

setcolor(12);

write_str_xy(10,300,buff);

getch();

closegraph();

}