Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Fredrik Bagge Carlson
SystemIdentification
Commits
32b22926
Commit
32b22926
authored
Sep 09, 2015
by
Fredrik Bagge Carlson
Browse files
Solved the issue of negative precision
parent
59d2e3ac
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/cuckooSearch.jl
View file @
32b22926
...
...
@@ -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
,
:
]
=
X0
t
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
.<
Lb
;
ns_tmp
[
I
]
=
Lb
[
I
];
I
=
s
.<
Lb
;
s
[
I
]
=
Lb
[
I
];
# Apply the upper bounds
J
=
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
...
...
src/rbfmodels/trainRBF_ARX.jl
View file @
32b22926
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
+
2
n_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
:
2
n_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
:
2
n_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
:
2
n_state
:
n_centers
*
2
n_state
Lb
[
i
:
i
+
n_state
-
1
]
=
mis
Ub
[
i
:
i
+
n_state
-
1
]
=
mas
Lb
[
i
+
n_state
:
i
+
2
n_state
-
1
]
=
0.000001
Ub
[
i
+
n_state
:
i
+
2
n_state
-
1
]
=
10
*
Znl
.
x
[
n_state
+
1
:
2
n_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
=
3
0
,
@time
(
bestnest
,
fmin
)
=
cuckoo_search
(
x
->
rms
(
f
(
x
)),
X0
,
Lb
,
Ub
;
n
=
5
0
,
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
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment