มีอะไรอยู่ในกระเป๋าเครื่องมือ Mathematica ของคุณ? [ปิด]


152

เราทุกคนรู้ว่า Mathematica นั้นยอดเยี่ยม แต่ก็มักจะขาดฟังก์ชั่นที่สำคัญ คุณใช้แพ็คเกจ / เครื่องมือ / ทรัพยากรภายนอกประเภทใดกับ Mathematica

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

นอกจากนี้ยังมีคุณสมบัติที่ไม่มีประโยชน์และมีประโยชน์ใน Mathematica 7 และเกินกว่าที่คุณพบว่าตัวเองหรือขุดขึ้นมาจากกระดาษ / เว็บไซต์บางส่วนได้รับการต้อนรับมากที่สุด

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


แพคเกจ:

  1. LevelSchemeเป็นแพ็คเกจที่ขยายขีดความสามารถของ Mathematica อย่างมากในการสร้างแปลงที่ดูดี ฉันใช้มันหากไม่ใช่เพื่อสิ่งอื่นแล้วสำหรับการควบคุมเห็บเฟรม / แกน รุ่นใหม่ล่าสุดเรียกว่า SciDraw และจะวางจำหน่ายในปีนี้
  2. David Park's Presentation Package(US $ 50 - ไม่มีค่าใช้จ่ายสำหรับการอัปเดต)
  3. grassmannOpsแพ็คเกจของ Jeremy Michelson ให้ทรัพยากรสำหรับการทำพีชคณิตและแคลคูลัสด้วยตัวแปร Grassmann และผู้ประกอบการที่มีความสัมพันธ์ในการแลกเปลี่ยนที่ไม่สำคัญ
  4. GrassmannAlgebraแพ็คเกจของ John Brown และหนังสือสำหรับการทำงานกับ algebras Grassmann และ Clifford
  5. RISC (สถาบันวิจัยเพื่อการคำนวณเชิงสัญลักษณ์)มีแพ็คเกจหลากหลายสำหรับ Mathematica (และภาษาอื่น ๆ ) ให้ดาวน์โหลดได้ โดยเฉพาะอย่างยิ่งมีTheoremaสำหรับการพิสูจน์ทฤษฎีบทอัตโนมัติและความหลากหลายของแพคเกจสำหรับการบวกสัญลักษณ์สมการความแตกต่างอื่น ๆ ที่ที่หน้าซอฟต์แวร์กลุ่มขั้นตอนของ Combinatorics

เครื่องมือ

  1. MASHเป็นสคริปต์Perl ที่ยอดเยี่ยมของ Daniel Reeves โดยพื้นฐานแล้วให้การสนับสนุนการเขียนสคริปต์สำหรับ Mathematica v7 (ตอนนี้สร้างขึ้นใน Mathematica 8 พร้อม-scriptตัวเลือก)
  2. ใช้alternate Mathematica shellกับอินพุต readline GNU (โดยใช้ python, * ระวังเท่านั้น)
  3. แพ็คเกจ ColourMaths ช่วยให้คุณสามารถเลือกส่วนต่าง ๆ ของนิพจน์และจัดการได้ http://www.dbaileyconsultancy.co.uk/colour_maths/colour_maths.html

แหล่งข้อมูล:

  1. ที่เก็บข้อมูลของ Wolfram MathSourceมีประโยชน์มากมายหากโน้ตบุ๊กแคบสำหรับการใช้งานที่หลากหลาย ตรวจสอบส่วนอื่น ๆ เช่น

  2. Mathematica วิกิตำรา

หนังสือ:

  1. การเขียนโปรแกรม Mathematica: การแนะนำขั้นสูงโดย Leonid Shifrin ( web, pdf) เป็นสิ่งที่ต้องอ่านหากคุณต้องการทำอะไรมากกว่าสำหรับลูปใน Mathematica เรามีความสุขที่ได้Leonidตอบคำถามของตัวเองที่นี่
  2. วิธีการควอนตัมด้วย Mathematicaโดย James F. Feagin ( amazon )
  3. หนังสือ Mathematicaโดย Stephen Wolfram ( amazon ) ( web)
  4. โครงร่างของ Schaum ( amazon )
  5. Mathematica in Actionโดย Stan Wagon ( amazon ) - ตัวอย่างที่ประณีตกว่า 600 หน้าและไปสู่ ​​Mathematica เวอร์ชัน 7 เทคนิคการสร้างภาพเป็นสิ่งที่ดีเป็นDemonstrations Pageพิเศษ
  6. Mathematica Programming Fundamentalsโดย Richard Gaylord ( pdf) - เป็นการแนะนำที่กระชับเกี่ยวกับสิ่งที่คุณต้องรู้เกี่ยวกับการเขียนโปรแกรม Mathematica
  7. Mathematica Cookbook โดย Sal Mangano จัดพิมพ์โดย O'Reilly 2010 832 หน้า - เขียนในสไตล์ O'Reilly Cookbook ที่รู้จักกันดี: ปัญหา - วิธีแก้ไข สำหรับคนกลาง
  8. สมการเชิงอนุพันธ์กับ Mathematica, Ed 3 Elsevier 2004 Amsterdam โดย Martha L. Abell, James P. Braselton - 893 หน้าสำหรับผู้เริ่มต้นเรียนรู้การแก้ปัญหา DE และ Mathematica ในเวลาเดียวกัน

คุณสมบัติที่ไม่มีเอกสาร (หรือมีเอกสารน้อยมาก):

  1. วิธีปรับแต่งแป้นพิมพ์ลัด Mathematica this questionดู
  2. วิธีตรวจสอบรูปแบบและฟังก์ชั่นที่ใช้โดยฟังก์ชั่นของ Mathematica ดูthis answer
  3. วิธีการบรรลุขนาดที่สอดคล้องกันสำหรับ GraphPlots ใน Mathematica? this questionดู
  4. วิธีผลิตเอกสารและการนำเสนอด้วย Mathematica this questionดู

2
Mathematica 8 ออกมาพร้อมกับการรวมเชลล์สคริปต์ที่ดีขึ้นมาก wolfram.com/mathematica/new-in-8/mathematica-shell-scripts
Joshua Martell

2
+1 สำหรับ LevelScheme มันช้าไปหน่อยบางครั้ง แต่มันมีวิธีการที่ชาญฉลาดในการสร้างเครื่องหมายติ๊กและมันง่ายกว่ามากในการสร้างเลย์เอาต์ที่น่าสนใจสำหรับกราฟิกในรูปแบบกราฟิคGridหรืออะไรทำนองนั้น
rcollyer

2
ตามข้อเสนอของอเล็กซ์ในการแสดงความคิดเห็นในคำถามนี้stackoverflow.com/questions/5152551/...ผมเสนอเปลี่ยนชื่อแท็กสำหรับ Mathematica ที่นี่: meta.stackexchange.com/questions/81152/... โปรดดูและโหวตถ้าคุณเห็นด้วย ฉันโพสต์ไว้ที่นี่เพราะคำถามนี้มีรายการโปรดมากมายในชุมชน Mma ที่นี่
ดร. เบลิซา

1
ทั้งหมดคำถามนี้ควรเป็นชุมชนวิกิเนื่องจากเหตุผลทั้งหมด: ไม่มีคำตอบที่ถูกต้องและเป็นรายการมากกว่าสิ่งอื่นใด ฉันขอโทษทุกคนที่ทำกำไรอย่างดีในชื่อเสียงออกจากคำถามนี้
rcollyer

2
คำตอบสำหรับคำถามนี้มีความสร้างสรรค์ควรเปิดใหม่
MR

คำตอบ:


29

ฉันเคยพูดถึงเรื่องนี้มาก่อน แต่เครื่องมือที่ฉันพบว่ามีประโยชน์มากที่สุดคือแอปพลิเคชันReapและการSowเลียนแบบ / ยืดอายุการทำงานของGatherBy:

