web-dev-qa-db-fra.com

Que contient votre sac à outils Mathematica?

Nous savons tous que Mathematica est génial, mais il manque également souvent de fonctionnalités essentielles. Quels types de packages/outils/ressources externes utilisez-vous avec Mathematica?

Je modifierai (et inviterai quelqu'un d'autre à le faire également) ce poste principal pour inclure des ressources qui sont axées sur l'applicabilité générale dans la recherche scientifique et que le plus de personnes possible trouveront utiles. N'hésitez pas à apporter n'importe quoi, même de petits extraits de code (comme je l'ai fait ci-dessous pour une routine de chronométrage).

De plus, les fonctionnalités non documentées et utiles de Mathematica 7 et au-delà, vous vous êtes retrouvé ou déterré à partir de papier/site sont les bienvenues.

Veuillez inclure une brève description ou un commentaire sur les raisons pour lesquelles quelque chose est génial ou sur l'utilité qu'il offre. Si vous créez un lien vers des livres sur Amazon avec des liens d'affiliation, veuillez le mentionner, par exemple, en mettant votre nom après le lien.


Paquets:

  1. LevelScheme est un paquet qui étend considérablement la capacité de Mathematica à produire de bons graphiques. Je l'utilise si ce n'est pour autre chose que pour le contrôle beaucoup, beaucoup amélioré des tics de trame/axes. Sa dernière version s'appelle SciDraw et sortira cette année.
  2. David Park Presentation Package (50 $ US - sans frais pour les mises à jour)
  3. Le package grassmannOps de Jeremy Michelson fournit des ressources pour faire de l'algèbre et du calcul avec des variables et des opérateurs de Grassmann qui ont des relations de commutation non triviales.
  4. John Brown's GrassmannAlgebra package et livre pour travailler avec les algèbres Grassmann et Clifford.
  5. RISC (Research Institute for Symbolic Computation) propose une variété de packages pour Mathematica (et d'autres langues) disponibles en téléchargement. En particulier, il y a Theorema pour la démonstration automatisée des théorèmes, et la multitude de packages pour la sommation symbolique, les équations aux différences, etc. sur la page du logiciel du groupe de combinatoire algorithmique .

Outils:

  1. MASH est l'excellent script Perl de Daniel Reeves fournissant essentiellement un support de script pour Mathematica v7. (Désormais intégré à partir de Mathematica 8 avec le -script option.)
  2. Un alternate Mathematica Shell avec une GNU readline (en utilisant python, * nix uniquement)
  3. Le package ColourMaths vous permet de sélectionner visuellement des parties d'une expression et de les manipuler. http://www.dbaileyconsultancy.co.uk/colour_maths/colour_maths.html

Ressources:

  1. Le propre dépôt de Wolfram MathSource a beaucoup de cahiers utiles si étroits pour diverses applications. Consultez également les autres sections telles que

  2. Le Mathematica Wikibook .

Livres:

  1. Programmation Mathematica: une introduction avancée par Leonid Shifrin ( web , pdf ) est un must lisez si vous voulez faire plus que Pour boucles dans Mathematica. Nous avons le plaisir d'avoir Leonid lui-même répondant aux questions ici.
  2. Méthodes quantiques avec Mathematica par James F. Feagin ( Amazon )
  3. Le livre Mathematica par Stephen Wolfram ( Amazon ) ( web )
  4. Schéma de Schaum ( Amazon )
  5. Mathematica en action par Stan Wagon ( Amazon ) - 600 pages d'exemples soignés et monte à Mathematica version 7. Les techniques de visualisation sont particulièrement bonnes, vous pouvez voir certaines de les sur l'auteur Demonstrations Page .
  6. Mathematica Programming Fundamentals par Richard Gaylord ( pdf ) - Une bonne introduction concise à la plupart de ce que vous devez savoir sur la programmation Mathematica.
  7. Mathematica Cookbook par Sal Mangano publié par O'Reilly 2010 832 pages. - Écrit dans le style bien connu O'Reilly Cookbook: Problème - Solution. Pour les intermédiaires.
  8. Équations différentielles avec Mathematica, 3e éd. Elsevier 2004 Amsterdam par Martha L. Abell, James P. Braselton - 893 pages Pour les débutants, apprenez à résoudre les DE et Mathematica en même temps.

Fonctionnalités non documentées (ou à peine documentées):

  1. Comment personnaliser les raccourcis clavier de Mathematica. Voir this question .
  2. Comment inspecter les modèles et les fonctions utilisés par les propres fonctions de Mathematica. Voir this answer
  3. Comment obtenir une taille cohérente pour GraphPlots dans Mathematica? Voir this question .
  4. Comment produire des documents et des présentations avec Mathematica. Voir this question .
149
Timo

J'ai mentionné this auparavant, mais l'outil que je trouve le plus utile est une application de Reap et Sow qui imite/étend le comportement de GatherBy:

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

Cela me permet de regrouper les listes selon n'importe quel critère et de les transformer dans le processus. La façon dont cela fonctionne est qu'une fonction de critère (f) marque chaque élément de la liste, chaque élément est ensuite transformé par une deuxième fonction fournie (g), et la sortie spécifique est contrôlée par une troisième fonction (h). La fonction h accepte deux arguments: une balise et une liste des éléments collectés qui ont cette balise. Les articles conservent leur ordre d'origine, donc si vous définissez h = #1& alors vous obtenez un Union non trié, comme dans le exemples pour Reap. Mais, il peut être utilisé pour un traitement secondaire.

Comme exemple de son utilité, j'ai travaillé avec Wannier9 qui sort le hamiltonien spatialement dépendant dans un fichier où chaque ligne est un élément différent dans la matrice, comme suit

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

Pour transformer cette liste en un ensemble de matrices, j'ai rassemblé toutes les sous-listes qui contiennent la même coordonnée, transformé les informations d'élément en une règle (c'est-à-dire {i, j} -> Re [Hij] + I Im [Hij]), et puis a transformé les règles collectées en SparseArray le tout avec une seule ligne:

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

Honnêtement, c'est mon couteau suisse, et cela rend les choses complexes très simples. La plupart de mes autres outils sont quelque peu spécifiques au domaine, donc je ne les publierai probablement pas. Cependant, la plupart, sinon tous, font référence à SelectEquivalents.

Edit : il n'imite pas complètement GatherBy en ce qu'il ne peut pas grouper plusieurs niveaux de l'expression comme simplement comme GatherBy peut. Cependant, Map fonctionne très bien pour la plupart de ce dont j'ai besoin.

Exemple : @Yaroslav Bulatov a demandé un exemple autonome. Voici une de mes recherches qui a été grandement simplifiée. Donc, disons que nous avons un ensemble de points dans un avion

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}}

