For an assignment, I am required to estimate pi in Erlang using the Montecarlo method, but with a specified number of actors and iterations. I have a working version (adapted from https://programmingpraxis.com/2009/10/09/calculating-pi/) that does not use concurrency and thus takes one argument, N = number of iterations (points). I am trying to add to it by creating another montecarlo() function that takes two arguments, N = # of iterations and X = # of actors. I am having trouble figuring out how to use a (pseudo)loop to spawn each actor.
The previous version returns the pi estimation, but after I figure out the spawning, I assume I would have to average the return values from each actor for the final pi estimation.
Here is what I have:
-module(pi).
-export([montecarlo/1, montecarlo/2]).
montecarlo(N, X)->
NumIterPerActor = N div X,
%io:fwrite("Number of actors = ~w~n",[X]),
%io:fwrite("Number of iterations per actor = ~w~n",[NumIterPerActor]),
lists:seq(1, X),
spawn(pi, montecarlo, [NumIterPerActor]).
montecarlo(N)->
montecarlo(N,0,0).
montecarlo(0,InCircle,NumPoints)->
PiEst = 4*InCircle / NumPoints,
io:fwrite("Pi = ~w~n", [PiEst]);
montecarlo(N,InCircle,NumPoints)->
Xcoord = rand:uniform(),
Ycoord = rand:uniform(),
montecarlo(N-1,if Xcoord*Xcoord + Ycoord*Ycoord < 1 -> InCircle + 1; true -> InCircle end,NumPoints + 1).
From researching the problem, I have seen using map(), but to my understanding, you are creating a new function inside of map(), rather than using ones already implemented.
EDIT:
I didn't receive any suggestions before the deadline (my fault for waiting so long), so I sought help from a classmate and came up with a recursive solution:
-module(pi).
-export([montecarlo/1, montecarlo/2, assign/3, compute/2, addPi/3]).
montecarlo(N, X)->
NumIterPerActor = N div X, %number of iterations for each actor
io:fwrite("Number of actors = ~w~n",[X]),
io:fwrite("Number of iterations per actor = ~w~n",[NumIterPerActor]),
%Actors = lists:seq(1, X), %generate desired number of actors
%Pi1 = spawn(pi, montecarlo, [NumIterPerActor]),
%Pi2 = spawn(pi, montecarlo, [NumIterPerActor]).
ReceiverID = spawn(pi, addPi, [0, X, X]),
assign(ReceiverID, X, NumIterPerActor).
assign(ReceiverID, 1, Iter)->
spawn(pi, compute, [Iter, ReceiverID]);
assign(ReceiverID, X, Iter)->
spawn(pi, compute, [Iter, ReceiverID]),
assign(ReceiverID, X-1, Iter).
compute(Iter, ReceiverID)->
Est = montecarlo(Iter),
ReceiverID ! {Est}.
addPi(Pies, X, 0)->
FinalPi = Pies/X,
io:fwrite("Pi = ~w~n", [FinalPi]);
addPi(Pies, X, Rem)->
receive
{Estimate} ->
addPi(Pies+Estimate, X, Rem-1)
end.
montecarlo(N)->
montecarlo(N,0,0).
montecarlo(0,InCircle,NumPoints)->
4*InCircle / NumPoints;
%io:fwrite("Pi = ~w~n", [PiEst]);
montecarlo(N,InCircle,NumPoints)->
Xcoord = rand:uniform(),
Ycoord = rand:uniform(),
montecarlo(N-1,if Xcoord*Xcoord + Ycoord*Ycoord < 1 -> InCircle + 1; true -> InCircle end,NumPoints + 1).
The lists:foreach/2 seems like a good fit when you need to do something iteratively with side effects such as spawning a process.
You could map/2 the NumIterPerActor into a IterList list and use foreach/2 to spawn the processes iteratively over it.
montecarlo(N, X) ->
NumIterPerActor = N div X,
IterList = lists:map(fun(_) -> NumIterPerActor end, lists:seq(1, X)),
lists:foreach(fun(IPA) -> spawn(?MODULE, montecarlo, [IPA]) end, IterList).
To answer your last question, note that inside map/2 or foreach/2 you could wrap any function call inside a lambda function and pass the relevant arguments to it.
Related
I'm implementing the Runge-Kutta-4 method for ODE approximation with a step correction procedure.
Here's the code:
function RK4 (v,h,cant_ec) !Runge-Kutta 4to Orden
real(8),dimension(0:cant_ec)::RK4,v
real::h
integer::cant_ec
real(8),dimension(0:cant_ec)::k1,k2,k3,k4
k1 = h*vprima(v)
k2 = h*vprima(v+k1/2.0)
k3 = h*vprima(v+k2/2.0)
k4 = h*vprima(v+k3)
v = v + (k1+2.0*k2+2.0*k3+k4)/6.0 !la aproximación actual con paso h
RK4 = v
end function RK4
subroutine RK4h1(v,h,xf,tol,cant_ec) !Runge-Kutta con corrección de paso por método 1
real(8),dimension(0:cant_ec)::v
real::h,tol,xf
integer::cant_ec,i,n
real(8),dimension(0:cant_ec)::v1,v2
real(8)::error
n = int((xf-v(0))/h +0.5)
open(2,file = "derivada.txt",status="replace")
error = 2*tol
do i = 1,n, 1
do while(error > tol)
v1 = RK4(v,h,cant_ec)
v2 = RK4(v,h/2,cant_ec)
v2 = v2 + RK4(v+v2,h/2,cant_ec)
error = MAXVAL(ABS(v1-v2))
if (error > tol) then
h = h/2
end if
end do
end do
write(*,*)v1
write(2,*)v1
close(2,status="keep")
call system("gnuplot -persist 'derivada.p'")
end subroutine Rk4h1
Where h is the step size, v is a vector of cant_ec components that corresponds to the order of the ODE (that is: v(0) = x,v(1) = y,v(2) = y', etc), tol is the tolerance of error and xf is the end of the x interval (assuming it starts at 0). All these values are inputted by the user before the subroutine call. The initial values given for this particular function are y(0) = -1. Everything else is defined by the user when running the script.
The differential equation is given by:
function vprima(v,x,y) !definición de la función derivada
real(8),dimension(0:cant_ec)::v,vprima
vprima(0) = 1.0
vprima(1) = (-v(1)/(v(0)**2+1))
end function vprima
noting that on the main program this assignment occurs:
v(0) = x
v(1) = y
where x and y are the initial values of the function, given by the user.
My issue is, the script seems to get stuck on an infinite loop when I call RK4h1.
Any help, or clue, would be appreciated. Thank you.
v2 = v2 + RK4(v+v2,h/2,cant_ec) is wrong, it should be v2 = RK4(v2,h/2,cant_ec), as the result of RK4 is the next point, not the update to the next point. As the error calculation is thus wrong, the step size gets reduced indefinitely. After some 50 reductions, the RK4 step will no longer advance the state, the increment being too small.
It will lead to problems if you have a fixed step number with a variable step size.
The inner loop does not make any sense whatsoever. The overall effect is that after each step size reduction i gets incremented by one. So theoretically, if n<50 the program should terminate, but with a final state very close to the initial state.
The local error should be compared to tol*h, so that the global error becomes proportional to tol.
There should also be an instruction that increases h if the local error becomes too small.
See How to perform adaptive step size using Runge-Kutta fourth order (Matlab)? for another example of using RK4 with step-size control by double steps.
In my python application I have a big list (now with almost 9000 indexes). I need to find the two most similar items in this list. So, what I have now is something like:
aux1 = 0
aux2 = 1
min_distance = 0xffff
weights = get_weights()
for i in range(0, len(_list)):
for j in range(i + 1, len(_list)):
obj1 = _list[i]
obj2 = _list[j]
dist = 0
for key in self.__fields:
dist += weights[key] * (obj1[key] - obj2[key]) ** 2
if dist < min_distance:
min_distance = dist
aux1 = i
aux2 = j
return aux1, aux2, min_distance
In the code, weights is a dict, obj1 and obj2 are both objects in which the __getitem__ is implemented and the return value also comes from a dict. And self.__fields is a list with the selected fields (it has now 9 items).
My problem is, this loop is taking too much time to complete. Even after 5 hours, the i variable still in the first 100th list items.
With this next silly code, I come to the conclusion that the problem is not the size of the list (the silly code finishes with 5 minutes of difference).
count = 0
total = 9000
for i in range(0, total):
for j in range(i + 1, total):
for k in range(0, 10):
count += 1
print("Count is " + str(count))
Therefore, the problem seems to be in the most internal loop of my code:
for key in self.__fields:
dist += weights[key] * (obj1[key] - obj2[key]) ** 2
I know Python, but I'm not a Python specialist. I conclude that the access to the values of three objects through their key is a slow operation. Some time ago, I saw in some blog that list comprehensions and/or lambda operations can be faster.
So, my question is: how do I make this most internal loop faster using list comprehensions and/or lambda? Feel free to give any other advice if you want.
Not sure whether it's any faster, but you could rewrite that code using itertools.combinations and get the min using a key function calculating the "distance".
from itertools import combinations
weights = get_weights()
aux1, aux2 = min(combinations(_list, 2),
key=lambda pair: sum(weights[key] * (pair[0][key] - pair[1][key]) ** 2
for key in self.__fields))
If this does not help, you might consider temporarily turning the dictionaries in _list into lists, holding just the values of the relevant fields. Instead of using dictionary lookup, you can then just zip those lists together with the weights. Afterwards, turm them back into dicts.
weights_list = [weights[f] for f in self.__fields]
as_lists = [[d[f] for f in self.__fields] for d in _list]
aux1, aux2 = min(combinations(as_lists, 2),
key=lambda pair: sum(w * (x - y) ** 2
for w, x, y in zip(weights_list, *pair)))
aux1, aux2 = (dict(zip(self.__fields, x)) for x in (aux1, aux2))
This should be a bit faster, but it will only work if the dicts do not have any other fields than those in self.__fields, otherwise the dicts can not be reconstructed from the lists (at least not as easily). Alternatively, you might use tuples instead of lists and use another dictionary to map those tuples to the original dictionaries...
Or try this, using the indices of the elements instead of the elements themselves (not tested):
idx1, idx2 = min(combinations(range(len(_list)), 2),
key=lambda pair: sum(w * (x - y) ** 2
for w, x, y in zip(weights_list, as_list[pair[0]], as_list[pair[1]])))
aux1, aux2 = _lists[idx1], _lists[idx2]
I am trying to solve a set of M simultaneous eqns with M variables. I input a M X 2 matrix in as an initial guess to my function and it returns a M X 2 matrix, where each entry would equal zero if my guess was correct. Thus my function can be represented as f_k(u1,u2,...uN) = 0 for k=1,2,...N. Below is the code for my function, (for simplicities sake I have left out the modules that go with this code, i.e. p. or phi. for instance. I was more wondering if anyone else has had this error before)
M = len(p.x_lat)
def main(u_A):
## unpack u_A
u_P = u_total[:,0]
u_W = u_total[:,1]
## calculate phi_A for all monomeric species
G_W = exp(-u_W)
phi_W = zeros(M)
phi_W[1:] = p.phi_Wb * G_W[1:]
## calculate phi_A for all polymeric species
G_P = exp(-u_P)
G_P[0] = 0.
G_fwd = phi.fwd_propagator(G_P,p.Np,0) #(function that takes G_P and propagates outward)
G_bkwd = phi.bkwd_propagator(G_P,p.Np,0) #(function that takes G_P and propagates inward)
phi_P = phi.phi_P(G_fwd,G_bkwd,p.norm_graft_density,p.Np) #(function that takes the two propagators and combines them to calculate a segment density at each point)
## calculate u_A components
u_intW = en.u_int_AB(p.chi_PW,phi_P,p.phi_Pb) + en.u_int_AB(p.chi_SW,p.phi_S,p.phi_Sb) #(fxn that calculates new potential from the new segment densities)
u_intW[0] = 0.
u_Wprime = u_W - u_intW
u_intP = en.u_int_AB(p.chi_PW,phi_W,p.phi_Wb) + en.u_int_AB(p.chi_PS,p.phi_S,p.phi_Sb) #(fxn that calculates new potential from the new segment densities)
u_intP[0] = 0.
u_Pprime = u_P - u_intP
## calculate f_A
phi_total = p.phi_S + phi_W + phi_P
u_prime = 0.5 * (u_Wprime + u_Pprime)
f_total = zeros( (M, 2) )
f_total[:,0] = 1. - 1./phi_total + u_prime - u_Wprime
f_total[:,1] = 1. - 1./phi_total + u_prime - u_Pprime
return f_total
I researched ways of solving nonlinear equations such as this one using python. I came across the scipy.optimize library with the several options for solvers http://docs.scipy.org/doc/scipy-0.13.0/reference/optimize.nonlin.html. I first tried to use the newton_krylov solver and received the following error message:
ValueError: Jacobian inversion yielded zero vector. This indicates a bug in the Jacobian approximation.
I also tried broyden1 solver and it never converged but simply stayed stagnant. Code for implementation of both below:
sol = newton_krylov(main, guess, verbose=1, f_tol=10e-7)
sol = broyden1(main, guess, verbose=1, f_tol=10e-7)
My initial guess is given below here:
## first guess of u_A(x)
u_P = zeros(M)
u_P[1] = -0.0001
u_P[M-1] = 0.0001
u_W = zeros(M)
u_W[1] = 0.0001
u_W[M-1] = -0.0001
u_total = zeros( (M,2) )
u_total[:,0] = u_P
u_total[:,1] = u_W
guess = u_total
Any help would be greatly appreciated!
I am working on a object tracking project and I want to improve the results I am getting using a Kalman filter.
I have found a lot of examples on the internet which are working but I really want to understand what is behind it.
Using opencv, here is a part of the code :
KalmanFilter KF(6, 2, 0);
Mat_ state(6, 1);
Mat processNoise(6, 1, CV_32F);
...
KF.statePre.at(0) = mouse_info.x;
KF.statePre.at(1) = mouse_info.y;
KF.statePre.at(2) = 0;
KF.statePre.at(3) = 0;
KF.statePre.at(4) = 0;
KF.statePre.at(5) = 0;
KF.transitionMatrix = *(Mat_(6, 6) << 1,0,1,0,0.5,0, 0,1,0,1,0,0.5, 0,0,1,0,1,0, 0,0,0,1,0,1, 0,0,0,0,1,0, 0,0,0,0,0,1);
KF.measurementMatrix = *(Mat_(2, 6) << 1,0,1,0,0.5,0, 0,1,0,1,0,0.5);
This one gives smoother results than a KalmanFilter(4,2,0) but I don't really understand why.
Can someone explain me what is behind this (6,6) transition matrix ?
EDIT : The solution is probably here but obviously I am not good enough to find it by myself ...
Thank you for your help.
You have a state vector X made up of 6 components, the first two of which are the x and y position of an object; let's assume that the other 4 are their velocities and accelerations:
X = [x, y, v_x, v_y, a_x, a_y] t
In the Kalman filter, your next state, Xt+1, is equal to the previous state Xt multiplied by the transition matrix A, so with the transition matrix you posted, you would have:
x t+1 = x t + v_x t + 0.5 a_x t
y t+1 = y t + v_y t + 0.5 a_y t
v_x t+1 = v_x t + a_x t
v_y t+1 = v_t t + a_t t
a_x t+1 = a_x t
a_y t+1 = a_y t
Which are the discrete approximation of the equations of an object moving with constant acceleration if the time interval between the two states is equal to 1 (and that's why it makes sense to suppose that the other four variables are velocities and accelerations).
This is a Kalman filter that allows for faster variations in the velocity estimation, so it introduces a lower delay than a (4, 2, 0) filter, which would use a constant velocity model.
Let std::vector<int> counts be a vector of positive integers and let N:=counts[0]+...+counts[counts.length()-1] be the the sum of vector components. Setting pi:=counts[i]/N, I compute the entropy using the classic formula H=p0*log2(p0)+...+pn*log2(pn).
The counts vector is changing --- counts are incremented --- and every 200 changes I recompute the entropy. After a quick google and stackoverflow search I couldn't find any method for incremental entropy computation. So the question: Is there an incremental method, like the ones for variance, for entropy computation?
EDIT: Motivation for this question was usage of such formulas for incremental information gain estimation in VFDT-like learners.
Resolved: See this mathoverflow post.
I derived update formulas and algorithms for entropy and Gini index and made the note available on arXiv. (The working version of the note is available here.) Also see this mathoverflow answer.
For the sake of convenience I am including simple Python code, demonstrating the derived formulas:
from math import log
from random import randint
# maps x to -x*log2(x) for x>0, and to 0 otherwise
h = lambda p: -p*log(p, 2) if p > 0 else 0
# update entropy if new example x comes in
def update(H, S, x):
new_S = S+x
return 1.0*H*S/new_S+h(1.0*x/new_S)+h(1.0*S/new_S)
# entropy of union of two samples with entropies H1 and H2
def update(H1, S1, H2, S2):
S = S1+S2
return 1.0*H1*S1/S+h(1.0*S1/S)+1.0*H2*S2/S+h(1.0*S2/S)
# compute entropy(L) using only `update' function
def test(L):
S = 0.0 # sum of the sample elements
H = 0.0 # sample entropy
for x in L:
H = update(H, S, x)
S = S+x
return H
# compute entropy using the classic equation
def entropy(L):
n = 1.0*sum(L)
return sum([h(x/n) for x in L])
# entry point
if __name__ == "__main__":
L = [randint(1,100) for k in range(100)]
M = [randint(100,1000) for k in range(100)]
L_ent = entropy(L)
L_sum = sum(L)
M_ent = entropy(M)
M_sum = sum(M)
T = L+M
print("Full = ", entropy(T))
print("Update = ", update(L_ent, L_sum, M_ent, M_sum))
You could re-compute the entropy by re-computing the counts and using some simple mathematical identity to simplify the entropy formula
K = count.size();
N = count[0] + ... + count[K - 1];
H = count[0]/N * log2(count[0]/N) + ... + count[K - 1]/N * log2(count[K - 1]/N)
= F * h
h = (count[0] * log2(count[0]) + ... + count[K - 1] * log2(count[K - 1]))
F = -1/(N * log2(N))
which holds because of log2(a / b) == log2(a) - log2(b)
Now given an old vector count of observations so far and another vector of new 200 observations called batch, you can do in C++11
void update_H(double& H, std::vector<int>& count, int& N, std::vector<int> const& batch)
{
N += batch.size();
auto F = -1/(N * log2(N));
for (auto b: batch)
++count[b];
H = F * std::accumulate(count.begin(), count.end(), 0.0, [](int elem) {
return elem * log2(elem);
});
}
Here I assume that you have encoded your observations as int. If you have some kind of symbol, you would need a symbol table std::map<Symbol, int>, and do a lookup for each symbol in batch before you update the count.
This seems the quickest way of writing some code for a general update. If you know that in every batch only few counts actually change, you can do as #migdal does and keep track of the changing counts, subtract their old contribution to the entropy and add the new contribution.