-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Observations should be independent #76
Comments
Observation follows normal distribution with mean = height and variance = observation noise |
Some issues:
|
rr, inv_rr are obsolete. |
This could be achieved by just replacing |
|
Well, generally speaking matrix/vector calculations are the fastest possible calculations you can do on CPUs, so independent observations are not necessarily faster. I will test this and give some numbers. |
Just making sure I understand. Do you then want the observation noise to drawn from a normal distribution with |
I am mostly advocating this for two reasons:
(ignore my comment there, it does work 😊) I tested replacing with cov_obs = Diagonal(ones(params.nobs) * params.obs_noise_amplitude) The calculation of weights using the parameters from #74 sped up from 82 microseconds to 30 microseconds, and in both cases is an insignificant fraction of the total run time. I'll try implementing it as a loop sampling from independent normal distributions to see if it becomes much faster. |
The answer to the question of which way is faster is, it depends on the number of particles (and does not matter much either way). Here is a test using 100 particles: ────────────────────────────────────────────────────────────────────────────────
Time Allocations
────────────────────── ───────────────────────
Tot / % measured: 14.9s / 100% 148MiB / 100%
Section ncalls time %tot avg alloc %tot avg
────────────────────────────────────────────────────────────────────────────────
Weights Diagonal 10 46.3μs 0.00% 4.63μs 20.0KiB 0.07% 2.00KiB
Weights Independent 10 31.8μs 0.00% 3.18μs 0.00B 0.00% 0.00B and here is a test using 1000 particles: ────────────────────────────────────────────────────────────────────────────────
Time Allocations
────────────────────── ───────────────────────
Tot / % measured: 14.9s / 100% 148MiB / 100%
Section ncalls time %tot avg alloc %tot avg
────────────────────────────────────────────────────────────────────────────────
Weights Independent 10 216μs 0.00% 21.6μs 0.00B 0.00% 0.00B
Weights Diagonal 10 185μs 0.00% 18.5μs 161KiB 0.11% 16.1KiB I labeled the way I suggested above function get_weights!(weight::AbstractVector{T},
obs::AbstractVector{T},
obs_model::AbstractMatrix{T},
obs_noise_std::T) where T
nobs = size(obs_model,1)
nprt = size(obs_model,2)
@assert size(obs,1) == nobs
@assert size(weight,1) == nprt
weight .= 1.0
for iobs = 1:nobs
for iprt = 1:nprt
weight[iprt] += logpdf(Normal(obs[iobs], obs_noise_std), obs_model[iobs,iprt])
end
end
@. weight = exp(weight)
weight ./= sum(weight)
end |
I will leave both methods in the code, in case weight calculation ever becomes a bottleneck. |
Well, I think there are some matrix inversions also involved, so as long as the system understands it is dealing with a diagonal matrix (so such inversions are trivial) then the two approaches should be fairly similar. |
The two things you mention are equivalent, so no problem with any of them. |
Yes, that is absolutely fine. |
At exactly this part of the code - the exponentiation of the log-weights - it is a standard practice in the area to apply the following to avoid numerical instabilities: a) get log-weights for all particles. b) adding a constant to all these log-weights does not affect the algorithm, as the effect of the constant will disappear upon exponentiating & standardising the weights (to sum up to one). But it can have an effect in terms of avoiding numerical instabilities. log-weights = log-weights - max(log-weights) c) It is after this that one exponentiates: weights = exp(log-weights), and then standardises, weights = weights/sum(weights). |
Thanks for the explanation, I did not really understand why you wanted to add a constant in your original message |
Well, partly this is exactly what people want to avoid: i.e. weights correspond to likelihoods, and there could be scenarios well all weights are exp(-large) which the system will set equal to 0, and that is not good. |
@AlexandrosBeskos is this related to what you're talking about? https://github.com/baggepinnen/MonteCarloMeasurements.jl/blob/4f9b688d298157dc24a5b0a518d971221fbe15dd/src/resampling.jl#L1-L17? |
Yes, this seems to be trying to do the same thing, though is seems a bit either overly-complicated or sophisticated. I think a simple action as the one I have described is the one that everybody is using as a standard in my field. |
That function calculates a log-sum at the end which, as far as I understood, we don't want. I added a function to the PR that does the offset, thanks again for explaining Alex |
It could be what is in the reference is already doing exactly as I have described - it is just that I am not familiar with all coding practices in Julia. |
ok, from my little/intuitive understanding of the "advanced" version of Julia commands that you have used, I would bet that all is fine now. |
Merged the changes to master in #79 |
Remove
cov_obs
, get weights by multiplying independent likelihoods drawn from observations.The text was updated successfully, but these errors were encountered: