# Tag Info

75

Preamble I had a talk devoted specifically to this topic, on Second Russian WTC in 2014. Unfortunately, it is in Russian. But I will try to summarize it here. Since this post is becoming too long, I decided to split it to several smaller ones, each dedicated to some particular set of methods / techniques. This one will contain a general / conceptual ...

71

A "lazy list", "functional style" solution to this problem might look something like this: sIntegers[] ~sMap~ Prime ~sFilter~ palindromicQ ~sTake~ 400 // sList No such notation is built into Mathematica. However, creating such notations is Mathematica's strong suit. Let's do it. First, we need to define the notion of a "stream". Streams are inherently ...

41

These three functions are similar (speaking commonly), and in some applications any of them could be used, yet they have very different special applications. Rudimentarily: Map wraps (sub)expressions in a given Head, and returns the modified input Apply replaces Heads in (sub)expressions, and returns the modified input Scan "visits" (sub)expressions, ...

40

Here are some advices from my experience. Explore new ideas with the Mathematica frontend. Don't hesitate to use sections and subsections in the frontend to structure your work and experiment various possibilities. When you have instructions that work, package them into functions, still in the frontend. It's practical to select all the useful ...

38

It is good practice to check the precedence of code that is not behaving as you expect. One of the easiest ways to do this is to use Ctrl+. to expand the selection outward from the cursor while respecting Mathematica precedence. Converting the expression to StandardForm (Ctrl+Shift+N) will often reveal something about the way Mathematica is parsing your ...

37

Managing the complexity, II: controlling complexity on the smaller scale There are a few things you can do to control and reduce the complexity of your code, even on the small scale - long before you move to packages and split code into several files. Effective use of the core data structures This is probably the first thing to mention. The most important ...

35

Going out on a limb here, but the exhibited expression looks like a brave but flawed attempt to implement the Y-combinator extremely concisely. The Y-combinator is a technical trick used to implement recursion in the lambda calculus. Here is an implementation that stoops to using some symbols: Y[f_] := #[#]&[Function[n, f[#[#]][n]]&] ... and ...

33

