Mar 23, 2016

ใบเฟิร์น Barnsley

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


การสร้าง fractal รูปใบเฟิร์นอย่างง่าย สามารถอธิบายคร่าวๆ ได้ด้วยขั้นตอนวิธีนี้


  1. ลากเส้นตรงความยาว $l$ ไม่ต้องเยอะมากนัก แล้วเลือกปลายข้างหนึ่งไว้เป็นปลายที่จะต่อยอดออกไป
  2. ที่ปลายยอดของเส้นตั้งต้น ทำสองขั้นตอนต่อไปนี้เพื่อลากเส้นเพิ่ม 3 เส้น
    • ลากเส้นตรงความยาว $0.2$ เท่าของความยาวเส้นตั้งต้น ในทิศทางตั้งฉากกับเส้นตั้งต้นทั้งสองข้าง
    • ลากเส้นตรงความยาว $0.8$ เท่าของความยาวเส้นตั้งต้น ในทิศทางต่อขึ้นไปตรงๆ จากเส้นตั้งต้น
  3. สำหรับแต่ละเส้นที่ลากต่อออกมาในข้อ 2 นั้น เลือกปลายด้านที่ว่างๆ ไว้เป็นปลายต่อยอด แล้ววนกลับไปทำขั้นตอนที่ 2 โดยเปลี่ยนมาใช้เส้นตั้งต้นเป็นเส้นที่ได้จากข้อ 2 แทน (คิดซะว่าเส้นใหม่นี้ยาว $l$) ทำไปเรื่อยๆ จนกว่าจะพอใจผลลัพธ์

วิธีการข้างต้นจะให้ผลลัพธ์เป็นรูปใบเฟิร์นเรียบๆ ตรงๆ ไม่หวือหวานัก แต่ก็มีนักคณิตศาสตร์นามว่า Michael Barnsley ได้เขียนสมการกำหนดมุมและจัดตำแหน่งของการต่อยอดให้สวยงามมีลูกเล่น เนื่องจากเขาเป็นคนแรกที่เขียนเรื่องนี้ไว้ตั้งแต่ปี 1993 ทุกคนเลยพากันเรียกใบเฟิร์นที่สวยงามเป็นเอกลักษณ์นี้ว่า ใบเฟิร์น Barnsley



พูดให้รัดกุมเป็นภาษาคณิตศาสตร์ก็คือ การสร้างใบเฟิร์น Barnsley เริ่มจากลากเส้นแรกยาว $1.6$ หน่วยจากจุด $(0,0)$ ขึ้นไปตามแกน $y$ แล้วเอาเส้นนั้นมาวาดซ้ำๆ อีกครั้ง จากเลื่อนและปรับขนาดด้วยสมการดังนี้


f_1(x, y) = [ 0.85, 0.04; -0.04, 0.85 ] [ x; y ] + [ 0; 1.6 ]
f_2(x, y) = [ 0.20 & -0.26 \\ 0.23 & 0.22 ] [ x; y ] + [ 0; 1.6 ]
f_3(x, y) = [ -0.15, 0.28; 0.26 & 0.24 ] [ x; y ] + [ 0; 0.44 ]

โดย $f_1, f_2, f_3$ คือสมการสำหรับคำนวณรูปร่างก้านที่ต่อยอดขึ้นข้างบน ก้านที่เอียงไปด้านซ้าย และก้านที่พลิกตัวแล้วเอียงไปด้านขวา ตามลำดับ


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


from PIL import Image, ImageDraw

def transform(matrix, xy):
    return [sum(e * p for e, p in zip(row, xy)) for row in matrix]

def translate(vector, xy):
    return [e + p for e, p in zip(vector, xy)]

class BarnsleyFern(object):
    affines = [([[0.85, 0.04], [-0.04, 0.85]], [0, 1.6]),
               ([[0.20, -0.26], [0.23, 0.22]], [0, 1.6]),
               ([[-0.15, 0.28], [0.26, 0.24]], [0, 0.44])]

    def __init__(self, depth=10, size=(800,800)):
        self.image = Image.new('RGB', size)
        self.draw = ImageDraw.Draw(self.image)
        self.iterate([0.0, 0.0], [0.0, 1.6], depth)

    def canvas_coordinate(self, xy):
        width, height = self.image.size
        return [width/2 + xy[0]*width/10, height - xy[1]*height/10]

    def linespec(self, xy0, xy1):
        return self.canvas_coordinate(xy0) + self.canvas_coordinate(xy1)

    def draw_too_small(self, xy0, xy1, pos=2):
        return all(round(a, pos) == round(b, pos) for a, b in zip(xy0, xy1))

    def iterate(self, xy0, xy1, depth, affine=None):
        if depth == 0:
            return
        if affine is not None:
            xy0 = translate(affine[1], transform(affine[0], xy0))
            xy1 = translate(affine[1], transform(affine[0], xy1))
        if self.draw_too_small(xy0, xy1):
            return
        self.draw.line(self.linespec(xy0, xy1), fill='#0C3')
        for affine in self.affines:
            self.iterate(xy0, xy1, depth-1, affine)



