Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

closed as off-topic by Kuba, Öskå, Louis, MarcoB, blochwave Dec 5 '15 at 22:48

  • The question does not concern the technical computing software Mathematica by Wolfram Research. Please see the help center to find out about the topics that can be asked here.
If this question can be reworded to fit the rules in the help center, please edit the 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
4  
I'm voting to close this question as off-topic because it is too localized. Minimal example is needed. – Kuba Dec 5 '15 at 9:35