One way to get the lazy aspect is to use a closure, or the closest way for Mathematica to fake a closure. This is the closures constructor: makePalindromePrimeC[start_: 1] := Module[{p = Prime[start], r}, ((r = NestWhile[NextPrime, p, With[{d = IntegerDigits[#]}, d != Reverse[d]] &]); p = NextPrime[r]; r) &] This creates one: ...

33

Function has the attribute HoldAll, so the reference to i in the Table expression will not be expanded. However, you can use With to inject the value into the held expressions: Table[With[{i = i}, a[[i]]*Sin[#] &], {i, 3}] (* {a[[1]] Sin[#1] &, a[[2]] Sin[#1] &, a[[3]] Sin[#1] &} *)

29

Updated with new functions and additional timings Since this question inspired so many answers I think there is as need to compare them. I have included two of my own functions, freely borrowing from previous answers: wizard1[] := Inner[Compose, sel /. {True -> f, False -> Identity}, list, List] wizard2[] := Module[{x = list}, x[[#]] = f /@ x[[#]];...

29

Clearly the @ notation is inspired by the usual mathematical notation for function composition. f@g[x] looks very similar to the mathematical notation $(f\circ g)(x)$. But it is important to understand that @ does not denote function composition. In mathematical notation $f\circ g$ is also a function. In Mathematica f@x is simply a different way to ...

28

As explained by Michael Pilat you cannot create your own compound operators* with custom precedence. (You could conceivably write your own parser as Leonid has worked on, or attempt to coerce the Box form with CellEvaluationFunction.) You can however use an existing operator with the desired precedence. Looking at the table Colon appears to be a good ...

26

Since you're learning, I'll show you how to break down your procedural function midpointRK into bare parts and reassemble it in a functional style. FoldList will again be the function of choice here, so since you're already familiar with it, I'll skip the explanation on that. First, observe that ta, tb and h0 are all constants, so there is no need to ...

26

Good News Everyone! Two-parameter syntax for Fold and FoldList has been (silently) implemented! Taliesin Beynon informs me that this was implemented in 2011, so check your older versions as well. As Naitree notes this is now documented in 10.0.2: Fold[f, a] FoldList[f, a] f[f[f[1, 2], 3], 4] {1, f[1, 2], f[f[1, 2], 3], f[f[f[1, 2], 3], 4]} And ...

26

Managing the complexity III: using powerful abstractions In this section I will list a few techniques which allow one to write more modular code and better separate the concerns, by using certain powerful abstractions provided by or possible to have in the Mathematica. Higher-order functions These are functions which take other functions as arguments. In ...

23

Due to insistent public demand: If, in a sequence of iterates $\{x,f(x),f(f(x)),\dots\}$, one only needs every $k$-th iterate (say, for $k=3$, you want $\{x,f(f(f(x))),f(f(f(f(f(f(x)))))),\dots\}$), then one can cleverly combine Nest[] and NestList[] like so: NestList[Nest[f, #, k] &, start, n] which yields a list containing the zeroth, $k$-th, $2k$-...

21

This is a precedence issue: You may use (value[#[[1]], #[[2]]] = 0.) & /@ tuples instead (ie, explicitly indicate precedence by using brackets). One way to see what is going on is to notice the colour of the # in the notebook. Or select the & symbol, then press Ctrl+. repeatedly. This progressively selects larger chunks of the expression to which ...

21

I took inspiration from WReach's work of art answer, and made a package that took his ideas and expanded them into a broad, general solution for lazy data in Mathematica. You can find my implemenation on github. To use the package to answer the original question from this post, you'd do something like: palindromicQ[n_] := IntegerDigits[n] /. d_ :> d === ...

21

This answer is based on the original poster's statement that he has been using Mathematica for six months, and is now trying to build something a bit more complex. I do not take this to mean a large project in the sense that an application developer would use the word. The notebook interface is really easy to experiment in, and I know that when I had used ...

19

(#[#] &)[#[#][#] &] You have a function that applies its argument to itself (#[#] &)[8] --> 8[8] We have, on the other hand, a function that applies to itself to make the head it applies to itself (#[#][#]&)[8] --> (8[8])[8] 8[8] is the head of 8[8][8] If we apply the first function to the second one, we get the second function ...

19

Implementation Here are my versions. I will start with FoldWhile: Clear[dressInCtr]; dressInCtr[test_, max_] := Module[{ctr = 0}, (++ctr <= max ) && test[##] &] Clear[FoldWhile]; FoldWhile[f_, test_, start_, secargs_List, max_Integer] := FoldWhile[f, dressInCtr[test, max], start, secargs]; FoldWhile[f_, test_, start_, secargs_List] :...

18

Is this what you want? l1 = {a, b, c}; l2 = {aa, bb, cc}; sth[#1, #2] & @@@ Tuples[{l1, l2}] {sth[a, aa], sth[a, bb], sth[a, cc], sth[b, aa], sth[b, bb], sth[b, cc], sth[c, aa], sth[c, bb], sth[c, cc]}

17

There are some features of this specific problem one can take advantage of. The boundary of the x,y,z,n domain represented by val <= max is linear in x,y,z and only quadratic in n; furthermore val increases with each of the variables. So basically the loops might be done in any order, and the limits might be solved for explicitly. We'll start with the ...

17

Not the "lazy" but shortest: Select[ToString /@ Prime[Range[10^4]], # == StringReverse[#] &] Faster: Select[Prime[Range[10^4]], IntegerDigits[#] == Reverse[IntegerDigits[#]] &] Faster: Pick[#, (# == Reverse[#]) & /@ IntegerDigits /@ #, True] &@ Prime[Range[10^4]] Fastest: (twice faster than the rest, but slower than "lazy") Select[...

16

EDIT To address hard-coded Table and SparseArray limits, and efficiency As pointed out in the comments, hard-coded limits on the Table or SparseArray dimensions may not work in general. Besides being slow, the Table approach quickly eats up system memory for moderate values of max. Here is a variation on WReach's recursive scheme using ReplaceRepeated. With ...

16

You can take advantage of listability. As a rule if a function has the Listable attribute listable operations will be faster than other alternatives such as mapping. {a, b, c} = Transpose[{a, b, c}]; Apply[Plus, x^a*y^b*z^c] or {a, b, c} = Transpose[{a, b, c}]; Total[x^a*y^b*z^c]

16

Example square matrix: n = 4; m = Range[n^2] ~Partition~ n; m // MatrixForm $\left( \begin{array}{cccc} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & 14 & 15 & 16 \\ \end{array} \right)$ Operation: MapAt[f, m, {#, # ;;} & ~Array~ Length @ m] // MatrixForm \$\left( \begin{array}{...

16

Use an IDE like Workbench and remember good software development practices Take a look at workbench which is a branded version of Eclipse, a very common Integrated Development Platfom (IDE). On the WRI site a lot of information is given of which I would like to point you to a White Paper on Building Large Software in Mathematica. It contains very helpful ...

15

Currying I don't know if it is possible to make all functions work in the Currying form (h[x1][x2][..]) but it is at least possible to extend Hold behavior to all arguments which natively that pattern will not have. I will copy my favorite method which I learned from this post by Grisha Kirilin: SetAttributes[f, HoldAllComplete] f[a_, b_, c_] := Hold[a, ...

Only top voted, non community-wiki answers of a minimum length are eligible