fractal ยังมีรูปร่างอื่นๆ อีกมากมาย ทั้งที่พบได้ในธรรมชาติ เช่น ดอกทานตะวัน บรอคโคลี เกล็ดหิมะ หรือมากจากการสังเคราะห์ขึ้นอย่าง สามเหลี่ยม Sierpinski หรือ เซ็ต Mandelbrot


แต่ความมหัศจรรย์ของ fractal ที่แท้จริง คือเราไม่สามารถรู้ได้เลยว่าตอนนี้เรากำลังอยู่ตรงไหนของมันกันแน่ ลองคิดภาพว่าตัวเองเป็น Ant-Man ที่จะปรับขนาดตัวให้ไม่ใหญ่ไปกว่าก้านใบเฟิร์นที่ยืนอยู่ได้ แล้วก็ลองไปยืนอยู่บนใบเฟิร์นข้างต้นดู ณ ขณะหนึ่งเราอาจจะคิดว่าตัวเองอยู่บนก้านที่ใหญ่ที่สุดแล้ว แต่นอกจากขนาดที่แตกต่างกัน ก้านที่เราคิดว่าใหญ่ที่สุดนั้น ก็ไม่ได้มีอะไรที่แตกต่างจากก้านย่อยก้านอื่นๆ เลย หากเราเดินย้อนกลับไปเรื่อยๆ อาจพบว่าก้านที่เราคิดว่าใหญ่ที่สุดนั้น เป็นเพียงแค่ก้านย่อยที่แตกแขนงแยกออกมาก็เป็นได้


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


ก็เปรียบเหมือนความรู้ เราจะรู้ได้ไงว่าอะไรคือพื้นฐานที่แท้จริงกันแน พันปีก่อนเราอาจคิดว่าถ้าได้รู้จักอะตอมก็คือรู้ถึงพื้นฐานแห่งทุกสรรพสิ่งแล้ว แต่ไม่กี่ร้อยปีก่อนเราเพิ่งพบว่าอะตอมยังแบ่งแยกย้อยลงไปได้อีกเป็นโปรตอน นิวตรอน อิเล็กตรอน และปฏิรูปพื้นฐานความรู้ด้านเคมีขึ้นใหม่ ส่วนปัจจุบันเรายังแบ่งย่อยสิ่งต่างๆ ลงไปได้อีกเป็นควาร์ก หรือแม้กระทั่งเสนอทฤษฎีสตริงซึ่งเป็นพื้นฐานของทุกอนุภาค


อีกนัยหนึ่ง พื้นฐานความรู้ที่ลึกเกินไปอาจเป็นสิ่งไม่จำเป็น หรือยิ่งไปกว่านั้น มันอาจเป็นตัวถ่วงให้เราไม่กล้าที่จะเดินหน้าสำรวจโลกใหม่ๆ ก็เป็นได้


Mar 14, 2016

มองสมการแล้วรู้สึกเป็นยาขม มองให้เห็นเป็นภาพสิจะได้สนุก

ตอนอยู่ม.ปลาย NutSnC เคยให้หนังสือ Proof Without Words มา คือตอนนั้นเรามองว่าคณิตศาสตร์สนุกอยู่แล้ว แต่พอได้เล่มนี้มาอ่านยิ่งรู้สึกสนุกเข้าไปใหญ่ เลยคิดว่ามันน่าจะช่วยให้ใครที่คิดว่าคณิตศาสตร์ไม่สนุก รู้สึกสนุกไปกับมันได้บ้าง

แนวคิดง่ายๆ ของหนังสือคือโยนสมการที่มีแต่ตัวหนังสือยั๊วเยี๊ยะทิ้งไปเลย แล้วเปลี่ยนมาคิดมันด้วยสิ่งที่จับต้องได้มาขึ้นอย่างรูปภาพแทน



ตัวอย่างหนึ่งในหนังสือ เช่น ต้องการพิสูจน์อนุกรมจำนวนเต็ม

1 + 2 + 3 + ... + n = n(n+1)/2

ก็ให้คิดด้วยลูกแก้วแทน ลูกแก้วแถวแรกมี 1 ลูก แถวที่สองมี 2 ลูก ลงไปเรื่อยๆ จนแถวสุดท้ายที่มี n ลูก

ถ้าจัดตำแหน่งลูกแก้วอย่างสวยๆ จะได้ว่ามันเป็นรูปสามเหลี่ยมนั่นเอง ดังนั้นพอเอาสามเหลี่ยมสองชุดมาประกบกันก็จะได้สี่เหลี่ยม ซึ่งก็ง่ายแล้วเพราะตอนนี้แค่หาพื้นที่ก็ได้คำตอบ