et nous aimerions réduire le nombre de points par un ensemble d'opérations de symétrie. (Pour les curieux, nous générons le petit groupe de chaque point.) Pour cet exemple, utilisons un axe de rotation quadruple autour de l'axe z

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

En utilisant SelectEquivalents nous pouvons regrouper les points qui produisent le même ensemble d'images sous ces opérations, c'est-à-dire qu'ils sont équivalents, en utilisant ce qui suit

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}}}

qui produit 3 sous-listes contenant les points équivalents. (Remarque, Union est absolument vital ici car il garantit que la même image est produite par chaque point. À l'origine, j'utilisais Sort, mais si un point se trouve sur un axe de symétrie, il est invariant sous la rotation autour de cet axe donnant une image supplémentaire de lui-même. Ainsi, Union élimine ces images supplémentaires. De plus, GatherBy produirait le même résultat.) Dans ce cas, les points sont déjà dans un formulaire que j'utiliserai, mais je n'ai besoin que d'un point représentatif de chaque groupe et je voudrais un décompte des points équivalents. Depuis, je n'ai pas besoin de transformer chaque point, j'utilise la fonction Identity en deuxième position. Pour la troisième fonction, nous devons être prudents. Le premier argument qui lui sera transmis sera les images des points sous les rotations qui pour le point {0,0,0} est une liste de quatre éléments identiques, et son utilisation détruirait le décompte. Cependant, le deuxième argument est juste une liste de tous les éléments qui ont cette balise, donc il ne contiendra que {0,0,0}. Dans du code,

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}}

Notez que cette dernière étape peut tout aussi bien être accomplie par

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

Mais, avec cela et l'exemple moins complet ci-dessus, il est facile de voir comment des transformations très complexes sont possibles avec un minimum de code.

29
rcollyer

Une des bonnes choses à propos de l'interface du bloc-notes Mathematica est qu'elle peut évaluer les expressions dans le langage any, pas seulement Mathematica. Comme exemple simple, envisagez de créer un nouveau type de cellule d'entrée Shell qui transmet l'expression contenue au système d'exploitation Shell pour évaluation.

Tout d'abord, définissez une fonction qui délègue l'évaluation d'une commande textuelle au shell externe:

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

Le deuxième argument est nécessaire et ignoré pour des raisons qui apparaîtront plus tard. Ensuite, nous voulons créer un nouveau style appelé Shell:

  1. Ouvrez un nouveau carnet.
  2. Sélectionnez l'élément de menu Formater/Modifier la feuille de style ...
  3. Dans la boîte de dialogue, à côté de Entrez un nom de style: tapez Shell.
  4. Sélectionnez le crochet de cellule à côté du nouveau style.
  5. Sélectionnez l'élément de menu Cell/Show Expression
  6. Remplacez l'expression de la cellule par le texte de l'étape 6 indiqué ci-dessous.
  7. Encore une fois, sélectionnez l'élément de menu Cell/Show Expression
  8. Fermez la boîte de dialogue.

Utilisez l'expression de cellule suivante comme texte de l'étape 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"]

La plupart de cette expression a été copiée directement dans le style intégré Program. Les principaux changements sont les suivants:

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

Evaluatable active la fonctionnalité MAJ + ENTRÉE pour la cellule. L'évaluation appellera le CellEvaluationFunction en passant le contenu de la cellule et le type de contenu comme arguments (shellEvaluate ignore ce dernier argument). CellFrameLabels est juste une subtilité qui permet à l'utilisateur d'identifier que cette cellule est inhabituelle.

Avec tout cela en place, nous pouvons maintenant saisir et évaluer une expression Shell:

  1. Dans le bloc-notes créé dans les étapes ci-dessus, créez une cellule vide et sélectionnez le support de cellule.
  2. Sélectionnez l'élément de menu Format/Style/Shell.
  3. Tapez une commande Shell du système d'exploitation valide dans la cellule (par exemple, `` ls '' sous Unix ou `` dir '' sous Windows).
  4. Appuyez sur MAJ + ENTRÉE.

Il est préférable de conserver ce style défini dans une feuille de style située au centre. De plus, les fonctions d'évaluation comme shellEvaluate sont mieux définies comme des stubs en utilisant DeclarePackage in init.m. Les détails de ces deux activités dépassent le cadre de cette réponse.

