Hot answers tagged coding-style
45
Let's improve the specific cases given.
Case #1
Explicit loops are often counterproductive in Mathematica, not only taking more keystrokes, but also more execution time. They are also, in my opinion, more prone to mistakes.
Better ways are to use Do, Scan, or Map.
Do and Scan are (typically) appropriate for operations that do not accumulate a list of ...
35
This answer may be unacceptable right from the outset because it uses undocumented functions. However, it has advantages over some of the approaches suggested so far which might be redeeming enough in certain scenarios to recommend it in practice. In particular, it provides totally encapsulated state (unlike, e.g., DownValues or Temporary symbols) and O(1) ...
26
There were several attempts to emulate structs in Mathematica. Emphasis on emulate, since AFAIK there is no built - in support for it yet. One reason for that may be that structs are inherently mutable, while idiomatic Mathematica gravitates towards immutability. You may find these discussions interesting:
Struct-data-type-in-mathematica
...
24
Quoting the OP's comment:
Most of the work I do involves constructing mathematical models and
then testing various scenarios against those models. I'd like to be
able to populate a particular scenario and then pass that scenario to
a model. I'd also like to be able to copy that scenario, modify one or
more parameters, and then pass the new ...
22
I prefer the Condition to appear on the left-hand-side and outside the square brackets for several reasons.
Type signature
I often think of the condition as (part of) the analog of the signature in a typed language, so it should go on the left hand side.
Order of operations
I like that the elements of the function definition appear in the order in which ...
22
There are many alternative ways to approach various programming problems that do not use loops and are more efficient (and concise) in Mathematica. Most of them execute faster, but even where they do not, they are faster to type: development time matters, too!
Here are some rules of thumb for easier programming and iterating on lists.
1. Most arithmetic ...
19
rcollyer has answered the question you actually asked, but I wondered if there wasn't an easier way to code this. If I understand your original code correctly, you want to save the final state of the pond after ten fishing decisions, as well as the total number of fish caught in that sequence of fishing decisions, and the list of fishing decisions. You can ...
15
The answers already posted show that built-in Mathematica functionality can be used to get the meaningful functionality provided by a C struct. If you want your code to be readable by other Mathematica users, I suggest using a list of rules as already advised above.
However, if you really want struct-style syntax I'll offer an implementation that I've ...
14
You cannot make assignments to First, Last, Rest, or Most the way you can with Part. Therefore, there is greater consistency in using Part for all operations. See this answer for an example of and argument for this consistency.
Also, you must change functions if you need to update your code to index a different element or change an element to a Span. By ...
14
No, they are not needed. You can specify as many "iterators" (the parameters of the form {x, xmin, xmax} or {x, xmin, xmax, dx}) as you wish. (See the last form list in the documentation.) For example,
Table[i j, {i, 3}, {j, 3}]
produces
{{1, 2, 3}, {2, 4, 6}, {3, 6, 9}}
Additionally, any iterator can rely on those that came before it, but not those ...
14
It seems to me that this is the correct way to extract values from a nested list of rules:
Data
ad = {"accept_rate" -> 75, "account_id" -> 395497, "age" -> 41,
"badge_counts" -> {"bronze" -> 35, "gold" -> 0, "silver" -> 11},
"creation_date" -> 1326833982, "display_name" -> "Verbeia",
"is_employee" -> False, ...
14
Reasons why adding rules to Set is a really bad idea
First, let me list the reasons why I think that adding rules to Set globally is a very bad practice:
This is a hugely non-local system modification. We have no idea which parts of the system will be affected, but we can be sure that there will be many.
Set is a very frequently used command (see first ...
13
So the naive way to set up a data structure like struct is, as the OP suggested, to simply used DownValues and/or SubValues. In the below, I use SubValues.
Copying the Wikipedia C language struct example
struct account {
int account_number;
char *first_name;
char *last_name;
float balance;
};
struct account s; // Create new account labelled s
...
13
As described by Andy Ross in a comment, you can make a definition that preprocesses the argument(s) into a canonical form. Turning his example around simply to illustrate flexibility:
f[{args__}] := f[args]
f[args__] := Multinomial[args] / Plus[args]
f[{12, 7, 3}] == f[12, 7, 3]
True
This method is useful for more complicated preprocessing, but in ...
10
I arrived very late to this party and I'm very much afraid that nobody comes here anymore. Still I'm posting this in hope that an occasional visitor may find it a practical approach to implementing data structures with named fields within Mathematica.
The concept
The idea is to use protected symbols to name a structure and its fields. The symbol that names ...
10
Two more ways:
parti1[a_, p_] := SortBy[a, {Sign[# - p] &, # == # &}]
or
parti2[a_, p_] := Join[Select[a, # < p &], {p}, Select[a, # >= p &]]
With
a = {3, 5, 6, 7, 2, 1, 2}; (* and *) p =3
both give
{2, 1, 2, 3, 5, 6, 7}
Update: While the two methods above and Heike's two methods give exactly the same results, ...
10
To my mind, the differences are significant if obscure. The very big difference in evaluation was described already by @Sal. Here are several more subtle ones, which may however bite you. So, functions go first.
Functions
Can be in two forms, Function[x,x^2] or Function[#^2] (the last is equivalent to #^2&), which are not always equivalent. ...
9
Style is a matter of taste and education. There is not a definite answer, only a personal answer. Having said that, there is another way for the condition that is common in code:
h[x_ /; OddQ[x]] := 1;
h[x_] := 0
h[4] // Trace
My personal preference is your f[] style, since I find that a good compromise between readability and closeness to the actual ...
9
There is too much that can be said here so this answer is going to be incomplete but let me give it a shot.
First off, With, Block and Module are not interchangeable, in general. To understand when one is preferred you first have to understand how they are different. Performance is not the primary issue here.
With[{x=1}, ...] is appropriate when x is ...
9
It is possible to get rid of all but one ReplaceAll. First, you need to remember that ReplaceAll tests each Rule in order, so to deal with the missing "badge_counts" condition, you can simply add that to the list, as follows
{"display_name", "creation_date", "reputation", "reputation_change_week",
"is_employee", "last_access_date", "user_type",
...
9
I can think of several main advantages of additional arguments:
Efficiency
More concise and readable code
Better abstraction level
Less chances for bugs.
In brief, I think that the first reason is bad most of the time, the second and third are valid, and the last may or may not be valid. Let us now consider these arguments.
I start with efficiency. My ...
9
If you're willing to use a slightly different syntax to invoke System`Utilities`HashTableAdd, you can create your own wrapper around System`Utilities`HashTable that does most of what you want without modifying any built-in functions. The loss of the convenient hashTable.key = value syntax is unfortunately necessary because you can't use TagSet to set a tag ...
9
As Daniel points out, you will always get a good speed-up by compiling. I want to take a different approach and consider how you can get a faster execution by writing your code in a more "functional" style.
My machine is slower than yours and ran your code in 17.2 seconds, according to AbsoluteTiming.
The first thing I noticed is that you are creating and ...
9
First I want to say, as you mentioned in your comment that your ultimate goal is to to do it for nMax over 100, I suggest you first symbolicly calculate the correlation of the following function, treating $r_n$ ($n=-s,-s+1,\dots,s$, and $s$ is nSteps for short) as variables as $x$:
$$\xi(x,r_{-s},r_{-s+1},\dots,r_{s})=\sum _{n=-s}^{s} r_n\, ...
8
This will give a modest improvement. I'm probably missing a few more though.
One other remark: this way of choosing a "random" direction is far from uniform.
numparticles = 10^4;
numsteps = 10^3;
radius = 1.;
particles = ConstantArray[{1.001, 0., 0.}, numparticles];
rnew = Map[#.# &, particles];
numcrossings = ConstantArray[0., numparticles];
...
8
For reference there is a built-in function CholeskyDecomposition.
For improving your existing code Array may be a minor subjective improvement:
HalfFunctionalCholesky2[matrin_List?PositiveDefiniteMatrixQ] :=
Module[{dimens, uu},
dimens = Length[matrin];
uu = ConstantArray[0, {dimens, dimens}];
Array[(uu[[#]] = makerow[matrin, #, uu, dimens]) ...
8
An interesting problem.
Trivially one could use Print like this:
Print[2 + 2, Spacer[50], "this is a note"]
4 this is a note
But that is hardly a usable syntax. Looking deeper into the system one observes that (* comments *) are stripped during parsing so those are out of reach without prohibitive contortions. Strings however are inert objects ...
8
Very vague question but let me give you a start. Say you have a list l and a step function which appends or does not append a random element to your list. Now you want to call step over and over again, until your list reached a specific length:
step[{l_, iter_}] :=
{If[RandomChoice[{True, False}], Append[l, RandomInteger[]], l], iter + 1}
Depending on ...
8
I know halirutan's answer is intended only as a simple example but I believe it is worth noting that it is inefficient for the specific operation that he illustrates.
One could directly write RandomInteger[1, 30] but that has no "loop" condition and is therefore inapplicable. What I show below may also be inapplicable, but hopefully it is still of ...
7
One way of doing this is to do something like
parti[lst_, p_] := Flatten[Reap[Sow[#, Sign[# - p]] & /@ lst, {-1, 0, 1}][[2]]]
If the list consists of integers only, you could also do something like
parti[lst_, p_] := Flatten[BinLists[lst, {{-Infinity, p, p+1, Infinity}}]]
Only top voted, non community-wiki answers of a minimum length are eligible