แต่ลองให้ใช้สมการอย่างเดียวอธิบายดู จะพบกับความยาวเฟื้อยเช่นนี้

sum  i  for i=1 to n = 1 + 2 + 3 + ... + n
    2 sum  i  for i=1 to n = 2(1 + 2 + 3 + ... + n)
                           = (1 + 2 + 3 + ... + n) + (1 + 2 + 3 + ... + n)
                           = (1 + 2 + 3 + ... + n) + (n + ... + 3 + 2 + 1)
                           = (1+n) + (2+n-1) + (3+n-2) + ... + (n+1)
                           = (n+1) + (n+1) + (n+1) ... + (n+1)
                           = n(n+1)
      sum  i  for i=1 to n = n(n+1)/2

เทียบกันแล้ว การพิสูจน์ด้วยรูปภาพง่ายและสวยงามกว่ากันเยอะเลย



วิธีข้างต้นยังนำไปประยุกต์ใช้กับสมการอื่นๆ ได้อีกมากมาย เช่น

  • อนุกรมจำนวนเต็มคี่
  • อนุกรมจำนวนเต็มยกกำลังสอง
  • อนุกรมจำนวนเต็มยกกำลังสาม
  • อนุกรมเรขาคณิต

ฝากไว้เป็นการบ้านให้ลองกลับไปวาดรูปเล่นกันดูครับ :3

Mar 8, 2016

มาขีดเขียนหนังสือกันเถอะ!

จั่วหัวไว้อย่างนี้ ไม่ได้หมายความว่าผมจะมาชวนเปลี่ยนกระดาษว่างๆ ให้เป็นหนังสือเล่มหนึ่งนะครับ :P

แต่ต้องการจะสื่อว่า เวลาที่หยิบหนังสือที่มีขึ้นมาอ่าน เรามาขีดเขียนเพิ่มเติมรูปภาพ/ข้อความส่วนตัวลงไปในหนังสือเล่มนั้นกันเถอะ!

เหตุผลที่ควรขีดเขียนหนังสือ

  • เพื่อจดบันทึกว่า ตัวเองในขณะนั้นกำลังคิดอะไรอยู่
  • เพื่อแบ่งบันกับพื่อนนักอ่านว่า เราได้ตกผลึกอะไรบ้างตอนที่อ่านถึงตรงนั้น
  • หนังสือไม่ใช่พระเจ้า หนังสือเป็นแค่สื่อเพื่อเผยแพร่ความคิด ไม่ต้องถึงขั้นกราบไหว้บูชาดูแลรักษาไม่ให้มีความด่างพร้อยก็ได้



พูดแล้วผมก็นึกถึงหนังสือสามก๊ก ฉบับเจ้าพระยาพระคลัง (หน) ที่ขายเป็นกล่องรวมเล่มสีทองๆ สวยงามครับ ถ้าซื้อรุ่นที่พิมพ์ครั้งหลังๆ หน่อย นอกจากจะได้หนังสือหนาๆ สามเล่มที่เป็นเนื้อเรื่องในสามก๊กแล้ว ยังจะได้หนังสือเล่มบางเพิ่มขึ้นอีกหนึ่งเล่ม เล่าถึงประวัติการแปลหนังสือสามก๊กชุดนี้เป็นภาษาไทย

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

แน่นอนว่าการแสดงความเห็น-ถกเถียง-อภิปรายแบบนี้ ปัจจุบันคงหาได้ไม่ยากตามกระทู้ออนไลน์ (และก็น่าจะรับประกันได้ว่าผู้เขียนบันทึกคนแรก มีสิทธิ์กลับมาอ่านสูงกว่าการบันทึกลงหนังสือด้วย) แต่การขีดเขียนหนังสือตรงๆ ก็ยังคงมีเสน่ห์ของมันอย่างไม่สิ่งอื่นทดแทนได้ เช่น ทฤษฎีบทสุดท้ายของแฟร์มา ที่เขากล่าวติดตลกขณะกำลังอ่านหนังสือคณิตศาสตร์ตอนหนึ่งว่า "ฉันพบวิธีพิสูจน์[ทฤษฎีบท]อันแสนอัศจรรย์แล้ว ติดที่ว่าขอบกระดาษนี้กว้างไม่พอที่จะจดลงไป" (I have discovered a truly marvellous proof of this, which this margin is too narrow to contain.)



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

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

ส่วนถ้าใครตัดสินใจจะลองทำตามแล้ว ก็ดูด้วยนะครับว่าเจ้าของหนังสือยินยอมหรือเปล่า ไม่งั้นเดี๋ยวมีเรื่องจะหาว่าไม่เตือนนะ :p