samer@4
|
1 function [f,Y]=history_nest(fields,dim,H)
|
samer@4
|
2 % history_nest - return state transformer that logs old states
|
samer@4
|
3 %
|
samer@4
|
4 % history ::
|
samer@4
|
5 % F:{[N]->string} ~'list of field names',
|
samer@4
|
6 % natural ~'dimension to cat along (defaults to 1)',
|
samer@4
|
7 % struct F ~'old history to build on'
|
samer@4
|
8 % -> (history(A,F) ->history(A,F)),
|
samer@4
|
9 % history(A,F).
|
samer@4
|
10 %
|
samer@4
|
11 % history(A,F) ~ 'structure A with history of fields F' ::=
|
samer@4
|
12 % struct {
|
samer@4
|
13 % current :: struct A ~'original fields from A';
|
samer@4
|
14 % history :: struct F ~ 'sub-struct containing fields F'
|
samer@4
|
15 % }.
|
samer@4
|
16 %
|
samer@4
|
17 % This function returns a state transformer function. The state MUST be
|
samer@4
|
18 % a structure but it can have any fields. The history mechanism adds the
|
samer@4
|
19 % field 'history' which contains the histories of certain fields from
|
samer@4
|
20 % the main structure. The returned function concatenates the current
|
samer@4
|
21 % values of the named fields onto the end of the corresponding fields
|
samer@4
|
22 % in the history, if X is a sequence whose elements contain a field
|
samer@4
|
23 % called 'cost', then
|
samer@4
|
24 %
|
samer@4
|
25 % [logcost,H0]=history({'cost'},1);
|
samer@4
|
26 % Y=scandata(logcost,H0,X);
|
samer@4
|
27 %
|
samer@4
|
28 % Elements of Y will have fields 'current' and 'history' which
|
samer@4
|
29 % contain values from X and a history of 'cost' respectively.
|
samer@4
|
30
|
samer@4
|
31 g=@logfields_scanner;
|
samer@4
|
32 if nargin<2, dim=1; end
|
samer@4
|
33 if nargin<3, H=struct; end
|
samer@4
|
34
|
samer@4
|
35 for i=1:length(fields)
|
samer@4
|
36 % initialise history fields if not present already
|
samer@4
|
37 if ~isfield(H,fields{i}),
|
samer@4
|
38 H.(fields{i}) = [];
|
samer@4
|
39 end
|
samer@4
|
40 end
|
samer@4
|
41
|
samer@4
|
42 f=@logfields;
|
samer@4
|
43 Y.current=[];
|
samer@4
|
44 Y.history=H;
|
samer@4
|
45
|
samer@4
|
46 function Y=logfields(Y,X)
|
samer@4
|
47 Y.current=X;
|
samer@4
|
48 Y.history=logfields_scanner(Y.history,X);
|
samer@4
|
49 end
|
samer@4
|
50
|
samer@4
|
51 function H=logfields_scanner(H,X)
|
samer@4
|
52 for i=1:length(fields)
|
samer@4
|
53 field=fields{i};
|
samer@4
|
54 H.(field) = cat(dim,H.(field),X.(field));
|
samer@4
|
55 end
|
samer@4
|
56 end
|
samer@4
|
57 end
|
samer@4
|
58
|
samer@4
|
59
|
samer@4
|
60
|
samer@4
|
61
|