Avec cette fonctionnalité, on peut créer des cahiers qui contiennent des expressions d'entrée dans n'importe quelle syntaxe d'intérêt. La fonction d'évaluation peut être écrite en pur Mathematica, ou déléguer tout ou partie de l'évaluation à une agence externe. N'oubliez pas qu'il existe d'autres hooks liés à l'évaluation des cellules, comme CellEpilog, CellProlog et CellDynamicExpression.

Un modèle courant consiste à écrire le texte de l'expression d'entrée dans un fichier temporaire, à compiler le fichier dans une langue, à exécuter le programme et à capturer la sortie pour un affichage final dans la cellule de sortie. Il y a beaucoup de détails à aborder lors de la mise en œuvre d'une solution complète de ce type (comme capturer correctement les messages d'erreur), mais il faut apprécier le fait qu'il est non seulement possible de faire des choses comme ça, mais pratique.

Sur une note personnelle, ce sont des fonctionnalités comme celle-ci qui font de l'interface du notebook le centre de mon univers de programmation.

Mise à jour

La fonction d'assistance suivante est utile pour créer de telles cellules:

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]
  )

Il est utilisé ainsi:

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

Maintenant si shellCell[] est évalué, la cellule d'entrée sera supprimée et remplacée par une nouvelle cellule d'entrée qui évalue son contenu en tant que commande Shell.

57
WReach

Todd Gayley (Wolfram Research) vient de m'envoyer un joli hack qui permet de "boucler" les fonctions intégrées avec du code arbitraire. Je sens que je dois partager cet instrument utile. Ce qui suit est la réponse de Todd sur mon question .

Un peu d'histoire (?) Intéressante: ce style de hack pour "encapsuler" une fonction intégrée a été inventé vers 1994 par Robby Villegas et moi, ironiquement pour la fonction Message, dans un package appelé ErrorHelp que j'ai écrit pour le Mathematica Journal à l'époque. Il a été utilisé à plusieurs reprises, par de nombreuses personnes, depuis lors. C'est un peu un truc d'initié, mais je pense qu'il est juste de dire que c'est devenu la manière canonique d'injecter votre propre code dans la définition d'une fonction intégrée. Il fait bien le travail. Vous pouvez bien sûr placer la variable $ inMsg dans le contexte privé de votre choix.

Unprotect[Message];

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

Protect[Message];
35
Alexey Popkov

Ce n'est pas une ressource complète, donc je la présente ici dans la section des réponses, mais je l'ai trouvée très utile pour résoudre les problèmes de vitesse (ce qui, malheureusement, est une grande partie de la programmation Mathematica).

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};

L'utilisation est alors simplement timeAvg@funcYouWantToTest.

EDIT: Mr. Wizard a fourni une version plus simple qui supprime Throw et Catch et est un peu plus facile à analyser:

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

EDIT: Voici une version de acl (tirée de ici ):

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]
25
Timo

Mathematica est un outil pointu, mais il peut vous couper avec son peu comportement non typé et avalanches de cryptique messages de diagnostic . Une façon de gérer cela est de définir des fonctions suivant cet idiome:

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

C'est beaucoup de passe-partout, que je suis souvent tenté de sauter. Surtout lors du prototypage, ce qui arrive souvent dans Mathematica. Donc, j'utilise une macro appelée define qui me permet de rester discipliné, avec beaucoup moins de passe-partout.

Une utilisation de base de define est comme ceci:

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

fact[5]

120

Cela ne ressemble pas beaucoup au début, mais il y a des avantages cachés. Le premier service fourni par define est qu'il applique automatiquement ClearAll au symbole en cours de définition. Cela garantit qu'il n'y a pas de définitions restantes - un phénomène courant lors du développement initial d'une fonction.

Le deuxième service est que la fonction définie est automatiquement "fermée". J'entends par là que la fonction émettra un message et abandonnera si elle est invoquée avec une liste d'arguments qui ne correspond à aucune des définitions:

fact[-1]

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

Il s'agit de la valeur principale de define, qui détecte une classe d'erreur très courante.

Une autre commodité est une manière concise de spécifier des attributs sur la fonction en cours de définition. Faisons la fonction Listable:

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

fact[{3, 5, 8}]

{6, 120, 40320}

En plus de tous les attributs normaux, define accepte un attribut supplémentaire appelé Open. Cela empêche define d'ajouter la définition d'erreur fourre-tout à la fonction:

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

successor /@ {1, "hi"}

{2, successor["hi"]}

Plusieurs attributs peuvent être définis pour une fonction:

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

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

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

Sans plus tarder, voici la définition de 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: ``";

L'implémentation présentée ne prend en charge ni les valeurs montantes ni le curry, ni les modèles plus généraux que la simple définition de fonction. Cela reste cependant utile.

19
WReach

Commencez sans un carnet vierge ouvert

J'ai été gêné de faire démarrer Mathematica avec un cahier vierge ouvert. Je pourrais fermer ce cahier avec un script, mais il s'ouvrirait tout de même brièvement. Mon hack est de créer un fichier Invisible.nb contenant:

Notebook[{},Visible->False]

Et ajoutez ceci à mon Kernel\init.m:

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

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

Je lance maintenant Mathematica en ouvrant Invisible.nb

Il y a peut-être une meilleure façon, mais cela m'a bien servi.


Fold et FoldList personnalisés

Fold[f, x] est rendu équivalent à Fold[f, First@x, Rest@x]

Soit dit en passant, je pense que cela pourrait trouver sa place dans une future version de Mathematica.

