Commit 32b22926 by Fredrik Bagge Carlson

### Solved the issue of negative precision

parent 59d2e3ac
 ... ... @@ -15,7 +15,8 @@ Based on implementation by } http://www.mathworks.com/matlabcentral/fileexchange/29809-cuckoo-search--cs--algorithm """ function cuckoo_search(f,X0;Lb=-convert(Float64,Inf),Ub=convert(Float64,Inf),n=25,pa=0.25, Tol=1.0e-5, max_iter = 1e5, timeout = Inf) function cuckoo_search(f,X0, Lb,Ub;n=25,pa=0.25, Tol=1.0e-5, max_iter = 1e5, timeout = Inf) X00 = deepcopy(X0) nd=size(X0,1); X0t = X0' Lb = Lb' ... ... @@ -29,13 +30,18 @@ function cuckoo_search(f,X0;Lb=-convert(Float64,Inf),Ub=convert(Float64,Inf),n=2 # Random initial solutions nest = zeros(n,nd) nest[1,:] = X0 nest[1,:] = X0t for i=2:n nest[i,:]=Lb+(Ub-Lb).*rand(size(Lb)); DEBUG && @assert !any(nest[i,:] .> Ub) DEBUG && @assert !any(nest[i,:] .< Lb) end # Get the current best fitness=10^20*ones(n,1); fmin,bestnest,nest,fitness=get_best_nest(f,nest,nest,fitness); DEBUG && println("f(X0) = \$(f(X00)), f(bestnest) = \$(fmin)") DEBUG && @assert X00 == X0 N_iter=0; t0 = time() ## Starting iterations ... ... @@ -72,6 +78,7 @@ function cuckoo_search(f,X0;Lb=-convert(Float64,Inf),Ub=convert(Float64,Inf),n=2 ## Post-optimization processing ## Display all the nests println("Total number of iterations=",N_iter); println("f(bestnest) = \$(fmin)") squeeze(bestnest',2),fmin end ... ... @@ -106,8 +113,10 @@ function get_cuckoos(nest,best,Lb,Ub) s=s+stepsize.*randn(size(s)); # Apply simple bounds/limits nest[j,:]=simplebounds(s,Lb,Ub); DEBUG && @assert !any(nest[j,:] .> Ub) DEBUG && @assert !any(nest[j,:] .< Lb) end nest return nest end ## Find the current best nest function get_best_nest(f,nest,newnest,fitness) ... ... @@ -123,7 +132,7 @@ function get_best_nest(f,nest,newnest,fitness) # Find the current best (fmin,K) = findmin(fitness) ; best=nest[K,:]; fmin,best,nest,fitness return fmin,best,nest,fitness end ... ... @@ -140,19 +149,21 @@ function empty_nests(nest,Lb,Ub,pa) ## New solution by biased/selective random walks stepsize=rand()*(nest[randperm(n),:]-nest[randperm(n),:]); new_nest=nest+stepsize.*K; for j = 1:size(nest,1) new_nest[j,:]=simplebounds(new_nest[j,:],Lb,Ub); end return new_nest end # Application of simple constraints function simplebounds(s,Lb,Ub) # Apply the lower bound ns_tmp=s; I=ns_tmp.Ub; ns_tmp[J]=Ub[J]; # Update this new move s=ns_tmp; J = s.>Ub; s[J] = Ub[J]; return s end # # ## You can replace the following by your own functions ... ...
 using Devectorize using Clustering using Debug # using Debug include("levenberg_marquardt.jl") include("../cuckooSearch.jl") type RbfNonlinearParameters x::Vector{Float64} ... ... @@ -9,14 +10,6 @@ type RbfNonlinearParameters n_centers::Integer end type RbfLinearParameters x::Vector{Float64} end type RbfParameters n::RbfNonlinearParameters l::RbfLinearParameters end ... ... @@ -51,6 +44,7 @@ function trainRBF_ARX(y, A, state, nc; liniters=3,nonliniters=50, normalized=fal params[si:si+n_state-1,iter] = clusterresult.centers[:,i] C = cov(state[clusterresult.assignments .== i,:]) params[si+n_state:si+2n_state-1,iter] = diag(inv(C)) @assert !any(diag(inv(C)) .< 0) end errorvec[iter] = rms(predictionerror(params[:,iter])) end ... ... @@ -76,57 +70,12 @@ function trainRBF_ARX(y, A, state, nc; liniters=3,nonliniters=50, normalized=fal newplot(X[:,1],X[:,2],"o"); title("Centers") end function getΨ(Znl) RBF(x, Znl::VecOrMat,n_state::Integer) = exp(-(((x-Znl[1:n_state]).^2.*Znl[n_state+1:end])[1])) if normalized rowsum = ones(n_points) for (j,Zi) in enumerate(Znl) for i = n_state+1:2n_state Zi[i] = Zi[i] <= 0 ? 1.0 : Zi[i] # Reset to 1 if precision became negative end for i = 1:n_points statei = squeeze(state[i,:]',2) a = RBF(statei, Zi, n_state) Ψ[i,j] = a rowsum[i] += a end end for i = 1:n_points if rowsum[i] <= 1e-10 continue end @devec Ψ[i,:] ./= rowsum[i] end else # Not normalized for (j,Zi) in enumerate(Znl) for i = n_state+1:2n_state Zi[i] = Zi[i] <= 0 ? 1.0 : Zi[i] # Reset to 1 if precision became negative end for i = 1:n_points statei = squeeze(state[i,:]',2) # statei = slice(state,i,:) Ψ[i,j] = RBF(statei, Zi, n_state) if DEBUG && !isfinite(Ψ[i,j]) @show i,j,statei, Zi, n_state, Ψ[i,j] @show (statei-Zi[1:n_state]).^2 @show Zi[n_state+1:end] # @show exp(-(((statei-Zi[1:n_state]).^2.*Zi[n_state+1:end])[1])) error("Stopping") end end end end if DEBUG && sum(!isfinite(Ψ)) > 0 @show sum(!isfinite(Ψ)) end return Ψ end function fitlinear(V) try assert(isa(V,Matrix)) assert(isa(y,Vector)) DEBUG && assert(isa(V,Matrix)) DEBUG && assert(isa(y,Vector)) DEBUG && assert(!any(!isfinite(V))) DEBUG && assert(!any(!isfinite(y))) return V\y ... ... @@ -170,42 +119,14 @@ function trainRBF_ARX(y, A, state, nc; liniters=3,nonliniters=50, normalized=fal return J end function getLinearRegressor(Ψ) if outputnet ii = 1 for i = 1:na for k = 1:n_centers+1 for j = 1:n_state for l = 1:n_points V[l,ii] = Ψ[l,k]*A[l,i]*state[l,j] end ii = ii+1 end end end else ii = 1 for i = 1:na for k = 1:n_centers+1 for l = 1:n_points V[l,ii] = Ψ[l,k]*A[l,i] end ii = ii+1 end end end if DEBUG && sum(!isfinite(V)) > 0 @show sum(!isfinite(V)) end return V end function predictionerror(z) znl = RbfNonlinearParameters(z,n_state,n_centers) getΨ(znl); getLinearRegressor(Ψ); zl = fitlinear(V); prediction = V*zl psi = getΨ(deepcopy(Ψ), znl, state, n_points, n_state, normalized) v = getLinearRegressor(deepcopy(V),psi,A,state,outputnet,na,n_state,n_centers,n_points) zl = fitlinear(v); prediction = v*zl error = prediction-y return error end ... ... @@ -243,9 +164,9 @@ function trainRBF_ARX(y, A, state, nc; liniters=3,nonliniters=50, normalized=fal Znl = getcentersKmeans(state,nc); debug("gotcentersKmeans") end @ddshow Znl getΨ(Znl); debug("Got Ψ") getΨ(Ψ, Znl, state, n_points, n_state, normalized); debug("Got Ψ") @ddshow sum(!isfinite(Ψ)) getLinearRegressor(Ψ); debug("Got linear regressor V") getLinearRegressor(V,Ψ,A,state,outputnet,na,n_state,n_centers,n_points); debug("Got linear regressor V") @ddshow size(V) @ddshow sum(!isfinite(V)) Zl = fitlinear(V); debug("fitlinear") ... ... @@ -254,55 +175,80 @@ function trainRBF_ARX(y, A, state, nc; liniters=3,nonliniters=50, normalized=fal error = y - prediction errors = zeros(liniters+1) Lb = zeros(Znl.x) Ub = zeros(Znl.x) mas = maximum(state,1)' mis = minimum(state,1)' for i = 1:2n_state:n_centers*2n_state Lb[i:i+n_state-1] = mis Ub[i:i+n_state-1] = mas Lb[i+n_state:i+2n_state-1] = 0.000001 Ub[i+n_state:i+2n_state-1] = 10*Znl.x[n_state+1:2n_state] end @show Lb @show Ub # ============= Main loop ================================================ debug("Calculating initial error") errors[1] = sse(predictionerror(Znl.x)) errors[1] = rms(predictionerror(Znl.x)) println("Training RBF_ARX Centers: \$(Znl.n_centers), Nonlinear parameters: \$(length(Znl.x)), Linear parameters: \$(length(Zl))") function g(z) znl = RbfNonlinearParameters(z,n_state,n_centers) w = fitlinear(V) jacobian(znl,Ψ, w) end f(z) = predictionerror(z) X0 = deepcopy(Znl.x) for i = 1:liniters function g(z) znl = RbfNonlinearParameters(z,n_state,n_centers) w = fitlinear(V) jacobian(znl,Ψ, w) end f(z) = predictionerror(z) X0 = Znl.x if i%2 == 1 || !cuckoosearch @time res = levenberg_marquardt(f, g, X0, maxIter = nonliniters, tolG = 1e-7, tolX = 1e-10, show_trace=true, timeout = 60) Znl = RbfNonlinearParameters(saturatePrecision(res.minimum,n_state),n_state,n_centers) timeout = 60, n_state = n_state) X0 = deepcopy(res.minimum) assert(X0 == res.minimum) @show rms(f(X0)) if DEBUG _V = deepcopy(V) _Ψ = deepcopy(Ψ) end @show rms(f(res.minimum)) if DEBUG @show res.minimum == X0 @show _V == V @show _Ψ == Ψ end assert(X0 == res.minimum) # Znl = RbfNonlinearParameters(saturatePrecision(copy(res.minimum),n_state),n_state,n_centers) Znl = RbfNonlinearParameters(deepcopy(res.minimum),n_state,n_centers) errors[i+1] = res.f_minimum # show(res.trace) else display("Using cuckoo search to escape local minimum") @time (bestnest,fmin) = cuckoo_search(x -> sum(f(x).^2),X0; n=30, @time (bestnest,fmin) = cuckoo_search(x -> rms(f(x)),X0, Lb, Ub; n=50, pa=0.25, Tol=1.0e-5, max_iter = i < liniters-1 ? 80 : 200, timeout = 120) debug("cuckoo_search done") Znl = RbfNonlinearParameters(bestnest,n_state,n_centers) X0 = deepcopy(bestnest) @ddshow rms(f(X0)) Znl = RbfNonlinearParameters(deepcopy(bestnest),n_state,n_centers) errors[i+1] = fmin end if abs(errors[i+1]-errors[i]) < 1e-10 display("No significant change in function value") break end getΨ(Znl) getLinearRegressor(Ψ) fitlinear(V) # Znl.x = res.minimum end # Test =============================================== getΨ(Znl) getLinearRegressor(Ψ) getΨ(Ψ, Znl, state, n_points, n_state, normalized) getLinearRegressor(V,Ψ,A,state,outputnet,na,n_state,n_centers,n_points) Zl = fitlinear(V); debug("fitlinear") prediction = V*Zl error = y - prediction ... ... @@ -361,4 +307,85 @@ end function getΨ(Ψ, Znl, state, n_points, n_state, normalized::Bool) Ψ = normalized ? getΨnormalized(Ψ, Znl, state, n_points, n_state) : getΨnonnormalized(Ψ, Znl, state, n_points, n_state) if DEBUG && sum(!isfinite(Ψ)) > 0 @show sum(!isfinite(Ψ)) end return Ψ end function getΨnormalized(Ψ, Znl, state, n_points, n_state) RBF(x, Znl::VecOrMat,n_state::Integer) = exp(-(((x-Znl[1:n_state]).^2.*Znl[n_state+1:end])[1])) rowsum = ones(n_points) for (j,Zin) in enumerate(Znl) Zi = deepcopy(Zin) # for i = n_state+1:2n_state # Zi[i] = Zi[i] <= 0 ? 0.01 : Zi[i] # Reset to 1 if precision became negative # end for i = 1:n_points statei = squeeze(state[i,:]',2) a = RBF(statei, Zi, n_state) Ψ[i,j] = a rowsum[i] += a end end for i = 1:n_points if rowsum[i] <= 1e-10 continue end @devec Ψ[i,:] ./= rowsum[i] end return Ψ end function getΨnonnormalized(Ψ, Znl, state, n_points, n_state) RBF(x, Znl::VecOrMat,n_state::Integer) = exp(-(((x-Znl[1:n_state]).^2.*Znl[n_state+1:end])[1])) for (j,Zin) in enumerate(Znl) Zi = deepcopy(Zin) for i = 1:n_points statei = squeeze(state[i,:]',2) # statei = slice(state,i,:) Ψ[i,j] = RBF(statei, Zi, n_state) if DEBUG && !isfinite(Ψ[i,j]) @show i,j,statei, Zi, n_state, Ψ[i,j] @show (statei-Zi[1:n_state]).^2 @show Zi[n_state+1:end] # @show exp(-(((statei-Zi[1:n_state]).^2.*Zi[n_state+1:end])[1])) error("Stopping") end end end return Ψ end function getLinearRegressor(V,Ψ,A,state,outputnet,na,n_state,n_centers,n_points) if outputnet ii = 1 for i = 1:na for k = 1:n_centers+1 for j = 1:n_state for l = 1:n_points V[l,ii] = Ψ[l,k]*A[l,i]*state[l,j] end ii = ii+1 end end end else ii = 1 for i = 1:na for k = 1:n_centers+1 for l = 1:n_points V[l,ii] = Ψ[l,k]*A[l,i] end ii = ii+1 end end end if DEBUG && sum(!isfinite(V)) > 0 @show sum(!isfinite(V)) end return V end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!