Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

The idea: I need to generate a sequence of events then run a "propagator" over the list of events where the "propagator" will update the state of the following event. I can then write functions that tally results or makes visualizations.

The following is a mix of code I have found here and some of my own. This example is a short prof of concept.

Clear[CircleMinus]
sys_\[CircleMinus]sub_ := sub /. sys
sys_\[CircleMinus]sub_[n_] := (sub /. sys)[[n]]
sys_\[CircleMinus]sub_[f_Function] := 
Module[{s}, s = Select[(sub /. sys), f];
(*remove redundant {}*)s /. {x_List} :> x];

Clear[keypos]
(*local Function*)
keypos[s_, key_] := Module[{v},
v = Flatten[Position[Map[#[[1]] &, s], key]];
If[Length[v] > 0, v[[1]], "Null"]
];

Clear[ud]
ud[sys_, sub_, val_] := Module[{pos, sysin},
sysin = sys;
pos = keypos[sys, sub];
If[pos == "Null",
  AppendTo[sysin, (sub -> val)],
  sysin[[pos]] = (sub -> val)
];
Return[sysin]
]

Clear[PropView]
PropView[dt_, x_, v_, a_: 0] := x + v dt + 1/2 a dt^2;

Now for a list of actions with minimal input.

actions = {
  {"Pos" -> {0, 0},
  "Vec" -> {1, 1},
  "StartTime" -> 0,
  "dTime" -> .1,
  "State" -> {"Pen" -> 1, "Color" -> {1, 0, 0}}
  },
  {
  "dTime" -> .1,
  "State" -> {"Pen" -> 1, "Color" -> {1, 1, 0}}
  },
 {
 "a" -> {-2, 2},
 "dTime" -> .1,
 "State" -> {"Pen" -> 2, "Color" -> {0, 0, 0}}
 },
 {
 "dTime" -> .1,
 "State" -> {"Pen" -> 1, "Color" -> {0, 1, 1}}
 }
 }

Notice I only need to include information in the actions where states change. For example at step actions[[3]] there is an acceleration.

Now for the propagator:

Do[
  pos = actions[[i]]\[CircleMinus]"Pos";
  vec = actions[[i]]\[CircleMinus]"Vec";
  st = actions[[i]]\[CircleMinus]"StartTime";
  dt = actions[[i]]\[CircleMinus]"\[Delta]Time";
  a = actions[[i]]\[CircleMinus]"a";
  If[a == "a", a = 0];
  actions[[i + 1]] = ud[actions[[i + 1]], "Pos", PropView[dt, pos, vec, a]];
  actions[[i + 1]] = ud[actions[[i + 1]], "Vec", PropView[dt, vec, a, 0]];
  actions[[i + 1]] = ud[actions[[i + 1]], "StartTime", st + dt],
 {i, 1, Length[actions] - 1}]

At this point the actions list is filled with state information. (Each event now has a key value pair for "Pos" etc.) This is just a very simple example that shows the main idea. In my real problem my actions list will be much more complicated. I would like to have a few levels of information. Like what is shown in the actions list above with the "State" key. But in the example I have not used or modified the "State" key's value.

The Question: How do I easily modify key-values at lower levels? My simple "ud" function will not work

  ud[actions[[2]]\[CircleMinus]"State", "Color", {1, 1, 1}] 

I would love to be able to do something like this:

  actions[[2]]\[CircleMinus]"State"\[CircleMinus]"Color"={1,1,1}

Where "Color" would be created if it did not exist and so would the sub-structure if "State" did not exist. I would prefer a solution that did not involve coping my actions list for each operation of my functions.

I'm also open to solutions or ideas that take me from my initial thoughts.

Update and Partial Solution

Accessing the data is the same as above:

Clear[CircleMinus]
sys_\[CircleMinus]sub_ := sub /. sys;
sys_\[CircleMinus]sub_[n_] := (sub /. sys)[[n]];
sys_\[CircleMinus]sub_[f_Function] := 
Module[{s}, s = Select[(sub /. sys), f];
 (*remove redundant {}*)s /. {x_List} :> x];

This code I found here on this website and I'm sorry I could not find the reference again.

The next part is an extension on what István Zachar did in the dynamic part of his answer: István Zachar

Clear[ud]
(*ud[obj_]:=obj;*)
ud[obj_, field_, val_] := Module[{pos},
 If[ListQ[obj], pos = Position[obj, field, {0, \[Infinity]}, 1], 
    pos = {}];
 If[pos === {}, 
     If[ListQ[obj], Join[obj, {field -> val}], {field -> val}], 
    ReplacePart[obj, {First@First@pos, 2} -> val]]];

 ud[obj_, field_, field2_, val_] := 
    ud[obj, field, ud[obj\[CircleMinus]field, field2, val]];

 ud[obj_, field_, field2_, field3_, val_] := 
 ud[obj, field, 
        ud[obj\[CircleMinus]field, field2, 
            ud[obj\[CircleMinus]field\[CircleMinus]field2, field3, val]
          ]
  ];

I can now easy add and update key value pairs down to the third level. However I do not consider my additions good code because it is not generalized for updating to the $n^{\text{th}}$ level.

share|improve this question
    
For a 1D list here is another way of doing this: István Zachar –  c186282 Mar 20 '13 at 0:27
3  
Is this an approximately minimal example? –  Rojo Mar 20 '13 at 0:32
    
Sounds like a FoldList in which you are folding in "events." You could then map over the list thereby produced to obtain whatever sorts of visualizations interested you. –  Seth Chandler Mar 20 '13 at 3:35
    
I think you could get some good ideas from reading two questions previously considered and their answers. The first deals with data-structure-like constructs and the second with multi-level qualified references. Both these topics seem relevant to your question. –  m_goldberg Mar 20 '13 at 7:50
    
What you seem to be after is a list (array) of nested hash-tables. A nested hash table can be implemented based on DownValues, SubValues, or System`Utilities`Hashtable - all of which is covered in various answers in the question linked by @m_goldberg. –  Leonid Shifrin Mar 20 '13 at 15:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.