Surprise! Ceci a été implémenté, bien qu'il soit actuellement non documenté. Je suis informé qu'il a été implémenté en 2011 par Oliver Ruebenkoenig , apparemment peu de temps après avoir posté cela. Merci 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]

Mis à jour pour permettre ceci:

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

"Partition dynamique"

Voir Mathematica.SE post # 7512 pour une nouvelle version de cette fonction.

Souvent, je veux partitionner une liste selon une séquence de longueurs.

exemple de pseudo-code:

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

Sortie: {{1,2}, {3,4,5}, {6}}

Je suis venu avec ceci:

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

Ce que j'ai ensuite complété avec ceci, y compris les tests d'arguments:

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

Le troisième argument contrôle ce qui arrive aux éléments au-delà de la spécification de fractionnement.


astuces Mathematica de Szabolcs

Celui que j'utilise le plus fréquemment est la palette de données tabulaires de collage

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"]]]]]}

Modifier des données externes depuis Compile

Récemment, Daniel Lichtblau a montré cette méthode que je n'avais jamais vue auparavant. À mon avis, cela étend considérablement l'utilité de 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.}  *)
16
Mr.Wizard

Problèmes généraux et solutions d'exportation PDF/EMF

1) Il est complètement inattendu et non documenté, mais Mathematica exporte et enregistre les graphiques aux formats PDF et EPS en utilisant un ensemble des définitions de style qui diffèrent de celle utilisée pour afficher les blocs-notes à l'écran. Par défaut, les blocs-notes sont affichés à l'écran dans l'environnement de style "Fonctionnement" (qui est la valeur par défaut de ScreenStyleEvironment global $FrontEnd option) mais sont imprimés dans le "Printout" environnement de style (qui est la valeur par défaut pour PrintingStyleEnvironment global $FrontEnd option). Quand on exporte des graphiques dans des formats raster tels que GIF et PNG ou au format EMF Mathematica génère des graphiques qui ressemblent exactement à il regarde à l'intérieur de Notebook. Il semble que le "Working" L'environnement de style est utilisé pour le rendu dans ce cas. Mais ce n'est pas le cas lorsque vous exportez/enregistrez quoi que ce soit aux formats PDF ou EPS! Dans ce cas, le "Printout" l'environnement de style est utilisé par défaut qui diffère très profondément de l'environnement de style "Working". Tout d'abord, le "Printout" L'environnement de style définit Magnification à 80% . Deuxièmement, il utilise ses propres valeurs pour les tailles de police de différents styles, ce qui entraîne des changements de taille de police incohérents dans le fichier généré PDF par rapport à la représentation originale à l'écran. Cette dernière peut être appelé FontSize fluctuations qui sont très ennuyeux. Mais heureusement, cela peut être évité en définissant le PrintingStyleEnvironment global $FrontEnd option pour "Travailler" :

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

2) Le problème courant avec l'exportation au format EMF est que la plupart des programmes (pas seulement Mathematica ) génèrent un fichier qui a l'air bien à la taille par défaut mais devient moche lorsque vous l'agrandissez. C'est parce que les métafichiers sont échantillonnés à la fidélité de résolution d'écran . La qualité du fichier EMF EMF $ === généré peut être amélioré en Magnifying l'objet graphique d'origine afin que l'exactitude de l'échantillonnage des graphiques originaux devienne beaucoup plus précise. Comparez deux fichiers:

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

Si vous insérez ces fichiers dans Microsoft Word et les zoomez, vous verrez que le premier "a" a des dents de scie alors que le second ne l'a pas (testé avec Mathematica 6).

Chris Degnen une autre voie à travers ImageResolution a été suggérée == (cette option a un effet au moins à partir de Mathematica 8):

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

3) Dans Mathematica nous avons trois façons de convertir les graphiques en métafichier: via Export en "EMF" (méthode fortement recommandée: produit un métafichier de la meilleure qualité possible), via Save selection As... élément de menu ( produit un chiffre beaucoup moins précis , non recommandé) et via Edit ► Copy As ► Metafile élément de menu ( je déconseille fortement cette route ).

14
Alexey Popkov

Mettre en cache des expressions

Je trouve ces fonctions très utiles pour mettre en cache n'importe quelle expression. La chose intéressante ici pour ces deux fonctions est que l'expression maintenue elle-même est utilisée comme clé de la table de hachage/symbole Cache ou CacheIndex, par rapport à la mémorisation bien connue dans Mathemica où vous ne pouvez mettre en cache le résultat que si la fonction est définie comme f [x_]: = f [x] = ... Vous pouvez donc mettre en cache n'importe quelle partie d'un code, ceci est utile si une fonction doit être appelée plusieurs fois mais que certaines parties du code ne doivent pas être recalculées.

Pour mettre en cache une expression indépendamment de ses arguments.

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

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

La deuxième fois, l'expression renvoie 6 sans attendre.

Pour mettre en cache une expression à l'aide d'une expression d'alias qui peut dépendre d'un argument de l'expression mise en cache.

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

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

Si expr prend un certain temps à calculer, il est beaucoup plus rapide d'évaluer {"f", 2} par exemple pour récupérer le résultat mis en cache.

Pour une variation de ces fonctions afin d'avoir un cache localisé (c'est-à-dire que la mémoire cache est automatiquement libérée en dehors de la construction Block) voir ce post Évitez les appels répétés à l'interpolation

Suppression de valeurs mises en cache

Pour supprimer les valeurs mises en cache lorsque vous ne connaissez pas le nombre de définitions d'une fonction. Je considère que les définitions ont un blanc quelque part dans leurs arguments.

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