SelectEquivalents[x_List,f_:Identity, g_:Identity, h_:(#2&)]:=
   Reap[Sow[g[#],{f[#]}]&/@x, _, h][[2]];

สิ่งนี้ทำให้ฉันสามารถจัดกลุ่มรายการตามเกณฑ์ใด ๆ และแปลงพวกเขาในกระบวนการ วิธีการทำงานคือฟังก์ชั่น criteria ( f) ติดแท็กแต่ละรายการในรายการจากนั้นแต่ละรายการจะถูกแปลงโดยฟังก์ชันที่ให้มาครั้งที่สอง ( g) และเอาต์พุตเฉพาะจะถูกควบคุมโดยฟังก์ชันที่สาม ( h) ฟังก์ชั่นhยอมรับสองข้อโต้แย้ง: แท็กและรายการของรายการที่รวบรวมที่มีแท็กนั้น รายการที่เก็บคำสั่งเดิมของพวกเขาดังนั้นถ้าคุณตั้งค่าh = #1&แล้วคุณจะได้รับการคัดเลือกUnionเช่นในตัวอย่างReapสำหรับ แต่มันสามารถใช้สำหรับการประมวลผลรอง

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

rx ry rz i j Re[Hij] Im[Hij]

ในการเปลี่ยนรายการนั้นเป็นชุดของเมทริกซ์ฉันรวบรวมรายการย่อยทั้งหมดที่มีพิกัดเดียวกันเปลี่ยนข้อมูลองค์ประกอบเป็นกฎ (เช่น {i, j} -> Re [Hij] + I Im [Hij]) และ จากนั้นเปลี่ยนกฎที่รวบรวมไว้ให้เป็นSparseArrayกลุ่มเดียว:

SelectEquivalents[hamlst, 
      #[[;; 3]] &, 
      #[[{4, 5}]] -> (Complex @@ #[[6 ;;]]) &, 
      {#1, SparseArray[#2]} &]

จริงๆแล้วนี่คือ Swiss Army Knife ของฉันและทำให้สิ่งที่ซับซ้อนนั้นง่ายมาก เครื่องมืออื่น ๆ ของฉันส่วนใหญ่ค่อนข้างเจาะจงโดเมนดังนั้นฉันอาจไม่โพสต์ SelectEquivalentsแต่ส่วนใหญ่ถ้าไม่ได้ทั้งหมดของพวกเขาอ้างอิง

แก้ไข : มันไม่ได้เลียนแบบอย่างสมบูรณ์GatherByในการที่ไม่สามารถจัดกลุ่มนิพจน์ได้หลายระดับอย่างที่GatherByทำได้ อย่างไรก็ตามMapทำงานได้ดีสำหรับสิ่งที่ฉันต้องการ

ตัวอย่าง : @Yaroslav Bulatov ได้ขอตัวอย่างที่มีในตัวเอง นี่คือหนึ่งในงานวิจัยของฉันที่ง่ายขึ้นมาก สมมุติว่าเรามีจุดหนึ่งจุดในระนาบ

In[1] := pts = {{-1, -1, 0}, {-1, 0, 0}, {-1, 1, 0}, {0, -1, 0}, {0, 0, 0}, 
 {0, 1, 0}, {1, -1, 0}, {1, 0, 0}, {1, 1, 0}}

และเราต้องการลดจำนวนคะแนนโดยชุดของการดำเนินการแบบสมมาตร (สำหรับคนที่อยากรู้อยากเห็นเรากำลังสร้างกลุ่มเล็ก ๆของแต่ละจุด) สำหรับตัวอย่างนี้เราจะใช้แกนหมุนสี่เท่าเกี่ยวกับแกน z

In[2] := rots = RotationTransform[#, {0, 0, 1}] & /@ (Pi/2 Range[0, 3]);

การใช้SelectEquivalentsเราสามารถจัดกลุ่มจุดที่ให้ภาพชุดเดียวกันภายใต้การดำเนินการเหล่านี้ได้ซึ่งเทียบเท่ากันโดยใช้สิ่งต่อไปนี้

In[3] := SelectEquivalents[ pts, Union[Through[rots[#] ] ]& ] (*<-- Note Union*)
Out[3]:= {{{-1, -1, 0}, {-1, 1, 0}, {1, -1, 0}, {1, 1, 0}},
          {{-1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {1, 0, 0}},
          {{0,0,0}}}

ซึ่งสร้าง 3 รายการย่อยที่มีคะแนนเท่ากัน (หมายเหตุUnionมีความสำคัญอย่างยิ่งที่นี่เพื่อให้แน่ใจว่าภาพเดียวกันนั้นสร้างขึ้นโดยแต่ละจุดในขั้นต้นฉันใช้Sortแต่ถ้ามีจุดหนึ่งอยู่บนแกนสมมาตร ดังนั้นUnionกำจัดภาพพิเศษเหล่านี้นอกจากนี้GatherByจะให้ผลลัพธ์เหมือนกัน) ในกรณีนี้คะแนนอยู่ในรูปแบบที่ฉันจะใช้แล้ว แต่ฉันต้องการเพียงจุดตัวแทนจากแต่ละกลุ่มเท่านั้นและฉันต้องการการนับ ของคะแนนเทียบเท่า เนื่องจากฉันไม่ต้องการแปลงแต่ละจุดฉันจึงใช้Identityฟังก์ชั่นในตำแหน่งที่สอง สำหรับฟังก์ชั่นที่สามเราต้องระวัง อาร์กิวเมนต์แรกที่ถูกส่งผ่านไปนั้นคือรูปภาพของจุดใต้การหมุนซึ่งสำหรับจุด{0,0,0}นั้นคือรายการขององค์ประกอบสี่อย่างที่เหมือนกันและการใช้มันจะทำให้เกิดการนับ {0,0,0}อย่างไรก็ตามอาร์กิวเมนต์ที่สองเป็นเพียงรายการขององค์ประกอบทั้งหมดที่มีแท็กนั้นจึงจะมีเฉพาะ ในรหัส

In[4] := SelectEquivalents[pts,  
             Union[Through[rots[#]]]&, #&, {#2[[1]], Length[#2]}& ]
Out[4]:= {{{-1, -1, 0}, 4}, {{-1, 0, 0}, 4}, {{0, 0, 0}, 1}}

หมายเหตุขั้นตอนสุดท้ายนี้สามารถทำได้โดยง่าย

In[5] := {#[[1]], Length[#]}& /@ Out[3]

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


รหัส Fortran77 ดั้งเดิมได้รับการปรับโครงสร้างใหม่ในวันขอบคุณพระเจ้าปี 1996 และเป็นเวลาหลายปีที่รู้จักกันในชื่อ turkey.f ... : D กราฟิกที่ดีมาก BTW จำฉันเป็นสัตว์ประหลาดของ Falicov ...
ดร. เบลิซาเรี

@belisarius ฉันไม่ได้อ่านประวัตินั่นเป็นเรื่องตลก ฉันเพิ่งเริ่มใช้ Wannier90 แต่มันเป็นFortranโค้ดที่ดีและเป็นระเบียบที่สุดเท่าที่ฉันเคยเห็น ทำให้ฉันเกือบจะพิจารณาใช้Fortran...
rcollyer

ฉันสงสัยว่าคุณสามารถเพิ่มเป็นตัวอย่างที่อยู่ในตัวเองของ SelectEquivalents ในการดำเนินการ
ยาโรสลาฟ Bulatov

@Yaroslav Bulatov เพิ่มตัวอย่างต่อคำขอ แจ้งให้เราทราบหากสิ่งนี้ช่วยได้ หากไม่เป็นเช่นนั้นเราจะเห็นสิ่งที่เราสามารถทำได้
rcollyer

คุณได้เครื่องหมายถูกกับ "คำถาม" นี้สำหรับการสนับสนุนข้อมูลโค้ดที่น่าสนใจที่สุด
Timo

57

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

ขั้นแรกให้กำหนดฟังก์ชั่นที่มอบหมายการประเมินผลคำสั่งแบบข้อความให้กับเชลล์ภายนอก:

shellEvaluate[cmd_, _] := Import["!"~~cmd, "Text"]

จำเป็นต้องมีอาร์กิวเมนต์ที่สองและละเว้นด้วยเหตุผลที่จะปรากฏในภายหลัง ต่อไปเราต้องการสร้างสไตล์ใหม่ที่เรียกว่าShell :

  1. เปิดสมุดบันทึกใหม่
  2. เลือกรายการเมนูรูปแบบ / แก้ไขสไตล์ชีท ...
  3. ในกล่องโต้ตอบข้างป้อนชื่อรูปแบบ:Shellชนิด
  4. เลือกวงเล็บเซลล์ข้างสไตล์ใหม่
  5. เลือกรายการเมนูเซลล์ / แสดงนิพจน์
  6. เขียนทับการแสดงออกของเซลล์ด้วยข้อความขั้นตอนที่ 6ด้านล่าง
  7. เลือกรายการเมนูCell / Show Expressionอีกครั้ง
  8. ปิดกล่องโต้ตอบ

ใช้การแสดงออกของเซลล์ต่อไปนี้เป็นข้อความขั้นตอนที่ 6 :

Cell[StyleData["Shell"],
 CellFrame->{{0, 0}, {0.5, 0.5}},
 CellMargins->{{66, 4}, {0, 8}},
 Evaluatable->True,
 StripStyleOnPaste->True,
 CellEvaluationFunction->shellEvaluate,
 CellFrameLabels->{{None, "Shell"}, {None, None}},
 Hyphenation->False,
 AutoQuoteCharacters->{},
 PasteAutoQuoteCharacters->{},
 LanguageCategory->"Formula",
 ScriptLevel->1,
 MenuSortingValue->1800,
 FontFamily->"Courier"]

นิพจน์นี้ส่วนใหญ่ถูกคัดลอกโดยตรงจากรูปแบบของโปรแกรมในตัว การเปลี่ยนแปลงที่สำคัญคือบรรทัดเหล่านี้:

 Evaluatable->True,
 CellEvaluationFunction->shellEvaluate,
 CellFrameLabels->{{None, "Shell"}, {None, None}},

Evaluatableเปิดใช้งานฟังก์ชัน SHIFT + ENTER สำหรับเซลล์ การประเมินผลจะเรียกการCellEvaluationFunctionส่งผ่านเนื้อหาของเซลล์และประเภทเนื้อหาเป็นอาร์กิวเมนต์ ( shellEvaluateละเว้นอาร์กิวเมนต์หลัง) CellFrameLabelsเป็นเพียงความดีที่ให้ผู้ใช้ระบุว่าเซลล์นี้ผิดปกติ

ด้วยสิ่งเหล่านี้เราสามารถป้อนและประเมินค่านิพจน์ของเชลล์ได้แล้ว:

  1. ในสมุดบันทึกที่สร้างในขั้นตอนข้างต้นสร้างเซลล์ว่างและเลือกวงเล็บเซลล์
  2. เลือกรายการเมนูรูปแบบ / รูปแบบ / เชลล์
  3. พิมพ์คำสั่งเชลล์ระบบปฏิบัติการที่ถูกต้องลงในเซลล์ (เช่น 'ls' บน Unix หรือ 'dir' บน Windows)
  4. กด SHIFT + ENTER

เป็นการดีที่สุดที่จะรักษาสไตล์ที่กำหนดไว้นี้ในสไตล์ชีทที่ตั้งอยู่ใจกลางเมือง นอกจากนี้ฟังก์ชั่นการประเมินผลการชอบshellEvaluateมีการกำหนดไว้อย่างดีในฐานะสมบูรณ์โดยใช้DeclarePackageinit.mใน รายละเอียดของกิจกรรมทั้งสองนี้อยู่นอกเหนือขอบเขตของการตอบสนองนี้

ด้วยฟังก์ชั่นนี้เราสามารถสร้างสมุดบันทึกที่มีการแสดงออกของการป้อนข้อมูลในไวยากรณ์ที่น่าสนใจใด ๆ ฟังก์ชั่นการประเมินสามารถเขียนด้วย Mathematica บริสุทธิ์หรือมอบหมายการประเมินส่วนใดส่วนหนึ่งหรือทั้งหมดให้แก่หน่วยงานภายนอก โปรดทราบว่ามีตะขออื่น ๆ ที่เกี่ยวข้องกับการประเมินผลของเซลล์เช่นCellEpilog, และCellPrologCellDynamicExpression

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

ในบันทึกส่วนตัวมันเป็นคุณสมบัติแบบนี้ที่ทำให้ส่วนต่อประสานโน้ตบุ๊คเป็นศูนย์กลางของจักรวาลการเขียนโปรแกรมของฉัน

ปรับปรุง

ฟังก์ชันตัวช่วยต่อไปนี้มีประโยชน์สำหรับการสร้างเซลล์ดังกล่าว:

evaluatableCell[label_String, evaluationFunction_] :=
  ( CellPrint[
      TextCell[
        ""
      , "Program"
      , Evaluatable -> True
      , CellEvaluationFunction -> (evaluationFunction[#]&)
      , CellFrameLabels -> {{None, label}, {None, None}}
      , CellGroupingRules -> "InputGrouping"
      ]
    ]
  ; SelectionMove[EvaluationNotebook[], All, EvaluationCell]
  ; NotebookDelete[]
  ; SelectionMove[EvaluationNotebook[], Next, CellContents]
  )

มันถูกใช้ดังนี้:

shellCell[] := evaluatableCell["shell", Import["!"~~#, "Text"] &]

ตอนนี้หากshellCell[]ประเมินผลเซลล์อินพุตจะถูกลบและแทนที่ด้วยเซลล์อินพุตใหม่ที่ประเมินเนื้อหาเป็นคำสั่งเชลล์


3
@ ยอดถึง 100! ฉันหวังว่าฉันรู้เรื่องนี้ก่อนหน้านี้! นี่คือสิ่งที่มีประโยชน์มากสำหรับฉันอย่างน้อย ขอบคุณสำหรับการแบ่งปัน!
Leonid Shifrin

นี่มันช่างงามเหลือเกิน! CellEvaluationFunctionสามารถใช้สำหรับการแฮ็กไวยากรณ์ในระดับต่ำได้เช่นกันฉันคิดว่า
Mr.Wizard

@ Leonid อย่างน้อยสำหรับ FrontEnd CellEvaluationFunctionคุณชอบหาอะไร
Mr.Wizard

2
นอกจากนี้: มีอีกหนึ่งCellตัวเลือกที่เกี่ยวข้องกับการประเมินผลเซลล์ Evaluator -> "EvaluatorName"- ความหมายของ"EvaluatorName"สามารถกำหนดค่าผ่านไดอะล็อกการประเมินผล :: ตัวเลือกการกำหนดค่าเคอร์เนล ... ฉันยังไม่ทราบว่าเป็นไปได้หรือไม่ที่จะกำหนดค่าร่วมกันโดยทางโปรแกรม ... เทคนิคนี้อนุญาตให้ใช้ MathKernels ที่แตกต่างกันCellในสมุดบันทึกที่ต่างกัน MathKernels เหล่านี้สามารถติดตั้งจากMathematicaรุ่นต่างๆ
Alexey Popkov

1
@Sababcs การใช้งานของฉันเองของเทคนิคนี้เกี่ยวข้องกับวิธีstdin _ / _ stdoutตามที่แสดงด้านบนหรือการร้องขอระยะไกลที่มีอยู่ในตัวเองเช่นแบบสอบถาม SQL หรือการดำเนินการ HTTP คุณอาจลองตั้งค่าแอปพลิเคชัน Python REPL เว็บ (เช่นนี้ ) และโต้ตอบกับมันโดยใช้Importหรืออาจเริ่มต้นกระบวนการ Python ภายนอกและสื่อสารผ่านสตรีม (เช่นการใช้ Java ProcessBuilder ) ฉันแน่ใจว่ามีวิธี Mathematica ที่ดีกว่า - ดูเหมือนคำถาม SO ที่ดี :)
WReach

36

Todd Gayley (Wolfram Research) เพียงส่งแฮ็คที่ดีซึ่งอนุญาตให้ "ห่อ" ฟังก์ชั่นในตัวด้วยโค้ดที่กำหนดเอง ฉันรู้สึกว่าฉันต้องแบ่งปันเครื่องมือที่มีประโยชน์นี้ questionต่อไปนี้คือคำตอบของทอดด์ของฉัน

ประวัติ (?) ที่น่าสนใจ: รูปแบบของการแฮ็กสำหรับ "การตัด" ฟังก์ชั่นในตัวนั้นถูกประดิษฐ์ขึ้นในปี 1994 โดย Robby Villegas และ I ซึ่งฟังดูน่าฟังสำหรับฟังก์ชั่นข้อความในแพ็คเกจที่ชื่อว่า ErrorHelp ณ ตอนนั้น. มันถูกนำมาใช้หลายครั้งหลายต่อหลายคนตั้งแต่นั้นมา มันเป็นเคล็ดลับของคนวงใน แต่ฉันคิดว่ามันยุติธรรมที่จะบอกว่ามันได้กลายเป็นวิธีมาตรฐานของการฉีดโค้ดของคุณเองลงในนิยามของฟังก์ชั่นในตัว มันทำให้งานสำเร็จเป็นอย่างดี แน่นอนคุณสามารถใส่ตัวแปร $ inMsg ในบริบทส่วนตัวที่คุณต้องการ

Unprotect[Message];

Message[args___] := Block[{$inMsg = True, result},
   "some code here";
   result = Message[args];
   "some code here";
   result] /; ! TrueQ[$inMsg]

Protect[Message];

@ Alexey ฉันมีปัญหาในการเข้าใจสิ่งนี้ คุณอธิบายได้ไหมว่ามันทำงานอย่างไร ไม่ควรมีการป้องกันข้อความ [ที่ไหนสักแห่ง]? และตัวอย่างนี้ไม่มีการเรียกซ้ำแบบไม่สิ้นสุดใช่ไหม และ! TrueQ [$ inMsg] เหมาะสมกับ $ inMsg ที่กำหนดไว้ภายในขอบเขต Block และไม่ได้กำหนดนอก Block
Sjoerd C. de Vries

9
@ Joerd จากสิ่งที่ฉันเข้าใจUnprotectจริง ๆ ต้องเป็นถูกเพิ่งออก จุดของBlock(การกำหนดขอบเขตแบบไดนามิก) และ$inMsgเป็นการป้องกันการวนซ้ำแบบไม่สิ้นสุด เนื่องจาก$inMsgไม่ได้กำหนดไว้ภายนอก (นี่เป็นข้อกำหนดที่สำคัญ) ในตอนแรกTrueQประเมินFalseและเราเข้าสู่ร่างกายของฟังก์ชัน แต่เมื่อเรามีการเรียกใช้ฟังก์ชั่นภายในร่างกายเงื่อนไขประเมินเป็นFalse(เนื่องจากตัวแปรได้รับการนิยามใหม่โดยบล็อก) ดังนั้นกฎที่ผู้ใช้กำหนดจะไม่ตรงกันและใช้กฎที่มีอยู่แล้วแทน
Leonid Shifrin

1
@ Leonid ขอบคุณฉันรับมันตอนนี้ ฉลาดมาก!
Sjoerd C. de Vries

1
ฉันเพิ่งพบว่าเทคนิคนี้ได้รับการกล่าวถึงโดย Robby Villegas จาก Wolfram Research ในการประชุมนักพัฒนาปี 1999 ดู"การทำงานกับ unevaluated นิพจน์"โน๊ตบุ๊คโพสต์ที่นี่ ในสมุดบันทึกนี้ Robby Villegas กล่าวถึงเคล็ดลับนี้ในส่วน "My Block trick สำหรับการดักการโทรไปยังฟังก์ชันในตัว" ส่วนย่อย
Alexey Popkov

1
@ Mr.Wizard นี่ไม่ใช่วิธีเดียวที่จะทำสิ่งนี้ เป็นเวลานานฉันใช้รุ่นที่คุณกำหนดใหม่ในDownValuesเวลาทำงานคุณสามารถดูโพสต์นี้groups.google.com/group/comp.soft-sys.math.mathematica/ ......ตัวอย่าง ( SetDelayedredefinition) . แต่วิธีการของฉันนั้นสวยงามน้อยกว่ามีความทนทานน้อยกว่าและมีข้อผิดพลาดมากกว่าและทำให้แตกหักจากการเรียกซ้ำไปมาก ดังนั้นในสถานการณ์ส่วนใหญ่วิธีการที่อธิบายโดย @Alexey ชนะมือลง
Leonid Shifrin

25

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

timeAvg[func_] := Module[
{x = 0, y = 0, timeLimit = 0.1, p, q, iterTimes = Power[10, Range[0, 10]]},
Catch[
 If[(x = First[Timing[(y++; Do[func, {#}]);]]) > timeLimit,
    Throw[{x, y}]
    ] & /@ iterTimes
 ] /. {p_, q_} :> p/iterTimes[[q]]
];
Attributes[timeAvg] = {HoldAll};

timeAvg@funcYouWantToTestการใช้งานแล้วก็

แก้ไข: ตัวช่วยสร้างนายได้ให้รุ่นที่ง่ายกว่าที่จะไปThrowและCatchและเป็นเรื่องง่ายที่จะแยกวิเคราะห์:

SetAttributes[timeAvg, HoldFirst]
timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ 
                     Timing @ Do[func, {5^i}]
                     ,{i, 0, 15}]

แก้ไข: นี่คือรุ่นจากacl (นำมาจากที่นี่ ):

timeIt::usage = "timeIt[expr] gives the time taken to execute expr, \
  repeating as many times as necessary to achieve a total time of 1s";

SetAttributes[timeIt, HoldAll]
timeIt[expr_] := Module[{t = Timing[expr;][[1]], tries = 1},
  While[t < 1., tries *= 2; t = Timing[Do[expr, {tries}];][[1]];]; 
  t/tries]

ทำซ้ำอีกครั้งแล้วก็ถึงเวลาใส่กระเป๋าของฉัน TNX!
ดร. เบลิซาเรี

1
ปัญหาอย่างหนึ่งของรหัสนี้ (อาจเป็นมุมมองของผู้ชอบความสมบูรณ์แบบ) คือเราสามารถจับบางสิ่งที่เราไม่ได้โยนและตีความสิ่งนี้ว่าเป็นผลการจับเวลาที่ไม่ถูกต้อง ทั้งCatchและThrowควรถูกใช้กับแท็กข้อยกเว้นที่ไม่ซ้ำกัน
Leonid Shifrin

2
ติโมฉันดีใจที่คุณชอบการกระทำของฉันมากพอที่จะรวมไว้ ขอบคุณที่ให้เครดิตฉันด้วย ฉันอยากรู้เกี่ยวกับวิธีที่คุณจัดรูปแบบโค้ดของฉันใหม่ ฉันไม่ปฏิบัติตามแนวทางเฉพาะใด ๆ ในรหัสของฉันนอกเหนือจากการทำให้อ่านตัวเองได้ง่าย มีโรงเรียนแห่งความคิดอยู่เบื้องหลังการจัดรูปแบบของคุณหรือเป็นเพียงการตั้งค่า? Mathematica ไม่สนับสนุนการจัดรูปแบบโค้ดที่แม่นยำเนื่องจากวิธีการป้อนข้อมูลซ้ำ แต่การโพสต์โค้ดที่นี่ทำให้ฉันเริ่มคิดเกี่ยวกับมัน BTW ฉันคิดว่าคุณหมายถึง " ThrowและCatch" มากกว่า " ReapและSow"
Mr.Wizard

1
@Simon, Mr.Wizard ฉันใช้วิธีนี้กับฟังก์ชั่น smallish รุ่นต่าง ๆ ซึ่งจะเรียกว่าหลายครั้ง ไม่จำเป็นต้องอยู่ในโครงสร้างวนรอบ แต่แน่นอนภายในโครงสร้างที่ MMA ปรับให้เหมาะสม ในบริบทเวลานี้การดำเนินการของลูปทำให้รู้สึกและประสิทธิภาพจะใกล้เคียงกับการใช้งานจริง สำหรับการจับเวลาฟังก์ชั่นที่ซับซ้อนขนาดใหญ่ (อาจจะเป็นเซลล์เริ่มต้นทั้งหมด) วิธีการของไซม่อนจะให้ผลลัพธ์ที่ดีกว่า สรุปทั้งหมดฉันสนใจค่าสัมพัทธ์มากกว่าและวิธีใดวิธีหนึ่งควรทำงานที่นั่น
ติโม

3
ตอนนี้มีRepeatedTimingการทำเช่นนี้
masterxilo

20

Internal`InheritedBlock

ฉันได้เรียนรู้เมื่อเร็ว ๆ นี้การดำรงอยู่ของฟังก์ชั่นที่มีประโยชน์เช่นInternal`InheritedBlockจากข้อความของ Daniel Lichtblauในกลุ่มข่าวอย่างเป็นทางการ

ตามที่ฉันเข้าใจInternal`InheritedBlockอนุญาตให้ส่งสำเนาของฟังก์ชันขาออกภายในBlockขอบเขต:

In[1]:= Internal`InheritedBlock[{Message},
Print[Attributes[Message]];
Unprotect[Message];
Message[x___]:=Print[{{x},Stack[]}];
Sin[1,1]
]
Sin[1,1]
During evaluation of In[1]:= {HoldFirst,Protected}
During evaluation of In[1]:= {{Sin::argx,Sin,2},{Internal`InheritedBlock,CompoundExpression,Sin,Print,List}}
Out[1]= Sin[1,1]
During evaluation of In[1]:= Sin::argx: Sin called with 2 arguments; 1 argument is expected. >>
Out[2]= Sin[1,1]

ฉันคิดว่าฟังก์ชั่นนี้มีประโยชน์มากสำหรับทุกคนที่ต้องการแก้ไขฟังก์ชั่นในตัวชั่วคราว!

เปรียบเทียบกับบล็อก

ให้เรานิยามฟังก์ชั่นบางอย่าง:

a := Print[b]

ตอนนี้เราต้องการส่งสำเนาของฟังก์ชันนี้ไปยังBlockขอบเขต การทดลองที่ไร้เดียงสาไม่ได้ให้สิ่งที่เราต้องการ:

In[2]:= Block[{a = a}, OwnValues[a]]

During evaluation of In[9]:= b

Out[2]= {HoldPattern[a] :> Null}

ตอนนี้พยายามที่จะใช้คำจำกัดความล่าช้าในการโต้แย้งแรกของBlock(มันเป็นคุณสมบัติที่ไม่มีเอกสารเกินไป):

In[3]:= Block[{a := a}, OwnValues[a]]
Block[{a := a}, a]

Out[3]= {HoldPattern[a] :> a}

During evaluation of In[3]:= b

เราเห็นว่าในกรณีนี้ใช้aงานได้ แต่เรายังไม่ได้สำเนาต้นฉบับaภายในBlockขอบเขต

ตอนนี้ให้เราลองInternal`InheritedBlock:

In[5]:= Internal`InheritedBlock[{a}, OwnValues[a]]

Out[5]= {HoldPattern[a] :> Print[b]}

เราได้รับสำเนาของคำจำกัดความดั้งเดิมสำหรับaภายในBlockขอบเขตและเราอาจแก้ไขมันในแบบที่เราต้องการโดยไม่ส่งผลต่อข้อกำหนดระดับโลกสำหรับa!


+1 มีประโยชน์มาก! อีกหนึ่งเครื่องมือในกระเป๋าและอีก 10 คะแนนที่ใกล้เคียงกับการแก้ไขสิทธิ์สำหรับคุณ
Mr.Wizard

สำหรับฉันแล้วสิ่งนี้ปรากฏเป็นตัวแปรของการประเมินแบบเร็วหรือช้าหรือไม่เลยและการประเมินแบบเต็ม
user2432923

19

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

ClearAll@zot
SetAttributes[zot, ...]
zot[a_] := ...
zot[b_ /; ...] := ...
zot[___] := (Message[zot::invalidArguments]; Abort[])

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

การใช้งานพื้นฐานของdefineเป็นเช่นนี้:

define[
  fact[0] = 1
; fact[n_ /; n > 0] := n * fact[n-1]
]

fact[5]

120

ตอนแรกมันดูไม่เหมือน แต่มีประโยชน์ซ่อนเร้น บริการแรกที่defineให้บริการคือมีการใช้งานโดยอัตโนมัติClearAllกับสัญลักษณ์ที่กำหนดไว้โดยอัตโนมัติ สิ่งนี้ทำให้มั่นใจได้ว่าไม่มีคำจำกัดความที่หลงเหลืออยู่ - เกิดขึ้นบ่อยครั้งในระหว่างการพัฒนาเริ่มต้นของฟังก์ชัน

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

fact[-1]

define::badargs: There is no definition for 'fact' applicable to fact[-1].
$Aborted

นี่คือค่าหลักของdefineซึ่งจับคลาสของข้อผิดพลาดที่พบบ่อยมาก

ความสะดวกสบายอีกประการหนึ่งคือวิธีรัดกุมในการระบุแอตทริบิวต์ในฟังก์ชันที่กำหนดไว้ มาทำฟังก์ชั่นListableกันเถอะ:

define[
  fact[0] = 1
; fact[n_ /; n > 0] := n * fact[n-1]
, Listable
]

fact[{3, 5, 8}]

{6, 120, 40320}

นอกจากทั้งหมดของแอตทริบิวต์ปกติยอมรับแอตทริบิวต์เพิ่มเติมที่เรียกว่าdefine Openสิ่งนี้ป้องกันไม่ให้defineเพิ่มการกำหนดข้อผิดพลาด catch-all ไปยังฟังก์ชัน:

define[
  successor[x_ /; x > 0] := x + 1
, Open
]

successor /@ {1, "hi"}

{2, successor["hi"]}

อาจมีการกำหนดแอตทริบิวต์หลายรายการสำหรับฟังก์ชัน:

define[
  flatHold[x___] := Hold[x]
, {Flat, HoldAll}
]

flatHold[flatHold[1+1, flatHold[2+3]], 4+5]

Hold[1 + 1, 2 + 3, 4 + 5]

นี่คือคำจำกัดความของdefine:

ClearAll@define
SetAttributes[define, HoldAll]
define[body_, attribute_Symbol] := define[body, {attribute}]
define[body:(_Set|_SetDelayed), attributes_List:{}] := define[CompoundExpression[body], attributes]
define[body:CompoundExpression[((Set|SetDelayed)[name_Symbol[___], _])..], attributes_List:{}] :=
  ( ClearAll@name
  ; SetAttributes[name, DeleteCases[attributes, Open]]
  ; If[!MemberQ[attributes, Open]
    , def:name[___] := (Message[define::badargs, name, Defer@def]; Abort[])
    ]
  ; body
  ;
  )
def:define[___] := (Message[define::malformed, Defer@def]; Abort[])

define::badargs = "There is no definition for '``' applicable to ``.";
define::malformed = "Malformed definition: ``";

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


2
+1 - นี่คือสิ่งที่มีประโยชน์จริงๆ ฉันใช้เครื่องมือที่คล้ายกัน มาโคร (เช่นเดียวกับการวิปัสสนาและเทคนิคการเขียนโปรแกรมเมตาดาต้าอื่น ๆ ) นั้นมีประสิทธิภาพมาก แต่ดูเหมือนจะไม่ค่อยได้รับความนิยมนักในชุมชน Mathematica หรืออย่างน้อยสิ่งนี้ก็เป็นความประทับใจของฉัน
Leonid Shifrin

ฉันเพิ่งกำหนดสิ่งที่คล้ายกัน +1 สำหรับการสนับสนุน Compound Expression สำหรับการทำหลายคำจำกัดความยกเลิก [] (ดูเหมือนว่าจะดีกว่ายังมีข้อความมาก) และเปิด (ดีสำหรับผู้สร้างเช่น)
masterxilo

16

เริ่มโดยไม่ต้องเปิดสมุดบันทึกเปล่า

ฉันรู้สึกรำคาญที่เริ่มต้น Mathematica โดยเปิดสมุดบันทึกเปล่า ฉันสามารถปิดสมุดบันทึกนี้ด้วยสคริปต์ แต่จะยังคงเปิดแฟลชชั่วครู่ แฮ็คของฉันคือการสร้างไฟล์Invisible.nbที่มี:

Notebook[{},Visible->False]

และเพิ่มลงในของฉันKernel\init.m:

If[Length[Notebooks["Invisible*"]] > 0, 
  NotebookClose[Notebooks["Invisible*"][[1]]]
]

SetOptions[$FrontEnd,
  Options[$FrontEnd, NotebooksMenu] /. 
    HoldPattern["Invisible.nb" -> {__}] :> Sequence[]
]

ตอนนี้ฉันเริ่มต้น Mathematica ด้วยการเปิด Invisible.nb

อาจจะมีวิธีที่ดีกว่านี้ แต่สิ่งนี้ช่วยฉันได้ดี


ปรับแต่งFoldและFoldList

Fold[f, x] ทำเทียบเท่า Fold[f, First@x, Rest@x]

บังเอิญฉันเชื่อว่านี่อาจหาทางไปสู่ ​​Mathematica รุ่นอนาคต

เซอร์ไพร์ส! สิ่งนี้ได้รับการดำเนินการแม้ว่าจะไม่ได้จดทะเบียนในปัจจุบัน ฉันได้รับแจ้งว่ามีการใช้งานในปี 2554 โดย Oliver Ruebenkoenig ไม่นานหลังจากที่ฉันโพสต์ข้อความนี้ ขอบคุณ Oliver Ruebenkoenig!

Unprotect[Fold, FoldList]

Fold[f_, h_[a_, b__]] := Fold[f, Unevaluated @ a, h @ b]
FoldList[f_, h_[a_, b__]] := FoldList[f, Unevaluated @ a, h @ b]

(* Faysal's recommendation to modify SyntaxInformation *)
SyntaxInformation[Fold]     = {"ArgumentsPattern" -> {_, _, _.}};
SyntaxInformation[FoldList] = {"ArgumentsPattern" -> {_, _., {__}}};

Protect[Fold, FoldList]

อัปเดตเพื่ออนุญาตสิ่งนี้:

SetAttributes[f, HoldAll]
Fold[f, Hold[1 + 1, 2/2, 3^3]]
f[f[1 + 1, 2/2], 3^3]

"พาร์ติชันแบบไดนามิก"

ดู Mathematica.SE โพสต์ # 7512สำหรับรุ่นใหม่ของฟังก์ชั่นนี้

บ่อยครั้งที่ฉันต้องการแบ่งพาร์ติชันรายการตามลำดับความยาว

ตัวอย่างรหัสเทียม:

partition[{1,2,3,4,5,6}, {2,3,1}]

เอาท์พุท: {{1,2}, {3,4,5}, {6}}

ฉันมากับสิ่งนี้:

dynP[l_, p_] := 
 MapThread[l[[# ;; #2]] &, {{0} ~Join~ Most@# + 1, #} &@Accumulate@p]

ซึ่งฉันแล้วเสร็จกับสิ่งนี้รวมถึงการทดสอบอาร์กิวเมนต์:

dynamicPartition[l_List, p : {_Integer?NonNegative ..}] :=
  dynP[l, p] /; Length@l >= Tr@p

dynamicPartition[l_List, p : {_Integer?NonNegative ..}, All] :=
  dynP[l, p] ~Append~ Drop[l, Tr@p] /; Length@l >= Tr@p

dynamicPartition[l_List, p : {_Integer?NonNegative ..}, n__ | {n__}] :=
  dynP[l, p] ~Join~ Partition[l ~Drop~ Tr@p, n] /; Length@l >= Tr@p

อาร์กิวเมนต์ที่สามควบคุมสิ่งที่เกิดขึ้นกับองค์ประกอบที่เกินกว่าข้อกำหนดแยก


อุบายของ Mathematica ของ Szabolcs

สิ่งที่ฉันใช้บ่อยที่สุดคือ Paste Data Table Palette

CreatePalette@
 Column@{Button["TSV", 
    Module[{data, strip}, 
     data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
     strip[s_String] := 
      StringReplace[s, RegularExpression["^\\s*(.*?)\\s*$"] -> "$1"];
     strip[e_] := e;
     If[Head[data] === String, 
      NotebookWrite[InputNotebook[], 
       ToBoxes@Map[strip, ImportString[data, "TSV"], {2}]]]]], 
   Button["CSV", 
    Module[{data, strip}, 
     data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
     strip[s_String] := 
      StringReplace[s, RegularExpression["^\\s*(.*?)\\s*$"] -> "$1"];
     strip[e_] := e;
     If[Head[data] === String, 
      NotebookWrite[InputNotebook[], 
       ToBoxes@Map[strip, ImportString[data, "CSV"], {2}]]]]], 
   Button["Table", 
    Module[{data}, data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
     If[Head[data] === String, 
      NotebookWrite[InputNotebook[], 
       ToBoxes@ImportString[data, "Table"]]]]]}

แก้ไขข้อมูลภายนอกจากภายใน Compile

เมื่อเร็ว ๆ นี้ Daniel Lichtblau แสดงวิธีนี้ที่ฉันไม่เคยเห็นมาก่อน ในความคิดของฉันมันมีนัยสำคัญขยายยูทิลิตี้ของCompile

ll = {2., 3., 4.};
c = Compile[{{x}, {y}}, ll[[1]] = x; y];

c[4.5, 5.6]

ll

(* Out[1] = 5.6  *)

(* Out[2] = {4.5, 3., 4.}  *)

3
+1 คอลเลคชั่นที่ดี! เกี่ยวกับการแก้ไขภายนอกจากภายใน Compile- โพสต์ทั้งหมดของฉันที่นี่: stackoverflow.com/questions/5246330// , เป็นการแสดงความเป็นไปได้นี้ในการตั้งค่าที่ไม่สำคัญ (มีวิธีแก้ปัญหาที่สั้นและเร็วกว่าสำหรับคำถามที่โพสต์แล้ว) . IMO, ชัยชนะที่ยิ่งใหญ่ที่สุดที่นี่คือความสามารถในการเลียนแบบการอ้างอิงโดยผ่านและแบ่งฟังก์ชั่นการคอมไพล์ขนาดใหญ่เป็นชิ้นที่จัดการได้และนำกลับมาใช้ใหม่ได้มากขึ้น
Leonid Shifrin

1
นอกจากนี้คุณยังสามารถปรับข้อมูลไวยากรณ์ของ FoldList พับและในความหมายใหม่ของคุณ: SyntaxInformation [พับ] = { "ArgumentsPattern" -> {_ , _}}; SyntaxInformation [FoldList] = {"ArgumentsPattern" -> {_, _., {_ }}};
faysou

14

ปัญหาและแนวทางแก้ไขปัญหาการส่งออก PDF / EMF ทั่วไป

1) เป็นสิ่งที่คาดไม่ถึงและไม่มีเอกสารอย่างสมบูรณ์ แต่Mathematicaส่งออกและบันทึกกราฟิกในรูปแบบ PDF และ EPS โดยใช้ชุดคำจำกัดความของสไตล์ที่แตกต่างจากที่ใช้ในการแสดงสมุดบันทึกบนหน้าจอ โดยค่าเริ่มต้นสมุดบันทึกจะปรากฏบนหน้าจอในสภาพแวดล้อมแบบ "ทำงาน" (ซึ่งเป็นค่าเริ่มต้นสำหรับตัวเลือกScreenStyleEvironmentทั่วโลก$FrontEnd) แต่พิมพ์ใน"Printout"สภาพแวดล้อมแบบ (ซึ่งเป็นค่าเริ่มต้นสำหรับตัวเลือกPrintingStyleEnvironmentทั่วโลก$FrontEnd) เมื่อมีการส่งออกกราฟิกในรูปแบบแรสเตอร์เช่น GIF และ PNG หรือในรูปแบบ EMF Mathematicaจะสร้างกราฟิกที่มีลักษณะเหมือนอยู่ภายในโน๊ตบุ๊ค ดูเหมือนว่า"Working"สภาพแวดล้อมสไตล์ที่ใช้สำหรับการแสดงผลในกรณีนี้ แต่ไม่ใช่ในกรณีที่คุณส่งออก / บันทึกอะไรในรูปแบบ PDF หรือ EPS! ในกรณีนี้สิ่ง"Printout"สภาพแวดล้อมสไตล์จะถูกใช้โดยค่าเริ่มต้นที่แตกต่างอย่างมากจากสภาพแวดล้อมสไตล์ "การทำงาน" แรกของทุกชุดสภาพแวดล้อมสไตล์ถึง 80% ประการที่สองมันใช้ค่าของตัวเองสำหรับขนาดตัวอักษรของรูปแบบที่แตกต่างกันและผลลัพธ์นี้ในการเปลี่ยนแปลงขนาดตัวอักษรที่ไม่สอดคล้องกันในไฟล์ PDF ที่สร้างแบบจำลองเมื่อเปรียบเทียบกับการแสดงบนหน้าจอดั้งเดิม หลังสามารถเรียกความผันผวนของ FontSizeซึ่งน่ารำคาญมาก แต่มีความสุขที่สามารถหลีกเลี่ยงได้โดยการตั้งค่าตัวเลือกสากลเป็น "ทำงาน" :"Printout"MagnificationPrintingStyleEnvironment$FrontEnd

SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"]

2) ปัญหาที่พบบ่อยกับการส่งออกไปยังรูปแบบ EMF คือว่าส่วนใหญ่ของโปรแกรม (ไม่เพียง แต่มาติกา ) สร้างไฟล์ที่หน้าตาดีที่ขนาดเริ่มต้น แต่จะกลายเป็นน่าเกลียดเมื่อคุณซูมไว้ใน. มันเป็นเพราะmetafiles เป็นตัวอย่างที่มีความละเอียดหน้าจอความจงรักภักดี คุณภาพของไฟล์ EMF ที่สร้างขึ้นสามารถปรับปรุงได้โดยMagnifyการฝังวัตถุกราฟิกดั้งเดิมเพื่อให้ความแม่นยำในการสุ่มตัวอย่างกราฟิกต้นฉบับมีความแม่นยำมากขึ้น เปรียบเทียบสองไฟล์:

graphics1 = 
  First@ImportString[
    ExportString[Style["a", FontFamily -> "Times"], "PDF"], "PDF"];
graphics2 = Magnify[graphics1, 10];
Export["C:\\test1.emf", graphics1]
Export["C:\\test2.emf", graphics2]

หากคุณแทรกไฟล์เหล่านี้ลงใน Microsoft Word และซูมเข้าคุณจะเห็นว่า "a" ตัวแรกมีฟันเลื่อยอยู่ในขณะที่ไฟล์ที่สองไม่ได้ (ทดสอบกับMathematica 6)

อีกวิธีหนึ่งImageResolutionคือChris Degnen แนะนำ (ตัวเลือกนี้มีผลอย่างน้อยเริ่มต้นจากMathematica 8):

Export["C:\\test1.emf", graphics1]
Export["C:\\test2.emf", graphics1, ImageResolution -> 300]

3) ในMathematicaเรามีสามวิธีในการแปลงกราฟิกเป็น metafile: ผ่านExportไปยัง"EMF"(วิธีที่แนะนำอย่างยิ่ง: ผลิต metafile ที่มีคุณภาพสูงสุดที่เป็นไปได้) ผ่านSave selection As...รายการเมนู (ผลิตมากน้อยกว่าตัวเลขที่แม่นยำไม่แนะนำ) และผ่านทางEdit ► Copy As ► Metafileรายการเมนู ( ผมขอแนะนำ กับเส้นทางนี้ )


13

ได้รับความนิยมรหัสเพื่อสร้างบน 10 SO answerers พล็อต (ยกเว้นคำอธิบายประกอบ ) โดยใช้SO API

ป้อนคำอธิบายรูปภาพที่นี่

getRepChanges[userID_Integer] :=
 Module[{totalChanges},
  totalChanges = 
   "total" /. 
    Import["http://api.stackoverflow.com/1.1/users/" <> 
      ToString[userID] <> "/reputation?fromdate=0&pagesize=10&page=1",
      "JSON"];
  Join @@ Table[
    "rep_changes" /. 
     Import["http://api.stackoverflow.com/1.1/users/" <> 
       ToString[userID] <> 
       "/reputation?fromdate=0&pagesize=10&page=" <> ToString[page], 
      "JSON"],
    {page, 1, Ceiling[totalChanges/10]}
    ]
  ]

topAnswerers = ({"display_name", 
      "user_id"} /. #) & /@ ("user" /. ("top_users" /. 
      Import["http://api.stackoverflow.com/1.1/tags/mathematica/top-\
answerers/all-time", "JSON"]))

repChangesTopUsers =
  Monitor[Table[
    repChange = 
     ReleaseHold[(Hold[{DateList[
              "on_date" + AbsoluteTime["January 1, 1970"]], 
             "positive_rep" - "negative_rep"}] /. #) & /@ 
        getRepChanges[userID]] // Sort;
    accRepChange = {repChange[[All, 1]], 
       Accumulate[repChange[[All, 2]]]}\[Transpose],
    {userID, topAnswerers[[All, 2]]}
    ], userID];

pl = DateListLogPlot[
  Tooltip @@@ 
   Take[({repChangesTopUsers, topAnswerers[[All, 1]]}\[Transpose]), 
    10], Joined -> True, Mesh -> None, ImageSize -> 1000, 
  PlotRange -> {All, {10, All}}, 
  BaseStyle -> {FontFamily -> "Arial-Bold", FontSize -> 16}, 
  DateTicksFormat -> {"MonthNameShort", " ", "Year"}, 
  GridLines -> {True, None}, 
  FrameLabel -> (Style[#, FontSize -> 18] & /@ {"Date", "Reputation", 
      "Top-10 answerers", ""})]

1
Brett โพสต์คำถามเพื่อขอรหัสที่ถูกต้องเกือบนี้ อาจจะเหมาะสมที่สุดที่นั่นด้วยการบิดหนึ่งหรือสองเพื่อให้พอดีกับคำถาม จริง ๆ แล้วฉันจะคุ้มค่าตัวแทนเมื่อเทียบกับคำถามนี้
rcollyer

@rcollyer ถูกต้อง นี่คือ "Community Wiki"
Dr. belisarius

@belisarius ฉันเพิ่งคัดลอกในคำตอบสำหรับคำถามของเบร็ท ...
Sjoerd C. de Vries

@Sjoerd Your Plot ที่นี่ไม่อัปเดตอัตโนมัติ
ดร. เบลิซาเรีย

@belisarius จริง ๆ แล้วฉันหวังว่าคุณจะใช้งานนั้นกับคุณ ... ;-)
Sjoerd C. de Vries

13

นิพจน์แคช

ฉันพบว่าฟังก์ชันเหล่านี้มีประโยชน์มากในการแคชนิพจน์ใด ๆ สิ่งที่น่าสนใจสำหรับทั้งสองฟังก์ชั่นนี้คือการแสดงออกของตัวเองถูกใช้เป็นกุญแจสำคัญของ hashtable / symbol Cache หรือ CacheIndex เมื่อเทียบกับการบันทึกความทรงจำที่รู้จักกันดีใน mathematica ที่คุณสามารถแคชผลลัพธ์ได้เฉพาะ [x_]: = f [x] = ... ดังนั้นคุณสามารถแคชส่วนใดส่วนหนึ่งของรหัสได้ซึ่งจะมีประโยชน์หากฟังก์ชั่นถูกเรียกหลายครั้ง แต่เพียงบางส่วนของรหัสจะต้องไม่ถูกคำนวณใหม่

ในการแคชนิพจน์ที่เป็นอิสระจากการขัดแย้ง

SetAttributes[Cache, HoldFirst];
c:Cache[expr_] := c = expr;

Ex: Cache[Pause[5]; 6]
Cache[Pause[5]; 6]

ครั้งที่สองที่นิพจน์ส่งคืน 6 โดยไม่ต้องรอ

เมื่อต้องการแคชนิพจน์โดยใช้นิพจน์นามแฝงที่สามารถขึ้นอยู่กับอาร์กิวเมนต์ของนิพจน์แคช

SetAttributes[CacheIndex, HoldRest];
c:CacheIndex[index_,expr_] := c = expr;

Ex: CacheIndex[{"f",2},x=2;y=4;x+y]

หาก expr ใช้เวลาในการคำนวณมันจะเร็วกว่ามากในการประเมิน {"f", 2} เช่นเพื่อดึงผลลัพธ์ที่แคช

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

การลบค่าที่เก็บไว้

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

DeleteCachedValues[f_] := 
       DownValues[f] = Select[DownValues[f], !FreeQ[Hold@#,Pattern]&];

ในการลบค่าที่เก็บไว้เมื่อคุณทราบจำนวนคำจำกัดความของฟังก์ชั่น (เร็วขึ้นเล็กน้อย)

DeleteCachedValues[f_,nrules_] := 
       DownValues[f] = Extract[DownValues[f], List /@ Range[-nrules, -1]];

สิ่งนี้ใช้ข้อเท็จจริงที่ว่าคำจำกัดความของฟังก์ชั่นอยู่ที่ส่วนท้ายของรายการ DownValues ​​ค่าที่แคชไว้ก่อนหน้านี้

การใช้สัญลักษณ์เพื่อเก็บข้อมูลและฟังก์ชั่นเหมือนวัตถุ

นอกจากนี้ที่นี่ยังมีฟังก์ชั่นที่น่าสนใจในการใช้สัญลักษณ์ต่างๆเช่นวัตถุ

เป็นที่ทราบกันดีอยู่แล้วว่าคุณสามารถจัดเก็บข้อมูลเป็นสัญลักษณ์และเข้าถึงได้อย่างรวดเร็วโดยใช้ DownValues

mysymbol["property"]=2;

คุณสามารถเข้าถึงรายการของคีย์ (หรือคุณสมบัติ) ของสัญลักษณ์โดยใช้ฟังก์ชั่นเหล่านี้ตามสิ่งที่ dreeves ส่งในโพสต์บนเว็บไซต์นี้:

SetAttributes[RemoveHead, {HoldAll}];
RemoveHead[h_[args___]] := {args};
NKeys[symbol_] := RemoveHead @@@ DownValues[symbol(*,Sort->False*)][[All,1]];
Keys[symbol_] := NKeys[symbol] /. {x_} :> x;

ฉันใช้ฟังก์ชั่นนี้มากมายเพื่อแสดงข่าวสารทั้งหมดที่มีอยู่ใน DownValues ​​ของสัญลักษณ์:

PrintSymbol[symbol_] :=
  Module[{symbolKeys},
    symbolKeys = Keys[symbol];
    TableForm@Transpose[{symbolKeys, symbol /@ symbolKeys}]
  ];

ในที่สุดนี่เป็นวิธีที่ง่ายในการสร้างสัญลักษณ์ที่ทำตัวเหมือนวัตถุในการเขียนโปรแกรมเชิงวัตถุ (มันเพิ่งทำซ้ำพฤติกรรมพื้นฐานที่สุดของ OOP แต่ฉันพบว่าไวยากรณ์สง่างาม):

Options[NewObject]={y->2};
NewObject[OptionsPattern[]]:=
  Module[{newObject},
    newObject["y"]=OptionValue[y];

    function[newObject,x_] ^:= newObject["y"]+x;
    newObject /: newObject.function2[x_] := 2 newObject["y"]+x;

    newObject
  ];

คุณสมบัติจะถูกจัดเก็บเป็น DownValues ​​และเมธอดที่ล่าช้าค่าสูงสุดในสัญลักษณ์ที่สร้างโดยโมดูลที่ส่งคืน ฉันพบไวยากรณ์สำหรับ function2 ที่เป็นไวยากรณ์ OO ปกติสำหรับฟังก์ชันในโครงสร้างข้อมูลแบบต้นไม้ใน MathematicaMathematica

สำหรับรายการประเภทค่าที่มีอยู่ที่แต่ละสัญลักษณ์มีให้ดูที่http://reference.wolfram.com/mathematica/tutorial/PatternsAndTransformationRules.htmlและhttp://www.verbeia.com/mathematica/tips/HTMLLinks/Tricks_Misc_4.html .

ตัวอย่างเช่นลองสิ่งนี้

x = NewObject[y -> 3];
function[x, 4]
x.function2[5]

คุณสามารถไปต่อได้ถ้าคุณต้องการจำลองการสืบทอดวัตถุโดยใช้แพ็คเกจชื่อ InheritRules ที่นี่ http://library.wolfram.com/infocenter/MathSource/671/

คุณสามารถจัดเก็บนิยามฟังก์ชันไม่ได้อยู่ใน newObject แต่เป็นสัญลักษณ์ชนิดดังนั้นหาก NewObject ส่งคืนชนิด [newObject] แทน newObject คุณสามารถกำหนดฟังก์ชันและ function2 แบบนี้นอก NewObject (และไม่ได้อยู่ข้างใน) และมีการใช้งานเหมือนเดิม .

function[type[object_], x_] ^:= object["y"] + x;
type /: type[object_].function2[x_] := 2 object["y"]+x;

ใช้ UpValues ​​[type] เพื่อดูฟังก์ชันและ function2 ที่กำหนดไว้ในสัญลักษณ์ชนิด

แนวคิดเพิ่มเติมเกี่ยวกับไวยากรณ์ล่าสุดนี้มีการนำเสนอที่นี่https://mathematica.stackexchange.com/a/999/66 https://mathematica.stackexchange.com/a/999/66

รุ่นที่ได้รับการปรับปรุงของ SelectEquivalents

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

Options[SelectEquivalents] = 
   {
      TagElement->Identity,
      TransformElement->Identity,
      TransformResults->(#2&) (*#1=tag,#2 list of elements corresponding to tag*),
      MapLevel->1,
      TagPattern->_,
      FinalFunction->Identity
   };

SelectEquivalents[x_List,OptionsPattern[]] := 
   With[
      {
         tagElement=OptionValue@TagElement,
         transformElement=OptionValue@TransformElement,
         transformResults=OptionValue@TransformResults,
         mapLevel=OptionValue@MapLevel,
         tagPattern=OptionValue@TagPattern,
         finalFunction=OptionValue@FinalFunction
      }
      ,
      finalFunction[
         Reap[
            Map[
               Sow[
                  transformElement@#
                  ,
                  {tagElement@#}
               ]&
               , 
               x
               , 
               {mapLevel}
            ] 
            , 
            tagPattern
            , 
            transformResults
         ][[2]]
      ]
   ];

นี่คือตัวอย่างของวิธีการใช้เวอร์ชันนี้:

ใช้ Mathematica Gather / รวบรวมอย่างถูกต้อง

คุณจะใช้ฟังก์ชัน PivotTable ใน Mathematica ได้อย่างไร

อัลกอริทึม Binning ทางคณิตศาสตร์อย่างรวดเร็ว 2D

Internal`Bag

Daniel Lichtblau อธิบายโครงสร้างข้อมูลภายในที่น่าสนใจสำหรับรายการที่กำลังเติบโต

การใช้ Quadtree ใน Mathematica

ฟังก์ชั่นการแก้จุดบกพร่อง

โพสต์ทั้งสองนี้ชี้ไปที่ฟังก์ชันที่มีประโยชน์สำหรับการดีบัก:

วิธีการแก้ปัญหาเมื่อเขียนรหัสขนาดเล็กหรือใหญ่โดยใช้ Mathematica? ปรับแต่ง? mma debugger? หรืออย่างอื่น? (แสดง)

/programming/5459735/the-clearest-way-to-represent-mathematicas-evaluation-sequence/5527117#5527117 (TraceView)

นี่คือฟังก์ชันอื่นที่ใช้ Reap และ Sow เพื่อแยกนิพจน์จากส่วนต่าง ๆ ของโปรแกรมและเก็บไว้ในสัญลักษณ์

SetAttributes[ReapTags,HoldFirst];
ReapTags[expr_]:=
   Module[{elements},
      Reap[expr,_,(elements[#1]=#2/.{x_}:>x)&];
      elements
   ];

นี่คือตัวอย่าง

ftest[]:=((*some code*)Sow[1,"x"];(*some code*)Sow[2,"x"];(*some code*)Sow[3,"y"]);
s=ReapTags[ftest[]];
Keys[s]
s["x"]
PrintSymbol[s] (*Keys and PrintSymbol are defined above*)

แหล่งข้อมูลอื่น ๆ

นี่คือรายการลิงก์ที่น่าสนใจสำหรับจุดประสงค์การเรียนรู้:

ชุดของแหล่งเรียนรู้ทางคณิตศาสตร์

อัปเดตที่นี่: https://mathematica.stackexchange.com/a/259/66


ที่เกี่ยวข้อง: " วิธีที่ดีที่สุดในการสร้างฟังก์ชั่นที่มีหน่วยความจำ " WReach ได้ให้ตัวอย่างที่ยอดเยี่ยมของฟังก์ชั่นง่าย ๆ ที่ไม่เพียง แต่จดจำค่าของมัน แต่ยังเขียนลงในไฟล์และอ่านย้อนหลังเมื่อรีสตาร์ท
Alexey Popkov

1
ที่เกี่ยวข้อง: " Mathematica: วิธีล้างแคชสำหรับสัญลักษณ์เช่น UnVortues ที่ไม่มีรูปแบบ Unset " คำถามนี้แสดงให้เห็นถึงวิธีการล้างแคชโดยใช้มาตรฐานf[x_] := f[x] = some codememoization
Simon

7
1 c:Cache[expr_] := c = exprมีความสะดวกสบายที่ดีคือสัญลักษณ์ที่ช่วยลดความจำเป็นในการที่จะทำซ้ำด้านซ้ายมือของความหมายในฟังก์ชั่นการใช้แคชเช่น:
WReach

SelectEquivalentsตัวแปรที่ดีของ ฉันคิดว่าฉันคงTagOnElementเป็นพารามิเตอร์ที่สองที่ผิดนัดไปIdentityเพราะมันใช้งานได้ดีที่สุด ฉันไม่คิดว่าฉันต้องการรวมทั้งเป็นมันสามารถจัดการภายในFinalOp OpOnTaggedElemsฉันจะย่อชื่อตัวเลือกให้สั้นลงเนื่องจากความยาวของพวกมันทำให้พิมพ์ออกมาไม่สะดวก ลองTagFunction, TransformElement, TransformResultsและTagPatternแทน ทั้งสองTagPatternและMapLevelเป็นส่วนเพิ่มเติมที่ดีในการทำงานและการเขียนที่ดีโดยรวม
rcollyer

ขอบคุณสำหรับความคิดเห็นของคุณ rcollyer ฉันนำมาพิจารณาและปรับปรุงการอ่านรหัส ฉันเก็บ FinalFunction เพราะมันทำงานกับผลลัพธ์ของ Reap ตัวอย่างเช่นถ้าคุณต้องการเรียงลำดับผลลัพธ์สุดท้ายด้วยแท็กถ้าคุณเก็บไว้
faysou

12

ฟังก์ชั่นยูทิลิตี้ของฉัน (ฉันมีสิ่งเหล่านี้ในตัว MASH ซึ่งถูกกล่าวถึงในคำถาม):

pr = WriteString["stdout", ##]&;            (* More                           *)
prn = pr[##, "\n"]&;                        (*  convenient                    *)
perr = WriteString["stderr", ##]&;          (*   print                        *)
perrn = perr[##, "\n"]&;                    (*    statements.                 *)
re = RegularExpression;                     (* I wish mathematica             *)
eval = ToExpression[cat[##]]&;              (*  weren't so damn               *)
EOF = EndOfFile;                            (*   verbose!                     *)
read[] := InputString[""];                  (* Grab a line from stdin.        *)
doList[f_, test_] :=                        (* Accumulate list of what f[]    *)
  Most@NestWhileList[f[]&, f[], test];      (*  returns while test is true.   *)
readList[] := doList[read, #=!=EOF&];       (* Slurp list'o'lines from stdin. *)
cat = StringJoin@@(ToString/@{##})&;        (* Like sprintf/strout in C/C++.  *)
system = Run@cat@##&;                       (* System call.                   *)
backtick = Import[cat["!", ##], "Text"]&;   (* System call; returns stdout.   *)
slurp = Import[#, "Text"]&;                 (* Fetch contents of file as str. *)
                                            (* ABOVE: mma-scripting related.  *)
keys[f_, i_:1] :=                           (* BELOW: general utilities.      *)
  DownValues[f, Sort->False][[All,1,1,i]];  (* Keys of a hash/dictionary.     *)
SetAttributes[each, HoldAll];               (* each[pattern, list, body]      *)
each[pat_, lst_, bod_] := ReleaseHold[      (*  converts pattern to body for  *)
  Hold[Cases[Evaluate@lst, pat:>bod];]];    (*   each element of list.        *)
some[f_, l_List] := True ===                (* Whether f applied to some      *)
  Scan[If[f[#], Return[True]]&, l];         (*  element of list is True.      *)
every[f_, l_List] := Null ===               (* Similarly, And @@ f/@l         *)
  Scan[If[!f[#], Return[False]]&, l];       (*  (but with lazy evaluation).   *)

สำหรับฟังก์ชั่น "แต่ละคน" ดูstackoverflow.com/questions/160216/foreach-loop-in-mathematica
dreeves

11

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

foo[x_] := x + 1;
expr : foo[___] /; (Message[foo::argx, foo, Length@Unevaluated[expr], 1]; 
                    False) := Null; (* never reached *)

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

นอกจากนี้ในหมวดหมู่ "metaprogramming" ถ้าคุณมีแพคเกจ Mathematica ( .m) แฟ้มคุณสามารถใช้"HeldExpressions"องค์ประกอบHoldCompleteที่จะได้รับการแสดงออกทั้งหมดในไฟล์ห่อ สิ่งนี้ทำให้การติดตามสิ่งต่างๆง่ายกว่าการใช้การค้นหาด้วยข้อความ น่าเสียดายที่ไม่มีวิธีง่ายๆในการทำสิ่งเดียวกันกับโน้ตบุ๊ก แต่คุณสามารถรับนิพจน์อินพุตทั้งหมดโดยใช้สิ่งต่อไปนี้:

inputExpressionsFromNotebookFile[nb_String] :=
 Cases[Get[nb],
  Cell[BoxData[boxes_], "Input", ___] :>
   MakeExpression[StripBoxes[boxes], StandardForm],
  Infinity]

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

ClearAll[MakeStack, StackInstance, EmptyQ, Pop, Push, Peek]
 With[{emptyStack = Unique["empty"]},
  Attributes[StackInstance] = HoldFirst;
  MakeStack[] :=
   Module[{backing = emptyStack},
    StackInstance[backing]];

  StackInstance::empty = "stack is empty";

  EmptyQ[StackInstance[backing_]] := (backing === emptyStack);

  HoldPattern[
    Pop[instance : StackInstance[backing_]]] /;
    ! EmptyQ[instance] || (Message[StackInstance::empty]; False) :=
   (backing = Last@backing; instance);

  HoldPattern[Push[instance : StackInstance[backing_], new_]] :=
   (backing = {new, backing}; instance);

  HoldPattern[Peek[instance : StackInstance[backing_]]] /;
    ! EmptyQ[instance] || (Message[StackInstance::empty]; False) :=
   First@backing]

ตอนนี้คุณสามารถพิมพ์องค์ประกอบของรายการในลำดับย้อนกลับในลักษณะที่ซับซ้อนโดยไม่จำเป็น!

With[{stack = MakeStack[], list},
 Do[Push[stack, elt], {elt, list}];

 While[!EmptyQ[stack],
  Print[Peek@stack];
  Pop@stack]]

1
+1 สำหรับHeldExpressionsองค์ประกอบในแพ็คเกจไม่ทราบ ฉันมักจะนำเข้าเป็นสตริงแล้วใช้ToExpressionพร้อมด้วยHoldCompleteหาเรื่องล่าสุด เกี่ยวกับการใช้Conditionข้อความ - นี่เป็นเทคนิคมาตรฐานในการเขียนแพ็คเกจตั้งแต่อย่างน้อยปี 1994 เกี่ยวกับการคงอยู่ผ่านModulevars - ฉันได้โพสต์ข้อความยาว ๆ ใน Mathgroup มานานแล้ว: groups.google.com/group/comp.soft- sys.math.mathematica / … (โพสต์ที่สามของฉันในเธรดนั้น) อยู่ในบรรทัดเดียวกันและมีลิงก์ไปยังตัวอย่างการใช้งานที่แปลกประหลาด
Leonid Shifrin

@ Leonid Shifrin: ฉันหยิบConditionสิ่งที่เป็นตำนานอาจมาจากเพื่อนร่วมงาน แต่ไม่ได้ตระหนักว่ามันเป็นเทคนิคมาตรฐาน ลิงค์เกี่ยวกับการใช้Moduleสัญลักษณ์เป็นประเภทการอ้างอิงเป็นเรื่องที่น่าสนใจ!
Pillsy

+1 ฉันไม่เคยคิดเลย ยิ่งฉันเรียนรู้เกี่ยวกับภาษานี้มากเท่าไหร่ก็ยิ่งมีพลังมากขึ้นเท่านั้น
rcollyer

@Pillsy จุดประสงค์ในการทำสแต็คเป็นอย่างไร
Mr.Wizard

@ Mr.Wizard: ฉันเลือกโครงสร้างข้อมูลที่ไม่แน่นอนที่ง่ายที่สุดที่ฉันสามารถนึกได้เพื่อแสดงให้เห็นถึงเทคนิค
Pillsy

11

คำจำกัดความสัญลักษณ์ระบบการพิมพ์ที่ไม่มีบริบทไว้ล่วงหน้า

contextFreeDefinition[]ฟังก์ชั่นดังต่อไปนี้จะพยายามที่จะพิมพ์ความหมายของสัญลักษณ์โดยไม่มีบริบทที่พบมากที่สุดใช้ได้ คำจำกัดความนั้นสามารถคัดลอกไปยัง Workbench และจัดรูปแบบเพื่อให้สามารถอ่านได้ (เลือกคลิกขวาที่แหล่งที่มา -> รูปแบบ)

Clear[commonestContexts, contextFreeDefinition]

commonestContexts[sym_Symbol, n_: 1] := Quiet[
  Commonest[
   Cases[Level[DownValues[sym], {-1}, HoldComplete], 
    s_Symbol /; FreeQ[$ContextPath, Context[s]] :> Context[s]], n],
  Commonest::dstlms]

contextFreeDefinition::contexts = "Not showing the following contexts: `1`";

contextFreeDefinition[sym_Symbol, contexts_List] := 
 (If[contexts =!= {}, Message[contextFreeDefinition::contexts, contexts]];
  Internal`InheritedBlock[{sym}, ClearAttributes[sym, ReadProtected];
   Block[{$ContextPath = Join[$ContextPath, contexts]}, 
    Print@InputForm[FullDefinition[sym]]]])

contextFreeDefinition[sym_Symbol, context_String] := 
 contextFreeDefinition[sym, {context}]

contextFreeDefinition[sym_Symbol] := 
 contextFreeDefinition[sym, commonestContexts[sym]]

withRules []

Caveat: ฟังก์ชั่นนี้จะไม่ จำกัด วงตัวแปรในลักษณะเดียวกันWithและModuleทำซึ่งหมายความว่าโครงสร้างการแปลที่ซ้อนกันจะไม่ทำงานตามที่คาดไว้ withRules[{a -> 1, b -> 2}, With[{a=3}, b_ :> b]] จะแทนที่aและbซ้อนกันWithและRuleในขณะที่Withไม่ทำเช่นนี้

นี่คือตัวแปรWithที่ใช้กฎแทน=และ:=:

ClearAll[withRules]
SetAttributes[withRules, HoldAll]
withRules[rules_, expr_] :=
  Internal`InheritedBlock[
    {Rule, RuleDelayed},
    SetAttributes[{Rule, RuleDelayed}, HoldFirst];
    Unevaluated[expr] /. rules
  ]

ฉันพบว่ามีประโยชน์ในขณะที่ทำความสะอาดโค้ดที่เขียนระหว่างการทดสอบและการแปลตัวแปร {par1 -> 1.1, par2 -> 2.2}บางครั้งผมจบลงด้วยรายการพารามิเตอร์ในรูปแบบของ ด้วยwithRulesค่าพารามิเตอร์ง่ายต่อการแทรกลงในรหัสก่อนหน้านี้เขียนโดยใช้ตัวแปรทั่วโลก

การใช้งานเป็นเช่นWith:

withRules[
  {a -> 1, b -> 2},
  a+b
]

การลบรอยหยักกราฟิก 3D

นี่เป็นเทคนิคที่ง่ายมากในการสร้างกราฟิก antialias แม้ว่าฮาร์ดแวร์กราฟิกของคุณจะไม่รองรับก็ตาม

antialias[g_, n_: 3] := 
  ImageResize[Rasterize[g, "Image", ImageResolution -> n 72], Scaled[1/n]]

นี่คือตัวอย่าง:

กราฟิกทางคณิตศาสตร์ กราฟิกทางคณิตศาสตร์

โปรดทราบว่าค่าขนาดใหญ่สำหรับnหรือขนาดของภาพขนาดใหญ่มีแนวโน้มที่จะแสดงข้อบกพร่องของไดรเวอร์กราฟิกหรือแนะนำสิ่งประดิษฐ์


ฟังก์ชั่น diff โน๊ตบุ๊ค

ฟังก์ชันการทำงานของโน้ตบุ๊ค diff มีให้ใน<<AuthorTools`แพ็คเกจและ (อย่างน้อยในรุ่น 8) ในNotebookTools`บริบทที่ไม่มีเอกสาร นี่เป็น GUI เล็กน้อยเพื่อแยกโน้ตบุ๊กสองตัวที่เปิดอยู่ในปัจจุบัน:

PaletteNotebook@DynamicModule[
  {nb1, nb2}, 
  Dynamic@Column[
    {PopupMenu[Dynamic[nb1], 
      Thread[Notebooks[] -> NotebookTools`NotebookName /@ Notebooks[]]], 
     PopupMenu[Dynamic[nb2], 
      Thread[Notebooks[] -> NotebookTools`NotebookName /@ Notebooks[]]], 
     Button["Show differences", 
      CreateDocument@NotebookTools`NotebookDiff[nb1, nb2]]}]
  ]

กราฟิกทางคณิตศาสตร์


ทั้งหมดจะดี แต่ไม่ได้จริงๆจำกัดตัวแปรที่คุณสามารถดูโดยการกำหนดพูดก่อนที่จะโทรตัวอย่างของคุณแล้วโทรa = 3; b = 4; คุณสามารถบันทึกได้โดยการแทนการใช้ต่อไปนี้:withRules SetAttributes[withRules, HoldAll];withRules[rules_, expr_] := Unevaluated[expr] /. Unevaluated[rules]ความแตกต่างความหมายของ WRT Withแล้ว: 1 rhsides ของกฎในขณะนี้จะไม่ได้รับการประเมิน 2. withRulesไม่สามารถแก้ไขความขัดแย้งในการตั้งชื่อที่มีการกำหนดขอบเขตโครงสร้างภายในเป็นWithไม่ อันสุดท้ายค่อนข้างจริงจัง - เป็นเรื่องดีหรือไม่ดีแล้วแต่กรณี
Leonid Shifrin

@ Leonid คุณพูดถูกต้องดูเหมือนว่าฉันไม่เคยเรียนรู้เกี่ยวกับการตรวจสอบรหัสอย่างถูกต้องก่อนโพสต์ ... เมื่อฉันใช้สิ่งนี้ฉันแทบไม่เคยกำหนดค่าให้กับตัวแปร แต่เป็นปัญหาที่ร้ายแรงมากคุณพูดถูก คุณคิดอย่างไรกับเวอร์ชันที่แก้ไขแล้ว? (ฉันไม่สนใจว่าจะไม่จัดการกับWiths ซ้อนกันมันไม่ได้ทำงานกับการสร้าง localin เช่นWith[{a=1}, Block[{a=2}, a]]กันคุณคิดว่ามีเหตุผลที่ดีไหมที่nested Blockไม่ได้ จำกัด อยู่ที่นั่นเช่น nested WithและModuleไม่?)
Szabolcs

@ Leonid ฉันไม่ได้ใช้เพียงUnevaluated[rules]เพราะฉันต้องการx -> 1+1ประเมิน RHS
Szabolcs

@ Leonid คุณจริงถูกต้องปัญหาการแปลหลายระดับอาจค่อนข้างร้ายแรง ฉันคิดว่าWiths ซ้อนกันง่ายต่อการมองเห็นและหลีกเลี่ยง แต่รูปแบบไม่ได้: With[{a = 1}, a_ -> a]localize ในaขณะที่withRulesไม่ คุณรู้หรือไม่ว่ามีวิธีใดบ้างที่จะเข้าถึงกลไกการโลคัลไลเซชั่นการแปลภายในของ Mathematica และสร้างโครงสร้างใหม่ (คล้ายกับRule) ซึ่งยัง จำกัด วงด้วย? ฉันอาจจะลบคำตอบนี้ในภายหลังเพราะมันอันตรายกว่ามีประโยชน์ แต่ฉันต้องการเล่นกับมันก่อน
Szabolcs

ฉันคิดว่าการใช้งานของคุณInheritedBlockนั้นยอดเยี่ยมและแก้ปัญหาได้อย่างสวยงาม สำหรับความขัดแย้งในการกำหนดขอบเขตโดยปกติการผูกสำหรับการกำหนดขอบเขตคำศัพท์เกิดขึ้นที่ "เวลาการรวมคำศัพท์" ซึ่งคือ - ก่อนเวลารันไทม์ขณะที่การกำหนดขอบเขตแบบไดนามิกผูกที่เวลารันไทม์ซึ่งอาจอธิบายได้ คุณสามารถเปรียบเทียบกับกรณีที่คล้ายกันModuleซึ่งอนุญาตให้ใช้งานได้อย่างสร้างสรรค์ (ดูที่นี่เช่นstackoverflow.com/questions/7394113/… ) ปัญหาคือว่าBlockต้องการสัญลักษณ์บางอย่างเพื่อ ...
Leonid Shifrin

9

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

ClearAll[setNew, componentsBFLS];
setNew[x_, x_] := Null;
setNew[lhs_, rhs_]:=lhs:=Function[Null, (#1 := #0[##]); #2, HoldFirst][lhs, rhs];

componentsBFLS[lst_List] := Module[{f}, setNew @@@ Map[f, lst, {2}];
   GatherBy[Tally[Flatten@lst][[All, 1]], f]];

จะเกิดอะไรขึ้นที่นี่เป็นที่แรกที่เรา map สัญลักษณ์หุ่นในแต่ละหมายเลขจุดสุดยอดและการตั้งค่าวิธีการที่ได้รับการจับคู่ของจุดแล้ว{f[5],f[10]}พูดแล้วจะประเมินf[5] f[10]ฟังก์ชั่นบริสุทธิ์แบบเรียกซ้ำใช้เป็นเครื่องอัดพา ธ (เพื่อตั้งค่าการบันทึกในลักษณะที่แทนที่จะใช้โซ่ยาว ๆ เช่นf[1]=f[3],f[3]=f[4],f[4]=f[2], ...ค่าที่บันทึกไว้จะได้รับการแก้ไขทุกครั้งที่ค้นพบ "รูท" ใหม่ของส่วนประกอบ เนื่องจากเราใช้การมอบหมายเราจึงจำเป็นต้องเป็นโฮลด์ทั้งหมดซึ่งทำให้โครงสร้างนี้ยิ่งคลุมเครือและน่าดึงดูดยิ่งขึ้น) ฟังก์ชั่นนี้เป็นผลมาจากการพูดคุยทางคณิตศาสตร์แบบเปิดและปิดที่เกี่ยวข้องกับ Fred Simons, Szabolcs Horvat, DrMajorBob และของคุณอย่างแท้จริง ตัวอย่าง:

In[13]:= largeTest=RandomInteger[{1,80000},{40000,2}];

In[14]:= componentsBFLS[largeTest]//Short//Timing
Out[14]= {0.828,{{33686,62711,64315,11760,35384,45604,10212,52552,63986,  
     <<8>>,40962,7294,63002,38018,46533,26503,43515,73143,5932},<<10522>>}}

มันช้ากว่าในตัว แต่สำหรับขนาดของรหัส IMO ยังค่อนข้างเร็ว

อีกตัวอย่างหนึ่ง: นี่คือการเรียกซ้ำSelectโดยยึดตามรายการที่เชื่อมโยงและฟังก์ชันบริสุทธิ์แบบเรียกซ้ำ:

selLLNaive[x_List, test_] :=
  Flatten[If[TrueQ[test[#1]],
     {#1, If[#2 === {}, {}, #0 @@ #2]},
     If[#2 === {}, {}, #0 @@ #2]] & @@ Fold[{#2, #1} &, {}, Reverse[x]]];

ตัวอย่างเช่น,

In[5]:= Block[
         {$RecursionLimit= Infinity},
         selLLNaive[Range[3000],EvenQ]]//Short//Timing

Out[5]= {0.047,{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,
 <<1470>>,2972,2974,2976,2978,2980,2982,2984,2986,2988,2990,
  2992,2994,2996,2998,3000}}

อย่างไรก็ตามมันไม่ได้วนซ้ำอย่างถูกต้องและจะระเบิดสแต็ก (ทำให้เคอร์เนลเสียหาย) สำหรับรายการขนาดใหญ่ นี่คือเวอร์ชันแบบเรียกซ้ำ:

selLLTailRec[x_List, test_] :=
Flatten[
 If[Last[#1] === {},
  If[TrueQ[test[First[#1]]],
   {#2, First[#1]}, #2],
  (* else *)
  #0[Last[#1],
   If[TrueQ[test[First[#1]]], {#2, First[#1]}, #2]
   ]] &[Fold[{#2, #1} &, {}, Reverse[x]], {}]];

ตัวอย่างเช่น,

In[6]:= Block[{$IterationLimit= Infinity},
       selLLTailRec[Range[500000],EvenQ]]//Short//Timing
Out[6]= {2.39,{2,4,6,8,10,12,14,16,18,20,22,
       <<249978>>,499980,499982,499984,499986,499988,499990,499992,
        499994,499996,499998,500000}} 

ฟังก์ชั่นสำหรับอุปกรณ์ที่เชื่อมต่อก็ยังคงเป็นที่ชื่นชอบของฉัน :-)
Szabolcs

@ Szabolcs ใช่มันค่อนข้างเท่ห์ คุณและเฟร็ดทำส่วนใหญ่บ๊อบบี้และฉันเพิ่มการปรับแต่งสองสามอย่างเท่านั้น IIRC
Leonid Shifrin

8

นี่คือสูตรจากหนังสือของ Stan Wagon ... ใช้มันเมื่อมีการแปลงในตัวทำงานผิดปกติเนื่องจากขาดความแม่นยำ

Options[PrecisePlot] = {PrecisionGoal -> 6};
PrecisePlot[f_, {x_, a_, b_}, opts___] := Module[{g, pg},
   pg = PrecisionGoal /. {opts} /. Options[PrecisePlot];
   SetAttributes[g, NumericFunction];
   g[z_?InexactNumberQ] := Evaluate[f /. x -> z];
   Plot[N[g[SetPrecision[y, \[Infinity]]], pg], {y, a, b},
    Evaluate[Sequence @@ FilterRules[{opts}, Options[Plot]]]]];

ฉันมักจะใช้เคล็ดลับต่อไปนี้จาก Kristjan Kannike เมื่อฉันต้องการพฤติกรรม "เหมือนพจนานุกรม" จากการลดลงของ Mathematica

index[downvalue_, 
   dict_] := (downvalue[[1]] /. HoldPattern[dict[x_]] -> x) // 
   ReleaseHold;
value[downvalue_] := downvalue[[-1]];
indices[dict_] := 
  Map[#[[1]] /. {HoldPattern[dict[x_]] -> x} &, DownValues[dict]] // 
   ReleaseHold;
values[dict_] := Map[#[[-1]] &, DownValues[dict]];
items[dict_] := Map[{index[#, dict], value[#]} &, DownValues[dict]];
indexQ[dict_, index_] := 
  If[MatchQ[dict[index], HoldPattern[dict[index]]], False, True];

(* Usage example: *)
(* Count number of times each subexpression occurs in an expression *)
expr = Cos[x + Cos[Cos[x] + Sin[x]]] + Cos[Cos[x] + Sin[x]]
Map[(counts[#] = If[indexQ[counts, #], counts[#] + 1, 1]; #) &, expr, Infinity];
items[counts]

เมื่อผลการประเมินมีความสับสนบางครั้งก็ช่วยดัมพ์ขั้นตอนการประเมินลงในไฟล์ข้อความ

SetAttributes[recordSteps, HoldAll];
recordSteps[expr_] :=
 Block[{$Output = List@OpenWrite["~/temp/msgStream.m"]}, 
  TracePrint[Unevaluated[expr], _?(FreeQ[#, Off] &), 
   TraceInternal -> True];
  Close /@ $Output;
  Thread[Union@
    Cases[ReadList["~/temp/msgStream.m", HoldComplete[Expression]], 
     symb_Symbol /; 
       AtomQ@Unevaluated@symb && 
        Context@Unevaluated@symb === "System`" :> 
      HoldComplete@symb, {0, Infinity}, Heads -> True], HoldComplete]
  ]

(* Usage example: *)
(* puts steps of evaluation of 1+2+Sin[5]) into ~/temp/msgStream.m *)
recordSteps[1+2+Sin[5]]

ตัวอย่างการใช้งานจะยอดเยี่ยม ลองโพสต์หนึ่งเมื่อคุณมีเวลา
ดร. เบลิซาเรี

คุณรู้จัก Kristjan หรือไม่? ฉันเคยทำงานในกลุ่มเดียวกันกับเขาในเฮลซิงกิ นิสัยดีโลกใบเล็ก
Timo

ไม่พบรหัสของเขาบนเว็บ ที่จริงแล้วพยายามส่งอีเมลถึงเขาเพื่อแก้ไขข้อบกพร่องเล็ก ๆ ในรหัส แต่อีเมลบนหน้าเว็บของเขาไม่ทำงานอีกต่อไป
Yaroslav Bulatov

8

เป็นไปได้ที่จะรัน MathKernel ในโหมดแบตช์โดยใช้ตัวเลือกบรรทัดคำสั่งที่-batchinput-batchoutputไม่มีเอกสารและ :

math -batchinput -batchoutput < input.m > outputfile.txt

(โดยที่input.mไฟล์อินพุตแบตช์ที่ลงท้ายด้วยอักขระบรรทัดใหม่outputfile.txtคือไฟล์ที่เอาต์พุตจะถูกเปลี่ยนทิศทาง)

ในMathematica v.> = 6 MathKernel มีตัวเลือกบรรทัดคำสั่งที่ไม่มีเอกสาร:

-noicon

ซึ่งควบคุมว่า MathKernel จะมีไอคอนที่มองเห็นได้บนแถบงาน (อย่างน้อยใน Windows)

FrontEnd (อย่างน้อยจาก v.5) มีตัวเลือกบรรทัดคำสั่งที่ไม่มีเอกสาร

-b

ซึ่งปิดการใช้งานหน้าจอเริ่มต้นและอนุญาตให้เรียกใช้Mathematica FrontEnd เร็วขึ้นมาก

และตัวเลือก

-directlaunch

ซึ่งปิดการใช้งานกลไกที่เปิดตัวล่าสุดรุ่นMathematicaล่าสุดที่ติดตั้งแทนการเปิดตัวรุ่นที่เกี่ยวข้องกับไฟล์. nb ในรีจิสทรีของระบบ

อีกวิธีในการทำเช่นนี้อาจเป็นไปได้ เป็น :

แทนที่จะเรียกใช้ Mathematica.exe แบบไบนารีในไดเรกทอรีการติดตั้งให้เรียกใช้แบบไบนารี Mathematica.exe ใน SystemFiles \ FrontEnd \ Binaries \ Windows ในอดีตเป็นโปรแกรมตัวเรียกใช้งานแบบง่ายซึ่งพยายามที่จะเปลี่ยนเส้นทางการร้องขอสำหรับการเปิดโน้ตบุ๊กไปยังการทำสำเนาส่วนต่อประสานผู้ใช้ ส่วนหลังคือไบนารีส่วนต่อประสานผู้ใช้

มันเป็นการรวมตัวเลือกบรรทัดคำสั่งสุดท้ายเข้ากับการตั้งค่าตัวเลือก FrontEnd แบบโกลบอลVersionedPreferences->True ซึ่งปิดใช้งานการแชร์การกำหนดค่าตามความชอบระหว่างการติดตั้งMathematicaรุ่นต่างๆ :

SetOptions[$FrontEnd, VersionedPreferences -> True]

(ควรจะประเมินข้างต้นในล่าสุด เวอร์ชั่นMathematica ที่ติดตั้งล่าสุด)

ในMathematica 8นี้จะถูกควบคุมในกล่องโต้ตอบการตั้งค่าในบานหน้าต่างด้านระบบภายใต้การตั้งค่า "สร้างและการบำรุงรักษาการตั้งค่าส่วนหน้ารุ่นที่เฉพาะเจาะจง"

เป็นไปได้ที่จะได้รับรายการที่ไม่สมบูรณ์ของตัวเลือกบรรทัดคำสั่งของ FrontEnd โดยใช้คีย์ที่ไม่มีเอกสาร-h(รหัสสำหรับ Windows):

SetDirectory[$InstallationDirectory <> 
   "\\SystemFiles\\FrontEnd\\Binaries\\Windows\\"];
Import["!Mathematica -h", "Text"]

ให้:

Usage:  Mathematica [options] [files]
Valid options:
    -h (--help):  prints help message
    -cleanStart (--cleanStart):  removes existing preferences upon startup
    -clean (--clean):  removes existing preferences upon startup
    -nogui (--nogui):  starts in a mode which is initially hidden
    -server (--server):  starts in a mode which disables user interaction
    -activate (--activate):  makes application frontmost upon startup
    -topDirectory (--topDirectory):  specifies the directory to search for resources and initialization files
    -preferencesDirectory (--preferencesDirectory):  specifies the directory to search for user AddOns and preference files
    -password (--password):  specifies the password contents
    -pwfile (--pwfile):  specifies the path for the password file
    -pwpath (--pwpath):  specifies the directory to search for the password file
    -b (--b):  launches without the splash screen
    -min (--min):  launches as minimized

ตัวเลือกอื่น ๆ ได้แก่ :

-directLaunch:  force this FE to start
-32:  force the 32-bit FE to start
-matchingkernel:  sets the frontend to use the kernel of matching bitness
-Embedding:  specifies that this instance is being used to host content out of process

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

คำถามที่เกี่ยวข้อง


"จับคู่เป็นพยาน?" นั่นหมายความว่าอย่างไร?
Mr.Wizard

@ Mr.Wizard อาจเป็นไปได้ว่าตัวเลือกนี้มีความรู้สึกภายใต้ระบบ 64 บิตร่วมกับตัวเลือก-32และหมายความว่าการเป็นสักขีพยานของ MathKernel ที่ใช้โดย FrontEnd จะจับคู่กับระบบปฏิบัติการ (64 บิต) ดูเหมือนว่าในกรณีอื่นตัวเลือกนี้จะไม่เปลี่ยนแปลงอะไรเลย
Alexey Popkov

7

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

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

  1. ทำให้สมุดบันทึกมีบริบทส่วนตัวโหลดแพคเกจฉันต้องการทำให้บันทึกอัตโนมัติ
  2. หลังจากทำงานกับสมุดบันทึกนี้มาระยะหนึ่งแล้วฉันต้องการที่จะทำการคำนวณรอยขีดข่วนในสมุดบันทึกแยกต่างหากโดยมีบริบทส่วนตัวของตัวเองในขณะที่สามารถเข้าถึงคำจำกัดความที่ฉันใช้ในสมุดบันทึก "หลัก" เนื่องจากฉันตั้งค่าบริบทส่วนตัวสิ่งนี้จึงจำเป็นต้องปรับ $ ContextPath ด้วยตนเอง

การทำทั้งหมดนี้ด้วยมือซ้ำแล้วซ้ำอีกเป็นความเจ็บปวดดังนั้นให้อัตโนมัติ! ขั้นแรกให้โค้ดยูทิลิตี้บางตัว:

(* Credit goes to Sasha for SelfDestruct[] *)
SetAttributes[SelfDestruct, HoldAllComplete];
SelfDestruct[e_] := (If[$FrontEnd =!= $Failed,
   SelectionMove[EvaluationNotebook[], All, EvaluationCell]; 
   NotebookDelete[]]; e)

writeAndEval[nb_,boxExpr_]:=(
    NotebookWrite[nb,  CellGroupData[{Cell[BoxData[boxExpr],"Input"]}]];
    SelectionMove[nb, Previous, Cell]; 
    SelectionMove[nb, Next, Cell];
    SelectionEvaluate[nb];
)

ExposeContexts::badargs = 
  "Exposed contexts should be given as a list of strings.";
ExposeContexts[list___] := 
 Module[{ctList}, ctList = Flatten@List@list; 
  If[! MemberQ[ctList, Except[_String]],AppendTo[$ContextPath, #] & /@ ctList, 
   Message[ExposeContexts::badargs]];
  $ContextPath = DeleteDuplicates[$ContextPath];
  $ContextPath]

    Autosave[x:(True|False)] := SetOptions[EvaluationNotebook[],NotebookAutoSave->x];

ทีนี้มาสร้างมาโครที่จะใส่เซลล์ต่อไปนี้ลงในสมุดบันทึก:

SetOptions[EvaluationNotebook[], CellContext -> Notebook]
Needs["LVAutils`"]
Autosave[True]

และนี่คือแมโคร:

MyPrivatize[exposedCtxts : ({__String} | Null) : Null]:=
  SelfDestruct@Module[{contBox,lvaBox,expCtxtBox,assembledStatements,strList},
    contBox = MakeBoxes[SetOptions[EvaluationNotebook[], CellContext -> Notebook]];
    lvaBox = MakeBoxes[Needs["LVAutils`"]];

    assembledStatements = {lvaBox,MakeBoxes[Autosave[True]],"(*********)"};
    assembledStatements = Riffle[assembledStatements,"\[IndentingNewLine]"]//RowBox;
    writeAndEval[InputNotebook[],contBox];
    writeAndEval[InputNotebook[],assembledStatements];
    If[exposedCtxts =!= Null,
       strList = Riffle[("\"" <> # <> "\"") & /@ exposedCtxts, ","];
       expCtxtBox = RowBox[{"ExposeContexts", "[", RowBox[{"{", RowBox[strList], "}"}], "]"}];
       writeAndEval[InputNotebook[],expCtxtBox];
      ]
 ]

ตอนนี้เมื่อฉันพิมพ์MyPrivatize[]คือสร้างบริบทส่วนตัวและโหลดแพ็คเกจมาตรฐานของฉัน ตอนนี้เรามาสร้างคำสั่งที่จะเปิดสมุดบันทึกรอยขีดข่วนใหม่ด้วยบริบทส่วนตัวของมันเอง (เพื่อให้คุณสามารถแฮ็คที่นั่นด้วยการละทิ้งโดยไม่ต้องเสี่ยงต่อการไขคำจำกัดความ) แต่สามารถเข้าถึงบริบทปัจจุบันของคุณได้

SpawnScratch[] := SelfDestruct@Module[{nb,boxExpr,strList},
    strList = Riffle[("\"" <> # <> "\"") & /@ $ContextPath, ","];
    boxExpr = RowBox[{"MyPrivatize", "[",
        RowBox[{"{", RowBox[strList], "}"}], "]"}];
    nb = CreateDocument[];
    writeAndEval[nb,boxExpr];
]

สิ่งที่ยอดเยี่ยมเกี่ยวกับเรื่องนี้คือเนื่องจากSelfDestructเมื่อคำสั่งรันคำสั่งจะไม่ทิ้งร่องรอยในสมุดบันทึกปัจจุบัน - ซึ่งดีเพราะไม่เช่นนั้นจะสร้างความยุ่งเหยิง

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


7

เพิ่มผนวกกับ PageWidth -> Infinity

ในMathematica การใช้PutAppendคำสั่งเป็นวิธีที่ตรงไปตรงมาที่สุดในการรักษาไฟล์บันทึกการทำงานที่มีผลลัพธ์ของการคำนวณระดับกลาง แต่จะใช้PageWith->78การตั้งค่าเริ่มต้นเมื่อส่งออกนิพจน์ไปยังไฟล์ดังนั้นจึงไม่มีการรับประกันว่าเอาต์พุตกลางทุกอันจะใช้เวลาเพียงหนึ่งบรรทัดในบันทึก

PutAppendไม่มีตัวเลือกใด ๆ แต่การติดตามผลการประเมินพบว่ามันขึ้นอยู่กับOpenAppendฟังก์ชั่นที่มีPageWithตัวเลือกและอนุญาตให้เปลี่ยนค่าเริ่มต้นโดยSetOptionsคำสั่ง:

In[2]:= Trace[x>>>"log.txt",TraceInternal->True]
Out[2]= {x>>>log.txt,{OpenAppend[log.txt,CharacterEncoding->PrintableASCII],OutputStream[log.txt,15]},Null}

เพื่อให้เราสามารถPutAppendต่อท้ายบรรทัดเดียวโดยการตั้งค่า:

SetOptions[OpenAppend, PageWidth -> Infinity]

UPDATE

มีข้อบกพร่องในรุ่น 10 (แก้ไขในรุ่น 11.3): SetOptionsไม่มีผลต่อพฤติกรรมของOpenWriteและOpenAppendและ

วิธีแก้ปัญหาคือการใช้เวอร์ชันของคุณเองPutAppendด้วยPageWidth -> Infinityตัวเลือกที่ชัดเจน:

Clear[myPutAppend]
myPutAppend[expr_, pathtofile_String] :=
 (Write[#, expr]; Close[#];) &[OpenAppend[pathtofile, PageWidth -> Infinity]]

โปรดทราบว่าเราอาจใช้มันผ่านทางWriteStringตามที่แสดงในนี้คำตอบ แต่ในกรณีนี้มันจะมีความจำเป็นที่จะแสดงออกในเบื้องต้นแปลงลงในที่สอดคล้องกันผ่านทางInputFormToString[expr, InputForm]


6

ฉันแค่มองผ่านหนึ่งในแพ็คเกจของฉันเพื่อรวมไว้ในนี้และพบว่ามีข้อความบางส่วนที่ฉันกำหนดไว้ว่าสิ่งมหัศจรรย์ในการทำงาน: Debug::<some name>. โดยค่าเริ่มต้นพวกเขาจะปิดดังนั้นอย่าผลิตมากเกินไป แต่ฉันสามารถทิ้งรหัสไว้กับพวกเขาและเปิดใช้งานได้หากฉันต้องการทราบว่ารหัสมีพฤติกรรมอย่างไร


จาก The Help> ตั้งแต่ Version 2.0 (วางจำหน่ายในปี 1991) Debug ได้ถูกแทนที่โดย Trace
ดร. เบลิซาเรี

1
@belisarius คุณพลาดจุดนี้ไป มันเป็นทั้งDebugมิได้Traceฟังก์ชั่น; มันเป็นชุดของข้อความที่ฉันสร้างขึ้นที่ฉันสามารถทิ้งขยะรหัสของฉันด้วยเพื่อเปิด / ปิดได้ตามต้องการ พวกเขาจะถูกนำหน้าด้วยคำว่าDebugในทำนองเดียวกันusagemsg จะถูกนำหน้าด้วยชื่อของฟังก์ชั่น มันมีฟังก์ชั่นเช่นเดียวกับการวางcoutงบจำนวนมากในรหัส c ++
rcollyer

1
โอ้ ... ขอโทษ ฉันสับสนเพราะฉันไม่เคยเรียนจบจากโรงเรียนอนุบาลเพราะไม่เรียน "เมืองหลวงสำหรับประเทศ": D
Dr. belisarius

6

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

With[{a = 5, b = 2 * a},
    ...
]

เมื่อไม่นานมานี้ฉันได้พบกับแมโครชื่อว่า WithNest ที่ให้คุณทำสิ่งนี้ได้ ฉันพบว่ามันมีประโยชน์เพราะมันช่วยให้คุณสามารถเชื่อมโยงตัวแปรภายในเครื่องโดยไม่ต้องทำอะไร

Module[{a = 5,b},
    b = 2 * a;
    ...
]

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

หากคุณต้องการทดลองใช้ให้ใส่คำสั่งต่อไปนี้ลงในไฟล์ชื่อScoping.m:

BeginPackage["Scoping`"];

WithNest::usage=
"WithNest[{var1=val1,var2=val2,...},body] works just like With, except that
values are evaluated in order and later values have access to earlier ones.
For example, val2 can use var1 in its definition.";

Begin["`Private`"];

(* Set up a custom symbol that works just like Hold. *)
SetAttributes[WithNestHold,HoldAll];

(* The user-facing call.  Give a list of bindings and a body that's not
our custom symbol, and we start a recursive call by using the custom
symbol. *)
WithNest[bindings_List,body:Except[_WithNestHold]]:=
WithNest[bindings,WithNestHold[body]];

(* Base case of recursive definition *)
WithNest[{},WithNestHold[body_]]:=body;

WithNest[{bindings___,a_},WithNestHold[body_]]:=
WithNest[
{bindings},
WithNestHold[With[List@a,body]]];

SyntaxInformation[WithNest]={"ArgumentsPattern"->{{__},_}};
SetAttributes[WithNest,{HoldAll,Protected}];

End[];

EndPackage[];

Janus โพสต์เวอร์ชันนี้และอ้างอิงคำถามของคุณใน MathGroup: stackoverflow.com/questions/4190845/custom-notation-question/ …
Mr.Wizard

ขอบคุณสำหรับการชี้ให้เห็น! ไม่นานมานี้ที่ฉันได้ดูสิ่งนี้และน่าสนใจที่จะเห็นวิธีการอื่น ๆ เหล่านี้ทั้งหมด
DGrady

5

อันนี้เขียนโดย Alberto Di Lullo (ผู้ที่ไม่ปรากฏใน Stack Overflow)

CopyToClipboardสำหรับ Mathematica 7 (ใน Mathematica 8 สร้างขึ้นแล้ว)

CopyToClipboard[expr_] := 
  Module[{nb}, 
   nb = CreateDocument[Null, Visible -> False, WindowSelected -> True];
   NotebookWrite[nb, Cell[OutputFormData@expr], All];
   FrontEndExecute[FrontEndToken[nb, "Copy"]];
   NotebookClose@nb];

โพสต์ต้นฉบับ: http://forums.wolfram.com/mathgroup/archive/2010/Jun/msg00148.html

ฉันพบว่ารูทีนนี้มีประโยชน์สำหรับการคัดลอกจำนวนจริงจำนวนมากไปยังคลิปบอร์ดในรูปแบบทศนิยมปกติ เช่นCopyToClipboard["123456789.12345"]

Cell[OutputFormData@expr] ลบคำพูดออกอย่างเรียบร้อย


5

รหัสนี้ทำให้จานสีที่อัปโหลดส่วนที่เลือกไปยัง Stack Exchange เป็นรูปภาพ บน Windows มีปุ่มพิเศษที่ให้การเรนเดอร์การเลือกที่เที่ยงตรงยิ่งขึ้น

คัดลอกรหัสลงในเซลล์โน้ตบุ๊คและประเมินผล จากนั้นเปิดพาเลตต์จากเอาต์พุตและติดตั้งโดยใช้Palettes -> Install Palette...

หากคุณมีปัญหาใด ๆ กับมันแสดงความคิดเห็นที่นี่ ดาวน์โหลดรุ่นโน๊ตบุ๊คที่นี่


Begin["SOUploader`"];

Global`palette = PaletteNotebook@DynamicModule[{},

   Column[{
     Button["Upload to SE",
      With[{img = rasterizeSelection1[]},
       If[img === $Failed, Beep[], uploadWithPreview[img]]],
      Appearance -> "Palette"],

     If[$OperatingSystem === "Windows",

      Button["Upload to SE (pp)",
       With[{img = rasterizeSelection2[]},
        If[img === $Failed, Beep[], uploadWithPreview[img]]],
       Appearance -> "Palette"],

      Unevaluated@Sequence[]
      ]
     }],

   (* Init start *)
   Initialization :>
    (

     stackImage::httperr = "Server returned respose code: `1`";
     stackImage::err = "Server returner error: `1`";

     stackImage[g_] :=
      Module[
       {getVal, url, client, method, data, partSource, part, entity,
        code, response, error, result},

       getVal[res_, key_String] :=
        With[{k = "var " <> key <> " = "},
         StringTrim[

          First@StringCases[
            First@Select[res, StringMatchQ[#, k ~~ ___] &],
            k ~~ v___ ~~ ";" :> v],
          "'"]
         ];

       data = ExportString[g, "PNG"];

       JLink`JavaBlock[
        url = "http://stackoverflow.com/upload/image";
        client =
         JLink`JavaNew["org.apache.commons.httpclient.HttpClient"];
        method =
         JLink`JavaNew[
          "org.apache.commons.httpclient.methods.PostMethod", url];
        partSource =
         JLink`JavaNew[
          "org.apache.commons.httpclient.methods.multipart.\
ByteArrayPartSource", "mmagraphics.png",
          JLink`MakeJavaObject[data]@toCharArray[]];
        part =
         JLink`JavaNew[
          "org.apache.commons.httpclient.methods.multipart.FilePart",
          "name", partSource];
        part@setContentType["image/png"];
        entity =
         JLink`JavaNew[
          "org.apache.commons.httpclient.methods.multipart.\
MultipartRequestEntity", {part}, method@getParams[]];
        method@setRequestEntity[entity];
        code = client@executeMethod[method];
        response = method@getResponseBodyAsString[];
        ];

       If[code =!= 200, Message[stackImage::httperr, code];
        Return[$Failed]];
       response = StringTrim /@ StringSplit[response, "\n"];

       error = getVal[response, "error"];
       result = getVal[response, "result"];
       If[StringMatchQ[result, "http*"],
        result,
        Message[stackImage::err, error]; $Failed]
       ];

     stackMarkdown[g_] :=
      "![Mathematica graphics](" <> stackImage[g] <> ")";

     stackCopyMarkdown[g_] := Module[{nb, markdown},
       markdown = Check[stackMarkdown[g], $Failed];
       If[markdown =!= $Failed,
        nb = NotebookCreate[Visible -> False];
        NotebookWrite[nb, Cell[markdown, "Text"]];
        SelectionMove[nb, All, Notebook];
        FrontEndTokenExecute[nb, "Copy"];
        NotebookClose[nb];
        ]
       ];

     (* Returns available vertical screen space,
     taking into account screen elements like the taskbar and menu *)


     screenHeight[] := -Subtract @@
        Part[ScreenRectangle /. Options[$FrontEnd, ScreenRectangle],
         2];

     uploadWithPreview[img_Image] :=
      CreateDialog[
       Column[{
         Style["Upload image to the Stack Exchange network?", Bold],
         Pane[

          Image[img, Magnification -> 1], {Automatic,
           Min[screenHeight[] - 140, 1 + ImageDimensions[img][[2]]]},
          Scrollbars -> Automatic, AppearanceElements -> {},
          ImageMargins -> 0
          ],
         Item[
          ChoiceButtons[{"Upload and copy MarkDown"}, \
{stackCopyMarkdown[img]; DialogReturn[]}], Alignment -> Right]
         }],
       WindowTitle -> "Upload image to Stack Exchange?"
       ];

     (* Multiplatform, fixed-width version.
        The default max width is 650 to fit Stack Exchange *)
     rasterizeSelection1[maxWidth_: 650] :=
      Module[{target, selection, image},
       selection = NotebookRead[SelectedNotebook[]];
       If[MemberQ[Hold[{}, $Failed, NotebookRead[$Failed]], selection],

        $Failed, (* There was nothing selected *)

        target =
         CreateDocument[{}, WindowSelected -> False, Visible -> False,
           WindowSize -> maxWidth];
        NotebookWrite[target, selection];
        image = Rasterize[target, "Image"];
        NotebookClose[target];
        image
        ]
       ];

     (* Windows-only pixel perfect version *)
     rasterizeSelection2[] :=
      If[
       MemberQ[Hold[{}, $Failed, NotebookRead[$Failed]],
        NotebookRead[SelectedNotebook[]]],

       $Failed, (* There was nothing selected *)

       Module[{tag},
        FrontEndExecute[
         FrontEndToken[FrontEnd`SelectedNotebook[], "CopySpecial",
          "MGF"]];
        Catch[
         NotebookGet@ClipboardNotebook[] /.
          r_RasterBox :>
           Block[{},
            Throw[Image[First[r], "Byte", ColorSpace -> "RGB"], tag] /;
              True];
         $Failed,
         tag
         ]
        ]
       ];
     )
   (* Init end *)
   ]

End[];

4

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

แก้ไข

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

รหัสเดิมที่ฉันใช้อยู่ที่ด้านล่าง ขอบคุณความคิดเห็นที่ฉันพบว่ามันเป็นปัญหาและดีกว่ามากที่จะทำในวิธีอื่นโดยใช้ScheduledTask(ซึ่งจะใช้ได้เฉพาะในMathematica 8)

รหัสสำหรับสิ่งนี้สามารถพบได้ในคำตอบนี้จากSjoerd C. de Vries (เนื่องจากฉันไม่แน่ใจว่ามันตกลงที่จะคัดลอกไปที่นี่ฉันทิ้งไว้เป็นลิงค์เท่านั้น)


Dynamicวิธีการแก้ปัญหาด้านล่างใช้ มันจะประหยัดโน้ตบุ๊คทุก 60 วินาที แต่เห็นได้ชัดว่าเฉพาะในกรณีที่เซลล์จะมองเห็นได้ ฉันจะออกจากที่นี่เพียงเพื่อเหตุผลที่ทำให้เสร็จ (และสำหรับผู้ใช้Mathematica 6 และ 7)

/ แก้ไข

ในการแก้ปัญหาฉันใช้รหัสนี้ในตอนต้นของสมุดบันทึก:

Dynamic[Refresh[NotebookSave[]; DateString[], UpdateInterval -> 60]]

สิ่งนี้จะบันทึกงานของคุณทุก ๆ 60 วินาที
ฉันชอบมันมากNotebookAutoSave[]เพราะจะบันทึกก่อนการประมวลผลอินพุตและเนื่องจากไฟล์บางไฟล์เป็นข้อความมากกว่าอินพุต

ฉันพบมันที่นี่: http://en.wikipedia.org/wiki/Talk:Mathematica#Criticisms

โปรดทราบว่าเมื่อเรียกใช้บรรทัดนี้การบันทึกจะเกิดขึ้นแม้ว่าคุณจะปิดและเปิดไฟล์ของคุณอีกครั้ง (ตราบเท่าที่เปิดใช้งานการอัปเดตแบบไดนามิก)

นอกจากนี้เนื่องจากไม่มีการเลิกทำในMathematicaโปรดระวังอย่าลบเนื้อหาทั้งหมดของคุณเนื่องจากการบันทึกจะทำให้ไม่สามารถย้อนกลับได้ (เป็นการย้ายข้อควรระวังฉันจึงลบรหัสนี้ออกจากสมุดบันทึกที่เสร็จสิ้นทุกครั้ง)


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

คุณสามารถทำสิ่งที่ชอบNotebookSave[SelectedNotebook[], "work-" <> IntegerString[i] <> ".nb"]; i++แต่ฉันคิดว่าการอ้างอิงใด ๆ กับชื่อสมุดบันทึกปัจจุบันจะกลายเป็นแบบเรียกซ้ำ
tsvikas

2
ฉันคิดว่าDynamicวัตถุจะได้รับการรีเฟรชเมื่อมองเห็นเท่านั้นดังนั้นฉันจึงไม่แน่ใจว่าวิธีการนี้จะใช้ได้ถ้าคุณเลื่อนDynamicวัตถุออกจากพื้นที่ที่มองเห็น จากนั้นอีกครั้งฉันไม่ได้ลอง ไม่ว่าในกรณีใดฉันเพียง แต่เสนอให้เป็นข้อเสนอแนะ
acl

1
Dynamic[Refresh[i++, UpdateInterval -> 1, TrackedSymbols -> {}]]คุณสามารถทดสอบนี้โดยใช้ เลื่อนจำนวนที่เพิ่มขึ้นจากสายตารอสักครู่เลื่อนกลับและดูหมายเลขที่ไม่ได้เพิ่มขึ้น 60 เกี่ยวกับUpdateInterval: มักจะใช้ถ้าเป็นไปได้ แต่ถ้ารหัสของคุณมีตัวแปรที่เปลี่ยนแปลง ช่วงเวลาสิ้นสุดลง ลองบรรทัดด้านบนโดยไม่ต้องTrackedSymbols
Sjoerd C. de Vries

1
@ j0ker5 ลองใช้โค้ดด้านบนของฉันและคุณจะเห็นว่า UpdateInterval ไม่บังคับให้มีการเว้นระยะอัปเดตตามช่วงเวลาที่ระบุ รหัสนี้ยังแสดงให้เห็นว่าแบบไดนามิกจะทำงานเฉพาะถ้าเซลล์ที่มีอยู่ในที่ปรากฏอยู่ในส่วนหน้า มันหยุดทันทีที่มองไม่เห็น ผู้คนไม่ควรเชื่อถือรหัสนี้เพื่อบันทึกไฟล์เพราะมันไม่ได้ อันตราย
Sjoerd C. de Vries


3

ฉันพบว่ามีประโยชน์จริง ๆ เมื่อพัฒนาแพ็คเกจเพื่อเพิ่มแป้นพิมพ์ลัดนี้ลงในSystemFiles/FrontEnd/TextResources/Windows/KeyEventTranslations.trไฟล์ของฉัน

(* Evaluate Initialization Cells: Real useful for reloading library changes. *)

Item[KeyEvent["i", Modifiers -> {Control, Command}],
    FrontEndExecute[
        FrontEndToken[
            SelectedNotebook[],
            "EvaluateInitialization"]]],

ถัดไปสำหรับทุก ๆPackagename.mฉันทำPackagenameTest.nbสมุดบันทึกสำหรับการทดสอบและ 2 เซลล์แรกของสมุดบันทึกทดสอบตั้งเป็นเซลล์เริ่มต้น ในเซลล์แรกฉันใส่

Needs["PackageManipulations`"]

เพื่อโหลดไลบรารีPackageManipulations ที่มีประโยชน์มากซึ่งเขียนโดย Leonid เซลล์ที่สองประกอบด้วย

PackageRemove["Packagename`Private`"]
PackageRemove["Packagename`"]
PackageReload["Packagename`"]

ซึ่งทั้งหมดทำแพคเกจจริงโหลด หมายเหตุสองบรรทัดแรกนั้นมีเฉพาะกับRemoveสัญลักษณ์ทั้งหมดเท่าที่ฉันต้องการให้บริบทสะอาดที่สุดเท่าที่จะทำได้

จากนั้นเวิร์กโฟลว์สำหรับการเขียนและทดสอบแพคเกจจะกลายเป็นแบบนี้

  1. Packagename.mบันทึกการเปลี่ยนแปลง
  2. ไปและทำPackagenameTest.nbCTRL + ALT + i

ทำให้เซลล์เริ่มต้นโหลดแพคเกจใหม่ซึ่งทำให้การทดสอบง่ายขึ้นจริง


1

ฟังก์ชันต่อไปนี้format[expr_]สามารถใช้เพื่อเยื้อง / จัดรูปแบบmathematicaนิพจน์ที่ไม่ได้จัดรูปแบบซึ่งครอบคลุมทั่วหน้า

indent[str_String, ob_String, cb_String, delim_String] := 
  Module[{ind, indent, f, tab}, ind = 0; tab = "    ";
   indent[i_, tab_, nl_] := nl <> Nest[tab <> ToString[#] &, "", i];
   f[c_] := (indent[ind, "", " "] <> c <> indent[++ind, tab, "\n"]) /;StringMatchQ[ob, ___ ~~ c ~~ ___];
   f[c_] := (indent[--ind, "", " "] <> c <> indent[ind, tab, "\n"]) /;StringMatchQ[cb, ___ ~~ c ~~ ___];
   f[c_] := (c <> indent[ind, tab, "\n"]) /;StringMatchQ[delim, ___ ~~ c ~~ ___];
   f[c_] := c;
   f /@ Characters@str // StringJoin];
format[expr_] := indent[expr // InputForm // ToString, "[({", "])}", ";"];

(*    
format[Hold@Module[{ind, indent, f, tab}, ind = 0; tab = "    ";
 indent[i_, tab_, nl_] := nl <> Nest[tab <> ToString[#] &, "", i];
 f[c_] := (indent[ind, "", " "] <> c <> indent[++ind, tab, "\n"]) /;StringMatchQ[ob, ___ ~~ c ~~ ___];
 f[c_] := (indent[--ind, "", " "] <> c <> indent[ind, tab, "\n"]) /;StringMatchQ[cb, ___ ~~ c ~~ ___];
 f[c_] := (c <> indent[ind, tab, "\n"]) /;StringMatchQ[delim, ___ ~~ c ~~ ___];
 f[c_] := c;
 f /@ Characters@str // StringJoin]]
*)

อ้างอิง: /codegolf/3088/indent-a-string-using-given-parentheses


คุณใช้อะไรในการฝึกซ้อม? ผลลัพธ์เป็นบิต"ตลก"เกินไปที่จะอ่านได้ทั้งเมื่อนำไปใช้กับรหัสของคุณหรือกับข้อมูล (รายการformat@RandomInteger[10,{3,3}]): pastebin.com/nUT54Emq เนื่องจากคุณมีพื้นฐานและสนใจสิ่งนี้แล้วคุณสามารถปรับปรุงรหัสเพื่อ จัดรูปแบบที่อ่านได้ประโยชน์? จากนั้นขั้นตอนต่อไปคือการสร้างปุ่มวางที่จะสร้างเซลล์อินพุตด้วยรหัส Mathematica ที่เยื้องเข้าไปคำถามที่เกี่ยวข้องของฉัน
Szabolcs
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.