Mercurial > hg > camir-aes2014
comparison toolboxes/FullBNT-1.0.7/netlab3.3/metrop.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 function [samples, energies, diagn] = metrop(f, x, options, gradf, varargin) | |
2 %METROP Markov Chain Monte Carlo sampling with Metropolis algorithm. | |
3 % | |
4 % Description | |
5 % SAMPLES = METROP(F, X, OPTIONS) uses the Metropolis algorithm to | |
6 % sample from the distribution P ~ EXP(-F), where F is the first | |
7 % argument to METROP. The Markov chain starts at the point X and each | |
8 % candidate state is picked from a Gaussian proposal distribution and | |
9 % accepted or rejected according to the Metropolis criterion. | |
10 % | |
11 % SAMPLES = METROP(F, X, OPTIONS, [], P1, P2, ...) allows additional | |
12 % arguments to be passed to F(). The fourth argument is ignored, but | |
13 % is included for compatibility with HMC and the optimisers. | |
14 % | |
15 % [SAMPLES, ENERGIES, DIAGN] = METROP(F, X, OPTIONS) also returns a log | |
16 % of the energy values (i.e. negative log probabilities) for the | |
17 % samples in ENERGIES and DIAGN, a structure containing diagnostic | |
18 % information (position and acceptance threshold) for each step of the | |
19 % chain in DIAGN.POS and DIAGN.ACC respectively. All candidate states | |
20 % (including rejected ones) are stored in DIAGN.POS. | |
21 % | |
22 % S = METROP('STATE') returns a state structure that contains the state | |
23 % of the two random number generators RAND and RANDN. These are | |
24 % contained in fields randstate, randnstate. | |
25 % | |
26 % METROP('STATE', S) resets the state to S. If S is an integer, then | |
27 % it is passed to RAND and RANDN. If S is a structure returned by | |
28 % METROP('STATE') then it resets the generator to exactly the same | |
29 % state. | |
30 % | |
31 % The optional parameters in the OPTIONS vector have the following | |
32 % interpretations. | |
33 % | |
34 % OPTIONS(1) is set to 1 to display the energy values and rejection | |
35 % threshold at each step of the Markov chain. If the value is 2, then | |
36 % the position vectors at each step are also displayed. | |
37 % | |
38 % OPTIONS(14) is the number of samples retained from the Markov chain; | |
39 % default 100. | |
40 % | |
41 % OPTIONS(15) is the number of samples omitted from the start of the | |
42 % chain; default 0. | |
43 % | |
44 % OPTIONS(18) is the variance of the proposal distribution; default 1. | |
45 % | |
46 % See also | |
47 % HMC | |
48 % | |
49 | |
50 % Copyright (c) Ian T Nabney (1996-2001) | |
51 | |
52 if nargin <= 2 | |
53 if ~strcmp(f, 'state') | |
54 error('Unknown argument to metrop'); | |
55 end | |
56 switch nargin | |
57 case 1 | |
58 % Return state of sampler | |
59 samples = get_state(f); % Function defined in this module | |
60 return; | |
61 case 2 | |
62 % Set the state of the sampler | |
63 set_state(f, x); % Function defined in this module | |
64 return; | |
65 end | |
66 end | |
67 | |
68 if 0 | |
69 seed = 42; | |
70 randn('state', seed); | |
71 rand('state', seed) | |
72 end | |
73 | |
74 display = options(1); | |
75 if options(14) > 0 | |
76 nsamples = options(14); | |
77 else | |
78 nsamples = 100; | |
79 end | |
80 if options(15) >= 0 | |
81 nomit = options(15); | |
82 else | |
83 nomit = 0; | |
84 end | |
85 if options(18) > 0.0 | |
86 std_dev = sqrt(options(18)); | |
87 else | |
88 std_dev = 1.0; % default | |
89 end | |
90 nparams = length(x); | |
91 | |
92 % Set up string for evaluating potential function. | |
93 f = fcnchk(f, length(varargin)); | |
94 | |
95 samples = zeros(nsamples, nparams); % Matrix of returned samples. | |
96 if nargout >= 2 | |
97 en_save = 1; | |
98 energies = zeros(nsamples, 1); | |
99 else | |
100 en_save = 0; | |
101 end | |
102 if nargout >= 3 | |
103 diagnostics = 1; | |
104 diagn_pos = zeros(nsamples, nparams); | |
105 diagn_acc = zeros(nsamples, 1); | |
106 else | |
107 diagnostics = 0; | |
108 end | |
109 | |
110 % Main loop. | |
111 n = - nomit + 1; | |
112 Eold = feval(f, x, varargin{:}); % Evaluate starting energy. | |
113 nreject = 0; % Initialise count of rejected states. | |
114 while n <= nsamples | |
115 | |
116 xold = x; | |
117 % Sample a new point from the proposal distribution | |
118 x = xold + randn(1, nparams)*std_dev; | |
119 %fprintf('netlab propose: xold = %5.3f,%5.3f, xnew = %5.3f,%5.3f\n',... | |
120 % xold(1), xold(2), x(1), x(2)); | |
121 | |
122 % Now apply Metropolis algorithm. | |
123 Enew = feval(f, x, varargin{:}); % Evaluate new energy. | |
124 a = exp(Eold - Enew); % Acceptance threshold. | |
125 if (diagnostics & n > 0) | |
126 diagn_pos(n,:) = x; | |
127 diagn_acc(n,:) = a; | |
128 end | |
129 if (display > 1) | |
130 fprintf(1, 'New position is\n'); | |
131 disp(x); | |
132 end | |
133 | |
134 r = rand(1); | |
135 %fprintf('netlab: n=%d, a=%f/%f=%5.3f (%5.3f), r=%5.3f\n',... | |
136 % n, exp(-Enew), exp(-Eold), a, exp(-Enew)/exp(-Eold), r); | |
137 if a > r % Accept the new state. | |
138 Eold = Enew; | |
139 if (display > 0) | |
140 fprintf(1, 'Finished step %4d Threshold: %g\n', n, a); | |
141 end | |
142 else % Reject the new state | |
143 if n > 0 | |
144 nreject = nreject + 1; | |
145 end | |
146 x = xold; % Reset position | |
147 if (display > 0) | |
148 fprintf(1, ' Sample rejected %4d. Threshold: %g\n', n, a); | |
149 end | |
150 end | |
151 if n > 0 | |
152 samples(n,:) = x; % Store sample. | |
153 if en_save | |
154 energies(n) = Eold; % Store energy. | |
155 end | |
156 end | |
157 n = n + 1; | |
158 end | |
159 | |
160 if (display > 0) | |
161 fprintf(1, '\nFraction of samples rejected: %g\n', ... | |
162 nreject/(nsamples)); | |
163 end | |
164 | |
165 if diagnostics | |
166 diagn.pos = diagn_pos; | |
167 diagn.acc = diagn_acc; | |
168 end | |
169 | |
170 % Return complete state of the sampler. | |
171 function state = get_state(f) | |
172 | |
173 state.randstate = rand('state'); | |
174 state.randnstate = randn('state'); | |
175 return | |
176 | |
177 % Set state of sampler, either from full state, or with an integer | |
178 function set_state(f, x) | |
179 | |
180 if isnumeric(x) | |
181 rand('state', x); | |
182 randn('state', x); | |
183 else | |
184 if ~isstruct(x) | |
185 error('Second argument to metrop must be number or state structure'); | |
186 end | |
187 if (~isfield(x, 'randstate') | ~isfield(x, 'randnstate')) | |
188 error('Second argument to metrop must contain correct fields') | |
189 end | |
190 rand('state', x.randstate); | |
191 randn('state', x.randnstate); | |
192 end | |
193 return |