Pour supprimer les valeurs mises en cache lorsque vous connaissez le nombre de définitions d'une fonction (va légèrement plus vite).

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

Cela utilise le fait que les définitions d'une fonction se trouvent à la fin de leur liste DownValues, les valeurs mises en cache sont antérieures.

Utilisation de symboles pour stocker des données et des fonctions de type objet

Voici également des fonctions intéressantes pour utiliser des symboles comme des objets.

Il est déjà bien connu que vous pouvez stocker des données dans des symboles et y accéder rapidement en utilisant DownValues

mysymbol["property"]=2;

Vous pouvez accéder à la liste des clés (ou propriétés) d'un symbole en utilisant ces fonctions en fonction de ce que dreeves a soumis dans un post sur ce site:

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

J'utilise beaucoup cette fonction pour afficher toutes les informations contenues dans les DownValues ​​d'un symbole:

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

Enfin, voici un moyen simple de créer un symbole qui se comporte comme un objet dans la programmation orientée objet (il reproduit juste le comportement le plus basique de OOP mais je trouve la syntaxe élégante):

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
  ];

Les propriétés sont stockées en tant que DownValues ​​et les méthodes en tant que Upvalues ​​retardées dans le symbole créé par Module qui est renvoyé. J'ai trouvé la syntaxe pour function2 qui est la syntaxe OO habituelle pour les fonctions dans Structure de données arborescente dans Mathematica .

Pour une liste des types de valeurs existants de chaque symbole, voir http://reference.wolfram.com/mathematica/tutorial/PatternsAndTransformationRules.html et http: //www.verbeia. com/mathématique/astuces/HTMLLinks/Tricks_Misc_4.html .

Par exemple, essayez ceci

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

Vous pouvez aller plus loin si vous souhaitez émuler l'héritage d'objets à l'aide d'un package appelé InheritRules disponible ici http://library.wolfram.com/infocenter/MathSource/671/

Vous pouvez également stocker la définition de fonction non pas dans newObject mais dans un symbole de type, donc si NewObject retourne le type [newObject] au lieu de newObject, vous pouvez définir function et function2 comme ceci en dehors de NewObject (et non à l'intérieur) et avoir le même usage qu'auparavant .

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

Utilisez UpValues ​​[type] pour voir que la fonction et la fonction2 sont définies dans le symbole de type.

D'autres idées sur cette dernière syntaxe sont présentées ici https://mathematica.stackexchange.com/a/999/66 .

Version améliorée de SelectEquivalents

@rcollyer: Merci beaucoup d'avoir apporté SelectEquivalents à la surface, c'est une fonction incroyable. Voici une version améliorée de SelectEquivalents listée ci-dessus avec plus de possibilités et d'utilisation d'options, cela la rend plus facile à utiliser.

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]]
      ]
   ];

Voici des exemples d'utilisation de cette version:

tilisation correcte de Mathematica Gather/Collect

Comment feriez-vous une fonction de tableau croisé dynamique dans Mathematica?

algorithme de binning 2D Mathematica rapide

