Hot answers tagged data-structures
59
Preamble
I spent some time and designed and implemented a tiny framework to deal with this problem, over the last two days. Here is what I've got. The main ideas will involve implementing a simple key-value store in Mathematica based on a file system, heavy use and automatic generation of UpValues, some OOP - inspired ideas, Compress, and a few other ...
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) ...
34
Preview and comparative results
The implementation below may be not the most "minimal" one, because I don't use any of the built-in functionality (DictionaryLookup with patterns, Graph-related functions, etc), except the core language functions. However, it uses efficient data structures, such as Trie, linked lists, and hash tables, and arguably maximally ...
34
My solution is a recursive tree traversal algorithm which seeks and searches neighbouring vertices only if it will lead to a word (e.g., Something starting with ZQ is immediately disqualified), but it's faster than yours because I construct the adjacent vertices list from the adjacency matrix rather than calling NeighborhoodGraph each time. On my machine, ...
31
I will answer a couple of your questions only.
Space efficiency
Packed arrays are significantly more space efficient. Example: Let's create an unpacked array, check its size, then do the same after packing it:
f = Developer`FromPackedArray[RandomReal[{-1, 1}, 10000]];
ByteCount[f]
ByteCount[Developer`ToPackedArray[f]]
(*
320040
80168
*)
Time efficiency
...
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
...
25
The difference
Packed arrays give you pretty much an access to a direct C memory layout, where the arrays are stored. Unpacked arrays reference arrays of pointers to their elements. This explains most of the other differences, in particular:
Space efficiency: if you look at how much space is required for packed arrays, you see that it is exactly the ...
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 ...
21
A combination of rules and recursion is able to produce rather powerful solutions. Here is my take on it:
ClearAll[makeTree];
makeTree[wrds : {__String}] := makeTree[Characters[wrds]];
makeTree[wrds_ /; MemberQ[wrds, {}]] :=
Prepend[makeTree[DeleteCases[wrds, {}]], {} -> {}];
makeTree[wrds_] :=
Reap[If[# =!= {}, Sow[Rest[#], First@#]] & /@ ...
20
You can implement an imperative-style circular buffer.
big = Range@1*^7;
size = Length@big;
pointer = size;
updateElement[new_Integer] := (pointer = 1 + Mod[pointer, size]; big[[pointer]] = new)
Do[updateElement[RandomInteger@99], {100}] // AbsoluteTiming
{0.000374, Null}
To bring the buffer back to the normal form use
big = RotateLeft[big, ...
17
In practice, enforcing strong types in Mathematica seldom pays off, just because, as mentioned by @belisarius, Mathematica is untyped (and perhaps more so than most other langauges, since it is really a term-rewriting system). So, most of the time, the suggestion of @Mr.Wizard describes what I'd also do.
The way to define ADT-s (strong types) was described ...
17
Format is what you are looking for: Create a data structure, something like this:
mkMyData[d1_, d2_] := MyData[d1, d2]
GetD1[a_MyData] := a[[1]]
GetD2[a_MyData] := a[[2]]
Format[MyData[d1_, d2_]] := "MyData[<" <> ToString[Length[d1] + Length[d2]] <> ">]"
Call the constructor:
data = mkMyData[Range[5], q]
(*
"MyData[<5>]"
*)
...
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 ...
15
I will answer the technical part of the question - namely, how to get the entire graph. How one would go about analyzing and visualizing it, is another story.
This will open and parse a given guide notebook, and get the links to other notebooks:
ClearAll[getLinks];
getLinks[file_] :=
With[{nb = NotebookOpen[file]},
With[{result =
...
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
Using this webcrawler code from Wolfram site, and Guides page in online docs as the starting url:
webcrawler[rooturl_, depth_] := Flatten[Rest[NestList[Union[Flatten[Thread[# -> Import[#, "Hyperlinks"]] & /@ Last /@ #]] &, {"" -> rooturl}, depth]]];
style = {VertexStyle -> White, VertexShapeFunction -> "Point",
EdgeStyle -> ...
13
Preamble
I will discuss here two methods for doing computations on very large data sets which don't fit into memory. The first method is based on sequential reading of chunks of data from a file. The second method is based on converting a data set to a file-backed list representation. The unifying idea for both methods is the use of iterators as a useful ...
12
Preamble
I think this is a very good question. Trying to address it in a reasonably general way, I ended up with a tiny framework which implements a limited form of pointer-like semantics, which I'd like to describe and illustarate.
Code
This allows one to mark some portion of the code (some expression) as a reference.
ClearAll[Ptr, new, llp];
...
11
No ADT in Mma (natively at least) ... but in your case you could use pattern matching:
yours = {{100, {1, 2, 3, 4, 5}}, {105, {2, 4, 6, 8}}, {42, {42, 39, 56}}};
f[x_] := 1 /; MatchQ[x, List[List[_Integer, List[_Integer ...]] ...]]
f[yours]
f["mySymbol"]
(*->
1
f["mySymbol"]
*)
11
The notebook DocumentationNavigator.nb has all the inter-dependencies built-in (they're arguments supplied to TreeBrowse`LoadVirtualCells and other undocumented functions that build up the documentation center. We can then parse the raw text contents of this notebook to pull out this list. I do that in the following, but I haven't restricted it solely to ...
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
A way of getting around the a_/;test[a] syntax is to write out the tests in string form, and use replace to insert the values. For this to work you need to build rules from your table. Here is a simple implementation:
SetAttributes[queryCriteria, HoldAll]
queryCriteria[theTable_, query_] := Function[{entry},
Unevaluated[query] /. (Rule @@@ ...
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
For such small trees I would memoize those that already have the element...
ClearAll[leftsubtree, rightsubtree, nodevalue, emptyTree, treeInsert]
leftsubtree[{left_, _, _}] := left
rightsubtree[{_, _, right_}] := right
nodevalue[{_, val_, _}] := val
emptyTree = {};
treeInsert[emptyTree, elem_] := {emptyTree, elem, emptyTree}
(*This is the changed line*)
t ...
9
As Michael Pilat explained here it is more robust to use MakeBoxes, rather than Format.
Using MakeBoxes:
MakeBoxes[diag[m_?MatrixQ], _] ^:=
InterpretationBox[RowBox[{"diag", "[", #, ",", #2, "]"}], diag[m]] & @@
ToBoxes /@ {Dimensions[m], Diagonal[m]}
Here is a definition for handling Part extraction:
diag[m_?MatrixQ][[part___]] ^:= m[[part]]
...
9
If your Excel file test.xls is very simple:
Then the code is a one-liner (if I understand correctly what is needed):
Set@@@Transpose[{ToExpression[First[#]], Transpose[Rest[#]]}&@Import["test.xls"][[1]]]
To check:
{Paris, Moscow}
{{1., 2., 3., 4., 5., 6., 7., 8.}, {12., 23., 34., 45., 56., 67., 78., 89.}}
The rest is more complex cases. ...
9
If I understand you correctly, is the following what you want?
correlations2 = Map[
Outer[Correlation, #, #, 1] &[Transpose[#]] &,
partitionedData, {2}];
Now the Correlation receives two vector as its input, and you can replace it with SpearmanRankCorrelation or KendallRankCorrelation legally.
To verify it, compare correlations2 with your ...
8
I'd like to discuss two points:
Cases, destructuring and escaping in patterns
There indeed can be a problem when using Cases to destructure expressions involving rules, because Cases has an extended syntax which uses rules, and interprets them differently. For example:
dataR = {row1 -> {key1 -> value1, key2 -> value2},
row2 -> {key1 -> ...
8
As you mentioned in your question and belisarius illustrates above, you can check arguments with arbitrary pattern matching.
When I need to checks of this kind I often use a couple of methods. I will define the pattern once and then reference it by name:
p1 = {{_Integer, {_Integer ...}} ...};
dat = {{100, {1, 2, 3, 4, 5}}, {105, {2, 4, 6, 8}}, {42, {42, ...
8
You can effectively create your own types by using the feature that Mathematica expressions have a Head, the head can be used to define a type. Functions can then use the Head value to apply only to arguments matching the defined type.
A version with loose format checking, format checked only upon creation,can be implemented as simply as this:
(* Define ...
Only top voted, non community-wiki answers of a minimum length are eligible

