วาดกราฟ exponential sums

พอดีว่าไปเห็นกราฟที่วาดจาก Exponential sums จากเวบ https://www.maths.unsw.edu.au/about/exponential-sums แล้วดูว่าสวยดีเลยอยากลองทำดูบ้างด้วย Mathematica

การวาดกราฟจาก exponential sums หรือที่เขียนอยู่ในรูปแบบ \sum_{n=1}^N e^{2\pi if(n)} ที่ทำนี้ก็คือถ้าเราค่อยๆบวกเข้าไปทีละเทอมและเอาค่าที่ได้มาพล็อตกราฟใน complex plane โดยที่แกนนอนคือจำนวนจริงและแกนตั้งคือจำนวนจินตภาพ ลองดูที่โค้ดน่าจะเข้าใจมากขึ้นครับ

fn[n_] := Log[n]^4
NP = 5000;
ls = Accumulate[Table[Exp[2 \[Pi] I fn[n]] // N, {n, 1, NP}]];
Manipulate[
 ListPlot[{Re@#, Im@#}\[Transpose] &@(ls[[1 ;; np]]), Joined -> True, 
  AspectRatio -> Full, PlotStyle -> Black, 
  PlotRange -> {{-5, 70}, {-60, 20}}]
 ,
 {np, 1, NP, 1, Appearance -> "Labeled"}]

 

fn[n_] := n/dd + n^2/mm + n^3/yy /. {dd -> 23, mm -> 11, yy -> 78}
NP = 10000;
ls = Accumulate[Table[Exp[2 \[Pi] I fn[n]] // N, {n, 1, NP}]];
Manipulate[
 ListPlot[{Re@#, Im@#}\[Transpose] &@(ls[[1 ;; np]]), Joined -> True, 
  AspectRatio -> Full, PlotStyle -> Black]
 ,
 {np, 3, NP, 1}]

 

 

 

 

มาลองทำให้โค้ดMathematicaรันเร็วขึ้น

โค้ดที่เขียนด้วยMathematicaหรือภาษา Wolfram นั้นมันจะมีวิธีที่ช่วยให้มันรันได้เร็วขึ้นอยู่หลายวิธีครับ ขึ้นกับปัญหาและวิธีการเขียน ที่จะโชว์ให้ดูนี้ผมก็ใช้เทคนิคง่ายๆด้วยการทำ parallel ด้วยคำสั่ง ParallelTable และ compile ด้วยคำสั่ง Compile ครับ  โค้ดตัวอย่างที่จะเอามาลองนี้เป็นโค้ดที่ใช้วาดรูป Mandelbrot set ครับ

แบบที่ 1 เป็นโค้ดเริ่มต้นที่ยังไม่มีการทำให้มันเร็วครับเขียนโดยใช้ loop จากคำสั่ง Table

AbsoluteTiming[
 test1 = Block[{i, x, p}, 
    Table[i = 0; x = 0. I; p = r + I c; 
     While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
     Tanh[Power[i/9^3, (7)^-1]], {c, -1, 1, .01}, {r, -2, 1, .01}]];]

(* เวลาที่ใช้คือ 77.4437 วินาที *)

แบบที่ 2 ในแบบนี้ผมทดลองให้มันรันแบบขนานโดยใช้คำสั่ง ParallelTable เครื่องที่ผมใช้นี้มันมี 4 cores ครับ เวลาก็ลดลง ถ้าคิดง่ายๆก็ใช้เวลาเหลือเกือบๆ 1 ใน 4

AbsoluteTiming[
 test2 = Block[{i, x, p}, 
    ParallelTable[i = 0; x = 0. I; p = r + I c; 
     While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
     Tanh[Power[i/9^3, (7)^-1]], {c, -1, 1, .01}, {r, -2, 1, .01}]];]

(* เวลาที่ใช้คือ 23.8938 วินาที *)

แบบที่ 3  แบบนี้ก็คือเอาแบบที่ 1 มา compile เป็น binary code ด้วยคำสั่ง Compile เวลาก็เร็วขึ้นอย่างเห็นได้ชัด

test3 = Compile[{}, 
  Block[{i, x, p}, 
   Table[i = 0; x = 0. I; p = r + I c; 
    While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
    Tanh[Power[i/9^3, (7)^-1]], {c, -1, 1, .01}, {r, -2, 1, .01}]]]

AbsoluteTiming[test3[];]

(* เวลาที่ใช้คือ 2.68316 วินาที *)

แบบที่ 4  แบบนี้ก็คือแบบที่ 3 ที่เอามารันแบบขนานด้วยคำสั่ง ParallelTable ซึ่งเวลาที่ใช้ก็เร็วขึ้นอีกกว่าแบบที่ 3

test4 = Compile[{{c, _Real}, {r, _Real}},
   Module[{i, x, p},
    i = 0; x = 0. I; p = r + I c; 
    While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
    Tanh[Power[i/9^3, (7)^-1]]
    ]
   ];

ParallelTable[
   test4[c, r], {c, -1, 1, .01}, {r, -2, 1, .01}]; // AbsoluteTiming

(* เวลาที่ใช้คือ 1.04455 วินาที *)

แบบที่ 5 แบบนี้เหมือนกับแบบที่ 4 แต่แทนที่จะให้มัน compile เป็น binary code โดย Mathematica เอง ก็ให้มันแปลงเป็นภาษา C ด้วย option CompilationTarget -> “C” เลยโดยใช้ compiler อย่าง gcc ครับ เวลาก็เร็วขึ้นอีกประมาณ 60% จากแบบที่ 4 ครับ

Needs["CCompilerDriver`GenericCCompiler`"]

$CCompiler = {"Compiler" -> GenericCCompiler, 
   "CompilerInstallation" -> "C:/Rtools/mingw_64", 
   "CompilerName" -> "x86_64-w64-mingw32-gcc.exe"};


test5 = Compile[{{c, _Real}, {r, _Real}},
   Module[{i, x, p},
    i = 0; x = 0. I; p = r + I c; 
    While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
    Tanh[Power[i/9^3, (7)^-1]]
    ], CompilationTarget -> "C"];

ParallelTable[
   test5[c, r], {c, -1, 1, .01}, {r, -2, 1, .01}]; // AbsoluteTiming

(* เวลาที่ใช้ 0.393584 วินาที *)

 

external packages / tools / resources ของ Mathematica ที่สนใจ

แนะนำ Link นี้ครับสำหรับผู้สนใจใช้งาน Mathematica ขุมทรัพย์อีกแห่งเลยครับ 🙂

https://stackoverflow.com/questions/4198961/what-is-in-your-mathematica-tool-bag

เทคนิคเจ๋งๆเพียบเลยครับ

 

 

รวมชีทไฟล์ XLSX แบบง่ายๆ

เห็นมีคนเข้ามาดูโพสท์ที่ผมเขียน เกี่ยวกับการรวมชีท Excel ที่มีheader เหมือนกัน (https://www.sakngoi.com/2011/01/23/การรวมms-excel-sheets-ไว้ในหน้าเดียว/) เยอะพอสมควร ก็เลยคิดว่าเขียนแบบง่ายๆไว้ให้ใช้กันแบบออนไลน์ก็คงดี ผมก็เลยเขียนแบบง่ายไว้ให้ครับที่ (แต่ขอเตือนนะครับว่า ไม่ควรเป็นข้อมูลที่ sensitive นะครับ เพราะผมจะไม่รับผิดชอบใดๆทั้งสิ้นหากมีปัญหาการรั่วไหลของข้อมูลขึ้นมา)

https://www.wolframcloud.com/objects/cae100b5-7a2d-41ed-bed4-da1b86a5f67d

เพียงลากไฟล์ xlsx ไปปล่อยหรือคลิกเลือกแล้วกด submit ครับ เช่นถ้าผมมีไฟล์xlsx ที่แต่ล่ะชีทเป็นตามนี้

ผลที่ได้ก็คือ จะมีแค่ชีทเดียวที่รวมทุกชีกเข้าไว้ด้วยกัน

บ้างครั้งมันอาจจะขึ้น error ว่า “The supplied object cannot be interpreted as a file of type XLSX.” ก็ให้ลองกดรีเพรชหน้านั้นใหม่นะครับแล้วลองคลิกโหลดไฟล์ใหม่ครับ

ใช้งาน gcc ที่มากับ Rtools ใน Mathematica

ใน Rtools จะมี compiler ของ gcc (mingw) มาด้วยแล้วทั้งที่เป็นแบบ 32 bits และ 64 bits หากอยากจะเอาไปใช้ใน Mathematica ก็ต้องเรียกผ่าน CCompilerDriver`GenericCCompiler` ครับ แล้วเพียงเซ็ต Path ของ gcc จาก Rtools นี้ให้ถูก เช่น

Needs["CCompilerDriver`GenericCCompiler`"]

ทดลองเรียกใช้งาน

greeter = CreateExecutable[StringJoin[
 "#include <stdio.h>\n",
 "int main(){\n",
 " printf(\"Hello MinGW-w64 world.\\n\");\n",
 "}\n"],
 "helloworld", "Compiler" -> GenericCCompiler, 
 "CompilerInstallation" -> "C:/Rtools/mingw_64", 
 "CompilerName" -> "x86_64-w64-mingw32-gcc.exe"]

Import["!\""<>greeter<>"\"","Text"]
Hello MinGW-w64 world.

ที่นี้ถ้าอยากจะให้ Mathematica มันเรียกใช้เจ้า mingw 64 จาก Rtools นี้ตลอด อย่างเช่นคำสั่ง Compile ก็สามารถทำได้โดยเซ็ตค่าที่มันเกี่ยวข้องอย่างเช่น Path กับตัวแปร $CCompiler ได้เลยครับ

$CCompiler = {"Compiler" -> GenericCCompiler, 
 "CompilerInstallation" -> "C:/Rtools/mingw_64", 
 "CompilerName" -> "x86_64-w64-mingw32-gcc.exe"};

f = Compile[{x, y}, Sqrt[x^2 + y^2], CompilationTarget -> "C"]

Table[{x, f[x, 5/4 x]}, {x, 0, 6, 0.5}]

 

ใช้งาน OpenCLLink บนเครื่อง Dell XPS 13

ผมเพิ่งสั่งเครื่องxps 13 9370 มาใช้งานกับMathematica (Windows 10) โดยใช้กับแพ็คเกจ OpenCLLink เป็นหลักพูดง่ายๆก็คือจะใช้งานที่เกี่ยวกับการคำนวณที่ใช้ gpu เหตุที่ต้องใช้ OpenCL ไม่ใช้ CUDA เพราะ การ์ดที่มีกับเครื่องเป็น intel uhd m620 ครับ แต่ก็มีแผนจะใช้ การ์ด nvidia แบบ eGPU ครับ

การใช้งาน OpenCL บนเครื่องนี้กับMathematicaเราต้องติดตั้ง amd app sdk ก่อนครับ ไม่เช่นนั้นคำสั่ง OpenCLQ ของ Mathematica มันจะให้ค่า false แล้วมันจะใช้งานไม่ได้ครับ

เพิ่มเติม: ส่วนที่จะใช้ OpenCL กับ visual studio ก็ให้ลง intel sdk for opencl applications ครับ

 

 

undocumented Mathematica functions

Mathematica แต่ล่ะเวอร์ชั่นจะมีคำสั่งใหม่ๆแปลกๆ และเจ๋งๆเพิ่มขึ้นมาเสมอ และบ่อยครั้งก็จะมี functions ที่ไม่เอกสารอธิบายการทำงานของ functions แปลกใหม่นั้น แต่มันก็มีกลุ่มคนที่ใช้งาน Mathematica แบบ hardcore หน่อยที่ชอบเปิดดู code ที่เขาเขียนมา ชอบหาอะไรแปลกเพื่อหาดูว่าจะปรับปรุงแก้ไขปัญหาที่เจอหรือที่กำลังทำอยู่ได้อย่างไร ถ้าสนใจอยากดูว่ามี undocumented functions อะไรที่น่าสนใจลองดูที่นี่ครับ

https://mathematica.stackexchange.com/questions/805/what-are-some-useful-undocumented-mathematica-functions

undocumented functions นี้พอในเวอร์ชั่นใหม่ๆอาจจะหายหรือกลับมาก็แล้วแต่ว่ามีการปรับปรุงอะไรกันไป หลายครั้งที่อ่านตามเวบอย่าง stackexchange หรือ stackoverflow ก็จะงงๆอยูตลอดเกี่ยวกับพวก undocumented functions นี้ว่าเขาหากันมาอย่างไร แต่ก็มีคนคุยเรื่องกันอยู่บ้างเช่น https://mathematica.stackexchange.com/questions/809/how-can-one-find-undocumented-options-or-option-values-in-mathematica