Internal`Bag

Daniel Lichtblau décrit ici une structure de données interne intéressante pour les listes croissantes.

Implémentation d'un Quadtree dans Mathematica

Fonctions de débogage

Ces deux articles indiquent des fonctions utiles pour le débogage:

Comment déboguer lors de l'écriture de petits ou grands codes à l'aide de Mathematica? Workbench? Mma debugger? Ou autre chose? (ShowIt)

https://stackoverflow.com/questions/5459735/the-clearest-way-to-represent-mathematicas-evaluation-sequence/5527117#5527117 (TraceView)

Voici une autre fonction basée sur Reap et Sow pour extraire des expressions de différentes parties d'un programme et les stocker dans un symbole.

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

Voici un exemple

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*)

Autres ressources

Voici une liste de liens intéressants à des fins d'apprentissage:

ne collection de ressources d'apprentissage Mathematica

Mis à jour ici: https://mathematica.stackexchange.com/a/259/66

13
Faysal Aberkane

À la demande générale, le code pour générer le top-10 SO plot de répondeurs (sauf annotations ) en utilisant SO API .

enter image description here

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", ""})]
13
Sjoerd C. de Vries

Mes fonctions utilitaires (je les ai intégrées à MASH, ce qui est mentionné dans la question):

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).   *)
12
dreeves

Définition des définitions de symboles du système sans contexte ajouté

Le contextFreeDefinition[] la fonction ci-dessous tentera d'imprimer la définition d'un symbole sans le contexte le plus courant ajouté. La définition peut ensuite être copiée dans Workbench et formatée pour la lisibilité (sélectionnez-la, faites un clic droit, Source -> Format)

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 []

Avertissement: Cette fonction ne localise pas les variables de la même manière que With et Module, ce qui signifie que les constructions de localisation imbriquées ne fonctionneront pas comme prévu. withRules[{a -> 1, b -> 2}, With[{a=3}, b_ :> b]] remplacera a et b dans les imbriqués With et Rule, tandis que With ne le fait pas.

Il s'agit d'une variante de With qui utilise des règles au lieu de = et :=:

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

J'ai trouvé cela utile lors du nettoyage du code écrit pendant l'expérimentation et la localisation des variables. Parfois, je me retrouve avec des listes de paramètres sous la forme de {par1 -> 1.1, par2 -> 2.2}. Avec withRules, les valeurs des paramètres sont faciles à injecter dans du code précédemment écrit à l'aide de variables globales.

L'utilisation est comme With:

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

Graphiques 3D anti-crénelage

Il s'agit d'une technique très simple pour l'antialias des graphiques 3D, même si votre matériel graphique ne le prend pas en charge de manière native.

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

Voici un exemple:

Mathematica graphicsMathematica graphics

Notez qu'une grande valeur pour n ou une grande taille d'image a tendance à exposer les bogues du pilote graphique ou à introduire des artefacts.


Fonctionnalité de diff pour ordinateur portable

La fonctionnalité de comparaison des ordinateurs portables est disponible dans le <<AuthorTools` package, et (au moins dans la version 8) dans le document non documenté NotebookTools` le contexte. Voici une petite interface graphique pour différencier deux ordinateurs portables actuellement ouverts:

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]]}]
  ]

Mathematica graphics

11
Szabolcs

Une astuce que j'ai utilisée, qui vous permet d'émuler la façon dont la plupart des fonctions intégrées fonctionnent avec de mauvais arguments (en envoyant un message puis en renvoyant le formulaire entier sans évaluation) exploite une bizarrerie de la manière Condition fonctionne lorsqu'il est utilisé dans une définition. Si foo ne devrait fonctionner qu'avec un seul argument:

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

Si vous avez des besoins plus complexes, il est facile de prendre en compte la validation des arguments et la génération de messages en tant que fonction indépendante. Vous pouvez faire des choses plus élaborées en utilisant des effets secondaires dans Condition au-delà de la simple génération de messages, mais à mon avis, la plupart d'entre eux entrent dans la catégorie "hack louche" et doivent être évités si possible.

De plus, dans la catégorie "métaprogrammation", si vous avez un package Mathematica (.m), vous pouvez utiliser le fichier "HeldExpressions" element pour obtenir toutes les expressions du fichier enveloppé dans HoldComplete. Cela rend le suivi des choses beaucoup plus facile que l'utilisation de recherches textuelles. Malheureusement, il n'y a pas de moyen facile de faire la même chose avec un ordinateur portable, mais vous pouvez obtenir toutes les expressions d'entrée en utilisant quelque chose comme ceci:

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

Enfin, vous pouvez utiliser le fait que Module émule des fermetures lexicales pour créer l'équivalent des types de référence. Voici une pile simple (qui utilise une variante de l'astuce Condition pour la gestion des erreurs en bonus):

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]

Vous pouvez maintenant imprimer les éléments d'une liste dans l'ordre inverse d'une manière inutilement alambiquée!

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

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

Les fonctions récursives pures (#0) Semblent être l'un des coins les plus sombres du langage. Voici quelques exemples non triviaux de leur utilisation, où cela est vraiment utile (pas qu'ils ne puissent pas se faire sans). Ce qui suit est une fonction assez concise et assez rapide pour trouver les composants connectés dans un graphique, étant donné une liste d'arêtes spécifiées sous forme de paires de sommets:

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]];

Ce qui se passe ici, c'est que nous mappons d'abord un symbole fictif sur chacun des nombres de sommets, puis configurons une manière qui, étant donné une paire de sommets {f[5],f[10]}, Disons, alors f[5] Serait évalué à f[10]. La fonction récursive pure est utilisée comme compresseur de chemin (pour configurer la mémorisation de telle manière qu'au lieu de longues chaînes comme f[1]=f[3],f[3]=f[4],f[4]=f[2], ..., Les valeurs mémorisées soient corrigées chaque fois qu'une nouvelle "racine" du composant est découverte. Cela donne une accélération importante. Parce que nous utilisons l'affectation, nous avons besoin que ce soit HoldAll, ce qui rend cette construction encore plus obscure et plus attrayante). Cette fonction est le résultat d'une discussion Mathgroup en ligne et hors ligne impliquant Fred Simons, Szabolcs Horvat, DrMajorBob et le vôtre. Exemple:

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>>}}

Il est certainement beaucoup plus lent qu'un intégré, mais pour la taille du code, assez rapide encore IMO.

Autre exemple: voici une réalisation récursive de Select, basée sur des listes liées et des fonctions pures récursives:

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

Par exemple,

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}}

Cependant, il n'est pas correctement récursif et fera exploser la pile (plantera le noyau) pour les listes plus grandes. Voici la version queue récursive:

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]], {}]];

Par exemple,

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}} 
9
Leonid Shifrin

Ceci est une recette du livre de Stan Wagon ... utilisez-la lorsque le tracé intégré se comporte de manière irrégulière en raison d'un manque de précision

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]]]]];

J'utilise souvent l'astuce suivante de Kristjan Kannike lorsque j'ai besoin d'un comportement "semblable à un dictionnaire" des valeurs de 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]

Lorsque les résultats de l'évaluation prêtent à confusion, il est parfois utile de vider les étapes de l'évaluation dans un fichier texte

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]]
8
Yaroslav Bulatov

Il est possible d'exécuter MathKernel en mode batch en utilisant non documenté options de ligne de commande -batchinput et -batchoutput :

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

(où input.m est le fichier d'entrée par lots se terminant par le caractère de nouvelle ligne, outputfile.txt est le fichier vers lequel la sortie sera redirigée).

Dans Mathematica v.> = 6 le MathKernel a une option de ligne de commande non documentée:

-noicon

qui contrôle si le MathKernel aura une icône visible dans la barre des tâches (au moins sous Windows).

Le FrontEnd (au moins à partir de la v.5) a une option de ligne de commande non documentée

-b

ce qui désactive l'écran de démarrage et permet d'exécuter le Mathematica FrontEnd beaucoup plus rapidement

et option

-directlaunch

qui désactive le mécanisme qui lance la version la plus récente Mathematica installée au lieu de lancer la version associée aux fichiers .nb dans le registre système.

Une autre façon de le faire est probablement est :

Au lieu de lancer le binaire Mathematica.exe dans le répertoire d'installation, lancez le binaire Mathematica.exe dans SystemFiles\FrontEnd\Binaries\Windows. Le premier est un programme de lancement simple qui fait de son mieux pour rediriger les demandes d'ouverture de cahiers vers des copies en cours d'exécution de l'interface utilisateur. Ce dernier est le binaire de l'interface utilisateur lui-même.

Il est pratique de combiner la dernière option de ligne de commande avec la définition de l'option globale FrontEnd VersionedPreferences->Truequi désactive le partage des préférences entre différentes Mathematica versions installées :

SetOptions[$FrontEnd, VersionedPreferences -> True]

(Ce qui précède doit être évalué dans la version la plus récente Mathematica installée.)

Dans Mathematica 8 ceci est contrôlé dans la boîte de dialogue Préférences, dans le volet Système, sous le paramètre "Créer et maintenir des préférences front-end spécifiques à la version" .

Il est possible d'obtenir une liste incomplète des options de ligne de commande du FrontEnd en utilisant la clé non documentée -h (le code pour Windows):

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

donne:

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

Les autres options incluent:

-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

Existe-t-il d'autres options de ligne de commande potentiellement utiles du MathKernel et du FrontEnd? Veuillez partager si vous le savez.

Question connexe .

8
Alexey Popkov

Mes hacks préférés sont de petites macros génératrices de code qui vous permettent de remplacer un tas de commandes standard standard par une courte. Alternativement, vous pouvez créer des commandes pour ouvrir/créer des cahiers.

Voici ce que j'utilise depuis un certain temps dans mon flux de travail Mathematica au quotidien. Je me suis retrouvé à faire beaucoup de choses comme suit:

  1. Faites en sorte qu'un bloc-notes ait un contexte privé, chargez les packages dont j'ai besoin, enregistrez-les automatiquement.
  2. Après avoir travaillé avec ce bloc-notes pendant un certain temps, je voudrais faire quelques calculs à gratter dans un bloc-notes séparé, avec son propre contexte privé, tout en ayant accès aux définitions que j'ai utilisées dans le bloc-notes "principal". Parce que j'ai configuré le contexte privé, cela nécessite d'ajuster manuellement $ ContextPath

Faire tout cela à la main, encore et encore, est pénible, alors automatisons! Tout d'abord, un code utilitaire:

(* 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];

Maintenant, créons une macro qui va mettre les cellules suivantes dans le cahier:

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

Et voici la macro:

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];
      ]
 ]

Maintenant, quand je tape MyPrivatize[] is crée le contexte privé et charge mon package standard. Créons maintenant une commande qui ouvrira un nouveau bloc-notes avec son propre contexte privé (afin que vous puissiez y pirater avec un abandon sauvage sans risque de bousiller les définitions), mais a accès à vos contextes actuels.

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

La chose intéressante à ce sujet est qu'en raison de SelfDestruct, lorsque la commande s'exécute, elle ne laisse aucune trace dans le bloc-notes actuel - ce qui est bien, car sinon cela créerait simplement de l'encombrement.

Pour des points de style supplémentaires, vous pouvez créer des déclencheurs de mots clés pour ces macros en utilisant InputAutoReplacements, mais je laisserai cela comme un exercice pour le lecteur.

7
Leo Alekseyev

PutAppend avec PageWidth -> Infinity

Dans Mathematica l'utilisation de la commande PutAppend est le moyen le plus simple de maintenir un fichier journal en cours d'exécution avec les résultats des calculs intermédiaires. Mais il utilise par défaut PageWith->78 paramètre lors de l'exportation d'expressions dans un fichier et il n'y a donc aucune garantie que chaque sortie intermédiaire ne prendra qu'une seule ligne dans le journal.

PutAppend n'a aucune option lui-même mais le suivi de ses évaluations révèle qu'elle est basée sur la fonction OpenAppend qui a l'option PageWith et permet de changer sa valeur par défaut par SetOptions commande:

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

Nous pouvons donc demander à PutAppend d'ajouter une seule ligne à la fois en définissant:

SetOptions[OpenAppend, PageWidth -> Infinity]

[~ # ~] mise à jour [~ # ~]

Il y a un bug introduit dans la version 10 (corrigé dans la version 11.3): SetOptions n'affecte plus le comportement de OpenWrite et OpenAppend.

Une solution consiste à implémenter votre propre version de PutAppend avec explicit PageWidth -> Infinity option:

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

Notez que nous pouvons également l'implémenter via WriteString comme indiqué dans la réponse this , mais dans ce cas, il sera nécessaire de convertir au préalable l'expression dans le InputForm correspondant via ToString[expr, InputForm].

7
Alexey Popkov

L'une des choses qui me dérange dans les constructions de portée intégrées est qu'elles évaluent toutes les définitions de variables locales à la fois, vous ne pouvez donc pas écrire par exemple

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

Il y a quelque temps, j'ai créé une macro appelée WithNest qui vous permet de le faire. Je le trouve pratique, car il vous permet de garder les liaisons de variables locales sans avoir à faire quelque chose comme

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

En fin de compte, la meilleure façon de le faire était d'utiliser un symbole spécial pour faciliter la récurrence sur la liste des liaisons, et j'ai mis la définition dans son propre package pour garder ce symbole caché. Peut-être que quelqu'un a une solution plus simple à ce problème?

Si vous voulez l'essayer, mettez ce qui suit dans un fichier appelé 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[];
6
DGrady

Je cherchais juste à travers l'un de mes packages pour l'inclure dans ceci, et j'ai trouvé quelques messages que j'ai définis qui fonctionnent à merveille: Debug::<some name>. Par défaut, ils sont désactivés, donc ne générez pas beaucoup de surcharge. Mais, je peux jeter mon code avec eux, et les activer si j'ai besoin de comprendre exactement comment se comporte un peu de code.

6
rcollyer

Ce code crée une palette qui télécharge la sélection vers Stack Exchange sous forme d'image. Sous Windows, un bouton supplémentaire est fourni pour un rendu plus fidèle de la sélection.

Copiez le code dans une cellule de cahier et évaluez. Ensuite, sortez la palette de la sortie et installez-la à l'aide de Palettes -> Install Palette...

Si vous rencontrez des problèmes, postez un commentaire ici. Téléchargez la version portable ici .


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[];
5
Szabolcs

Celui-ci a été écrit par Alberto Di Lullo, (qui ne semble pas être sur Stack Overflow).

CopyToClipboard, pour Mathematica 7 (dans Mathematica 8 il est intégré)

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

Message d'origine: http://forums.wolfram.com/mathgroup/archive/2010/Jun/msg00148.html

J'ai trouvé cette routine utile pour copier de grands nombres réels dans le presse-papiers sous forme décimale ordinaire. Par exemple. CopyToClipboard["123456789.12345"]

Cell[OutputFormData@expr] supprime soigneusement les guillemets.

4
Chris Degnen

Je suis sûr que beaucoup de gens ont rencontré la situation où ils exécutent des trucs, réalisant que non seulement ils ont bloqué le programme, mais ils ont aussi n'ont pas enregistré pendant les 10 dernières minutes !

MODIFIER

Après avoir souffert de cela pendant un certain temps, j'ai découvert un jour que on pouvait créer une sauvegarde automatique à partir du Mathematica = code. Je pense que l'utilisation d'une telle sauvegarde automatique m'a beaucoup aidé dans le passé, et j'ai toujours pensé que la possibilité elle-même était quelque chose que peu de gens savent qu'ils peuvent faire.

Le code d'origine que j'ai utilisé est en bas. Grâce aux commentaires, j'ai découvert que c'est problématique, et qu'il vaut mieux le faire d'une manière alternative, en utilisant ScheduledTask (qui ne fonctionnera qu'en Mathematica = 8).

Le code pour cela peut être trouvé dans cette réponse de Sjoerd C. de Vries (Étant donné que je ne suis pas sûr de pouvoir le copier ici, je le laisse uniquement sous forme de lien.)


La solution ci-dessous utilise Dynamic. Il enregistrera le bloc-notes toutes les 60 secondes, mais apparemment uniquement si sa cellule est visible . Je le laisse ici uniquement pour des raisons d'achèvement. (et pour les utilisateurs de Mathematica 6 et 7)

/MODIFIER

Pour le résoudre j'utilise ce code au début d'un cahier:

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

Cela permettra d'économiser votre travail toutes les 60 secondes.
Je le préfère à NotebookAutoSave[] car il enregistre avant le traitement de l'entrée et parce que certains fichiers contiennent plus de texte que l'entrée.

Je l'ai trouvé à l'origine ici: http://en.wikipedia.org/wiki/Talk:Mathematica#Criticisms

Notez qu'une fois cette ligne exécutée, l'enregistrement se produira même si vous fermez et rouvrez votre fichier (tant que la mise à jour dynamique est activée).

De plus, comme il n'y a pas d'annulation dans Mathematica, veillez à ne pas supprimer tout votre contenu, car l'enregistrement le rendra irréversible (par mesure de précaution, je supprime ce code de chaque carnet fini)

4
tsvikas

N'oubliez pas que The Mathematica Book est également disponible en ligne sur http://reference.wolfram.com/legacy/v5_2/ - bien qu'il soit remplacé par la documentation actuelle sur http: // reference. wolfram.com

3
Bill White

Je trouve très utile lors du développement de packages d'ajouter ce raccourci clavier à mon SystemFiles/FrontEnd/TextResources/Windows/KeyEventTranslations.tr fichier.

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

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

Suivant pour chaque Packagename.m Je fais un PackagenameTest.nb notebook pour le test et les 2 premières cellules du notebook de test sont définies comme cellules d'initialisation. Dans la première cellule, je mets

Needs["PackageManipulations`"]

pour charger la bibliothèque très utile PackageManipulations qui a été écrite par Leonid. La deuxième cellule contient

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

qui effectuent tous le rechargement du package. Notez que les deux premières lignes sont là uniquement pour Remove tous les symboles car j'aime garder les contextes aussi propres que possible.

Ensuite, le flux de travail pour écrire et tester un package devient quelque chose comme ça.

  1. Enregistrer les modifications Packagename.m.
  2. Aller à PackagenameTest.nb et fait CTRL + ALT + i.

Cela provoque le rechargement du package par les cellules d'initialisation, ce qui rend le test très simple.

3
nixeagle

Fonction suivante format[expr_] peut être utilisé pour mettre en retrait/formater des expressions mathematica non formatées qui s'étendent sur une page

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]]
*)

réf: https://codegolf.stackexchange.com/questions/3088/indent-a-string-using-given-parentheses

1
Prashant Bhate