23 #if (AE_COMPILER==AE_MSVC) 24 #pragma warning(disable:4100) 25 #pragma warning(disable:4127) 26 #pragma warning(disable:4702) 27 #pragma warning(disable:4996) 73 alglib_impl::dsoptimalsplit2(const_cast<alglib_impl::ae_vector*>(a.
c_ptr()), const_cast<alglib_impl::ae_vector*>(c.
c_ptr()), n, &info, &threshold, &pal, &pbl, &par, &pbr, &cve, &_alglib_env_state);
107 void dsoptimalsplit2fast(
real_1d_array &
a,
integer_1d_array &
c,
integer_1d_array &tiesbuf,
integer_1d_array &cntbuf,
real_1d_array &bufr,
integer_1d_array &bufi,
const ae_int_t n,
const ae_int_t nc,
const double alpha,
ae_int_t &info,
double &
threshold,
double &
rms,
double &cvrms)
113 alglib_impl::dsoptimalsplit2fast(const_cast<alglib_impl::ae_vector*>(a.
c_ptr()), const_cast<alglib_impl::ae_vector*>(c.
c_ptr()), const_cast<alglib_impl::ae_vector*>(tiesbuf.
c_ptr()), const_cast<alglib_impl::ae_vector*>(cntbuf.
c_ptr()), const_cast<alglib_impl::ae_vector*>(bufr.
c_ptr()), const_cast<alglib_impl::ae_vector*>(bufi.
c_ptr()), n, nc, alpha, &info, &threshold, &rms, &cvrms, &_alglib_env_state);
132 _clusterizerstate_owner::_clusterizerstate_owner()
136 throw ap_error(
"ALGLIB: malloc error");
138 throw ap_error(
"ALGLIB: malloc error");
145 throw ap_error(
"ALGLIB: malloc error");
147 throw ap_error(
"ALGLIB: malloc error");
156 throw ap_error(
"ALGLIB: malloc error");
160 _clusterizerstate_owner::~_clusterizerstate_owner()
287 throw ap_error(
"ALGLIB: malloc error");
289 throw ap_error(
"ALGLIB: malloc error");
296 throw ap_error(
"ALGLIB: malloc error");
298 throw ap_error(
"ALGLIB: malloc error");
307 throw ap_error(
"ALGLIB: malloc error");
382 throw ap_error(
"ALGLIB: malloc error");
384 throw ap_error(
"ALGLIB: malloc error");
391 throw ap_error(
"ALGLIB: malloc error");
393 throw ap_error(
"ALGLIB: malloc error");
402 throw ap_error(
"ALGLIB: malloc error");
589 nfeatures = xy.
cols();
683 throw ap_error(
"Error while calling 'clusterizersetdistances': looks like one of arguments has wrong size");
1181 alglib_impl::kmeansgenerate(const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, nvars, k, restarts, &info, const_cast<alglib_impl::ae_matrix*>(c.
c_ptr()), const_cast<alglib_impl::ae_vector*>(xyc.
c_ptr()), &_alglib_env_state);
1198 throw ap_error(
"ALGLIB: malloc error");
1200 throw ap_error(
"ALGLIB: malloc error");
1207 throw ap_error(
"ALGLIB: malloc error");
1209 throw ap_error(
"ALGLIB: malloc error");
1218 throw ap_error(
"ALGLIB: malloc error");
1265 throw ap_error(
"ALGLIB: malloc error");
1267 throw ap_error(
"ALGLIB: malloc error");
1274 throw ap_error(
"ALGLIB: malloc error");
1276 throw ap_error(
"ALGLIB: malloc error");
1285 throw ap_error(
"ALGLIB: malloc error");
1304 dfreport::dfreport() :
_dfreport_owner() ,relclserror(
p_struct->relclserror),avgce(
p_struct->avgce),rmserror(
p_struct->rmserror),avgerror(
p_struct->avgerror),avgrelerror(
p_struct->avgrelerror),oobrelclserror(
p_struct->oobrelclserror),oobavgce(
p_struct->oobavgce),oobrmserror(
p_struct->oobrmserror),oobavgerror(
p_struct->oobavgerror),oobavgrelerror(
p_struct->oobavgrelerror)
1308 dfreport::dfreport(
const dfreport &rhs):
_dfreport_owner(rhs) ,
relclserror(
p_struct->
relclserror),
avgce(
p_struct->
avgce),
rmserror(
p_struct->
rmserror),
avgerror(
p_struct->
avgerror),
avgrelerror(
p_struct->
avgrelerror),
oobrelclserror(
p_struct->
oobrelclserror),
oobavgce(
p_struct->
oobavgce),
oobrmserror(
p_struct->
oobrmserror),
oobavgerror(
p_struct->
oobavgerror),
oobavgrelerror(
p_struct->
oobavgrelerror)
1359 s_out.reserve((
size_t)(ssize+1));
1363 if( s_out.length()>(size_t)ssize )
1364 throw ap_error(
"ALGLIB: serialization integrity error");
1488 alglib_impl::dfbuildrandomdecisionforestx1(const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, nvars, nclasses, ntrees, nrndvars, r, &info, const_cast<alglib_impl::decisionforest*>(df.
c_ptr()), const_cast<alglib_impl::dfreport*>(rep.
c_ptr()), &_alglib_env_state);
1520 alglib_impl::dfprocess(const_cast<alglib_impl::decisionforest*>(df.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(y.
c_ptr()), &_alglib_env_state);
1547 alglib_impl::dfprocessi(const_cast<alglib_impl::decisionforest*>(df.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(y.
c_ptr()), &_alglib_env_state);
1578 double result =
alglib_impl::dfrelclserror(const_cast<alglib_impl::decisionforest*>(df.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
1580 return *(
reinterpret_cast<double*
>(&result));
1609 double result =
alglib_impl::dfavgce(const_cast<alglib_impl::decisionforest*>(df.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
1611 return *(
reinterpret_cast<double*
>(&result));
1642 double result =
alglib_impl::dfrmserror(const_cast<alglib_impl::decisionforest*>(df.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
1644 return *(
reinterpret_cast<double*
>(&result));
1674 double result =
alglib_impl::dfavgerror(const_cast<alglib_impl::decisionforest*>(df.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
1676 return *(
reinterpret_cast<double*
>(&result));
1706 double result =
alglib_impl::dfavgrelerror(const_cast<alglib_impl::decisionforest*>(df.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
1708 return *(
reinterpret_cast<double*
>(&result));
1723 throw ap_error(
"ALGLIB: malloc error");
1725 throw ap_error(
"ALGLIB: malloc error");
1732 throw ap_error(
"ALGLIB: malloc error");
1734 throw ap_error(
"ALGLIB: malloc error");
1743 throw ap_error(
"ALGLIB: malloc error");
1804 throw ap_error(
"ALGLIB: malloc error");
1806 throw ap_error(
"ALGLIB: malloc error");
1813 throw ap_error(
"ALGLIB: malloc error");
1815 throw ap_error(
"ALGLIB: malloc error");
1824 throw ap_error(
"ALGLIB: malloc error");
1905 alglib_impl::lrbuild(const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, nvars, &info, const_cast<alglib_impl::linearmodel*>(lm.
c_ptr()), const_cast<alglib_impl::lrreport*>(ar.
c_ptr()), &_alglib_env_state);
1951 alglib_impl::lrbuilds(const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), const_cast<alglib_impl::ae_vector*>(s.
c_ptr()), npoints, nvars, &info, const_cast<alglib_impl::linearmodel*>(lm.
c_ptr()), const_cast<alglib_impl::lrreport*>(ar.
c_ptr()), &_alglib_env_state);
1977 alglib_impl::lrbuildzs(const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), const_cast<alglib_impl::ae_vector*>(s.
c_ptr()), npoints, nvars, &info, const_cast<alglib_impl::linearmodel*>(lm.
c_ptr()), const_cast<alglib_impl::lrreport*>(ar.
c_ptr()), &_alglib_env_state);
2003 alglib_impl::lrbuildz(const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, nvars, &info, const_cast<alglib_impl::linearmodel*>(lm.
c_ptr()), const_cast<alglib_impl::lrreport*>(ar.
c_ptr()), &_alglib_env_state);
2064 alglib_impl::lrpack(const_cast<alglib_impl::ae_vector*>(v.
c_ptr()), nvars, const_cast<alglib_impl::linearmodel*>(lm.
c_ptr()), &_alglib_env_state);
2093 double result =
alglib_impl::lrprocess(const_cast<alglib_impl::linearmodel*>(lm.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), &_alglib_env_state);
2095 return *(
reinterpret_cast<double*
>(&result));
2123 double result =
alglib_impl::lrrmserror(const_cast<alglib_impl::linearmodel*>(lm.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
2125 return *(
reinterpret_cast<double*
>(&result));
2153 double result =
alglib_impl::lravgerror(const_cast<alglib_impl::linearmodel*>(lm.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
2155 return *(
reinterpret_cast<double*
>(&result));
2185 return *(
reinterpret_cast<double*
>(&result));
2551 alglib_impl::fisherlda(const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, nvars, nclasses, &info, const_cast<alglib_impl::ae_vector*>(w.
c_ptr()), &_alglib_env_state);
2602 alglib_impl::fisherldan(const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, nvars, nclasses, &info, const_cast<alglib_impl::ae_matrix*>(w.
c_ptr()), &_alglib_env_state);
2629 throw ap_error(
"ALGLIB: malloc error");
2631 throw ap_error(
"ALGLIB: malloc error");
2638 throw ap_error(
"ALGLIB: malloc error");
2640 throw ap_error(
"ALGLIB: malloc error");
2649 throw ap_error(
"ALGLIB: malloc error");
2696 throw ap_error(
"ALGLIB: malloc error");
2698 throw ap_error(
"ALGLIB: malloc error");
2705 throw ap_error(
"ALGLIB: malloc error");
2707 throw ap_error(
"ALGLIB: malloc error");
2716 throw ap_error(
"ALGLIB: malloc error");
2790 s_out.reserve((
size_t)(ssize+1));
2794 if( s_out.length()>(size_t)ssize )
2795 throw ap_error(
"ALGLIB: serialization integrity error");
2966 alglib_impl::mlpcreateb2(nin, nhid1, nhid2, nout, b, d, const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), &_alglib_env_state);
3034 alglib_impl::mlpcreater2(nin, nhid1, nhid2, nout, a, b, const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), &_alglib_env_state);
3194 return *(
reinterpret_cast<ae_int_t*
>(&result));
3216 return *(
reinterpret_cast<ae_int_t*
>(&result));
3238 return *(
reinterpret_cast<ae_int_t*
>(&result));
3260 return *(
reinterpret_cast<bool*
>(&result));
3283 return *(
reinterpret_cast<ae_int_t*
>(&result));
3311 return *(
reinterpret_cast<ae_int_t*
>(&result));
3455 return *(
reinterpret_cast<double*
>(&result));
3665 alglib_impl::mlpprocess(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(y.
c_ptr()), &_alglib_env_state);
3693 alglib_impl::mlpprocessi(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(y.
c_ptr()), &_alglib_env_state);
3770 double result =
alglib_impl::mlperror(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
3772 return *(
reinterpret_cast<double*
>(&result));
3787 double result =
alglib_impl::_pexec_mlperror(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
3789 return *(
reinterpret_cast<double*
>(&result));
3868 double result =
alglib_impl::mlperrorsparse(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::sparsematrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
3870 return *(
reinterpret_cast<double*
>(&result));
3887 return *(
reinterpret_cast<double*
>(&result));
3910 double result =
alglib_impl::mlperrorn(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), ssize, &_alglib_env_state);
3912 return *(
reinterpret_cast<double*
>(&result));
3989 return *(
reinterpret_cast<ae_int_t*
>(&result));
4006 return *(
reinterpret_cast<ae_int_t*
>(&result));
4082 double result =
alglib_impl::mlprelclserror(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
4084 return *(
reinterpret_cast<double*
>(&result));
4101 return *(
reinterpret_cast<double*
>(&result));
4180 return *(
reinterpret_cast<double*
>(&result));
4197 return *(
reinterpret_cast<double*
>(&result));
4273 double result =
alglib_impl::mlpavgce(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
4275 return *(
reinterpret_cast<double*
>(&result));
4290 double result =
alglib_impl::_pexec_mlpavgce(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
4292 return *(
reinterpret_cast<double*
>(&result));
4373 double result =
alglib_impl::mlpavgcesparse(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::sparsematrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
4375 return *(
reinterpret_cast<double*
>(&result));
4392 return *(
reinterpret_cast<double*
>(&result));
4469 double result =
alglib_impl::mlprmserror(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
4471 return *(
reinterpret_cast<double*
>(&result));
4488 return *(
reinterpret_cast<double*
>(&result));
4571 return *(
reinterpret_cast<double*
>(&result));
4588 return *(
reinterpret_cast<double*
>(&result));
4664 double result =
alglib_impl::mlpavgerror(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
4666 return *(
reinterpret_cast<double*
>(&result));
4683 return *(
reinterpret_cast<double*
>(&result));
4765 return *(
reinterpret_cast<double*
>(&result));
4782 return *(
reinterpret_cast<double*
>(&result));
4859 double result =
alglib_impl::mlpavgrelerror(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
4861 return *(
reinterpret_cast<double*
>(&result));
4878 return *(
reinterpret_cast<double*
>(&result));
4961 return *(
reinterpret_cast<double*
>(&result));
4978 return *(
reinterpret_cast<double*
>(&result));
5011 alglib_impl::mlpgrad(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(desiredy.
c_ptr()), &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), &_alglib_env_state);
5047 alglib_impl::mlpgradn(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(desiredy.
c_ptr()), &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), &_alglib_env_state);
5115 alglib_impl::mlpgradbatch(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), ssize, &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), &_alglib_env_state);
5202 alglib_impl::mlpgradbatchsparse(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::sparsematrix*>(xy.
c_ptr()), ssize, &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), &_alglib_env_state);
5301 alglib_impl::mlpgradbatchsubset(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), setsize, const_cast<alglib_impl::ae_vector*>(idx.
c_ptr()), subsetsize, &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), &_alglib_env_state);
5318 alglib_impl::_pexec_mlpgradbatchsubset(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), setsize, const_cast<alglib_impl::ae_vector*>(idx.
c_ptr()), subsetsize, &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), &_alglib_env_state);
5405 alglib_impl::mlpgradbatchsparsesubset(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::sparsematrix*>(xy.
c_ptr()), setsize, const_cast<alglib_impl::ae_vector*>(idx.
c_ptr()), subsetsize, &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), &_alglib_env_state);
5461 alglib_impl::mlpgradnbatch(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), ssize, &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), &_alglib_env_state);
5489 alglib_impl::mlphessiannbatch(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), ssize, &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(h.
c_ptr()), &_alglib_env_state);
5517 alglib_impl::mlphessianbatch(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), ssize, &e, const_cast<alglib_impl::ae_vector*>(grad.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(h.
c_ptr()), &_alglib_env_state);
5581 alglib_impl::mlpallerrorssubset(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), setsize, const_cast<alglib_impl::ae_vector*>(subset.
c_ptr()), subsetsize, const_cast<alglib_impl::modelerrors*>(rep.
c_ptr()), &_alglib_env_state);
5598 alglib_impl::_pexec_mlpallerrorssubset(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), setsize, const_cast<alglib_impl::ae_vector*>(subset.
c_ptr()), subsetsize, const_cast<alglib_impl::modelerrors*>(rep.
c_ptr()), &_alglib_env_state);
5663 alglib_impl::mlpallerrorssparsesubset(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::sparsematrix*>(xy.
c_ptr()), setsize, const_cast<alglib_impl::ae_vector*>(subset.
c_ptr()), subsetsize, const_cast<alglib_impl::modelerrors*>(rep.
c_ptr()), &_alglib_env_state);
5759 double result =
alglib_impl::mlperrorsubset(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), setsize, const_cast<alglib_impl::ae_vector*>(subset.
c_ptr()), subsetsize, &_alglib_env_state);
5761 return *(
reinterpret_cast<double*
>(&result));
5776 double result =
alglib_impl::_pexec_mlperrorsubset(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), setsize, const_cast<alglib_impl::ae_vector*>(subset.
c_ptr()), subsetsize, &_alglib_env_state);
5778 return *(
reinterpret_cast<double*
>(&result));
5860 double result =
alglib_impl::mlperrorsparsesubset(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::sparsematrix*>(xy.
c_ptr()), setsize, const_cast<alglib_impl::ae_vector*>(subset.
c_ptr()), subsetsize, &_alglib_env_state);
5862 return *(
reinterpret_cast<double*
>(&result));
5879 return *(
reinterpret_cast<double*
>(&result));
5894 throw ap_error(
"ALGLIB: malloc error");
5896 throw ap_error(
"ALGLIB: malloc error");
5903 throw ap_error(
"ALGLIB: malloc error");
5905 throw ap_error(
"ALGLIB: malloc error");
5914 throw ap_error(
"ALGLIB: malloc error");
5963 throw ap_error(
"ALGLIB: malloc error");
5965 throw ap_error(
"ALGLIB: malloc error");
5972 throw ap_error(
"ALGLIB: malloc error");
5974 throw ap_error(
"ALGLIB: malloc error");
5983 throw ap_error(
"ALGLIB: malloc error");
6054 alglib_impl::mnltrainh(const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, nvars, nclasses, &info, const_cast<alglib_impl::logitmodel*>(lm.
c_ptr()), const_cast<alglib_impl::mnlreport*>(rep.
c_ptr()), &_alglib_env_state);
6089 alglib_impl::mnlprocess(const_cast<alglib_impl::logitmodel*>(lm.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(y.
c_ptr()), &_alglib_env_state);
6117 alglib_impl::mnlprocessi(const_cast<alglib_impl::logitmodel*>(lm.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(y.
c_ptr()), &_alglib_env_state);
6151 alglib_impl::mnlunpack(const_cast<alglib_impl::logitmodel*>(lm.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(a.
c_ptr()), &nvars, &nclasses, &_alglib_env_state);
6182 alglib_impl::mnlpack(const_cast<alglib_impl::ae_matrix*>(a.
c_ptr()), nvars, nclasses, const_cast<alglib_impl::logitmodel*>(lm.
c_ptr()), &_alglib_env_state);
6212 double result =
alglib_impl::mnlavgce(const_cast<alglib_impl::logitmodel*>(lm.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
6214 return *(
reinterpret_cast<double*
>(&result));
6244 return *(
reinterpret_cast<double*
>(&result));
6272 double result =
alglib_impl::mnlrmserror(const_cast<alglib_impl::logitmodel*>(lm.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
6274 return *(
reinterpret_cast<double*
>(&result));
6302 double result =
alglib_impl::mnlavgerror(const_cast<alglib_impl::logitmodel*>(lm.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
6304 return *(
reinterpret_cast<double*
>(&result));
6334 return *(
reinterpret_cast<double*
>(&result));
6356 return *(
reinterpret_cast<ae_int_t*
>(&result));
6376 throw ap_error(
"ALGLIB: malloc error");
6378 throw ap_error(
"ALGLIB: malloc error");
6385 throw ap_error(
"ALGLIB: malloc error");
6387 throw ap_error(
"ALGLIB: malloc error");
6396 throw ap_error(
"ALGLIB: malloc error");
6455 throw ap_error(
"ALGLIB: malloc error");
6457 throw ap_error(
"ALGLIB: malloc error");
6464 throw ap_error(
"ALGLIB: malloc error");
6466 throw ap_error(
"ALGLIB: malloc error");
6475 throw ap_error(
"ALGLIB: malloc error");
7077 alglib_impl::mcpdsetbc(const_cast<alglib_impl::mcpdstate*>(s.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(bndl.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(bndu.
c_ptr()), &_alglib_env_state);
7198 alglib_impl::mcpdsetlc(const_cast<alglib_impl::mcpdstate*>(s.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(c.
c_ptr()), const_cast<alglib_impl::ae_vector*>(ct.
c_ptr()), k, &_alglib_env_state);
7254 throw ap_error(
"Error while calling 'mcpdsetlc': looks like one of arguments has wrong size");
7259 alglib_impl::mcpdsetlc(const_cast<alglib_impl::mcpdstate*>(s.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(c.
c_ptr()), const_cast<alglib_impl::ae_vector*>(ct.
c_ptr()), k, &_alglib_env_state);
7435 alglib_impl::mcpdresults(const_cast<alglib_impl::mcpdstate*>(s.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(p.
c_ptr()), const_cast<alglib_impl::mcpdreport*>(rep.
c_ptr()), &_alglib_env_state);
7452 throw ap_error(
"ALGLIB: malloc error");
7454 throw ap_error(
"ALGLIB: malloc error");
7461 throw ap_error(
"ALGLIB: malloc error");
7463 throw ap_error(
"ALGLIB: malloc error");
7472 throw ap_error(
"ALGLIB: malloc error");
7546 s_out.reserve((
size_t)(ssize+1));
7550 if( s_out.length()>(size_t)ssize )
7551 throw ap_error(
"ALGLIB: serialization integrity error");
7640 alglib_impl::mlpecreate2(nin, nhid1, nhid2, nout, ensemblesize, const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), &_alglib_env_state);
7706 alglib_impl::mlpecreateb2(nin, nhid1, nhid2, nout, b, d, ensemblesize, const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), &_alglib_env_state);
7772 alglib_impl::mlpecreater2(nin, nhid1, nhid2, nout, a, b, ensemblesize, const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), &_alglib_env_state);
7928 return *(
reinterpret_cast<bool*
>(&result));
7960 alglib_impl::mlpeprocess(const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(y.
c_ptr()), &_alglib_env_state);
7988 alglib_impl::mlpeprocessi(const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), const_cast<alglib_impl::ae_vector*>(x.
c_ptr()), const_cast<alglib_impl::ae_vector*>(y.
c_ptr()), &_alglib_env_state);
8022 return *(
reinterpret_cast<double*
>(&result));
8051 double result =
alglib_impl::mlpeavgce(const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
8053 return *(
reinterpret_cast<double*
>(&result));
8083 double result =
alglib_impl::mlpermserror(const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
8085 return *(
reinterpret_cast<double*
>(&result));
8114 double result =
alglib_impl::mlpeavgerror(const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, &_alglib_env_state);
8116 return *(
reinterpret_cast<double*
>(&result));
8147 return *(
reinterpret_cast<double*
>(&result));
8175 throw ap_error(
"ALGLIB: malloc error");
8177 throw ap_error(
"ALGLIB: malloc error");
8184 throw ap_error(
"ALGLIB: malloc error");
8186 throw ap_error(
"ALGLIB: malloc error");
8195 throw ap_error(
"ALGLIB: malloc error");
8242 throw ap_error(
"ALGLIB: malloc error");
8244 throw ap_error(
"ALGLIB: malloc error");
8251 throw ap_error(
"ALGLIB: malloc error");
8253 throw ap_error(
"ALGLIB: malloc error");
8262 throw ap_error(
"ALGLIB: malloc error");
8312 throw ap_error(
"ALGLIB: malloc error");
8314 throw ap_error(
"ALGLIB: malloc error");
8321 throw ap_error(
"ALGLIB: malloc error");
8323 throw ap_error(
"ALGLIB: malloc error");
8332 throw ap_error(
"ALGLIB: malloc error");
8408 alglib_impl::mlptrainlm(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, decay, restarts, &info, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), &_alglib_env_state);
8461 alglib_impl::mlptrainlbfgs(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, decay, restarts, wstep, maxits, &info, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), &_alglib_env_state);
8527 alglib_impl::mlptraines(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(trnxy.
c_ptr()), trnsize, const_cast<alglib_impl::ae_matrix*>(valxy.
c_ptr()), valsize, decay, restarts, &info, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), &_alglib_env_state);
8566 void mlpkfoldcvlbfgs(
const multilayerperceptron &network,
const real_2d_array &xy,
const ae_int_t npoints,
const double decay,
const ae_int_t restarts,
const double wstep,
const ae_int_t maxits,
const ae_int_t foldscount,
ae_int_t &info,
mlpreport &rep,
mlpcvreport &cvrep)
8572 alglib_impl::mlpkfoldcvlbfgs(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, decay, restarts, wstep, maxits, foldscount, &info, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), const_cast<alglib_impl::mlpcvreport*>(cvrep.
c_ptr()), &_alglib_env_state);
8615 alglib_impl::mlpkfoldcvlm(const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, decay, restarts, foldscount, &info, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), const_cast<alglib_impl::mlpcvreport*>(cvrep.
c_ptr()), &_alglib_env_state);
8711 alglib_impl::mlpkfoldcv(const_cast<alglib_impl::mlptrainer*>(s.
c_ptr()), const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), nrestarts, foldscount, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), &_alglib_env_state);
8728 alglib_impl::_pexec_mlpkfoldcv(const_cast<alglib_impl::mlptrainer*>(s.
c_ptr()), const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), nrestarts, foldscount, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), &_alglib_env_state);
9076 alglib_impl::mlptrainnetwork(const_cast<alglib_impl::mlptrainer*>(s.
c_ptr()), const_cast<alglib_impl::multilayerperceptron*>(network.
c_ptr()), nrestarts, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), &_alglib_env_state);
9270 return *(
reinterpret_cast<bool*
>(&result));
9287 return *(
reinterpret_cast<bool*
>(&result));
9326 alglib_impl::mlpebagginglm(const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, decay, restarts, &info, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), const_cast<alglib_impl::mlpcvreport*>(ooberrors.
c_ptr()), &_alglib_env_state);
9370 alglib_impl::mlpebagginglbfgs(const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, decay, restarts, wstep, maxits, &info, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), const_cast<alglib_impl::mlpcvreport*>(ooberrors.
c_ptr()), &_alglib_env_state);
9410 alglib_impl::mlpetraines(const_cast<alglib_impl::mlpensemble*>(ensemble.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(xy.
c_ptr()), npoints, decay, restarts, &info, const_cast<alglib_impl::mlpreport*>(rep.
c_ptr()), &_alglib_env_state);
9553 alglib_impl::pcabuildbasis(const_cast<alglib_impl::ae_matrix*>(x.
c_ptr()), npoints, nvars, &info, const_cast<alglib_impl::ae_vector*>(s2.
c_ptr()), const_cast<alglib_impl::ae_matrix*>(v.
c_ptr()), &_alglib_env_state);
9571 static double bdss_xlny(
double x,
double y,
ae_state *_state);
9572 static double bdss_getcv(
ae_vector* cnt,
9589 static ae_int_t clustering_parallelcomplexity = 200000;
9604 static void clustering_evaluatedistancematrixrec(
ae_matrix* xy,
9617 static ae_int_t dforest_innernodewidth = 3;
9618 static ae_int_t dforest_leafnodewidth = 2;
9619 static ae_int_t dforest_dfusestrongsplits = 1;
9620 static ae_int_t dforest_dfuseevs = 2;
9621 static ae_int_t dforest_dffirstversion = 0;
9631 static void dforest_dfbuildtree(
ae_matrix* xy,
9638 dfinternalbuffers* bufs,
9641 static void dforest_dfbuildtreerec(
ae_matrix* xy,
9651 dfinternalbuffers* bufs,
9654 static void dforest_dfsplitc(
ae_vector* x,
9666 static void dforest_dfsplitr(
ae_vector* x,
9679 static void linreg_lrinternal(
ae_matrix* xy,
9693 static ae_int_t mlpbase_mlpvnum = 7;
9694 static ae_int_t mlpbase_mlpfirstversion = 0;
9695 static ae_int_t mlpbase_nfieldwidth = 4;
9696 static ae_int_t mlpbase_hlconnfieldwidth = 5;
9697 static ae_int_t mlpbase_hlnfieldwidth = 4;
9698 static ae_int_t mlpbase_gradbasecasecost = 50000;
9699 static ae_int_t mlpbase_microbatchsize = 64;
9700 static void mlpbase_addinputlayer(
ae_int_t ncount,
9707 static void mlpbase_addbiasedsummatorlayer(
ae_int_t ncount,
9714 static void mlpbase_addactivationlayer(
ae_int_t functype,
9721 static void mlpbase_addzerolayer(
ae_vector* lsizes,
9761 static void mlpbase_mlpcreate(
ae_int_t nin,
9802 static double mlpbase_safecrossentropy(
double t,
9812 static double logit_ftol = 0.0001;
9813 static double logit_gtol = 0.3;
9815 static double logit_stpmin = 1.0E-2;
9816 static double logit_stpmax = 1.0E5;
9817 static ae_int_t logit_logitvnum = 6;
9821 static void logit_mnlallerrors(
logitmodel* lm,
9830 static void logit_mnlmcsrch(
ae_int_t n,
9839 logitmcstate* state,
9842 static void logit_mnlmcstep(
double* stx,
9858 static double mcpd_xtol = 1.0E-8;
9859 static void mcpd_mcpdinit(
ae_int_t n,
9866 static ae_int_t mlpe_mlpefirstversion = 1;
9869 static double mlptrain_mindecay = 0.001;
9870 static ae_int_t mlptrain_defaultlbfgsfactor = 6;
9884 static void mlptrain_mlpkfoldsplit(
ae_matrix* xy,
9891 static void mlptrain_mthreadcv(
mlptrainer* s,
9900 static void mlptrain_mlptrainnetworkx(
mlptrainer* s,
9912 static void mlptrain_mlptrainensemblex(
mlptrainer* s,
9922 static void mlptrain_mlpstarttrainingx(
mlptrainer* s,
9927 smlptrnsession* session,
9933 smlptrnsession* session,
9935 static void mlptrain_mlpebagginginternal(
mlpensemble* ensemble,
9950 smlptrnsession* session,
9959 mlpetrnsession* session,
10050 for(j=1; j<=nclasses-1; j++)
10069 for(j=0; j<=nclasses-1; j++)
10098 for(j=1; j<=nout-1; j++)
10106 for(j=1; j<=nout-1; j++)
10117 for(j=0; j<=nout-1; j++)
10194 if( npoints<=0||nvars<1 )
10208 for(j=0; j<=nvars-1; j++)
10211 samplemoments(&tmp, npoints, &mean, &variance, &skewness, &kurtosis, _state);
10218 for(i=0; i<=npoints-1; i++)
10258 if( npoints<=0||nvars<1 )
10272 for(j=0; j<=nvars-1; j++)
10275 samplemoments(&tmp, npoints, &mean, &variance, &skewness, &kurtosis, _state);
10313 if( npoints<=0||nvars<1 )
10324 for(i=0; i<=npoints-1; i++)
10329 for(i=0; i<=npoints-1; i++)
10331 for(j=i+1; j<=npoints-1; j++)
10342 for(i=0; i<=npoints-1; i++)
10390 tagsort(a, n, p1, p2, _state);
10396 for(i=1; i<=n-1; i++)
10400 *tiecount = *tiecount+1;
10406 for(i=1; i<=n-1; i++)
10463 for(i=1; i<=n-1; i++)
10559 for(i=0; i<=n-1; i++)
10573 dstie(a, n, &ties, &tiecount, &p1, &p2, _state);
10574 for(i=0; i<=n-1; i++)
10607 for(i=0; i<=n-1; i++)
10620 for(k=0; k<=tiecount-2; k++)
10645 cv = cv-bdss_xlny(*pal+pak, (*pal+pak)/(*pal+pak+(*pbl)+pbk+1), _state);
10646 cv = cv-bdss_xlny(*pbl+pbk, (*pbl+pbk)/(*pal+pak+1+(*pbl)+pbk), _state);
10647 cv = cv-bdss_xlny(*par-pak, (*par-pak)/(*par-pak+(*pbr)-pbk+1), _state);
10648 cv = cv-bdss_xlny(*pbr-pbk, (*pbr-pbk)/(*par-pak+1+(*pbr)-pbk), _state);
10673 for(i=0; i<=n-1; i++)
10774 for(i=0; i<=n-1; i++)
10787 dstiefasti(a, c, n, tiesbuf, &tiecount, bufr, bufi, _state);
10801 for(i=0; i<=2*nc-1; i++)
10805 for(i=0; i<=n-1; i++)
10814 for(k=0; k<=tiecount-2; k++)
10820 for(i=tiesbuf->
ptr.
p_int[k]; i<=tiesbuf->ptr.p_int[k+1]-1; i++)
10833 for(i=0; i<=nc-1; i++)
10836 v = v+w*
ae_sqr(w/sl-1, _state);
10837 v = v+(sl-
w)*
ae_sqr(w/sl, _state);
10839 v = v+w*
ae_sqr(w/sr-1, _state);
10840 v = v+(sr-
w)*
ae_sqr(w/sr, _state);
10842 v =
ae_sqrt(v/(nc*n), _state);
10847 x = (double)(2*sl)/(double)(sl+sr)-1;
10848 cc = v*(1-alpha+alpha*
ae_sqr(x, _state));
10863 for(i=0; i<=nc-1; i++)
10868 *cvrms = *cvrms+w*
ae_sqr((w-1)/(sl-1)-1, _state);
10869 *cvrms = *cvrms+(sl-
w)*
ae_sqr(w/(sl-1), _state);
10874 *cvrms = *cvrms+w*
ae_sqr((
double)1/(
double)nc-1, _state);
10875 *cvrms = *cvrms+(sl-
w)*
ae_sqr((
double)1/(double)nc, _state);
10880 *cvrms = *cvrms+w*
ae_sqr((w-1)/(sr-1)-1, _state);
10881 *cvrms = *cvrms+(sr-
w)*
ae_sqr(w/(sr-1), _state);
10886 *cvrms = *cvrms+w*
ae_sqr((
double)1/(
double)nc-1, _state);
10887 *cvrms = *cvrms+(sr-
w)*
ae_sqr((
double)1/(double)nc, _state);
10890 *cvrms =
ae_sqrt(*cvrms/(nc*n), _state);
10963 if( (n<=0||nc<2)||kmax<2 )
10969 for(i=0; i<=n-1; i++)
10983 dstie(a, n, &ties, &tiecount, &p1, &p2, _state);
10984 for(i=0; i<=n-1; i++)
11008 kmax =
ae_minint(kmax, tiecount, _state);
11019 for(i=1; i<=tiecount-1; i++)
11027 ae_assert(j>0,
"DSSplitK: internal error #1!", _state);
11032 for(i=0; i<=nc-1; i++)
11036 for(i=0; i<=j-1; i++)
11038 bdss_tieaddc(c, &ties, i, nc, &cnt, _state);
11040 bestcve = bestcve+bdss_getcv(&cnt, nc, _state);
11041 for(i=0; i<=nc-1; i++)
11045 for(i=j; i<=tiecount-1; i++)
11047 bdss_tieaddc(c, &ties, i, nc, &cnt, _state);
11049 bestcve = bestcve+bdss_getcv(&cnt, nc, _state);
11055 for(k=2; k<=kmax; k++)
11061 for(i=0; i<=k-1; i++)
11067 while(j<=tiecount-1&&i<=k-1)
11083 if( tiecount-j==k-1-i )
11112 ae_assert(cursizes.
ptr.
p_int[k-1]!=0&&j==tiecount,
"DSSplitK: internal error #1", _state);
11119 for(i=0; i<=k-1; i++)
11121 for(j1=0; j1<=nc-1; j1++)
11125 for(j1=j; j1<=j+cursizes.
ptr.
p_int[
i]-1; j1++)
11129 curcve = curcve+bdss_getcv(&cnt, nc, _state);
11138 for(i=0; i<=k-1; i++)
11154 for(i=1; i<=bestk-1; i++)
11223 if( (n<=0||nc<2)||kmax<2 )
11229 for(i=0; i<=n-1; i++)
11243 dstie(a, n, &ties, &tiecount, &p1, &p2, _state);
11244 for(i=0; i<=n-1; i++)
11268 kmax =
ae_minint(kmax, tiecount, _state);
11273 for(j=0; j<=nc-1; j++)
11277 for(j=0; j<=tiecount-1; j++)
11279 bdss_tieaddc(c, &ties, j, nc, &cnt, _state);
11283 for(k=1; k<=kmax-1; k++)
11285 for(j=0; j<=nc-1; j++)
11294 for(j=k; j<=tiecount-1; j++)
11300 bdss_tieaddc(c, &ties, j, nc, &cnt, _state);
11305 for(i=0; i<=nc-1; i++)
11311 for(s=k+1; s<=
j; s++)
11317 bdss_tiesubc(c, &ties, s-1, nc, &cnt2, _state);
11322 cvtemp = cv.
ptr.
pp_double[k-1][s-1]+bdss_getcv(&cnt2, nc, _state);
11337 for(k=0; k<=kmax-1; k++)
11345 ae_assert(koptimal>=0,
"DSOptimalSplitK: internal error #1!", _state);
11358 for(i=1; i<=tiecount-1; i++)
11366 ae_assert(j>0,
"DSOptimalSplitK: internal error #2!", _state);
11371 for(i=0; i<=nc-1; i++)
11375 for(i=0; i<=j-1; i++)
11377 bdss_tieaddc(c, &ties, i, nc, &cnt, _state);
11379 *cve = *cve+bdss_getcv(&cnt, nc, _state);
11380 for(i=0; i<=nc-1; i++)
11384 for(i=j; i<=tiecount-1; i++)
11386 bdss_tieaddc(c, &ties, i, nc, &cnt, _state);
11388 *cve = *cve+bdss_getcv(&cnt, nc, _state);
11402 jl = splits.
ptr.
pp_int[koptimal][tiecount-1];
11404 for(k=koptimal; k>=1; k--)
11419 static double bdss_xlny(
double x,
double y,
ae_state *_state)
11430 result = x*
ae_log(y, _state);
11440 static double bdss_getcv(
ae_vector* cnt,
11450 for(i=0; i<=nc-1; i++)
11455 for(i=0; i<=nc-1; i++)
11457 result = result-bdss_xlny(cnt->
ptr.
p_int[i], cnt->
ptr.
p_int[i]/(s+nc-1), _state);
11466 static void bdss_tieaddc(
ae_vector* c,
11476 for(i=ties->
ptr.
p_int[ntie]; i<=ties->ptr.p_int[ntie+1]-1; i++)
11486 static void bdss_tiesubc(
ae_vector* c,
11496 for(i=ties->
ptr.
p_int[ntie]; i<=ties->ptr.p_int[ntie+1]-1; i++)
11624 ae_assert((((((((disttype==0||disttype==1)||disttype==2)||disttype==10)||disttype==11)||disttype==12)||disttype==13)||disttype==20)||disttype==21,
"ClusterizerSetPoints: incorrect DistType", _state);
11625 ae_assert(npoints>=0,
"ClusterizerSetPoints: NPoints<0", _state);
11626 ae_assert(nfeatures>=1,
"ClusterizerSetPoints: NFeatures<1", _state);
11627 ae_assert(xy->
rows>=npoints,
"ClusterizerSetPoints: Rows(XY)<NPoints", _state);
11628 ae_assert(xy->
cols>=nfeatures,
"ClusterizerSetPoints: Cols(XY)<NFeatures", _state);
11634 for(i=0; i<=npoints-1; i++)
11682 ae_assert(npoints>=0,
"ClusterizerSetDistances: NPoints<0", _state);
11683 ae_assert(d->
rows>=npoints,
"ClusterizerSetDistances: Rows(D)<NPoints", _state);
11684 ae_assert(d->
cols>=npoints,
"ClusterizerSetDistances: Cols(D)<NPoints", _state);
11689 for(i=0; i<=npoints-1; i++)
11701 for(j=j0; j<=j1; j++)
11732 ae_assert(((algo==0||algo==1)||algo==2)||algo==3,
"ClusterizerSetHCAlgo: incorrect algorithm type", _state);
11760 ae_assert(restarts>=1,
"ClusterizerSetKMeansLimits: Restarts<=0", _state);
11761 ae_assert(maxits>=0,
"ClusterizerSetKMeansLimits: MaxIts<0", _state);
11861 clustering_clusterizerrunahcinternal(s, &s->
d, rep, _state);
11876 clustering_clusterizerrunahcinternal(s, &d, rep, _state);
11936 ae_assert(k>=0,
"ClusterizerRunKMeans: K<0", _state);
11983 kmeansgenerateinternal(&s->
xy, s->
npoints, s->
nfeatures, k, s->
kmeansmaxits, s->
kmeansrestarts, &rep->
terminationtype, &dummy,
ae_false, &rep->
c,
ae_true, &rep->
cidx, _state);
12077 ae_assert(nfeatures>=1,
"ClusterizerGetDistances: NFeatures<1", _state);
12078 ae_assert(npoints>=0,
"ClusterizerGetDistances: NPoints<1", _state);
12079 ae_assert((((((((disttype==0||disttype==1)||disttype==2)||disttype==10)||disttype==11)||disttype==12)||disttype==13)||disttype==20)||disttype==21,
"ClusterizerGetDistances: incorrect DistType", _state);
12080 ae_assert(xy->
rows>=npoints,
"ClusterizerGetDistances: Rows(XY)<NPoints", _state);
12081 ae_assert(xy->
cols>=nfeatures,
"ClusterizerGetDistances: Cols(XY)<NFeatures", _state);
12103 if( disttype==0||disttype==1 )
12112 clustering_evaluatedistancematrixrec(xy, nfeatures, disttype, d, 0, npoints, 0, npoints, _state);
12129 for(j=0; j<=nfeatures-1; j++)
12133 v = (double)1/(
double)npoints;
12134 for(i=0; i<=npoints-1; i++)
12138 for(i=0; i<=npoints-1; i++)
12143 rmatrixsyrk(npoints, nfeatures, 1.0, &tmpxy, 0, 0, 0, 0.0, d, 0, 0,
ae_true, _state);
12144 for(i=0; i<=npoints-1; i++)
12148 for(i=0; i<=npoints-1; i++)
12151 for(j=i+1; j<=npoints-1; j++)
12161 if( disttype==10||disttype==11 )
12172 for(i=0; i<=npoints-1; i++)
12175 for(j=0; j<=nfeatures-1; j++)
12180 for(j=0; j<=nfeatures-1; j++)
12185 rmatrixsyrk(npoints, nfeatures, 1.0, &tmpxy, 0, 0, 0, 0.0, d, 0, 0,
ae_true, _state);
12186 for(i=0; i<=npoints-1; i++)
12190 for(i=0; i<=npoints-1; i++)
12193 for(j=i+1; j<=npoints-1; j++)
12212 if( disttype==12||disttype==13 )
12222 rmatrixsyrk(npoints, nfeatures, 1.0, xy, 0, 0, 0, 0.0, d, 0, 0,
ae_true, _state);
12223 for(i=0; i<=npoints-1; i++)
12227 for(i=0; i<=npoints-1; i++)
12230 for(j=i+1; j<=npoints-1; j++)
12245 if( disttype==20||disttype==21 )
12257 rmatrixcopy(npoints, nfeatures, xy, 0, 0, &tmpxy, 0, 0, _state);
12259 rmatrixsyrk(npoints, nfeatures, 1.0, &tmpxy, 0, 0, 0, 0.0, d, 0, 0,
ae_true, _state);
12260 for(i=0; i<=npoints-1; i++)
12271 for(i=0; i<=npoints-1; i++)
12275 for(j=i+1; j<=npoints-1; j++)
12385 ae_assert(npoints>=0,
"ClusterizerGetKClusters: internal error in Rep integrity", _state);
12386 ae_assert(k>=0,
"ClusterizerGetKClusters: K<=0", _state);
12387 ae_assert(k<=npoints, "ClusterizerGetKClusters: K>NPoints
", _state); 12388 ae_assert(k>0||npoints==0, "ClusterizerGetKClusters:
K<=0
", _state); 12389 ae_assert(npoints==rep->npoints, "ClusterizerGetKClusters: NPoints<>Rep.NPoints
", _state); 12396 ae_frame_leave(_state); 12401 ae_vector_set_length(cz, 1, _state); 12402 ae_vector_set_length(cidx, 1, _state); 12403 cz->ptr.p_int[0] = 0; 12404 cidx->ptr.p_int[0] = 0; 12405 ae_frame_leave(_state); 12410 * Replay merges, from top to bottom, 12411 * keep track of clusters being present at the moment 12413 ae_vector_set_length(&presentclusters, 2*npoints-1, _state); 12414 ae_vector_set_length(&tmpidx, npoints, _state); 12415 for(i=0; i<=2*npoints-3; i++) 12417 presentclusters.ptr.p_bool[i] = ae_false; 12419 presentclusters.ptr.p_bool[2*npoints-2] = ae_true; 12420 for(i=0; i<=npoints-1; i++) 12422 tmpidx.ptr.p_int[i] = 2*npoints-2; 12424 for(mergeidx=npoints-2; mergeidx>=npoints-k; mergeidx--) 12428 * Update information about clusters being present at the moment 12430 presentclusters.ptr.p_bool[npoints+mergeidx] = ae_false; 12431 presentclusters.ptr.p_bool[rep->z.ptr.pp_int[mergeidx][0]] = ae_true; 12432 presentclusters.ptr.p_bool[rep->z.ptr.pp_int[mergeidx][1]] = ae_true; 12435 * Update TmpIdx according to the current state of the dataset 12437 * NOTE: TmpIdx contains cluster indexes from [0..2*NPoints-2]; 12438 * we will convert them to [0..K-1] later. 12440 i0 = rep->pm.ptr.pp_int[mergeidx][0]; 12441 i1 = rep->pm.ptr.pp_int[mergeidx][1]; 12442 t = rep->z.ptr.pp_int[mergeidx][0]; 12443 for(i=i0; i<=i1; i++) 12445 tmpidx.ptr.p_int[i] = t; 12447 i0 = rep->pm.ptr.pp_int[mergeidx][2]; 12448 i1 = rep->pm.ptr.pp_int[mergeidx][3]; 12449 t = rep->z.ptr.pp_int[mergeidx][1]; 12450 for(i=i0; i<=i1; i++) 12452 tmpidx.ptr.p_int[i] = t; 12457 * Fill CZ - array which allows us to convert cluster indexes 12458 * from one system to another. 12460 ae_vector_set_length(cz, k, _state); 12461 ae_vector_set_length(&clusterindexes, 2*npoints-1, _state); 12463 for(i=0; i<=2*npoints-2; i++) 12465 if( presentclusters.ptr.p_bool[i] ) 12467 cz->ptr.p_int[t] = i; 12468 clusterindexes.ptr.p_int[i] = t; 12472 ae_assert(t==k, "ClusterizerGetKClusters:
internal error", _state); 12475 * Convert indexes stored in CIdx 12477 ae_vector_set_length(cidx, npoints, _state); 12478 for(i=0; i<=npoints-1; i++) 12480 cidx->ptr.p_int[i] = clusterindexes.ptr.p_int[tmpidx.ptr.p_int[rep->p.ptr.p_int[i]]]; 12482 ae_frame_leave(_state); 12486 /************************************************************************* 12487 This function accepts AHC report Rep, desired minimum intercluster 12488 distance and returns top clusters from hierarchical clusterization tree 12489 which are separated by distance R or HIGHER. 12491 It returns assignment of points to clusters (array of cluster indexes). 12493 There is one more function with similar name - ClusterizerSeparatedByCorr, 12494 which returns clusters with intercluster correlation equal to R or LOWER 12495 (note: higher for distance, lower for correlation). 12498 Rep - report from ClusterizerRunAHC() performed on XY 12499 R - desired minimum intercluster distance, R>=0 12502 K - number of clusters, 1<=K<=NPoints 12503 CIdx - array[NPoints], I-th element contains cluster index (from 12504 0 to K-1) for I-th point of the dataset. 12505 CZ - array[K]. This array allows to convert cluster indexes 12506 returned by this function to indexes used by Rep.Z. J-th 12507 cluster returned by this function corresponds to CZ[J]-th 12508 cluster stored in Rep.Z/PZ/PM. 12509 It is guaranteed that CZ[I]<CZ[I+1]. 12511 NOTE: K clusters built by this subroutine are assumed to have no hierarchy. 12512 Although they were obtained by manipulation with top K nodes of 12513 dendrogram (i.e. hierarchical decomposition of dataset), this 12514 function does not return information about hierarchy. Each of the 12515 clusters stand on its own. 12517 NOTE: Cluster indexes returned by this function does not correspond to 12518 indexes returned in Rep.Z/PZ/PM. Either you work with hierarchical 12519 representation of the dataset (dendrogram), or you work with "flat
" 12520 representation returned by this function. Each of representations 12521 has its own clusters indexing system (former uses [0, 2*NPoints-2]), 12522 while latter uses [0..K-1]), although it is possible to perform 12523 conversion from one system to another by means of CZ array, returned 12524 by this function, which allows you to convert indexes stored in CIdx 12525 to the numeration system used by Rep.Z. 12527 NOTE: this subroutine is optimized for moderate values of K. Say, for K=5 12528 it will perform many times faster than for K=100. Its worst-case 12529 performance is O(N*K), although in average case it perform better 12530 (up to O(N*log(K))). 12533 Copyright 10.07.2012 by Bochkanov Sergey 12534 *************************************************************************/ 12535 void clusterizerseparatedbydist(ahcreport* rep, 12538 /* Integer */ ae_vector* cidx, 12539 /* Integer */ ae_vector* cz, 12544 ae_vector_clear(cidx); 12545 ae_vector_clear(cz); 12547 ae_assert(ae_isfinite(r, _state)&&ae_fp_greater_eq(r,0), "ClusterizerSeparatedByDist: R is infinite
or less than 0
", _state); 12549 while(*k<rep->npoints&&ae_fp_greater_eq(rep->mergedist.ptr.p_double[rep->npoints-1-(*k)],r)) 12553 clusterizergetkclusters(rep, *k, cidx, cz, _state); 12557 /************************************************************************* 12558 This function accepts AHC report Rep, desired maximum intercluster 12559 correlation and returns top clusters from hierarchical clusterization tree 12560 which are separated by correlation R or LOWER. 12562 It returns assignment of points to clusters (array of cluster indexes). 12564 There is one more function with similar name - ClusterizerSeparatedByDist, 12565 which returns clusters with intercluster distance equal to R or HIGHER 12566 (note: higher for distance, lower for correlation). 12569 Rep - report from ClusterizerRunAHC() performed on XY 12570 R - desired maximum intercluster correlation, -1<=R<=+1 12573 K - number of clusters, 1<=K<=NPoints 12574 CIdx - array[NPoints], I-th element contains cluster index (from 12575 0 to K-1) for I-th point of the dataset. 12576 CZ - array[K]. This array allows to convert cluster indexes 12577 returned by this function to indexes used by Rep.Z. J-th 12578 cluster returned by this function corresponds to CZ[J]-th 12579 cluster stored in Rep.Z/PZ/PM. 12580 It is guaranteed that CZ[I]<CZ[I+1]. 12582 NOTE: K clusters built by this subroutine are assumed to have no hierarchy. 12583 Although they were obtained by manipulation with top K nodes of 12584 dendrogram (i.e. hierarchical decomposition of dataset), this 12585 function does not return information about hierarchy. Each of the 12586 clusters stand on its own. 12588 NOTE: Cluster indexes returned by this function does not correspond to 12589 indexes returned in Rep.Z/PZ/PM. Either you work with hierarchical 12590 representation of the dataset (dendrogram), or you work with "flat
" 12591 representation returned by this function. Each of representations 12592 has its own clusters indexing system (former uses [0, 2*NPoints-2]), 12593 while latter uses [0..K-1]), although it is possible to perform 12594 conversion from one system to another by means of CZ array, returned 12595 by this function, which allows you to convert indexes stored in CIdx 12596 to the numeration system used by Rep.Z. 12598 NOTE: this subroutine is optimized for moderate values of K. Say, for K=5 12599 it will perform many times faster than for K=100. Its worst-case 12600 performance is O(N*K), although in average case it perform better 12601 (up to O(N*log(K))). 12604 Copyright 10.07.2012 by Bochkanov Sergey 12605 *************************************************************************/ 12606 void clusterizerseparatedbycorr(ahcreport* rep, 12609 /* Integer */ ae_vector* cidx, 12610 /* Integer */ ae_vector* cz, 12615 ae_vector_clear(cidx); 12616 ae_vector_clear(cz); 12618 ae_assert((ae_isfinite(r, _state)&&ae_fp_greater_eq(r,-1))&&ae_fp_less_eq(r,1), "ClusterizerSeparatedByCorr: R is infinite
or less than 0
", _state); 12620 while(*k<rep->npoints&&ae_fp_greater_eq(rep->mergedist.ptr.p_double[rep->npoints-1-(*k)],1-r)) 12624 clusterizergetkclusters(rep, *k, cidx, cz, _state); 12628 /************************************************************************* 12629 K-means++ clusterization 12632 XY - dataset, array [0..NPoints-1,0..NVars-1]. 12633 NPoints - dataset size, NPoints>=K 12634 NVars - number of variables, NVars>=1 12635 K - desired number of clusters, K>=1 12636 Restarts - number of restarts, Restarts>=1 12639 Info - return code: 12640 * -3, if task is degenerate (number of distinct points is 12642 * -1, if incorrect NPoints/NFeatures/K/Restarts was passed 12643 * 1, if subroutine finished successfully 12644 CCol - array[0..NVars-1,0..K-1].matrix whose columns store 12646 NeedCCol - True in case caller requires to store result in CCol 12647 CRow - array[0..K-1,0..NVars-1], same as CCol, but centers are 12649 NeedCRow - True in case caller requires to store result in CCol 12650 XYC - array[NPoints], which contains cluster indexes 12653 Copyright 21.03.2009 by Bochkanov Sergey 12654 *************************************************************************/ 12655 void kmeansgenerateinternal(/* Real */ ae_matrix* xy, 12662 /* Real */ ae_matrix* ccol, 12664 /* Real */ ae_matrix* crow, 12666 /* Integer */ ae_vector* xyc, 12669 ae_frame _frame_block; 12688 ae_bool waschanges; 12689 ae_bool zerosizeclusters; 12694 ae_frame_make(_state, &_frame_block); 12696 ae_matrix_clear(ccol); 12697 ae_matrix_clear(crow); 12698 ae_vector_clear(xyc); 12699 ae_matrix_init(&ct, 0, 0, DT_REAL, _state, ae_true); 12700 ae_matrix_init(&ctbest, 0, 0, DT_REAL, _state, ae_true); 12701 ae_vector_init(&xycbest, 0, DT_INT, _state, ae_true); 12702 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 12703 ae_vector_init(&tmp, 0, DT_REAL, _state, ae_true); 12704 ae_vector_init(&d2, 0, DT_REAL, _state, ae_true); 12705 ae_vector_init(&p, 0, DT_REAL, _state, ae_true); 12706 ae_vector_init(&csizes, 0, DT_INT, _state, ae_true); 12707 ae_vector_init(&cbusy, 0, DT_BOOL, _state, ae_true); 12708 ae_vector_init(&work, 0, DT_REAL, _state, ae_true); 12709 _hqrndstate_init(&rs, _state, ae_true); 12715 if( ((npoints<k||nvars<1)||k<1)||restarts<1 ) 12718 ae_frame_leave(_state); 12723 * TODO: special case K=1 12724 * TODO: special case K=NPoints 12729 * Multiple passes of k-means++ algorithm 12731 ae_matrix_set_length(&ct, k, nvars, _state); 12732 ae_matrix_set_length(&ctbest, k, nvars, _state); 12733 ae_vector_set_length(xyc, npoints, _state); 12734 ae_vector_set_length(&xycbest, npoints, _state); 12735 ae_vector_set_length(&d2, npoints, _state); 12736 ae_vector_set_length(&p, npoints, _state); 12737 ae_vector_set_length(&tmp, nvars, _state); 12738 ae_vector_set_length(&csizes, k, _state); 12739 ae_vector_set_length(&cbusy, k, _state); 12740 ebest = ae_maxrealnumber; 12741 hqrndrandomize(&rs, _state); 12742 for(pass=1; pass<=restarts; pass++) 12746 * Select initial centers using k-means++ algorithm 12747 * 1. Choose first center at random 12748 * 2. Choose next centers using their distance from centers already chosen 12750 * Note that for performance reasons centers are stored in ROWS of CT, not 12751 * in columns. We'll transpose CT in the end and store it in the C. 12753 i = hqrnduniformi(&rs, npoints, _state); 12754 ae_v_move(&ct.ptr.pp_double[0][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 12755 cbusy.ptr.p_bool[0] = ae_true; 12756 for(i=1; i<=k-1; i++) 12758 cbusy.ptr.p_bool[i] = ae_false; 12760 if( !clustering_selectcenterpp(xy, npoints, nvars, &ct, &cbusy, k, &d2, &p, &tmp, _state) ) 12763 ae_frame_leave(_state); 12769 * 2. update center positions 12771 for(i=0; i<=npoints-1; i++) 12773 xyc->ptr.p_int[i] = -1; 12775 eprev = ae_maxrealnumber; 12778 while(maxits==0||itcnt<maxits) 12782 * Update iteration counter 12787 * fill XYC with center numbers 12789 waschanges = ae_false; 12790 for(i=0; i<=npoints-1; i++) 12793 dclosest = ae_maxrealnumber; 12794 for(j=0; j<=k-1; j++) 12796 ae_v_move(&tmp.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 12797 ae_v_sub(&tmp.ptr.p_double[0], 1, &ct.ptr.pp_double[j][0], 1, ae_v_len(0,nvars-1)); 12798 v = ae_v_dotproduct(&tmp.ptr.p_double[0], 1, &tmp.ptr.p_double[0], 1, ae_v_len(0,nvars-1)); 12799 if( ae_fp_less(v,dclosest) ) 12805 if( xyc->ptr.p_int[i]!=cclosest ) 12807 waschanges = ae_true; 12809 xyc->ptr.p_int[i] = cclosest; 12815 for(j=0; j<=k-1; j++) 12817 csizes.ptr.p_int[j] = 0; 12819 for(i=0; i<=k-1; i++) 12821 for(j=0; j<=nvars-1; j++) 12823 ct.ptr.pp_double[i][j] = 0; 12826 for(i=0; i<=npoints-1; i++) 12828 csizes.ptr.p_int[xyc->ptr.p_int[i]] = csizes.ptr.p_int[xyc->ptr.p_int[i]]+1; 12829 ae_v_add(&ct.ptr.pp_double[xyc->ptr.p_int[i]][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 12831 zerosizeclusters = ae_false; 12832 for(j=0; j<=k-1; j++) 12834 if( csizes.ptr.p_int[j]!=0 ) 12836 v = (double)1/(double)csizes.ptr.p_int[j]; 12837 ae_v_muld(&ct.ptr.pp_double[j][0], 1, ae_v_len(0,nvars-1), v); 12839 cbusy.ptr.p_bool[j] = csizes.ptr.p_int[j]!=0; 12840 zerosizeclusters = zerosizeclusters||csizes.ptr.p_int[j]==0; 12842 if( zerosizeclusters ) 12846 * Some clusters have zero size - rare, but possible. 12847 * We'll choose new centers for such clusters using k-means++ rule 12848 * and restart algorithm 12850 if( !clustering_selectcenterpp(xy, npoints, nvars, &ct, &cbusy, k, &d2, &p, &tmp, _state) ) 12853 ae_frame_leave(_state); 12860 * Stop if one of two conditions is met: 12861 * 1. nothing has changed during iteration 12862 * 2. energy function increased 12865 for(i=0; i<=npoints-1; i++) 12867 ae_v_move(&tmp.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 12868 ae_v_sub(&tmp.ptr.p_double[0], 1, &ct.ptr.pp_double[xyc->ptr.p_int[i]][0], 1, ae_v_len(0,nvars-1)); 12869 v = ae_v_dotproduct(&tmp.ptr.p_double[0], 1, &tmp.ptr.p_double[0], 1, ae_v_len(0,nvars-1)); 12872 if( !waschanges||ae_fp_greater_eq(e,eprev) ) 12884 * 3. Calculate E, compare with best centers found so far 12886 if( ae_fp_less(e,ebest) ) 12893 copymatrix(&ct, 0, k-1, 0, nvars-1, &ctbest, 0, k-1, 0, nvars-1, _state); 12894 for(i=0; i<=npoints-1; i++) 12896 xycbest.ptr.p_int[i] = xyc->ptr.p_int[i]; 12902 * Copy and transpose 12906 ae_matrix_set_length(ccol, nvars, k, _state); 12907 copyandtranspose(&ctbest, 0, k-1, 0, nvars-1, ccol, 0, nvars-1, 0, k-1, _state); 12911 ae_matrix_set_length(crow, k, nvars, _state); 12912 rmatrixcopy(k, nvars, &ctbest, 0, 0, crow, 0, 0, _state); 12914 for(i=0; i<=npoints-1; i++) 12916 xyc->ptr.p_int[i] = xycbest.ptr.p_int[i]; 12918 ae_frame_leave(_state); 12922 /************************************************************************* 12923 Select center for a new cluster using k-means++ rule 12924 *************************************************************************/ 12925 static ae_bool clustering_selectcenterpp(/* Real */ ae_matrix* xy, 12928 /* Real */ ae_matrix* centers, 12929 /* Boolean */ ae_vector* busycenters, 12931 /* Real */ ae_vector* d2, 12932 /* Real */ ae_vector* p, 12933 /* Real */ ae_vector* tmp, 12945 for(cc=0; cc<=ccnt-1; cc++) 12947 if( !busycenters->ptr.p_bool[cc] ) 12953 for(i=0; i<=npoints-1; i++) 12955 d2->ptr.p_double[i] = ae_maxrealnumber; 12956 for(j=0; j<=ccnt-1; j++) 12958 if( busycenters->ptr.p_bool[j] ) 12960 ae_v_move(&tmp->ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 12961 ae_v_sub(&tmp->ptr.p_double[0], 1, ¢ers->ptr.pp_double[j][0], 1, ae_v_len(0,nvars-1)); 12962 v = ae_v_dotproduct(&tmp->ptr.p_double[0], 1, &tmp->ptr.p_double[0], 1, ae_v_len(0,nvars-1)); 12963 if( ae_fp_less(v,d2->ptr.p_double[i]) ) 12965 d2->ptr.p_double[i] = v; 12972 * calculate P (non-cumulative) 12975 for(i=0; i<=npoints-1; i++) 12977 s = s+d2->ptr.p_double[i]; 12979 if( ae_fp_eq(s,0) ) 12985 ae_v_moved(&p->ptr.p_double[0], 1, &d2->ptr.p_double[0], 1, ae_v_len(0,npoints-1), s); 12988 * choose one of points with probability P 12989 * random number within (0,1) is generated and 12990 * inverse empirical CDF is used to randomly choose a point. 12993 v = ae_randomreal(_state); 12994 for(i=0; i<=npoints-1; i++) 12996 s = s+p->ptr.p_double[i]; 12997 if( ae_fp_less_eq(v,s)||i==npoints-1 ) 12999 ae_v_move(¢ers->ptr.pp_double[cc][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 13000 busycenters->ptr.p_bool[cc] = ae_true; 13010 /************************************************************************* 13011 This function performs agglomerative hierarchical clustering using 13012 precomputed distance matrix. Internal function, should not be called 13016 S - clusterizer state, initialized by ClusterizerCreate() 13017 D - distance matrix, array[S.NFeatures,S.NFeatures] 13018 Contents of the matrix is destroyed during 13019 algorithm operation. 13022 Rep - clustering results; see description of AHCReport 13023 structure for more information. 13026 Copyright 10.07.2012 by Bochkanov Sergey 13027 *************************************************************************/ 13028 static void clustering_clusterizerrunahcinternal(clusterizerstate* s, 13029 /* Real */ ae_matrix* d, 13033 ae_frame _frame_block; 13051 ae_frame_make(_state, &_frame_block); 13052 ae_vector_init(&cidx, 0, DT_INT, _state, ae_true); 13053 ae_vector_init(&csizes, 0, DT_INT, _state, ae_true); 13054 ae_vector_init(&nnidx, 0, DT_INT, _state, ae_true); 13055 ae_matrix_init(&cinfo, 0, 0, DT_INT, _state, ae_true); 13057 npoints = s->npoints; 13060 * Fill Rep.NPoints, quick exit when NPoints<=1 13062 rep->npoints = npoints; 13065 ae_vector_set_length(&rep->p, 0, _state); 13066 ae_matrix_set_length(&rep->z, 0, 0, _state); 13067 ae_matrix_set_length(&rep->pz, 0, 0, _state); 13068 ae_matrix_set_length(&rep->pm, 0, 0, _state); 13069 ae_vector_set_length(&rep->mergedist, 0, _state); 13070 ae_frame_leave(_state); 13075 ae_vector_set_length(&rep->p, 1, _state); 13076 ae_matrix_set_length(&rep->z, 0, 0, _state); 13077 ae_matrix_set_length(&rep->pz, 0, 0, _state); 13078 ae_matrix_set_length(&rep->pm, 0, 0, _state); 13079 ae_vector_set_length(&rep->mergedist, 0, _state); 13080 rep->p.ptr.p_int[0] = 0; 13081 ae_frame_leave(_state); 13084 ae_matrix_set_length(&rep->z, npoints-1, 2, _state); 13085 ae_vector_set_length(&rep->mergedist, npoints-1, _state); 13088 * Build list of nearest neighbors 13090 ae_vector_set_length(&nnidx, npoints, _state); 13091 for(i=0; i<=npoints-1; i++) 13095 * Calculate index of the nearest neighbor 13098 v = ae_maxrealnumber; 13099 for(j=0; j<=npoints-1; j++) 13101 if( j!=i&&ae_fp_less(d->ptr.pp_double[i][j],v) ) 13104 v = d->ptr.pp_double[i][j]; 13107 ae_assert(ae_fp_less(v,ae_maxrealnumber), "ClusterizerRunAHC:
internal error", _state); 13108 nnidx.ptr.p_int[i] = k; 13112 * Distance matrix is built, perform merges. 13114 * NOTE 1: CIdx is array[NPoints] which maps rows/columns of the 13115 * distance matrix D to indexes of clusters. Values of CIdx 13116 * from [0,NPoints) denote single-point clusters, and values 13117 * from [NPoints,2*NPoints-1) denote ones obtained by merging 13118 * smaller clusters. Negative calues correspond to absent clusters. 13120 * Initially it contains [0...NPoints-1], after each merge 13121 * one element of CIdx (one with index C0) is replaced by 13122 * NPoints+MergeIdx, and another one with index C1 is 13125 * NOTE 2: CSizes is array[NPoints] which stores sizes of clusters. 13128 ae_vector_set_length(&cidx, npoints, _state); 13129 ae_vector_set_length(&csizes, npoints, _state); 13130 for(i=0; i<=npoints-1; i++) 13132 cidx.ptr.p_int[i] = i; 13133 csizes.ptr.p_int[i] = 1; 13135 for(mergeidx=0; mergeidx<=npoints-2; mergeidx++) 13139 * Select pair of clusters (C0,C1) with CIdx[C0]<CIdx[C1] to merge. 13143 v = ae_maxrealnumber; 13144 for(i=0; i<=npoints-1; i++) 13146 if( cidx.ptr.p_int[i]>=0 ) 13148 if( ae_fp_less(d->ptr.pp_double[i][nnidx.ptr.p_int[i]],v) ) 13151 c1 = nnidx.ptr.p_int[i]; 13152 v = d->ptr.pp_double[i][nnidx.ptr.p_int[i]]; 13156 ae_assert(ae_fp_less(v,ae_maxrealnumber), "ClusterizerRunAHC:
internal error", _state); 13157 if( cidx.ptr.p_int[c0]>cidx.ptr.p_int[c1] ) 13165 * Fill one row of Rep.Z and one element of Rep.MergeDist 13167 rep->z.ptr.pp_int[mergeidx][0] = cidx.ptr.p_int[c0]; 13168 rep->z.ptr.pp_int[mergeidx][1] = cidx.ptr.p_int[c1]; 13169 rep->mergedist.ptr.p_double[mergeidx] = v; 13172 * Update distance matrix: 13173 * * row/column C0 are updated by distances to the new cluster 13174 * * row/column C1 are considered empty (we can fill them by zeros, 13175 * but do not want to spend time - we just ignore them) 13177 * NOTE: it is important to update distance matrix BEFORE CIdx/CSizes 13180 ae_assert(((s->ahcalgo==0||s->ahcalgo==1)||s->ahcalgo==2)||s->ahcalgo==3, "ClusterizerRunAHC:
internal error", _state); 13181 for(i=0; i<=npoints-1; i++) 13185 if( s->ahcalgo==0 ) 13187 d->ptr.pp_double[i][c0] = ae_maxreal(d->ptr.pp_double[i][c0], d->ptr.pp_double[i][c1], _state); 13189 if( s->ahcalgo==1 ) 13191 d->ptr.pp_double[i][c0] = ae_minreal(d->ptr.pp_double[i][c0], d->ptr.pp_double[i][c1], _state); 13193 if( s->ahcalgo==2 ) 13195 d->ptr.pp_double[i][c0] = (csizes.ptr.p_int[c0]*d->ptr.pp_double[i][c0]+csizes.ptr.p_int[c1]*d->ptr.pp_double[i][c1])/(csizes.ptr.p_int[c0]+csizes.ptr.p_int[c1]); 13197 if( s->ahcalgo==3 ) 13199 d->ptr.pp_double[i][c0] = (d->ptr.pp_double[i][c0]+d->ptr.pp_double[i][c1])/2; 13201 d->ptr.pp_double[c0][i] = d->ptr.pp_double[i][c0]; 13206 * Update CIdx and CSizes 13208 cidx.ptr.p_int[c0] = npoints+mergeidx; 13209 cidx.ptr.p_int[c1] = -1; 13210 csizes.ptr.p_int[c0] = csizes.ptr.p_int[c0]+csizes.ptr.p_int[c1]; 13211 csizes.ptr.p_int[c1] = 0; 13214 * Update nearest neighbors array: 13215 * * update nearest neighbors of everything except for C0/C1 13216 * * update neighbors of C0/C1 13218 for(i=0; i<=npoints-1; i++) 13220 if( (cidx.ptr.p_int[i]>=0&&i!=c0)&&(nnidx.ptr.p_int[i]==c0||nnidx.ptr.p_int[i]==c1) ) 13224 * I-th cluster which is distinct from C0/C1 has former C0/C1 cluster as its nearest 13225 * neighbor. We handle this issue depending on specific AHC algorithm being used. 13227 if( s->ahcalgo==1 ) 13231 * Single linkage. Merging of two clusters together 13232 * does NOT change distances between new cluster and 13235 * The only thing we have to do is to update nearest neighbor index 13237 nnidx.ptr.p_int[i] = c0; 13243 * Something other than single linkage. We have to re-examine 13244 * all the row to find nearest neighbor. 13247 v = ae_maxrealnumber; 13248 for(j=0; j<=npoints-1; j++) 13250 if( (cidx.ptr.p_int[j]>=0&&j!=i)&&ae_fp_less(d->ptr.pp_double[i][j],v) ) 13253 v = d->ptr.pp_double[i][j]; 13256 ae_assert(ae_fp_less(v,ae_maxrealnumber)||mergeidx==npoints-2, "ClusterizerRunAHC:
internal error", _state); 13257 nnidx.ptr.p_int[i] = k; 13262 v = ae_maxrealnumber; 13263 for(j=0; j<=npoints-1; j++) 13265 if( (cidx.ptr.p_int[j]>=0&&j!=c0)&&ae_fp_less(d->ptr.pp_double[c0][j],v) ) 13268 v = d->ptr.pp_double[c0][j]; 13271 ae_assert(ae_fp_less(v,ae_maxrealnumber)||mergeidx==npoints-2, "ClusterizerRunAHC:
internal error", _state); 13272 nnidx.ptr.p_int[c0] = k; 13276 * Calculate Rep.P and Rep.PM. 13278 * In order to do that, we fill CInfo matrix - (2*NPoints-1)*3 matrix, 13279 * with I-th row containing: 13280 * * CInfo[I,0] - size of I-th cluster 13281 * * CInfo[I,1] - beginning of I-th cluster 13282 * * CInfo[I,2] - end of I-th cluster 13283 * * CInfo[I,3] - height of I-th cluster 13285 * We perform it as follows: 13286 * * first NPoints clusters have unit size (CInfo[I,0]=1) and zero 13287 * height (CInfo[I,3]=0) 13288 * * we replay NPoints-1 merges from first to last and fill sizes of 13289 * corresponding clusters (new size is a sum of sizes of clusters 13290 * being merged) and height (new height is max(heights)+1). 13291 * * now we ready to determine locations of clusters. Last cluster 13292 * spans entire dataset, we know it. We replay merges from last to 13293 * first, during each merge we already know location of the merge 13294 * result, and we can position first cluster to the left part of 13295 * the result, and second cluster to the right part. 13297 ae_vector_set_length(&rep->p, npoints, _state); 13298 ae_matrix_set_length(&rep->pm, npoints-1, 6, _state); 13299 ae_matrix_set_length(&cinfo, 2*npoints-1, 4, _state); 13300 for(i=0; i<=npoints-1; i++) 13302 cinfo.ptr.pp_int[i][0] = 1; 13303 cinfo.ptr.pp_int[i][3] = 0; 13305 for(i=0; i<=npoints-2; i++) 13307 cinfo.ptr.pp_int[npoints+i][0] = cinfo.ptr.pp_int[rep->z.ptr.pp_int[i][0]][0]+cinfo.ptr.pp_int[rep->z.ptr.pp_int[i][1]][0]; 13308 cinfo.ptr.pp_int[npoints+i][3] = ae_maxint(cinfo.ptr.pp_int[rep->z.ptr.pp_int[i][0]][3], cinfo.ptr.pp_int[rep->z.ptr.pp_int[i][1]][3], _state)+1; 13310 cinfo.ptr.pp_int[2*npoints-2][1] = 0; 13311 cinfo.ptr.pp_int[2*npoints-2][2] = npoints-1; 13312 for(i=npoints-2; i>=0; i--) 13316 * We merge C0 which spans [A0,B0] and C1 (spans [A1,B1]), 13317 * with unknown A0, B0, A1, B1. However, we know that result 13318 * is CR, which spans [AR,BR] with known AR/BR, and we know 13319 * sizes of C0, C1, CR (denotes as S0, S1, SR). 13321 c0 = rep->z.ptr.pp_int[i][0]; 13322 c1 = rep->z.ptr.pp_int[i][1]; 13323 s0 = cinfo.ptr.pp_int[c0][0]; 13324 s1 = cinfo.ptr.pp_int[c1][0]; 13325 ar = cinfo.ptr.pp_int[npoints+i][1]; 13326 br = cinfo.ptr.pp_int[npoints+i][2]; 13327 cinfo.ptr.pp_int[c0][1] = ar; 13328 cinfo.ptr.pp_int[c0][2] = ar+s0-1; 13329 cinfo.ptr.pp_int[c1][1] = br-(s1-1); 13330 cinfo.ptr.pp_int[c1][2] = br; 13331 rep->pm.ptr.pp_int[i][0] = cinfo.ptr.pp_int[c0][1]; 13332 rep->pm.ptr.pp_int[i][1] = cinfo.ptr.pp_int[c0][2]; 13333 rep->pm.ptr.pp_int[i][2] = cinfo.ptr.pp_int[c1][1]; 13334 rep->pm.ptr.pp_int[i][3] = cinfo.ptr.pp_int[c1][2]; 13335 rep->pm.ptr.pp_int[i][4] = cinfo.ptr.pp_int[c0][3]; 13336 rep->pm.ptr.pp_int[i][5] = cinfo.ptr.pp_int[c1][3]; 13338 for(i=0; i<=npoints-1; i++) 13340 ae_assert(cinfo.ptr.pp_int[i][1]==cinfo.ptr.pp_int[i][2], "Assertion failed
", _state); 13341 rep->p.ptr.p_int[i] = cinfo.ptr.pp_int[i][1]; 13347 ae_matrix_set_length(&rep->pz, npoints-1, 2, _state); 13348 for(i=0; i<=npoints-2; i++) 13350 rep->pz.ptr.pp_int[i][0] = rep->z.ptr.pp_int[i][0]; 13351 rep->pz.ptr.pp_int[i][1] = rep->z.ptr.pp_int[i][1]; 13352 if( rep->pz.ptr.pp_int[i][0]<npoints ) 13354 rep->pz.ptr.pp_int[i][0] = rep->p.ptr.p_int[rep->pz.ptr.pp_int[i][0]]; 13356 if( rep->pz.ptr.pp_int[i][1]<npoints ) 13358 rep->pz.ptr.pp_int[i][1] = rep->p.ptr.p_int[rep->pz.ptr.pp_int[i][1]]; 13361 ae_frame_leave(_state); 13365 static void clustering_evaluatedistancematrixrec(/* Real */ ae_matrix* xy, 13366 ae_int_t nfeatures, 13368 /* Real */ ae_matrix* d, 13375 double rcomplexity; 13385 ae_assert(disttype==0||disttype==1, "EvaluateDistanceMatrixRec: incorrect DistType
", _state); 13389 * * J0:=max(J0,I0) - we ignore lower triangle 13390 * * J1:=max(J1,J0) - normalize J1 13392 j0 = ae_maxint(j0, i0, _state); 13393 j1 = ae_maxint(j1, j0, _state); 13394 if( j1<=j0||i1<=i0 ) 13400 * Try to process in parallel. Two condtions must hold in order to 13401 * activate parallel processing: 13402 * 1. I1-I0>2 or J1-J0>2 13403 * 2. (I1-I0)*(J1-J0)*NFeatures>=ParallelComplexity 13405 * NOTE: all quantities are converted to reals in order to avoid 13406 * integer overflow during multiplication 13408 * NOTE: strict inequality in (1) is necessary to reduce task to 2x2 13409 * basecases. In future versions we will be able to handle such 13410 * basecases more efficiently than 1x1 cases. 13412 rcomplexity = i1-i0; 13413 rcomplexity = rcomplexity*(j1-j0); 13414 rcomplexity = rcomplexity*nfeatures; 13415 if( ae_fp_greater_eq(rcomplexity,clustering_parallelcomplexity)&&(i1-i0>2||j1-j0>2) ) 13419 * Recursive division along largest of dimensions 13423 splitlengtheven(i1-i0, &len0, &len1, _state); 13424 clustering_evaluatedistancematrixrec(xy, nfeatures, disttype, d, i0, i0+len0, j0, j1, _state); 13425 clustering_evaluatedistancematrixrec(xy, nfeatures, disttype, d, i0+len0, i1, j0, j1, _state); 13429 splitlengtheven(j1-j0, &len0, &len1, _state); 13430 clustering_evaluatedistancematrixrec(xy, nfeatures, disttype, d, i0, i1, j0, j0+len0, _state); 13431 clustering_evaluatedistancematrixrec(xy, nfeatures, disttype, d, i0, i1, j0+len0, j1, _state); 13437 * Sequential processing 13439 for(i=i0; i<=i1-1; i++) 13441 for(j=j0; j<=j1-1; j++) 13448 for(k=0; k<=nfeatures-1; k++) 13450 vv = xy->ptr.pp_double[i][k]-xy->ptr.pp_double[j][k]; 13451 if( ae_fp_less(vv,0) ) 13455 if( ae_fp_greater(vv,v) ) 13463 for(k=0; k<=nfeatures-1; k++) 13465 vv = xy->ptr.pp_double[i][k]-xy->ptr.pp_double[j][k]; 13466 if( ae_fp_less(vv,0) ) 13473 d->ptr.pp_double[i][j] = v; 13480 ae_bool _clusterizerstate_init(void* _p, ae_state *_state, ae_bool make_automatic) 13482 clusterizerstate *p = (clusterizerstate*)_p; 13483 ae_touch_ptr((void*)p); 13484 if( !ae_matrix_init(&p->xy, 0, 0, DT_REAL, _state, make_automatic) ) 13486 if( !ae_matrix_init(&p->d, 0, 0, DT_REAL, _state, make_automatic) ) 13492 ae_bool _clusterizerstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 13494 clusterizerstate *dst = (clusterizerstate*)_dst; 13495 clusterizerstate *src = (clusterizerstate*)_src; 13496 dst->npoints = src->npoints; 13497 dst->nfeatures = src->nfeatures; 13498 dst->disttype = src->disttype; 13499 if( !ae_matrix_init_copy(&dst->xy, &src->xy, _state, make_automatic) ) 13501 if( !ae_matrix_init_copy(&dst->d, &src->d, _state, make_automatic) ) 13503 dst->ahcalgo = src->ahcalgo; 13504 dst->kmeansrestarts = src->kmeansrestarts; 13505 dst->kmeansmaxits = src->kmeansmaxits; 13510 void _clusterizerstate_clear(void* _p) 13512 clusterizerstate *p = (clusterizerstate*)_p; 13513 ae_touch_ptr((void*)p); 13514 ae_matrix_clear(&p->xy); 13515 ae_matrix_clear(&p->d); 13519 void _clusterizerstate_destroy(void* _p) 13521 clusterizerstate *p = (clusterizerstate*)_p; 13522 ae_touch_ptr((void*)p); 13523 ae_matrix_destroy(&p->xy); 13524 ae_matrix_destroy(&p->d); 13528 ae_bool _ahcreport_init(void* _p, ae_state *_state, ae_bool make_automatic) 13530 ahcreport *p = (ahcreport*)_p; 13531 ae_touch_ptr((void*)p); 13532 if( !ae_vector_init(&p->p, 0, DT_INT, _state, make_automatic) ) 13534 if( !ae_matrix_init(&p->z, 0, 0, DT_INT, _state, make_automatic) ) 13536 if( !ae_matrix_init(&p->pz, 0, 0, DT_INT, _state, make_automatic) ) 13538 if( !ae_matrix_init(&p->pm, 0, 0, DT_INT, _state, make_automatic) ) 13540 if( !ae_vector_init(&p->mergedist, 0, DT_REAL, _state, make_automatic) ) 13546 ae_bool _ahcreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 13548 ahcreport *dst = (ahcreport*)_dst; 13549 ahcreport *src = (ahcreport*)_src; 13550 dst->npoints = src->npoints; 13551 if( !ae_vector_init_copy(&dst->p, &src->p, _state, make_automatic) ) 13553 if( !ae_matrix_init_copy(&dst->z, &src->z, _state, make_automatic) ) 13555 if( !ae_matrix_init_copy(&dst->pz, &src->pz, _state, make_automatic) ) 13557 if( !ae_matrix_init_copy(&dst->pm, &src->pm, _state, make_automatic) ) 13559 if( !ae_vector_init_copy(&dst->mergedist, &src->mergedist, _state, make_automatic) ) 13565 void _ahcreport_clear(void* _p) 13567 ahcreport *p = (ahcreport*)_p; 13568 ae_touch_ptr((void*)p); 13569 ae_vector_clear(&p->p); 13570 ae_matrix_clear(&p->z); 13571 ae_matrix_clear(&p->pz); 13572 ae_matrix_clear(&p->pm); 13573 ae_vector_clear(&p->mergedist); 13577 void _ahcreport_destroy(void* _p) 13579 ahcreport *p = (ahcreport*)_p; 13580 ae_touch_ptr((void*)p); 13581 ae_vector_destroy(&p->p); 13582 ae_matrix_destroy(&p->z); 13583 ae_matrix_destroy(&p->pz); 13584 ae_matrix_destroy(&p->pm); 13585 ae_vector_destroy(&p->mergedist); 13589 ae_bool _kmeansreport_init(void* _p, ae_state *_state, ae_bool make_automatic) 13591 kmeansreport *p = (kmeansreport*)_p; 13592 ae_touch_ptr((void*)p); 13593 if( !ae_matrix_init(&p->c, 0, 0, DT_REAL, _state, make_automatic) ) 13595 if( !ae_vector_init(&p->cidx, 0, DT_INT, _state, make_automatic) ) 13601 ae_bool _kmeansreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 13603 kmeansreport *dst = (kmeansreport*)_dst; 13604 kmeansreport *src = (kmeansreport*)_src; 13605 dst->npoints = src->npoints; 13606 dst->nfeatures = src->nfeatures; 13607 dst->terminationtype = src->terminationtype; 13609 if( !ae_matrix_init_copy(&dst->c, &src->c, _state, make_automatic) ) 13611 if( !ae_vector_init_copy(&dst->cidx, &src->cidx, _state, make_automatic) ) 13617 void _kmeansreport_clear(void* _p) 13619 kmeansreport *p = (kmeansreport*)_p; 13620 ae_touch_ptr((void*)p); 13621 ae_matrix_clear(&p->c); 13622 ae_vector_clear(&p->cidx); 13626 void _kmeansreport_destroy(void* _p) 13628 kmeansreport *p = (kmeansreport*)_p; 13629 ae_touch_ptr((void*)p); 13630 ae_matrix_destroy(&p->c); 13631 ae_vector_destroy(&p->cidx); 13637 /************************************************************************* 13638 k-means++ clusterization. 13639 Backward compatibility function, we recommend to use CLUSTERING subpackage 13640 as better replacement. 13643 Copyright 21.03.2009 by Bochkanov Sergey 13644 *************************************************************************/ 13645 void kmeansgenerate(/* Real */ ae_matrix* xy, 13651 /* Real */ ae_matrix* c, 13652 /* Integer */ ae_vector* xyc, 13655 ae_frame _frame_block; 13658 ae_frame_make(_state, &_frame_block); 13660 ae_matrix_clear(c); 13661 ae_vector_clear(xyc); 13662 ae_matrix_init(&dummy, 0, 0, DT_REAL, _state, ae_true); 13664 kmeansgenerateinternal(xy, npoints, nvars, k, 0, restarts, info, c, ae_true, &dummy, ae_false, xyc, _state); 13665 ae_frame_leave(_state); 13671 /************************************************************************* 13672 This subroutine builds random decision forest. 13676 NPoints - training set size, NPoints>=1 13677 NVars - number of independent variables, NVars>=1 13678 NClasses - task type: 13679 * NClasses=1 - regression task with one 13681 * NClasses>1 - classification task with 13683 NTrees - number of trees in a forest, NTrees>=1. 13684 recommended values: 50-100. 13685 R - percent of a training set used to build 13686 individual trees. 0<R<=1. 13687 recommended values: 0.1 <= R <= 0.66. 13690 Info - return code: 13691 * -2, if there is a point with class number 13692 outside of [0..NClasses-1]. 13693 * -1, if incorrect parameters was passed 13694 (NPoints<1, NVars<1, NClasses<1, NTrees<1, R<=0 13696 * 1, if task has been solved 13698 Rep - training report, contains error on a training set 13699 and out-of-bag estimates of generalization error. 13702 Copyright 19.02.2009 by Bochkanov Sergey 13703 *************************************************************************/ 13704 void dfbuildrandomdecisionforest(/* Real */ ae_matrix* xy, 13711 decisionforest* df, 13715 ae_int_t samplesize; 13718 _decisionforest_clear(df); 13719 _dfreport_clear(rep); 13721 if( ae_fp_less_eq(r,0)||ae_fp_greater(r,1) ) 13726 samplesize = ae_maxint(ae_round(r*npoints, _state), 1, _state); 13727 dfbuildinternal(xy, npoints, nvars, nclasses, ntrees, samplesize, ae_maxint(nvars/2, 1, _state), dforest_dfusestrongsplits+dforest_dfuseevs, info, df, rep, _state); 13731 /************************************************************************* 13732 This subroutine builds random decision forest. 13733 This function gives ability to tune number of variables used when choosing 13738 NPoints - training set size, NPoints>=1 13739 NVars - number of independent variables, NVars>=1 13740 NClasses - task type: 13741 * NClasses=1 - regression task with one 13743 * NClasses>1 - classification task with 13745 NTrees - number of trees in a forest, NTrees>=1. 13746 recommended values: 50-100. 13747 NRndVars - number of variables used when choosing best split 13748 R - percent of a training set used to build 13749 individual trees. 0<R<=1. 13750 recommended values: 0.1 <= R <= 0.66. 13753 Info - return code: 13754 * -2, if there is a point with class number 13755 outside of [0..NClasses-1]. 13756 * -1, if incorrect parameters was passed 13757 (NPoints<1, NVars<1, NClasses<1, NTrees<1, R<=0 13759 * 1, if task has been solved 13761 Rep - training report, contains error on a training set 13762 and out-of-bag estimates of generalization error. 13765 Copyright 19.02.2009 by Bochkanov Sergey 13766 *************************************************************************/ 13767 void dfbuildrandomdecisionforestx1(/* Real */ ae_matrix* xy, 13775 decisionforest* df, 13779 ae_int_t samplesize; 13782 _decisionforest_clear(df); 13783 _dfreport_clear(rep); 13785 if( ae_fp_less_eq(r,0)||ae_fp_greater(r,1) ) 13790 if( nrndvars<=0||nrndvars>nvars ) 13795 samplesize = ae_maxint(ae_round(r*npoints, _state), 1, _state); 13796 dfbuildinternal(xy, npoints, nvars, nclasses, ntrees, samplesize, nrndvars, dforest_dfusestrongsplits+dforest_dfuseevs, info, df, rep, _state); 13800 void dfbuildinternal(/* Real */ ae_matrix* xy, 13805 ae_int_t samplesize, 13806 ae_int_t nfeatures, 13809 decisionforest* df, 13813 ae_frame _frame_block; 13818 ae_int_t lasttreeoffs; 13822 ae_int_t nvarsinpool; 13824 dfinternalbuffers bufs; 13827 ae_vector oobcntbuf; 13832 ae_int_t oobrelcnt; 13839 ae_frame_make(_state, &_frame_block); 13841 _decisionforest_clear(df); 13842 _dfreport_clear(rep); 13843 _dfinternalbuffers_init(&bufs, _state, ae_true); 13844 ae_vector_init(&permbuf, 0, DT_INT, _state, ae_true); 13845 ae_vector_init(&oobbuf, 0, DT_REAL, _state, ae_true); 13846 ae_vector_init(&oobcntbuf, 0, DT_INT, _state, ae_true); 13847 ae_matrix_init(&xys, 0, 0, DT_REAL, _state, ae_true); 13848 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 13849 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 13850 _hqrndstate_init(&rs, _state, ae_true); 13856 if( (((((npoints<1||samplesize<1)||samplesize>npoints)||nvars<1)||nclasses<1)||ntrees<1)||nfeatures<1 ) 13859 ae_frame_leave(_state); 13864 for(i=0; i<=npoints-1; i++) 13866 if( ae_round(xy->ptr.pp_double[i][nvars], _state)<0||ae_round(xy->ptr.pp_double[i][nvars], _state)>=nclasses ) 13869 ae_frame_leave(_state); 13879 useevs = flags/dforest_dfuseevs%2!=0; 13882 * Allocate data, prepare header 13884 treesize = 1+dforest_innernodewidth*(samplesize-1)+dforest_leafnodewidth*samplesize; 13885 ae_vector_set_length(&permbuf, npoints-1+1, _state); 13886 ae_vector_set_length(&bufs.treebuf, treesize-1+1, _state); 13887 ae_vector_set_length(&bufs.idxbuf, npoints-1+1, _state); 13888 ae_vector_set_length(&bufs.tmpbufr, npoints-1+1, _state); 13889 ae_vector_set_length(&bufs.tmpbufr2, npoints-1+1, _state); 13890 ae_vector_set_length(&bufs.tmpbufi, npoints-1+1, _state); 13891 ae_vector_set_length(&bufs.sortrbuf, npoints, _state); 13892 ae_vector_set_length(&bufs.sortrbuf2, npoints, _state); 13893 ae_vector_set_length(&bufs.sortibuf, npoints, _state); 13894 ae_vector_set_length(&bufs.varpool, nvars-1+1, _state); 13895 ae_vector_set_length(&bufs.evsbin, nvars-1+1, _state); 13896 ae_vector_set_length(&bufs.evssplits, nvars-1+1, _state); 13897 ae_vector_set_length(&bufs.classibuf, 2*nclasses-1+1, _state); 13898 ae_vector_set_length(&oobbuf, nclasses*npoints-1+1, _state); 13899 ae_vector_set_length(&oobcntbuf, npoints-1+1, _state); 13900 ae_vector_set_length(&df->trees, ntrees*treesize-1+1, _state); 13901 ae_matrix_set_length(&xys, samplesize-1+1, nvars+1, _state); 13902 ae_vector_set_length(&x, nvars-1+1, _state); 13903 ae_vector_set_length(&y, nclasses-1+1, _state); 13904 for(i=0; i<=npoints-1; i++) 13906 permbuf.ptr.p_int[i] = i; 13908 for(i=0; i<=npoints*nclasses-1; i++) 13910 oobbuf.ptr.p_double[i] = 0; 13912 for(i=0; i<=npoints-1; i++) 13914 oobcntbuf.ptr.p_int[i] = 0; 13918 * Prepare variable pool and EVS (extended variable selection/splitting) buffers 13919 * (whether EVS is turned on or not): 13920 * 1. detect binary variables and pre-calculate splits for them 13921 * 2. detect variables with non-distinct values and exclude them from pool 13923 for(i=0; i<=nvars-1; i++) 13925 bufs.varpool.ptr.p_int[i] = i; 13927 nvarsinpool = nvars; 13930 for(j=0; j<=nvars-1; j++) 13932 vmin = xy->ptr.pp_double[0][j]; 13934 for(i=0; i<=npoints-1; i++) 13936 v = xy->ptr.pp_double[i][j]; 13937 vmin = ae_minreal(vmin, v, _state); 13938 vmax = ae_maxreal(vmax, v, _state); 13940 if( ae_fp_eq(vmin,vmax) ) 13944 * exclude variable from pool 13946 bufs.varpool.ptr.p_int[j] = bufs.varpool.ptr.p_int[nvarsinpool-1]; 13947 bufs.varpool.ptr.p_int[nvarsinpool-1] = -1; 13948 nvarsinpool = nvarsinpool-1; 13952 for(i=0; i<=npoints-1; i++) 13954 v = xy->ptr.pp_double[i][j]; 13955 if( ae_fp_neq(v,vmin)&&ae_fp_neq(v,vmax) ) 13965 * non-binary variable 13967 bufs.evsbin.ptr.p_bool[j] = ae_false; 13975 bufs.evsbin.ptr.p_bool[j] = ae_true; 13976 bufs.evssplits.ptr.p_double[j] = 0.5*(vmin+vmax); 13977 if( ae_fp_less_eq(bufs.evssplits.ptr.p_double[j],vmin) ) 13979 bufs.evssplits.ptr.p_double[j] = vmax; 13986 * RANDOM FOREST FORMAT 13987 * W[0] - size of array 13988 * W[1] - version number 13990 * W[3] - NClasses (1 for regression) 13992 * W[5] - trees offset 13996 * W[Offs] - size of sub-array 13998 * W[K+0] - variable number (-1 for leaf mode) 13999 * W[K+1] - threshold (class/value for leaf node) 14000 * W[K+2] - ">=
" branch index (absent for leaf node) 14004 df->nclasses = nclasses; 14005 df->ntrees = ntrees; 14010 hqrndrandomize(&rs, _state); 14012 for(i=0; i<=ntrees-1; i++) 14018 for(k=0; k<=samplesize-1; k++) 14020 j = k+hqrnduniformi(&rs, npoints-k, _state); 14021 tmpi = permbuf.ptr.p_int[k]; 14022 permbuf.ptr.p_int[k] = permbuf.ptr.p_int[j]; 14023 permbuf.ptr.p_int[j] = tmpi; 14024 j = permbuf.ptr.p_int[k]; 14025 ae_v_move(&xys.ptr.pp_double[k][0], 1, &xy->ptr.pp_double[j][0], 1, ae_v_len(0,nvars)); 14031 dforest_dfbuildtree(&xys, samplesize, nvars, nclasses, nfeatures, nvarsinpool, flags, &bufs, &rs, _state); 14032 j = ae_round(bufs.treebuf.ptr.p_double[0], _state); 14033 ae_v_move(&df->trees.ptr.p_double[offs], 1, &bufs.treebuf.ptr.p_double[0], 1, ae_v_len(offs,offs+j-1)); 14034 lasttreeoffs = offs; 14040 for(k=samplesize; k<=npoints-1; k++) 14042 for(j=0; j<=nclasses-1; j++) 14044 y.ptr.p_double[j] = 0; 14046 j = permbuf.ptr.p_int[k]; 14047 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[j][0], 1, ae_v_len(0,nvars-1)); 14048 dforest_dfprocessinternal(df, lasttreeoffs, &x, &y, _state); 14049 ae_v_add(&oobbuf.ptr.p_double[j*nclasses], 1, &y.ptr.p_double[0], 1, ae_v_len(j*nclasses,(j+1)*nclasses-1)); 14050 oobcntbuf.ptr.p_int[j] = oobcntbuf.ptr.p_int[j]+1; 14053 df->bufsize = offs; 14056 * Normalize OOB results 14058 for(i=0; i<=npoints-1; i++) 14060 if( oobcntbuf.ptr.p_int[i]!=0 ) 14062 v = (double)1/(double)oobcntbuf.ptr.p_int[i]; 14063 ae_v_muld(&oobbuf.ptr.p_double[i*nclasses], 1, ae_v_len(i*nclasses,i*nclasses+nclasses-1), v); 14068 * Calculate training set estimates 14070 rep->relclserror = dfrelclserror(df, xy, npoints, _state); 14071 rep->avgce = dfavgce(df, xy, npoints, _state); 14072 rep->rmserror = dfrmserror(df, xy, npoints, _state); 14073 rep->avgerror = dfavgerror(df, xy, npoints, _state); 14074 rep->avgrelerror = dfavgrelerror(df, xy, npoints, _state); 14077 * Calculate OOB estimates. 14079 rep->oobrelclserror = 0; 14081 rep->oobrmserror = 0; 14082 rep->oobavgerror = 0; 14083 rep->oobavgrelerror = 0; 14086 for(i=0; i<=npoints-1; i++) 14088 if( oobcntbuf.ptr.p_int[i]!=0 ) 14090 ooboffs = i*nclasses; 14095 * classification-specific code 14097 k = ae_round(xy->ptr.pp_double[i][nvars], _state); 14099 for(j=1; j<=nclasses-1; j++) 14101 if( ae_fp_greater(oobbuf.ptr.p_double[ooboffs+j],oobbuf.ptr.p_double[ooboffs+tmpi]) ) 14108 rep->oobrelclserror = rep->oobrelclserror+1; 14110 if( ae_fp_neq(oobbuf.ptr.p_double[ooboffs+k],0) ) 14112 rep->oobavgce = rep->oobavgce-ae_log(oobbuf.ptr.p_double[ooboffs+k], _state); 14116 rep->oobavgce = rep->oobavgce-ae_log(ae_minrealnumber, _state); 14118 for(j=0; j<=nclasses-1; j++) 14122 rep->oobrmserror = rep->oobrmserror+ae_sqr(oobbuf.ptr.p_double[ooboffs+j]-1, _state); 14123 rep->oobavgerror = rep->oobavgerror+ae_fabs(oobbuf.ptr.p_double[ooboffs+j]-1, _state); 14124 rep->oobavgrelerror = rep->oobavgrelerror+ae_fabs(oobbuf.ptr.p_double[ooboffs+j]-1, _state); 14125 oobrelcnt = oobrelcnt+1; 14129 rep->oobrmserror = rep->oobrmserror+ae_sqr(oobbuf.ptr.p_double[ooboffs+j], _state); 14130 rep->oobavgerror = rep->oobavgerror+ae_fabs(oobbuf.ptr.p_double[ooboffs+j], _state); 14138 * regression-specific code 14140 rep->oobrmserror = rep->oobrmserror+ae_sqr(oobbuf.ptr.p_double[ooboffs]-xy->ptr.pp_double[i][nvars], _state); 14141 rep->oobavgerror = rep->oobavgerror+ae_fabs(oobbuf.ptr.p_double[ooboffs]-xy->ptr.pp_double[i][nvars], _state); 14142 if( ae_fp_neq(xy->ptr.pp_double[i][nvars],0) ) 14144 rep->oobavgrelerror = rep->oobavgrelerror+ae_fabs((oobbuf.ptr.p_double[ooboffs]-xy->ptr.pp_double[i][nvars])/xy->ptr.pp_double[i][nvars], _state); 14145 oobrelcnt = oobrelcnt+1; 14150 * update OOB estimates count. 14157 rep->oobrelclserror = rep->oobrelclserror/oobcnt; 14158 rep->oobavgce = rep->oobavgce/oobcnt; 14159 rep->oobrmserror = ae_sqrt(rep->oobrmserror/(oobcnt*nclasses), _state); 14160 rep->oobavgerror = rep->oobavgerror/(oobcnt*nclasses); 14163 rep->oobavgrelerror = rep->oobavgrelerror/oobrelcnt; 14166 ae_frame_leave(_state); 14170 /************************************************************************* 14174 DF - decision forest model 14175 X - input vector, array[0..NVars-1]. 14178 Y - result. Regression estimate when solving regression task, 14179 vector of posterior probabilities for classification task. 14181 See also DFProcessI. 14184 Copyright 16.02.2009 by Bochkanov Sergey 14185 *************************************************************************/ 14186 void dfprocess(decisionforest* df, 14187 /* Real */ ae_vector* x, 14188 /* Real */ ae_vector* y, 14200 if( y->cnt<df->nclasses ) 14202 ae_vector_set_length(y, df->nclasses, _state); 14205 for(i=0; i<=df->nclasses-1; i++) 14207 y->ptr.p_double[i] = 0; 14209 for(i=0; i<=df->ntrees-1; i++) 14213 * Process basic tree 14215 dforest_dfprocessinternal(df, offs, x, y, _state); 14220 offs = offs+ae_round(df->trees.ptr.p_double[offs], _state); 14222 v = (double)1/(double)df->ntrees; 14223 ae_v_muld(&y->ptr.p_double[0], 1, ae_v_len(0,df->nclasses-1), v); 14227 /************************************************************************* 14228 'interactive' variant of DFProcess for languages like Python which support 14229 constructs like "Y = DFProcessI(DF,X)
" and interactive mode of interpreter 14231 This function allocates new array on each call, so it is significantly 14232 slower than its 'non-interactive' counterpart, but it is more convenient 14233 when you call it from command line. 14236 Copyright 28.02.2010 by Bochkanov Sergey 14237 *************************************************************************/ 14238 void dfprocessi(decisionforest* df, 14239 /* Real */ ae_vector* x, 14240 /* Real */ ae_vector* y, 14244 ae_vector_clear(y); 14246 dfprocess(df, x, y, _state); 14250 /************************************************************************* 14251 Relative classification error on the test set 14254 DF - decision forest model 14256 NPoints - test set size 14259 percent of incorrectly classified cases. 14260 Zero if model solves regression task. 14263 Copyright 16.02.2009 by Bochkanov Sergey 14264 *************************************************************************/ 14265 double dfrelclserror(decisionforest* df, 14266 /* Real */ ae_matrix* xy, 14273 result = (double)dforest_dfclserror(df, xy, npoints, _state)/(double)npoints; 14278 /************************************************************************* 14279 Average cross-entropy (in bits per element) on the test set 14282 DF - decision forest model 14284 NPoints - test set size 14287 CrossEntropy/(NPoints*LN(2)). 14288 Zero if model solves regression task. 14291 Copyright 16.02.2009 by Bochkanov Sergey 14292 *************************************************************************/ 14293 double dfavgce(decisionforest* df, 14294 /* Real */ ae_matrix* xy, 14298 ae_frame _frame_block; 14307 ae_frame_make(_state, &_frame_block); 14308 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 14309 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 14311 ae_vector_set_length(&x, df->nvars-1+1, _state); 14312 ae_vector_set_length(&y, df->nclasses-1+1, _state); 14314 for(i=0; i<=npoints-1; i++) 14316 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,df->nvars-1)); 14317 dfprocess(df, &x, &y, _state); 14318 if( df->nclasses>1 ) 14322 * classification-specific code 14324 k = ae_round(xy->ptr.pp_double[i][df->nvars], _state); 14326 for(j=1; j<=df->nclasses-1; j++) 14328 if( ae_fp_greater(y.ptr.p_double[j],y.ptr.p_double[tmpi]) ) 14333 if( ae_fp_neq(y.ptr.p_double[k],0) ) 14335 result = result-ae_log(y.ptr.p_double[k], _state); 14339 result = result-ae_log(ae_minrealnumber, _state); 14343 result = result/npoints; 14344 ae_frame_leave(_state); 14349 /************************************************************************* 14350 RMS error on the test set 14353 DF - decision forest model 14355 NPoints - test set size 14358 root mean square error. 14359 Its meaning for regression task is obvious. As for 14360 classification task, RMS error means error when estimating posterior 14364 Copyright 16.02.2009 by Bochkanov Sergey 14365 *************************************************************************/ 14366 double dfrmserror(decisionforest* df, 14367 /* Real */ ae_matrix* xy, 14371 ae_frame _frame_block; 14380 ae_frame_make(_state, &_frame_block); 14381 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 14382 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 14384 ae_vector_set_length(&x, df->nvars-1+1, _state); 14385 ae_vector_set_length(&y, df->nclasses-1+1, _state); 14387 for(i=0; i<=npoints-1; i++) 14389 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,df->nvars-1)); 14390 dfprocess(df, &x, &y, _state); 14391 if( df->nclasses>1 ) 14395 * classification-specific code 14397 k = ae_round(xy->ptr.pp_double[i][df->nvars], _state); 14399 for(j=1; j<=df->nclasses-1; j++) 14401 if( ae_fp_greater(y.ptr.p_double[j],y.ptr.p_double[tmpi]) ) 14406 for(j=0; j<=df->nclasses-1; j++) 14410 result = result+ae_sqr(y.ptr.p_double[j]-1, _state); 14414 result = result+ae_sqr(y.ptr.p_double[j], _state); 14422 * regression-specific code 14424 result = result+ae_sqr(y.ptr.p_double[0]-xy->ptr.pp_double[i][df->nvars], _state); 14427 result = ae_sqrt(result/(npoints*df->nclasses), _state); 14428 ae_frame_leave(_state); 14433 /************************************************************************* 14434 Average error on the test set 14437 DF - decision forest model 14439 NPoints - test set size 14442 Its meaning for regression task is obvious. As for 14443 classification task, it means average error when estimating posterior 14447 Copyright 16.02.2009 by Bochkanov Sergey 14448 *************************************************************************/ 14449 double dfavgerror(decisionforest* df, 14450 /* Real */ ae_matrix* xy, 14454 ae_frame _frame_block; 14462 ae_frame_make(_state, &_frame_block); 14463 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 14464 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 14466 ae_vector_set_length(&x, df->nvars-1+1, _state); 14467 ae_vector_set_length(&y, df->nclasses-1+1, _state); 14469 for(i=0; i<=npoints-1; i++) 14471 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,df->nvars-1)); 14472 dfprocess(df, &x, &y, _state); 14473 if( df->nclasses>1 ) 14477 * classification-specific code 14479 k = ae_round(xy->ptr.pp_double[i][df->nvars], _state); 14480 for(j=0; j<=df->nclasses-1; j++) 14484 result = result+ae_fabs(y.ptr.p_double[j]-1, _state); 14488 result = result+ae_fabs(y.ptr.p_double[j], _state); 14496 * regression-specific code 14498 result = result+ae_fabs(y.ptr.p_double[0]-xy->ptr.pp_double[i][df->nvars], _state); 14501 result = result/(npoints*df->nclasses); 14502 ae_frame_leave(_state); 14507 /************************************************************************* 14508 Average relative error on the test set 14511 DF - decision forest model 14513 NPoints - test set size 14516 Its meaning for regression task is obvious. As for 14517 classification task, it means average relative error when estimating 14518 posterior probability of belonging to the correct class. 14521 Copyright 16.02.2009 by Bochkanov Sergey 14522 *************************************************************************/ 14523 double dfavgrelerror(decisionforest* df, 14524 /* Real */ ae_matrix* xy, 14528 ae_frame _frame_block; 14537 ae_frame_make(_state, &_frame_block); 14538 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 14539 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 14541 ae_vector_set_length(&x, df->nvars-1+1, _state); 14542 ae_vector_set_length(&y, df->nclasses-1+1, _state); 14545 for(i=0; i<=npoints-1; i++) 14547 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,df->nvars-1)); 14548 dfprocess(df, &x, &y, _state); 14549 if( df->nclasses>1 ) 14553 * classification-specific code 14555 k = ae_round(xy->ptr.pp_double[i][df->nvars], _state); 14556 for(j=0; j<=df->nclasses-1; j++) 14560 result = result+ae_fabs(y.ptr.p_double[j]-1, _state); 14569 * regression-specific code 14571 if( ae_fp_neq(xy->ptr.pp_double[i][df->nvars],0) ) 14573 result = result+ae_fabs((y.ptr.p_double[0]-xy->ptr.pp_double[i][df->nvars])/xy->ptr.pp_double[i][df->nvars], _state); 14580 result = result/relcnt; 14582 ae_frame_leave(_state); 14587 /************************************************************************* 14588 Copying of DecisionForest strucure 14597 Copyright 13.02.2009 by Bochkanov Sergey 14598 *************************************************************************/ 14599 void dfcopy(decisionforest* df1, decisionforest* df2, ae_state *_state) 14602 _decisionforest_clear(df2); 14604 df2->nvars = df1->nvars; 14605 df2->nclasses = df1->nclasses; 14606 df2->ntrees = df1->ntrees; 14607 df2->bufsize = df1->bufsize; 14608 ae_vector_set_length(&df2->trees, df1->bufsize-1+1, _state); 14609 ae_v_move(&df2->trees.ptr.p_double[0], 1, &df1->trees.ptr.p_double[0], 1, ae_v_len(0,df1->bufsize-1)); 14613 /************************************************************************* 14614 Serializer: allocation 14617 Copyright 14.03.2011 by Bochkanov Sergey 14618 *************************************************************************/ 14619 void dfalloc(ae_serializer* s, decisionforest* forest, ae_state *_state) 14623 ae_serializer_alloc_entry(s); 14624 ae_serializer_alloc_entry(s); 14625 ae_serializer_alloc_entry(s); 14626 ae_serializer_alloc_entry(s); 14627 ae_serializer_alloc_entry(s); 14628 ae_serializer_alloc_entry(s); 14629 allocrealarray(s, &forest->trees, forest->bufsize, _state); 14633 /************************************************************************* 14634 Serializer: serialization 14637 Copyright 14.03.2011 by Bochkanov Sergey 14638 *************************************************************************/ 14639 void dfserialize(ae_serializer* s, 14640 decisionforest* forest, 14645 ae_serializer_serialize_int(s, getrdfserializationcode(_state), _state); 14646 ae_serializer_serialize_int(s, dforest_dffirstversion, _state); 14647 ae_serializer_serialize_int(s, forest->nvars, _state); 14648 ae_serializer_serialize_int(s, forest->nclasses, _state); 14649 ae_serializer_serialize_int(s, forest->ntrees, _state); 14650 ae_serializer_serialize_int(s, forest->bufsize, _state); 14651 serializerealarray(s, &forest->trees, forest->bufsize, _state); 14655 /************************************************************************* 14656 Serializer: unserialization 14659 Copyright 14.03.2011 by Bochkanov Sergey 14660 *************************************************************************/ 14661 void dfunserialize(ae_serializer* s, 14662 decisionforest* forest, 14668 _decisionforest_clear(forest); 14672 * check correctness of header 14674 ae_serializer_unserialize_int(s, &i0, _state); 14675 ae_assert(i0==getrdfserializationcode(_state), "DFUnserialize: stream header corrupted
", _state); 14676 ae_serializer_unserialize_int(s, &i1, _state); 14677 ae_assert(i1==dforest_dffirstversion, "DFUnserialize: stream header corrupted
", _state); 14682 ae_serializer_unserialize_int(s, &forest->nvars, _state); 14683 ae_serializer_unserialize_int(s, &forest->nclasses, _state); 14684 ae_serializer_unserialize_int(s, &forest->ntrees, _state); 14685 ae_serializer_unserialize_int(s, &forest->bufsize, _state); 14686 unserializerealarray(s, &forest->trees, _state); 14690 /************************************************************************* 14691 Classification error 14692 *************************************************************************/ 14693 static ae_int_t dforest_dfclserror(decisionforest* df, 14694 /* Real */ ae_matrix* xy, 14698 ae_frame _frame_block; 14707 ae_frame_make(_state, &_frame_block); 14708 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 14709 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 14711 if( df->nclasses<=1 ) 14714 ae_frame_leave(_state); 14717 ae_vector_set_length(&x, df->nvars-1+1, _state); 14718 ae_vector_set_length(&y, df->nclasses-1+1, _state); 14720 for(i=0; i<=npoints-1; i++) 14722 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,df->nvars-1)); 14723 dfprocess(df, &x, &y, _state); 14724 k = ae_round(xy->ptr.pp_double[i][df->nvars], _state); 14726 for(j=1; j<=df->nclasses-1; j++) 14728 if( ae_fp_greater(y.ptr.p_double[j],y.ptr.p_double[tmpi]) ) 14738 ae_frame_leave(_state); 14743 /************************************************************************* 14744 Internal subroutine for processing one decision tree starting at Offs 14745 *************************************************************************/ 14746 static void dforest_dfprocessinternal(decisionforest* df, 14748 /* Real */ ae_vector* x, 14749 /* Real */ ae_vector* y, 14758 * Set pointer to the root 14763 * Navigate through the tree 14767 if( ae_fp_eq(df->trees.ptr.p_double[k],-1) ) 14769 if( df->nclasses==1 ) 14771 y->ptr.p_double[0] = y->ptr.p_double[0]+df->trees.ptr.p_double[k+1]; 14775 idx = ae_round(df->trees.ptr.p_double[k+1], _state); 14776 y->ptr.p_double[idx] = y->ptr.p_double[idx]+1; 14780 if( ae_fp_less(x->ptr.p_double[ae_round(df->trees.ptr.p_double[k], _state)],df->trees.ptr.p_double[k+1]) ) 14782 k = k+dforest_innernodewidth; 14786 k = offs+ae_round(df->trees.ptr.p_double[k+2], _state); 14792 /************************************************************************* 14793 Builds one decision tree. Just a wrapper for the DFBuildTreeRec. 14794 *************************************************************************/ 14795 static void dforest_dfbuildtree(/* Real */ ae_matrix* xy, 14799 ae_int_t nfeatures, 14800 ae_int_t nvarsinpool, 14802 dfinternalbuffers* bufs, 14806 ae_int_t numprocessed; 14810 ae_assert(npoints>0, "Assertion failed
", _state); 14813 * Prepare IdxBuf. It stores indices of the training set elements. 14814 * When training set is being split, contents of IdxBuf is 14815 * correspondingly reordered so we can know which elements belong 14816 * to which branch of decision tree. 14818 for(i=0; i<=npoints-1; i++) 14820 bufs->idxbuf.ptr.p_int[i] = i; 14824 * Recursive procedure 14827 dforest_dfbuildtreerec(xy, npoints, nvars, nclasses, nfeatures, nvarsinpool, flags, &numprocessed, 0, npoints-1, bufs, rs, _state); 14828 bufs->treebuf.ptr.p_double[0] = numprocessed; 14832 /************************************************************************* 14833 Builds one decision tree (internal recursive subroutine) 14836 TreeBuf - large enough array, at least TreeSize 14837 IdxBuf - at least NPoints elements 14838 TmpBufR - at least NPoints 14839 TmpBufR2 - at least NPoints 14840 TmpBufI - at least NPoints 14841 TmpBufI2 - at least NPoints+1 14842 *************************************************************************/ 14843 static void dforest_dfbuildtreerec(/* Real */ ae_matrix* xy, 14847 ae_int_t nfeatures, 14848 ae_int_t nvarsinpool, 14850 ae_int_t* numprocessed, 14853 dfinternalbuffers* bufs, 14883 * these initializers are not really necessary, 14884 * but without them compiler complains about uninitialized locals 14891 ae_assert(npoints>0, "Assertion failed
", _state); 14892 ae_assert(idx2>=idx1, "Assertion failed
", _state); 14893 useevs = flags/dforest_dfuseevs%2!=0; 14900 bufs->treebuf.ptr.p_double[*numprocessed] = -1; 14901 bufs->treebuf.ptr.p_double[*numprocessed+1] = xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[idx1]][nvars]; 14902 *numprocessed = *numprocessed+dforest_leafnodewidth; 14908 * Select random variable, prepare split: 14909 * 1. prepare default solution - no splitting, class at random 14910 * 2. investigate possible splits, compare with default/best 14917 * default solution for classification 14919 for(i=0; i<=nclasses-1; i++) 14921 bufs->classibuf.ptr.p_int[i] = 0; 14924 for(i=idx1; i<=idx2; i++) 14926 j = ae_round(xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[i]][nvars], _state); 14927 bufs->classibuf.ptr.p_int[j] = bufs->classibuf.ptr.p_int[j]+1; 14930 for(i=0; i<=nclasses-1; i++) 14932 ebest = ebest+bufs->classibuf.ptr.p_int[i]*ae_sqr(1-bufs->classibuf.ptr.p_int[i]/s, _state)+(s-bufs->classibuf.ptr.p_int[i])*ae_sqr(bufs->classibuf.ptr.p_int[i]/s, _state); 14934 ebest = ae_sqrt(ebest/(nclasses*(idx2-idx1+1)), _state); 14940 * default solution for regression 14943 for(i=idx1; i<=idx2; i++) 14945 v = v+xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[i]][nvars]; 14947 v = v/(idx2-idx1+1); 14949 for(i=idx1; i<=idx2; i++) 14951 ebest = ebest+ae_sqr(xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[i]][nvars]-v, _state); 14953 ebest = ae_sqrt(ebest/(idx2-idx1+1), _state); 14956 while(i<=ae_minint(nfeatures, nvarsinpool, _state)-1) 14960 * select variables from pool 14962 j = i+hqrnduniformi(rs, nvarsinpool-i, _state); 14963 k = bufs->varpool.ptr.p_int[i]; 14964 bufs->varpool.ptr.p_int[i] = bufs->varpool.ptr.p_int[j]; 14965 bufs->varpool.ptr.p_int[j] = k; 14966 varcur = bufs->varpool.ptr.p_int[i]; 14969 * load variable values to working array 14971 * apply EVS preprocessing: if all variable values are same, 14972 * variable is excluded from pool. 14974 * This is necessary for binary pre-splits (see later) to work. 14976 for(j=idx1; j<=idx2; j++) 14978 bufs->tmpbufr.ptr.p_double[j-idx1] = xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[j]][varcur]; 14983 v = bufs->tmpbufr.ptr.p_double[0]; 14984 for(j=0; j<=idx2-idx1; j++) 14986 if( ae_fp_neq(bufs->tmpbufr.ptr.p_double[j],v) ) 14996 * exclude variable from pool, 14997 * go to the next iteration. 14998 * I is not increased. 15000 k = bufs->varpool.ptr.p_int[i]; 15001 bufs->varpool.ptr.p_int[i] = bufs->varpool.ptr.p_int[nvarsinpool-1]; 15002 bufs->varpool.ptr.p_int[nvarsinpool-1] = k; 15003 nvarsinpool = nvarsinpool-1; 15009 * load labels to working array 15013 for(j=idx1; j<=idx2; j++) 15015 bufs->tmpbufi.ptr.p_int[j-idx1] = ae_round(xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[j]][nvars], _state); 15020 for(j=idx1; j<=idx2; j++) 15022 bufs->tmpbufr2.ptr.p_double[j-idx1] = xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[j]][nvars]; 15029 if( useevs&&bufs->evsbin.ptr.p_bool[varcur] ) 15033 * Pre-calculated splits for binary variables. 15034 * Threshold is already known, just calculate RMS error 15036 threshold = bufs->evssplits.ptr.p_double[varcur]; 15041 * classification-specific code 15043 for(j=0; j<=2*nclasses-1; j++) 15045 bufs->classibuf.ptr.p_int[j] = 0; 15049 for(j=0; j<=idx2-idx1; j++) 15051 k = bufs->tmpbufi.ptr.p_int[j]; 15052 if( ae_fp_less(bufs->tmpbufr.ptr.p_double[j],threshold) ) 15054 bufs->classibuf.ptr.p_int[k] = bufs->classibuf.ptr.p_int[k]+1; 15059 bufs->classibuf.ptr.p_int[k+nclasses] = bufs->classibuf.ptr.p_int[k+nclasses]+1; 15063 ae_assert(ae_fp_neq(sl,0)&&ae_fp_neq(sr,0), "DFBuildTreeRec: something strange!
", _state); 15065 for(j=0; j<=nclasses-1; j++) 15067 w = bufs->classibuf.ptr.p_int[j]; 15068 currms = currms+w*ae_sqr(w/sl-1, _state); 15069 currms = currms+(sl-w)*ae_sqr(w/sl, _state); 15070 w = bufs->classibuf.ptr.p_int[nclasses+j]; 15071 currms = currms+w*ae_sqr(w/sr-1, _state); 15072 currms = currms+(sr-w)*ae_sqr(w/sr, _state); 15074 currms = ae_sqrt(currms/(nclasses*(idx2-idx1+1)), _state); 15080 * regression-specific code 15086 for(j=0; j<=idx2-idx1; j++) 15088 if( ae_fp_less(bufs->tmpbufr.ptr.p_double[j],threshold) ) 15090 v1 = v1+bufs->tmpbufr2.ptr.p_double[j]; 15095 v2 = v2+bufs->tmpbufr2.ptr.p_double[j]; 15099 ae_assert(ae_fp_neq(sl,0)&&ae_fp_neq(sr,0), "DFBuildTreeRec: something strange!
", _state); 15103 for(j=0; j<=idx2-idx1; j++) 15105 if( ae_fp_less(bufs->tmpbufr.ptr.p_double[j],threshold) ) 15107 currms = currms+ae_sqr(v1-bufs->tmpbufr2.ptr.p_double[j], _state); 15111 currms = currms+ae_sqr(v2-bufs->tmpbufr2.ptr.p_double[j], _state); 15114 currms = ae_sqrt(currms/(idx2-idx1+1), _state); 15126 dforest_dfsplitc(&bufs->tmpbufr, &bufs->tmpbufi, &bufs->classibuf, idx2-idx1+1, nclasses, dforest_dfusestrongsplits, &info, &threshold, &currms, &bufs->sortrbuf, &bufs->sortibuf, _state); 15130 dforest_dfsplitr(&bufs->tmpbufr, &bufs->tmpbufr2, idx2-idx1+1, dforest_dfusestrongsplits, &info, &threshold, &currms, &bufs->sortrbuf, &bufs->sortrbuf2, _state); 15135 if( ae_fp_less_eq(currms,ebest) ) 15150 * to split or not to split 15156 * All values are same, cannot split. 15158 bufs->treebuf.ptr.p_double[*numprocessed] = -1; 15163 * Select random class label (randomness allows us to 15164 * approximate distribution of the classes) 15166 bufs->treebuf.ptr.p_double[*numprocessed+1] = ae_round(xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[idx1+hqrnduniformi(rs, idx2-idx1+1, _state)]][nvars], _state); 15172 * Select average (for regression task). 15175 for(i=idx1; i<=idx2; i++) 15177 v = v+xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[i]][nvars]/(idx2-idx1+1); 15179 bufs->treebuf.ptr.p_double[*numprocessed+1] = v; 15181 *numprocessed = *numprocessed+dforest_leafnodewidth; 15189 bufs->treebuf.ptr.p_double[*numprocessed] = idxbest; 15190 bufs->treebuf.ptr.p_double[*numprocessed+1] = tbest; 15197 * Reorder indices so that left partition is in [Idx1..I1-1], 15198 * and right partition is in [I2+1..Idx2] 15200 if( ae_fp_less(xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[i1]][idxbest],tbest) ) 15205 if( ae_fp_greater_eq(xy->ptr.pp_double[bufs->idxbuf.ptr.p_int[i2]][idxbest],tbest) ) 15210 j = bufs->idxbuf.ptr.p_int[i1]; 15211 bufs->idxbuf.ptr.p_int[i1] = bufs->idxbuf.ptr.p_int[i2]; 15212 bufs->idxbuf.ptr.p_int[i2] = j; 15216 oldnp = *numprocessed; 15217 *numprocessed = *numprocessed+dforest_innernodewidth; 15218 dforest_dfbuildtreerec(xy, npoints, nvars, nclasses, nfeatures, nvarsinpool, flags, numprocessed, idx1, i1-1, bufs, rs, _state); 15219 bufs->treebuf.ptr.p_double[oldnp+2] = *numprocessed; 15220 dforest_dfbuildtreerec(xy, npoints, nvars, nclasses, nfeatures, nvarsinpool, flags, numprocessed, i2+1, idx2, bufs, rs, _state); 15225 /************************************************************************* 15226 Makes split on attribute 15227 *************************************************************************/ 15228 static void dforest_dfsplitc(/* Real */ ae_vector* x, 15229 /* Integer */ ae_vector* c, 15230 /* Integer */ ae_vector* cntbuf, 15237 /* Real */ ae_vector* sortrbuf, 15238 /* Integer */ ae_vector* sortibuf, 15261 tagsortfasti(x, c, sortrbuf, sortibuf, n, _state); 15262 *e = ae_maxrealnumber; 15263 *threshold = 0.5*(x->ptr.p_double[0]+x->ptr.p_double[n-1]); 15265 if( flags/dforest_dfusestrongsplits%2==0 ) 15269 * weak splits, split at half 15279 * strong splits: choose best quartile 15285 for(q=qmin; q<=qmax; q++) 15287 cursplit = x->ptr.p_double[n*q/qcnt]; 15291 for(i=0; i<=n-1; i++) 15293 if( ae_fp_less(x->ptr.p_double[i],cursplit) ) 15297 if( ae_fp_eq(x->ptr.p_double[i],cursplit) ) 15301 if( ae_fp_greater(x->ptr.p_double[i],cursplit) ) 15303 ngreater = ngreater+1; 15306 ae_assert(neq!=0, "DFSplitR: NEq=0, something strange!!!
", _state); 15307 if( nless!=0||ngreater!=0 ) 15311 * set threshold between two partitions, with 15312 * some tweaking to avoid problems with floating point 15315 * The problem is that when you calculates C = 0.5*(A+B) there 15316 * can be no C which lies strictly between A and B (for example, 15317 * there is no floating point number which is 15318 * greater than 1 and less than 1+eps). In such situations 15319 * we choose right side as threshold (remember that 15320 * points which lie on threshold falls to the right side). 15322 if( nless<ngreater ) 15324 cursplit = 0.5*(x->ptr.p_double[nless+neq-1]+x->ptr.p_double[nless+neq]); 15326 if( ae_fp_less_eq(cursplit,x->ptr.p_double[nless+neq-1]) ) 15328 cursplit = x->ptr.p_double[nless+neq]; 15333 cursplit = 0.5*(x->ptr.p_double[nless-1]+x->ptr.p_double[nless]); 15335 if( ae_fp_less_eq(cursplit,x->ptr.p_double[nless-1]) ) 15337 cursplit = x->ptr.p_double[nless]; 15342 for(i=0; i<=2*nc-1; i++) 15344 cntbuf->ptr.p_int[i] = 0; 15346 for(i=0; i<=nleft-1; i++) 15348 cntbuf->ptr.p_int[c->ptr.p_int[i]] = cntbuf->ptr.p_int[c->ptr.p_int[i]]+1; 15350 for(i=nleft; i<=n-1; i++) 15352 cntbuf->ptr.p_int[nc+c->ptr.p_int[i]] = cntbuf->ptr.p_int[nc+c->ptr.p_int[i]]+1; 15357 for(i=0; i<=nc-1; i++) 15359 w = cntbuf->ptr.p_int[i]; 15360 v = v+w*ae_sqr(w/sl-1, _state); 15361 v = v+(sl-w)*ae_sqr(w/sl, _state); 15362 w = cntbuf->ptr.p_int[nc+i]; 15363 v = v+w*ae_sqr(w/sr-1, _state); 15364 v = v+(sr-w)*ae_sqr(w/sr, _state); 15366 cure = ae_sqrt(v/(nc*n), _state); 15367 if( ae_fp_less(cure,*e) ) 15369 *threshold = cursplit; 15377 /************************************************************************* 15378 Makes split on attribute 15379 *************************************************************************/ 15380 static void dforest_dfsplitr(/* Real */ ae_vector* x, 15381 /* Real */ ae_vector* y, 15387 /* Real */ ae_vector* sortrbuf, 15388 /* Real */ ae_vector* sortrbuf2, 15408 tagsortfastr(x, y, sortrbuf, sortrbuf2, n, _state); 15409 *e = ae_maxrealnumber; 15410 *threshold = 0.5*(x->ptr.p_double[0]+x->ptr.p_double[n-1]); 15412 if( flags/dforest_dfusestrongsplits%2==0 ) 15416 * weak splits, split at half 15426 * strong splits: choose best quartile 15432 for(q=qmin; q<=qmax; q++) 15434 cursplit = x->ptr.p_double[n*q/qcnt]; 15438 for(i=0; i<=n-1; i++) 15440 if( ae_fp_less(x->ptr.p_double[i],cursplit) ) 15444 if( ae_fp_eq(x->ptr.p_double[i],cursplit) ) 15448 if( ae_fp_greater(x->ptr.p_double[i],cursplit) ) 15450 ngreater = ngreater+1; 15453 ae_assert(neq!=0, "DFSplitR: NEq=0, something strange!!!
", _state); 15454 if( nless!=0||ngreater!=0 ) 15458 * set threshold between two partitions, with 15459 * some tweaking to avoid problems with floating point 15462 * The problem is that when you calculates C = 0.5*(A+B) there 15463 * can be no C which lies strictly between A and B (for example, 15464 * there is no floating point number which is 15465 * greater than 1 and less than 1+eps). In such situations 15466 * we choose right side as threshold (remember that 15467 * points which lie on threshold falls to the right side). 15469 if( nless<ngreater ) 15471 cursplit = 0.5*(x->ptr.p_double[nless+neq-1]+x->ptr.p_double[nless+neq]); 15473 if( ae_fp_less_eq(cursplit,x->ptr.p_double[nless+neq-1]) ) 15475 cursplit = x->ptr.p_double[nless+neq]; 15480 cursplit = 0.5*(x->ptr.p_double[nless-1]+x->ptr.p_double[nless]); 15482 if( ae_fp_less_eq(cursplit,x->ptr.p_double[nless-1]) ) 15484 cursplit = x->ptr.p_double[nless]; 15490 for(i=0; i<=nleft-1; i++) 15492 v = v+y->ptr.p_double[i]; 15495 for(i=0; i<=nleft-1; i++) 15497 cure = cure+ae_sqr(y->ptr.p_double[i]-v, _state); 15500 for(i=nleft; i<=n-1; i++) 15502 v = v+y->ptr.p_double[i]; 15505 for(i=nleft; i<=n-1; i++) 15507 cure = cure+ae_sqr(y->ptr.p_double[i]-v, _state); 15509 cure = ae_sqrt(cure/n, _state); 15510 if( ae_fp_less(cure,*e) ) 15512 *threshold = cursplit; 15520 ae_bool _decisionforest_init(void* _p, ae_state *_state, ae_bool make_automatic) 15522 decisionforest *p = (decisionforest*)_p; 15523 ae_touch_ptr((void*)p); 15524 if( !ae_vector_init(&p->trees, 0, DT_REAL, _state, make_automatic) ) 15530 ae_bool _decisionforest_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 15532 decisionforest *dst = (decisionforest*)_dst; 15533 decisionforest *src = (decisionforest*)_src; 15534 dst->nvars = src->nvars; 15535 dst->nclasses = src->nclasses; 15536 dst->ntrees = src->ntrees; 15537 dst->bufsize = src->bufsize; 15538 if( !ae_vector_init_copy(&dst->trees, &src->trees, _state, make_automatic) ) 15544 void _decisionforest_clear(void* _p) 15546 decisionforest *p = (decisionforest*)_p; 15547 ae_touch_ptr((void*)p); 15548 ae_vector_clear(&p->trees); 15552 void _decisionforest_destroy(void* _p) 15554 decisionforest *p = (decisionforest*)_p; 15555 ae_touch_ptr((void*)p); 15556 ae_vector_destroy(&p->trees); 15560 ae_bool _dfreport_init(void* _p, ae_state *_state, ae_bool make_automatic) 15562 dfreport *p = (dfreport*)_p; 15563 ae_touch_ptr((void*)p); 15568 ae_bool _dfreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 15570 dfreport *dst = (dfreport*)_dst; 15571 dfreport *src = (dfreport*)_src; 15572 dst->relclserror = src->relclserror; 15573 dst->avgce = src->avgce; 15574 dst->rmserror = src->rmserror; 15575 dst->avgerror = src->avgerror; 15576 dst->avgrelerror = src->avgrelerror; 15577 dst->oobrelclserror = src->oobrelclserror; 15578 dst->oobavgce = src->oobavgce; 15579 dst->oobrmserror = src->oobrmserror; 15580 dst->oobavgerror = src->oobavgerror; 15581 dst->oobavgrelerror = src->oobavgrelerror; 15586 void _dfreport_clear(void* _p) 15588 dfreport *p = (dfreport*)_p; 15589 ae_touch_ptr((void*)p); 15593 void _dfreport_destroy(void* _p) 15595 dfreport *p = (dfreport*)_p; 15596 ae_touch_ptr((void*)p); 15600 ae_bool _dfinternalbuffers_init(void* _p, ae_state *_state, ae_bool make_automatic) 15602 dfinternalbuffers *p = (dfinternalbuffers*)_p; 15603 ae_touch_ptr((void*)p); 15604 if( !ae_vector_init(&p->treebuf, 0, DT_REAL, _state, make_automatic) ) 15606 if( !ae_vector_init(&p->idxbuf, 0, DT_INT, _state, make_automatic) ) 15608 if( !ae_vector_init(&p->tmpbufr, 0, DT_REAL, _state, make_automatic) ) 15610 if( !ae_vector_init(&p->tmpbufr2, 0, DT_REAL, _state, make_automatic) ) 15612 if( !ae_vector_init(&p->tmpbufi, 0, DT_INT, _state, make_automatic) ) 15614 if( !ae_vector_init(&p->classibuf, 0, DT_INT, _state, make_automatic) ) 15616 if( !ae_vector_init(&p->sortrbuf, 0, DT_REAL, _state, make_automatic) ) 15618 if( !ae_vector_init(&p->sortrbuf2, 0, DT_REAL, _state, make_automatic) ) 15620 if( !ae_vector_init(&p->sortibuf, 0, DT_INT, _state, make_automatic) ) 15622 if( !ae_vector_init(&p->varpool, 0, DT_INT, _state, make_automatic) ) 15624 if( !ae_vector_init(&p->evsbin, 0, DT_BOOL, _state, make_automatic) ) 15626 if( !ae_vector_init(&p->evssplits, 0, DT_REAL, _state, make_automatic) ) 15632 ae_bool _dfinternalbuffers_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 15634 dfinternalbuffers *dst = (dfinternalbuffers*)_dst; 15635 dfinternalbuffers *src = (dfinternalbuffers*)_src; 15636 if( !ae_vector_init_copy(&dst->treebuf, &src->treebuf, _state, make_automatic) ) 15638 if( !ae_vector_init_copy(&dst->idxbuf, &src->idxbuf, _state, make_automatic) ) 15640 if( !ae_vector_init_copy(&dst->tmpbufr, &src->tmpbufr, _state, make_automatic) ) 15642 if( !ae_vector_init_copy(&dst->tmpbufr2, &src->tmpbufr2, _state, make_automatic) ) 15644 if( !ae_vector_init_copy(&dst->tmpbufi, &src->tmpbufi, _state, make_automatic) ) 15646 if( !ae_vector_init_copy(&dst->classibuf, &src->classibuf, _state, make_automatic) ) 15648 if( !ae_vector_init_copy(&dst->sortrbuf, &src->sortrbuf, _state, make_automatic) ) 15650 if( !ae_vector_init_copy(&dst->sortrbuf2, &src->sortrbuf2, _state, make_automatic) ) 15652 if( !ae_vector_init_copy(&dst->sortibuf, &src->sortibuf, _state, make_automatic) ) 15654 if( !ae_vector_init_copy(&dst->varpool, &src->varpool, _state, make_automatic) ) 15656 if( !ae_vector_init_copy(&dst->evsbin, &src->evsbin, _state, make_automatic) ) 15658 if( !ae_vector_init_copy(&dst->evssplits, &src->evssplits, _state, make_automatic) ) 15664 void _dfinternalbuffers_clear(void* _p) 15666 dfinternalbuffers *p = (dfinternalbuffers*)_p; 15667 ae_touch_ptr((void*)p); 15668 ae_vector_clear(&p->treebuf); 15669 ae_vector_clear(&p->idxbuf); 15670 ae_vector_clear(&p->tmpbufr); 15671 ae_vector_clear(&p->tmpbufr2); 15672 ae_vector_clear(&p->tmpbufi); 15673 ae_vector_clear(&p->classibuf); 15674 ae_vector_clear(&p->sortrbuf); 15675 ae_vector_clear(&p->sortrbuf2); 15676 ae_vector_clear(&p->sortibuf); 15677 ae_vector_clear(&p->varpool); 15678 ae_vector_clear(&p->evsbin); 15679 ae_vector_clear(&p->evssplits); 15683 void _dfinternalbuffers_destroy(void* _p) 15685 dfinternalbuffers *p = (dfinternalbuffers*)_p; 15686 ae_touch_ptr((void*)p); 15687 ae_vector_destroy(&p->treebuf); 15688 ae_vector_destroy(&p->idxbuf); 15689 ae_vector_destroy(&p->tmpbufr); 15690 ae_vector_destroy(&p->tmpbufr2); 15691 ae_vector_destroy(&p->tmpbufi); 15692 ae_vector_destroy(&p->classibuf); 15693 ae_vector_destroy(&p->sortrbuf); 15694 ae_vector_destroy(&p->sortrbuf2); 15695 ae_vector_destroy(&p->sortibuf); 15696 ae_vector_destroy(&p->varpool); 15697 ae_vector_destroy(&p->evsbin); 15698 ae_vector_destroy(&p->evssplits); 15704 /************************************************************************* 15707 Subroutine builds model: 15709 Y = A(0)*X[0] + ... + A(N-1)*X[N-1] + A(N) 15711 and model found in ALGLIB format, covariation matrix, training set errors 15712 (rms, average, average relative) and leave-one-out cross-validation 15713 estimate of the generalization error. CV estimate calculated using fast 15714 algorithm with O(NPoints*NVars) complexity. 15716 When covariation matrix is calculated standard deviations of function 15717 values are assumed to be equal to RMS error on the training set. 15720 XY - training set, array [0..NPoints-1,0..NVars]: 15721 * NVars columns - independent variables 15722 * last column - dependent variable 15723 NPoints - training set size, NPoints>NVars+1 15724 NVars - number of independent variables 15727 Info - return code: 15728 * -255, in case of unknown internal error 15729 * -4, if internal SVD subroutine haven't converged 15730 * -1, if incorrect parameters was passed (NPoints<NVars+2, NVars<1). 15731 * 1, if subroutine successfully finished 15732 LM - linear model in the ALGLIB format. Use subroutines of 15733 this unit to work with the model. 15734 AR - additional results 15738 Copyright 02.08.2008 by Bochkanov Sergey 15739 *************************************************************************/ 15740 void lrbuild(/* Real */ ae_matrix* xy, 15748 ae_frame _frame_block; 15753 ae_frame_make(_state, &_frame_block); 15755 _linearmodel_clear(lm); 15756 _lrreport_clear(ar); 15757 ae_vector_init(&s, 0, DT_REAL, _state, ae_true); 15759 if( npoints<=nvars+1||nvars<1 ) 15762 ae_frame_leave(_state); 15765 ae_vector_set_length(&s, npoints-1+1, _state); 15766 for(i=0; i<=npoints-1; i++) 15768 s.ptr.p_double[i] = 1; 15770 lrbuilds(xy, &s, npoints, nvars, info, lm, ar, _state); 15773 ae_frame_leave(_state); 15776 sigma2 = ae_sqr(ar->rmserror, _state)*npoints/(npoints-nvars-1); 15777 for(i=0; i<=nvars; i++) 15779 ae_v_muld(&ar->c.ptr.pp_double[i][0], 1, ae_v_len(0,nvars), sigma2); 15781 ae_frame_leave(_state); 15785 /************************************************************************* 15788 Variant of LRBuild which uses vector of standatd deviations (errors in 15792 XY - training set, array [0..NPoints-1,0..NVars]: 15793 * NVars columns - independent variables 15794 * last column - dependent variable 15795 S - standard deviations (errors in function values) 15796 array[0..NPoints-1], S[i]>0. 15797 NPoints - training set size, NPoints>NVars+1 15798 NVars - number of independent variables 15801 Info - return code: 15802 * -255, in case of unknown internal error 15803 * -4, if internal SVD subroutine haven't converged 15804 * -1, if incorrect parameters was passed (NPoints<NVars+2, NVars<1). 15806 * 1, if subroutine successfully finished 15807 LM - linear model in the ALGLIB format. Use subroutines of 15808 this unit to work with the model. 15809 AR - additional results 15813 Copyright 02.08.2008 by Bochkanov Sergey 15814 *************************************************************************/ 15815 void lrbuilds(/* Real */ ae_matrix* xy, 15816 /* Real */ ae_vector* s, 15824 ae_frame _frame_block; 15838 ae_frame_make(_state, &_frame_block); 15840 _linearmodel_clear(lm); 15841 _lrreport_clear(ar); 15842 ae_matrix_init(&xyi, 0, 0, DT_REAL, _state, ae_true); 15843 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 15844 ae_vector_init(&means, 0, DT_REAL, _state, ae_true); 15845 ae_vector_init(&sigmas, 0, DT_REAL, _state, ae_true); 15851 if( npoints<=nvars+1||nvars<1 ) 15854 ae_frame_leave(_state); 15859 * Copy data, add one more column (constant term) 15861 ae_matrix_set_length(&xyi, npoints-1+1, nvars+1+1, _state); 15862 for(i=0; i<=npoints-1; i++) 15864 ae_v_move(&xyi.ptr.pp_double[i][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 15865 xyi.ptr.pp_double[i][nvars] = 1; 15866 xyi.ptr.pp_double[i][nvars+1] = xy->ptr.pp_double[i][nvars]; 15872 ae_vector_set_length(&x, npoints-1+1, _state); 15873 ae_vector_set_length(&means, nvars-1+1, _state); 15874 ae_vector_set_length(&sigmas, nvars-1+1, _state); 15875 for(j=0; j<=nvars-1; j++) 15877 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[0][j], xy->stride, ae_v_len(0,npoints-1)); 15878 samplemoments(&x, npoints, &mean, &variance, &skewness, &kurtosis, _state); 15879 means.ptr.p_double[j] = mean; 15880 sigmas.ptr.p_double[j] = ae_sqrt(variance, _state); 15881 if( ae_fp_eq(sigmas.ptr.p_double[j],0) ) 15883 sigmas.ptr.p_double[j] = 1; 15885 for(i=0; i<=npoints-1; i++) 15887 xyi.ptr.pp_double[i][j] = (xyi.ptr.pp_double[i][j]-means.ptr.p_double[j])/sigmas.ptr.p_double[j]; 15892 * Internal processing 15894 linreg_lrinternal(&xyi, s, npoints, nvars+1, info, lm, ar, _state); 15897 ae_frame_leave(_state); 15902 * Un-standartization 15904 offs = ae_round(lm->w.ptr.p_double[3], _state); 15905 for(j=0; j<=nvars-1; j++) 15909 * Constant term is updated (and its covariance too, 15910 * since it gets some variance from J-th component) 15912 lm->w.ptr.p_double[offs+nvars] = lm->w.ptr.p_double[offs+nvars]-lm->w.ptr.p_double[offs+j]*means.ptr.p_double[j]/sigmas.ptr.p_double[j]; 15913 v = means.ptr.p_double[j]/sigmas.ptr.p_double[j]; 15914 ae_v_subd(&ar->c.ptr.pp_double[nvars][0], 1, &ar->c.ptr.pp_double[j][0], 1, ae_v_len(0,nvars), v); 15915 ae_v_subd(&ar->c.ptr.pp_double[0][nvars], ar->c.stride, &ar->c.ptr.pp_double[0][j], ar->c.stride, ae_v_len(0,nvars), v); 15918 * J-th term is updated 15920 lm->w.ptr.p_double[offs+j] = lm->w.ptr.p_double[offs+j]/sigmas.ptr.p_double[j]; 15921 v = 1/sigmas.ptr.p_double[j]; 15922 ae_v_muld(&ar->c.ptr.pp_double[j][0], 1, ae_v_len(0,nvars), v); 15923 ae_v_muld(&ar->c.ptr.pp_double[0][j], ar->c.stride, ae_v_len(0,nvars), v); 15925 ae_frame_leave(_state); 15929 /************************************************************************* 15930 Like LRBuildS, but builds model 15932 Y = A(0)*X[0] + ... + A(N-1)*X[N-1] 15934 i.e. with zero constant term. 15937 Copyright 30.10.2008 by Bochkanov Sergey 15938 *************************************************************************/ 15939 void lrbuildzs(/* Real */ ae_matrix* xy, 15940 /* Real */ ae_vector* s, 15948 ae_frame _frame_block; 15961 ae_frame_make(_state, &_frame_block); 15963 _linearmodel_clear(lm); 15964 _lrreport_clear(ar); 15965 ae_matrix_init(&xyi, 0, 0, DT_REAL, _state, ae_true); 15966 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 15967 ae_vector_init(&c, 0, DT_REAL, _state, ae_true); 15973 if( npoints<=nvars+1||nvars<1 ) 15976 ae_frame_leave(_state); 15981 * Copy data, add one more column (constant term) 15983 ae_matrix_set_length(&xyi, npoints-1+1, nvars+1+1, _state); 15984 for(i=0; i<=npoints-1; i++) 15986 ae_v_move(&xyi.ptr.pp_double[i][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 15987 xyi.ptr.pp_double[i][nvars] = 0; 15988 xyi.ptr.pp_double[i][nvars+1] = xy->ptr.pp_double[i][nvars]; 15992 * Standartization: unusual scaling 15994 ae_vector_set_length(&x, npoints-1+1, _state); 15995 ae_vector_set_length(&c, nvars-1+1, _state); 15996 for(j=0; j<=nvars-1; j++) 15998 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[0][j], xy->stride, ae_v_len(0,npoints-1)); 15999 samplemoments(&x, npoints, &mean, &variance, &skewness, &kurtosis, _state); 16000 if( ae_fp_greater(ae_fabs(mean, _state),ae_sqrt(variance, _state)) ) 16004 * variation is relatively small, it is better to 16005 * bring mean value to 1 16007 c.ptr.p_double[j] = mean; 16013 * variation is large, it is better to bring variance to 1 16015 if( ae_fp_eq(variance,0) ) 16019 c.ptr.p_double[j] = ae_sqrt(variance, _state); 16021 for(i=0; i<=npoints-1; i++) 16023 xyi.ptr.pp_double[i][j] = xyi.ptr.pp_double[i][j]/c.ptr.p_double[j]; 16028 * Internal processing 16030 linreg_lrinternal(&xyi, s, npoints, nvars+1, info, lm, ar, _state); 16033 ae_frame_leave(_state); 16038 * Un-standartization 16040 offs = ae_round(lm->w.ptr.p_double[3], _state); 16041 for(j=0; j<=nvars-1; j++) 16045 * J-th term is updated 16047 lm->w.ptr.p_double[offs+j] = lm->w.ptr.p_double[offs+j]/c.ptr.p_double[j]; 16048 v = 1/c.ptr.p_double[j]; 16049 ae_v_muld(&ar->c.ptr.pp_double[j][0], 1, ae_v_len(0,nvars), v); 16050 ae_v_muld(&ar->c.ptr.pp_double[0][j], ar->c.stride, ae_v_len(0,nvars), v); 16052 ae_frame_leave(_state); 16056 /************************************************************************* 16057 Like LRBuild but builds model 16059 Y = A(0)*X[0] + ... + A(N-1)*X[N-1] 16061 i.e. with zero constant term. 16064 Copyright 30.10.2008 by Bochkanov Sergey 16065 *************************************************************************/ 16066 void lrbuildz(/* Real */ ae_matrix* xy, 16074 ae_frame _frame_block; 16079 ae_frame_make(_state, &_frame_block); 16081 _linearmodel_clear(lm); 16082 _lrreport_clear(ar); 16083 ae_vector_init(&s, 0, DT_REAL, _state, ae_true); 16085 if( npoints<=nvars+1||nvars<1 ) 16088 ae_frame_leave(_state); 16091 ae_vector_set_length(&s, npoints-1+1, _state); 16092 for(i=0; i<=npoints-1; i++) 16094 s.ptr.p_double[i] = 1; 16096 lrbuildzs(xy, &s, npoints, nvars, info, lm, ar, _state); 16099 ae_frame_leave(_state); 16102 sigma2 = ae_sqr(ar->rmserror, _state)*npoints/(npoints-nvars-1); 16103 for(i=0; i<=nvars; i++) 16105 ae_v_muld(&ar->c.ptr.pp_double[i][0], 1, ae_v_len(0,nvars), sigma2); 16107 ae_frame_leave(_state); 16111 /************************************************************************* 16112 Unpacks coefficients of linear model. 16115 LM - linear model in ALGLIB format 16118 V - coefficients, array[0..NVars] 16119 constant term (intercept) is stored in the V[NVars]. 16120 NVars - number of independent variables (one less than number 16124 Copyright 30.08.2008 by Bochkanov Sergey 16125 *************************************************************************/ 16126 void lrunpack(linearmodel* lm, 16127 /* Real */ ae_vector* v, 16133 ae_vector_clear(v); 16136 ae_assert(ae_round(lm->w.ptr.p_double[1], _state)==linreg_lrvnum, "LINREG: Incorrect LINREG version!
", _state); 16137 *nvars = ae_round(lm->w.ptr.p_double[2], _state); 16138 offs = ae_round(lm->w.ptr.p_double[3], _state); 16139 ae_vector_set_length(v, *nvars+1, _state); 16140 ae_v_move(&v->ptr.p_double[0], 1, &lm->w.ptr.p_double[offs], 1, ae_v_len(0,*nvars)); 16144 /************************************************************************* 16145 "Packs
" coefficients and creates linear model in ALGLIB format (LRUnpack 16149 V - coefficients, array[0..NVars] 16150 NVars - number of independent variables 16156 Copyright 30.08.2008 by Bochkanov Sergey 16157 *************************************************************************/ 16158 void lrpack(/* Real */ ae_vector* v, 16165 _linearmodel_clear(lm); 16167 ae_vector_set_length(&lm->w, 4+nvars+1, _state); 16169 lm->w.ptr.p_double[0] = 4+nvars+1; 16170 lm->w.ptr.p_double[1] = linreg_lrvnum; 16171 lm->w.ptr.p_double[2] = nvars; 16172 lm->w.ptr.p_double[3] = offs; 16173 ae_v_move(&lm->w.ptr.p_double[offs], 1, &v->ptr.p_double[0], 1, ae_v_len(offs,offs+nvars)); 16177 /************************************************************************* 16182 X - input vector, array[0..NVars-1]. 16185 value of linear model regression estimate 16188 Copyright 03.09.2008 by Bochkanov Sergey 16189 *************************************************************************/ 16190 double lrprocess(linearmodel* lm, 16191 /* Real */ ae_vector* x, 16200 ae_assert(ae_round(lm->w.ptr.p_double[1], _state)==linreg_lrvnum, "LINREG: Incorrect LINREG version!
", _state); 16201 nvars = ae_round(lm->w.ptr.p_double[2], _state); 16202 offs = ae_round(lm->w.ptr.p_double[3], _state); 16203 v = ae_v_dotproduct(&x->ptr.p_double[0], 1, &lm->w.ptr.p_double[offs], 1, ae_v_len(0,nvars-1)); 16204 result = v+lm->w.ptr.p_double[offs+nvars]; 16209 /************************************************************************* 16210 RMS error on the test set 16215 NPoints - test set size 16218 root mean square error. 16221 Copyright 30.08.2008 by Bochkanov Sergey 16222 *************************************************************************/ 16223 double lrrmserror(linearmodel* lm, 16224 /* Real */ ae_matrix* xy, 16235 ae_assert(ae_round(lm->w.ptr.p_double[1], _state)==linreg_lrvnum, "LINREG: Incorrect LINREG version!
", _state); 16236 nvars = ae_round(lm->w.ptr.p_double[2], _state); 16237 offs = ae_round(lm->w.ptr.p_double[3], _state); 16239 for(i=0; i<=npoints-1; i++) 16241 v = ae_v_dotproduct(&xy->ptr.pp_double[i][0], 1, &lm->w.ptr.p_double[offs], 1, ae_v_len(0,nvars-1)); 16242 v = v+lm->w.ptr.p_double[offs+nvars]; 16243 result = result+ae_sqr(v-xy->ptr.pp_double[i][nvars], _state); 16245 result = ae_sqrt(result/npoints, _state); 16250 /************************************************************************* 16251 Average error on the test set 16256 NPoints - test set size 16262 Copyright 30.08.2008 by Bochkanov Sergey 16263 *************************************************************************/ 16264 double lravgerror(linearmodel* lm, 16265 /* Real */ ae_matrix* xy, 16276 ae_assert(ae_round(lm->w.ptr.p_double[1], _state)==linreg_lrvnum, "LINREG: Incorrect LINREG version!
", _state); 16277 nvars = ae_round(lm->w.ptr.p_double[2], _state); 16278 offs = ae_round(lm->w.ptr.p_double[3], _state); 16280 for(i=0; i<=npoints-1; i++) 16282 v = ae_v_dotproduct(&xy->ptr.pp_double[i][0], 1, &lm->w.ptr.p_double[offs], 1, ae_v_len(0,nvars-1)); 16283 v = v+lm->w.ptr.p_double[offs+nvars]; 16284 result = result+ae_fabs(v-xy->ptr.pp_double[i][nvars], _state); 16286 result = result/npoints; 16291 /************************************************************************* 16292 RMS error on the test set 16297 NPoints - test set size 16300 average relative error. 16303 Copyright 30.08.2008 by Bochkanov Sergey 16304 *************************************************************************/ 16305 double lravgrelerror(linearmodel* lm, 16306 /* Real */ ae_matrix* xy, 16318 ae_assert(ae_round(lm->w.ptr.p_double[1], _state)==linreg_lrvnum, "LINREG: Incorrect LINREG version!
", _state); 16319 nvars = ae_round(lm->w.ptr.p_double[2], _state); 16320 offs = ae_round(lm->w.ptr.p_double[3], _state); 16323 for(i=0; i<=npoints-1; i++) 16325 if( ae_fp_neq(xy->ptr.pp_double[i][nvars],0) ) 16327 v = ae_v_dotproduct(&xy->ptr.pp_double[i][0], 1, &lm->w.ptr.p_double[offs], 1, ae_v_len(0,nvars-1)); 16328 v = v+lm->w.ptr.p_double[offs+nvars]; 16329 result = result+ae_fabs((v-xy->ptr.pp_double[i][nvars])/xy->ptr.pp_double[i][nvars], _state); 16341 /************************************************************************* 16342 Copying of LinearModel strucure 16351 Copyright 15.03.2009 by Bochkanov Sergey 16352 *************************************************************************/ 16353 void lrcopy(linearmodel* lm1, linearmodel* lm2, ae_state *_state) 16357 _linearmodel_clear(lm2); 16359 k = ae_round(lm1->w.ptr.p_double[0], _state); 16360 ae_vector_set_length(&lm2->w, k-1+1, _state); 16361 ae_v_move(&lm2->w.ptr.p_double[0], 1, &lm1->w.ptr.p_double[0], 1, ae_v_len(0,k-1)); 16365 void lrlines(/* Real */ ae_matrix* xy, 16366 /* Real */ ae_vector* s, 16403 for(i=0; i<=n-1; i++) 16405 if( ae_fp_less_eq(s->ptr.p_double[i],0) ) 16414 * Calculate S, SX, SY, SXX 16420 for(i=0; i<=n-1; i++) 16422 t = ae_sqr(s->ptr.p_double[i], _state); 16424 sx = sx+xy->ptr.pp_double[i][0]/t; 16425 sy = sy+xy->ptr.pp_double[i][1]/t; 16426 sxx = sxx+ae_sqr(xy->ptr.pp_double[i][0], _state)/t; 16430 * Test for condition number 16432 t = ae_sqrt(4*ae_sqr(sx, _state)+ae_sqr(ss-sxx, _state), _state); 16433 e1 = 0.5*(ss+sxx+t); 16434 e2 = 0.5*(ss+sxx-t); 16435 if( ae_fp_less_eq(ae_minreal(e1, e2, _state),1000*ae_machineepsilon*ae_maxreal(e1, e2, _state)) ) 16447 for(i=0; i<=n-1; i++) 16449 t = (xy->ptr.pp_double[i][0]-sx/ss)/s->ptr.p_double[i]; 16450 *b = *b+t*xy->ptr.pp_double[i][1]/s->ptr.p_double[i]; 16451 stt = stt+ae_sqr(t, _state); 16454 *a = (sy-sx*(*b))/ss; 16457 * Calculate goodness-of-fit 16462 for(i=0; i<=n-1; i++) 16464 chi2 = chi2+ae_sqr((xy->ptr.pp_double[i][1]-(*a)-*b*xy->ptr.pp_double[i][0])/s->ptr.p_double[i], _state); 16466 *p = incompletegammac((double)(n-2)/(double)2, chi2/2, _state); 16474 * Calculate other parameters 16476 *vara = (1+ae_sqr(sx, _state)/(ss*stt))/ss; 16478 *covab = -sx/(ss*stt); 16479 *corrab = *covab/ae_sqrt(*vara*(*varb), _state); 16483 void lrline(/* Real */ ae_matrix* xy, 16490 ae_frame _frame_block; 16499 ae_frame_make(_state, &_frame_block); 16503 ae_vector_init(&s, 0, DT_REAL, _state, ae_true); 16508 ae_frame_leave(_state); 16511 ae_vector_set_length(&s, n-1+1, _state); 16512 for(i=0; i<=n-1; i++) 16514 s.ptr.p_double[i] = 1; 16516 lrlines(xy, &s, n, info, a, b, &vara, &varb, &covab, &corrab, &p, _state); 16517 ae_frame_leave(_state); 16521 /************************************************************************* 16522 Internal linear regression subroutine 16523 *************************************************************************/ 16524 static void linreg_lrinternal(/* Real */ ae_matrix* xy, 16525 /* Real */ ae_vector* s, 16533 ae_frame _frame_block; 16557 ae_frame_make(_state, &_frame_block); 16559 _linearmodel_clear(lm); 16560 _lrreport_clear(ar); 16561 ae_matrix_init(&a, 0, 0, DT_REAL, _state, ae_true); 16562 ae_matrix_init(&u, 0, 0, DT_REAL, _state, ae_true); 16563 ae_matrix_init(&vt, 0, 0, DT_REAL, _state, ae_true); 16564 ae_matrix_init(&vm, 0, 0, DT_REAL, _state, ae_true); 16565 ae_matrix_init(&xym, 0, 0, DT_REAL, _state, ae_true); 16566 ae_vector_init(&b, 0, DT_REAL, _state, ae_true); 16567 ae_vector_init(&sv, 0, DT_REAL, _state, ae_true); 16568 ae_vector_init(&t, 0, DT_REAL, _state, ae_true); 16569 ae_vector_init(&svi, 0, DT_REAL, _state, ae_true); 16570 ae_vector_init(&work, 0, DT_REAL, _state, ae_true); 16571 _lrreport_init(&ar2, _state, ae_true); 16572 _linearmodel_init(&tlm, _state, ae_true); 16577 * Check for errors in data 16579 if( npoints<nvars||nvars<1 ) 16582 ae_frame_leave(_state); 16585 for(i=0; i<=npoints-1; i++) 16587 if( ae_fp_less_eq(s->ptr.p_double[i],0) ) 16590 ae_frame_leave(_state); 16597 * Create design matrix 16599 ae_matrix_set_length(&a, npoints-1+1, nvars-1+1, _state); 16600 ae_vector_set_length(&b, npoints-1+1, _state); 16601 for(i=0; i<=npoints-1; i++) 16603 r = 1/s->ptr.p_double[i]; 16604 ae_v_moved(&a.ptr.pp_double[i][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1), r); 16605 b.ptr.p_double[i] = xy->ptr.pp_double[i][nvars]/s->ptr.p_double[i]; 16611 * W[1] version number, 0 16612 * W[2] NVars (minus 1, to be compatible with external representation) 16613 * W[3] coefficients offset 16615 ae_vector_set_length(&lm->w, 4+nvars-1+1, _state); 16617 lm->w.ptr.p_double[0] = 4+nvars; 16618 lm->w.ptr.p_double[1] = linreg_lrvnum; 16619 lm->w.ptr.p_double[2] = nvars-1; 16620 lm->w.ptr.p_double[3] = offs; 16623 * Solve problem using SVD: 16625 * 0. check for degeneracy (different types) 16626 * 1. A = U*diag(sv)*V' 16628 * 3. w = SUM((T[i]/sv[i])*V[..,i]) 16629 * 4. cov(wi,wj) = SUM(Vji*Vjk/sv[i]^2,K=1..M) 16631 * see $15.4 of "Numerical Recipes
in C
" for more information 16633 ae_vector_set_length(&t, nvars-1+1, _state); 16634 ae_vector_set_length(&svi, nvars-1+1, _state); 16635 ae_matrix_set_length(&ar->c, nvars-1+1, nvars-1+1, _state); 16636 ae_matrix_set_length(&vm, nvars-1+1, nvars-1+1, _state); 16637 if( !rmatrixsvd(&a, npoints, nvars, 1, 1, 2, &sv, &u, &vt, _state) ) 16640 ae_frame_leave(_state); 16643 if( ae_fp_less_eq(sv.ptr.p_double[0],0) ) 16647 * Degenerate case: zero design matrix. 16649 for(i=offs; i<=offs+nvars-1; i++) 16651 lm->w.ptr.p_double[i] = 0; 16653 ar->rmserror = lrrmserror(lm, xy, npoints, _state); 16654 ar->avgerror = lravgerror(lm, xy, npoints, _state); 16655 ar->avgrelerror = lravgrelerror(lm, xy, npoints, _state); 16656 ar->cvrmserror = ar->rmserror; 16657 ar->cvavgerror = ar->avgerror; 16658 ar->cvavgrelerror = ar->avgrelerror; 16659 ar->ncvdefects = 0; 16660 ae_vector_set_length(&ar->cvdefects, nvars-1+1, _state); 16661 ae_matrix_set_length(&ar->c, nvars-1+1, nvars-1+1, _state); 16662 for(i=0; i<=nvars-1; i++) 16664 for(j=0; j<=nvars-1; j++) 16666 ar->c.ptr.pp_double[i][j] = 0; 16669 ae_frame_leave(_state); 16672 if( ae_fp_less_eq(sv.ptr.p_double[nvars-1],epstol*ae_machineepsilon*sv.ptr.p_double[0]) ) 16676 * Degenerate case, non-zero design matrix. 16678 * We can leave it and solve task in SVD least squares fashion. 16679 * Solution and covariance matrix will be obtained correctly, 16680 * but CV error estimates - will not. It is better to reduce 16681 * it to non-degenerate task and to obtain correct CV estimates. 16683 for(k=nvars; k>=1; k--) 16685 if( ae_fp_greater(sv.ptr.p_double[k-1],epstol*ae_machineepsilon*sv.ptr.p_double[0]) ) 16691 ae_matrix_set_length(&xym, npoints-1+1, k+1, _state); 16692 for(i=0; i<=npoints-1; i++) 16694 for(j=0; j<=k-1; j++) 16696 r = ae_v_dotproduct(&xy->ptr.pp_double[i][0], 1, &vt.ptr.pp_double[j][0], 1, ae_v_len(0,nvars-1)); 16697 xym.ptr.pp_double[i][j] = r; 16699 xym.ptr.pp_double[i][k] = xy->ptr.pp_double[i][nvars]; 16705 linreg_lrinternal(&xym, s, npoints, k, info, &tlm, &ar2, _state); 16708 ae_frame_leave(_state); 16713 * Convert back to un-reduced format 16715 for(j=0; j<=nvars-1; j++) 16717 lm->w.ptr.p_double[offs+j] = 0; 16719 for(j=0; j<=k-1; j++) 16721 r = tlm.w.ptr.p_double[offs+j]; 16722 ae_v_addd(&lm->w.ptr.p_double[offs], 1, &vt.ptr.pp_double[j][0], 1, ae_v_len(offs,offs+nvars-1), r); 16724 ar->rmserror = ar2.rmserror; 16725 ar->avgerror = ar2.avgerror; 16726 ar->avgrelerror = ar2.avgrelerror; 16727 ar->cvrmserror = ar2.cvrmserror; 16728 ar->cvavgerror = ar2.cvavgerror; 16729 ar->cvavgrelerror = ar2.cvavgrelerror; 16730 ar->ncvdefects = ar2.ncvdefects; 16731 ae_vector_set_length(&ar->cvdefects, nvars-1+1, _state); 16732 for(j=0; j<=ar->ncvdefects-1; j++) 16734 ar->cvdefects.ptr.p_int[j] = ar2.cvdefects.ptr.p_int[j]; 16736 ae_matrix_set_length(&ar->c, nvars-1+1, nvars-1+1, _state); 16737 ae_vector_set_length(&work, nvars+1, _state); 16738 matrixmatrixmultiply(&ar2.c, 0, k-1, 0, k-1, ae_false, &vt, 0, k-1, 0, nvars-1, ae_false, 1.0, &vm, 0, k-1, 0, nvars-1, 0.0, &work, _state); 16739 matrixmatrixmultiply(&vt, 0, k-1, 0, nvars-1, ae_true, &vm, 0, k-1, 0, nvars-1, ae_false, 1.0, &ar->c, 0, nvars-1, 0, nvars-1, 0.0, &work, _state); 16740 ae_frame_leave(_state); 16745 ae_frame_leave(_state); 16748 for(i=0; i<=nvars-1; i++) 16750 if( ae_fp_greater(sv.ptr.p_double[i],epstol*ae_machineepsilon*sv.ptr.p_double[0]) ) 16752 svi.ptr.p_double[i] = 1/sv.ptr.p_double[i]; 16756 svi.ptr.p_double[i] = 0; 16759 for(i=0; i<=nvars-1; i++) 16761 t.ptr.p_double[i] = 0; 16763 for(i=0; i<=npoints-1; i++) 16765 r = b.ptr.p_double[i]; 16766 ae_v_addd(&t.ptr.p_double[0], 1, &u.ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1), r); 16768 for(i=0; i<=nvars-1; i++) 16770 lm->w.ptr.p_double[offs+i] = 0; 16772 for(i=0; i<=nvars-1; i++) 16774 r = t.ptr.p_double[i]*svi.ptr.p_double[i]; 16775 ae_v_addd(&lm->w.ptr.p_double[offs], 1, &vt.ptr.pp_double[i][0], 1, ae_v_len(offs,offs+nvars-1), r); 16777 for(j=0; j<=nvars-1; j++) 16779 r = svi.ptr.p_double[j]; 16780 ae_v_moved(&vm.ptr.pp_double[0][j], vm.stride, &vt.ptr.pp_double[j][0], 1, ae_v_len(0,nvars-1), r); 16782 for(i=0; i<=nvars-1; i++) 16784 for(j=i; j<=nvars-1; j++) 16786 r = ae_v_dotproduct(&vm.ptr.pp_double[i][0], 1, &vm.ptr.pp_double[j][0], 1, ae_v_len(0,nvars-1)); 16787 ar->c.ptr.pp_double[i][j] = r; 16788 ar->c.ptr.pp_double[j][i] = r; 16793 * Leave-1-out cross-validation error. 16797 * A*x = b original linear least squares task 16799 * ai i-th row of the A 16800 * bi i-th element of the b 16801 * xf solution of the original LLS task 16803 * Cross-validation error of i-th element from a sample is 16804 * calculated using following formula: 16806 * ERRi = ai*xf - (ai*xf-bi*(ui*ui'))/(1-ui*ui') (1) 16808 * This formula can be derived from normal equations of the 16811 * (A'*A)x = A'*b (2) 16813 * by applying modification (zeroing out i-th row of A) to (2): 16815 * (A-ai)'*(A-ai) = (A-ai)'*b 16817 * and using Sherman-Morrison formula for updating matrix inverse 16819 * NOTE 1: b is not zeroed out since it is much simpler and 16820 * does not influence final result. 16822 * NOTE 2: some design matrices A have such ui that 1-ui*ui'=0. 16823 * Formula (1) can't be applied for such cases and they are skipped 16824 * from CV calculation (which distorts resulting CV estimate). 16825 * But from the properties of U we can conclude that there can 16826 * be no more than NVars such vectors. Usually 16827 * NVars << NPoints, so in a normal case it only slightly 16828 * influences result. 16835 ar->avgrelerror = 0; 16836 ar->cvrmserror = 0; 16837 ar->cvavgerror = 0; 16838 ar->cvavgrelerror = 0; 16839 ar->ncvdefects = 0; 16840 ae_vector_set_length(&ar->cvdefects, nvars-1+1, _state); 16841 for(i=0; i<=npoints-1; i++) 16845 * Error on a training set 16847 r = ae_v_dotproduct(&xy->ptr.pp_double[i][0], 1, &lm->w.ptr.p_double[offs], 1, ae_v_len(0,nvars-1)); 16848 ar->rmserror = ar->rmserror+ae_sqr(r-xy->ptr.pp_double[i][nvars], _state); 16849 ar->avgerror = ar->avgerror+ae_fabs(r-xy->ptr.pp_double[i][nvars], _state); 16850 if( ae_fp_neq(xy->ptr.pp_double[i][nvars],0) ) 16852 ar->avgrelerror = ar->avgrelerror+ae_fabs((r-xy->ptr.pp_double[i][nvars])/xy->ptr.pp_double[i][nvars], _state); 16857 * Error using fast leave-one-out cross-validation 16859 p = ae_v_dotproduct(&u.ptr.pp_double[i][0], 1, &u.ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 16860 if( ae_fp_greater(p,1-epstol*ae_machineepsilon) ) 16862 ar->cvdefects.ptr.p_int[ar->ncvdefects] = i; 16863 ar->ncvdefects = ar->ncvdefects+1; 16866 r = s->ptr.p_double[i]*(r/s->ptr.p_double[i]-b.ptr.p_double[i]*p)/(1-p); 16867 ar->cvrmserror = ar->cvrmserror+ae_sqr(r-xy->ptr.pp_double[i][nvars], _state); 16868 ar->cvavgerror = ar->cvavgerror+ae_fabs(r-xy->ptr.pp_double[i][nvars], _state); 16869 if( ae_fp_neq(xy->ptr.pp_double[i][nvars],0) ) 16871 ar->cvavgrelerror = ar->cvavgrelerror+ae_fabs((r-xy->ptr.pp_double[i][nvars])/xy->ptr.pp_double[i][nvars], _state); 16880 * Something strange: ALL ui are degenerate. 16884 ae_frame_leave(_state); 16887 ar->rmserror = ae_sqrt(ar->rmserror/npoints, _state); 16888 ar->avgerror = ar->avgerror/npoints; 16891 ar->avgrelerror = ar->avgrelerror/na; 16893 ar->cvrmserror = ae_sqrt(ar->cvrmserror/ncv, _state); 16894 ar->cvavgerror = ar->cvavgerror/ncv; 16897 ar->cvavgrelerror = ar->cvavgrelerror/nacv; 16899 ae_frame_leave(_state); 16903 ae_bool _linearmodel_init(void* _p, ae_state *_state, ae_bool make_automatic) 16905 linearmodel *p = (linearmodel*)_p; 16906 ae_touch_ptr((void*)p); 16907 if( !ae_vector_init(&p->w, 0, DT_REAL, _state, make_automatic) ) 16913 ae_bool _linearmodel_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 16915 linearmodel *dst = (linearmodel*)_dst; 16916 linearmodel *src = (linearmodel*)_src; 16917 if( !ae_vector_init_copy(&dst->w, &src->w, _state, make_automatic) ) 16923 void _linearmodel_clear(void* _p) 16925 linearmodel *p = (linearmodel*)_p; 16926 ae_touch_ptr((void*)p); 16927 ae_vector_clear(&p->w); 16931 void _linearmodel_destroy(void* _p) 16933 linearmodel *p = (linearmodel*)_p; 16934 ae_touch_ptr((void*)p); 16935 ae_vector_destroy(&p->w); 16939 ae_bool _lrreport_init(void* _p, ae_state *_state, ae_bool make_automatic) 16941 lrreport *p = (lrreport*)_p; 16942 ae_touch_ptr((void*)p); 16943 if( !ae_matrix_init(&p->c, 0, 0, DT_REAL, _state, make_automatic) ) 16945 if( !ae_vector_init(&p->cvdefects, 0, DT_INT, _state, make_automatic) ) 16951 ae_bool _lrreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 16953 lrreport *dst = (lrreport*)_dst; 16954 lrreport *src = (lrreport*)_src; 16955 if( !ae_matrix_init_copy(&dst->c, &src->c, _state, make_automatic) ) 16957 dst->rmserror = src->rmserror; 16958 dst->avgerror = src->avgerror; 16959 dst->avgrelerror = src->avgrelerror; 16960 dst->cvrmserror = src->cvrmserror; 16961 dst->cvavgerror = src->cvavgerror; 16962 dst->cvavgrelerror = src->cvavgrelerror; 16963 dst->ncvdefects = src->ncvdefects; 16964 if( !ae_vector_init_copy(&dst->cvdefects, &src->cvdefects, _state, make_automatic) ) 16970 void _lrreport_clear(void* _p) 16972 lrreport *p = (lrreport*)_p; 16973 ae_touch_ptr((void*)p); 16974 ae_matrix_clear(&p->c); 16975 ae_vector_clear(&p->cvdefects); 16979 void _lrreport_destroy(void* _p) 16981 lrreport *p = (lrreport*)_p; 16982 ae_touch_ptr((void*)p); 16983 ae_matrix_destroy(&p->c); 16984 ae_vector_destroy(&p->cvdefects); 16990 /************************************************************************* 16991 Filters: simple moving averages (unsymmetric). 16993 This filter replaces array by results of SMA(K) filter. SMA(K) is defined 16994 as filter which averages at most K previous points (previous - not points 16995 AROUND central point) - or less, in case of the first K-1 points. 16998 X - array[N], array to process. It can be larger than N, 16999 in this case only first N points are processed. 17000 N - points count, N>=0 17001 K - K>=1 (K can be larger than N , such cases will be 17002 correctly handled). Window width. K=1 corresponds to 17003 identity transformation (nothing changes). 17006 X - array, whose first N elements were processed with SMA(K) 17008 NOTE 1: this function uses efficient in-place algorithm which does not 17009 allocate temporary arrays. 17011 NOTE 2: this algorithm makes only one pass through array and uses running 17012 sum to speed-up calculation of the averages. Additional measures 17013 are taken to ensure that running sum on a long sequence of zero 17014 elements will be correctly reset to zero even in the presence of 17017 NOTE 3: this is unsymmetric version of the algorithm, which does NOT 17018 averages points after the current one. Only X[i], X[i-1], ... are 17019 used when calculating new value of X[i]. We should also note that 17020 this algorithm uses BOTH previous points and current one, i.e. 17021 new value of X[i] depends on BOTH previous point and X[i] itself. 17024 Copyright 25.10.2011 by Bochkanov Sergey 17025 *************************************************************************/ 17026 void filtersma(/* Real */ ae_vector* x, 17034 ae_int_t zeroprefix; 17038 ae_assert(n>=0, "FilterSMA: N<0
", _state); 17039 ae_assert(x->cnt>=n, "FilterSMA: Length(X)<N
", _state); 17040 ae_assert(isfinitevector(x, n, _state), "FilterSMA: X contains
INF or NAN
", _state); 17041 ae_assert(k>=1, "FilterSMA:
K<1
", _state); 17044 * Quick exit, if necessary 17052 * Prepare variables (see below for explanation) 17056 for(i=ae_maxint(n-k, 0, _state); i<=n-1; i++) 17058 runningsum = runningsum+x->ptr.p_double[i]; 17059 termsinsum = termsinsum+1; 17061 i = ae_maxint(n-k, 0, _state); 17063 while(i<=n-1&&ae_fp_eq(x->ptr.p_double[i],0)) 17065 zeroprefix = zeroprefix+1; 17070 * General case: we assume that N>1 and K>1 17072 * Make one pass through all elements. At the beginning of 17073 * the iteration we have: 17074 * * I element being processed 17075 * * RunningSum current value of the running sum 17076 * (including I-th element) 17077 * * TermsInSum number of terms in sum, 0<=TermsInSum<=K 17078 * * ZeroPrefix length of the sequence of zero elements 17079 * which starts at X[I-K+1] and continues towards X[I]. 17080 * Equal to zero in case X[I-K+1] is non-zero. 17081 * This value is used to make RunningSum exactly zero 17082 * when it follows from the problem properties. 17084 for(i=n-1; i>=0; i--) 17088 * Store new value of X[i], save old value in V 17090 v = x->ptr.p_double[i]; 17091 x->ptr.p_double[i] = runningsum/termsinsum; 17094 * Update RunningSum and TermsInSum 17098 runningsum = runningsum-v+x->ptr.p_double[i-k]; 17102 runningsum = runningsum-v; 17103 termsinsum = termsinsum-1; 17107 * Update ZeroPrefix. 17108 * In case we have ZeroPrefix=TermsInSum, 17109 * RunningSum is reset to zero. 17113 if( ae_fp_neq(x->ptr.p_double[i-k],0) ) 17119 zeroprefix = ae_minint(zeroprefix+1, k, _state); 17124 zeroprefix = ae_minint(zeroprefix, i+1, _state); 17126 if( ae_fp_eq(zeroprefix,termsinsum) ) 17134 /************************************************************************* 17135 Filters: exponential moving averages. 17137 This filter replaces array by results of EMA(alpha) filter. EMA(alpha) is 17138 defined as filter which replaces X[] by S[]: 17140 S[t] = alpha*X[t] + (1-alpha)*S[t-1] 17143 X - array[N], array to process. It can be larger than N, 17144 in this case only first N points are processed. 17145 N - points count, N>=0 17146 alpha - 0<alpha<=1, smoothing parameter. 17149 X - array, whose first N elements were processed 17152 NOTE 1: this function uses efficient in-place algorithm which does not 17153 allocate temporary arrays. 17155 NOTE 2: this algorithm uses BOTH previous points and current one, i.e. 17156 new value of X[i] depends on BOTH previous point and X[i] itself. 17158 NOTE 3: technical analytis users quite often work with EMA coefficient 17159 expressed in DAYS instead of fractions. If you want to calculate 17160 EMA(N), where N is a number of days, you can use alpha=2/(N+1). 17163 Copyright 25.10.2011 by Bochkanov Sergey 17164 *************************************************************************/ 17165 void filterema(/* Real */ ae_vector* x, 17173 ae_assert(n>=0, "FilterEMA: N<0
", _state); 17174 ae_assert(x->cnt>=n, "FilterEMA: Length(X)<N
", _state); 17175 ae_assert(isfinitevector(x, n, _state), "FilterEMA: X contains
INF or NAN
", _state); 17176 ae_assert(ae_fp_greater(alpha,0), "FilterEMA: Alpha<=0
", _state); 17177 ae_assert(ae_fp_less_eq(alpha,1), "FilterEMA: Alpha>1
", _state); 17180 * Quick exit, if necessary 17182 if( n<=1||ae_fp_eq(alpha,1) ) 17190 for(i=1; i<=n-1; i++) 17192 x->ptr.p_double[i] = alpha*x->ptr.p_double[i]+(1-alpha)*x->ptr.p_double[i-1]; 17197 /************************************************************************* 17198 Filters: linear regression moving averages. 17200 This filter replaces array by results of LRMA(K) filter. 17202 LRMA(K) is defined as filter which, for each data point, builds linear 17203 regression model using K prevous points (point itself is included in 17204 these K points) and calculates value of this linear model at the point in 17208 X - array[N], array to process. It can be larger than N, 17209 in this case only first N points are processed. 17210 N - points count, N>=0 17211 K - K>=1 (K can be larger than N , such cases will be 17212 correctly handled). Window width. K=1 corresponds to 17213 identity transformation (nothing changes). 17216 X - array, whose first N elements were processed with SMA(K) 17218 NOTE 1: this function uses efficient in-place algorithm which does not 17219 allocate temporary arrays. 17221 NOTE 2: this algorithm makes only one pass through array and uses running 17222 sum to speed-up calculation of the averages. Additional measures 17223 are taken to ensure that running sum on a long sequence of zero 17224 elements will be correctly reset to zero even in the presence of 17227 NOTE 3: this is unsymmetric version of the algorithm, which does NOT 17228 averages points after the current one. Only X[i], X[i-1], ... are 17229 used when calculating new value of X[i]. We should also note that 17230 this algorithm uses BOTH previous points and current one, i.e. 17231 new value of X[i] depends on BOTH previous point and X[i] itself. 17234 Copyright 25.10.2011 by Bochkanov Sergey 17235 *************************************************************************/ 17236 void filterlrma(/* Real */ ae_vector* x, 17241 ae_frame _frame_block; 17255 ae_frame_make(_state, &_frame_block); 17256 ae_matrix_init(&xy, 0, 0, DT_REAL, _state, ae_true); 17257 ae_vector_init(&s, 0, DT_REAL, _state, ae_true); 17259 ae_assert(n>=0, "FilterLRMA: N<0
", _state); 17260 ae_assert(x->cnt>=n, "FilterLRMA: Length(X)<N
", _state); 17261 ae_assert(isfinitevector(x, n, _state), "FilterLRMA: X contains
INF or NAN
", _state); 17262 ae_assert(k>=1, "FilterLRMA:
K<1
", _state); 17265 * Quick exit, if necessary: 17266 * * either N is equal to 1 (nothing to average) 17267 * * or K is 1 (only point itself is used) or 2 (model is too simple, 17268 * we will always get identity transformation) 17272 ae_frame_leave(_state); 17277 * General case: K>2, N>1. 17278 * We do not process points with I<2 because first two points (I=0 and I=1) will be 17279 * left unmodified by LRMA filter in any case. 17281 ae_matrix_set_length(&xy, k, 2, _state); 17282 ae_vector_set_length(&s, k, _state); 17283 for(i=0; i<=k-1; i++) 17285 xy.ptr.pp_double[i][0] = i; 17286 s.ptr.p_double[i] = 1.0; 17288 for(i=n-1; i>=2; i--) 17290 m = ae_minint(i+1, k, _state); 17291 ae_v_move(&xy.ptr.pp_double[0][1], xy.stride, &x->ptr.p_double[i-m+1], 1, ae_v_len(0,m-1)); 17292 lrlines(&xy, &s, m, &info, &a, &b, &vara, &varb, &covab, &corrab, &p, _state); 17293 ae_assert(info==1, "FilterLRMA:
internal error", _state); 17294 x->ptr.p_double[i] = a+b*(m-1); 17296 ae_frame_leave(_state); 17302 /************************************************************************* 17303 Multiclass Fisher LDA 17305 Subroutine finds coefficients of linear combination which optimally separates 17306 training set on classes. 17309 XY - training set, array[0..NPoints-1,0..NVars]. 17310 First NVars columns store values of independent 17311 variables, next column stores number of class (from 0 17312 to NClasses-1) which dataset element belongs to. Fractional 17313 values are rounded to nearest integer. 17314 NPoints - training set size, NPoints>=0 17315 NVars - number of independent variables, NVars>=1 17316 NClasses - number of classes, NClasses>=2 17320 Info - return code: 17321 * -4, if internal EVD subroutine hasn't converged 17322 * -2, if there is a point with class number 17323 outside of [0..NClasses-1]. 17324 * -1, if incorrect parameters was passed (NPoints<0, 17325 NVars<1, NClasses<2) 17326 * 1, if task has been solved 17327 * 2, if there was a multicollinearity in training set, 17328 but task has been solved. 17329 W - linear combination coefficients, array[0..NVars-1] 17332 Copyright 31.05.2008 by Bochkanov Sergey 17333 *************************************************************************/ 17334 void fisherlda(/* Real */ ae_matrix* xy, 17339 /* Real */ ae_vector* w, 17342 ae_frame _frame_block; 17345 ae_frame_make(_state, &_frame_block); 17347 ae_vector_clear(w); 17348 ae_matrix_init(&w2, 0, 0, DT_REAL, _state, ae_true); 17350 fisherldan(xy, npoints, nvars, nclasses, info, &w2, _state); 17353 ae_vector_set_length(w, nvars-1+1, _state); 17354 ae_v_move(&w->ptr.p_double[0], 1, &w2.ptr.pp_double[0][0], w2.stride, ae_v_len(0,nvars-1)); 17356 ae_frame_leave(_state); 17360 /************************************************************************* 17361 N-dimensional multiclass Fisher LDA 17363 Subroutine finds coefficients of linear combinations which optimally separates 17364 training set on classes. It returns N-dimensional basis whose vector are sorted 17365 by quality of training set separation (in descending order). 17368 XY - training set, array[0..NPoints-1,0..NVars]. 17369 First NVars columns store values of independent 17370 variables, next column stores number of class (from 0 17371 to NClasses-1) which dataset element belongs to. Fractional 17372 values are rounded to nearest integer. 17373 NPoints - training set size, NPoints>=0 17374 NVars - number of independent variables, NVars>=1 17375 NClasses - number of classes, NClasses>=2 17379 Info - return code: 17380 * -4, if internal EVD subroutine hasn't converged 17381 * -2, if there is a point with class number 17382 outside of [0..NClasses-1]. 17383 * -1, if incorrect parameters was passed (NPoints<0, 17384 NVars<1, NClasses<2) 17385 * 1, if task has been solved 17386 * 2, if there was a multicollinearity in training set, 17387 but task has been solved. 17388 W - basis, array[0..NVars-1,0..NVars-1] 17389 columns of matrix stores basis vectors, sorted by 17390 quality of training set separation (in descending order) 17393 Copyright 31.05.2008 by Bochkanov Sergey 17394 *************************************************************************/ 17395 void fisherldan(/* Real */ ae_matrix* xy, 17400 /* Real */ ae_matrix* w, 17403 ae_frame _frame_block; 17427 ae_frame_make(_state, &_frame_block); 17429 ae_matrix_clear(w); 17430 ae_vector_init(&c, 0, DT_INT, _state, ae_true); 17431 ae_vector_init(&mu, 0, DT_REAL, _state, ae_true); 17432 ae_matrix_init(&muc, 0, 0, DT_REAL, _state, ae_true); 17433 ae_vector_init(&nc, 0, DT_INT, _state, ae_true); 17434 ae_matrix_init(&sw, 0, 0, DT_REAL, _state, ae_true); 17435 ae_matrix_init(&st, 0, 0, DT_REAL, _state, ae_true); 17436 ae_matrix_init(&z, 0, 0, DT_REAL, _state, ae_true); 17437 ae_matrix_init(&z2, 0, 0, DT_REAL, _state, ae_true); 17438 ae_matrix_init(&tm, 0, 0, DT_REAL, _state, ae_true); 17439 ae_matrix_init(&sbroot, 0, 0, DT_REAL, _state, ae_true); 17440 ae_matrix_init(&a, 0, 0, DT_REAL, _state, ae_true); 17441 ae_matrix_init(&xyproj, 0, 0, DT_REAL, _state, ae_true); 17442 ae_matrix_init(&wproj, 0, 0, DT_REAL, _state, ae_true); 17443 ae_vector_init(&tf, 0, DT_REAL, _state, ae_true); 17444 ae_vector_init(&d, 0, DT_REAL, _state, ae_true); 17445 ae_vector_init(&d2, 0, DT_REAL, _state, ae_true); 17446 ae_vector_init(&work, 0, DT_REAL, _state, ae_true); 17452 if( (npoints<0||nvars<1)||nclasses<2 ) 17455 ae_frame_leave(_state); 17458 for(i=0; i<=npoints-1; i++) 17460 if( ae_round(xy->ptr.pp_double[i][nvars], _state)<0||ae_round(xy->ptr.pp_double[i][nvars], _state)>=nclasses ) 17463 ae_frame_leave(_state); 17470 * Special case: NPoints<=1 17476 ae_matrix_set_length(w, nvars-1+1, nvars-1+1, _state); 17477 for(i=0; i<=nvars-1; i++) 17479 for(j=0; j<=nvars-1; j++) 17483 w->ptr.pp_double[i][j] = 1; 17487 w->ptr.pp_double[i][j] = 0; 17491 ae_frame_leave(_state); 17496 * Prepare temporaries 17498 ae_vector_set_length(&tf, nvars-1+1, _state); 17499 ae_vector_set_length(&work, ae_maxint(nvars, npoints, _state)+1, _state); 17502 * Convert class labels from reals to integers (just for convenience) 17504 ae_vector_set_length(&c, npoints-1+1, _state); 17505 for(i=0; i<=npoints-1; i++) 17507 c.ptr.p_int[i] = ae_round(xy->ptr.pp_double[i][nvars], _state); 17511 * Calculate class sizes and means 17513 ae_vector_set_length(&mu, nvars-1+1, _state); 17514 ae_matrix_set_length(&muc, nclasses-1+1, nvars-1+1, _state); 17515 ae_vector_set_length(&nc, nclasses-1+1, _state); 17516 for(j=0; j<=nvars-1; j++) 17518 mu.ptr.p_double[j] = 0; 17520 for(i=0; i<=nclasses-1; i++) 17522 nc.ptr.p_int[i] = 0; 17523 for(j=0; j<=nvars-1; j++) 17525 muc.ptr.pp_double[i][j] = 0; 17528 for(i=0; i<=npoints-1; i++) 17530 ae_v_add(&mu.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 17531 ae_v_add(&muc.ptr.pp_double[c.ptr.p_int[i]][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 17532 nc.ptr.p_int[c.ptr.p_int[i]] = nc.ptr.p_int[c.ptr.p_int[i]]+1; 17534 for(i=0; i<=nclasses-1; i++) 17536 v = (double)1/(double)nc.ptr.p_int[i]; 17537 ae_v_muld(&muc.ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1), v); 17539 v = (double)1/(double)npoints; 17540 ae_v_muld(&mu.ptr.p_double[0], 1, ae_v_len(0,nvars-1), v); 17545 ae_matrix_set_length(&st, nvars-1+1, nvars-1+1, _state); 17546 for(i=0; i<=nvars-1; i++) 17548 for(j=0; j<=nvars-1; j++) 17550 st.ptr.pp_double[i][j] = 0; 17553 for(k=0; k<=npoints-1; k++) 17555 ae_v_move(&tf.ptr.p_double[0], 1, &xy->ptr.pp_double[k][0], 1, ae_v_len(0,nvars-1)); 17556 ae_v_sub(&tf.ptr.p_double[0], 1, &mu.ptr.p_double[0], 1, ae_v_len(0,nvars-1)); 17557 for(i=0; i<=nvars-1; i++) 17559 v = tf.ptr.p_double[i]; 17560 ae_v_addd(&st.ptr.pp_double[i][0], 1, &tf.ptr.p_double[0], 1, ae_v_len(0,nvars-1), v); 17567 ae_matrix_set_length(&sw, nvars-1+1, nvars-1+1, _state); 17568 for(i=0; i<=nvars-1; i++) 17570 for(j=0; j<=nvars-1; j++) 17572 sw.ptr.pp_double[i][j] = 0; 17575 for(k=0; k<=npoints-1; k++) 17577 ae_v_move(&tf.ptr.p_double[0], 1, &xy->ptr.pp_double[k][0], 1, ae_v_len(0,nvars-1)); 17578 ae_v_sub(&tf.ptr.p_double[0], 1, &muc.ptr.pp_double[c.ptr.p_int[k]][0], 1, ae_v_len(0,nvars-1)); 17579 for(i=0; i<=nvars-1; i++) 17581 v = tf.ptr.p_double[i]; 17582 ae_v_addd(&sw.ptr.pp_double[i][0], 1, &tf.ptr.p_double[0], 1, ae_v_len(0,nvars-1), v); 17587 * Maximize ratio J=(w'*ST*w)/(w'*SW*w). 17589 * First, make transition from w to v such that w'*ST*w becomes v'*v: 17590 * v = root(ST)*w = R*w 17592 * w = (root(ST)^-1)*v = RI*v 17593 * RI = Z*inv(root(D)) 17594 * J = (v'*v)/(v'*(RI'*SW*RI)*v) 17599 * J = (v'*v) / (v'*(inv(root(D))*Z'*SW*Z*inv(root(D)))*v) = 17600 * = (v'*v) / (v'*A*v) 17602 if( !smatrixevd(&st, nvars, 1, ae_true, &d, &z, _state) ) 17605 ae_frame_leave(_state); 17608 ae_matrix_set_length(w, nvars-1+1, nvars-1+1, _state); 17609 if( ae_fp_less_eq(d.ptr.p_double[nvars-1],0)||ae_fp_less_eq(d.ptr.p_double[0],1000*ae_machineepsilon*d.ptr.p_double[nvars-1]) ) 17613 * Special case: D[NVars-1]<=0 17614 * Degenerate task (all variables takes the same value). 17616 if( ae_fp_less_eq(d.ptr.p_double[nvars-1],0) ) 17619 for(i=0; i<=nvars-1; i++) 17621 for(j=0; j<=nvars-1; j++) 17625 w->ptr.pp_double[i][j] = 1; 17629 w->ptr.pp_double[i][j] = 0; 17633 ae_frame_leave(_state); 17638 * Special case: degenerate ST matrix, multicollinearity found. 17639 * Since we know ST eigenvalues/vectors we can translate task to 17640 * non-degenerate form. 17642 * Let WG is orthogonal basis of the non zero variance subspace 17643 * of the ST and let WZ is orthogonal basis of the zero variance 17646 * Projection on WG allows us to use LDA on reduced M-dimensional 17647 * subspace, N-M vectors of WZ allows us to update reduced LDA 17648 * factors to full N-dimensional subspace. 17651 for(k=0; k<=nvars-1; k++) 17653 if( ae_fp_less_eq(d.ptr.p_double[k],1000*ae_machineepsilon*d.ptr.p_double[nvars-1]) ) 17658 ae_assert(m!=0, "FisherLDAN:
internal error #1
", _state); 17659 ae_matrix_set_length(&xyproj, npoints-1+1, nvars-m+1, _state); 17660 matrixmatrixmultiply(xy, 0, npoints-1, 0, nvars-1, ae_false, &z, 0, nvars-1, m, nvars-1, ae_false, 1.0, &xyproj, 0, npoints-1, 0, nvars-m-1, 0.0, &work, _state); 17661 for(i=0; i<=npoints-1; i++) 17663 xyproj.ptr.pp_double[i][nvars-m] = xy->ptr.pp_double[i][nvars]; 17665 fisherldan(&xyproj, npoints, nvars-m, nclasses, info, &wproj, _state); 17668 ae_frame_leave(_state); 17671 matrixmatrixmultiply(&z, 0, nvars-1, m, nvars-1, ae_false, &wproj, 0, nvars-m-1, 0, nvars-m-1, ae_false, 1.0, w, 0, nvars-1, 0, nvars-m-1, 0.0, &work, _state); 17672 for(k=nvars-m; k<=nvars-1; k++) 17674 ae_v_move(&w->ptr.pp_double[0][k], w->stride, &z.ptr.pp_double[0][k-(nvars-m)], z.stride, ae_v_len(0,nvars-1)); 17682 * General case: no multicollinearity 17684 ae_matrix_set_length(&tm, nvars-1+1, nvars-1+1, _state); 17685 ae_matrix_set_length(&a, nvars-1+1, nvars-1+1, _state); 17686 matrixmatrixmultiply(&sw, 0, nvars-1, 0, nvars-1, ae_false, &z, 0, nvars-1, 0, nvars-1, ae_false, 1.0, &tm, 0, nvars-1, 0, nvars-1, 0.0, &work, _state); 17687 matrixmatrixmultiply(&z, 0, nvars-1, 0, nvars-1, ae_true, &tm, 0, nvars-1, 0, nvars-1, ae_false, 1.0, &a, 0, nvars-1, 0, nvars-1, 0.0, &work, _state); 17688 for(i=0; i<=nvars-1; i++) 17690 for(j=0; j<=nvars-1; j++) 17692 a.ptr.pp_double[i][j] = a.ptr.pp_double[i][j]/ae_sqrt(d.ptr.p_double[i]*d.ptr.p_double[j], _state); 17695 if( !smatrixevd(&a, nvars, 1, ae_true, &d2, &z2, _state) ) 17698 ae_frame_leave(_state); 17701 for(k=0; k<=nvars-1; k++) 17703 for(i=0; i<=nvars-1; i++) 17705 tf.ptr.p_double[i] = z2.ptr.pp_double[i][k]/ae_sqrt(d.ptr.p_double[i], _state); 17707 for(i=0; i<=nvars-1; i++) 17709 v = ae_v_dotproduct(&z.ptr.pp_double[i][0], 1, &tf.ptr.p_double[0], 1, ae_v_len(0,nvars-1)); 17710 w->ptr.pp_double[i][k] = v; 17718 * * converting to non-negative form, if possible 17720 for(k=0; k<=nvars-1; k++) 17722 v = ae_v_dotproduct(&w->ptr.pp_double[0][k], w->stride, &w->ptr.pp_double[0][k], w->stride, ae_v_len(0,nvars-1)); 17723 v = 1/ae_sqrt(v, _state); 17724 ae_v_muld(&w->ptr.pp_double[0][k], w->stride, ae_v_len(0,nvars-1), v); 17726 for(i=0; i<=nvars-1; i++) 17728 v = v+w->ptr.pp_double[i][k]; 17730 if( ae_fp_less(v,0) ) 17732 ae_v_muld(&w->ptr.pp_double[0][k], w->stride, ae_v_len(0,nvars-1), -1); 17735 ae_frame_leave(_state); 17741 /************************************************************************* 17742 This function returns number of weights updates which is required for 17743 gradient calculation problem to be splitted. 17744 *************************************************************************/ 17745 ae_int_t mlpgradsplitcost(ae_state *_state) 17750 result = mlpbase_gradbasecasecost; 17755 /************************************************************************* 17756 This function returns number of elements in subset of dataset which is 17757 required for gradient calculation problem to be splitted. 17758 *************************************************************************/ 17759 ae_int_t mlpgradsplitsize(ae_state *_state) 17764 result = mlpbase_microbatchsize; 17769 /************************************************************************* 17770 Creates neural network with NIn inputs, NOut outputs, without hidden 17771 layers, with linear output layer. Network weights are filled with small 17775 Copyright 04.11.2007 by Bochkanov Sergey 17776 *************************************************************************/ 17777 void mlpcreate0(ae_int_t nin, 17779 multilayerperceptron* network, 17782 ae_frame _frame_block; 17785 ae_vector lconnfirst; 17786 ae_vector lconnlast; 17787 ae_int_t layerscount; 17790 ae_frame_make(_state, &_frame_block); 17791 _multilayerperceptron_clear(network); 17792 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 17793 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 17794 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 17795 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 17802 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 17803 ae_vector_set_length(<ypes, layerscount-1+1, _state); 17804 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 17805 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 17810 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17811 mlpbase_addbiasedsummatorlayer(nout, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17812 mlpbase_addactivationlayer(-5, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17817 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_false, network, _state); 17818 mlpbase_fillhighlevelinformation(network, nin, 0, 0, nout, ae_false, ae_true, _state); 17819 ae_frame_leave(_state); 17823 /************************************************************************* 17824 Same as MLPCreate0, but with one hidden layer (NHid neurons) with 17825 non-linear activation function. Output layer is linear. 17828 Copyright 04.11.2007 by Bochkanov Sergey 17829 *************************************************************************/ 17830 void mlpcreate1(ae_int_t nin, 17833 multilayerperceptron* network, 17836 ae_frame _frame_block; 17839 ae_vector lconnfirst; 17840 ae_vector lconnlast; 17841 ae_int_t layerscount; 17844 ae_frame_make(_state, &_frame_block); 17845 _multilayerperceptron_clear(network); 17846 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 17847 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 17848 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 17849 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 17851 layerscount = 1+3+3; 17856 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 17857 ae_vector_set_length(<ypes, layerscount-1+1, _state); 17858 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 17859 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 17864 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17865 mlpbase_addbiasedsummatorlayer(nhid, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17866 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17867 mlpbase_addbiasedsummatorlayer(nout, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17868 mlpbase_addactivationlayer(-5, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17873 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_false, network, _state); 17874 mlpbase_fillhighlevelinformation(network, nin, nhid, 0, nout, ae_false, ae_true, _state); 17875 ae_frame_leave(_state); 17879 /************************************************************************* 17880 Same as MLPCreate0, but with two hidden layers (NHid1 and NHid2 neurons) 17881 with non-linear activation function. Output layer is linear. 17885 Copyright 04.11.2007 by Bochkanov Sergey 17886 *************************************************************************/ 17887 void mlpcreate2(ae_int_t nin, 17891 multilayerperceptron* network, 17894 ae_frame _frame_block; 17897 ae_vector lconnfirst; 17898 ae_vector lconnlast; 17899 ae_int_t layerscount; 17902 ae_frame_make(_state, &_frame_block); 17903 _multilayerperceptron_clear(network); 17904 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 17905 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 17906 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 17907 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 17909 layerscount = 1+3+3+3; 17914 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 17915 ae_vector_set_length(<ypes, layerscount-1+1, _state); 17916 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 17917 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 17922 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17923 mlpbase_addbiasedsummatorlayer(nhid1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17924 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17925 mlpbase_addbiasedsummatorlayer(nhid2, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17926 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17927 mlpbase_addbiasedsummatorlayer(nout, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17928 mlpbase_addactivationlayer(-5, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 17933 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_false, network, _state); 17934 mlpbase_fillhighlevelinformation(network, nin, nhid1, nhid2, nout, ae_false, ae_true, _state); 17935 ae_frame_leave(_state); 17939 /************************************************************************* 17940 Creates neural network with NIn inputs, NOut outputs, without hidden 17941 layers with non-linear output layer. Network weights are filled with small 17944 Activation function of the output layer takes values: 17954 Copyright 30.03.2008 by Bochkanov Sergey 17955 *************************************************************************/ 17956 void mlpcreateb0(ae_int_t nin, 17960 multilayerperceptron* network, 17963 ae_frame _frame_block; 17966 ae_vector lconnfirst; 17967 ae_vector lconnlast; 17968 ae_int_t layerscount; 17972 ae_frame_make(_state, &_frame_block); 17973 _multilayerperceptron_clear(network); 17974 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 17975 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 17976 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 17977 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 17980 if( ae_fp_greater_eq(d,0) ) 17992 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 17993 ae_vector_set_length(<ypes, layerscount-1+1, _state); 17994 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 17995 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 18000 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18001 mlpbase_addbiasedsummatorlayer(nout, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18002 mlpbase_addactivationlayer(3, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18007 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_false, network, _state); 18008 mlpbase_fillhighlevelinformation(network, nin, 0, 0, nout, ae_false, ae_false, _state); 18011 * Turn on ouputs shift/scaling. 18013 for(i=nin; i<=nin+nout-1; i++) 18015 network->columnmeans.ptr.p_double[i] = b; 18016 network->columnsigmas.ptr.p_double[i] = d; 18018 ae_frame_leave(_state); 18022 /************************************************************************* 18023 Same as MLPCreateB0 but with non-linear hidden layer. 18026 Copyright 30.03.2008 by Bochkanov Sergey 18027 *************************************************************************/ 18028 void mlpcreateb1(ae_int_t nin, 18033 multilayerperceptron* network, 18036 ae_frame _frame_block; 18039 ae_vector lconnfirst; 18040 ae_vector lconnlast; 18041 ae_int_t layerscount; 18045 ae_frame_make(_state, &_frame_block); 18046 _multilayerperceptron_clear(network); 18047 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 18048 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 18049 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 18050 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 18052 layerscount = 1+3+3; 18053 if( ae_fp_greater_eq(d,0) ) 18065 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 18066 ae_vector_set_length(<ypes, layerscount-1+1, _state); 18067 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 18068 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 18073 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18074 mlpbase_addbiasedsummatorlayer(nhid, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18075 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18076 mlpbase_addbiasedsummatorlayer(nout, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18077 mlpbase_addactivationlayer(3, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18082 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_false, network, _state); 18083 mlpbase_fillhighlevelinformation(network, nin, nhid, 0, nout, ae_false, ae_false, _state); 18086 * Turn on ouputs shift/scaling. 18088 for(i=nin; i<=nin+nout-1; i++) 18090 network->columnmeans.ptr.p_double[i] = b; 18091 network->columnsigmas.ptr.p_double[i] = d; 18093 ae_frame_leave(_state); 18097 /************************************************************************* 18098 Same as MLPCreateB0 but with two non-linear hidden layers. 18101 Copyright 30.03.2008 by Bochkanov Sergey 18102 *************************************************************************/ 18103 void mlpcreateb2(ae_int_t nin, 18109 multilayerperceptron* network, 18112 ae_frame _frame_block; 18115 ae_vector lconnfirst; 18116 ae_vector lconnlast; 18117 ae_int_t layerscount; 18121 ae_frame_make(_state, &_frame_block); 18122 _multilayerperceptron_clear(network); 18123 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 18124 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 18125 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 18126 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 18128 layerscount = 1+3+3+3; 18129 if( ae_fp_greater_eq(d,0) ) 18141 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 18142 ae_vector_set_length(<ypes, layerscount-1+1, _state); 18143 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 18144 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 18149 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18150 mlpbase_addbiasedsummatorlayer(nhid1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18151 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18152 mlpbase_addbiasedsummatorlayer(nhid2, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18153 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18154 mlpbase_addbiasedsummatorlayer(nout, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18155 mlpbase_addactivationlayer(3, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18160 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_false, network, _state); 18161 mlpbase_fillhighlevelinformation(network, nin, nhid1, nhid2, nout, ae_false, ae_false, _state); 18164 * Turn on ouputs shift/scaling. 18166 for(i=nin; i<=nin+nout-1; i++) 18168 network->columnmeans.ptr.p_double[i] = b; 18169 network->columnsigmas.ptr.p_double[i] = d; 18171 ae_frame_leave(_state); 18175 /************************************************************************* 18176 Creates neural network with NIn inputs, NOut outputs, without hidden 18177 layers with non-linear output layer. Network weights are filled with small 18178 random values. Activation function of the output layer takes values [A,B]. 18181 Copyright 30.03.2008 by Bochkanov Sergey 18182 *************************************************************************/ 18183 void mlpcreater0(ae_int_t nin, 18187 multilayerperceptron* network, 18190 ae_frame _frame_block; 18193 ae_vector lconnfirst; 18194 ae_vector lconnlast; 18195 ae_int_t layerscount; 18199 ae_frame_make(_state, &_frame_block); 18200 _multilayerperceptron_clear(network); 18201 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 18202 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 18203 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 18204 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 18211 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 18212 ae_vector_set_length(<ypes, layerscount-1+1, _state); 18213 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 18214 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 18219 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18220 mlpbase_addbiasedsummatorlayer(nout, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18221 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18226 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_false, network, _state); 18227 mlpbase_fillhighlevelinformation(network, nin, 0, 0, nout, ae_false, ae_false, _state); 18230 * Turn on outputs shift/scaling. 18232 for(i=nin; i<=nin+nout-1; i++) 18234 network->columnmeans.ptr.p_double[i] = 0.5*(a+b); 18235 network->columnsigmas.ptr.p_double[i] = 0.5*(a-b); 18237 ae_frame_leave(_state); 18241 /************************************************************************* 18242 Same as MLPCreateR0, but with non-linear hidden layer. 18245 Copyright 30.03.2008 by Bochkanov Sergey 18246 *************************************************************************/ 18247 void mlpcreater1(ae_int_t nin, 18252 multilayerperceptron* network, 18255 ae_frame _frame_block; 18258 ae_vector lconnfirst; 18259 ae_vector lconnlast; 18260 ae_int_t layerscount; 18264 ae_frame_make(_state, &_frame_block); 18265 _multilayerperceptron_clear(network); 18266 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 18267 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 18268 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 18269 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 18271 layerscount = 1+3+3; 18276 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 18277 ae_vector_set_length(<ypes, layerscount-1+1, _state); 18278 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 18279 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 18284 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18285 mlpbase_addbiasedsummatorlayer(nhid, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18286 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18287 mlpbase_addbiasedsummatorlayer(nout, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18288 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18293 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_false, network, _state); 18294 mlpbase_fillhighlevelinformation(network, nin, nhid, 0, nout, ae_false, ae_false, _state); 18297 * Turn on outputs shift/scaling. 18299 for(i=nin; i<=nin+nout-1; i++) 18301 network->columnmeans.ptr.p_double[i] = 0.5*(a+b); 18302 network->columnsigmas.ptr.p_double[i] = 0.5*(a-b); 18304 ae_frame_leave(_state); 18308 /************************************************************************* 18309 Same as MLPCreateR0, but with two non-linear hidden layers. 18312 Copyright 30.03.2008 by Bochkanov Sergey 18313 *************************************************************************/ 18314 void mlpcreater2(ae_int_t nin, 18320 multilayerperceptron* network, 18323 ae_frame _frame_block; 18326 ae_vector lconnfirst; 18327 ae_vector lconnlast; 18328 ae_int_t layerscount; 18332 ae_frame_make(_state, &_frame_block); 18333 _multilayerperceptron_clear(network); 18334 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 18335 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 18336 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 18337 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 18339 layerscount = 1+3+3+3; 18344 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 18345 ae_vector_set_length(<ypes, layerscount-1+1, _state); 18346 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 18347 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 18352 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18353 mlpbase_addbiasedsummatorlayer(nhid1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18354 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18355 mlpbase_addbiasedsummatorlayer(nhid2, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18356 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18357 mlpbase_addbiasedsummatorlayer(nout, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18358 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18363 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_false, network, _state); 18364 mlpbase_fillhighlevelinformation(network, nin, nhid1, nhid2, nout, ae_false, ae_false, _state); 18367 * Turn on outputs shift/scaling. 18369 for(i=nin; i<=nin+nout-1; i++) 18371 network->columnmeans.ptr.p_double[i] = 0.5*(a+b); 18372 network->columnsigmas.ptr.p_double[i] = 0.5*(a-b); 18374 ae_frame_leave(_state); 18378 /************************************************************************* 18379 Creates classifier network with NIn inputs and NOut possible classes. 18380 Network contains no hidden layers and linear output layer with SOFTMAX- 18381 normalization (so outputs sums up to 1.0 and converge to posterior 18385 Copyright 04.11.2007 by Bochkanov Sergey 18386 *************************************************************************/ 18387 void mlpcreatec0(ae_int_t nin, 18389 multilayerperceptron* network, 18392 ae_frame _frame_block; 18395 ae_vector lconnfirst; 18396 ae_vector lconnlast; 18397 ae_int_t layerscount; 18400 ae_frame_make(_state, &_frame_block); 18401 _multilayerperceptron_clear(network); 18402 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 18403 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 18404 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 18405 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 18407 ae_assert(nout>=2, "MLPCreateC0: NOut<2!
", _state); 18408 layerscount = 1+2+1; 18413 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 18414 ae_vector_set_length(<ypes, layerscount-1+1, _state); 18415 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 18416 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 18421 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18422 mlpbase_addbiasedsummatorlayer(nout-1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18423 mlpbase_addzerolayer(&lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18428 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_true, network, _state); 18429 mlpbase_fillhighlevelinformation(network, nin, 0, 0, nout, ae_true, ae_true, _state); 18430 ae_frame_leave(_state); 18434 /************************************************************************* 18435 Same as MLPCreateC0, but with one non-linear hidden layer. 18438 Copyright 04.11.2007 by Bochkanov Sergey 18439 *************************************************************************/ 18440 void mlpcreatec1(ae_int_t nin, 18443 multilayerperceptron* network, 18446 ae_frame _frame_block; 18449 ae_vector lconnfirst; 18450 ae_vector lconnlast; 18451 ae_int_t layerscount; 18454 ae_frame_make(_state, &_frame_block); 18455 _multilayerperceptron_clear(network); 18456 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 18457 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 18458 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 18459 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 18461 ae_assert(nout>=2, "MLPCreateC1: NOut<2!
", _state); 18462 layerscount = 1+3+2+1; 18467 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 18468 ae_vector_set_length(<ypes, layerscount-1+1, _state); 18469 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 18470 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 18475 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18476 mlpbase_addbiasedsummatorlayer(nhid, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18477 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18478 mlpbase_addbiasedsummatorlayer(nout-1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18479 mlpbase_addzerolayer(&lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18484 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_true, network, _state); 18485 mlpbase_fillhighlevelinformation(network, nin, nhid, 0, nout, ae_true, ae_true, _state); 18486 ae_frame_leave(_state); 18490 /************************************************************************* 18491 Same as MLPCreateC0, but with two non-linear hidden layers. 18494 Copyright 04.11.2007 by Bochkanov Sergey 18495 *************************************************************************/ 18496 void mlpcreatec2(ae_int_t nin, 18500 multilayerperceptron* network, 18503 ae_frame _frame_block; 18506 ae_vector lconnfirst; 18507 ae_vector lconnlast; 18508 ae_int_t layerscount; 18511 ae_frame_make(_state, &_frame_block); 18512 _multilayerperceptron_clear(network); 18513 ae_vector_init(&lsizes, 0, DT_INT, _state, ae_true); 18514 ae_vector_init(<ypes, 0, DT_INT, _state, ae_true); 18515 ae_vector_init(&lconnfirst, 0, DT_INT, _state, ae_true); 18516 ae_vector_init(&lconnlast, 0, DT_INT, _state, ae_true); 18518 ae_assert(nout>=2, "MLPCreateC2: NOut<2!
", _state); 18519 layerscount = 1+3+3+2+1; 18524 ae_vector_set_length(&lsizes, layerscount-1+1, _state); 18525 ae_vector_set_length(<ypes, layerscount-1+1, _state); 18526 ae_vector_set_length(&lconnfirst, layerscount-1+1, _state); 18527 ae_vector_set_length(&lconnlast, layerscount-1+1, _state); 18532 mlpbase_addinputlayer(nin, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18533 mlpbase_addbiasedsummatorlayer(nhid1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18534 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18535 mlpbase_addbiasedsummatorlayer(nhid2, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18536 mlpbase_addactivationlayer(1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18537 mlpbase_addbiasedsummatorlayer(nout-1, &lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18538 mlpbase_addzerolayer(&lsizes, <ypes, &lconnfirst, &lconnlast, &lastproc, _state); 18543 mlpbase_mlpcreate(nin, nout, &lsizes, <ypes, &lconnfirst, &lconnlast, layerscount, ae_true, network, _state); 18544 mlpbase_fillhighlevelinformation(network, nin, nhid1, nhid2, nout, ae_true, ae_true, _state); 18545 ae_frame_leave(_state); 18549 /************************************************************************* 18550 Copying of neural network 18553 Network1 - original 18559 Copyright 04.11.2007 by Bochkanov Sergey 18560 *************************************************************************/ 18561 void mlpcopy(multilayerperceptron* network1, 18562 multilayerperceptron* network2, 18566 _multilayerperceptron_clear(network2); 18568 mlpcopyshared(network1, network2, _state); 18572 /************************************************************************* 18573 Copying of neural network (second parameter is passed as shared object). 18576 Network1 - original 18582 Copyright 04.11.2007 by Bochkanov Sergey 18583 *************************************************************************/ 18584 void mlpcopyshared(multilayerperceptron* network1, 18585 multilayerperceptron* network2, 18588 ae_frame _frame_block; 18594 ae_frame_make(_state, &_frame_block); 18595 _mlpbuffers_init(&buf, _state, ae_true); 18596 _smlpgrad_init(&sgrad, _state, ae_true); 18600 * Copy scalar and array fields 18602 network2->hlnetworktype = network1->hlnetworktype; 18603 network2->hlnormtype = network1->hlnormtype; 18604 copyintegerarray(&network1->hllayersizes, &network2->hllayersizes, _state); 18605 copyintegerarray(&network1->hlconnections, &network2->hlconnections, _state); 18606 copyintegerarray(&network1->hlneurons, &network2->hlneurons, _state); 18607 copyintegerarray(&network1->structinfo, &network2->structinfo, _state); 18608 copyrealarray(&network1->weights, &network2->weights, _state); 18609 copyrealarray(&network1->columnmeans, &network2->columnmeans, _state); 18610 copyrealarray(&network1->columnsigmas, &network2->columnsigmas, _state); 18611 copyrealarray(&network1->neurons, &network2->neurons, _state); 18612 copyrealarray(&network1->dfdnet, &network2->dfdnet, _state); 18613 copyrealarray(&network1->derror, &network2->derror, _state); 18614 copyrealarray(&network1->x, &network2->x, _state); 18615 copyrealarray(&network1->y, &network2->y, _state); 18616 copyrealarray(&network1->nwbuf, &network2->nwbuf, _state); 18617 copyintegerarray(&network1->integerbuf, &network2->integerbuf, _state); 18622 wcount = mlpgetweightscount(network1, _state); 18623 ae_shared_pool_set_seed(&network2->buf, &buf, sizeof(buf), _mlpbuffers_init, _mlpbuffers_init_copy, _mlpbuffers_destroy, _state); 18624 ae_vector_set_length(&sgrad.g, wcount, _state); 18626 for(i=0; i<=wcount-1; i++) 18628 sgrad.g.ptr.p_double[i] = 0.0; 18630 ae_shared_pool_set_seed(&network2->gradbuf, &sgrad, sizeof(sgrad), _smlpgrad_init, _smlpgrad_init_copy, _smlpgrad_destroy, _state); 18631 ae_frame_leave(_state); 18635 /************************************************************************* 18636 This function compares architectures of neural networks. Only geometries 18637 are compared, weights and other parameters are not tested. 18640 Copyright 20.06.2013 by Bochkanov Sergey 18641 *************************************************************************/ 18642 ae_bool mlpsamearchitecture(multilayerperceptron* network1, 18643 multilayerperceptron* network2, 18651 ae_assert(network1->structinfo.cnt>0&&network1->structinfo.cnt>=network1->structinfo.ptr.p_int[0], "MLPSameArchitecture: Network1 is uninitialized
", _state); 18652 ae_assert(network2->structinfo.cnt>0&&network2->structinfo.cnt>=network2->structinfo.ptr.p_int[0], "MLPSameArchitecture: Network2 is uninitialized
", _state); 18654 if( network1->structinfo.ptr.p_int[0]!=network2->structinfo.ptr.p_int[0] ) 18658 ninfo = network1->structinfo.ptr.p_int[0]; 18659 for(i=0; i<=ninfo-1; i++) 18661 if( network1->structinfo.ptr.p_int[i]!=network2->structinfo.ptr.p_int[i] ) 18671 /************************************************************************* 18672 This function copies tunable parameters (weights/means/sigmas) from one 18673 network to another with same architecture. It performs some rudimentary 18674 checks that architectures are same, and throws exception if check fails. 18676 It is intended for fast copying of states between two network which are 18677 known to have same geometry. 18680 Network1 - source, must be correctly initialized 18681 Network2 - target, must have same architecture 18684 Network2 - network state is copied from source to target 18687 Copyright 20.06.2013 by Bochkanov Sergey 18688 *************************************************************************/ 18689 void mlpcopytunableparameters(multilayerperceptron* network1, 18690 multilayerperceptron* network2, 18700 ae_assert(network1->structinfo.cnt>0&&network1->structinfo.cnt>=network1->structinfo.ptr.p_int[0], "MLPCopyTunableParameters: Network1 is uninitialized
", _state); 18701 ae_assert(network2->structinfo.cnt>0&&network2->structinfo.cnt>=network2->structinfo.ptr.p_int[0], "MLPCopyTunableParameters: Network2 is uninitialized
", _state); 18702 ae_assert(network1->structinfo.ptr.p_int[0]==network2->structinfo.ptr.p_int[0], "MLPCopyTunableParameters: Network1 geometry differs from that of Network2
", _state); 18703 ninfo = network1->structinfo.ptr.p_int[0]; 18704 for(i=0; i<=ninfo-1; i++) 18706 ae_assert(network1->structinfo.ptr.p_int[i]==network2->structinfo.ptr.p_int[i], "MLPCopyTunableParameters: Network1 geometry differs from that of Network2
", _state); 18708 mlpproperties(network1, &nin, &nout, &wcount, _state); 18709 for(i=0; i<=wcount-1; i++) 18711 network2->weights.ptr.p_double[i] = network1->weights.ptr.p_double[i]; 18713 if( mlpissoftmax(network1, _state) ) 18715 for(i=0; i<=nin-1; i++) 18717 network2->columnmeans.ptr.p_double[i] = network1->columnmeans.ptr.p_double[i]; 18718 network2->columnsigmas.ptr.p_double[i] = network1->columnsigmas.ptr.p_double[i]; 18723 for(i=0; i<=nin+nout-1; i++) 18725 network2->columnmeans.ptr.p_double[i] = network1->columnmeans.ptr.p_double[i]; 18726 network2->columnsigmas.ptr.p_double[i] = network1->columnsigmas.ptr.p_double[i]; 18732 /************************************************************************* 18733 This function exports tunable parameters (weights/means/sigmas) from 18734 network to contiguous array. Nothing is guaranteed about array format, the 18735 only thing you can count for is that MLPImportTunableParameters() will be 18738 It is intended for fast copying of states between network and backup array 18741 Network - source, must be correctly initialized 18742 P - array to use. If its size is enough to store data, it 18746 P - array which stores network parameters, resized if needed 18747 PCount - number of parameters stored in array. 18750 Copyright 20.06.2013 by Bochkanov Sergey 18751 *************************************************************************/ 18752 void mlpexporttunableparameters(multilayerperceptron* network, 18753 /* Real */ ae_vector* p, 18765 ae_assert(network->structinfo.cnt>0&&network->structinfo.cnt>=network->structinfo.ptr.p_int[0], "MLPExportTunableParameters: Network is uninitialized
", _state); 18766 mlpproperties(network, &nin, &nout, &wcount, _state); 18767 if( mlpissoftmax(network, _state) ) 18769 *pcount = wcount+2*nin; 18770 rvectorsetlengthatleast(p, *pcount, _state); 18772 for(i=0; i<=wcount-1; i++) 18774 p->ptr.p_double[k] = network->weights.ptr.p_double[i]; 18777 for(i=0; i<=nin-1; i++) 18779 p->ptr.p_double[k] = network->columnmeans.ptr.p_double[i]; 18781 p->ptr.p_double[k] = network->columnsigmas.ptr.p_double[i]; 18787 *pcount = wcount+2*(nin+nout); 18788 rvectorsetlengthatleast(p, *pcount, _state); 18790 for(i=0; i<=wcount-1; i++) 18792 p->ptr.p_double[k] = network->weights.ptr.p_double[i]; 18795 for(i=0; i<=nin+nout-1; i++) 18797 p->ptr.p_double[k] = network->columnmeans.ptr.p_double[i]; 18799 p->ptr.p_double[k] = network->columnsigmas.ptr.p_double[i]; 18806 /************************************************************************* 18807 This function imports tunable parameters (weights/means/sigmas) which 18808 were exported by MLPExportTunableParameters(). 18810 It is intended for fast copying of states between network and backup array 18814 * must be correctly initialized 18815 * must have same geometry as network used to export params 18816 P - array with parameters 18819 Copyright 20.06.2013 by Bochkanov Sergey 18820 *************************************************************************/ 18821 void mlpimporttunableparameters(multilayerperceptron* network, 18822 /* Real */ ae_vector* p, 18832 ae_assert(network->structinfo.cnt>0&&network->structinfo.cnt>=network->structinfo.ptr.p_int[0], "MLPImportTunableParameters: Network is uninitialized
", _state); 18833 mlpproperties(network, &nin, &nout, &wcount, _state); 18834 if( mlpissoftmax(network, _state) ) 18837 for(i=0; i<=wcount-1; i++) 18839 network->weights.ptr.p_double[i] = p->ptr.p_double[k]; 18842 for(i=0; i<=nin-1; i++) 18844 network->columnmeans.ptr.p_double[i] = p->ptr.p_double[k]; 18846 network->columnsigmas.ptr.p_double[i] = p->ptr.p_double[k]; 18853 for(i=0; i<=wcount-1; i++) 18855 network->weights.ptr.p_double[i] = p->ptr.p_double[k]; 18858 for(i=0; i<=nin+nout-1; i++) 18860 network->columnmeans.ptr.p_double[i] = p->ptr.p_double[k]; 18862 network->columnsigmas.ptr.p_double[i] = p->ptr.p_double[k]; 18869 /************************************************************************* 18870 Serialization of MultiLayerPerceptron strucure 18876 RA - array of real numbers which stores network, 18881 Copyright 29.03.2008 by Bochkanov Sergey 18882 *************************************************************************/ 18883 void mlpserializeold(multilayerperceptron* network, 18884 /* Real */ ae_vector* ra, 18896 ae_vector_clear(ra); 18903 ssize = network->structinfo.ptr.p_int[0]; 18904 nin = network->structinfo.ptr.p_int[1]; 18905 nout = network->structinfo.ptr.p_int[2]; 18906 wcount = network->structinfo.ptr.p_int[4]; 18907 if( mlpissoftmax(network, _state) ) 18913 sigmalen = nin+nout; 18920 * 1 version (MLPVNum) 18921 * 1 StructInfo size 18924 * SigmaLen ColumnMeans 18925 * SigmaLen ColumnSigmas 18927 *rlen = 3+ssize+wcount+2*sigmalen; 18928 ae_vector_set_length(ra, *rlen-1+1, _state); 18929 ra->ptr.p_double[0] = *rlen; 18930 ra->ptr.p_double[1] = mlpbase_mlpvnum; 18931 ra->ptr.p_double[2] = ssize; 18933 for(i=0; i<=ssize-1; i++) 18935 ra->ptr.p_double[offs+i] = network->structinfo.ptr.p_int[i]; 18938 ae_v_move(&ra->ptr.p_double[offs], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(offs,offs+wcount-1)); 18939 offs = offs+wcount; 18940 ae_v_move(&ra->ptr.p_double[offs], 1, &network->columnmeans.ptr.p_double[0], 1, ae_v_len(offs,offs+sigmalen-1)); 18941 offs = offs+sigmalen; 18942 ae_v_move(&ra->ptr.p_double[offs], 1, &network->columnsigmas.ptr.p_double[0], 1, ae_v_len(offs,offs+sigmalen-1)); 18943 offs = offs+sigmalen; 18947 /************************************************************************* 18948 Unserialization of MultiLayerPerceptron strucure 18951 RA - real array which stores network 18954 Network - restored network 18957 Copyright 29.03.2008 by Bochkanov Sergey 18958 *************************************************************************/ 18959 void mlpunserializeold(/* Real */ ae_vector* ra, 18960 multilayerperceptron* network, 18972 _multilayerperceptron_clear(network); 18974 ae_assert(ae_round(ra->ptr.p_double[1], _state)==mlpbase_mlpvnum, "MLPUnserialize: incorrect array!
", _state); 18977 * Unload StructInfo from IA 18980 ssize = ae_round(ra->ptr.p_double[2], _state); 18981 ae_vector_set_length(&network->structinfo, ssize-1+1, _state); 18982 for(i=0; i<=ssize-1; i++) 18984 network->structinfo.ptr.p_int[i] = ae_round(ra->ptr.p_double[offs+i], _state); 18989 * Unload info from StructInfo 18991 ssize = network->structinfo.ptr.p_int[0]; 18992 nin = network->structinfo.ptr.p_int[1]; 18993 nout = network->structinfo.ptr.p_int[2]; 18994 ntotal = network->structinfo.ptr.p_int[3]; 18995 wcount = network->structinfo.ptr.p_int[4]; 18996 if( network->structinfo.ptr.p_int[6]==0 ) 18998 sigmalen = nin+nout; 19006 * Allocate space for other fields 19008 ae_vector_set_length(&network->weights, wcount-1+1, _state); 19009 ae_vector_set_length(&network->columnmeans, sigmalen-1+1, _state); 19010 ae_vector_set_length(&network->columnsigmas, sigmalen-1+1, _state); 19011 ae_vector_set_length(&network->neurons, ntotal-1+1, _state); 19012 ae_vector_set_length(&network->nwbuf, ae_maxint(wcount, 2*nout, _state)-1+1, _state); 19013 ae_vector_set_length(&network->dfdnet, ntotal-1+1, _state); 19014 ae_vector_set_length(&network->x, nin-1+1, _state); 19015 ae_vector_set_length(&network->y, nout-1+1, _state); 19016 ae_vector_set_length(&network->derror, ntotal-1+1, _state); 19019 * Copy parameters from RA 19021 ae_v_move(&network->weights.ptr.p_double[0], 1, &ra->ptr.p_double[offs], 1, ae_v_len(0,wcount-1)); 19022 offs = offs+wcount; 19023 ae_v_move(&network->columnmeans.ptr.p_double[0], 1, &ra->ptr.p_double[offs], 1, ae_v_len(0,sigmalen-1)); 19024 offs = offs+sigmalen; 19025 ae_v_move(&network->columnsigmas.ptr.p_double[0], 1, &ra->ptr.p_double[offs], 1, ae_v_len(0,sigmalen-1)); 19026 offs = offs+sigmalen; 19030 /************************************************************************* 19031 Randomization of neural network weights 19034 Copyright 06.11.2007 by Bochkanov Sergey 19035 *************************************************************************/ 19036 void mlprandomize(multilayerperceptron* network, ae_state *_state) 19038 ae_frame _frame_block; 19045 ae_int_t entrysize; 19046 ae_int_t entryoffs; 19047 ae_int_t neuronidx; 19048 ae_int_t neurontype; 19054 double desiredsigma; 19055 ae_int_t montecarlocnt; 19061 ae_frame_make(_state, &_frame_block); 19062 _hqrndstate_init(&r, _state, ae_true); 19064 hqrndrandomize(&r, _state); 19065 mlpproperties(network, &nin, &nout, &wcount, _state); 19066 ntotal = network->structinfo.ptr.p_int[3]; 19067 istart = network->structinfo.ptr.p_int[5]; 19068 desiredsigma = 0.5; 19069 montecarlocnt = 20; 19073 * * Network.Weights is filled by standard deviation of weights 19074 * * default values: sigma=1 19076 for(i=0; i<=wcount-1; i++) 19078 network->weights.ptr.p_double[i] = 1.0; 19083 * * assume that input neurons have zero mean and unit standard deviation 19084 * * assume that constant neurons have zero standard deviation 19085 * * perform forward pass along neurons 19086 * * for each non-input non-constant neuron: 19087 * * calculate mean and standard deviation of neuron's output 19088 * assuming that we know means/deviations of neurons which feed it 19089 * and assuming that weights has unit variance and zero mean. 19090 * * for each nonlinear neuron additionally we perform backward pass: 19091 * * scale variances of weights which feed it in such way that neuron's 19092 * input has unit standard deviation 19094 * NOTE: this algorithm assumes that each connection feeds at most one 19095 * non-linear neuron. This assumption can be incorrect in upcoming 19096 * architectures with strong neurons. However, algorithm should 19097 * work smoothly even in this case. 19099 * During this stage we use Network.RndBuf, which is grouped into NTotal 19100 * entries, each of them having following format: 19102 * Buf[Offset+0] mean value of neuron's output 19103 * Buf[Offset+1] standard deviation of neuron's output 19108 rvectorsetlengthatleast(&network->rndbuf, entrysize*ntotal, _state); 19109 for(neuronidx=0; neuronidx<=ntotal-1; neuronidx++) 19111 neurontype = network->structinfo.ptr.p_int[istart+neuronidx*mlpbase_nfieldwidth+0]; 19112 entryoffs = entrysize*neuronidx; 19113 if( neurontype==-2 ) 19117 * Input neuron: zero mean, unit variance. 19119 network->rndbuf.ptr.p_double[entryoffs+0] = 0.0; 19120 network->rndbuf.ptr.p_double[entryoffs+1] = 1.0; 19123 if( neurontype==-3 ) 19127 * "-1
" neuron: mean=-1, zero variance. 19129 network->rndbuf.ptr.p_double[entryoffs+0] = -1.0; 19130 network->rndbuf.ptr.p_double[entryoffs+1] = 0.0; 19133 if( neurontype==-4 ) 19137 * "0
" neuron: mean=0, zero variance. 19139 network->rndbuf.ptr.p_double[entryoffs+0] = 0.0; 19140 network->rndbuf.ptr.p_double[entryoffs+1] = 0.0; 19143 if( neurontype==0 ) 19147 * Adaptive summator neuron: 19148 * * calculate its mean and variance. 19149 * * we assume that weights of this neuron have unit variance and zero mean. 19150 * * thus, neuron's output is always have zero mean 19151 * * as for variance, it is a bit more interesting: 19152 * * let n[i] is i-th input neuron 19153 * * let w[i] is i-th weight 19154 * * we assume that n[i] and w[i] are independently distributed 19155 * * Var(n0*w0+n1*w1+...) = Var(n0*w0)+Var(n1*w1)+... 19156 * * Var(X*Y) = mean(X)^2*Var(Y) + mean(Y)^2*Var(X) + Var(X)*Var(Y) 19157 * * mean(w[i])=0, var(w[i])=1 19158 * * Var(n[i]*w[i]) = mean(n[i])^2 + Var(n[i]) 19160 n1 = network->structinfo.ptr.p_int[istart+neuronidx*mlpbase_nfieldwidth+2]; 19161 n2 = n1+network->structinfo.ptr.p_int[istart+neuronidx*mlpbase_nfieldwidth+1]-1; 19164 for(i=n1; i<=n2; i++) 19166 vvar = vvar+ae_sqr(network->rndbuf.ptr.p_double[entrysize*i+0], _state)+ae_sqr(network->rndbuf.ptr.p_double[entrysize*i+1], _state); 19168 network->rndbuf.ptr.p_double[entryoffs+0] = vmean; 19169 network->rndbuf.ptr.p_double[entryoffs+1] = ae_sqrt(vvar, _state); 19172 if( neurontype==-5 ) 19176 * Linear activation function 19178 i = network->structinfo.ptr.p_int[istart+neuronidx*mlpbase_nfieldwidth+2]; 19179 vmean = network->rndbuf.ptr.p_double[entrysize*i+0]; 19180 vvar = ae_sqr(network->rndbuf.ptr.p_double[entrysize*i+1], _state); 19181 if( ae_fp_greater(vvar,0) ) 19183 wscale = desiredsigma/ae_sqrt(vvar, _state); 19189 mlpbase_randomizebackwardpass(network, i, wscale, _state); 19190 network->rndbuf.ptr.p_double[entryoffs+0] = vmean*wscale; 19191 network->rndbuf.ptr.p_double[entryoffs+1] = desiredsigma; 19198 * Nonlinear activation function: 19199 * * scale its inputs 19200 * * estimate mean/sigma of its output using Monte-Carlo method 19201 * (we simulate different inputs with unit deviation and 19202 * sample activation function output on such inputs) 19204 i = network->structinfo.ptr.p_int[istart+neuronidx*mlpbase_nfieldwidth+2]; 19205 vmean = network->rndbuf.ptr.p_double[entrysize*i+0]; 19206 vvar = ae_sqr(network->rndbuf.ptr.p_double[entrysize*i+1], _state); 19207 if( ae_fp_greater(vvar,0) ) 19209 wscale = desiredsigma/ae_sqrt(vvar, _state); 19215 mlpbase_randomizebackwardpass(network, i, wscale, _state); 19218 vmean = vmean*wscale; 19219 for(i=0; i<=montecarlocnt-1; i++) 19221 v = vmean+desiredsigma*hqrndnormal(&r, _state); 19225 ef = ef/montecarlocnt; 19226 ef2 = ef2/montecarlocnt; 19227 network->rndbuf.ptr.p_double[entryoffs+0] = ef; 19228 network->rndbuf.ptr.p_double[entryoffs+1] = ae_maxreal(ef2-ef*ef, 0.0, _state); 19231 ae_assert(ae_false, "MLPRandomize: unexpected neuron
type", _state); 19235 * Stage 3: generate weights. 19237 for(i=0; i<=wcount-1; i++) 19239 network->weights.ptr.p_double[i] = network->weights.ptr.p_double[i]*hqrndnormal(&r, _state); 19241 ae_frame_leave(_state); 19245 /************************************************************************* 19246 Randomization of neural network weights and standartisator 19249 Copyright 10.03.2008 by Bochkanov Sergey 19250 *************************************************************************/ 19251 void mlprandomizefull(multilayerperceptron* network, ae_state *_state) 19263 mlpproperties(network, &nin, &nout, &wcount, _state); 19264 ntotal = network->structinfo.ptr.p_int[3]; 19265 istart = network->structinfo.ptr.p_int[5]; 19270 mlprandomize(network, _state); 19271 for(i=0; i<=nin-1; i++) 19273 network->columnmeans.ptr.p_double[i] = ae_randomreal(_state)-0.5; 19274 network->columnsigmas.ptr.p_double[i] = ae_randomreal(_state)+0.5; 19276 if( !mlpissoftmax(network, _state) ) 19278 for(i=0; i<=nout-1; i++) 19280 offs = istart+(ntotal-nout+i)*mlpbase_nfieldwidth; 19281 ntype = network->structinfo.ptr.p_int[offs+0]; 19286 * Shifts are changed only for linear outputs neurons 19288 network->columnmeans.ptr.p_double[nin+i] = 2*ae_randomreal(_state)-1; 19290 if( ntype==0||ntype==3 ) 19294 * Scales are changed only for linear or bounded outputs neurons. 19295 * Note that scale randomization preserves sign. 19297 network->columnsigmas.ptr.p_double[nin+i] = ae_sign(network->columnsigmas.ptr.p_double[nin+i], _state)*(1.5*ae_randomreal(_state)+0.5); 19304 /************************************************************************* 19305 Internal subroutine. 19308 Copyright 30.03.2008 by Bochkanov Sergey 19309 *************************************************************************/ 19310 void mlpinitpreprocessor(multilayerperceptron* network, 19311 /* Real */ ae_matrix* xy, 19315 ae_frame _frame_block; 19330 ae_frame_make(_state, &_frame_block); 19331 ae_vector_init(&means, 0, DT_REAL, _state, ae_true); 19332 ae_vector_init(&sigmas, 0, DT_REAL, _state, ae_true); 19334 mlpproperties(network, &nin, &nout, &wcount, _state); 19335 ntotal = network->structinfo.ptr.p_int[3]; 19336 istart = network->structinfo.ptr.p_int[5]; 19341 if( mlpissoftmax(network, _state) ) 19349 ae_vector_set_length(&means, jmax+1, _state); 19350 ae_vector_set_length(&sigmas, jmax+1, _state); 19351 for(i=0; i<=jmax; i++) 19353 means.ptr.p_double[i] = 0; 19354 sigmas.ptr.p_double[i] = 0; 19356 for(i=0; i<=ssize-1; i++) 19358 for(j=0; j<=jmax; j++) 19360 means.ptr.p_double[j] = means.ptr.p_double[j]+xy->ptr.pp_double[i][j]; 19363 for(i=0; i<=jmax; i++) 19365 means.ptr.p_double[i] = means.ptr.p_double[i]/ssize; 19367 for(i=0; i<=ssize-1; i++) 19369 for(j=0; j<=jmax; j++) 19371 sigmas.ptr.p_double[j] = sigmas.ptr.p_double[j]+ae_sqr(xy->ptr.pp_double[i][j]-means.ptr.p_double[j], _state); 19374 for(i=0; i<=jmax; i++) 19376 sigmas.ptr.p_double[i] = ae_sqrt(sigmas.ptr.p_double[i]/ssize, _state); 19382 for(i=0; i<=nin-1; i++) 19384 network->columnmeans.ptr.p_double[i] = means.ptr.p_double[i]; 19385 network->columnsigmas.ptr.p_double[i] = sigmas.ptr.p_double[i]; 19386 if( ae_fp_eq(network->columnsigmas.ptr.p_double[i],0) ) 19388 network->columnsigmas.ptr.p_double[i] = 1; 19395 if( !mlpissoftmax(network, _state) ) 19397 for(i=0; i<=nout-1; i++) 19399 offs = istart+(ntotal-nout+i)*mlpbase_nfieldwidth; 19400 ntype = network->structinfo.ptr.p_int[offs+0]; 19407 network->columnmeans.ptr.p_double[nin+i] = means.ptr.p_double[nin+i]; 19408 network->columnsigmas.ptr.p_double[nin+i] = sigmas.ptr.p_double[nin+i]; 19409 if( ae_fp_eq(network->columnsigmas.ptr.p_double[nin+i],0) ) 19411 network->columnsigmas.ptr.p_double[nin+i] = 1; 19416 * Bounded outputs (half-interval) 19420 s = means.ptr.p_double[nin+i]-network->columnmeans.ptr.p_double[nin+i]; 19421 if( ae_fp_eq(s,0) ) 19423 s = ae_sign(network->columnsigmas.ptr.p_double[nin+i], _state); 19425 if( ae_fp_eq(s,0) ) 19429 network->columnsigmas.ptr.p_double[nin+i] = ae_sign(network->columnsigmas.ptr.p_double[nin+i], _state)*ae_fabs(s, _state); 19430 if( ae_fp_eq(network->columnsigmas.ptr.p_double[nin+i],0) ) 19432 network->columnsigmas.ptr.p_double[nin+i] = 1; 19437 ae_frame_leave(_state); 19441 /************************************************************************* 19442 Internal subroutine. 19443 Initialization for preprocessor based on a sample. 19446 Network - initialized neural network; 19447 XY - sample, given by sparse matrix; 19448 SSize - sample size. 19451 Network - neural network with initialised preprocessor. 19454 Copyright 26.07.2012 by Bochkanov Sergey 19455 *************************************************************************/ 19456 void mlpinitpreprocessorsparse(multilayerperceptron* network, 19461 ae_frame _frame_block; 19476 ae_frame_make(_state, &_frame_block); 19477 ae_vector_init(&means, 0, DT_REAL, _state, ae_true); 19478 ae_vector_init(&sigmas, 0, DT_REAL, _state, ae_true); 19480 mlpproperties(network, &nin, &nout, &wcount, _state); 19481 ntotal = network->structinfo.ptr.p_int[3]; 19482 istart = network->structinfo.ptr.p_int[5]; 19487 if( mlpissoftmax(network, _state) ) 19495 ae_vector_set_length(&means, jmax+1, _state); 19496 ae_vector_set_length(&sigmas, jmax+1, _state); 19497 for(i=0; i<=jmax; i++) 19499 means.ptr.p_double[i] = 0; 19500 sigmas.ptr.p_double[i] = 0; 19502 for(i=0; i<=ssize-1; i++) 19504 sparsegetrow(xy, i, &network->xyrow, _state); 19505 for(j=0; j<=jmax; j++) 19507 means.ptr.p_double[j] = means.ptr.p_double[j]+network->xyrow.ptr.p_double[j]; 19510 for(i=0; i<=jmax; i++) 19512 means.ptr.p_double[i] = means.ptr.p_double[i]/ssize; 19514 for(i=0; i<=ssize-1; i++) 19516 sparsegetrow(xy, i, &network->xyrow, _state); 19517 for(j=0; j<=jmax; j++) 19519 sigmas.ptr.p_double[j] = sigmas.ptr.p_double[j]+ae_sqr(network->xyrow.ptr.p_double[j]-means.ptr.p_double[j], _state); 19522 for(i=0; i<=jmax; i++) 19524 sigmas.ptr.p_double[i] = ae_sqrt(sigmas.ptr.p_double[i]/ssize, _state); 19530 for(i=0; i<=nin-1; i++) 19532 network->columnmeans.ptr.p_double[i] = means.ptr.p_double[i]; 19533 network->columnsigmas.ptr.p_double[i] = sigmas.ptr.p_double[i]; 19534 if( ae_fp_eq(network->columnsigmas.ptr.p_double[i],0) ) 19536 network->columnsigmas.ptr.p_double[i] = 1; 19543 if( !mlpissoftmax(network, _state) ) 19545 for(i=0; i<=nout-1; i++) 19547 offs = istart+(ntotal-nout+i)*mlpbase_nfieldwidth; 19548 ntype = network->structinfo.ptr.p_int[offs+0]; 19555 network->columnmeans.ptr.p_double[nin+i] = means.ptr.p_double[nin+i]; 19556 network->columnsigmas.ptr.p_double[nin+i] = sigmas.ptr.p_double[nin+i]; 19557 if( ae_fp_eq(network->columnsigmas.ptr.p_double[nin+i],0) ) 19559 network->columnsigmas.ptr.p_double[nin+i] = 1; 19564 * Bounded outputs (half-interval) 19568 s = means.ptr.p_double[nin+i]-network->columnmeans.ptr.p_double[nin+i]; 19569 if( ae_fp_eq(s,0) ) 19571 s = ae_sign(network->columnsigmas.ptr.p_double[nin+i], _state); 19573 if( ae_fp_eq(s,0) ) 19577 network->columnsigmas.ptr.p_double[nin+i] = ae_sign(network->columnsigmas.ptr.p_double[nin+i], _state)*ae_fabs(s, _state); 19578 if( ae_fp_eq(network->columnsigmas.ptr.p_double[nin+i],0) ) 19580 network->columnsigmas.ptr.p_double[nin+i] = 1; 19585 ae_frame_leave(_state); 19589 /************************************************************************* 19590 Internal subroutine. 19591 Initialization for preprocessor based on a subsample. 19594 Network - network initialized with one of the network creation funcs 19595 XY - original dataset; one sample = one row; 19596 first NIn columns contain inputs, 19597 next NOut columns - desired outputs. 19598 SetSize - real size of XY, SetSize>=0; 19599 Idx - subset of SubsetSize elements, array[SubsetSize]: 19600 * Idx[I] stores row index in the original dataset which is 19601 given by XY. Gradient is calculated with respect to rows 19602 whose indexes are stored in Idx[]. 19603 * Idx[] must store correct indexes; this function throws 19604 an exception in case incorrect index (less than 0 or 19605 larger than rows(XY)) is given 19606 * Idx[] may store indexes in any order and even with 19608 SubsetSize- number of elements in Idx[] array. 19611 Network - neural network with initialised preprocessor. 19613 NOTE: when SubsetSize<0 is used full dataset by call MLPInitPreprocessor 19617 Copyright 23.08.2012 by Bochkanov Sergey 19618 *************************************************************************/ 19619 void mlpinitpreprocessorsubset(multilayerperceptron* network, 19620 /* Real */ ae_matrix* xy, 19622 /* Integer */ ae_vector* idx, 19623 ae_int_t subsetsize, 19626 ae_frame _frame_block; 19642 ae_frame_make(_state, &_frame_block); 19643 ae_vector_init(&means, 0, DT_REAL, _state, ae_true); 19644 ae_vector_init(&sigmas, 0, DT_REAL, _state, ae_true); 19646 ae_assert(setsize>=0, "MLPInitPreprocessorSubset: SetSize<0
", _state); 19649 mlpinitpreprocessor(network, xy, setsize, _state); 19650 ae_frame_leave(_state); 19653 ae_assert(subsetsize<=idx->cnt, "MLPInitPreprocessorSubset: SubsetSize>Length(Idx)
", _state); 19655 for(i=0; i<=subsetsize-1; i++) 19657 ae_assert(idx->ptr.p_int[i]>=0, "MLPInitPreprocessorSubset: incorrect
index of XY row(Idx[I]<0)
", _state); 19658 ae_assert(idx->ptr.p_int[i]<=npoints-1, "MLPInitPreprocessorSubset: incorrect
index of XY row(Idx[I]>Rows(XY)-1)
", _state); 19660 mlpproperties(network, &nin, &nout, &wcount, _state); 19661 ntotal = network->structinfo.ptr.p_int[3]; 19662 istart = network->structinfo.ptr.p_int[5]; 19667 if( mlpissoftmax(network, _state) ) 19675 ae_vector_set_length(&means, jmax+1, _state); 19676 ae_vector_set_length(&sigmas, jmax+1, _state); 19677 for(i=0; i<=jmax; i++) 19679 means.ptr.p_double[i] = 0; 19680 sigmas.ptr.p_double[i] = 0; 19682 for(i=0; i<=subsetsize-1; i++) 19684 for(j=0; j<=jmax; j++) 19686 means.ptr.p_double[j] = means.ptr.p_double[j]+xy->ptr.pp_double[idx->ptr.p_int[i]][j]; 19689 for(i=0; i<=jmax; i++) 19691 means.ptr.p_double[i] = means.ptr.p_double[i]/subsetsize; 19693 for(i=0; i<=subsetsize-1; i++) 19695 for(j=0; j<=jmax; j++) 19697 sigmas.ptr.p_double[j] = sigmas.ptr.p_double[j]+ae_sqr(xy->ptr.pp_double[idx->ptr.p_int[i]][j]-means.ptr.p_double[j], _state); 19700 for(i=0; i<=jmax; i++) 19702 sigmas.ptr.p_double[i] = ae_sqrt(sigmas.ptr.p_double[i]/subsetsize, _state); 19708 for(i=0; i<=nin-1; i++) 19710 network->columnmeans.ptr.p_double[i] = means.ptr.p_double[i]; 19711 network->columnsigmas.ptr.p_double[i] = sigmas.ptr.p_double[i]; 19712 if( ae_fp_eq(network->columnsigmas.ptr.p_double[i],0) ) 19714 network->columnsigmas.ptr.p_double[i] = 1; 19721 if( !mlpissoftmax(network, _state) ) 19723 for(i=0; i<=nout-1; i++) 19725 offs = istart+(ntotal-nout+i)*mlpbase_nfieldwidth; 19726 ntype = network->structinfo.ptr.p_int[offs+0]; 19733 network->columnmeans.ptr.p_double[nin+i] = means.ptr.p_double[nin+i]; 19734 network->columnsigmas.ptr.p_double[nin+i] = sigmas.ptr.p_double[nin+i]; 19735 if( ae_fp_eq(network->columnsigmas.ptr.p_double[nin+i],0) ) 19737 network->columnsigmas.ptr.p_double[nin+i] = 1; 19742 * Bounded outputs (half-interval) 19746 s = means.ptr.p_double[nin+i]-network->columnmeans.ptr.p_double[nin+i]; 19747 if( ae_fp_eq(s,0) ) 19749 s = ae_sign(network->columnsigmas.ptr.p_double[nin+i], _state); 19751 if( ae_fp_eq(s,0) ) 19755 network->columnsigmas.ptr.p_double[nin+i] = ae_sign(network->columnsigmas.ptr.p_double[nin+i], _state)*ae_fabs(s, _state); 19756 if( ae_fp_eq(network->columnsigmas.ptr.p_double[nin+i],0) ) 19758 network->columnsigmas.ptr.p_double[nin+i] = 1; 19763 ae_frame_leave(_state); 19767 /************************************************************************* 19768 Internal subroutine. 19769 Initialization for preprocessor based on a subsample. 19772 Network - network initialized with one of the network creation funcs 19773 XY - original dataset, given by sparse matrix; 19774 one sample = one row; 19775 first NIn columns contain inputs, 19776 next NOut columns - desired outputs. 19777 SetSize - real size of XY, SetSize>=0; 19778 Idx - subset of SubsetSize elements, array[SubsetSize]: 19779 * Idx[I] stores row index in the original dataset which is 19780 given by XY. Gradient is calculated with respect to rows 19781 whose indexes are stored in Idx[]. 19782 * Idx[] must store correct indexes; this function throws 19783 an exception in case incorrect index (less than 0 or 19784 larger than rows(XY)) is given 19785 * Idx[] may store indexes in any order and even with 19787 SubsetSize- number of elements in Idx[] array. 19790 Network - neural network with initialised preprocessor. 19792 NOTE: when SubsetSize<0 is used full dataset by call 19793 MLPInitPreprocessorSparse function. 19796 Copyright 26.07.2012 by Bochkanov Sergey 19797 *************************************************************************/ 19798 void mlpinitpreprocessorsparsesubset(multilayerperceptron* network, 19801 /* Integer */ ae_vector* idx, 19802 ae_int_t subsetsize, 19805 ae_frame _frame_block; 19821 ae_frame_make(_state, &_frame_block); 19822 ae_vector_init(&means, 0, DT_REAL, _state, ae_true); 19823 ae_vector_init(&sigmas, 0, DT_REAL, _state, ae_true); 19825 ae_assert(setsize>=0, "MLPInitPreprocessorSparseSubset: SetSize<0
", _state); 19828 mlpinitpreprocessorsparse(network, xy, setsize, _state); 19829 ae_frame_leave(_state); 19832 ae_assert(subsetsize<=idx->cnt, "MLPInitPreprocessorSparseSubset: SubsetSize>Length(Idx)
", _state); 19834 for(i=0; i<=subsetsize-1; i++) 19836 ae_assert(idx->ptr.p_int[i]>=0, "MLPInitPreprocessorSparseSubset: incorrect
index of XY row(Idx[I]<0)
", _state); 19837 ae_assert(idx->ptr.p_int[i]<=npoints-1, "MLPInitPreprocessorSparseSubset: incorrect
index of XY row(Idx[I]>Rows(XY)-1)
", _state); 19839 mlpproperties(network, &nin, &nout, &wcount, _state); 19840 ntotal = network->structinfo.ptr.p_int[3]; 19841 istart = network->structinfo.ptr.p_int[5]; 19846 if( mlpissoftmax(network, _state) ) 19854 ae_vector_set_length(&means, jmax+1, _state); 19855 ae_vector_set_length(&sigmas, jmax+1, _state); 19856 for(i=0; i<=jmax; i++) 19858 means.ptr.p_double[i] = 0; 19859 sigmas.ptr.p_double[i] = 0; 19861 for(i=0; i<=subsetsize-1; i++) 19863 sparsegetrow(xy, idx->ptr.p_int[i], &network->xyrow, _state); 19864 for(j=0; j<=jmax; j++) 19866 means.ptr.p_double[j] = means.ptr.p_double[j]+network->xyrow.ptr.p_double[j]; 19869 for(i=0; i<=jmax; i++) 19871 means.ptr.p_double[i] = means.ptr.p_double[i]/subsetsize; 19873 for(i=0; i<=subsetsize-1; i++) 19875 sparsegetrow(xy, idx->ptr.p_int[i], &network->xyrow, _state); 19876 for(j=0; j<=jmax; j++) 19878 sigmas.ptr.p_double[j] = sigmas.ptr.p_double[j]+ae_sqr(network->xyrow.ptr.p_double[j]-means.ptr.p_double[j], _state); 19881 for(i=0; i<=jmax; i++) 19883 sigmas.ptr.p_double[i] = ae_sqrt(sigmas.ptr.p_double[i]/subsetsize, _state); 19889 for(i=0; i<=nin-1; i++) 19891 network->columnmeans.ptr.p_double[i] = means.ptr.p_double[i]; 19892 network->columnsigmas.ptr.p_double[i] = sigmas.ptr.p_double[i]; 19893 if( ae_fp_eq(network->columnsigmas.ptr.p_double[i],0) ) 19895 network->columnsigmas.ptr.p_double[i] = 1; 19902 if( !mlpissoftmax(network, _state) ) 19904 for(i=0; i<=nout-1; i++) 19906 offs = istart+(ntotal-nout+i)*mlpbase_nfieldwidth; 19907 ntype = network->structinfo.ptr.p_int[offs+0]; 19914 network->columnmeans.ptr.p_double[nin+i] = means.ptr.p_double[nin+i]; 19915 network->columnsigmas.ptr.p_double[nin+i] = sigmas.ptr.p_double[nin+i]; 19916 if( ae_fp_eq(network->columnsigmas.ptr.p_double[nin+i],0) ) 19918 network->columnsigmas.ptr.p_double[nin+i] = 1; 19923 * Bounded outputs (half-interval) 19927 s = means.ptr.p_double[nin+i]-network->columnmeans.ptr.p_double[nin+i]; 19928 if( ae_fp_eq(s,0) ) 19930 s = ae_sign(network->columnsigmas.ptr.p_double[nin+i], _state); 19932 if( ae_fp_eq(s,0) ) 19936 network->columnsigmas.ptr.p_double[nin+i] = ae_sign(network->columnsigmas.ptr.p_double[nin+i], _state)*ae_fabs(s, _state); 19937 if( ae_fp_eq(network->columnsigmas.ptr.p_double[nin+i],0) ) 19939 network->columnsigmas.ptr.p_double[nin+i] = 1; 19944 ae_frame_leave(_state); 19948 /************************************************************************* 19949 Returns information about initialized network: number of inputs, outputs, 19953 Copyright 04.11.2007 by Bochkanov Sergey 19954 *************************************************************************/ 19955 void mlpproperties(multilayerperceptron* network, 19966 *nin = network->structinfo.ptr.p_int[1]; 19967 *nout = network->structinfo.ptr.p_int[2]; 19968 *wcount = network->structinfo.ptr.p_int[4]; 19972 /************************************************************************* 19973 Returns number of "internal", low-level neurons in the network (one which 19974 is stored in StructInfo). 19977 Copyright 04.11.2007 by Bochkanov Sergey 19978 *************************************************************************/ 19979 ae_int_t mlpntotal(multilayerperceptron* network, ae_state *_state) 19984 result = network->structinfo.ptr.p_int[3]; 19989 /************************************************************************* 19990 Returns number of inputs. 19993 Copyright 19.10.2011 by Bochkanov Sergey 19994 *************************************************************************/ 19995 ae_int_t mlpgetinputscount(multilayerperceptron* network, 20001 result = network->structinfo.ptr.p_int[1]; 20006 /************************************************************************* 20007 Returns number of outputs. 20010 Copyright 19.10.2011 by Bochkanov Sergey 20011 *************************************************************************/ 20012 ae_int_t mlpgetoutputscount(multilayerperceptron* network, 20018 result = network->structinfo.ptr.p_int[2]; 20023 /************************************************************************* 20024 Returns number of weights. 20027 Copyright 19.10.2011 by Bochkanov Sergey 20028 *************************************************************************/ 20029 ae_int_t mlpgetweightscount(multilayerperceptron* network, 20035 result = network->structinfo.ptr.p_int[4]; 20040 /************************************************************************* 20041 Tells whether network is SOFTMAX-normalized (i.e. classifier) or not. 20044 Copyright 04.11.2007 by Bochkanov Sergey 20045 *************************************************************************/ 20046 ae_bool mlpissoftmax(multilayerperceptron* network, ae_state *_state) 20051 result = network->structinfo.ptr.p_int[6]==1; 20056 /************************************************************************* 20057 This function returns total number of layers (including input, hidden and 20061 Copyright 25.03.2011 by Bochkanov Sergey 20062 *************************************************************************/ 20063 ae_int_t mlpgetlayerscount(multilayerperceptron* network, 20069 result = network->hllayersizes.cnt; 20074 /************************************************************************* 20075 This function returns size of K-th layer. 20077 K=0 corresponds to input layer, K=CNT-1 corresponds to output layer. 20079 Size of the output layer is always equal to the number of outputs, although 20080 when we have softmax-normalized network, last neuron doesn't have any 20081 connections - it is just zero. 20084 Copyright 25.03.2011 by Bochkanov Sergey 20085 *************************************************************************/ 20086 ae_int_t mlpgetlayersize(multilayerperceptron* network, 20093 ae_assert(k>=0&&k<network->hllayersizes.cnt, "MLPGetLayerSize: incorrect layer
index", _state); 20094 result = network->hllayersizes.ptr.p_int[k]; 20099 /************************************************************************* 20100 This function returns offset/scaling coefficients for I-th input of the 20109 Sigma - sigma term, guaranteed to be nonzero. 20111 I-th input is passed through linear transformation 20112 IN[i] = (IN[i]-Mean)/Sigma 20113 before feeding to the network 20116 Copyright 25.03.2011 by Bochkanov Sergey 20117 *************************************************************************/ 20118 void mlpgetinputscaling(multilayerperceptron* network, 20128 ae_assert(i>=0&&i<network->hllayersizes.ptr.p_int[0], "MLPGetInputScaling: incorrect (nonexistent) I
", _state); 20129 *mean = network->columnmeans.ptr.p_double[i]; 20130 *sigma = network->columnsigmas.ptr.p_double[i]; 20131 if( ae_fp_eq(*sigma,0) ) 20138 /************************************************************************* 20139 This function returns offset/scaling coefficients for I-th output of the 20148 Sigma - sigma term, guaranteed to be nonzero. 20150 I-th output is passed through linear transformation 20151 OUT[i] = OUT[i]*Sigma+Mean 20152 before returning it to user. In case we have SOFTMAX-normalized network, 20153 we return (Mean,Sigma)=(0.0,1.0). 20156 Copyright 25.03.2011 by Bochkanov Sergey 20157 *************************************************************************/ 20158 void mlpgetoutputscaling(multilayerperceptron* network, 20168 ae_assert(i>=0&&i<network->hllayersizes.ptr.p_int[network->hllayersizes.cnt-1], "MLPGetOutputScaling: incorrect (nonexistent) I
", _state); 20169 if( network->structinfo.ptr.p_int[6]==1 ) 20176 *mean = network->columnmeans.ptr.p_double[network->hllayersizes.ptr.p_int[0]+i]; 20177 *sigma = network->columnsigmas.ptr.p_double[network->hllayersizes.ptr.p_int[0]+i]; 20182 /************************************************************************* 20183 This function returns information about Ith neuron of Kth layer 20188 I - neuron index (within layer) 20191 FKind - activation function type (used by MLPActivationFunction()) 20192 this value is zero for input or linear neurons 20193 Threshold - also called offset, bias 20194 zero for input neurons 20196 NOTE: this function throws exception if layer or neuron with given index 20200 Copyright 25.03.2011 by Bochkanov Sergey 20201 *************************************************************************/ 20202 void mlpgetneuroninfo(multilayerperceptron* network, 20211 ae_int_t highlevelidx; 20212 ae_int_t activationoffset; 20217 ncnt = network->hlneurons.cnt/mlpbase_hlnfieldwidth; 20218 istart = network->structinfo.ptr.p_int[5]; 20223 network->integerbuf.ptr.p_int[0] = k; 20224 network->integerbuf.ptr.p_int[1] = i; 20225 highlevelidx = recsearch(&network->hlneurons, mlpbase_hlnfieldwidth, 2, 0, ncnt, &network->integerbuf, _state); 20226 ae_assert(highlevelidx>=0, "MLPGetNeuronInfo: incorrect (nonexistent) layer
or neuron
index", _state); 20229 * 1. find offset of the activation function record in the 20231 if( network->hlneurons.ptr.p_int[highlevelidx*mlpbase_hlnfieldwidth+2]>=0 ) 20233 activationoffset = istart+network->hlneurons.ptr.p_int[highlevelidx*mlpbase_hlnfieldwidth+2]*mlpbase_nfieldwidth; 20234 *fkind = network->structinfo.ptr.p_int[activationoffset+0]; 20240 if( network->hlneurons.ptr.p_int[highlevelidx*mlpbase_hlnfieldwidth+3]>=0 ) 20242 *threshold = network->weights.ptr.p_double[network->hlneurons.ptr.p_int[highlevelidx*mlpbase_hlnfieldwidth+3]]; 20251 /************************************************************************* 20252 This function returns information about connection from I0-th neuron of 20253 K0-th layer to I1-th neuron of K1-th layer. 20258 I0 - neuron index (within layer) 20260 I1 - neuron index (within layer) 20263 connection weight (zero for non-existent connections) 20266 1. throws exception if layer or neuron with given index do not exists. 20267 2. returns zero if neurons exist, but there is no connection between them 20270 Copyright 25.03.2011 by Bochkanov Sergey 20271 *************************************************************************/ 20272 double mlpgetweight(multilayerperceptron* network, 20280 ae_int_t highlevelidx; 20284 ccnt = network->hlconnections.cnt/mlpbase_hlconnfieldwidth; 20289 ae_assert(k0>=0&&k0<network->hllayersizes.cnt, "MLPGetWeight: incorrect (nonexistent) K0
", _state); 20290 ae_assert(i0>=0&&i0<network->hllayersizes.ptr.p_int[k0], "MLPGetWeight: incorrect (nonexistent) I0
", _state); 20291 ae_assert(k1>=0&&k1<network->hllayersizes.cnt, "MLPGetWeight: incorrect (nonexistent) K1
", _state); 20292 ae_assert(i1>=0&&i1<network->hllayersizes.ptr.p_int[k1], "MLPGetWeight: incorrect (nonexistent) I1
", _state); 20297 network->integerbuf.ptr.p_int[0] = k0; 20298 network->integerbuf.ptr.p_int[1] = i0; 20299 network->integerbuf.ptr.p_int[2] = k1; 20300 network->integerbuf.ptr.p_int[3] = i1; 20301 highlevelidx = recsearch(&network->hlconnections, mlpbase_hlconnfieldwidth, 4, 0, ccnt, &network->integerbuf, _state); 20302 if( highlevelidx>=0 ) 20304 result = network->weights.ptr.p_double[network->hlconnections.ptr.p_int[highlevelidx*mlpbase_hlconnfieldwidth+4]]; 20314 /************************************************************************* 20315 This function sets offset/scaling coefficients for I-th input of the 20322 Sigma - sigma term (if zero, will be replaced by 1.0) 20324 NTE: I-th input is passed through linear transformation 20325 IN[i] = (IN[i]-Mean)/Sigma 20326 before feeding to the network. This function sets Mean and Sigma. 20329 Copyright 25.03.2011 by Bochkanov Sergey 20330 *************************************************************************/ 20331 void mlpsetinputscaling(multilayerperceptron* network, 20339 ae_assert(i>=0&&i<network->hllayersizes.ptr.p_int[0], "MLPSetInputScaling: incorrect (nonexistent) I
", _state); 20340 ae_assert(ae_isfinite(mean, _state), "MLPSetInputScaling: infinite
or NAN Mean
", _state); 20341 ae_assert(ae_isfinite(sigma, _state), "MLPSetInputScaling: infinite
or NAN Sigma
", _state); 20342 if( ae_fp_eq(sigma,0) ) 20346 network->columnmeans.ptr.p_double[i] = mean; 20347 network->columnsigmas.ptr.p_double[i] = sigma; 20351 /************************************************************************* 20352 This function sets offset/scaling coefficients for I-th output of the 20359 Sigma - sigma term (if zero, will be replaced by 1.0) 20363 NOTE: I-th output is passed through linear transformation 20364 OUT[i] = OUT[i]*Sigma+Mean 20365 before returning it to user. This function sets Sigma/Mean. In case we 20366 have SOFTMAX-normalized network, you can not set (Sigma,Mean) to anything 20367 other than(0.0,1.0) - this function will throw exception. 20370 Copyright 25.03.2011 by Bochkanov Sergey 20371 *************************************************************************/ 20372 void mlpsetoutputscaling(multilayerperceptron* network, 20380 ae_assert(i>=0&&i<network->hllayersizes.ptr.p_int[network->hllayersizes.cnt-1], "MLPSetOutputScaling: incorrect (nonexistent) I
", _state); 20381 ae_assert(ae_isfinite(mean, _state), "MLPSetOutputScaling: infinite
or NAN Mean
", _state); 20382 ae_assert(ae_isfinite(sigma, _state), "MLPSetOutputScaling: infinite
or NAN Sigma
", _state); 20383 if( network->structinfo.ptr.p_int[6]==1 ) 20385 ae_assert(ae_fp_eq(mean,0), "MLPSetOutputScaling: you can not
set non-
zero Mean term
for classifier network
", _state); 20386 ae_assert(ae_fp_eq(sigma,1), "MLPSetOutputScaling: you can not
set non-unit Sigma term
for classifier network
", _state); 20390 if( ae_fp_eq(sigma,0) ) 20394 network->columnmeans.ptr.p_double[network->hllayersizes.ptr.p_int[0]+i] = mean; 20395 network->columnsigmas.ptr.p_double[network->hllayersizes.ptr.p_int[0]+i] = sigma; 20400 /************************************************************************* 20401 This function modifies information about Ith neuron of Kth layer 20406 I - neuron index (within layer) 20407 FKind - activation function type (used by MLPActivationFunction()) 20408 this value must be zero for input neurons 20409 (you can not set activation function for input neurons) 20410 Threshold - also called offset, bias 20411 this value must be zero for input neurons 20412 (you can not set threshold for input neurons) 20415 1. this function throws exception if layer or neuron with given index do 20417 2. this function also throws exception when you try to set non-linear 20418 activation function for input neurons (any kind of network) or for output 20419 neurons of classifier network. 20420 3. this function throws exception when you try to set non-zero threshold for 20421 input neurons (any kind of network). 20424 Copyright 25.03.2011 by Bochkanov Sergey 20425 *************************************************************************/ 20426 void mlpsetneuroninfo(multilayerperceptron* network, 20435 ae_int_t highlevelidx; 20436 ae_int_t activationoffset; 20439 ae_assert(ae_isfinite(threshold, _state), "MLPSetNeuronInfo: infinite
or NAN Threshold
", _state); 20444 ncnt = network->hlneurons.cnt/mlpbase_hlnfieldwidth; 20445 istart = network->structinfo.ptr.p_int[5]; 20450 network->integerbuf.ptr.p_int[0] = k; 20451 network->integerbuf.ptr.p_int[1] = i; 20452 highlevelidx = recsearch(&network->hlneurons, mlpbase_hlnfieldwidth, 2, 0, ncnt, &network->integerbuf, _state); 20453 ae_assert(highlevelidx>=0, "MLPSetNeuronInfo: incorrect (nonexistent) layer
or neuron
index", _state); 20456 * activation function 20458 if( network->hlneurons.ptr.p_int[highlevelidx*mlpbase_hlnfieldwidth+2]>=0 ) 20460 activationoffset = istart+network->hlneurons.ptr.p_int[highlevelidx*mlpbase_hlnfieldwidth+2]*mlpbase_nfieldwidth; 20461 network->structinfo.ptr.p_int[activationoffset+0] = fkind; 20465 ae_assert(fkind==0, "MLPSetNeuronInfo: you
try to
set activation
function for neuron which can not have one
", _state); 20471 if( network->hlneurons.ptr.p_int[highlevelidx*mlpbase_hlnfieldwidth+3]>=0 ) 20473 network->weights.ptr.p_double[network->hlneurons.ptr.p_int[highlevelidx*mlpbase_hlnfieldwidth+3]] = threshold; 20477 ae_assert(ae_fp_eq(threshold,0), "MLPSetNeuronInfo: you
try to
set non-
zero threshold
for neuron which can not have one
", _state); 20482 /************************************************************************* 20483 This function modifies information about connection from I0-th neuron of 20484 K0-th layer to I1-th neuron of K1-th layer. 20489 I0 - neuron index (within layer) 20491 I1 - neuron index (within layer) 20492 W - connection weight (must be zero for non-existent 20496 1. throws exception if layer or neuron with given index do not exists. 20497 2. throws exception if you try to set non-zero weight for non-existent 20501 Copyright 25.03.2011 by Bochkanov Sergey 20502 *************************************************************************/ 20503 void mlpsetweight(multilayerperceptron* network, 20512 ae_int_t highlevelidx; 20515 ccnt = network->hlconnections.cnt/mlpbase_hlconnfieldwidth; 20520 ae_assert(k0>=0&&k0<network->hllayersizes.cnt, "MLPSetWeight: incorrect (nonexistent) K0
", _state); 20521 ae_assert(i0>=0&&i0<network->hllayersizes.ptr.p_int[k0], "MLPSetWeight: incorrect (nonexistent) I0
", _state); 20522 ae_assert(k1>=0&&k1<network->hllayersizes.cnt, "MLPSetWeight: incorrect (nonexistent) K1
", _state); 20523 ae_assert(i1>=0&&i1<network->hllayersizes.ptr.p_int[k1], "MLPSetWeight: incorrect (nonexistent) I1
", _state); 20524 ae_assert(ae_isfinite(w, _state), "MLPSetWeight: infinite
or NAN weight
", _state); 20529 network->integerbuf.ptr.p_int[0] = k0; 20530 network->integerbuf.ptr.p_int[1] = i0; 20531 network->integerbuf.ptr.p_int[2] = k1; 20532 network->integerbuf.ptr.p_int[3] = i1; 20533 highlevelidx = recsearch(&network->hlconnections, mlpbase_hlconnfieldwidth, 4, 0, ccnt, &network->integerbuf, _state); 20534 if( highlevelidx>=0 ) 20536 network->weights.ptr.p_double[network->hlconnections.ptr.p_int[highlevelidx*mlpbase_hlconnfieldwidth+4]] = w; 20540 ae_assert(ae_fp_eq(w,0), "MLPSetWeight: you
try to
set non-
zero weight
for non-existent connection
", _state); 20545 /************************************************************************* 20546 Neural network activation function 20550 K - function index (zero for linear function) 20554 DF - its derivative 20555 D2F - its second derivative 20558 Copyright 04.11.2007 by Bochkanov Sergey 20559 *************************************************************************/ 20560 void mlpactivationfunction(double net, 20587 * TanH activation function 20589 if( ae_fp_less(ae_fabs(net, _state),100) ) 20591 *f = ae_tanh(net, _state); 20595 *f = ae_sign(net, _state); 20598 *d2f = -2*(*f)*(*df); 20605 * EX activation function 20607 if( ae_fp_greater_eq(net,0) ) 20611 root = ae_sqrt(arg, _state); 20615 *d2f = (root-net*r)/arg; 20619 *f = ae_exp(net, _state); 20627 *f = ae_exp(-ae_sqr(net, _state), _state); 20629 *d2f = -2*(*f+*df*net); 20638 /************************************************************************* 20642 Network - neural network 20643 X - input vector, array[0..NIn-1]. 20646 Y - result. Regression estimate when solving regression task, 20647 vector of posterior probabilities for classification task. 20649 See also MLPProcessI 20652 Copyright 04.11.2007 by Bochkanov Sergey 20653 *************************************************************************/ 20654 void mlpprocess(multilayerperceptron* network, 20655 /* Real */ ae_vector* x, 20656 /* Real */ ae_vector* y, 20661 if( y->cnt<network->structinfo.ptr.p_int[2] ) 20663 ae_vector_set_length(y, network->structinfo.ptr.p_int[2], _state); 20665 mlpinternalprocessvector(&network->structinfo, &network->weights, &network->columnmeans, &network->columnsigmas, &network->neurons, &network->dfdnet, x, y, _state); 20669 /************************************************************************* 20670 'interactive' variant of MLPProcess for languages like Python which 20671 support constructs like "Y = MLPProcess(NN,X)
" and interactive mode of the 20674 This function allocates new array on each call, so it is significantly 20675 slower than its 'non-interactive' counterpart, but it is more convenient 20676 when you call it from command line. 20679 Copyright 21.09.2010 by Bochkanov Sergey 20680 *************************************************************************/ 20681 void mlpprocessi(multilayerperceptron* network, 20682 /* Real */ ae_vector* x, 20683 /* Real */ ae_vector* y, 20687 ae_vector_clear(y); 20689 mlpprocess(network, x, y, _state); 20693 /************************************************************************* 20694 Error of the neural network on dataset. 20697 FOR USERS OF COMMERCIAL EDITION: 20699 ! Commercial version of ALGLIB includes two important improvements of 20701 ! * multicore support (C++ and C# computational cores) 20704 ! First improvement gives close-to-linear speedup on multicore systems. 20705 ! Second improvement gives constant speedup (2-3x, depending on your CPU) 20707 ! In order to use multicore features you have to: 20708 ! * use commercial version of ALGLIB 20709 ! * call this function with "smp_
" prefix, which indicates that 20710 ! multicore code will be used (for multicore support) 20712 ! In order to use SSE features you have to: 20713 ! * use commercial version of ALGLIB on Intel processors 20714 ! * use C++ computational core 20716 ! This note is given for users of commercial edition; if you use GPL 20717 ! edition, you still will be able to call smp-version of this function, 20718 ! but all computations will be done serially. 20720 ! We recommend you to carefully read ALGLIB Reference Manual, section 20721 ! called 'SMP support', before using parallel version of this function. 20725 Network - neural network; 20726 XY - training set, see below for information on the 20727 training set format; 20728 NPoints - points count. 20731 sum-of-squares error, SUM(sqr(y[i]-desired_y[i])/2) 20735 This function uses two different dataset formats - one for regression 20736 networks, another one for classification networks. 20738 For regression networks with NIn inputs and NOut outputs following dataset 20740 * dataset is given by NPoints*(NIn+NOut) matrix 20741 * each row corresponds to one example 20742 * first NIn columns are inputs, next NOut columns are outputs 20744 For classification networks with NIn inputs and NClasses clases following 20745 dataset format is used: 20746 * dataset is given by NPoints*(NIn+1) matrix 20747 * each row corresponds to one example 20748 * first NIn columns are inputs, last column stores class number (from 0 to 20752 Copyright 04.11.2007 by Bochkanov Sergey 20753 *************************************************************************/ 20754 double mlperror(multilayerperceptron* network, 20755 /* Real */ ae_matrix* xy, 20762 ae_assert(xy->rows>=npoints, "MLPError: XY has less than NPoints rows
", _state); 20765 if( mlpissoftmax(network, _state) ) 20767 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+1, "MLPError: XY has less than NIn+1 columns
", _state); 20771 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPError: XY has less than NIn+NOut columns
", _state); 20774 mlpallerrorsx(network, xy, &network->dummysxy, npoints, 0, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 20775 result = ae_sqr(network->err.rmserror, _state)*npoints*mlpgetoutputscount(network, _state)/2; 20780 /************************************************************************* 20781 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 20782 *************************************************************************/ 20783 double _pexec_mlperror(multilayerperceptron* network, 20784 /* Real */ ae_matrix* xy, 20785 ae_int_t npoints, ae_state *_state) 20787 return mlperror(network,xy,npoints, _state); 20791 /************************************************************************* 20792 Error of the neural network on dataset given by sparse matrix. 20795 FOR USERS OF COMMERCIAL EDITION: 20797 ! Commercial version of ALGLIB includes two important improvements of 20799 ! * multicore support (C++ and C# computational cores) 20802 ! First improvement gives close-to-linear speedup on multicore systems. 20803 ! Second improvement gives constant speedup (2-3x, depending on your CPU) 20805 ! In order to use multicore features you have to: 20806 ! * use commercial version of ALGLIB 20807 ! * call this function with "smp_
" prefix, which indicates that 20808 ! multicore code will be used (for multicore support) 20810 ! In order to use SSE features you have to: 20811 ! * use commercial version of ALGLIB on Intel processors 20812 ! * use C++ computational core 20814 ! This note is given for users of commercial edition; if you use GPL 20815 ! edition, you still will be able to call smp-version of this function, 20816 ! but all computations will be done serially. 20818 ! We recommend you to carefully read ALGLIB Reference Manual, section 20819 ! called 'SMP support', before using parallel version of this function. 20823 Network - neural network 20824 XY - training set, see below for information on the 20825 training set format. This function checks correctness 20826 of the dataset (no NANs/INFs, class numbers are 20827 correct) and throws exception when incorrect dataset 20828 is passed. Sparse matrix must use CRS format for 20830 NPoints - points count, >=0 20833 sum-of-squares error, SUM(sqr(y[i]-desired_y[i])/2) 20837 This function uses two different dataset formats - one for regression 20838 networks, another one for classification networks. 20840 For regression networks with NIn inputs and NOut outputs following dataset 20842 * dataset is given by NPoints*(NIn+NOut) matrix 20843 * each row corresponds to one example 20844 * first NIn columns are inputs, next NOut columns are outputs 20846 For classification networks with NIn inputs and NClasses clases following 20847 dataset format is used: 20848 * dataset is given by NPoints*(NIn+1) matrix 20849 * each row corresponds to one example 20850 * first NIn columns are inputs, last column stores class number (from 0 to 20854 Copyright 23.07.2012 by Bochkanov Sergey 20855 *************************************************************************/ 20856 double mlperrorsparse(multilayerperceptron* network, 20864 ae_assert(sparseiscrs(xy, _state), "MLPErrorSparse: XY is not
in CRS format.
", _state); 20865 ae_assert(sparsegetnrows(xy, _state)>=npoints, "MLPErrorSparse: XY has less than NPoints rows
", _state); 20868 if( mlpissoftmax(network, _state) ) 20870 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+1, "MLPErrorSparse: XY has less than NIn+1 columns
", _state); 20874 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPErrorSparse: XY has less than NIn+NOut columns
", _state); 20877 mlpallerrorsx(network, &network->dummydxy, xy, npoints, 1, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 20878 result = ae_sqr(network->err.rmserror, _state)*npoints*mlpgetoutputscount(network, _state)/2; 20883 /************************************************************************* 20884 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 20885 *************************************************************************/ 20886 double _pexec_mlperrorsparse(multilayerperceptron* network, 20888 ae_int_t npoints, ae_state *_state) 20890 return mlperrorsparse(network,xy,npoints, _state); 20894 /************************************************************************* 20895 Natural error function for neural network, internal subroutine. 20897 NOTE: this function is single-threaded. Unlike other error function, it 20898 receives no speed-up from being executed in SMP mode. 20901 Copyright 04.11.2007 by Bochkanov Sergey 20902 *************************************************************************/ 20903 double mlperrorn(multilayerperceptron* network, 20904 /* Real */ ae_matrix* xy, 20917 mlpproperties(network, &nin, &nout, &wcount, _state); 20919 for(i=0; i<=ssize-1; i++) 20925 ae_v_move(&network->x.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nin-1)); 20926 mlpprocess(network, &network->x, &network->y, _state); 20929 * Update error function 20931 if( network->structinfo.ptr.p_int[6]==0 ) 20935 * Least squares error function 20937 ae_v_sub(&network->y.ptr.p_double[0], 1, &xy->ptr.pp_double[i][nin], 1, ae_v_len(0,nout-1)); 20938 e = ae_v_dotproduct(&network->y.ptr.p_double[0], 1, &network->y.ptr.p_double[0], 1, ae_v_len(0,nout-1)); 20939 result = result+e/2; 20945 * Cross-entropy error function 20947 k = ae_round(xy->ptr.pp_double[i][nin], _state); 20950 result = result+mlpbase_safecrossentropy(1, network->y.ptr.p_double[k], _state); 20958 /************************************************************************* 20959 Classification error of the neural network on dataset. 20962 FOR USERS OF COMMERCIAL EDITION: 20964 ! Commercial version of ALGLIB includes two important improvements of 20966 ! * multicore support (C++ and C# computational cores) 20969 ! First improvement gives close-to-linear speedup on multicore systems. 20970 ! Second improvement gives constant speedup (2-3x depending on your CPU) 20972 ! In order to use multicore features you have to: 20973 ! * use commercial version of ALGLIB 20974 ! * call this function with "smp_
" prefix, which indicates that 20975 ! multicore code will be used (for multicore support) 20977 ! In order to use SSE features you have to: 20978 ! * use commercial version of ALGLIB on Intel processors 20979 ! * use C++ computational core 20981 ! This note is given for users of commercial edition; if you use GPL 20982 ! edition, you still will be able to call smp-version of this function, 20983 ! but all computations will be done serially. 20985 ! We recommend you to carefully read ALGLIB Reference Manual, section 20986 ! called 'SMP support', before using parallel version of this function. 20990 Network - neural network; 20991 XY - training set, see below for information on the 20992 training set format; 20993 NPoints - points count. 20996 classification error (number of misclassified cases) 21000 This function uses two different dataset formats - one for regression 21001 networks, another one for classification networks. 21003 For regression networks with NIn inputs and NOut outputs following dataset 21005 * dataset is given by NPoints*(NIn+NOut) matrix 21006 * each row corresponds to one example 21007 * first NIn columns are inputs, next NOut columns are outputs 21009 For classification networks with NIn inputs and NClasses clases following 21010 dataset format is used: 21011 * dataset is given by NPoints*(NIn+1) matrix 21012 * each row corresponds to one example 21013 * first NIn columns are inputs, last column stores class number (from 0 to 21017 Copyright 04.11.2007 by Bochkanov Sergey 21018 *************************************************************************/ 21019 ae_int_t mlpclserror(multilayerperceptron* network, 21020 /* Real */ ae_matrix* xy, 21027 ae_assert(xy->rows>=npoints, "MLPClsError: XY has less than NPoints rows
", _state); 21030 if( mlpissoftmax(network, _state) ) 21032 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+1, "MLPClsError: XY has less than NIn+1 columns
", _state); 21036 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPClsError: XY has less than NIn+NOut columns
", _state); 21039 mlpallerrorsx(network, xy, &network->dummysxy, npoints, 0, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 21040 result = ae_round(npoints*network->err.relclserror, _state); 21045 /************************************************************************* 21046 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21047 *************************************************************************/ 21048 ae_int_t _pexec_mlpclserror(multilayerperceptron* network, 21049 /* Real */ ae_matrix* xy, 21050 ae_int_t npoints, ae_state *_state) 21052 return mlpclserror(network,xy,npoints, _state); 21056 /************************************************************************* 21057 Relative classification error on the test set. 21060 FOR USERS OF COMMERCIAL EDITION: 21062 ! Commercial version of ALGLIB includes two important improvements of 21064 ! * multicore support (C++ and C# computational cores) 21067 ! First improvement gives close-to-linear speedup on multicore systems. 21068 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21070 ! In order to use multicore features you have to: 21071 ! * use commercial version of ALGLIB 21072 ! * call this function with "smp_
" prefix, which indicates that 21073 ! multicore code will be used (for multicore support) 21075 ! In order to use SSE features you have to: 21076 ! * use commercial version of ALGLIB on Intel processors 21077 ! * use C++ computational core 21079 ! This note is given for users of commercial edition; if you use GPL 21080 ! edition, you still will be able to call smp-version of this function, 21081 ! but all computations will be done serially. 21083 ! We recommend you to carefully read ALGLIB Reference Manual, section 21084 ! called 'SMP support', before using parallel version of this function. 21088 Network - neural network; 21089 XY - training set, see below for information on the 21090 training set format; 21091 NPoints - points count. 21094 Percent of incorrectly classified cases. Works both for classifier 21095 networks and general purpose networks used as classifiers. 21099 This function uses two different dataset formats - one for regression 21100 networks, another one for classification networks. 21102 For regression networks with NIn inputs and NOut outputs following dataset 21104 * dataset is given by NPoints*(NIn+NOut) matrix 21105 * each row corresponds to one example 21106 * first NIn columns are inputs, next NOut columns are outputs 21108 For classification networks with NIn inputs and NClasses clases following 21109 dataset format is used: 21110 * dataset is given by NPoints*(NIn+1) matrix 21111 * each row corresponds to one example 21112 * first NIn columns are inputs, last column stores class number (from 0 to 21116 Copyright 25.12.2008 by Bochkanov Sergey 21117 *************************************************************************/ 21118 double mlprelclserror(multilayerperceptron* network, 21119 /* Real */ ae_matrix* xy, 21126 ae_assert(xy->rows>=npoints, "MLPRelClsError: XY has less than NPoints rows
", _state); 21129 if( mlpissoftmax(network, _state) ) 21131 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+1, "MLPRelClsError: XY has less than NIn+1 columns
", _state); 21135 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPRelClsError: XY has less than NIn+NOut columns
", _state); 21140 result = (double)mlpclserror(network, xy, npoints, _state)/(double)npoints; 21150 /************************************************************************* 21151 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21152 *************************************************************************/ 21153 double _pexec_mlprelclserror(multilayerperceptron* network, 21154 /* Real */ ae_matrix* xy, 21155 ae_int_t npoints, ae_state *_state) 21157 return mlprelclserror(network,xy,npoints, _state); 21161 /************************************************************************* 21162 Relative classification error on the test set given by sparse matrix. 21165 FOR USERS OF COMMERCIAL EDITION: 21167 ! Commercial version of ALGLIB includes two important improvements of 21169 ! * multicore support (C++ and C# computational cores) 21172 ! First improvement gives close-to-linear speedup on multicore systems. 21173 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21175 ! In order to use multicore features you have to: 21176 ! * use commercial version of ALGLIB 21177 ! * call this function with "smp_
" prefix, which indicates that 21178 ! multicore code will be used (for multicore support) 21180 ! In order to use SSE features you have to: 21181 ! * use commercial version of ALGLIB on Intel processors 21182 ! * use C++ computational core 21184 ! This note is given for users of commercial edition; if you use GPL 21185 ! edition, you still will be able to call smp-version of this function, 21186 ! but all computations will be done serially. 21188 ! We recommend you to carefully read ALGLIB Reference Manual, section 21189 ! called 'SMP support', before using parallel version of this function. 21193 Network - neural network; 21194 XY - training set, see below for information on the 21195 training set format. Sparse matrix must use CRS format 21197 NPoints - points count, >=0. 21200 Percent of incorrectly classified cases. Works both for classifier 21201 networks and general purpose networks used as classifiers. 21205 This function uses two different dataset formats - one for regression 21206 networks, another one for classification networks. 21208 For regression networks with NIn inputs and NOut outputs following dataset 21210 * dataset is given by NPoints*(NIn+NOut) matrix 21211 * each row corresponds to one example 21212 * first NIn columns are inputs, next NOut columns are outputs 21214 For classification networks with NIn inputs and NClasses clases following 21215 dataset format is used: 21216 * dataset is given by NPoints*(NIn+1) matrix 21217 * each row corresponds to one example 21218 * first NIn columns are inputs, last column stores class number (from 0 to 21222 Copyright 09.08.2012 by Bochkanov Sergey 21223 *************************************************************************/ 21224 double mlprelclserrorsparse(multilayerperceptron* network, 21232 ae_assert(sparseiscrs(xy, _state), "MLPRelClsErrorSparse: sparse matrix XY is not
in CRS format.
", _state); 21233 ae_assert(sparsegetnrows(xy, _state)>=npoints, "MLPRelClsErrorSparse: sparse matrix XY has less than NPoints rows
", _state); 21236 if( mlpissoftmax(network, _state) ) 21238 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+1, "MLPRelClsErrorSparse: sparse matrix XY has less than NIn+1 columns
", _state); 21242 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPRelClsErrorSparse: sparse matrix XY has less than NIn+NOut columns
", _state); 21245 mlpallerrorsx(network, &network->dummydxy, xy, npoints, 1, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 21246 result = network->err.relclserror; 21251 /************************************************************************* 21252 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21253 *************************************************************************/ 21254 double _pexec_mlprelclserrorsparse(multilayerperceptron* network, 21256 ae_int_t npoints, ae_state *_state) 21258 return mlprelclserrorsparse(network,xy,npoints, _state); 21262 /************************************************************************* 21263 Average cross-entropy (in bits per element) on the test set. 21266 FOR USERS OF COMMERCIAL EDITION: 21268 ! Commercial version of ALGLIB includes two important improvements of 21270 ! * multicore support (C++ and C# computational cores) 21273 ! First improvement gives close-to-linear speedup on multicore systems. 21274 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21276 ! In order to use multicore features you have to: 21277 ! * use commercial version of ALGLIB 21278 ! * call this function with "smp_
" prefix, which indicates that 21279 ! multicore code will be used (for multicore support) 21281 ! In order to use SSE features you have to: 21282 ! * use commercial version of ALGLIB on Intel processors 21283 ! * use C++ computational core 21285 ! This note is given for users of commercial edition; if you use GPL 21286 ! edition, you still will be able to call smp-version of this function, 21287 ! but all computations will be done serially. 21289 ! We recommend you to carefully read ALGLIB Reference Manual, section 21290 ! called 'SMP support', before using parallel version of this function. 21294 Network - neural network; 21295 XY - training set, see below for information on the 21296 training set format; 21297 NPoints - points count. 21300 CrossEntropy/(NPoints*LN(2)). 21301 Zero if network solves regression task. 21305 This function uses two different dataset formats - one for regression 21306 networks, another one for classification networks. 21308 For regression networks with NIn inputs and NOut outputs following dataset 21310 * dataset is given by NPoints*(NIn+NOut) matrix 21311 * each row corresponds to one example 21312 * first NIn columns are inputs, next NOut columns are outputs 21314 For classification networks with NIn inputs and NClasses clases following 21315 dataset format is used: 21316 * dataset is given by NPoints*(NIn+1) matrix 21317 * each row corresponds to one example 21318 * first NIn columns are inputs, last column stores class number (from 0 to 21322 Copyright 08.01.2009 by Bochkanov Sergey 21323 *************************************************************************/ 21324 double mlpavgce(multilayerperceptron* network, 21325 /* Real */ ae_matrix* xy, 21332 ae_assert(xy->rows>=npoints, "MLPAvgCE: XY has less than NPoints rows
", _state); 21335 if( mlpissoftmax(network, _state) ) 21337 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+1, "MLPAvgCE: XY has less than NIn+1 columns
", _state); 21341 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPAvgCE: XY has less than NIn+NOut columns
", _state); 21344 mlpallerrorsx(network, xy, &network->dummysxy, npoints, 0, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 21345 result = network->err.avgce; 21350 /************************************************************************* 21351 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21352 *************************************************************************/ 21353 double _pexec_mlpavgce(multilayerperceptron* network, 21354 /* Real */ ae_matrix* xy, 21355 ae_int_t npoints, ae_state *_state) 21357 return mlpavgce(network,xy,npoints, _state); 21361 /************************************************************************* 21362 Average cross-entropy (in bits per element) on the test set given by 21366 FOR USERS OF COMMERCIAL EDITION: 21368 ! Commercial version of ALGLIB includes two important improvements of 21370 ! * multicore support (C++ and C# computational cores) 21373 ! First improvement gives close-to-linear speedup on multicore systems. 21374 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21376 ! In order to use multicore features you have to: 21377 ! * use commercial version of ALGLIB 21378 ! * call this function with "smp_
" prefix, which indicates that 21379 ! multicore code will be used (for multicore support) 21381 ! In order to use SSE features you have to: 21382 ! * use commercial version of ALGLIB on Intel processors 21383 ! * use C++ computational core 21385 ! This note is given for users of commercial edition; if you use GPL 21386 ! edition, you still will be able to call smp-version of this function, 21387 ! but all computations will be done serially. 21389 ! We recommend you to carefully read ALGLIB Reference Manual, section 21390 ! called 'SMP support', before using parallel version of this function. 21394 Network - neural network; 21395 XY - training set, see below for information on the 21396 training set format. This function checks correctness 21397 of the dataset (no NANs/INFs, class numbers are 21398 correct) and throws exception when incorrect dataset 21399 is passed. Sparse matrix must use CRS format for 21401 NPoints - points count, >=0. 21404 CrossEntropy/(NPoints*LN(2)). 21405 Zero if network solves regression task. 21409 This function uses two different dataset formats - one for regression 21410 networks, another one for classification networks. 21412 For regression networks with NIn inputs and NOut outputs following dataset 21414 * dataset is given by NPoints*(NIn+NOut) matrix 21415 * each row corresponds to one example 21416 * first NIn columns are inputs, next NOut columns are outputs 21418 For classification networks with NIn inputs and NClasses clases following 21419 dataset format is used: 21420 * dataset is given by NPoints*(NIn+1) matrix 21421 * each row corresponds to one example 21422 * first NIn columns are inputs, last column stores class number (from 0 to 21426 Copyright 9.08.2012 by Bochkanov Sergey 21427 *************************************************************************/ 21428 double mlpavgcesparse(multilayerperceptron* network, 21436 ae_assert(sparseiscrs(xy, _state), "MLPAvgCESparse: sparse matrix XY is not
in CRS format.
", _state); 21437 ae_assert(sparsegetnrows(xy, _state)>=npoints, "MLPAvgCESparse: sparse matrix XY has less than NPoints rows
", _state); 21440 if( mlpissoftmax(network, _state) ) 21442 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+1, "MLPAvgCESparse: sparse matrix XY has less than NIn+1 columns
", _state); 21446 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPAvgCESparse: sparse matrix XY has less than NIn+NOut columns
", _state); 21449 mlpallerrorsx(network, &network->dummydxy, xy, npoints, 1, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 21450 result = network->err.avgce; 21455 /************************************************************************* 21456 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21457 *************************************************************************/ 21458 double _pexec_mlpavgcesparse(multilayerperceptron* network, 21460 ae_int_t npoints, ae_state *_state) 21462 return mlpavgcesparse(network,xy,npoints, _state); 21466 /************************************************************************* 21467 RMS error on the test set given. 21470 FOR USERS OF COMMERCIAL EDITION: 21472 ! Commercial version of ALGLIB includes two important improvements of 21474 ! * multicore support (C++ and C# computational cores) 21477 ! First improvement gives close-to-linear speedup on multicore systems. 21478 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21480 ! In order to use multicore features you have to: 21481 ! * use commercial version of ALGLIB 21482 ! * call this function with "smp_
" prefix, which indicates that 21483 ! multicore code will be used (for multicore support) 21485 ! In order to use SSE features you have to: 21486 ! * use commercial version of ALGLIB on Intel processors 21487 ! * use C++ computational core 21489 ! This note is given for users of commercial edition; if you use GPL 21490 ! edition, you still will be able to call smp-version of this function, 21491 ! but all computations will be done serially. 21493 ! We recommend you to carefully read ALGLIB Reference Manual, section 21494 ! called 'SMP support', before using parallel version of this function. 21498 Network - neural network; 21499 XY - training set, see below for information on the 21500 training set format; 21501 NPoints - points count. 21504 Root mean square error. Its meaning for regression task is obvious. As for 21505 classification task, RMS error means error when estimating posterior 21510 This function uses two different dataset formats - one for regression 21511 networks, another one for classification networks. 21513 For regression networks with NIn inputs and NOut outputs following dataset 21515 * dataset is given by NPoints*(NIn+NOut) matrix 21516 * each row corresponds to one example 21517 * first NIn columns are inputs, next NOut columns are outputs 21519 For classification networks with NIn inputs and NClasses clases following 21520 dataset format is used: 21521 * dataset is given by NPoints*(NIn+1) matrix 21522 * each row corresponds to one example 21523 * first NIn columns are inputs, last column stores class number (from 0 to 21527 Copyright 04.11.2007 by Bochkanov Sergey 21528 *************************************************************************/ 21529 double mlprmserror(multilayerperceptron* network, 21530 /* Real */ ae_matrix* xy, 21537 ae_assert(xy->rows>=npoints, "MLPRMSError: XY has less than NPoints rows
", _state); 21540 if( mlpissoftmax(network, _state) ) 21542 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+1, "MLPRMSError: XY has less than NIn+1 columns
", _state); 21546 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPRMSError: XY has less than NIn+NOut columns
", _state); 21549 mlpallerrorsx(network, xy, &network->dummysxy, npoints, 0, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 21550 result = network->err.rmserror; 21555 /************************************************************************* 21556 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21557 *************************************************************************/ 21558 double _pexec_mlprmserror(multilayerperceptron* network, 21559 /* Real */ ae_matrix* xy, 21560 ae_int_t npoints, ae_state *_state) 21562 return mlprmserror(network,xy,npoints, _state); 21566 /************************************************************************* 21567 RMS error on the test set given by sparse matrix. 21570 FOR USERS OF COMMERCIAL EDITION: 21572 ! Commercial version of ALGLIB includes two important improvements of 21574 ! * multicore support (C++ and C# computational cores) 21577 ! First improvement gives close-to-linear speedup on multicore systems. 21578 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21580 ! In order to use multicore features you have to: 21581 ! * use commercial version of ALGLIB 21582 ! * call this function with "smp_
" prefix, which indicates that 21583 ! multicore code will be used (for multicore support) 21585 ! In order to use SSE features you have to: 21586 ! * use commercial version of ALGLIB on Intel processors 21587 ! * use C++ computational core 21589 ! This note is given for users of commercial edition; if you use GPL 21590 ! edition, you still will be able to call smp-version of this function, 21591 ! but all computations will be done serially. 21593 ! We recommend you to carefully read ALGLIB Reference Manual, section 21594 ! called 'SMP support', before using parallel version of this function. 21598 Network - neural network; 21599 XY - training set, see below for information on the 21600 training set format. This function checks correctness 21601 of the dataset (no NANs/INFs, class numbers are 21602 correct) and throws exception when incorrect dataset 21603 is passed. Sparse matrix must use CRS format for 21605 NPoints - points count, >=0. 21608 Root mean square error. Its meaning for regression task is obvious. As for 21609 classification task, RMS error means error when estimating posterior 21614 This function uses two different dataset formats - one for regression 21615 networks, another one for classification networks. 21617 For regression networks with NIn inputs and NOut outputs following dataset 21619 * dataset is given by NPoints*(NIn+NOut) matrix 21620 * each row corresponds to one example 21621 * first NIn columns are inputs, next NOut columns are outputs 21623 For classification networks with NIn inputs and NClasses clases following 21624 dataset format is used: 21625 * dataset is given by NPoints*(NIn+1) matrix 21626 * each row corresponds to one example 21627 * first NIn columns are inputs, last column stores class number (from 0 to 21631 Copyright 09.08.2012 by Bochkanov Sergey 21632 *************************************************************************/ 21633 double mlprmserrorsparse(multilayerperceptron* network, 21641 ae_assert(sparseiscrs(xy, _state), "MLPRMSErrorSparse: sparse matrix XY is not
in CRS format.
", _state); 21642 ae_assert(sparsegetnrows(xy, _state)>=npoints, "MLPRMSErrorSparse: sparse matrix XY has less than NPoints rows
", _state); 21645 if( mlpissoftmax(network, _state) ) 21647 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+1, "MLPRMSErrorSparse: sparse matrix XY has less than NIn+1 columns
", _state); 21651 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPRMSErrorSparse: sparse matrix XY has less than NIn+NOut columns
", _state); 21654 mlpallerrorsx(network, &network->dummydxy, xy, npoints, 1, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 21655 result = network->err.rmserror; 21660 /************************************************************************* 21661 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21662 *************************************************************************/ 21663 double _pexec_mlprmserrorsparse(multilayerperceptron* network, 21665 ae_int_t npoints, ae_state *_state) 21667 return mlprmserrorsparse(network,xy,npoints, _state); 21671 /************************************************************************* 21672 Average absolute error on the test set. 21675 FOR USERS OF COMMERCIAL EDITION: 21677 ! Commercial version of ALGLIB includes two important improvements of 21679 ! * multicore support (C++ and C# computational cores) 21682 ! First improvement gives close-to-linear speedup on multicore systems. 21683 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21685 ! In order to use multicore features you have to: 21686 ! * use commercial version of ALGLIB 21687 ! * call this function with "smp_
" prefix, which indicates that 21688 ! multicore code will be used (for multicore support) 21690 ! In order to use SSE features you have to: 21691 ! * use commercial version of ALGLIB on Intel processors 21692 ! * use C++ computational core 21694 ! This note is given for users of commercial edition; if you use GPL 21695 ! edition, you still will be able to call smp-version of this function, 21696 ! but all computations will be done serially. 21698 ! We recommend you to carefully read ALGLIB Reference Manual, section 21699 ! called 'SMP support', before using parallel version of this function. 21703 Network - neural network; 21704 XY - training set, see below for information on the 21705 training set format; 21706 NPoints - points count. 21709 Its meaning for regression task is obvious. As for classification task, it 21710 means average error when estimating posterior probabilities. 21714 This function uses two different dataset formats - one for regression 21715 networks, another one for classification networks. 21717 For regression networks with NIn inputs and NOut outputs following dataset 21719 * dataset is given by NPoints*(NIn+NOut) matrix 21720 * each row corresponds to one example 21721 * first NIn columns are inputs, next NOut columns are outputs 21723 For classification networks with NIn inputs and NClasses clases following 21724 dataset format is used: 21725 * dataset is given by NPoints*(NIn+1) matrix 21726 * each row corresponds to one example 21727 * first NIn columns are inputs, last column stores class number (from 0 to 21731 Copyright 11.03.2008 by Bochkanov Sergey 21732 *************************************************************************/ 21733 double mlpavgerror(multilayerperceptron* network, 21734 /* Real */ ae_matrix* xy, 21741 ae_assert(xy->rows>=npoints, "MLPAvgError: XY has less than NPoints rows
", _state); 21744 if( mlpissoftmax(network, _state) ) 21746 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+1, "MLPAvgError: XY has less than NIn+1 columns
", _state); 21750 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPAvgError: XY has less than NIn+NOut columns
", _state); 21753 mlpallerrorsx(network, xy, &network->dummysxy, npoints, 0, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 21754 result = network->err.avgerror; 21759 /************************************************************************* 21760 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21761 *************************************************************************/ 21762 double _pexec_mlpavgerror(multilayerperceptron* network, 21763 /* Real */ ae_matrix* xy, 21764 ae_int_t npoints, ae_state *_state) 21766 return mlpavgerror(network,xy,npoints, _state); 21770 /************************************************************************* 21771 Average absolute error on the test set given by sparse matrix. 21774 FOR USERS OF COMMERCIAL EDITION: 21776 ! Commercial version of ALGLIB includes two important improvements of 21778 ! * multicore support (C++ and C# computational cores) 21781 ! First improvement gives close-to-linear speedup on multicore systems. 21782 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21784 ! In order to use multicore features you have to: 21785 ! * use commercial version of ALGLIB 21786 ! * call this function with "smp_
" prefix, which indicates that 21787 ! multicore code will be used (for multicore support) 21789 ! In order to use SSE features you have to: 21790 ! * use commercial version of ALGLIB on Intel processors 21791 ! * use C++ computational core 21793 ! This note is given for users of commercial edition; if you use GPL 21794 ! edition, you still will be able to call smp-version of this function, 21795 ! but all computations will be done serially. 21797 ! We recommend you to carefully read ALGLIB Reference Manual, section 21798 ! called 'SMP support', before using parallel version of this function. 21802 Network - neural network; 21803 XY - training set, see below for information on the 21804 training set format. This function checks correctness 21805 of the dataset (no NANs/INFs, class numbers are 21806 correct) and throws exception when incorrect dataset 21807 is passed. Sparse matrix must use CRS format for 21809 NPoints - points count, >=0. 21812 Its meaning for regression task is obvious. As for classification task, it 21813 means average error when estimating posterior probabilities. 21817 This function uses two different dataset formats - one for regression 21818 networks, another one for classification networks. 21820 For regression networks with NIn inputs and NOut outputs following dataset 21822 * dataset is given by NPoints*(NIn+NOut) matrix 21823 * each row corresponds to one example 21824 * first NIn columns are inputs, next NOut columns are outputs 21826 For classification networks with NIn inputs and NClasses clases following 21827 dataset format is used: 21828 * dataset is given by NPoints*(NIn+1) matrix 21829 * each row corresponds to one example 21830 * first NIn columns are inputs, last column stores class number (from 0 to 21834 Copyright 09.08.2012 by Bochkanov Sergey 21835 *************************************************************************/ 21836 double mlpavgerrorsparse(multilayerperceptron* network, 21844 ae_assert(sparseiscrs(xy, _state), "MLPAvgErrorSparse: XY is not
in CRS format.
", _state); 21845 ae_assert(sparsegetnrows(xy, _state)>=npoints, "MLPAvgErrorSparse: XY has less than NPoints rows
", _state); 21848 if( mlpissoftmax(network, _state) ) 21850 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+1, "MLPAvgErrorSparse: XY has less than NIn+1 columns
", _state); 21854 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPAvgErrorSparse: XY has less than NIn+NOut columns
", _state); 21857 mlpallerrorsx(network, &network->dummydxy, xy, npoints, 1, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 21858 result = network->err.avgerror; 21863 /************************************************************************* 21864 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21865 *************************************************************************/ 21866 double _pexec_mlpavgerrorsparse(multilayerperceptron* network, 21868 ae_int_t npoints, ae_state *_state) 21870 return mlpavgerrorsparse(network,xy,npoints, _state); 21874 /************************************************************************* 21875 Average relative error on the test set. 21878 FOR USERS OF COMMERCIAL EDITION: 21880 ! Commercial version of ALGLIB includes two important improvements of 21882 ! * multicore support (C++ and C# computational cores) 21885 ! First improvement gives close-to-linear speedup on multicore systems. 21886 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21888 ! In order to use multicore features you have to: 21889 ! * use commercial version of ALGLIB 21890 ! * call this function with "smp_
" prefix, which indicates that 21891 ! multicore code will be used (for multicore support) 21893 ! In order to use SSE features you have to: 21894 ! * use commercial version of ALGLIB on Intel processors 21895 ! * use C++ computational core 21897 ! This note is given for users of commercial edition; if you use GPL 21898 ! edition, you still will be able to call smp-version of this function, 21899 ! but all computations will be done serially. 21901 ! We recommend you to carefully read ALGLIB Reference Manual, section 21902 ! called 'SMP support', before using parallel version of this function. 21906 Network - neural network; 21907 XY - training set, see below for information on the 21908 training set format; 21909 NPoints - points count. 21912 Its meaning for regression task is obvious. As for classification task, it 21913 means average relative error when estimating posterior probability of 21914 belonging to the correct class. 21918 This function uses two different dataset formats - one for regression 21919 networks, another one for classification networks. 21921 For regression networks with NIn inputs and NOut outputs following dataset 21923 * dataset is given by NPoints*(NIn+NOut) matrix 21924 * each row corresponds to one example 21925 * first NIn columns are inputs, next NOut columns are outputs 21927 For classification networks with NIn inputs and NClasses clases following 21928 dataset format is used: 21929 * dataset is given by NPoints*(NIn+1) matrix 21930 * each row corresponds to one example 21931 * first NIn columns are inputs, last column stores class number (from 0 to 21935 Copyright 11.03.2008 by Bochkanov Sergey 21936 *************************************************************************/ 21937 double mlpavgrelerror(multilayerperceptron* network, 21938 /* Real */ ae_matrix* xy, 21945 ae_assert(xy->rows>=npoints, "MLPAvgRelError: XY has less than NPoints rows
", _state); 21948 if( mlpissoftmax(network, _state) ) 21950 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+1, "MLPAvgRelError: XY has less than NIn+1 columns
", _state); 21954 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPAvgRelError: XY has less than NIn+NOut columns
", _state); 21957 mlpallerrorsx(network, xy, &network->dummysxy, npoints, 0, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 21958 result = network->err.avgrelerror; 21963 /************************************************************************* 21964 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 21965 *************************************************************************/ 21966 double _pexec_mlpavgrelerror(multilayerperceptron* network, 21967 /* Real */ ae_matrix* xy, 21968 ae_int_t npoints, ae_state *_state) 21970 return mlpavgrelerror(network,xy,npoints, _state); 21974 /************************************************************************* 21975 Average relative error on the test set given by sparse matrix. 21978 FOR USERS OF COMMERCIAL EDITION: 21980 ! Commercial version of ALGLIB includes two important improvements of 21982 ! * multicore support (C++ and C# computational cores) 21985 ! First improvement gives close-to-linear speedup on multicore systems. 21986 ! Second improvement gives constant speedup (2-3x depending on your CPU) 21988 ! In order to use multicore features you have to: 21989 ! * use commercial version of ALGLIB 21990 ! * call this function with "smp_
" prefix, which indicates that 21991 ! multicore code will be used (for multicore support) 21993 ! In order to use SSE features you have to: 21994 ! * use commercial version of ALGLIB on Intel processors 21995 ! * use C++ computational core 21997 ! This note is given for users of commercial edition; if you use GPL 21998 ! edition, you still will be able to call smp-version of this function, 21999 ! but all computations will be done serially. 22001 ! We recommend you to carefully read ALGLIB Reference Manual, section 22002 ! called 'SMP support', before using parallel version of this function. 22006 Network - neural network; 22007 XY - training set, see below for information on the 22008 training set format. This function checks correctness 22009 of the dataset (no NANs/INFs, class numbers are 22010 correct) and throws exception when incorrect dataset 22011 is passed. Sparse matrix must use CRS format for 22013 NPoints - points count, >=0. 22016 Its meaning for regression task is obvious. As for classification task, it 22017 means average relative error when estimating posterior probability of 22018 belonging to the correct class. 22022 This function uses two different dataset formats - one for regression 22023 networks, another one for classification networks. 22025 For regression networks with NIn inputs and NOut outputs following dataset 22027 * dataset is given by NPoints*(NIn+NOut) matrix 22028 * each row corresponds to one example 22029 * first NIn columns are inputs, next NOut columns are outputs 22031 For classification networks with NIn inputs and NClasses clases following 22032 dataset format is used: 22033 * dataset is given by NPoints*(NIn+1) matrix 22034 * each row corresponds to one example 22035 * first NIn columns are inputs, last column stores class number (from 0 to 22039 Copyright 09.08.2012 by Bochkanov Sergey 22040 *************************************************************************/ 22041 double mlpavgrelerrorsparse(multilayerperceptron* network, 22049 ae_assert(sparseiscrs(xy, _state), "MLPAvgRelErrorSparse: XY is not
in CRS format.
", _state); 22050 ae_assert(sparsegetnrows(xy, _state)>=npoints, "MLPAvgRelErrorSparse: XY has less than NPoints rows
", _state); 22053 if( mlpissoftmax(network, _state) ) 22055 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+1, "MLPAvgRelErrorSparse: XY has less than NIn+1 columns
", _state); 22059 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPAvgRelErrorSparse: XY has less than NIn+NOut columns
", _state); 22062 mlpallerrorsx(network, &network->dummydxy, xy, npoints, 1, &network->dummyidx, 0, npoints, 0, &network->buf, &network->err, _state); 22063 result = network->err.avgrelerror; 22068 /************************************************************************* 22069 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 22070 *************************************************************************/ 22071 double _pexec_mlpavgrelerrorsparse(multilayerperceptron* network, 22073 ae_int_t npoints, ae_state *_state) 22075 return mlpavgrelerrorsparse(network,xy,npoints, _state); 22079 /************************************************************************* 22080 Gradient calculation 22083 Network - network initialized with one of the network creation funcs 22084 X - input vector, length of array must be at least NIn 22085 DesiredY- desired outputs, length of array must be at least NOut 22086 Grad - possibly preallocated array. If size of array is smaller 22087 than WCount, it will be reallocated. It is recommended to 22088 reuse previously allocated array to reduce allocation 22092 E - error function, SUM(sqr(y[i]-desiredy[i])/2,i) 22093 Grad - gradient of E with respect to weights of network, array[WCount] 22096 Copyright 04.11.2007 by Bochkanov Sergey 22097 *************************************************************************/ 22098 void mlpgrad(multilayerperceptron* network, 22099 /* Real */ ae_vector* x, 22100 /* Real */ ae_vector* desiredy, 22102 /* Real */ ae_vector* grad, 22115 rvectorsetlengthatleast(grad, network->structinfo.ptr.p_int[4], _state); 22118 * Prepare dError/dOut, internal structures 22120 mlpprocess(network, x, &network->y, _state); 22121 nout = network->structinfo.ptr.p_int[2]; 22122 ntotal = network->structinfo.ptr.p_int[3]; 22124 for(i=0; i<=ntotal-1; i++) 22126 network->derror.ptr.p_double[i] = 0; 22128 for(i=0; i<=nout-1; i++) 22130 network->derror.ptr.p_double[ntotal-nout+i] = network->y.ptr.p_double[i]-desiredy->ptr.p_double[i]; 22131 *e = *e+ae_sqr(network->y.ptr.p_double[i]-desiredy->ptr.p_double[i], _state)/2; 22137 mlpbase_mlpinternalcalculategradient(network, &network->neurons, &network->weights, &network->derror, grad, ae_false, _state); 22141 /************************************************************************* 22142 Gradient calculation (natural error function is used) 22145 Network - network initialized with one of the network creation funcs 22146 X - input vector, length of array must be at least NIn 22147 DesiredY- desired outputs, length of array must be at least NOut 22148 Grad - possibly preallocated array. If size of array is smaller 22149 than WCount, it will be reallocated. It is recommended to 22150 reuse previously allocated array to reduce allocation 22154 E - error function, sum-of-squares for regression networks, 22155 cross-entropy for classification networks. 22156 Grad - gradient of E with respect to weights of network, array[WCount] 22159 Copyright 04.11.2007 by Bochkanov Sergey 22160 *************************************************************************/ 22161 void mlpgradn(multilayerperceptron* network, 22162 /* Real */ ae_vector* x, 22163 /* Real */ ae_vector* desiredy, 22165 /* Real */ ae_vector* grad, 22179 rvectorsetlengthatleast(grad, network->structinfo.ptr.p_int[4], _state); 22182 * Prepare dError/dOut, internal structures 22184 mlpprocess(network, x, &network->y, _state); 22185 nout = network->structinfo.ptr.p_int[2]; 22186 ntotal = network->structinfo.ptr.p_int[3]; 22187 for(i=0; i<=ntotal-1; i++) 22189 network->derror.ptr.p_double[i] = 0; 22192 if( network->structinfo.ptr.p_int[6]==0 ) 22196 * Regression network, least squares 22198 for(i=0; i<=nout-1; i++) 22200 network->derror.ptr.p_double[ntotal-nout+i] = network->y.ptr.p_double[i]-desiredy->ptr.p_double[i]; 22201 *e = *e+ae_sqr(network->y.ptr.p_double[i]-desiredy->ptr.p_double[i], _state)/2; 22208 * Classification network, cross-entropy 22211 for(i=0; i<=nout-1; i++) 22213 s = s+desiredy->ptr.p_double[i]; 22215 for(i=0; i<=nout-1; i++) 22217 network->derror.ptr.p_double[ntotal-nout+i] = s*network->y.ptr.p_double[i]-desiredy->ptr.p_double[i]; 22218 *e = *e+mlpbase_safecrossentropy(desiredy->ptr.p_double[i], network->y.ptr.p_double[i], _state); 22225 mlpbase_mlpinternalcalculategradient(network, &network->neurons, &network->weights, &network->derror, grad, ae_true, _state); 22229 /************************************************************************* 22230 Batch gradient calculation for a set of inputs/outputs 22233 FOR USERS OF COMMERCIAL EDITION: 22235 ! Commercial version of ALGLIB includes two important improvements of 22237 ! * multicore support (C++ and C# computational cores) 22240 ! First improvement gives close-to-linear speedup on multicore systems. 22241 ! Second improvement gives constant speedup (2-3x depending on your CPU) 22243 ! In order to use multicore features you have to: 22244 ! * use commercial version of ALGLIB 22245 ! * call this function with "smp_
" prefix, which indicates that 22246 ! multicore code will be used (for multicore support) 22248 ! In order to use SSE features you have to: 22249 ! * use commercial version of ALGLIB on Intel processors 22250 ! * use C++ computational core 22252 ! This note is given for users of commercial edition; if you use GPL 22253 ! edition, you still will be able to call smp-version of this function, 22254 ! but all computations will be done serially. 22256 ! We recommend you to carefully read ALGLIB Reference Manual, section 22257 ! called 'SMP support', before using parallel version of this function. 22261 Network - network initialized with one of the network creation funcs 22262 XY - original dataset in dense format; one sample = one row: 22263 * first NIn columns contain inputs, 22264 * for regression problem, next NOut columns store 22266 * for classification problem, next column (just one!) 22267 stores class number. 22268 SSize - number of elements in XY 22269 Grad - possibly preallocated array. If size of array is smaller 22270 than WCount, it will be reallocated. It is recommended to 22271 reuse previously allocated array to reduce allocation 22275 E - error function, SUM(sqr(y[i]-desiredy[i])/2,i) 22276 Grad - gradient of E with respect to weights of network, array[WCount] 22279 Copyright 04.11.2007 by Bochkanov Sergey 22280 *************************************************************************/ 22281 void mlpgradbatch(multilayerperceptron* network, 22282 /* Real */ ae_matrix* xy, 22285 /* Real */ ae_vector* grad, 22288 ae_frame _frame_block; 22295 ae_int_t subsettype; 22297 ae_smart_ptr _sgrad; 22299 ae_frame_make(_state, &_frame_block); 22301 ae_smart_ptr_init(&_sgrad, (void**)&sgrad, _state, ae_true); 22303 ae_assert(ssize>=0, "MLPGradBatchSparse: SSize<0
", _state); 22307 mlpproperties(network, &nin, &nout, &wcount, _state); 22308 rvectorsetlengthatleast(grad, wcount, _state); 22309 ae_shared_pool_first_recycled(&network->gradbuf, &_sgrad, _state); 22313 for(i=0; i<=wcount-1; i++) 22315 sgrad->g.ptr.p_double[i] = 0.0; 22317 ae_shared_pool_next_recycled(&network->gradbuf, &_sgrad, _state); 22319 mlpgradbatchx(network, xy, &network->dummysxy, ssize, 0, &network->dummyidx, subset0, subset1, subsettype, &network->buf, &network->gradbuf, _state); 22321 for(i=0; i<=wcount-1; i++) 22323 grad->ptr.p_double[i] = 0.0; 22325 ae_shared_pool_first_recycled(&network->gradbuf, &_sgrad, _state); 22329 for(i=0; i<=wcount-1; i++) 22331 grad->ptr.p_double[i] = grad->ptr.p_double[i]+sgrad->g.ptr.p_double[i]; 22333 ae_shared_pool_next_recycled(&network->gradbuf, &_sgrad, _state); 22335 ae_frame_leave(_state); 22339 /************************************************************************* 22340 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 22341 *************************************************************************/ 22342 void _pexec_mlpgradbatch(multilayerperceptron* network, 22343 /* Real */ ae_matrix* xy, 22346 /* Real */ ae_vector* grad, ae_state *_state) 22348 mlpgradbatch(network,xy,ssize,e,grad, _state); 22352 /************************************************************************* 22353 Batch gradient calculation for a set of inputs/outputs given by sparse 22357 FOR USERS OF COMMERCIAL EDITION: 22359 ! Commercial version of ALGLIB includes two important improvements of 22361 ! * multicore support (C++ and C# computational cores) 22364 ! First improvement gives close-to-linear speedup on multicore systems. 22365 ! Second improvement gives constant speedup (2-3x depending on your CPU) 22367 ! In order to use multicore features you have to: 22368 ! * use commercial version of ALGLIB 22369 ! * call this function with "smp_
" prefix, which indicates that 22370 ! multicore code will be used (for multicore support) 22372 ! In order to use SSE features you have to: 22373 ! * use commercial version of ALGLIB on Intel processors 22374 ! * use C++ computational core 22376 ! This note is given for users of commercial edition; if you use GPL 22377 ! edition, you still will be able to call smp-version of this function, 22378 ! but all computations will be done serially. 22380 ! We recommend you to carefully read ALGLIB Reference Manual, section 22381 ! called 'SMP support', before using parallel version of this function. 22385 Network - network initialized with one of the network creation funcs 22386 XY - original dataset in sparse format; one sample = one row: 22387 * MATRIX MUST BE STORED IN CRS FORMAT 22388 * first NIn columns contain inputs. 22389 * for regression problem, next NOut columns store 22391 * for classification problem, next column (just one!) 22392 stores class number. 22393 SSize - number of elements in XY 22394 Grad - possibly preallocated array. If size of array is smaller 22395 than WCount, it will be reallocated. It is recommended to 22396 reuse previously allocated array to reduce allocation 22400 E - error function, SUM(sqr(y[i]-desiredy[i])/2,i) 22401 Grad - gradient of E with respect to weights of network, array[WCount] 22404 Copyright 26.07.2012 by Bochkanov Sergey 22405 *************************************************************************/ 22406 void mlpgradbatchsparse(multilayerperceptron* network, 22410 /* Real */ ae_vector* grad, 22413 ae_frame _frame_block; 22420 ae_int_t subsettype; 22422 ae_smart_ptr _sgrad; 22424 ae_frame_make(_state, &_frame_block); 22426 ae_smart_ptr_init(&_sgrad, (void**)&sgrad, _state, ae_true); 22428 ae_assert(ssize>=0, "MLPGradBatchSparse: SSize<0
", _state); 22429 ae_assert(sparseiscrs(xy, _state), "MLPGradBatchSparse: sparse matrix XY must be
in CRS format.
", _state); 22433 mlpproperties(network, &nin, &nout, &wcount, _state); 22434 rvectorsetlengthatleast(grad, wcount, _state); 22435 ae_shared_pool_first_recycled(&network->gradbuf, &_sgrad, _state); 22439 for(i=0; i<=wcount-1; i++) 22441 sgrad->g.ptr.p_double[i] = 0.0; 22443 ae_shared_pool_next_recycled(&network->gradbuf, &_sgrad, _state); 22445 mlpgradbatchx(network, &network->dummydxy, xy, ssize, 1, &network->dummyidx, subset0, subset1, subsettype, &network->buf, &network->gradbuf, _state); 22447 for(i=0; i<=wcount-1; i++) 22449 grad->ptr.p_double[i] = 0.0; 22451 ae_shared_pool_first_recycled(&network->gradbuf, &_sgrad, _state); 22455 for(i=0; i<=wcount-1; i++) 22457 grad->ptr.p_double[i] = grad->ptr.p_double[i]+sgrad->g.ptr.p_double[i]; 22459 ae_shared_pool_next_recycled(&network->gradbuf, &_sgrad, _state); 22461 ae_frame_leave(_state); 22465 /************************************************************************* 22466 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 22467 *************************************************************************/ 22468 void _pexec_mlpgradbatchsparse(multilayerperceptron* network, 22472 /* Real */ ae_vector* grad, ae_state *_state) 22474 mlpgradbatchsparse(network,xy,ssize,e,grad, _state); 22478 /************************************************************************* 22479 Batch gradient calculation for a subset of dataset 22482 FOR USERS OF COMMERCIAL EDITION: 22484 ! Commercial version of ALGLIB includes two important improvements of 22486 ! * multicore support (C++ and C# computational cores) 22489 ! First improvement gives close-to-linear speedup on multicore systems. 22490 ! Second improvement gives constant speedup (2-3x depending on your CPU) 22492 ! In order to use multicore features you have to: 22493 ! * use commercial version of ALGLIB 22494 ! * call this function with "smp_
" prefix, which indicates that 22495 ! multicore code will be used (for multicore support) 22497 ! In order to use SSE features you have to: 22498 ! * use commercial version of ALGLIB on Intel processors 22499 ! * use C++ computational core 22501 ! This note is given for users of commercial edition; if you use GPL 22502 ! edition, you still will be able to call smp-version of this function, 22503 ! but all computations will be done serially. 22505 ! We recommend you to carefully read ALGLIB Reference Manual, section 22506 ! called 'SMP support', before using parallel version of this function. 22510 Network - network initialized with one of the network creation funcs 22511 XY - original dataset in dense format; one sample = one row: 22512 * first NIn columns contain inputs, 22513 * for regression problem, next NOut columns store 22515 * for classification problem, next column (just one!) 22516 stores class number. 22517 SetSize - real size of XY, SetSize>=0; 22518 Idx - subset of SubsetSize elements, array[SubsetSize]: 22519 * Idx[I] stores row index in the original dataset which is 22520 given by XY. Gradient is calculated with respect to rows 22521 whose indexes are stored in Idx[]. 22522 * Idx[] must store correct indexes; this function throws 22523 an exception in case incorrect index (less than 0 or 22524 larger than rows(XY)) is given 22525 * Idx[] may store indexes in any order and even with 22527 SubsetSize- number of elements in Idx[] array: 22528 * positive value means that subset given by Idx[] is processed 22529 * zero value results in zero gradient 22530 * negative value means that full dataset is processed 22531 Grad - possibly preallocated array. If size of array is smaller 22532 than WCount, it will be reallocated. It is recommended to 22533 reuse previously allocated array to reduce allocation 22537 E - error function, SUM(sqr(y[i]-desiredy[i])/2,i) 22538 Grad - gradient of E with respect to weights of network, 22542 Copyright 26.07.2012 by Bochkanov Sergey 22543 *************************************************************************/ 22544 void mlpgradbatchsubset(multilayerperceptron* network, 22545 /* Real */ ae_matrix* xy, 22547 /* Integer */ ae_vector* idx, 22548 ae_int_t subsetsize, 22550 /* Real */ ae_vector* grad, 22553 ae_frame _frame_block; 22561 ae_int_t subsettype; 22563 ae_smart_ptr _sgrad; 22565 ae_frame_make(_state, &_frame_block); 22567 ae_smart_ptr_init(&_sgrad, (void**)&sgrad, _state, ae_true); 22569 ae_assert(setsize>=0, "MLPGradBatchSubset: SetSize<0
", _state); 22570 ae_assert(subsetsize<=idx->cnt, "MLPGradBatchSubset: SubsetSize>Length(Idx)
", _state); 22581 subset1 = subsetsize; 22583 for(i=0; i<=subsetsize-1; i++) 22585 ae_assert(idx->ptr.p_int[i]>=0, "MLPGradBatchSubset: incorrect
index of XY row(Idx[I]<0)
", _state); 22586 ae_assert(idx->ptr.p_int[i]<=npoints-1, "MLPGradBatchSubset: incorrect
index of XY row(Idx[I]>Rows(XY)-1)
", _state); 22589 mlpproperties(network, &nin, &nout, &wcount, _state); 22590 rvectorsetlengthatleast(grad, wcount, _state); 22591 ae_shared_pool_first_recycled(&network->gradbuf, &_sgrad, _state); 22595 for(i=0; i<=wcount-1; i++) 22597 sgrad->g.ptr.p_double[i] = 0.0; 22599 ae_shared_pool_next_recycled(&network->gradbuf, &_sgrad, _state); 22601 mlpgradbatchx(network, xy, &network->dummysxy, setsize, 0, idx, subset0, subset1, subsettype, &network->buf, &network->gradbuf, _state); 22603 for(i=0; i<=wcount-1; i++) 22605 grad->ptr.p_double[i] = 0.0; 22607 ae_shared_pool_first_recycled(&network->gradbuf, &_sgrad, _state); 22611 for(i=0; i<=wcount-1; i++) 22613 grad->ptr.p_double[i] = grad->ptr.p_double[i]+sgrad->g.ptr.p_double[i]; 22615 ae_shared_pool_next_recycled(&network->gradbuf, &_sgrad, _state); 22617 ae_frame_leave(_state); 22621 /************************************************************************* 22622 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 22623 *************************************************************************/ 22624 void _pexec_mlpgradbatchsubset(multilayerperceptron* network, 22625 /* Real */ ae_matrix* xy, 22627 /* Integer */ ae_vector* idx, 22628 ae_int_t subsetsize, 22630 /* Real */ ae_vector* grad, ae_state *_state) 22632 mlpgradbatchsubset(network,xy,setsize,idx,subsetsize,e,grad, _state); 22636 /************************************************************************* 22637 Batch gradient calculation for a set of inputs/outputs for a subset of 22638 dataset given by set of indexes. 22641 FOR USERS OF COMMERCIAL EDITION: 22643 ! Commercial version of ALGLIB includes two important improvements of 22645 ! * multicore support (C++ and C# computational cores) 22648 ! First improvement gives close-to-linear speedup on multicore systems. 22649 ! Second improvement gives constant speedup (2-3x depending on your CPU) 22651 ! In order to use multicore features you have to: 22652 ! * use commercial version of ALGLIB 22653 ! * call this function with "smp_
" prefix, which indicates that 22654 ! multicore code will be used (for multicore support) 22656 ! In order to use SSE features you have to: 22657 ! * use commercial version of ALGLIB on Intel processors 22658 ! * use C++ computational core 22660 ! This note is given for users of commercial edition; if you use GPL 22661 ! edition, you still will be able to call smp-version of this function, 22662 ! but all computations will be done serially. 22664 ! We recommend you to carefully read ALGLIB Reference Manual, section 22665 ! called 'SMP support', before using parallel version of this function. 22669 Network - network initialized with one of the network creation funcs 22670 XY - original dataset in sparse format; one sample = one row: 22671 * MATRIX MUST BE STORED IN CRS FORMAT 22672 * first NIn columns contain inputs, 22673 * for regression problem, next NOut columns store 22675 * for classification problem, next column (just one!) 22676 stores class number. 22677 SetSize - real size of XY, SetSize>=0; 22678 Idx - subset of SubsetSize elements, array[SubsetSize]: 22679 * Idx[I] stores row index in the original dataset which is 22680 given by XY. Gradient is calculated with respect to rows 22681 whose indexes are stored in Idx[]. 22682 * Idx[] must store correct indexes; this function throws 22683 an exception in case incorrect index (less than 0 or 22684 larger than rows(XY)) is given 22685 * Idx[] may store indexes in any order and even with 22687 SubsetSize- number of elements in Idx[] array: 22688 * positive value means that subset given by Idx[] is processed 22689 * zero value results in zero gradient 22690 * negative value means that full dataset is processed 22691 Grad - possibly preallocated array. If size of array is smaller 22692 than WCount, it will be reallocated. It is recommended to 22693 reuse previously allocated array to reduce allocation 22697 E - error function, SUM(sqr(y[i]-desiredy[i])/2,i) 22698 Grad - gradient of E with respect to weights of network, 22701 NOTE: when SubsetSize<0 is used full dataset by call MLPGradBatchSparse 22705 Copyright 26.07.2012 by Bochkanov Sergey 22706 *************************************************************************/ 22707 void mlpgradbatchsparsesubset(multilayerperceptron* network, 22710 /* Integer */ ae_vector* idx, 22711 ae_int_t subsetsize, 22713 /* Real */ ae_vector* grad, 22716 ae_frame _frame_block; 22724 ae_int_t subsettype; 22726 ae_smart_ptr _sgrad; 22728 ae_frame_make(_state, &_frame_block); 22730 ae_smart_ptr_init(&_sgrad, (void**)&sgrad, _state, ae_true); 22732 ae_assert(setsize>=0, "MLPGradBatchSparseSubset: SetSize<0
", _state); 22733 ae_assert(subsetsize<=idx->cnt, "MLPGradBatchSparseSubset: SubsetSize>Length(Idx)
", _state); 22734 ae_assert(sparseiscrs(xy, _state), "MLPGradBatchSparseSubset: sparse matrix XY must be
in CRS format.
", _state); 22745 subset1 = subsetsize; 22747 for(i=0; i<=subsetsize-1; i++) 22749 ae_assert(idx->ptr.p_int[i]>=0, "MLPGradBatchSparseSubset: incorrect
index of XY row(Idx[I]<0)
", _state); 22750 ae_assert(idx->ptr.p_int[i]<=npoints-1, "MLPGradBatchSparseSubset: incorrect
index of XY row(Idx[I]>Rows(XY)-1)
", _state); 22753 mlpproperties(network, &nin, &nout, &wcount, _state); 22754 rvectorsetlengthatleast(grad, wcount, _state); 22755 ae_shared_pool_first_recycled(&network->gradbuf, &_sgrad, _state); 22759 for(i=0; i<=wcount-1; i++) 22761 sgrad->g.ptr.p_double[i] = 0.0; 22763 ae_shared_pool_next_recycled(&network->gradbuf, &_sgrad, _state); 22765 mlpgradbatchx(network, &network->dummydxy, xy, setsize, 1, idx, subset0, subset1, subsettype, &network->buf, &network->gradbuf, _state); 22767 for(i=0; i<=wcount-1; i++) 22769 grad->ptr.p_double[i] = 0.0; 22771 ae_shared_pool_first_recycled(&network->gradbuf, &_sgrad, _state); 22775 for(i=0; i<=wcount-1; i++) 22777 grad->ptr.p_double[i] = grad->ptr.p_double[i]+sgrad->g.ptr.p_double[i]; 22779 ae_shared_pool_next_recycled(&network->gradbuf, &_sgrad, _state); 22781 ae_frame_leave(_state); 22785 /************************************************************************* 22786 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 22787 *************************************************************************/ 22788 void _pexec_mlpgradbatchsparsesubset(multilayerperceptron* network, 22791 /* Integer */ ae_vector* idx, 22792 ae_int_t subsetsize, 22794 /* Real */ ae_vector* grad, ae_state *_state) 22796 mlpgradbatchsparsesubset(network,xy,setsize,idx,subsetsize,e,grad, _state); 22800 void mlpgradbatchx(multilayerperceptron* network, 22801 /* Real */ ae_matrix* densexy, 22802 sparsematrix* sparsexy, 22803 ae_int_t datasetsize, 22804 ae_int_t datasettype, 22805 /* Integer */ ae_vector* idx, 22808 ae_int_t subsettype, 22809 ae_shared_pool* buf, 22810 ae_shared_pool* gradbuf, 22813 ae_frame _frame_block; 22822 double problemcost; 22824 ae_smart_ptr _buf2; 22828 ae_smart_ptr _pbuf; 22830 ae_smart_ptr _sgrad; 22832 ae_frame_make(_state, &_frame_block); 22833 ae_smart_ptr_init(&_buf2, (void**)&buf2, _state, ae_true); 22834 ae_smart_ptr_init(&_pbuf, (void**)&pbuf, _state, ae_true); 22835 ae_smart_ptr_init(&_sgrad, (void**)&sgrad, _state, ae_true); 22837 ae_assert(datasetsize>=0, "MLPGradBatchX: SetSize<0
", _state); 22838 ae_assert(datasettype==0||datasettype==1, "MLPGradBatchX:
DatasetType is incorrect
", _state); 22839 ae_assert(subsettype==0||subsettype==1, "MLPGradBatchX: SubsetType is incorrect
", _state); 22842 * Determine network and dataset properties 22844 mlpproperties(network, &nin, &nout, &wcount, _state); 22845 if( mlpissoftmax(network, _state) ) 22851 rowsize = nin+nout; 22857 * Splitting problem allows us to reduce effect of single-precision 22858 * arithmetics (SSE-optimized version of MLPChunkedGradient uses single 22859 * precision internally, but converts them to double precision after 22860 * results are exported from HPC buffer to network). Small batches are 22861 * calculated in single precision, results are aggregated in double 22862 * precision, and it allows us to avoid accumulation of errors when 22863 * we process very large batches (tens of thousands of items). 22865 * NOTE: it is important to use real arithmetics for ProblemCost 22866 * because ProblemCost may be larger than MAXINT. 22868 problemcost = subset1-subset0; 22869 problemcost = problemcost*wcount; 22870 if( subset1-subset0>=2*mlpbase_microbatchsize&&ae_fp_greater(problemcost,mlpbase_gradbasecasecost) ) 22872 splitlength(subset1-subset0, mlpbase_microbatchsize, &len0, &len1, _state); 22873 mlpgradbatchx(network, densexy, sparsexy, datasetsize, datasettype, idx, subset0, subset0+len0, subsettype, buf, gradbuf, _state); 22874 mlpgradbatchx(network, densexy, sparsexy, datasetsize, datasettype, idx, subset0+len0, subset1, subsettype, buf, gradbuf, _state); 22875 ae_frame_leave(_state); 22880 * Chunked processing 22882 ae_shared_pool_retrieve(gradbuf, &_sgrad, _state); 22883 ae_shared_pool_retrieve(buf, &_pbuf, _state); 22884 hpcpreparechunkedgradient(&network->weights, wcount, mlpntotal(network, _state), nin, nout, pbuf, _state); 22886 while(cstart<subset1) 22890 * Determine size of current chunk and copy it to PBuf.XY 22892 csize = ae_minint(subset1, cstart+pbuf->chunksize, _state)-cstart; 22893 for(j=0; j<=csize-1; j++) 22896 if( subsettype==0 ) 22900 if( subsettype==1 ) 22902 srcidx = idx->ptr.p_int[cstart+j]; 22904 ae_assert(srcidx>=0, "MLPGradBatchX:
internal error", _state); 22905 if( datasettype==0 ) 22907 ae_v_move(&pbuf->xy.ptr.pp_double[j][0], 1, &densexy->ptr.pp_double[srcidx][0], 1, ae_v_len(0,rowsize-1)); 22909 if( datasettype==1 ) 22911 sparsegetrow(sparsexy, srcidx, &pbuf->xyrow, _state); 22912 ae_v_move(&pbuf->xy.ptr.pp_double[j][0], 1, &pbuf->xyrow.ptr.p_double[0], 1, ae_v_len(0,rowsize-1)); 22917 * Process chunk and advance line pointer 22919 mlpbase_mlpchunkedgradient(network, &pbuf->xy, 0, csize, &pbuf->batch4buf, &pbuf->hpcbuf, &sgrad->f, ae_false, _state); 22920 cstart = cstart+pbuf->chunksize; 22922 hpcfinalizechunkedgradient(pbuf, &sgrad->g, _state); 22923 ae_shared_pool_recycle(buf, &_pbuf, _state); 22924 ae_shared_pool_recycle(gradbuf, &_sgrad, _state); 22925 ae_frame_leave(_state); 22929 /************************************************************************* 22930 Batch gradient calculation for a set of inputs/outputs 22931 (natural error function is used) 22934 Network - network initialized with one of the network creation funcs 22935 XY - set of inputs/outputs; one sample = one row; 22936 first NIn columns contain inputs, 22937 next NOut columns - desired outputs. 22938 SSize - number of elements in XY 22939 Grad - possibly preallocated array. If size of array is smaller 22940 than WCount, it will be reallocated. It is recommended to 22941 reuse previously allocated array to reduce allocation 22945 E - error function, sum-of-squares for regression networks, 22946 cross-entropy for classification networks. 22947 Grad - gradient of E with respect to weights of network, array[WCount] 22950 Copyright 04.11.2007 by Bochkanov Sergey 22951 *************************************************************************/ 22952 void mlpgradnbatch(multilayerperceptron* network, 22953 /* Real */ ae_matrix* xy, 22956 /* Real */ ae_vector* grad, 22959 ae_frame _frame_block; 22965 ae_smart_ptr _pbuf; 22967 ae_frame_make(_state, &_frame_block); 22969 ae_smart_ptr_init(&_pbuf, (void**)&pbuf, _state, ae_true); 22975 mlpproperties(network, &nin, &nout, &wcount, _state); 22976 ae_shared_pool_retrieve(&network->buf, &_pbuf, _state); 22977 hpcpreparechunkedgradient(&network->weights, wcount, mlpntotal(network, _state), nin, nout, pbuf, _state); 22978 rvectorsetlengthatleast(grad, wcount, _state); 22979 for(i=0; i<=wcount-1; i++) 22981 grad->ptr.p_double[i] = 0; 22987 mlpbase_mlpchunkedgradient(network, xy, i, ae_minint(ssize, i+pbuf->chunksize, _state)-i, &pbuf->batch4buf, &pbuf->hpcbuf, e, ae_true, _state); 22988 i = i+pbuf->chunksize; 22990 hpcfinalizechunkedgradient(pbuf, grad, _state); 22991 ae_shared_pool_recycle(&network->buf, &_pbuf, _state); 22992 ae_frame_leave(_state); 22996 /************************************************************************* 22997 Batch Hessian calculation (natural error function) using R-algorithm. 22998 Internal subroutine. 23001 Copyright 26.01.2008 by Bochkanov Sergey. 23003 Hessian calculation based on R-algorithm described in 23004 "Fast Exact Multiplication by the Hessian
", 23006 Neural Computation, 1994. 23007 *************************************************************************/ 23008 void mlphessiannbatch(multilayerperceptron* network, 23009 /* Real */ ae_matrix* xy, 23012 /* Real */ ae_vector* grad, 23013 /* Real */ ae_matrix* h, 23019 mlpbase_mlphessianbatchinternal(network, xy, ssize, ae_true, e, grad, h, _state); 23023 /************************************************************************* 23024 Batch Hessian calculation using R-algorithm. 23025 Internal subroutine. 23028 Copyright 26.01.2008 by Bochkanov Sergey. 23030 Hessian calculation based on R-algorithm described in 23031 "Fast Exact Multiplication by the Hessian
", 23033 Neural Computation, 1994. 23034 *************************************************************************/ 23035 void mlphessianbatch(multilayerperceptron* network, 23036 /* Real */ ae_matrix* xy, 23039 /* Real */ ae_vector* grad, 23040 /* Real */ ae_matrix* h, 23046 mlpbase_mlphessianbatchinternal(network, xy, ssize, ae_false, e, grad, h, _state); 23050 /************************************************************************* 23051 Internal subroutine, shouldn't be called by user. 23052 *************************************************************************/ 23053 void mlpinternalprocessvector(/* Integer */ ae_vector* structinfo, 23054 /* Real */ ae_vector* weights, 23055 /* Real */ ae_vector* columnmeans, 23056 /* Real */ ae_vector* columnsigmas, 23057 /* Real */ ae_vector* neurons, 23058 /* Real */ ae_vector* dfdnet, 23059 /* Real */ ae_vector* x, 23060 /* Real */ ae_vector* y, 23083 * Read network geometry 23085 nin = structinfo->ptr.p_int[1]; 23086 nout = structinfo->ptr.p_int[2]; 23087 ntotal = structinfo->ptr.p_int[3]; 23088 istart = structinfo->ptr.p_int[5]; 23091 * Inputs standartisation and putting in the network 23093 for(i=0; i<=nin-1; i++) 23095 if( ae_fp_neq(columnsigmas->ptr.p_double[i],0) ) 23097 neurons->ptr.p_double[i] = (x->ptr.p_double[i]-columnmeans->ptr.p_double[i])/columnsigmas->ptr.p_double[i]; 23101 neurons->ptr.p_double[i] = x->ptr.p_double[i]-columnmeans->ptr.p_double[i]; 23108 for(i=0; i<=ntotal-1; i++) 23110 offs = istart+i*mlpbase_nfieldwidth; 23111 if( structinfo->ptr.p_int[offs+0]>0||structinfo->ptr.p_int[offs+0]==-5 ) 23115 * Activation function 23117 mlpactivationfunction(neurons->ptr.p_double[structinfo->ptr.p_int[offs+2]], structinfo->ptr.p_int[offs+0], &f, &df, &d2f, _state); 23118 neurons->ptr.p_double[i] = f; 23119 dfdnet->ptr.p_double[i] = df; 23122 if( structinfo->ptr.p_int[offs+0]==0 ) 23126 * Adaptive summator 23128 n1 = structinfo->ptr.p_int[offs+2]; 23129 n2 = n1+structinfo->ptr.p_int[offs+1]-1; 23130 w1 = structinfo->ptr.p_int[offs+3]; 23131 w2 = w1+structinfo->ptr.p_int[offs+1]-1; 23132 net = ae_v_dotproduct(&weights->ptr.p_double[w1], 1, &neurons->ptr.p_double[n1], 1, ae_v_len(w1,w2)); 23133 neurons->ptr.p_double[i] = net; 23134 dfdnet->ptr.p_double[i] = 1.0; 23135 touchint(&n2, _state); 23138 if( structinfo->ptr.p_int[offs+0]<0 ) 23141 if( structinfo->ptr.p_int[offs+0]==-2 ) 23145 * input neuron, left unchanged 23149 if( structinfo->ptr.p_int[offs+0]==-3 ) 23155 neurons->ptr.p_double[i] = -1; 23158 if( structinfo->ptr.p_int[offs+0]==-4 ) 23164 neurons->ptr.p_double[i] = 0; 23167 ae_assert(!perr, "MLPInternalProcessVector:
internal error - unknown neuron
type!
", _state); 23175 ae_v_move(&y->ptr.p_double[0], 1, &neurons->ptr.p_double[ntotal-nout], 1, ae_v_len(0,nout-1)); 23178 * Softmax post-processing or standardisation if needed 23180 ae_assert(structinfo->ptr.p_int[6]==0||structinfo->ptr.p_int[6]==1, "MLPInternalProcessVector: unknown normalization
type!
", _state); 23181 if( structinfo->ptr.p_int[6]==1 ) 23187 mx = y->ptr.p_double[0]; 23188 for(i=1; i<=nout-1; i++) 23190 mx = ae_maxreal(mx, y->ptr.p_double[i], _state); 23193 for(i=0; i<=nout-1; i++) 23195 y->ptr.p_double[i] = ae_exp(y->ptr.p_double[i]-mx, _state); 23196 net = net+y->ptr.p_double[i]; 23198 for(i=0; i<=nout-1; i++) 23200 y->ptr.p_double[i] = y->ptr.p_double[i]/net; 23209 for(i=0; i<=nout-1; i++) 23211 y->ptr.p_double[i] = y->ptr.p_double[i]*columnsigmas->ptr.p_double[nin+i]+columnmeans->ptr.p_double[nin+i]; 23217 /************************************************************************* 23218 Serializer: allocation 23221 Copyright 14.03.2011 by Bochkanov Sergey 23222 *************************************************************************/ 23223 void mlpalloc(ae_serializer* s, 23224 multilayerperceptron* network, 23238 nin = network->hllayersizes.ptr.p_int[0]; 23239 nout = network->hllayersizes.ptr.p_int[network->hllayersizes.cnt-1]; 23240 ae_serializer_alloc_entry(s); 23241 ae_serializer_alloc_entry(s); 23242 ae_serializer_alloc_entry(s); 23243 allocintegerarray(s, &network->hllayersizes, -1, _state); 23244 for(i=1; i<=network->hllayersizes.cnt-1; i++) 23246 for(j=0; j<=network->hllayersizes.ptr.p_int[i]-1; j++) 23248 mlpgetneuroninfo(network, i, j, &fkind, &threshold, _state); 23249 ae_serializer_alloc_entry(s); 23250 ae_serializer_alloc_entry(s); 23251 for(k=0; k<=network->hllayersizes.ptr.p_int[i-1]-1; k++) 23253 ae_serializer_alloc_entry(s); 23257 for(j=0; j<=nin-1; j++) 23259 mlpgetinputscaling(network, j, &v0, &v1, _state); 23260 ae_serializer_alloc_entry(s); 23261 ae_serializer_alloc_entry(s); 23263 for(j=0; j<=nout-1; j++) 23265 mlpgetoutputscaling(network, j, &v0, &v1, _state); 23266 ae_serializer_alloc_entry(s); 23267 ae_serializer_alloc_entry(s); 23272 /************************************************************************* 23273 Serializer: serialization 23276 Copyright 14.03.2011 by Bochkanov Sergey 23277 *************************************************************************/ 23278 void mlpserialize(ae_serializer* s, 23279 multilayerperceptron* network, 23293 nin = network->hllayersizes.ptr.p_int[0]; 23294 nout = network->hllayersizes.ptr.p_int[network->hllayersizes.cnt-1]; 23295 ae_serializer_serialize_int(s, getmlpserializationcode(_state), _state); 23296 ae_serializer_serialize_int(s, mlpbase_mlpfirstversion, _state); 23297 ae_serializer_serialize_bool(s, mlpissoftmax(network, _state), _state); 23298 serializeintegerarray(s, &network->hllayersizes, -1, _state); 23299 for(i=1; i<=network->hllayersizes.cnt-1; i++) 23301 for(j=0; j<=network->hllayersizes.ptr.p_int[i]-1; j++) 23303 mlpgetneuroninfo(network, i, j, &fkind, &threshold, _state); 23304 ae_serializer_serialize_int(s, fkind, _state); 23305 ae_serializer_serialize_double(s, threshold, _state); 23306 for(k=0; k<=network->hllayersizes.ptr.p_int[i-1]-1; k++) 23308 ae_serializer_serialize_double(s, mlpgetweight(network, i-1, k, i, j, _state), _state); 23312 for(j=0; j<=nin-1; j++) 23314 mlpgetinputscaling(network, j, &v0, &v1, _state); 23315 ae_serializer_serialize_double(s, v0, _state); 23316 ae_serializer_serialize_double(s, v1, _state); 23318 for(j=0; j<=nout-1; j++) 23320 mlpgetoutputscaling(network, j, &v0, &v1, _state); 23321 ae_serializer_serialize_double(s, v0, _state); 23322 ae_serializer_serialize_double(s, v1, _state); 23327 /************************************************************************* 23328 Serializer: unserialization 23331 Copyright 14.03.2011 by Bochkanov Sergey 23332 *************************************************************************/ 23333 void mlpunserialize(ae_serializer* s, 23334 multilayerperceptron* network, 23337 ae_frame _frame_block; 23350 ae_vector layersizes; 23352 ae_frame_make(_state, &_frame_block); 23353 _multilayerperceptron_clear(network); 23354 ae_vector_init(&layersizes, 0, DT_INT, _state, ae_true); 23358 * check correctness of header 23360 ae_serializer_unserialize_int(s, &i0, _state); 23361 ae_assert(i0==getmlpserializationcode(_state), "MLPUnserialize: stream header corrupted
", _state); 23362 ae_serializer_unserialize_int(s, &i1, _state); 23363 ae_assert(i1==mlpbase_mlpfirstversion, "MLPUnserialize: stream header corrupted
", _state); 23368 ae_serializer_unserialize_bool(s, &issoftmax, _state); 23369 unserializeintegerarray(s, &layersizes, _state); 23370 ae_assert((layersizes.cnt==2||layersizes.cnt==3)||layersizes.cnt==4, "MLPUnserialize: too many hidden layers!
", _state); 23371 nin = layersizes.ptr.p_int[0]; 23372 nout = layersizes.ptr.p_int[layersizes.cnt-1]; 23373 if( layersizes.cnt==2 ) 23377 mlpcreatec0(layersizes.ptr.p_int[0], layersizes.ptr.p_int[1], network, _state); 23381 mlpcreate0(layersizes.ptr.p_int[0], layersizes.ptr.p_int[1], network, _state); 23384 if( layersizes.cnt==3 ) 23388 mlpcreatec1(layersizes.ptr.p_int[0], layersizes.ptr.p_int[1], layersizes.ptr.p_int[2], network, _state); 23392 mlpcreate1(layersizes.ptr.p_int[0], layersizes.ptr.p_int[1], layersizes.ptr.p_int[2], network, _state); 23395 if( layersizes.cnt==4 ) 23399 mlpcreatec2(layersizes.ptr.p_int[0], layersizes.ptr.p_int[1], layersizes.ptr.p_int[2], layersizes.ptr.p_int[3], network, _state); 23403 mlpcreate2(layersizes.ptr.p_int[0], layersizes.ptr.p_int[1], layersizes.ptr.p_int[2], layersizes.ptr.p_int[3], network, _state); 23408 * Load neurons and weights 23410 for(i=1; i<=layersizes.cnt-1; i++) 23412 for(j=0; j<=layersizes.ptr.p_int[i]-1; j++) 23414 ae_serializer_unserialize_int(s, &fkind, _state); 23415 ae_serializer_unserialize_double(s, &threshold, _state); 23416 mlpsetneuroninfo(network, i, j, fkind, threshold, _state); 23417 for(k=0; k<=layersizes.ptr.p_int[i-1]-1; k++) 23419 ae_serializer_unserialize_double(s, &v0, _state); 23420 mlpsetweight(network, i-1, k, i, j, v0, _state); 23426 * Load standartizator 23428 for(j=0; j<=nin-1; j++) 23430 ae_serializer_unserialize_double(s, &v0, _state); 23431 ae_serializer_unserialize_double(s, &v1, _state); 23432 mlpsetinputscaling(network, j, v0, v1, _state); 23434 for(j=0; j<=nout-1; j++) 23436 ae_serializer_unserialize_double(s, &v0, _state); 23437 ae_serializer_unserialize_double(s, &v1, _state); 23438 mlpsetoutputscaling(network, j, v0, v1, _state); 23440 ae_frame_leave(_state); 23444 /************************************************************************* 23445 Calculation of all types of errors. 23448 FOR USERS OF COMMERCIAL EDITION: 23450 ! Commercial version of ALGLIB includes two important improvements of 23452 ! * multicore support (C++ and C# computational cores) 23455 ! First improvement gives close-to-linear speedup on multicore systems. 23456 ! Second improvement gives constant speedup (2-3x depending on your CPU) 23458 ! In order to use multicore features you have to: 23459 ! * use commercial version of ALGLIB 23460 ! * call this function with "smp_
" prefix, which indicates that 23461 ! multicore code will be used (for multicore support) 23463 ! In order to use SSE features you have to: 23464 ! * use commercial version of ALGLIB on Intel processors 23465 ! * use C++ computational core 23467 ! This note is given for users of commercial edition; if you use GPL 23468 ! edition, you still will be able to call smp-version of this function, 23469 ! but all computations will be done serially. 23471 ! We recommend you to carefully read ALGLIB Reference Manual, section 23472 ! called 'SMP support', before using parallel version of this function. 23476 Network - network initialized with one of the network creation funcs 23477 XY - original dataset; one sample = one row; 23478 first NIn columns contain inputs, 23479 next NOut columns - desired outputs. 23480 SetSize - real size of XY, SetSize>=0; 23481 Subset - subset of SubsetSize elements, array[SubsetSize]; 23482 SubsetSize- number of elements in Subset[] array. 23485 Rep - it contains all type of errors. 23487 NOTE: when SubsetSize<0 is used full dataset by call MLPGradBatch function. 23490 Copyright 04.09.2012 by Bochkanov Sergey 23491 *************************************************************************/ 23492 void mlpallerrorssubset(multilayerperceptron* network, 23493 /* Real */ ae_matrix* xy, 23495 /* Integer */ ae_vector* subset, 23496 ae_int_t subsetsize, 23504 _modelerrors_clear(rep); 23506 ae_assert(xy->rows>=setsize, "MLPAllErrorsSubset: XY has less than SetSize rows
", _state); 23509 if( mlpissoftmax(network, _state) ) 23511 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+1, "MLPAllErrorsSubset: XY has less than NIn+1 columns
", _state); 23515 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPAllErrorsSubset: XY has less than NIn+NOut columns
", _state); 23518 if( subsetsize>=0 ) 23530 mlpallerrorsx(network, xy, &network->dummysxy, setsize, 0, subset, idx0, idx1, idxtype, &network->buf, rep, _state); 23534 /************************************************************************* 23535 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 23536 *************************************************************************/ 23537 void _pexec_mlpallerrorssubset(multilayerperceptron* network, 23538 /* Real */ ae_matrix* xy, 23540 /* Integer */ ae_vector* subset, 23541 ae_int_t subsetsize, 23542 modelerrors* rep, ae_state *_state) 23544 mlpallerrorssubset(network,xy,setsize,subset,subsetsize,rep, _state); 23548 /************************************************************************* 23549 Calculation of all types of errors on sparse dataset. 23552 FOR USERS OF COMMERCIAL EDITION: 23554 ! Commercial version of ALGLIB includes two important improvements of 23556 ! * multicore support (C++ and C# computational cores) 23559 ! First improvement gives close-to-linear speedup on multicore systems. 23560 ! Second improvement gives constant speedup (2-3x depending on your CPU) 23562 ! In order to use multicore features you have to: 23563 ! * use commercial version of ALGLIB 23564 ! * call this function with "smp_
" prefix, which indicates that 23565 ! multicore code will be used (for multicore support) 23567 ! In order to use SSE features you have to: 23568 ! * use commercial version of ALGLIB on Intel processors 23569 ! * use C++ computational core 23571 ! This note is given for users of commercial edition; if you use GPL 23572 ! edition, you still will be able to call smp-version of this function, 23573 ! but all computations will be done serially. 23575 ! We recommend you to carefully read ALGLIB Reference Manual, section 23576 ! called 'SMP support', before using parallel version of this function. 23580 Network - network initialized with one of the network creation funcs 23581 XY - original dataset given by sparse matrix; 23582 one sample = one row; 23583 first NIn columns contain inputs, 23584 next NOut columns - desired outputs. 23585 SetSize - real size of XY, SetSize>=0; 23586 Subset - subset of SubsetSize elements, array[SubsetSize]; 23587 SubsetSize- number of elements in Subset[] array. 23590 Rep - it contains all type of errors. 23592 NOTE: when SubsetSize<0 is used full dataset by call MLPGradBatch function. 23595 Copyright 04.09.2012 by Bochkanov Sergey 23596 *************************************************************************/ 23597 void mlpallerrorssparsesubset(multilayerperceptron* network, 23600 /* Integer */ ae_vector* subset, 23601 ae_int_t subsetsize, 23609 _modelerrors_clear(rep); 23611 ae_assert(sparseiscrs(xy, _state), "MLPAllErrorsSparseSubset: XY is not
in CRS format.
", _state); 23612 ae_assert(sparsegetnrows(xy, _state)>=setsize, "MLPAllErrorsSparseSubset: XY has less than SetSize rows
", _state); 23615 if( mlpissoftmax(network, _state) ) 23617 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+1, "MLPAllErrorsSparseSubset: XY has less than NIn+1 columns
", _state); 23621 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPAllErrorsSparseSubset: XY has less than NIn+NOut columns
", _state); 23624 if( subsetsize>=0 ) 23636 mlpallerrorsx(network, &network->dummydxy, xy, setsize, 1, subset, idx0, idx1, idxtype, &network->buf, rep, _state); 23640 /************************************************************************* 23641 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 23642 *************************************************************************/ 23643 void _pexec_mlpallerrorssparsesubset(multilayerperceptron* network, 23646 /* Integer */ ae_vector* subset, 23647 ae_int_t subsetsize, 23648 modelerrors* rep, ae_state *_state) 23650 mlpallerrorssparsesubset(network,xy,setsize,subset,subsetsize,rep, _state); 23654 /************************************************************************* 23655 Error of the neural network on dataset. 23658 FOR USERS OF COMMERCIAL EDITION: 23660 ! Commercial version of ALGLIB includes two important improvements of 23662 ! * multicore support (C++ and C# computational cores) 23665 ! First improvement gives close-to-linear speedup on multicore systems. 23666 ! Second improvement gives constant speedup (2-3x depending on your CPU) 23668 ! In order to use multicore features you have to: 23669 ! * use commercial version of ALGLIB 23670 ! * call this function with "smp_
" prefix, which indicates that 23671 ! multicore code will be used (for multicore support) 23673 ! In order to use SSE features you have to: 23674 ! * use commercial version of ALGLIB on Intel processors 23675 ! * use C++ computational core 23677 ! This note is given for users of commercial edition; if you use GPL 23678 ! edition, you still will be able to call smp-version of this function, 23679 ! but all computations will be done serially. 23681 ! We recommend you to carefully read ALGLIB Reference Manual, section 23682 ! called 'SMP support', before using parallel version of this function. 23686 Network - neural network; 23687 XY - training set, see below for information on the 23688 training set format; 23689 SetSize - real size of XY, SetSize>=0; 23690 Subset - subset of SubsetSize elements, array[SubsetSize]; 23691 SubsetSize- number of elements in Subset[] array. 23694 sum-of-squares error, SUM(sqr(y[i]-desired_y[i])/2) 23698 This function uses two different dataset formats - one for regression 23699 networks, another one for classification networks. 23701 For regression networks with NIn inputs and NOut outputs following dataset 23703 * dataset is given by NPoints*(NIn+NOut) matrix 23704 * each row corresponds to one example 23705 * first NIn columns are inputs, next NOut columns are outputs 23707 For classification networks with NIn inputs and NClasses clases following 23708 dataset format is used: 23709 * dataset is given by NPoints*(NIn+1) matrix 23710 * each row corresponds to one example 23711 * first NIn columns are inputs, last column stores class number (from 0 to 23715 Copyright 04.09.2012 by Bochkanov Sergey 23716 *************************************************************************/ 23717 double mlperrorsubset(multilayerperceptron* network, 23718 /* Real */ ae_matrix* xy, 23720 /* Integer */ ae_vector* subset, 23721 ae_int_t subsetsize, 23730 ae_assert(xy->rows>=setsize, "MLPErrorSubset: XY has less than SetSize rows
", _state); 23733 if( mlpissoftmax(network, _state) ) 23735 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+1, "MLPErrorSubset: XY has less than NIn+1 columns
", _state); 23739 ae_assert(xy->cols>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPErrorSubset: XY has less than NIn+NOut columns
", _state); 23742 if( subsetsize>=0 ) 23754 mlpallerrorsx(network, xy, &network->dummysxy, setsize, 0, subset, idx0, idx1, idxtype, &network->buf, &network->err, _state); 23755 result = ae_sqr(network->err.rmserror, _state)*(idx1-idx0)*mlpgetoutputscount(network, _state)/2; 23760 /************************************************************************* 23761 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 23762 *************************************************************************/ 23763 double _pexec_mlperrorsubset(multilayerperceptron* network, 23764 /* Real */ ae_matrix* xy, 23766 /* Integer */ ae_vector* subset, 23767 ae_int_t subsetsize, ae_state *_state) 23769 return mlperrorsubset(network,xy,setsize,subset,subsetsize, _state); 23773 /************************************************************************* 23774 Error of the neural network on sparse dataset. 23777 FOR USERS OF COMMERCIAL EDITION: 23779 ! Commercial version of ALGLIB includes two important improvements of 23781 ! * multicore support (C++ and C# computational cores) 23784 ! First improvement gives close-to-linear speedup on multicore systems. 23785 ! Second improvement gives constant speedup (2-3x depending on your CPU) 23787 ! In order to use multicore features you have to: 23788 ! * use commercial version of ALGLIB 23789 ! * call this function with "smp_
" prefix, which indicates that 23790 ! multicore code will be used (for multicore support) 23792 ! In order to use SSE features you have to: 23793 ! * use commercial version of ALGLIB on Intel processors 23794 ! * use C++ computational core 23796 ! This note is given for users of commercial edition; if you use GPL 23797 ! edition, you still will be able to call smp-version of this function, 23798 ! but all computations will be done serially. 23800 ! We recommend you to carefully read ALGLIB Reference Manual, section 23801 ! called 'SMP support', before using parallel version of this function. 23805 Network - neural network; 23806 XY - training set, see below for information on the 23807 training set format. This function checks correctness 23808 of the dataset (no NANs/INFs, class numbers are 23809 correct) and throws exception when incorrect dataset 23810 is passed. Sparse matrix must use CRS format for 23812 SetSize - real size of XY, SetSize>=0; 23813 it is used when SubsetSize<0; 23814 Subset - subset of SubsetSize elements, array[SubsetSize]; 23815 SubsetSize- number of elements in Subset[] array. 23818 sum-of-squares error, SUM(sqr(y[i]-desired_y[i])/2) 23822 This function uses two different dataset formats - one for regression 23823 networks, another one for classification networks. 23825 For regression networks with NIn inputs and NOut outputs following dataset 23827 * dataset is given by NPoints*(NIn+NOut) matrix 23828 * each row corresponds to one example 23829 * first NIn columns are inputs, next NOut columns are outputs 23831 For classification networks with NIn inputs and NClasses clases following 23832 dataset format is used: 23833 * dataset is given by NPoints*(NIn+1) matrix 23834 * each row corresponds to one example 23835 * first NIn columns are inputs, last column stores class number (from 0 to 23839 Copyright 04.09.2012 by Bochkanov Sergey 23840 *************************************************************************/ 23841 double mlperrorsparsesubset(multilayerperceptron* network, 23844 /* Integer */ ae_vector* subset, 23845 ae_int_t subsetsize, 23854 ae_assert(sparseiscrs(xy, _state), "MLPErrorSparseSubset: XY is not
in CRS format.
", _state); 23855 ae_assert(sparsegetnrows(xy, _state)>=setsize, "MLPErrorSparseSubset: XY has less than SetSize rows
", _state); 23858 if( mlpissoftmax(network, _state) ) 23860 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+1, "MLPErrorSparseSubset: XY has less than NIn+1 columns
", _state); 23864 ae_assert(sparsegetncols(xy, _state)>=mlpgetinputscount(network, _state)+mlpgetoutputscount(network, _state), "MLPErrorSparseSubset: XY has less than NIn+NOut columns
", _state); 23867 if( subsetsize>=0 ) 23879 mlpallerrorsx(network, &network->dummydxy, xy, setsize, 1, subset, idx0, idx1, idxtype, &network->buf, &network->err, _state); 23880 result = ae_sqr(network->err.rmserror, _state)*(idx1-idx0)*mlpgetoutputscount(network, _state)/2; 23885 /************************************************************************* 23886 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 23887 *************************************************************************/ 23888 double _pexec_mlperrorsparsesubset(multilayerperceptron* network, 23891 /* Integer */ ae_vector* subset, 23892 ae_int_t subsetsize, ae_state *_state) 23894 return mlperrorsparsesubset(network,xy,setsize,subset,subsetsize, _state); 23898 void mlpallerrorsx(multilayerperceptron* network, 23899 /* Real */ ae_matrix* densexy, 23900 sparsematrix* sparsexy, 23901 ae_int_t datasetsize, 23902 ae_int_t datasettype, 23903 /* Integer */ ae_vector* idx, 23906 ae_int_t subsettype, 23907 ae_shared_pool* buf, 23911 ae_frame _frame_block; 23922 ae_smart_ptr _pbuf; 23928 ae_frame_make(_state, &_frame_block); 23929 ae_smart_ptr_init(&_pbuf, (void**)&pbuf, _state, ae_true); 23930 _modelerrors_init(&rep0, _state, ae_true); 23931 _modelerrors_init(&rep1, _state, ae_true); 23933 ae_assert(datasetsize>=0, "MLPAllErrorsX: SetSize<0
", _state); 23934 ae_assert(datasettype==0||datasettype==1, "MLPAllErrorsX:
DatasetType is incorrect
", _state); 23935 ae_assert(subsettype==0||subsettype==1, "MLPAllErrorsX: SubsetType is incorrect
", _state); 23938 * Determine network properties 23940 mlpproperties(network, &nin, &nout, &wcount, _state); 23941 iscls = mlpissoftmax(network, _state); 23946 * Splitting problem allows us to reduce effect of single-precision 23947 * arithmetics (SSE-optimized version of MLPChunkedProcess uses single 23948 * precision internally, but converts them to double precision after 23949 * results are exported from HPC buffer to network). Small batches are 23950 * calculated in single precision, results are aggregated in double 23951 * precision, and it allows us to avoid accumulation of errors when 23952 * we process very large batches (tens of thousands of items). 23954 * NOTE: it is important to use real arithmetics for ProblemCost 23955 * because ProblemCost may be larger than MAXINT. 23957 if( subset1-subset0>=2*mlpbase_microbatchsize&&ae_fp_greater(inttoreal(subset1-subset0, _state)*inttoreal(wcount, _state),mlpbase_gradbasecasecost) ) 23959 splitlength(subset1-subset0, mlpbase_microbatchsize, &len0, &len1, _state); 23960 mlpallerrorsx(network, densexy, sparsexy, datasetsize, datasettype, idx, subset0, subset0+len0, subsettype, buf, &rep0, _state); 23961 mlpallerrorsx(network, densexy, sparsexy, datasetsize, datasettype, idx, subset0+len0, subset1, subsettype, buf, &rep1, _state); 23962 rep->relclserror = (len0*rep0.relclserror+len1*rep1.relclserror)/(len0+len1); 23963 rep->avgce = (len0*rep0.avgce+len1*rep1.avgce)/(len0+len1); 23964 rep->rmserror = ae_sqrt((len0*ae_sqr(rep0.rmserror, _state)+len1*ae_sqr(rep1.rmserror, _state))/(len0+len1), _state); 23965 rep->avgerror = (len0*rep0.avgerror+len1*rep1.avgerror)/(len0+len1); 23966 rep->avgrelerror = (len0*rep0.avgrelerror+len1*rep1.avgrelerror)/(len0+len1); 23967 ae_frame_leave(_state); 23972 * Retrieve and prepare 23974 ae_shared_pool_retrieve(buf, &_pbuf, _state); 23978 dserrallocate(nout, &pbuf->tmp0, _state); 23982 rowsize = nin+nout; 23983 dserrallocate(-nout, &pbuf->tmp0, _state); 23989 hpcpreparechunkedgradient(&network->weights, wcount, mlpntotal(network, _state), nin, nout, pbuf, _state); 23991 while(cstart<subset1) 23995 * Determine size of current chunk and copy it to PBuf.XY 23997 csize = ae_minint(subset1, cstart+pbuf->chunksize, _state)-cstart; 23998 for(j=0; j<=csize-1; j++) 24001 if( subsettype==0 ) 24005 if( subsettype==1 ) 24007 srcidx = idx->ptr.p_int[cstart+j]; 24009 ae_assert(srcidx>=0, "MLPAllErrorsX:
internal error", _state); 24010 if( datasettype==0 ) 24012 ae_v_move(&pbuf->xy.ptr.pp_double[j][0], 1, &densexy->ptr.pp_double[srcidx][0], 1, ae_v_len(0,rowsize-1)); 24014 if( datasettype==1 ) 24016 sparsegetrow(sparsexy, srcidx, &pbuf->xyrow, _state); 24017 ae_v_move(&pbuf->xy.ptr.pp_double[j][0], 1, &pbuf->xyrow.ptr.p_double[0], 1, ae_v_len(0,rowsize-1)); 24022 * Unpack XY and process (temporary code, to be replaced by chunked processing) 24024 for(j=0; j<=csize-1; j++) 24026 ae_v_move(&pbuf->xy2.ptr.pp_double[j][0], 1, &pbuf->xy.ptr.pp_double[j][0], 1, ae_v_len(0,rowsize-1)); 24028 mlpbase_mlpchunkedprocess(network, &pbuf->xy2, 0, csize, &pbuf->batch4buf, &pbuf->hpcbuf, _state); 24029 for(j=0; j<=csize-1; j++) 24031 ae_v_move(&pbuf->x.ptr.p_double[0], 1, &pbuf->xy2.ptr.pp_double[j][0], 1, ae_v_len(0,nin-1)); 24032 ae_v_move(&pbuf->y.ptr.p_double[0], 1, &pbuf->xy2.ptr.pp_double[j][nin], 1, ae_v_len(0,nout-1)); 24035 pbuf->desiredy.ptr.p_double[0] = pbuf->xy.ptr.pp_double[j][nin]; 24039 ae_v_move(&pbuf->desiredy.ptr.p_double[0], 1, &pbuf->xy.ptr.pp_double[j][nin], 1, ae_v_len(0,nout-1)); 24041 dserraccumulate(&pbuf->tmp0, &pbuf->y, &pbuf->desiredy, _state); 24045 * Process chunk and advance line pointer 24047 cstart = cstart+pbuf->chunksize; 24049 dserrfinish(&pbuf->tmp0, _state); 24050 rep->relclserror = pbuf->tmp0.ptr.p_double[0]; 24051 rep->avgce = pbuf->tmp0.ptr.p_double[1]/ae_log(2, _state); 24052 rep->rmserror = pbuf->tmp0.ptr.p_double[2]; 24053 rep->avgerror = pbuf->tmp0.ptr.p_double[3]; 24054 rep->avgrelerror = pbuf->tmp0.ptr.p_double[4]; 24059 ae_shared_pool_recycle(buf, &_pbuf, _state); 24060 ae_frame_leave(_state); 24064 /************************************************************************* 24065 Internal subroutine: adding new input layer to network 24066 *************************************************************************/ 24067 static void mlpbase_addinputlayer(ae_int_t ncount, 24068 /* Integer */ ae_vector* lsizes, 24069 /* Integer */ ae_vector* ltypes, 24070 /* Integer */ ae_vector* lconnfirst, 24071 /* Integer */ ae_vector* lconnlast, 24072 ae_int_t* lastproc, 24077 lsizes->ptr.p_int[0] = ncount; 24078 ltypes->ptr.p_int[0] = -2; 24079 lconnfirst->ptr.p_int[0] = 0; 24080 lconnlast->ptr.p_int[0] = 0; 24085 /************************************************************************* 24086 Internal subroutine: adding new summator layer to network 24087 *************************************************************************/ 24088 static void mlpbase_addbiasedsummatorlayer(ae_int_t ncount, 24089 /* Integer */ ae_vector* lsizes, 24090 /* Integer */ ae_vector* ltypes, 24091 /* Integer */ ae_vector* lconnfirst, 24092 /* Integer */ ae_vector* lconnlast, 24093 ae_int_t* lastproc, 24098 lsizes->ptr.p_int[*lastproc+1] = 1; 24099 ltypes->ptr.p_int[*lastproc+1] = -3; 24100 lconnfirst->ptr.p_int[*lastproc+1] = 0; 24101 lconnlast->ptr.p_int[*lastproc+1] = 0; 24102 lsizes->ptr.p_int[*lastproc+2] = ncount; 24103 ltypes->ptr.p_int[*lastproc+2] = 0; 24104 lconnfirst->ptr.p_int[*lastproc+2] = *lastproc; 24105 lconnlast->ptr.p_int[*lastproc+2] = *lastproc+1; 24106 *lastproc = *lastproc+2; 24110 /************************************************************************* 24111 Internal subroutine: adding new summator layer to network 24112 *************************************************************************/ 24113 static void mlpbase_addactivationlayer(ae_int_t functype, 24114 /* Integer */ ae_vector* lsizes, 24115 /* Integer */ ae_vector* ltypes, 24116 /* Integer */ ae_vector* lconnfirst, 24117 /* Integer */ ae_vector* lconnlast, 24118 ae_int_t* lastproc, 24123 ae_assert(functype>0||functype==-5, "AddActivationLayer: incorrect
function type", _state); 24124 lsizes->ptr.p_int[*lastproc+1] = lsizes->ptr.p_int[*lastproc]; 24125 ltypes->ptr.p_int[*lastproc+1] = functype; 24126 lconnfirst->ptr.p_int[*lastproc+1] = *lastproc; 24127 lconnlast->ptr.p_int[*lastproc+1] = *lastproc; 24128 *lastproc = *lastproc+1; 24132 /************************************************************************* 24133 Internal subroutine: adding new zero layer to network 24134 *************************************************************************/ 24135 static void mlpbase_addzerolayer(/* Integer */ ae_vector* lsizes, 24136 /* Integer */ ae_vector* ltypes, 24137 /* Integer */ ae_vector* lconnfirst, 24138 /* Integer */ ae_vector* lconnlast, 24139 ae_int_t* lastproc, 24144 lsizes->ptr.p_int[*lastproc+1] = 1; 24145 ltypes->ptr.p_int[*lastproc+1] = -4; 24146 lconnfirst->ptr.p_int[*lastproc+1] = 0; 24147 lconnlast->ptr.p_int[*lastproc+1] = 0; 24148 *lastproc = *lastproc+1; 24152 /************************************************************************* 24153 This routine adds input layer to the high-level description of the network. 24155 It modifies Network.HLConnections and Network.HLNeurons and assumes that 24156 these arrays have enough place to store data. It accepts following 24159 ConnIdx - index of the first free entry in the HLConnections 24160 NeuroIdx - index of the first free entry in the HLNeurons 24161 StructInfoIdx- index of the first entry in the low level description 24162 of the current layer (in the StructInfo array) 24163 NIn - number of inputs 24165 It modified Network and indices. 24166 *************************************************************************/ 24167 static void mlpbase_hladdinputlayer(multilayerperceptron* network, 24169 ae_int_t* neuroidx, 24170 ae_int_t* structinfoidx, 24178 offs = mlpbase_hlnfieldwidth*(*neuroidx); 24179 for(i=0; i<=nin-1; i++) 24181 network->hlneurons.ptr.p_int[offs+0] = 0; 24182 network->hlneurons.ptr.p_int[offs+1] = i; 24183 network->hlneurons.ptr.p_int[offs+2] = -1; 24184 network->hlneurons.ptr.p_int[offs+3] = -1; 24185 offs = offs+mlpbase_hlnfieldwidth; 24187 *neuroidx = *neuroidx+nin; 24188 *structinfoidx = *structinfoidx+nin; 24192 /************************************************************************* 24193 This routine adds output layer to the high-level description of 24196 It modifies Network.HLConnections and Network.HLNeurons and assumes that 24197 these arrays have enough place to store data. It accepts following 24200 ConnIdx - index of the first free entry in the HLConnections 24201 NeuroIdx - index of the first free entry in the HLNeurons 24202 StructInfoIdx- index of the first entry in the low level description 24203 of the current layer (in the StructInfo array) 24204 WeightsIdx - index of the first entry in the Weights array which 24205 corresponds to the current layer 24206 K - current layer index 24207 NPrev - number of neurons in the previous layer 24208 NOut - number of outputs 24209 IsCls - is it classifier network? 24210 IsLinear - is it network with linear output? 24212 It modified Network and ConnIdx/NeuroIdx/StructInfoIdx/WeightsIdx. 24213 *************************************************************************/ 24214 static void mlpbase_hladdoutputlayer(multilayerperceptron* network, 24216 ae_int_t* neuroidx, 24217 ae_int_t* structinfoidx, 24218 ae_int_t* weightsidx, 24223 ae_bool islinearout, 24228 ae_int_t neurooffs; 24232 ae_assert((iscls&&islinearout)||!iscls, "HLAddOutputLayer:
internal error", _state); 24233 neurooffs = mlpbase_hlnfieldwidth*(*neuroidx); 24234 connoffs = mlpbase_hlconnfieldwidth*(*connidx); 24239 * Regression network 24241 for(i=0; i<=nout-1; i++) 24243 network->hlneurons.ptr.p_int[neurooffs+0] = k; 24244 network->hlneurons.ptr.p_int[neurooffs+1] = i; 24245 network->hlneurons.ptr.p_int[neurooffs+2] = *structinfoidx+1+nout+i; 24246 network->hlneurons.ptr.p_int[neurooffs+3] = *weightsidx+nprev+(nprev+1)*i; 24247 neurooffs = neurooffs+mlpbase_hlnfieldwidth; 24249 for(i=0; i<=nprev-1; i++) 24251 for(j=0; j<=nout-1; j++) 24253 network->hlconnections.ptr.p_int[connoffs+0] = k-1; 24254 network->hlconnections.ptr.p_int[connoffs+1] = i; 24255 network->hlconnections.ptr.p_int[connoffs+2] = k; 24256 network->hlconnections.ptr.p_int[connoffs+3] = j; 24257 network->hlconnections.ptr.p_int[connoffs+4] = *weightsidx+i+j*(nprev+1); 24258 connoffs = connoffs+mlpbase_hlconnfieldwidth; 24261 *connidx = *connidx+nprev*nout; 24262 *neuroidx = *neuroidx+nout; 24263 *structinfoidx = *structinfoidx+2*nout+1; 24264 *weightsidx = *weightsidx+nout*(nprev+1); 24270 * Classification network 24272 for(i=0; i<=nout-2; i++) 24274 network->hlneurons.ptr.p_int[neurooffs+0] = k; 24275 network->hlneurons.ptr.p_int[neurooffs+1] = i; 24276 network->hlneurons.ptr.p_int[neurooffs+2] = -1; 24277 network->hlneurons.ptr.p_int[neurooffs+3] = *weightsidx+nprev+(nprev+1)*i; 24278 neurooffs = neurooffs+mlpbase_hlnfieldwidth; 24280 network->hlneurons.ptr.p_int[neurooffs+0] = k; 24281 network->hlneurons.ptr.p_int[neurooffs+1] = i; 24282 network->hlneurons.ptr.p_int[neurooffs+2] = -1; 24283 network->hlneurons.ptr.p_int[neurooffs+3] = -1; 24284 for(i=0; i<=nprev-1; i++) 24286 for(j=0; j<=nout-2; j++) 24288 network->hlconnections.ptr.p_int[connoffs+0] = k-1; 24289 network->hlconnections.ptr.p_int[connoffs+1] = i; 24290 network->hlconnections.ptr.p_int[connoffs+2] = k; 24291 network->hlconnections.ptr.p_int[connoffs+3] = j; 24292 network->hlconnections.ptr.p_int[connoffs+4] = *weightsidx+i+j*(nprev+1); 24293 connoffs = connoffs+mlpbase_hlconnfieldwidth; 24296 *connidx = *connidx+nprev*(nout-1); 24297 *neuroidx = *neuroidx+nout; 24298 *structinfoidx = *structinfoidx+nout+2; 24299 *weightsidx = *weightsidx+(nout-1)*(nprev+1); 24304 /************************************************************************* 24305 This routine adds hidden layer to the high-level description of 24308 It modifies Network.HLConnections and Network.HLNeurons and assumes that 24309 these arrays have enough place to store data. It accepts following 24312 ConnIdx - index of the first free entry in the HLConnections 24313 NeuroIdx - index of the first free entry in the HLNeurons 24314 StructInfoIdx- index of the first entry in the low level description 24315 of the current layer (in the StructInfo array) 24316 WeightsIdx - index of the first entry in the Weights array which 24317 corresponds to the current layer 24318 K - current layer index 24319 NPrev - number of neurons in the previous layer 24320 NCur - number of neurons in the current layer 24322 It modified Network and ConnIdx/NeuroIdx/StructInfoIdx/WeightsIdx. 24323 *************************************************************************/ 24324 static void mlpbase_hladdhiddenlayer(multilayerperceptron* network, 24326 ae_int_t* neuroidx, 24327 ae_int_t* structinfoidx, 24328 ae_int_t* weightsidx, 24336 ae_int_t neurooffs; 24340 neurooffs = mlpbase_hlnfieldwidth*(*neuroidx); 24341 connoffs = mlpbase_hlconnfieldwidth*(*connidx); 24342 for(i=0; i<=ncur-1; i++) 24344 network->hlneurons.ptr.p_int[neurooffs+0] = k; 24345 network->hlneurons.ptr.p_int[neurooffs+1] = i; 24346 network->hlneurons.ptr.p_int[neurooffs+2] = *structinfoidx+1+ncur+i; 24347 network->hlneurons.ptr.p_int[neurooffs+3] = *weightsidx+nprev+(nprev+1)*i; 24348 neurooffs = neurooffs+mlpbase_hlnfieldwidth; 24350 for(i=0; i<=nprev-1; i++) 24352 for(j=0; j<=ncur-1; j++) 24354 network->hlconnections.ptr.p_int[connoffs+0] = k-1; 24355 network->hlconnections.ptr.p_int[connoffs+1] = i; 24356 network->hlconnections.ptr.p_int[connoffs+2] = k; 24357 network->hlconnections.ptr.p_int[connoffs+3] = j; 24358 network->hlconnections.ptr.p_int[connoffs+4] = *weightsidx+i+j*(nprev+1); 24359 connoffs = connoffs+mlpbase_hlconnfieldwidth; 24362 *connidx = *connidx+nprev*ncur; 24363 *neuroidx = *neuroidx+ncur; 24364 *structinfoidx = *structinfoidx+2*ncur+1; 24365 *weightsidx = *weightsidx+ncur*(nprev+1); 24369 /************************************************************************* 24370 This function fills high level information about network created using 24371 internal MLPCreate() function. 24373 This function does NOT examine StructInfo for low level information, it 24374 just expects that network has following structure: 24383 biased summator | hidden layer(s), if there are exists any 24384 activation function | 24386 activation function / 24389 biased summator | output layer: 24391 biased summator | * we have NOut summators/activators for regression networks 24392 activation function | * we have only NOut-1 summators and no activators for classifiers 24393 ... | * we have "0
" neuron only when we have classifier 24394 activation function | 24399 Copyright 30.03.2008 by Bochkanov Sergey 24400 *************************************************************************/ 24401 static void mlpbase_fillhighlevelinformation(multilayerperceptron* network, 24407 ae_bool islinearout, 24410 ae_int_t idxweights; 24411 ae_int_t idxstruct; 24416 ae_assert((iscls&&islinearout)||!iscls, "FillHighLevelInformation:
internal error", _state); 24419 * Preparations common to all types of networks 24425 network->hlnetworktype = 0; 24428 * network without hidden layers 24432 ae_vector_set_length(&network->hllayersizes, 2, _state); 24433 network->hllayersizes.ptr.p_int[0] = nin; 24434 network->hllayersizes.ptr.p_int[1] = nout; 24437 ae_vector_set_length(&network->hlconnections, mlpbase_hlconnfieldwidth*nin*nout, _state); 24438 ae_vector_set_length(&network->hlneurons, mlpbase_hlnfieldwidth*(nin+nout), _state); 24439 network->hlnormtype = 0; 24443 ae_vector_set_length(&network->hlconnections, mlpbase_hlconnfieldwidth*nin*(nout-1), _state); 24444 ae_vector_set_length(&network->hlneurons, mlpbase_hlnfieldwidth*(nin+nout), _state); 24445 network->hlnormtype = 1; 24447 mlpbase_hladdinputlayer(network, &idxconn, &idxneuro, &idxstruct, nin, _state); 24448 mlpbase_hladdoutputlayer(network, &idxconn, &idxneuro, &idxstruct, &idxweights, 1, nin, nout, iscls, islinearout, _state); 24453 * network with one hidden layers 24457 ae_vector_set_length(&network->hllayersizes, 3, _state); 24458 network->hllayersizes.ptr.p_int[0] = nin; 24459 network->hllayersizes.ptr.p_int[1] = nhid1; 24460 network->hllayersizes.ptr.p_int[2] = nout; 24463 ae_vector_set_length(&network->hlconnections, mlpbase_hlconnfieldwidth*(nin*nhid1+nhid1*nout), _state); 24464 ae_vector_set_length(&network->hlneurons, mlpbase_hlnfieldwidth*(nin+nhid1+nout), _state); 24465 network->hlnormtype = 0; 24469 ae_vector_set_length(&network->hlconnections, mlpbase_hlconnfieldwidth*(nin*nhid1+nhid1*(nout-1)), _state); 24470 ae_vector_set_length(&network->hlneurons, mlpbase_hlnfieldwidth*(nin+nhid1+nout), _state); 24471 network->hlnormtype = 1; 24473 mlpbase_hladdinputlayer(network, &idxconn, &idxneuro, &idxstruct, nin, _state); 24474 mlpbase_hladdhiddenlayer(network, &idxconn, &idxneuro, &idxstruct, &idxweights, 1, nin, nhid1, _state); 24475 mlpbase_hladdoutputlayer(network, &idxconn, &idxneuro, &idxstruct, &idxweights, 2, nhid1, nout, iscls, islinearout, _state); 24480 * Two hidden layers 24482 ae_vector_set_length(&network->hllayersizes, 4, _state); 24483 network->hllayersizes.ptr.p_int[0] = nin; 24484 network->hllayersizes.ptr.p_int[1] = nhid1; 24485 network->hllayersizes.ptr.p_int[2] = nhid2; 24486 network->hllayersizes.ptr.p_int[3] = nout; 24489 ae_vector_set_length(&network->hlconnections, mlpbase_hlconnfieldwidth*(nin*nhid1+nhid1*nhid2+nhid2*nout), _state); 24490 ae_vector_set_length(&network->hlneurons, mlpbase_hlnfieldwidth*(nin+nhid1+nhid2+nout), _state); 24491 network->hlnormtype = 0; 24495 ae_vector_set_length(&network->hlconnections, mlpbase_hlconnfieldwidth*(nin*nhid1+nhid1*nhid2+nhid2*(nout-1)), _state); 24496 ae_vector_set_length(&network->hlneurons, mlpbase_hlnfieldwidth*(nin+nhid1+nhid2+nout), _state); 24497 network->hlnormtype = 1; 24499 mlpbase_hladdinputlayer(network, &idxconn, &idxneuro, &idxstruct, nin, _state); 24500 mlpbase_hladdhiddenlayer(network, &idxconn, &idxneuro, &idxstruct, &idxweights, 1, nin, nhid1, _state); 24501 mlpbase_hladdhiddenlayer(network, &idxconn, &idxneuro, &idxstruct, &idxweights, 2, nhid1, nhid2, _state); 24502 mlpbase_hladdoutputlayer(network, &idxconn, &idxneuro, &idxstruct, &idxweights, 3, nhid2, nout, iscls, islinearout, _state); 24506 /************************************************************************* 24507 Internal subroutine. 24510 Copyright 04.11.2007 by Bochkanov Sergey 24511 *************************************************************************/ 24512 static void mlpbase_mlpcreate(ae_int_t nin, 24514 /* Integer */ ae_vector* lsizes, 24515 /* Integer */ ae_vector* ltypes, 24516 /* Integer */ ae_vector* lconnfirst, 24517 /* Integer */ ae_vector* lconnlast, 24518 ae_int_t layerscount, 24520 multilayerperceptron* network, 24523 ae_frame _frame_block; 24530 ae_int_t nprocessed; 24531 ae_int_t wallocated; 24532 ae_vector localtemp; 24538 ae_frame_make(_state, &_frame_block); 24539 _multilayerperceptron_clear(network); 24540 ae_vector_init(&localtemp, 0, DT_INT, _state, ae_true); 24541 ae_vector_init(&lnfirst, 0, DT_INT, _state, ae_true); 24542 ae_vector_init(&lnsyn, 0, DT_INT, _state, ae_true); 24543 _mlpbuffers_init(&buf, _state, ae_true); 24544 _smlpgrad_init(&sgrad, _state, ae_true); 24550 ae_assert(layerscount>0, "MLPCreate: wrong parameters!
", _state); 24551 ae_assert(ltypes->ptr.p_int[0]==-2, "MLPCreate: wrong LTypes[0] (must be -2)!
", _state); 24552 for(i=0; i<=layerscount-1; i++) 24554 ae_assert(lsizes->ptr.p_int[i]>0, "MLPCreate: wrong LSizes!
", _state); 24555 ae_assert(lconnfirst->ptr.p_int[i]>=0&&(lconnfirst->ptr.p_int[i]<i||i==0), "MLPCreate: wrong LConnFirst!
", _state); 24556 ae_assert(lconnlast->ptr.p_int[i]>=lconnfirst->ptr.p_int[i]&&(lconnlast->ptr.p_int[i]<i||i==0), "MLPCreate: wrong LConnLast!
", _state); 24560 * Build network geometry 24562 ae_vector_set_length(&lnfirst, layerscount-1+1, _state); 24563 ae_vector_set_length(&lnsyn, layerscount-1+1, _state); 24566 for(i=0; i<=layerscount-1; i++) 24570 * Analyze connections. 24571 * This code must throw an assertion in case of unknown LTypes[I] 24573 lnsyn.ptr.p_int[i] = -1; 24574 if( ltypes->ptr.p_int[i]>=0||ltypes->ptr.p_int[i]==-5 ) 24576 lnsyn.ptr.p_int[i] = 0; 24577 for(j=lconnfirst->ptr.p_int[i]; j<=lconnlast->ptr.p_int[i]; j++) 24579 lnsyn.ptr.p_int[i] = lnsyn.ptr.p_int[i]+lsizes->ptr.p_int[j]; 24584 if( (ltypes->ptr.p_int[i]==-2||ltypes->ptr.p_int[i]==-3)||ltypes->ptr.p_int[i]==-4 ) 24586 lnsyn.ptr.p_int[i] = 0; 24589 ae_assert(lnsyn.ptr.p_int[i]>=0, "MLPCreate:
internal error #0!
", _state); 24594 lnfirst.ptr.p_int[i] = ntotal; 24595 ntotal = ntotal+lsizes->ptr.p_int[i]; 24596 if( ltypes->ptr.p_int[i]==0 ) 24598 wcount = wcount+lnsyn.ptr.p_int[i]*lsizes->ptr.p_int[i]; 24601 ssize = 7+ntotal*mlpbase_nfieldwidth; 24606 ae_vector_set_length(&network->structinfo, ssize-1+1, _state); 24607 ae_vector_set_length(&network->weights, wcount-1+1, _state); 24610 ae_vector_set_length(&network->columnmeans, nin-1+1, _state); 24611 ae_vector_set_length(&network->columnsigmas, nin-1+1, _state); 24615 ae_vector_set_length(&network->columnmeans, nin+nout-1+1, _state); 24616 ae_vector_set_length(&network->columnsigmas, nin+nout-1+1, _state); 24618 ae_vector_set_length(&network->neurons, ntotal-1+1, _state); 24619 ae_vector_set_length(&network->nwbuf, ae_maxint(wcount, 2*nout, _state)-1+1, _state); 24620 ae_vector_set_length(&network->integerbuf, 3+1, _state); 24621 ae_vector_set_length(&network->dfdnet, ntotal-1+1, _state); 24622 ae_vector_set_length(&network->x, nin-1+1, _state); 24623 ae_vector_set_length(&network->y, nout-1+1, _state); 24624 ae_vector_set_length(&network->derror, ntotal-1+1, _state); 24627 * Fill structure: global info 24629 network->structinfo.ptr.p_int[0] = ssize; 24630 network->structinfo.ptr.p_int[1] = nin; 24631 network->structinfo.ptr.p_int[2] = nout; 24632 network->structinfo.ptr.p_int[3] = ntotal; 24633 network->structinfo.ptr.p_int[4] = wcount; 24634 network->structinfo.ptr.p_int[5] = 7; 24637 network->structinfo.ptr.p_int[6] = 1; 24641 network->structinfo.ptr.p_int[6] = 0; 24645 * Fill structure: neuron connections 24649 for(i=0; i<=layerscount-1; i++) 24651 for(j=0; j<=lsizes->ptr.p_int[i]-1; j++) 24653 offs = network->structinfo.ptr.p_int[5]+nprocessed*mlpbase_nfieldwidth; 24654 network->structinfo.ptr.p_int[offs+0] = ltypes->ptr.p_int[i]; 24655 if( ltypes->ptr.p_int[i]==0 ) 24659 * Adaptive summator: 24660 * * connections with weights to previous neurons 24662 network->structinfo.ptr.p_int[offs+1] = lnsyn.ptr.p_int[i]; 24663 network->structinfo.ptr.p_int[offs+2] = lnfirst.ptr.p_int[lconnfirst->ptr.p_int[i]]; 24664 network->structinfo.ptr.p_int[offs+3] = wallocated; 24665 wallocated = wallocated+lnsyn.ptr.p_int[i]; 24666 nprocessed = nprocessed+1; 24668 if( ltypes->ptr.p_int[i]>0||ltypes->ptr.p_int[i]==-5 ) 24672 * Activation layer: 24673 * * each neuron connected to one (only one) of previous neurons. 24676 network->structinfo.ptr.p_int[offs+1] = 1; 24677 network->structinfo.ptr.p_int[offs+2] = lnfirst.ptr.p_int[lconnfirst->ptr.p_int[i]]+j; 24678 network->structinfo.ptr.p_int[offs+3] = -1; 24679 nprocessed = nprocessed+1; 24681 if( (ltypes->ptr.p_int[i]==-2||ltypes->ptr.p_int[i]==-3)||ltypes->ptr.p_int[i]==-4 ) 24683 nprocessed = nprocessed+1; 24687 ae_assert(wallocated==wcount, "MLPCreate:
internal error #1!
", _state); 24688 ae_assert(nprocessed==ntotal, "MLPCreate:
internal error #2!
", _state); 24691 * Fill weights by small random values 24692 * Initialize means and sigmas 24694 for(i=0; i<=nin-1; i++) 24696 network->columnmeans.ptr.p_double[i] = 0; 24697 network->columnsigmas.ptr.p_double[i] = 1; 24701 for(i=0; i<=nout-1; i++) 24703 network->columnmeans.ptr.p_double[nin+i] = 0; 24704 network->columnsigmas.ptr.p_double[nin+i] = 1; 24707 mlprandomize(network, _state); 24712 ae_shared_pool_set_seed(&network->buf, &buf, sizeof(buf), _mlpbuffers_init, _mlpbuffers_init_copy, _mlpbuffers_destroy, _state); 24713 ae_vector_set_length(&sgrad.g, wcount, _state); 24715 for(i=0; i<=wcount-1; i++) 24717 sgrad.g.ptr.p_double[i] = 0.0; 24719 ae_shared_pool_set_seed(&network->gradbuf, &sgrad, sizeof(sgrad), _smlpgrad_init, _smlpgrad_init_copy, _smlpgrad_destroy, _state); 24720 ae_frame_leave(_state); 24724 /************************************************************************* 24725 Internal subroutine for Hessian calculation. 24727 WARNING! Unspeakable math far beyong human capabilities :) 24728 *************************************************************************/ 24729 static void mlpbase_mlphessianbatchinternal(multilayerperceptron* network, 24730 /* Real */ ae_matrix* xy, 24732 ae_bool naturalerr, 24734 /* Real */ ae_vector* grad, 24735 /* Real */ ae_matrix* h, 24738 ae_frame _frame_block; 24769 ae_vector desiredy; 24777 ae_frame_make(_state, &_frame_block); 24779 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 24780 ae_vector_init(&desiredy, 0, DT_REAL, _state, ae_true); 24781 ae_vector_init(>, 0, DT_REAL, _state, ae_true); 24782 ae_vector_init(&zeros, 0, DT_REAL, _state, ae_true); 24783 ae_matrix_init(&rx, 0, 0, DT_REAL, _state, ae_true); 24784 ae_matrix_init(&ry, 0, 0, DT_REAL, _state, ae_true); 24785 ae_matrix_init(&rdx, 0, 0, DT_REAL, _state, ae_true); 24786 ae_matrix_init(&rdy, 0, 0, DT_REAL, _state, ae_true); 24788 mlpproperties(network, &nin, &nout, &wcount, _state); 24789 ntotal = network->structinfo.ptr.p_int[3]; 24790 istart = network->structinfo.ptr.p_int[5]; 24795 ae_vector_set_length(&x, nin-1+1, _state); 24796 ae_vector_set_length(&desiredy, nout-1+1, _state); 24797 ae_vector_set_length(&zeros, wcount-1+1, _state); 24798 ae_vector_set_length(>, wcount-1+1, _state); 24799 ae_matrix_set_length(&rx, ntotal+nout-1+1, wcount-1+1, _state); 24800 ae_matrix_set_length(&ry, ntotal+nout-1+1, wcount-1+1, _state); 24801 ae_matrix_set_length(&rdx, ntotal+nout-1+1, wcount-1+1, _state); 24802 ae_matrix_set_length(&rdy, ntotal+nout-1+1, wcount-1+1, _state); 24804 for(i=0; i<=wcount-1; i++) 24806 zeros.ptr.p_double[i] = 0; 24808 ae_v_move(&grad->ptr.p_double[0], 1, &zeros.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 24809 for(i=0; i<=wcount-1; i++) 24811 ae_v_move(&h->ptr.pp_double[i][0], 1, &zeros.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 24817 for(k=0; k<=ssize-1; k++) 24821 * Process vector with MLPGradN. 24822 * Now Neurons, DFDNET and DError contains results of the last run. 24824 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[k][0], 1, ae_v_len(0,nin-1)); 24825 if( mlpissoftmax(network, _state) ) 24829 * class labels outputs 24831 kl = ae_round(xy->ptr.pp_double[k][nin], _state); 24832 for(i=0; i<=nout-1; i++) 24836 desiredy.ptr.p_double[i] = 1; 24840 desiredy.ptr.p_double[i] = 0; 24850 ae_v_move(&desiredy.ptr.p_double[0], 1, &xy->ptr.pp_double[k][nin], 1, ae_v_len(0,nout-1)); 24854 mlpgradn(network, &x, &desiredy, &et, >, _state); 24858 mlpgrad(network, &x, &desiredy, &et, >, _state); 24865 ae_v_add(&grad->ptr.p_double[0], 1, >.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 24869 * Forward pass of the R-algorithm 24871 for(i=0; i<=ntotal-1; i++) 24873 offs = istart+i*mlpbase_nfieldwidth; 24874 ae_v_move(&rx.ptr.pp_double[i][0], 1, &zeros.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 24875 ae_v_move(&ry.ptr.pp_double[i][0], 1, &zeros.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 24876 if( network->structinfo.ptr.p_int[offs+0]>0||network->structinfo.ptr.p_int[offs+0]==-5 ) 24880 * Activation function 24882 n1 = network->structinfo.ptr.p_int[offs+2]; 24883 ae_v_move(&rx.ptr.pp_double[i][0], 1, &ry.ptr.pp_double[n1][0], 1, ae_v_len(0,wcount-1)); 24884 v = network->dfdnet.ptr.p_double[i]; 24885 ae_v_moved(&ry.ptr.pp_double[i][0], 1, &rx.ptr.pp_double[i][0], 1, ae_v_len(0,wcount-1), v); 24888 if( network->structinfo.ptr.p_int[offs+0]==0 ) 24892 * Adaptive summator 24894 n1 = network->structinfo.ptr.p_int[offs+2]; 24895 n2 = n1+network->structinfo.ptr.p_int[offs+1]-1; 24896 w1 = network->structinfo.ptr.p_int[offs+3]; 24897 w2 = w1+network->structinfo.ptr.p_int[offs+1]-1; 24898 for(j=n1; j<=n2; j++) 24900 v = network->weights.ptr.p_double[w1+j-n1]; 24901 ae_v_addd(&rx.ptr.pp_double[i][0], 1, &ry.ptr.pp_double[j][0], 1, ae_v_len(0,wcount-1), v); 24902 rx.ptr.pp_double[i][w1+j-n1] = rx.ptr.pp_double[i][w1+j-n1]+network->neurons.ptr.p_double[j]; 24904 ae_v_move(&ry.ptr.pp_double[i][0], 1, &rx.ptr.pp_double[i][0], 1, ae_v_len(0,wcount-1)); 24907 if( network->structinfo.ptr.p_int[offs+0]<0 ) 24910 if( network->structinfo.ptr.p_int[offs+0]==-2 ) 24914 * input neuron, left unchanged 24918 if( network->structinfo.ptr.p_int[offs+0]==-3 ) 24922 * "-1
" neuron, left unchanged 24926 if( network->structinfo.ptr.p_int[offs+0]==-4 ) 24930 * "0
" neuron, left unchanged 24934 ae_assert(!bflag, "MLPHessianNBatch:
internal error - unknown neuron
type!
", _state); 24940 * Hessian. Backward pass of the R-algorithm. 24942 * Stage 1. Initialize RDY 24944 for(i=0; i<=ntotal+nout-1; i++) 24946 ae_v_move(&rdy.ptr.pp_double[i][0], 1, &zeros.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 24948 if( network->structinfo.ptr.p_int[6]==0 ) 24954 * In context of the Hessian calculation standardisation 24955 * is considered as additional layer with weightless 24956 * activation function: 24958 * F(NET) := Sigma*NET 24960 * So we add one more layer to forward pass, and 24961 * make forward/backward pass through this layer. 24963 for(i=0; i<=nout-1; i++) 24965 n1 = ntotal-nout+i; 24969 * Forward pass from N1 to N2 24971 ae_v_move(&rx.ptr.pp_double[n2][0], 1, &ry.ptr.pp_double[n1][0], 1, ae_v_len(0,wcount-1)); 24972 v = network->columnsigmas.ptr.p_double[nin+i]; 24973 ae_v_moved(&ry.ptr.pp_double[n2][0], 1, &rx.ptr.pp_double[n2][0], 1, ae_v_len(0,wcount-1), v); 24976 * Initialization of RDY 24978 ae_v_move(&rdy.ptr.pp_double[n2][0], 1, &ry.ptr.pp_double[n2][0], 1, ae_v_len(0,wcount-1)); 24981 * Backward pass from N2 to N1: 24982 * 1. Calculate R(dE/dX). 24983 * 2. No R(dE/dWij) is needed since weight of activation neuron 24984 * is fixed to 1. So we can update R(dE/dY) for 24985 * the connected neuron (note that Vij=0, Wij=1) 24987 df = network->columnsigmas.ptr.p_double[nin+i]; 24988 ae_v_moved(&rdx.ptr.pp_double[n2][0], 1, &rdy.ptr.pp_double[n2][0], 1, ae_v_len(0,wcount-1), df); 24989 ae_v_add(&rdy.ptr.pp_double[n1][0], 1, &rdx.ptr.pp_double[n2][0], 1, ae_v_len(0,wcount-1)); 24998 * Initialize RDY using generalized expression for ei'(yi) 24999 * (see expression (9) from p. 5 of "Fast Exact Multiplication by the Hessian
"). 25001 * When we are working with softmax network, generalized 25002 * expression for ei'(yi) is used because softmax 25003 * normalization leads to ei, which depends on all y's 25009 * softmax + cross-entropy. 25012 * S = sum(exp(yk)), 25013 * ei = sum(trn)*exp(yi)/S-trn_i 25015 * j=i: d(ei)/d(yj) = T*exp(yi)*(S-exp(yi))/S^2 25016 * j<>i: d(ei)/d(yj) = -T*exp(yi)*exp(yj)/S^2 25019 for(i=0; i<=nout-1; i++) 25021 t = t+desiredy.ptr.p_double[i]; 25023 mx = network->neurons.ptr.p_double[ntotal-nout]; 25024 for(i=0; i<=nout-1; i++) 25026 mx = ae_maxreal(mx, network->neurons.ptr.p_double[ntotal-nout+i], _state); 25029 for(i=0; i<=nout-1; i++) 25031 network->nwbuf.ptr.p_double[i] = ae_exp(network->neurons.ptr.p_double[ntotal-nout+i]-mx, _state); 25032 s = s+network->nwbuf.ptr.p_double[i]; 25034 for(i=0; i<=nout-1; i++) 25036 for(j=0; j<=nout-1; j++) 25040 deidyj = t*network->nwbuf.ptr.p_double[i]*(s-network->nwbuf.ptr.p_double[i])/ae_sqr(s, _state); 25041 ae_v_addd(&rdy.ptr.pp_double[ntotal-nout+i][0], 1, &ry.ptr.pp_double[ntotal-nout+i][0], 1, ae_v_len(0,wcount-1), deidyj); 25045 deidyj = -t*network->nwbuf.ptr.p_double[i]*network->nwbuf.ptr.p_double[j]/ae_sqr(s, _state); 25046 ae_v_addd(&rdy.ptr.pp_double[ntotal-nout+i][0], 1, &ry.ptr.pp_double[ntotal-nout+j][0], 1, ae_v_len(0,wcount-1), deidyj); 25055 * For a softmax + squared error we have expression 25056 * far beyond human imagination so we don't even try 25057 * to comment on it. Just enjoy the code... 25059 * P.S. That's why "natural
error" is called "natural
" - 25060 * compact beautiful expressions, fast code.... 25062 mx = network->neurons.ptr.p_double[ntotal-nout]; 25063 for(i=0; i<=nout-1; i++) 25065 mx = ae_maxreal(mx, network->neurons.ptr.p_double[ntotal-nout+i], _state); 25069 for(i=0; i<=nout-1; i++) 25071 network->nwbuf.ptr.p_double[i] = ae_exp(network->neurons.ptr.p_double[ntotal-nout+i]-mx, _state); 25072 s = s+network->nwbuf.ptr.p_double[i]; 25073 s2 = s2+ae_sqr(network->nwbuf.ptr.p_double[i], _state); 25076 for(i=0; i<=nout-1; i++) 25078 q = q+(network->y.ptr.p_double[i]-desiredy.ptr.p_double[i])*network->nwbuf.ptr.p_double[i]; 25080 for(i=0; i<=nout-1; i++) 25082 z = -q+(network->y.ptr.p_double[i]-desiredy.ptr.p_double[i])*s; 25083 expi = network->nwbuf.ptr.p_double[i]; 25084 for(j=0; j<=nout-1; j++) 25086 expj = network->nwbuf.ptr.p_double[j]; 25089 deidyj = expi/ae_sqr(s, _state)*((z+expi)*(s-2*expi)/s+expi*s2/ae_sqr(s, _state)); 25093 deidyj = expi*expj/ae_sqr(s, _state)*(s2/ae_sqr(s, _state)-2*z/s-(expi+expj)/s+(network->y.ptr.p_double[i]-desiredy.ptr.p_double[i])-(network->y.ptr.p_double[j]-desiredy.ptr.p_double[j])); 25095 ae_v_addd(&rdy.ptr.pp_double[ntotal-nout+i][0], 1, &ry.ptr.pp_double[ntotal-nout+j][0], 1, ae_v_len(0,wcount-1), deidyj); 25102 * Hessian. Backward pass of the R-algorithm 25104 * Stage 2. Process. 25106 for(i=ntotal-1; i>=0; i--) 25110 * Possible variants: 25111 * 1. Activation function 25112 * 2. Adaptive summator 25113 * 3. Special neuron 25115 offs = istart+i*mlpbase_nfieldwidth; 25116 if( network->structinfo.ptr.p_int[offs+0]>0||network->structinfo.ptr.p_int[offs+0]==-5 ) 25118 n1 = network->structinfo.ptr.p_int[offs+2]; 25121 * First, calculate R(dE/dX). 25123 mlpactivationfunction(network->neurons.ptr.p_double[n1], network->structinfo.ptr.p_int[offs+0], &f, &df, &d2f, _state); 25124 v = d2f*network->derror.ptr.p_double[i]; 25125 ae_v_moved(&rdx.ptr.pp_double[i][0], 1, &rdy.ptr.pp_double[i][0], 1, ae_v_len(0,wcount-1), df); 25126 ae_v_addd(&rdx.ptr.pp_double[i][0], 1, &rx.ptr.pp_double[i][0], 1, ae_v_len(0,wcount-1), v); 25129 * No R(dE/dWij) is needed since weight of activation neuron 25132 * So we can update R(dE/dY) for the connected neuron. 25133 * (note that Vij=0, Wij=1) 25135 ae_v_add(&rdy.ptr.pp_double[n1][0], 1, &rdx.ptr.pp_double[i][0], 1, ae_v_len(0,wcount-1)); 25138 if( network->structinfo.ptr.p_int[offs+0]==0 ) 25142 * Adaptive summator 25144 n1 = network->structinfo.ptr.p_int[offs+2]; 25145 n2 = n1+network->structinfo.ptr.p_int[offs+1]-1; 25146 w1 = network->structinfo.ptr.p_int[offs+3]; 25147 w2 = w1+network->structinfo.ptr.p_int[offs+1]-1; 25150 * First, calculate R(dE/dX). 25152 ae_v_move(&rdx.ptr.pp_double[i][0], 1, &rdy.ptr.pp_double[i][0], 1, ae_v_len(0,wcount-1)); 25155 * Then, calculate R(dE/dWij) 25157 for(j=w1; j<=w2; j++) 25159 v = network->neurons.ptr.p_double[n1+j-w1]; 25160 ae_v_addd(&h->ptr.pp_double[j][0], 1, &rdx.ptr.pp_double[i][0], 1, ae_v_len(0,wcount-1), v); 25161 v = network->derror.ptr.p_double[i]; 25162 ae_v_addd(&h->ptr.pp_double[j][0], 1, &ry.ptr.pp_double[n1+j-w1][0], 1, ae_v_len(0,wcount-1), v); 25166 * And finally, update R(dE/dY) for connected neurons. 25168 for(j=w1; j<=w2; j++) 25170 v = network->weights.ptr.p_double[j]; 25171 ae_v_addd(&rdy.ptr.pp_double[n1+j-w1][0], 1, &rdx.ptr.pp_double[i][0], 1, ae_v_len(0,wcount-1), v); 25172 rdy.ptr.pp_double[n1+j-w1][j] = rdy.ptr.pp_double[n1+j-w1][j]+network->derror.ptr.p_double[i]; 25176 if( network->structinfo.ptr.p_int[offs+0]<0 ) 25179 if( (network->structinfo.ptr.p_int[offs+0]==-2||network->structinfo.ptr.p_int[offs+0]==-3)||network->structinfo.ptr.p_int[offs+0]==-4 ) 25183 * Special neuron type, no back-propagation required 25187 ae_assert(bflag, "MLPHessianNBatch: unknown neuron
type!
", _state); 25192 ae_frame_leave(_state); 25196 /************************************************************************* 25197 Internal subroutine 25199 Network must be processed by MLPProcess on X 25200 *************************************************************************/ 25201 static void mlpbase_mlpinternalcalculategradient(multilayerperceptron* network, 25202 /* Real */ ae_vector* neurons, 25203 /* Real */ ae_vector* weights, 25204 /* Real */ ae_vector* derror, 25205 /* Real */ ae_vector* grad, 25206 ae_bool naturalerrorfunc, 25231 * Read network geometry 25233 nin = network->structinfo.ptr.p_int[1]; 25234 nout = network->structinfo.ptr.p_int[2]; 25235 ntotal = network->structinfo.ptr.p_int[3]; 25236 istart = network->structinfo.ptr.p_int[5]; 25239 * Pre-processing of dError/dOut: 25240 * from dError/dOut(normalized) to dError/dOut(non-normalized) 25242 ae_assert(network->structinfo.ptr.p_int[6]==0||network->structinfo.ptr.p_int[6]==1, "MLPInternalCalculateGradient: unknown normalization
type!
", _state); 25243 if( network->structinfo.ptr.p_int[6]==1 ) 25249 if( !naturalerrorfunc ) 25251 mx = network->neurons.ptr.p_double[ntotal-nout]; 25252 for(i=0; i<=nout-1; i++) 25254 mx = ae_maxreal(mx, network->neurons.ptr.p_double[ntotal-nout+i], _state); 25257 for(i=0; i<=nout-1; i++) 25259 network->nwbuf.ptr.p_double[i] = ae_exp(network->neurons.ptr.p_double[ntotal-nout+i]-mx, _state); 25260 net = net+network->nwbuf.ptr.p_double[i]; 25262 v = ae_v_dotproduct(&network->derror.ptr.p_double[ntotal-nout], 1, &network->nwbuf.ptr.p_double[0], 1, ae_v_len(ntotal-nout,ntotal-1)); 25263 for(i=0; i<=nout-1; i++) 25265 fown = network->nwbuf.ptr.p_double[i]; 25266 deown = network->derror.ptr.p_double[ntotal-nout+i]; 25267 network->nwbuf.ptr.p_double[nout+i] = (-v+deown*fown+deown*(net-fown))*fown/ae_sqr(net, _state); 25269 for(i=0; i<=nout-1; i++) 25271 network->derror.ptr.p_double[ntotal-nout+i] = network->nwbuf.ptr.p_double[nout+i]; 25279 * Un-standardisation 25281 for(i=0; i<=nout-1; i++) 25283 network->derror.ptr.p_double[ntotal-nout+i] = network->derror.ptr.p_double[ntotal-nout+i]*network->columnsigmas.ptr.p_double[nin+i]; 25290 for(i=ntotal-1; i>=0; i--) 25296 offs = istart+i*mlpbase_nfieldwidth; 25297 if( network->structinfo.ptr.p_int[offs+0]>0||network->structinfo.ptr.p_int[offs+0]==-5 ) 25301 * Activation function 25303 dedf = network->derror.ptr.p_double[i]; 25304 dfdnet = network->dfdnet.ptr.p_double[i]; 25305 derror->ptr.p_double[network->structinfo.ptr.p_int[offs+2]] = derror->ptr.p_double[network->structinfo.ptr.p_int[offs+2]]+dedf*dfdnet; 25308 if( network->structinfo.ptr.p_int[offs+0]==0 ) 25312 * Adaptive summator 25314 n1 = network->structinfo.ptr.p_int[offs+2]; 25315 n2 = n1+network->structinfo.ptr.p_int[offs+1]-1; 25316 w1 = network->structinfo.ptr.p_int[offs+3]; 25317 w2 = w1+network->structinfo.ptr.p_int[offs+1]-1; 25318 dedf = network->derror.ptr.p_double[i]; 25321 ae_v_moved(&grad->ptr.p_double[w1], 1, &neurons->ptr.p_double[n1], 1, ae_v_len(w1,w2), v); 25322 ae_v_addd(&derror->ptr.p_double[n1], 1, &weights->ptr.p_double[w1], 1, ae_v_len(n1,n2), v); 25325 if( network->structinfo.ptr.p_int[offs+0]<0 ) 25328 if( (network->structinfo.ptr.p_int[offs+0]==-2||network->structinfo.ptr.p_int[offs+0]==-3)||network->structinfo.ptr.p_int[offs+0]==-4 ) 25332 * Special neuron type, no back-propagation required 25336 ae_assert(bflag, "MLPInternalCalculateGradient: unknown neuron
type!
", _state); 25343 static void mlpbase_mlpchunkedgradient(multilayerperceptron* network, 25344 /* Real */ ae_matrix* xy, 25347 /* Real */ ae_vector* batch4buf, 25348 /* Real */ ae_vector* hpcbuf, 25350 ae_bool naturalerrorfunc, 25371 ae_int_t entrysize; 25373 ae_int_t derroroffs; 25374 ae_int_t entryoffs; 25375 ae_int_t neuronidx; 25376 ae_int_t srcentryoffs; 25377 ae_int_t srcneuronidx; 25378 ae_int_t srcweightidx; 25379 ae_int_t neurontype; 25392 ae_int_t chunksize; 25396 ae_assert(csize<=chunksize, "MLPChunkedGradient:
internal error (CSize>ChunkSize)
", _state); 25399 * Try to use HPC core, if possible 25401 if( hpcchunkedgradient(&network->weights, &network->structinfo, &network->columnmeans, &network->columnsigmas, xy, cstart, csize, batch4buf, hpcbuf, e, naturalerrorfunc, _state) ) 25407 * Read network geometry, prepare data 25409 nin = network->structinfo.ptr.p_int[1]; 25410 nout = network->structinfo.ptr.p_int[2]; 25411 ntotal = network->structinfo.ptr.p_int[3]; 25412 istart = network->structinfo.ptr.p_int[5]; 25418 * Fill Batch4Buf by zeros. 25420 * THIS STAGE IS VERY IMPORTANT! 25422 * We fill all components of entry - neuron values, dF/dNET, dError/dF. 25423 * It allows us to easily handle situations when CSize<ChunkSize by 25424 * simply working with ALL components of Batch4Buf, without ever 25425 * looking at CSize. The idea is that dError/dF for absent components 25426 * will be initialized by zeros - and won't be rewritten by non-zero 25427 * values during backpropagation. 25429 for(i=0; i<=entrysize*ntotal-1; i++) 25431 batch4buf->ptr.p_double[i] = 0; 25436 * 1. Load data into Batch4Buf. If CSize<ChunkSize, data are padded by zeros. 25437 * 2. Perform forward pass through network 25439 for(i=0; i<=nin-1; i++) 25441 entryoffs = entrysize*i; 25442 for(j=0; j<=csize-1; j++) 25444 if( ae_fp_neq(network->columnsigmas.ptr.p_double[i],0) ) 25446 batch4buf->ptr.p_double[entryoffs+j] = (xy->ptr.pp_double[cstart+j][i]-network->columnmeans.ptr.p_double[i])/network->columnsigmas.ptr.p_double[i]; 25450 batch4buf->ptr.p_double[entryoffs+j] = xy->ptr.pp_double[cstart+j][i]-network->columnmeans.ptr.p_double[i]; 25454 for(neuronidx=0; neuronidx<=ntotal-1; neuronidx++) 25456 entryoffs = entrysize*neuronidx; 25457 offs = istart+neuronidx*mlpbase_nfieldwidth; 25458 neurontype = network->structinfo.ptr.p_int[offs+0]; 25459 if( neurontype>0||neurontype==-5 ) 25463 * "activation
function" neuron, which takes value of neuron SrcNeuronIdx 25464 * and applies activation function to it. 25466 * This neuron has no weights and no tunable parameters. 25468 srcneuronidx = network->structinfo.ptr.p_int[offs+2]; 25469 srcentryoffs = entrysize*srcneuronidx; 25470 mlpactivationfunction(batch4buf->ptr.p_double[srcentryoffs+0], neurontype, &f, &df, &d2f, _state); 25471 batch4buf->ptr.p_double[entryoffs+0] = f; 25472 batch4buf->ptr.p_double[entryoffs+0+dfoffs] = df; 25473 mlpactivationfunction(batch4buf->ptr.p_double[srcentryoffs+1], neurontype, &f, &df, &d2f, _state); 25474 batch4buf->ptr.p_double[entryoffs+1] = f; 25475 batch4buf->ptr.p_double[entryoffs+1+dfoffs] = df; 25476 mlpactivationfunction(batch4buf->ptr.p_double[srcentryoffs+2], neurontype, &f, &df, &d2f, _state); 25477 batch4buf->ptr.p_double[entryoffs+2] = f; 25478 batch4buf->ptr.p_double[entryoffs+2+dfoffs] = df; 25479 mlpactivationfunction(batch4buf->ptr.p_double[srcentryoffs+3], neurontype, &f, &df, &d2f, _state); 25480 batch4buf->ptr.p_double[entryoffs+3] = f; 25481 batch4buf->ptr.p_double[entryoffs+3+dfoffs] = df; 25484 if( neurontype==0 ) 25488 * "adaptive summator
" neuron, whose output is a weighted sum of inputs. 25489 * It has weights, but has no activation function. 25491 nweights = network->structinfo.ptr.p_int[offs+1]; 25492 srcneuronidx = network->structinfo.ptr.p_int[offs+2]; 25493 srcentryoffs = entrysize*srcneuronidx; 25494 srcweightidx = network->structinfo.ptr.p_int[offs+3]; 25499 for(j=0; j<=nweights-1; j++) 25501 v = network->weights.ptr.p_double[srcweightidx]; 25502 srcweightidx = srcweightidx+1; 25503 v0 = v0+v*batch4buf->ptr.p_double[srcentryoffs+0]; 25504 v1 = v1+v*batch4buf->ptr.p_double[srcentryoffs+1]; 25505 v2 = v2+v*batch4buf->ptr.p_double[srcentryoffs+2]; 25506 v3 = v3+v*batch4buf->ptr.p_double[srcentryoffs+3]; 25507 srcentryoffs = srcentryoffs+entrysize; 25509 batch4buf->ptr.p_double[entryoffs+0] = v0; 25510 batch4buf->ptr.p_double[entryoffs+1] = v1; 25511 batch4buf->ptr.p_double[entryoffs+2] = v2; 25512 batch4buf->ptr.p_double[entryoffs+3] = v3; 25513 batch4buf->ptr.p_double[entryoffs+0+dfoffs] = 1; 25514 batch4buf->ptr.p_double[entryoffs+1+dfoffs] = 1; 25515 batch4buf->ptr.p_double[entryoffs+2+dfoffs] = 1; 25516 batch4buf->ptr.p_double[entryoffs+3+dfoffs] = 1; 25522 if( neurontype==-2 ) 25526 * Input neuron, left unchanged 25530 if( neurontype==-3 ) 25536 batch4buf->ptr.p_double[entryoffs+0] = -1; 25537 batch4buf->ptr.p_double[entryoffs+1] = -1; 25538 batch4buf->ptr.p_double[entryoffs+2] = -1; 25539 batch4buf->ptr.p_double[entryoffs+3] = -1; 25540 batch4buf->ptr.p_double[entryoffs+0+dfoffs] = 0; 25541 batch4buf->ptr.p_double[entryoffs+1+dfoffs] = 0; 25542 batch4buf->ptr.p_double[entryoffs+2+dfoffs] = 0; 25543 batch4buf->ptr.p_double[entryoffs+3+dfoffs] = 0; 25546 if( neurontype==-4 ) 25552 batch4buf->ptr.p_double[entryoffs+0] = 0; 25553 batch4buf->ptr.p_double[entryoffs+1] = 0; 25554 batch4buf->ptr.p_double[entryoffs+2] = 0; 25555 batch4buf->ptr.p_double[entryoffs+3] = 0; 25556 batch4buf->ptr.p_double[entryoffs+0+dfoffs] = 0; 25557 batch4buf->ptr.p_double[entryoffs+1+dfoffs] = 0; 25558 batch4buf->ptr.p_double[entryoffs+2+dfoffs] = 0; 25559 batch4buf->ptr.p_double[entryoffs+3+dfoffs] = 0; 25562 ae_assert(bflag, "MLPChunkedGradient:
internal error - unknown neuron
type!
", _state); 25568 * Intermediate phase between forward and backward passes. 25570 * For regression networks: 25571 * * forward pass is completely done (no additional post-processing is 25573 * * before starting backward pass, we have to calculate dError/dOut 25574 * for output neurons. We also update error at this phase. 25576 * For classification networks: 25577 * * in addition to forward pass we apply SOFTMAX normalization to 25579 * * after applying normalization, we have to calculate dError/dOut, 25580 * which is calculated in two steps: 25581 * * first, we calculate derivative of error with respect to SOFTMAX 25582 * normalized outputs (normalized dError) 25583 * * then, we calculate derivative of error with respect to values 25584 * of outputs BEFORE normalization was applied to them 25586 ae_assert(network->structinfo.ptr.p_int[6]==0||network->structinfo.ptr.p_int[6]==1, "MLPChunkedGradient: unknown normalization
type!
", _state); 25587 if( network->structinfo.ptr.p_int[6]==1 ) 25591 * SOFTMAX-normalized network. 25593 * First, calculate (V0,V1,V2,V3) - component-wise maximum 25594 * of output neurons. This vector of maximum values will be 25595 * used for normalization of outputs prior to calculating 25598 * NOTE: the only purpose of this stage is to prevent overflow 25599 * during calculation of exponentials. With this stage 25600 * we make sure that all exponentials are calculated 25601 * with non-positive argument. If you load (0,0,0,0) to 25602 * (V0,V1,V2,V3), your program will continue working - 25603 * although with less robustness. 25605 entryoffs = entrysize*(ntotal-nout); 25606 v0 = batch4buf->ptr.p_double[entryoffs+0]; 25607 v1 = batch4buf->ptr.p_double[entryoffs+1]; 25608 v2 = batch4buf->ptr.p_double[entryoffs+2]; 25609 v3 = batch4buf->ptr.p_double[entryoffs+3]; 25610 entryoffs = entryoffs+entrysize; 25611 for(i=1; i<=nout-1; i++) 25613 v = batch4buf->ptr.p_double[entryoffs+0]; 25618 v = batch4buf->ptr.p_double[entryoffs+1]; 25623 v = batch4buf->ptr.p_double[entryoffs+2]; 25628 v = batch4buf->ptr.p_double[entryoffs+3]; 25633 entryoffs = entryoffs+entrysize; 25637 * Then, calculate exponentials and place them to part of the 25638 * array which is located past the last entry. We also 25639 * calculate sum of exponentials which will be stored past the 25642 entryoffs = entrysize*(ntotal-nout); 25643 offs0 = entrysize*ntotal; 25648 for(i=0; i<=nout-1; i++) 25650 v = ae_exp(batch4buf->ptr.p_double[entryoffs+0]-v0, _state); 25652 batch4buf->ptr.p_double[offs0+0] = v; 25653 v = ae_exp(batch4buf->ptr.p_double[entryoffs+1]-v1, _state); 25655 batch4buf->ptr.p_double[offs0+1] = v; 25656 v = ae_exp(batch4buf->ptr.p_double[entryoffs+2]-v2, _state); 25658 batch4buf->ptr.p_double[offs0+2] = v; 25659 v = ae_exp(batch4buf->ptr.p_double[entryoffs+3]-v3, _state); 25661 batch4buf->ptr.p_double[offs0+3] = v; 25662 entryoffs = entryoffs+entrysize; 25663 offs0 = offs0+chunksize; 25665 offs0 = entrysize*ntotal+2*nout*chunksize; 25666 batch4buf->ptr.p_double[offs0+0] = s0; 25667 batch4buf->ptr.p_double[offs0+1] = s1; 25668 batch4buf->ptr.p_double[offs0+2] = s2; 25669 batch4buf->ptr.p_double[offs0+3] = s3; 25673 * * Batch4Buf[0...EntrySize*NTotal-1] stores: 25674 * * NTotal*ChunkSize neuron output values (SOFTMAX normalization 25675 * was not applied to these values), 25676 * * NTotal*ChunkSize values of dF/dNET (derivative of neuron 25677 * output with respect to its input) 25678 * * NTotal*ChunkSize zeros in the elements which correspond to 25679 * dError/dOut (derivative of error with respect to neuron output). 25680 * * Batch4Buf[EntrySize*NTotal...EntrySize*NTotal+ChunkSize*NOut-1] - 25681 * stores exponentials of last NOut neurons. 25682 * * Batch4Buf[EntrySize*NTotal+ChunkSize*NOut-1...EntrySize*NTotal+ChunkSize*2*NOut-1] 25683 * - can be used for temporary calculations 25684 * * Batch4Buf[EntrySize*NTotal+ChunkSize*2*NOut...EntrySize*NTotal+ChunkSize*2*NOut+ChunkSize-1] 25685 * - stores sum-of-exponentials 25687 * Block below calculates derivatives of error function with respect 25688 * to non-SOFTMAX-normalized output values of last NOut neurons. 25690 * It is quite complicated; we do not describe algebra behind it, 25691 * but if you want you may check it yourself :) 25693 if( naturalerrorfunc ) 25697 * Calculate derivative of error with respect to values of 25698 * output neurons PRIOR TO SOFTMAX NORMALIZATION. Because we 25699 * use natural error function (cross-entropy), we can do so 25702 offs0 = entrysize*ntotal+2*nout*chunksize; 25703 for(k=0; k<=csize-1; k++) 25705 s = batch4buf->ptr.p_double[offs0+k]; 25706 kl = ae_round(xy->ptr.pp_double[cstart+k][nin], _state); 25707 offs1 = (ntotal-nout)*entrysize+derroroffs+k; 25708 offs2 = entrysize*ntotal+k; 25709 for(i=0; i<=nout-1; i++) 25719 vv = batch4buf->ptr.p_double[offs2]; 25720 batch4buf->ptr.p_double[offs1] = vv/s-v; 25721 *e = *e+mlpbase_safecrossentropy(v, vv/s, _state); 25722 offs1 = offs1+entrysize; 25723 offs2 = offs2+chunksize; 25731 * SOFTMAX normalization makes things very difficult. 25732 * Sorry, we do not dare to describe this esoteric math 25735 offs0 = entrysize*ntotal+chunksize*2*nout; 25736 for(k=0; k<=csize-1; k++) 25738 s = batch4buf->ptr.p_double[offs0+k]; 25739 kl = ae_round(xy->ptr.pp_double[cstart+k][nin], _state); 25741 offs1 = entrysize*ntotal+k; 25742 offs2 = entrysize*ntotal+nout*chunksize+k; 25743 for(i=0; i<=nout-1; i++) 25745 fown = batch4buf->ptr.p_double[offs1]; 25754 batch4buf->ptr.p_double[offs2] = deown; 25755 vv = vv+deown*fown; 25756 *e = *e+deown*deown/2; 25757 offs1 = offs1+chunksize; 25758 offs2 = offs2+chunksize; 25760 offs1 = entrysize*ntotal+k; 25761 offs2 = entrysize*ntotal+nout*chunksize+k; 25762 for(i=0; i<=nout-1; i++) 25764 fown = batch4buf->ptr.p_double[offs1]; 25765 deown = batch4buf->ptr.p_double[offs2]; 25766 batch4buf->ptr.p_double[(ntotal-nout+i)*entrysize+derroroffs+k] = (-vv+deown*fown+deown*(s-fown))*fown/ae_sqr(s, _state); 25767 offs1 = offs1+chunksize; 25768 offs2 = offs2+chunksize; 25777 * Regression network with sum-of-squares function. 25779 * For each NOut of last neurons: 25780 * * calculate difference between actual and desired output 25781 * * calculate dError/dOut for this neuron (proportional to difference) 25782 * * store in in last 4 components of entry (these values are used 25783 * to start backpropagation) 25786 for(i=0; i<=nout-1; i++) 25788 v0 = network->columnsigmas.ptr.p_double[nin+i]; 25789 v1 = network->columnmeans.ptr.p_double[nin+i]; 25790 entryoffs = entrysize*(ntotal-nout+i); 25792 offs1 = entryoffs+derroroffs; 25793 for(j=0; j<=csize-1; j++) 25795 v = batch4buf->ptr.p_double[offs0+j]*v0+v1-xy->ptr.pp_double[cstart+j][nin+i]; 25796 batch4buf->ptr.p_double[offs1+j] = v*v0; 25805 for(neuronidx=ntotal-1; neuronidx>=0; neuronidx--) 25807 entryoffs = entrysize*neuronidx; 25808 offs = istart+neuronidx*mlpbase_nfieldwidth; 25809 neurontype = network->structinfo.ptr.p_int[offs+0]; 25810 if( neurontype>0||neurontype==-5 ) 25814 * Activation function 25816 srcneuronidx = network->structinfo.ptr.p_int[offs+2]; 25817 srcentryoffs = entrysize*srcneuronidx; 25818 offs0 = srcentryoffs+derroroffs; 25819 offs1 = entryoffs+derroroffs; 25820 offs2 = entryoffs+dfoffs; 25821 batch4buf->ptr.p_double[offs0+0] = batch4buf->ptr.p_double[offs0+0]+batch4buf->ptr.p_double[offs1+0]*batch4buf->ptr.p_double[offs2+0]; 25822 batch4buf->ptr.p_double[offs0+1] = batch4buf->ptr.p_double[offs0+1]+batch4buf->ptr.p_double[offs1+1]*batch4buf->ptr.p_double[offs2+1]; 25823 batch4buf->ptr.p_double[offs0+2] = batch4buf->ptr.p_double[offs0+2]+batch4buf->ptr.p_double[offs1+2]*batch4buf->ptr.p_double[offs2+2]; 25824 batch4buf->ptr.p_double[offs0+3] = batch4buf->ptr.p_double[offs0+3]+batch4buf->ptr.p_double[offs1+3]*batch4buf->ptr.p_double[offs2+3]; 25827 if( neurontype==0 ) 25831 * Adaptive summator 25833 nweights = network->structinfo.ptr.p_int[offs+1]; 25834 srcneuronidx = network->structinfo.ptr.p_int[offs+2]; 25835 srcentryoffs = entrysize*srcneuronidx; 25836 srcweightidx = network->structinfo.ptr.p_int[offs+3]; 25837 v0 = batch4buf->ptr.p_double[entryoffs+derroroffs+0]; 25838 v1 = batch4buf->ptr.p_double[entryoffs+derroroffs+1]; 25839 v2 = batch4buf->ptr.p_double[entryoffs+derroroffs+2]; 25840 v3 = batch4buf->ptr.p_double[entryoffs+derroroffs+3]; 25841 for(j=0; j<=nweights-1; j++) 25843 offs0 = srcentryoffs; 25844 offs1 = srcentryoffs+derroroffs; 25845 v = network->weights.ptr.p_double[srcweightidx]; 25846 hpcbuf->ptr.p_double[srcweightidx] = hpcbuf->ptr.p_double[srcweightidx]+batch4buf->ptr.p_double[offs0+0]*v0+batch4buf->ptr.p_double[offs0+1]*v1+batch4buf->ptr.p_double[offs0+2]*v2+batch4buf->ptr.p_double[offs0+3]*v3; 25847 batch4buf->ptr.p_double[offs1+0] = batch4buf->ptr.p_double[offs1+0]+v*v0; 25848 batch4buf->ptr.p_double[offs1+1] = batch4buf->ptr.p_double[offs1+1]+v*v1; 25849 batch4buf->ptr.p_double[offs1+2] = batch4buf->ptr.p_double[offs1+2]+v*v2; 25850 batch4buf->ptr.p_double[offs1+3] = batch4buf->ptr.p_double[offs1+3]+v*v3; 25851 srcentryoffs = srcentryoffs+entrysize; 25852 srcweightidx = srcweightidx+1; 25859 if( (neurontype==-2||neurontype==-3)||neurontype==-4 ) 25863 * Special neuron type, no back-propagation required 25867 ae_assert(bflag, "MLPInternalCalculateGradient: unknown neuron
type!
", _state); 25874 static void mlpbase_mlpchunkedprocess(multilayerperceptron* network, 25875 /* Real */ ae_matrix* xy, 25878 /* Real */ ae_vector* batch4buf, 25879 /* Real */ ae_vector* hpcbuf, 25894 ae_int_t entrysize; 25895 ae_int_t entryoffs; 25896 ae_int_t neuronidx; 25897 ae_int_t srcentryoffs; 25898 ae_int_t srcneuronidx; 25899 ae_int_t srcweightidx; 25900 ae_int_t neurontype; 25911 ae_int_t chunksize; 25915 ae_assert(csize<=chunksize, "MLPChunkedProcess:
internal error (CSize>ChunkSize)
", _state); 25918 * Try to use HPC core, if possible 25920 if( hpcchunkedprocess(&network->weights, &network->structinfo, &network->columnmeans, &network->columnsigmas, xy, cstart, csize, batch4buf, hpcbuf, _state) ) 25926 * Read network geometry, prepare data 25928 nin = network->structinfo.ptr.p_int[1]; 25929 nout = network->structinfo.ptr.p_int[2]; 25930 ntotal = network->structinfo.ptr.p_int[3]; 25931 istart = network->structinfo.ptr.p_int[5]; 25935 * Fill Batch4Buf by zeros. 25937 * THIS STAGE IS VERY IMPORTANT! 25939 * We fill all components of entry - neuron values, dF/dNET, dError/dF. 25940 * It allows us to easily handle situations when CSize<ChunkSize by 25941 * simply working with ALL components of Batch4Buf, without ever 25942 * looking at CSize. 25944 for(i=0; i<=entrysize*ntotal-1; i++) 25946 batch4buf->ptr.p_double[i] = 0; 25951 * 1. Load data into Batch4Buf. If CSize<ChunkSize, data are padded by zeros. 25952 * 2. Perform forward pass through network 25954 for(i=0; i<=nin-1; i++) 25956 entryoffs = entrysize*i; 25957 for(j=0; j<=csize-1; j++) 25959 if( ae_fp_neq(network->columnsigmas.ptr.p_double[i],0) ) 25961 batch4buf->ptr.p_double[entryoffs+j] = (xy->ptr.pp_double[cstart+j][i]-network->columnmeans.ptr.p_double[i])/network->columnsigmas.ptr.p_double[i]; 25965 batch4buf->ptr.p_double[entryoffs+j] = xy->ptr.pp_double[cstart+j][i]-network->columnmeans.ptr.p_double[i]; 25969 for(neuronidx=0; neuronidx<=ntotal-1; neuronidx++) 25971 entryoffs = entrysize*neuronidx; 25972 offs = istart+neuronidx*mlpbase_nfieldwidth; 25973 neurontype = network->structinfo.ptr.p_int[offs+0]; 25974 if( neurontype>0||neurontype==-5 ) 25978 * "activation
function" neuron, which takes value of neuron SrcNeuronIdx 25979 * and applies activation function to it. 25981 * This neuron has no weights and no tunable parameters. 25983 srcneuronidx = network->structinfo.ptr.p_int[offs+2]; 25984 srcentryoffs = entrysize*srcneuronidx; 25985 mlpactivationfunction(batch4buf->ptr.p_double[srcentryoffs+0], neurontype, &f, &df, &d2f, _state); 25986 batch4buf->ptr.p_double[entryoffs+0] = f; 25987 mlpactivationfunction(batch4buf->ptr.p_double[srcentryoffs+1], neurontype, &f, &df, &d2f, _state); 25988 batch4buf->ptr.p_double[entryoffs+1] = f; 25989 mlpactivationfunction(batch4buf->ptr.p_double[srcentryoffs+2], neurontype, &f, &df, &d2f, _state); 25990 batch4buf->ptr.p_double[entryoffs+2] = f; 25991 mlpactivationfunction(batch4buf->ptr.p_double[srcentryoffs+3], neurontype, &f, &df, &d2f, _state); 25992 batch4buf->ptr.p_double[entryoffs+3] = f; 25995 if( neurontype==0 ) 25999 * "adaptive summator
" neuron, whose output is a weighted sum of inputs. 26000 * It has weights, but has no activation function. 26002 nweights = network->structinfo.ptr.p_int[offs+1]; 26003 srcneuronidx = network->structinfo.ptr.p_int[offs+2]; 26004 srcentryoffs = entrysize*srcneuronidx; 26005 srcweightidx = network->structinfo.ptr.p_int[offs+3]; 26010 for(j=0; j<=nweights-1; j++) 26012 v = network->weights.ptr.p_double[srcweightidx]; 26013 srcweightidx = srcweightidx+1; 26014 v0 = v0+v*batch4buf->ptr.p_double[srcentryoffs+0]; 26015 v1 = v1+v*batch4buf->ptr.p_double[srcentryoffs+1]; 26016 v2 = v2+v*batch4buf->ptr.p_double[srcentryoffs+2]; 26017 v3 = v3+v*batch4buf->ptr.p_double[srcentryoffs+3]; 26018 srcentryoffs = srcentryoffs+entrysize; 26020 batch4buf->ptr.p_double[entryoffs+0] = v0; 26021 batch4buf->ptr.p_double[entryoffs+1] = v1; 26022 batch4buf->ptr.p_double[entryoffs+2] = v2; 26023 batch4buf->ptr.p_double[entryoffs+3] = v3; 26029 if( neurontype==-2 ) 26033 * Input neuron, left unchanged 26037 if( neurontype==-3 ) 26043 batch4buf->ptr.p_double[entryoffs+0] = -1; 26044 batch4buf->ptr.p_double[entryoffs+1] = -1; 26045 batch4buf->ptr.p_double[entryoffs+2] = -1; 26046 batch4buf->ptr.p_double[entryoffs+3] = -1; 26049 if( neurontype==-4 ) 26055 batch4buf->ptr.p_double[entryoffs+0] = 0; 26056 batch4buf->ptr.p_double[entryoffs+1] = 0; 26057 batch4buf->ptr.p_double[entryoffs+2] = 0; 26058 batch4buf->ptr.p_double[entryoffs+3] = 0; 26061 ae_assert(bflag, "MLPChunkedProcess:
internal error - unknown neuron
type!
", _state); 26067 * SOFTMAX normalization or scaling. 26069 ae_assert(network->structinfo.ptr.p_int[6]==0||network->structinfo.ptr.p_int[6]==1, "MLPChunkedProcess: unknown normalization
type!
", _state); 26070 if( network->structinfo.ptr.p_int[6]==1 ) 26074 * SOFTMAX-normalized network. 26076 * First, calculate (V0,V1,V2,V3) - component-wise maximum 26077 * of output neurons. This vector of maximum values will be 26078 * used for normalization of outputs prior to calculating 26081 * NOTE: the only purpose of this stage is to prevent overflow 26082 * during calculation of exponentials. With this stage 26083 * we make sure that all exponentials are calculated 26084 * with non-positive argument. If you load (0,0,0,0) to 26085 * (V0,V1,V2,V3), your program will continue working - 26086 * although with less robustness. 26088 entryoffs = entrysize*(ntotal-nout); 26089 v0 = batch4buf->ptr.p_double[entryoffs+0]; 26090 v1 = batch4buf->ptr.p_double[entryoffs+1]; 26091 v2 = batch4buf->ptr.p_double[entryoffs+2]; 26092 v3 = batch4buf->ptr.p_double[entryoffs+3]; 26093 entryoffs = entryoffs+entrysize; 26094 for(i=1; i<=nout-1; i++) 26096 v = batch4buf->ptr.p_double[entryoffs+0]; 26101 v = batch4buf->ptr.p_double[entryoffs+1]; 26106 v = batch4buf->ptr.p_double[entryoffs+2]; 26111 v = batch4buf->ptr.p_double[entryoffs+3]; 26116 entryoffs = entryoffs+entrysize; 26120 * Then, calculate exponentials and place them to part of the 26121 * array which is located past the last entry. We also 26122 * calculate sum of exponentials. 26124 entryoffs = entrysize*(ntotal-nout); 26125 offs0 = entrysize*ntotal; 26130 for(i=0; i<=nout-1; i++) 26132 v = ae_exp(batch4buf->ptr.p_double[entryoffs+0]-v0, _state); 26134 batch4buf->ptr.p_double[offs0+0] = v; 26135 v = ae_exp(batch4buf->ptr.p_double[entryoffs+1]-v1, _state); 26137 batch4buf->ptr.p_double[offs0+1] = v; 26138 v = ae_exp(batch4buf->ptr.p_double[entryoffs+2]-v2, _state); 26140 batch4buf->ptr.p_double[offs0+2] = v; 26141 v = ae_exp(batch4buf->ptr.p_double[entryoffs+3]-v3, _state); 26143 batch4buf->ptr.p_double[offs0+3] = v; 26144 entryoffs = entryoffs+entrysize; 26145 offs0 = offs0+chunksize; 26149 * Write SOFTMAX-normalized values to the output array. 26151 offs0 = entrysize*ntotal; 26152 for(i=0; i<=nout-1; i++) 26156 xy->ptr.pp_double[cstart+0][nin+i] = batch4buf->ptr.p_double[offs0+0]/s0; 26160 xy->ptr.pp_double[cstart+1][nin+i] = batch4buf->ptr.p_double[offs0+1]/s1; 26164 xy->ptr.pp_double[cstart+2][nin+i] = batch4buf->ptr.p_double[offs0+2]/s2; 26168 xy->ptr.pp_double[cstart+3][nin+i] = batch4buf->ptr.p_double[offs0+3]/s3; 26170 offs0 = offs0+chunksize; 26177 * Regression network with sum-of-squares function. 26179 * For each NOut of last neurons: 26180 * * calculate difference between actual and desired output 26181 * * calculate dError/dOut for this neuron (proportional to difference) 26182 * * store in in last 4 components of entry (these values are used 26183 * to start backpropagation) 26186 for(i=0; i<=nout-1; i++) 26188 v0 = network->columnsigmas.ptr.p_double[nin+i]; 26189 v1 = network->columnmeans.ptr.p_double[nin+i]; 26190 entryoffs = entrysize*(ntotal-nout+i); 26191 for(j=0; j<=csize-1; j++) 26193 xy->ptr.pp_double[cstart+j][nin+i] = batch4buf->ptr.p_double[entryoffs+j]*v0+v1; 26200 /************************************************************************* 26201 Returns T*Ln(T/Z), guarded against overflow/underflow. 26202 Internal subroutine. 26203 *************************************************************************/ 26204 static double mlpbase_safecrossentropy(double t, 26212 if( ae_fp_eq(t,0) ) 26218 if( ae_fp_greater(ae_fabs(z, _state),1) ) 26222 * Shouldn't be the case with softmax, 26223 * but we just want to be sure. 26225 if( ae_fp_eq(t/z,0) ) 26227 r = ae_minrealnumber; 26240 if( ae_fp_eq(z,0)||ae_fp_greater_eq(ae_fabs(t, _state),ae_maxrealnumber*ae_fabs(z, _state)) ) 26242 r = ae_maxrealnumber; 26249 result = t*ae_log(r, _state); 26255 /************************************************************************* 26256 This function performs backward pass of neural network randimization: 26257 * it assumes that Network.Weights stores standard deviation of weights 26258 (weights are not generated yet, only their deviations are present) 26259 * it sets deviations of weights which feed NeuronIdx-th neuron to specified value 26260 * it recursively passes to deeper neuron and modifies their weights 26261 * it stops after encountering nonlinear neurons, linear activation function, 26262 input neurons, "0
" and "-1
" neurons 26265 Copyright 27.06.2013 by Bochkanov Sergey 26266 *************************************************************************/ 26267 static void mlpbase_randomizebackwardpass(multilayerperceptron* network, 26268 ae_int_t neuronidx, 26273 ae_int_t neurontype; 26282 istart = network->structinfo.ptr.p_int[5]; 26283 neurontype = network->structinfo.ptr.p_int[istart+neuronidx*mlpbase_nfieldwidth+0]; 26284 if( neurontype==-2 ) 26288 * Input neuron - stop 26292 if( neurontype==-3 ) 26296 * "-1
" neuron: stop 26300 if( neurontype==-4 ) 26308 if( neurontype==0 ) 26312 * Adaptive summator neuron: 26313 * * modify deviations of its weights 26314 * * recursively call this function for its inputs 26316 offs = istart+neuronidx*mlpbase_nfieldwidth; 26317 n1 = network->structinfo.ptr.p_int[offs+2]; 26318 n2 = n1+network->structinfo.ptr.p_int[offs+1]-1; 26319 w1 = network->structinfo.ptr.p_int[offs+3]; 26320 w2 = w1+network->structinfo.ptr.p_int[offs+1]-1; 26321 for(i=w1; i<=w2; i++) 26323 network->weights.ptr.p_double[i] = v; 26325 for(i=n1; i<=n2; i++) 26327 mlpbase_randomizebackwardpass(network, i, v, _state); 26331 if( neurontype==-5 ) 26335 * Linear activation function: stop 26343 * Nonlinear activation function: stop 26347 ae_assert(ae_false, "RandomizeBackwardPass: unexpected neuron
type", _state); 26351 ae_bool _modelerrors_init(void* _p, ae_state *_state, ae_bool make_automatic) 26353 modelerrors *p = (modelerrors*)_p; 26354 ae_touch_ptr((void*)p); 26359 ae_bool _modelerrors_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 26361 modelerrors *dst = (modelerrors*)_dst; 26362 modelerrors *src = (modelerrors*)_src; 26363 dst->relclserror = src->relclserror; 26364 dst->avgce = src->avgce; 26365 dst->rmserror = src->rmserror; 26366 dst->avgerror = src->avgerror; 26367 dst->avgrelerror = src->avgrelerror; 26372 void _modelerrors_clear(void* _p) 26374 modelerrors *p = (modelerrors*)_p; 26375 ae_touch_ptr((void*)p); 26379 void _modelerrors_destroy(void* _p) 26381 modelerrors *p = (modelerrors*)_p; 26382 ae_touch_ptr((void*)p); 26386 ae_bool _smlpgrad_init(void* _p, ae_state *_state, ae_bool make_automatic) 26388 smlpgrad *p = (smlpgrad*)_p; 26389 ae_touch_ptr((void*)p); 26390 if( !ae_vector_init(&p->g, 0, DT_REAL, _state, make_automatic) ) 26396 ae_bool _smlpgrad_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 26398 smlpgrad *dst = (smlpgrad*)_dst; 26399 smlpgrad *src = (smlpgrad*)_src; 26401 if( !ae_vector_init_copy(&dst->g, &src->g, _state, make_automatic) ) 26407 void _smlpgrad_clear(void* _p) 26409 smlpgrad *p = (smlpgrad*)_p; 26410 ae_touch_ptr((void*)p); 26411 ae_vector_clear(&p->g); 26415 void _smlpgrad_destroy(void* _p) 26417 smlpgrad *p = (smlpgrad*)_p; 26418 ae_touch_ptr((void*)p); 26419 ae_vector_destroy(&p->g); 26423 ae_bool _multilayerperceptron_init(void* _p, ae_state *_state, ae_bool make_automatic) 26425 multilayerperceptron *p = (multilayerperceptron*)_p; 26426 ae_touch_ptr((void*)p); 26427 if( !ae_vector_init(&p->hllayersizes, 0, DT_INT, _state, make_automatic) ) 26429 if( !ae_vector_init(&p->hlconnections, 0, DT_INT, _state, make_automatic) ) 26431 if( !ae_vector_init(&p->hlneurons, 0, DT_INT, _state, make_automatic) ) 26433 if( !ae_vector_init(&p->structinfo, 0, DT_INT, _state, make_automatic) ) 26435 if( !ae_vector_init(&p->weights, 0, DT_REAL, _state, make_automatic) ) 26437 if( !ae_vector_init(&p->columnmeans, 0, DT_REAL, _state, make_automatic) ) 26439 if( !ae_vector_init(&p->columnsigmas, 0, DT_REAL, _state, make_automatic) ) 26441 if( !ae_vector_init(&p->neurons, 0, DT_REAL, _state, make_automatic) ) 26443 if( !ae_vector_init(&p->dfdnet, 0, DT_REAL, _state, make_automatic) ) 26445 if( !ae_vector_init(&p->derror, 0, DT_REAL, _state, make_automatic) ) 26447 if( !ae_vector_init(&p->x, 0, DT_REAL, _state, make_automatic) ) 26449 if( !ae_vector_init(&p->y, 0, DT_REAL, _state, make_automatic) ) 26451 if( !ae_matrix_init(&p->xy, 0, 0, DT_REAL, _state, make_automatic) ) 26453 if( !ae_vector_init(&p->xyrow, 0, DT_REAL, _state, make_automatic) ) 26455 if( !ae_vector_init(&p->nwbuf, 0, DT_REAL, _state, make_automatic) ) 26457 if( !ae_vector_init(&p->integerbuf, 0, DT_INT, _state, make_automatic) ) 26459 if( !_modelerrors_init(&p->err, _state, make_automatic) ) 26461 if( !ae_vector_init(&p->rndbuf, 0, DT_REAL, _state, make_automatic) ) 26463 if( !ae_shared_pool_init(&p->buf, _state, make_automatic) ) 26465 if( !ae_shared_pool_init(&p->gradbuf, _state, make_automatic) ) 26467 if( !ae_matrix_init(&p->dummydxy, 0, 0, DT_REAL, _state, make_automatic) ) 26469 if( !_sparsematrix_init(&p->dummysxy, _state, make_automatic) ) 26471 if( !ae_vector_init(&p->dummyidx, 0, DT_INT, _state, make_automatic) ) 26473 if( !ae_shared_pool_init(&p->dummypool, _state, make_automatic) ) 26479 ae_bool _multilayerperceptron_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 26481 multilayerperceptron *dst = (multilayerperceptron*)_dst; 26482 multilayerperceptron *src = (multilayerperceptron*)_src; 26483 dst->hlnetworktype = src->hlnetworktype; 26484 dst->hlnormtype = src->hlnormtype; 26485 if( !ae_vector_init_copy(&dst->hllayersizes, &src->hllayersizes, _state, make_automatic) ) 26487 if( !ae_vector_init_copy(&dst->hlconnections, &src->hlconnections, _state, make_automatic) ) 26489 if( !ae_vector_init_copy(&dst->hlneurons, &src->hlneurons, _state, make_automatic) ) 26491 if( !ae_vector_init_copy(&dst->structinfo, &src->structinfo, _state, make_automatic) ) 26493 if( !ae_vector_init_copy(&dst->weights, &src->weights, _state, make_automatic) ) 26495 if( !ae_vector_init_copy(&dst->columnmeans, &src->columnmeans, _state, make_automatic) ) 26497 if( !ae_vector_init_copy(&dst->columnsigmas, &src->columnsigmas, _state, make_automatic) ) 26499 if( !ae_vector_init_copy(&dst->neurons, &src->neurons, _state, make_automatic) ) 26501 if( !ae_vector_init_copy(&dst->dfdnet, &src->dfdnet, _state, make_automatic) ) 26503 if( !ae_vector_init_copy(&dst->derror, &src->derror, _state, make_automatic) ) 26505 if( !ae_vector_init_copy(&dst->x, &src->x, _state, make_automatic) ) 26507 if( !ae_vector_init_copy(&dst->y, &src->y, _state, make_automatic) ) 26509 if( !ae_matrix_init_copy(&dst->xy, &src->xy, _state, make_automatic) ) 26511 if( !ae_vector_init_copy(&dst->xyrow, &src->xyrow, _state, make_automatic) ) 26513 if( !ae_vector_init_copy(&dst->nwbuf, &src->nwbuf, _state, make_automatic) ) 26515 if( !ae_vector_init_copy(&dst->integerbuf, &src->integerbuf, _state, make_automatic) ) 26517 if( !_modelerrors_init_copy(&dst->err, &src->err, _state, make_automatic) ) 26519 if( !ae_vector_init_copy(&dst->rndbuf, &src->rndbuf, _state, make_automatic) ) 26521 if( !ae_shared_pool_init_copy(&dst->buf, &src->buf, _state, make_automatic) ) 26523 if( !ae_shared_pool_init_copy(&dst->gradbuf, &src->gradbuf, _state, make_automatic) ) 26525 if( !ae_matrix_init_copy(&dst->dummydxy, &src->dummydxy, _state, make_automatic) ) 26527 if( !_sparsematrix_init_copy(&dst->dummysxy, &src->dummysxy, _state, make_automatic) ) 26529 if( !ae_vector_init_copy(&dst->dummyidx, &src->dummyidx, _state, make_automatic) ) 26531 if( !ae_shared_pool_init_copy(&dst->dummypool, &src->dummypool, _state, make_automatic) ) 26537 void _multilayerperceptron_clear(void* _p) 26539 multilayerperceptron *p = (multilayerperceptron*)_p; 26540 ae_touch_ptr((void*)p); 26541 ae_vector_clear(&p->hllayersizes); 26542 ae_vector_clear(&p->hlconnections); 26543 ae_vector_clear(&p->hlneurons); 26544 ae_vector_clear(&p->structinfo); 26545 ae_vector_clear(&p->weights); 26546 ae_vector_clear(&p->columnmeans); 26547 ae_vector_clear(&p->columnsigmas); 26548 ae_vector_clear(&p->neurons); 26549 ae_vector_clear(&p->dfdnet); 26550 ae_vector_clear(&p->derror); 26551 ae_vector_clear(&p->x); 26552 ae_vector_clear(&p->y); 26553 ae_matrix_clear(&p->xy); 26554 ae_vector_clear(&p->xyrow); 26555 ae_vector_clear(&p->nwbuf); 26556 ae_vector_clear(&p->integerbuf); 26557 _modelerrors_clear(&p->err); 26558 ae_vector_clear(&p->rndbuf); 26559 ae_shared_pool_clear(&p->buf); 26560 ae_shared_pool_clear(&p->gradbuf); 26561 ae_matrix_clear(&p->dummydxy); 26562 _sparsematrix_clear(&p->dummysxy); 26563 ae_vector_clear(&p->dummyidx); 26564 ae_shared_pool_clear(&p->dummypool); 26568 void _multilayerperceptron_destroy(void* _p) 26570 multilayerperceptron *p = (multilayerperceptron*)_p; 26571 ae_touch_ptr((void*)p); 26572 ae_vector_destroy(&p->hllayersizes); 26573 ae_vector_destroy(&p->hlconnections); 26574 ae_vector_destroy(&p->hlneurons); 26575 ae_vector_destroy(&p->structinfo); 26576 ae_vector_destroy(&p->weights); 26577 ae_vector_destroy(&p->columnmeans); 26578 ae_vector_destroy(&p->columnsigmas); 26579 ae_vector_destroy(&p->neurons); 26580 ae_vector_destroy(&p->dfdnet); 26581 ae_vector_destroy(&p->derror); 26582 ae_vector_destroy(&p->x); 26583 ae_vector_destroy(&p->y); 26584 ae_matrix_destroy(&p->xy); 26585 ae_vector_destroy(&p->xyrow); 26586 ae_vector_destroy(&p->nwbuf); 26587 ae_vector_destroy(&p->integerbuf); 26588 _modelerrors_destroy(&p->err); 26589 ae_vector_destroy(&p->rndbuf); 26590 ae_shared_pool_destroy(&p->buf); 26591 ae_shared_pool_destroy(&p->gradbuf); 26592 ae_matrix_destroy(&p->dummydxy); 26593 _sparsematrix_destroy(&p->dummysxy); 26594 ae_vector_destroy(&p->dummyidx); 26595 ae_shared_pool_destroy(&p->dummypool); 26601 /************************************************************************* 26602 This subroutine trains logit model. 26605 XY - training set, array[0..NPoints-1,0..NVars] 26606 First NVars columns store values of independent 26607 variables, next column stores number of class (from 0 26608 to NClasses-1) which dataset element belongs to. Fractional 26609 values are rounded to nearest integer. 26610 NPoints - training set size, NPoints>=1 26611 NVars - number of independent variables, NVars>=1 26612 NClasses - number of classes, NClasses>=2 26615 Info - return code: 26616 * -2, if there is a point with class number 26617 outside of [0..NClasses-1]. 26618 * -1, if incorrect parameters was passed 26619 (NPoints<NVars+2, NVars<1, NClasses<2). 26620 * 1, if task has been solved 26622 Rep - training report 26625 Copyright 10.09.2008 by Bochkanov Sergey 26626 *************************************************************************/ 26627 void mnltrainh(/* Real */ ae_matrix* xy, 26636 ae_frame _frame_block; 26646 multilayerperceptron network; 26661 logitmcstate mcstate; 26664 ae_int_t solverinfo; 26665 densesolverreport solverrep; 26667 ae_frame_make(_state, &_frame_block); 26669 _logitmodel_clear(lm); 26670 _mnlreport_clear(rep); 26671 _multilayerperceptron_init(&network, _state, ae_true); 26672 ae_vector_init(&g, 0, DT_REAL, _state, ae_true); 26673 ae_matrix_init(&h, 0, 0, DT_REAL, _state, ae_true); 26674 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 26675 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 26676 ae_vector_init(&wbase, 0, DT_REAL, _state, ae_true); 26677 ae_vector_init(&wdir, 0, DT_REAL, _state, ae_true); 26678 ae_vector_init(&work, 0, DT_REAL, _state, ae_true); 26679 _logitmcstate_init(&mcstate, _state, ae_true); 26680 _densesolverreport_init(&solverrep, _state, ae_true); 26687 if( (npoints<nvars+2||nvars<1)||nclasses<2 ) 26690 ae_frame_leave(_state); 26693 for(i=0; i<=npoints-1; i++) 26695 if( ae_round(xy->ptr.pp_double[i][nvars], _state)<0||ae_round(xy->ptr.pp_double[i][nvars], _state)>=nclasses ) 26698 ae_frame_leave(_state); 26714 ssize = 5+(nvars+1)*(nclasses-1)+nclasses; 26715 ae_vector_set_length(&lm->w, ssize-1+1, _state); 26716 lm->w.ptr.p_double[0] = ssize; 26717 lm->w.ptr.p_double[1] = logit_logitvnum; 26718 lm->w.ptr.p_double[2] = nvars; 26719 lm->w.ptr.p_double[3] = nclasses; 26720 lm->w.ptr.p_double[4] = offs; 26723 * Degenerate case: all outputs are equal 26726 for(i=1; i<=npoints-1; i++) 26728 if( ae_round(xy->ptr.pp_double[i][nvars], _state)!=ae_round(xy->ptr.pp_double[i-1][nvars], _state) ) 26730 allsame = ae_false; 26735 for(i=0; i<=(nvars+1)*(nclasses-1)-1; i++) 26737 lm->w.ptr.p_double[offs+i] = 0; 26739 v = -2*ae_log(ae_minrealnumber, _state); 26740 k = ae_round(xy->ptr.pp_double[0][nvars], _state); 26741 if( k==nclasses-1 ) 26743 for(i=0; i<=nclasses-2; i++) 26745 lm->w.ptr.p_double[offs+i*(nvars+1)+nvars] = -v; 26750 for(i=0; i<=nclasses-2; i++) 26754 lm->w.ptr.p_double[offs+i*(nvars+1)+nvars] = v; 26758 lm->w.ptr.p_double[offs+i*(nvars+1)+nvars] = 0; 26762 ae_frame_leave(_state); 26768 * Prepare task and network. Allocate space. 26770 mlpcreatec0(nvars, nclasses, &network, _state); 26771 mlpinitpreprocessor(&network, xy, npoints, _state); 26772 mlpproperties(&network, &nin, &nout, &wcount, _state); 26773 for(i=0; i<=wcount-1; i++) 26775 network.weights.ptr.p_double[i] = (2*ae_randomreal(_state)-1)/nvars; 26777 ae_vector_set_length(&g, wcount-1+1, _state); 26778 ae_matrix_set_length(&h, wcount-1+1, wcount-1+1, _state); 26779 ae_vector_set_length(&wbase, wcount-1+1, _state); 26780 ae_vector_set_length(&wdir, wcount-1+1, _state); 26781 ae_vector_set_length(&work, wcount-1+1, _state); 26784 * First stage: optimize in gradient direction. 26786 for(k=0; k<=wcount/3+10; k++) 26790 * Calculate gradient in starting point 26792 mlpgradnbatch(&network, xy, npoints, &e, &g, _state); 26793 v = ae_v_dotproduct(&network.weights.ptr.p_double[0], 1, &network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 26795 ae_v_addd(&g.ptr.p_double[0], 1, &network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 26796 rep->ngrad = rep->ngrad+1; 26799 * Setup optimization scheme 26801 ae_v_moveneg(&wdir.ptr.p_double[0], 1, &g.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 26802 v = ae_v_dotproduct(&wdir.ptr.p_double[0], 1, &wdir.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 26803 wstep = ae_sqrt(v, _state); 26804 v = 1/ae_sqrt(v, _state); 26805 ae_v_muld(&wdir.ptr.p_double[0], 1, ae_v_len(0,wcount-1), v); 26807 logit_mnlmcsrch(wcount, &network.weights, &e, &g, &wdir, &wstep, &mcinfo, &mcnfev, &work, &mcstate, &mcstage, _state); 26810 mlpgradnbatch(&network, xy, npoints, &e, &g, _state); 26811 v = ae_v_dotproduct(&network.weights.ptr.p_double[0], 1, &network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 26813 ae_v_addd(&g.ptr.p_double[0], 1, &network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 26814 rep->ngrad = rep->ngrad+1; 26815 logit_mnlmcsrch(wcount, &network.weights, &e, &g, &wdir, &wstep, &mcinfo, &mcnfev, &work, &mcstate, &mcstage, _state); 26820 * Second stage: use Hessian when we are close to the minimum 26826 * Calculate and update E/G/H 26828 mlphessiannbatch(&network, xy, npoints, &e, &g, &h, _state); 26829 v = ae_v_dotproduct(&network.weights.ptr.p_double[0], 1, &network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 26831 ae_v_addd(&g.ptr.p_double[0], 1, &network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 26832 for(k=0; k<=wcount-1; k++) 26834 h.ptr.pp_double[k][k] = h.ptr.pp_double[k][k]+decay; 26836 rep->nhess = rep->nhess+1; 26839 * Select step direction 26840 * NOTE: it is important to use lower-triangle Cholesky 26841 * factorization since it is much faster than higher-triangle version. 26843 spd = spdmatrixcholesky(&h, wcount, ae_false, _state); 26844 spdmatrixcholeskysolve(&h, wcount, ae_false, &g, &solverinfo, &solverrep, &wdir, _state); 26845 spd = solverinfo>0; 26850 * H is positive definite. 26851 * Step in Newton direction. 26853 ae_v_muld(&wdir.ptr.p_double[0], 1, ae_v_len(0,wcount-1), -1); 26861 * Step in gradient direction. 26863 ae_v_moveneg(&wdir.ptr.p_double[0], 1, &g.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 26868 * Optimize in WDir direction 26870 v = ae_v_dotproduct(&wdir.ptr.p_double[0], 1, &wdir.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 26871 wstep = ae_sqrt(v, _state); 26872 v = 1/ae_sqrt(v, _state); 26873 ae_v_muld(&wdir.ptr.p_double[0], 1, ae_v_len(0,wcount-1), v); 26875 logit_mnlmcsrch(wcount, &network.weights, &e, &g, &wdir, &wstep, &mcinfo, &mcnfev, &work, &mcstate, &mcstage, _state); 26878 mlpgradnbatch(&network, xy, npoints, &e, &g, _state); 26879 v = ae_v_dotproduct(&network.weights.ptr.p_double[0], 1, &network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 26881 ae_v_addd(&g.ptr.p_double[0], 1, &network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 26882 rep->ngrad = rep->ngrad+1; 26883 logit_mnlmcsrch(wcount, &network.weights, &e, &g, &wdir, &wstep, &mcinfo, &mcnfev, &work, &mcstate, &mcstage, _state); 26885 if( spd&&((mcinfo==2||mcinfo==4)||mcinfo==6) ) 26892 * Convert from NN format to MNL format 26894 ae_v_move(&lm->w.ptr.p_double[offs], 1, &network.weights.ptr.p_double[0], 1, ae_v_len(offs,offs+wcount-1)); 26895 for(k=0; k<=nvars-1; k++) 26897 for(i=0; i<=nclasses-2; i++) 26899 s = network.columnsigmas.ptr.p_double[k]; 26900 if( ae_fp_eq(s,0) ) 26904 j = offs+(nvars+1)*i; 26905 v = lm->w.ptr.p_double[j+k]; 26906 lm->w.ptr.p_double[j+k] = v/s; 26907 lm->w.ptr.p_double[j+nvars] = lm->w.ptr.p_double[j+nvars]+v*network.columnmeans.ptr.p_double[k]/s; 26910 for(k=0; k<=nclasses-2; k++) 26912 lm->w.ptr.p_double[offs+(nvars+1)*k+nvars] = -lm->w.ptr.p_double[offs+(nvars+1)*k+nvars]; 26914 ae_frame_leave(_state); 26918 /************************************************************************* 26922 LM - logit model, passed by non-constant reference 26923 (some fields of structure are used as temporaries 26924 when calculating model output). 26925 X - input vector, array[0..NVars-1]. 26926 Y - (possibly) preallocated buffer; if size of Y is less than 26927 NClasses, it will be reallocated.If it is large enough, it 26928 is NOT reallocated, so we can save some time on reallocation. 26931 Y - result, array[0..NClasses-1] 26932 Vector of posterior probabilities for classification task. 26935 Copyright 10.09.2008 by Bochkanov Sergey 26936 *************************************************************************/ 26937 void mnlprocess(logitmodel* lm, 26938 /* Real */ ae_vector* x, 26939 /* Real */ ae_vector* y, 26950 ae_assert(ae_fp_eq(lm->w.ptr.p_double[1],logit_logitvnum), "MNLProcess: unexpected model version
", _state); 26951 nvars = ae_round(lm->w.ptr.p_double[2], _state); 26952 nclasses = ae_round(lm->w.ptr.p_double[3], _state); 26953 offs = ae_round(lm->w.ptr.p_double[4], _state); 26954 logit_mnliexp(&lm->w, x, _state); 26956 i1 = offs+(nvars+1)*(nclasses-1); 26957 for(i=i1; i<=i1+nclasses-1; i++) 26959 s = s+lm->w.ptr.p_double[i]; 26961 if( y->cnt<nclasses ) 26963 ae_vector_set_length(y, nclasses, _state); 26965 for(i=0; i<=nclasses-1; i++) 26967 y->ptr.p_double[i] = lm->w.ptr.p_double[i1+i]/s; 26972 /************************************************************************* 26973 'interactive' variant of MNLProcess for languages like Python which 26974 support constructs like "Y = MNLProcess(LM,X)
" and interactive mode of the 26977 This function allocates new array on each call, so it is significantly 26978 slower than its 'non-interactive' counterpart, but it is more convenient 26979 when you call it from command line. 26982 Copyright 10.09.2008 by Bochkanov Sergey 26983 *************************************************************************/ 26984 void mnlprocessi(logitmodel* lm, 26985 /* Real */ ae_vector* x, 26986 /* Real */ ae_vector* y, 26990 ae_vector_clear(y); 26992 mnlprocess(lm, x, y, _state); 26996 /************************************************************************* 26997 Unpacks coefficients of logit model. Logit model have form: 26999 P(class=i) = S(i) / (S(0) + S(1) + ... +S(M-1)) 27000 S(i) = Exp(A[i,0]*X[0] + ... + A[i,N-1]*X[N-1] + A[i,N]), when i<M-1 27004 LM - logit model in ALGLIB format 27007 V - coefficients, array[0..NClasses-2,0..NVars] 27008 NVars - number of independent variables 27009 NClasses - number of classes 27012 Copyright 10.09.2008 by Bochkanov Sergey 27013 *************************************************************************/ 27014 void mnlunpack(logitmodel* lm, 27015 /* Real */ ae_matrix* a, 27017 ae_int_t* nclasses, 27023 ae_matrix_clear(a); 27027 ae_assert(ae_fp_eq(lm->w.ptr.p_double[1],logit_logitvnum), "MNLUnpack: unexpected model version
", _state); 27028 *nvars = ae_round(lm->w.ptr.p_double[2], _state); 27029 *nclasses = ae_round(lm->w.ptr.p_double[3], _state); 27030 offs = ae_round(lm->w.ptr.p_double[4], _state); 27031 ae_matrix_set_length(a, *nclasses-2+1, *nvars+1, _state); 27032 for(i=0; i<=*nclasses-2; i++) 27034 ae_v_move(&a->ptr.pp_double[i][0], 1, &lm->w.ptr.p_double[offs+i*(*nvars+1)], 1, ae_v_len(0,*nvars)); 27039 /************************************************************************* 27040 "Packs
" coefficients and creates logit model in ALGLIB format (MNLUnpack 27044 A - model (see MNLUnpack) 27045 NVars - number of independent variables 27046 NClasses - number of classes 27052 Copyright 10.09.2008 by Bochkanov Sergey 27053 *************************************************************************/ 27054 void mnlpack(/* Real */ ae_matrix* a, 27064 _logitmodel_clear(lm); 27067 ssize = 5+(nvars+1)*(nclasses-1)+nclasses; 27068 ae_vector_set_length(&lm->w, ssize-1+1, _state); 27069 lm->w.ptr.p_double[0] = ssize; 27070 lm->w.ptr.p_double[1] = logit_logitvnum; 27071 lm->w.ptr.p_double[2] = nvars; 27072 lm->w.ptr.p_double[3] = nclasses; 27073 lm->w.ptr.p_double[4] = offs; 27074 for(i=0; i<=nclasses-2; i++) 27076 ae_v_move(&lm->w.ptr.p_double[offs+i*(nvars+1)], 1, &a->ptr.pp_double[i][0], 1, ae_v_len(offs+i*(nvars+1),offs+i*(nvars+1)+nvars)); 27081 /************************************************************************* 27082 Copying of LogitModel strucure 27091 Copyright 15.03.2009 by Bochkanov Sergey 27092 *************************************************************************/ 27093 void mnlcopy(logitmodel* lm1, logitmodel* lm2, ae_state *_state) 27097 _logitmodel_clear(lm2); 27099 k = ae_round(lm1->w.ptr.p_double[0], _state); 27100 ae_vector_set_length(&lm2->w, k-1+1, _state); 27101 ae_v_move(&lm2->w.ptr.p_double[0], 1, &lm1->w.ptr.p_double[0], 1, ae_v_len(0,k-1)); 27105 /************************************************************************* 27106 Average cross-entropy (in bits per element) on the test set 27111 NPoints - test set size 27114 CrossEntropy/(NPoints*ln(2)). 27117 Copyright 10.09.2008 by Bochkanov Sergey 27118 *************************************************************************/ 27119 double mnlavgce(logitmodel* lm, 27120 /* Real */ ae_matrix* xy, 27124 ae_frame _frame_block; 27132 ae_frame_make(_state, &_frame_block); 27133 ae_vector_init(&workx, 0, DT_REAL, _state, ae_true); 27134 ae_vector_init(&worky, 0, DT_REAL, _state, ae_true); 27136 ae_assert(ae_fp_eq(lm->w.ptr.p_double[1],logit_logitvnum), "MNLClsError: unexpected model version
", _state); 27137 nvars = ae_round(lm->w.ptr.p_double[2], _state); 27138 nclasses = ae_round(lm->w.ptr.p_double[3], _state); 27139 ae_vector_set_length(&workx, nvars-1+1, _state); 27140 ae_vector_set_length(&worky, nclasses-1+1, _state); 27142 for(i=0; i<=npoints-1; i++) 27144 ae_assert(ae_round(xy->ptr.pp_double[i][nvars], _state)>=0&&ae_round(xy->ptr.pp_double[i][nvars], _state)<nclasses, "MNLAvgCE: incorrect
class number!
", _state); 27149 ae_v_move(&workx.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 27150 mnlprocess(lm, &workx, &worky, _state); 27151 if( ae_fp_greater(worky.ptr.p_double[ae_round(xy->ptr.pp_double[i][nvars], _state)],0) ) 27153 result = result-ae_log(worky.ptr.p_double[ae_round(xy->ptr.pp_double[i][nvars], _state)], _state); 27157 result = result-ae_log(ae_minrealnumber, _state); 27160 result = result/(npoints*ae_log(2, _state)); 27161 ae_frame_leave(_state); 27166 /************************************************************************* 27167 Relative classification error on the test set 27172 NPoints - test set size 27175 percent of incorrectly classified cases. 27178 Copyright 10.09.2008 by Bochkanov Sergey 27179 *************************************************************************/ 27180 double mnlrelclserror(logitmodel* lm, 27181 /* Real */ ae_matrix* xy, 27188 result = (double)mnlclserror(lm, xy, npoints, _state)/(double)npoints; 27193 /************************************************************************* 27194 RMS error on the test set 27199 NPoints - test set size 27202 root mean square error (error when estimating posterior probabilities). 27205 Copyright 30.08.2008 by Bochkanov Sergey 27206 *************************************************************************/ 27207 double mnlrmserror(logitmodel* lm, 27208 /* Real */ ae_matrix* xy, 27220 ae_assert(ae_round(lm->w.ptr.p_double[1], _state)==logit_logitvnum, "MNLRMSError: Incorrect MNL version!
", _state); 27221 logit_mnlallerrors(lm, xy, npoints, &relcls, &avgce, &rms, &avg, &avgrel, _state); 27227 /************************************************************************* 27228 Average error on the test set 27233 NPoints - test set size 27236 average error (error when estimating posterior probabilities). 27239 Copyright 30.08.2008 by Bochkanov Sergey 27240 *************************************************************************/ 27241 double mnlavgerror(logitmodel* lm, 27242 /* Real */ ae_matrix* xy, 27254 ae_assert(ae_round(lm->w.ptr.p_double[1], _state)==logit_logitvnum, "MNLRMSError: Incorrect MNL version!
", _state); 27255 logit_mnlallerrors(lm, xy, npoints, &relcls, &avgce, &rms, &avg, &avgrel, _state); 27261 /************************************************************************* 27262 Average relative error on the test set 27267 NPoints - test set size 27270 average relative error (error when estimating posterior probabilities). 27273 Copyright 30.08.2008 by Bochkanov Sergey 27274 *************************************************************************/ 27275 double mnlavgrelerror(logitmodel* lm, 27276 /* Real */ ae_matrix* xy, 27288 ae_assert(ae_round(lm->w.ptr.p_double[1], _state)==logit_logitvnum, "MNLRMSError: Incorrect MNL version!
", _state); 27289 logit_mnlallerrors(lm, xy, ssize, &relcls, &avgce, &rms, &avg, &avgrel, _state); 27295 /************************************************************************* 27296 Classification error on test set = MNLRelClsError*NPoints 27299 Copyright 10.09.2008 by Bochkanov Sergey 27300 *************************************************************************/ 27301 ae_int_t mnlclserror(logitmodel* lm, 27302 /* Real */ ae_matrix* xy, 27306 ae_frame _frame_block; 27316 ae_frame_make(_state, &_frame_block); 27317 ae_vector_init(&workx, 0, DT_REAL, _state, ae_true); 27318 ae_vector_init(&worky, 0, DT_REAL, _state, ae_true); 27320 ae_assert(ae_fp_eq(lm->w.ptr.p_double[1],logit_logitvnum), "MNLClsError: unexpected model version
", _state); 27321 nvars = ae_round(lm->w.ptr.p_double[2], _state); 27322 nclasses = ae_round(lm->w.ptr.p_double[3], _state); 27323 ae_vector_set_length(&workx, nvars-1+1, _state); 27324 ae_vector_set_length(&worky, nclasses-1+1, _state); 27326 for(i=0; i<=npoints-1; i++) 27332 ae_v_move(&workx.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 27333 mnlprocess(lm, &workx, &worky, _state); 27336 * Logit version of the answer 27339 for(j=0; j<=nclasses-1; j++) 27341 if( ae_fp_greater(worky.ptr.p_double[j],worky.ptr.p_double[nmax]) ) 27350 if( nmax!=ae_round(xy->ptr.pp_double[i][nvars], _state) ) 27355 ae_frame_leave(_state); 27360 /************************************************************************* 27361 Internal subroutine. Places exponents of the anti-overflow shifted 27362 internal linear outputs into the service part of the W array. 27363 *************************************************************************/ 27364 static void logit_mnliexp(/* Real */ ae_vector* w, 27365 /* Real */ ae_vector* x, 27377 ae_assert(ae_fp_eq(w->ptr.p_double[1],logit_logitvnum), "LOGIT: unexpected model version
", _state); 27378 nvars = ae_round(w->ptr.p_double[2], _state); 27379 nclasses = ae_round(w->ptr.p_double[3], _state); 27380 offs = ae_round(w->ptr.p_double[4], _state); 27381 i1 = offs+(nvars+1)*(nclasses-1); 27382 for(i=0; i<=nclasses-2; i++) 27384 v = ae_v_dotproduct(&w->ptr.p_double[offs+i*(nvars+1)], 1, &x->ptr.p_double[0], 1, ae_v_len(offs+i*(nvars+1),offs+i*(nvars+1)+nvars-1)); 27385 w->ptr.p_double[i1+i] = v+w->ptr.p_double[offs+i*(nvars+1)+nvars]; 27387 w->ptr.p_double[i1+nclasses-1] = 0; 27389 for(i=i1; i<=i1+nclasses-1; i++) 27391 mx = ae_maxreal(mx, w->ptr.p_double[i], _state); 27393 for(i=i1; i<=i1+nclasses-1; i++) 27395 w->ptr.p_double[i] = ae_exp(w->ptr.p_double[i]-mx, _state); 27400 /************************************************************************* 27401 Calculation of all types of errors 27404 Copyright 30.08.2008 by Bochkanov Sergey 27405 *************************************************************************/ 27406 static void logit_mnlallerrors(logitmodel* lm, 27407 /* Real */ ae_matrix* xy, 27416 ae_frame _frame_block; 27425 ae_frame_make(_state, &_frame_block); 27431 ae_vector_init(&buf, 0, DT_REAL, _state, ae_true); 27432 ae_vector_init(&workx, 0, DT_REAL, _state, ae_true); 27433 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 27434 ae_vector_init(&dy, 0, DT_REAL, _state, ae_true); 27436 ae_assert(ae_round(lm->w.ptr.p_double[1], _state)==logit_logitvnum, "MNL unit: Incorrect MNL version!
", _state); 27437 nvars = ae_round(lm->w.ptr.p_double[2], _state); 27438 nclasses = ae_round(lm->w.ptr.p_double[3], _state); 27439 ae_vector_set_length(&workx, nvars-1+1, _state); 27440 ae_vector_set_length(&y, nclasses-1+1, _state); 27441 ae_vector_set_length(&dy, 0+1, _state); 27442 dserrallocate(nclasses, &buf, _state); 27443 for(i=0; i<=npoints-1; i++) 27445 ae_v_move(&workx.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 27446 mnlprocess(lm, &workx, &y, _state); 27447 dy.ptr.p_double[0] = xy->ptr.pp_double[i][nvars]; 27448 dserraccumulate(&buf, &y, &dy, _state); 27450 dserrfinish(&buf, _state); 27451 *relcls = buf.ptr.p_double[0]; 27452 *avgce = buf.ptr.p_double[1]; 27453 *rms = buf.ptr.p_double[2]; 27454 *avg = buf.ptr.p_double[3]; 27455 *avgrel = buf.ptr.p_double[4]; 27456 ae_frame_leave(_state); 27460 /************************************************************************* 27461 THE PURPOSE OF MCSRCH IS TO FIND A STEP WHICH SATISFIES A SUFFICIENT 27462 DECREASE CONDITION AND A CURVATURE CONDITION. 27464 AT EACH STAGE THE SUBROUTINE UPDATES AN INTERVAL OF UNCERTAINTY WITH 27465 ENDPOINTS STX AND STY. THE INTERVAL OF UNCERTAINTY IS INITIALLY CHOSEN 27466 SO THAT IT CONTAINS A MINIMIZER OF THE MODIFIED FUNCTION 27468 F(X+STP*S) - F(X) - FTOL*STP*(GRADF(X)'S). 27470 IF A STEP IS OBTAINED FOR WHICH THE MODIFIED FUNCTION HAS A NONPOSITIVE 27471 FUNCTION VALUE AND NONNEGATIVE DERIVATIVE, THEN THE INTERVAL OF 27472 UNCERTAINTY IS CHOSEN SO THAT IT CONTAINS A MINIMIZER OF F(X+STP*S). 27474 THE ALGORITHM IS DESIGNED TO FIND A STEP WHICH SATISFIES THE SUFFICIENT 27477 F(X+STP*S) .LE. F(X) + FTOL*STP*(GRADF(X)'S), 27479 AND THE CURVATURE CONDITION 27481 ABS(GRADF(X+STP*S)'S)) .LE. GTOL*ABS(GRADF(X)'S). 27483 IF FTOL IS LESS THAN GTOL AND IF, FOR EXAMPLE, THE FUNCTION IS BOUNDED 27484 BELOW, THEN THERE IS ALWAYS A STEP WHICH SATISFIES BOTH CONDITIONS. 27485 IF NO STEP CAN BE FOUND WHICH SATISFIES BOTH CONDITIONS, THEN THE 27486 ALGORITHM USUALLY STOPS WHEN ROUNDING ERRORS PREVENT FURTHER PROGRESS. 27487 IN THIS CASE STP ONLY SATISFIES THE SUFFICIENT DECREASE CONDITION. 27489 PARAMETERS DESCRIPRION 27491 N IS A POSITIVE INTEGER INPUT VARIABLE SET TO THE NUMBER OF VARIABLES. 27493 X IS AN ARRAY OF LENGTH N. ON INPUT IT MUST CONTAIN THE BASE POINT FOR 27494 THE LINE SEARCH. ON OUTPUT IT CONTAINS X+STP*S. 27496 F IS A VARIABLE. ON INPUT IT MUST CONTAIN THE VALUE OF F AT X. ON OUTPUT 27497 IT CONTAINS THE VALUE OF F AT X + STP*S. 27499 G IS AN ARRAY OF LENGTH N. ON INPUT IT MUST CONTAIN THE GRADIENT OF F AT X. 27500 ON OUTPUT IT CONTAINS THE GRADIENT OF F AT X + STP*S. 27502 S IS AN INPUT ARRAY OF LENGTH N WHICH SPECIFIES THE SEARCH DIRECTION. 27504 STP IS A NONNEGATIVE VARIABLE. ON INPUT STP CONTAINS AN INITIAL ESTIMATE 27505 OF A SATISFACTORY STEP. ON OUTPUT STP CONTAINS THE FINAL ESTIMATE. 27507 FTOL AND GTOL ARE NONNEGATIVE INPUT VARIABLES. TERMINATION OCCURS WHEN THE 27508 SUFFICIENT DECREASE CONDITION AND THE DIRECTIONAL DERIVATIVE CONDITION ARE 27511 XTOL IS A NONNEGATIVE INPUT VARIABLE. TERMINATION OCCURS WHEN THE RELATIVE 27512 WIDTH OF THE INTERVAL OF UNCERTAINTY IS AT MOST XTOL. 27514 STPMIN AND STPMAX ARE NONNEGATIVE INPUT VARIABLES WHICH SPECIFY LOWER AND 27515 UPPER BOUNDS FOR THE STEP. 27517 MAXFEV IS A POSITIVE INTEGER INPUT VARIABLE. TERMINATION OCCURS WHEN THE 27518 NUMBER OF CALLS TO FCN IS AT LEAST MAXFEV BY THE END OF AN ITERATION. 27520 INFO IS AN INTEGER OUTPUT VARIABLE SET AS FOLLOWS: 27521 INFO = 0 IMPROPER INPUT PARAMETERS. 27523 INFO = 1 THE SUFFICIENT DECREASE CONDITION AND THE 27524 DIRECTIONAL DERIVATIVE CONDITION HOLD. 27526 INFO = 2 RELATIVE WIDTH OF THE INTERVAL OF UNCERTAINTY 27529 INFO = 3 NUMBER OF CALLS TO FCN HAS REACHED MAXFEV. 27531 INFO = 4 THE STEP IS AT THE LOWER BOUND STPMIN. 27533 INFO = 5 THE STEP IS AT THE UPPER BOUND STPMAX. 27535 INFO = 6 ROUNDING ERRORS PREVENT FURTHER PROGRESS. 27536 THERE MAY NOT BE A STEP WHICH SATISFIES THE 27537 SUFFICIENT DECREASE AND CURVATURE CONDITIONS. 27538 TOLERANCES MAY BE TOO SMALL. 27540 NFEV IS AN INTEGER OUTPUT VARIABLE SET TO THE NUMBER OF CALLS TO FCN. 27542 WA IS A WORK ARRAY OF LENGTH N. 27544 ARGONNE NATIONAL LABORATORY. MINPACK PROJECT. JUNE 1983 27545 JORGE J. MORE', DAVID J. THUENTE 27546 *************************************************************************/ 27547 static void logit_mnlmcsrch(ae_int_t n, 27548 /* Real */ ae_vector* x, 27550 /* Real */ ae_vector* g, 27551 /* Real */ ae_vector* s, 27555 /* Real */ ae_vector* wa, 27556 logitmcstate* state, 27572 state->xtrapf = 4.0; 27595 * CHECK THE INPUT PARAMETERS FOR ERRORS. 27597 if( ((((((n<=0||ae_fp_less_eq(*stp,0))||ae_fp_less(logit_ftol,0))||ae_fp_less(logit_gtol,zero))||ae_fp_less(logit_xtol,zero))||ae_fp_less(logit_stpmin,zero))||ae_fp_less(logit_stpmax,logit_stpmin))||logit_maxfev<=0 ) 27604 * COMPUTE THE INITIAL GRADIENT IN THE SEARCH DIRECTION 27605 * AND CHECK THAT S IS A DESCENT DIRECTION. 27607 v = ae_v_dotproduct(&g->ptr.p_double[0], 1, &s->ptr.p_double[0], 1, ae_v_len(0,n-1)); 27609 if( ae_fp_greater_eq(state->dginit,0) ) 27616 * INITIALIZE LOCAL VARIABLES. 27618 state->brackt = ae_false; 27619 state->stage1 = ae_true; 27622 state->dgtest = logit_ftol*state->dginit; 27623 state->width = logit_stpmax-logit_stpmin; 27624 state->width1 = state->width/p5; 27625 ae_v_move(&wa->ptr.p_double[0], 1, &x->ptr.p_double[0], 1, ae_v_len(0,n-1)); 27628 * THE VARIABLES STX, FX, DGX CONTAIN THE VALUES OF THE STEP, 27629 * FUNCTION, AND DIRECTIONAL DERIVATIVE AT THE BEST STEP. 27630 * THE VARIABLES STY, FY, DGY CONTAIN THE VALUE OF THE STEP, 27631 * FUNCTION, AND DERIVATIVE AT THE OTHER ENDPOINT OF 27632 * THE INTERVAL OF UNCERTAINTY. 27633 * THE VARIABLES STP, F, DG CONTAIN THE VALUES OF THE STEP, 27634 * FUNCTION, AND DERIVATIVE AT THE CURRENT STEP. 27637 state->fx = state->finit; 27638 state->dgx = state->dginit; 27640 state->fy = state->finit; 27641 state->dgy = state->dginit; 27653 * START OF ITERATION. 27655 * SET THE MINIMUM AND MAXIMUM STEPS TO CORRESPOND 27656 * TO THE PRESENT INTERVAL OF UNCERTAINTY. 27658 if( state->brackt ) 27660 if( ae_fp_less(state->stx,state->sty) ) 27662 state->stmin = state->stx; 27663 state->stmax = state->sty; 27667 state->stmin = state->sty; 27668 state->stmax = state->stx; 27673 state->stmin = state->stx; 27674 state->stmax = *stp+state->xtrapf*(*stp-state->stx); 27678 * FORCE THE STEP TO BE WITHIN THE BOUNDS STPMAX AND STPMIN. 27680 if( ae_fp_greater(*stp,logit_stpmax) ) 27682 *stp = logit_stpmax; 27684 if( ae_fp_less(*stp,logit_stpmin) ) 27686 *stp = logit_stpmin; 27690 * IF AN UNUSUAL TERMINATION IS TO OCCUR THEN LET 27691 * STP BE THE LOWEST POINT OBTAINED SO FAR. 27693 if( (((state->brackt&&(ae_fp_less_eq(*stp,state->stmin)||ae_fp_greater_eq(*stp,state->stmax)))||*nfev>=logit_maxfev-1)||state->infoc==0)||(state->brackt&&ae_fp_less_eq(state->stmax-state->stmin,logit_xtol*state->stmax)) ) 27699 * EVALUATE THE FUNCTION AND GRADIENT AT STP 27700 * AND COMPUTE THE DIRECTIONAL DERIVATIVE. 27702 ae_v_move(&x->ptr.p_double[0], 1, &wa->ptr.p_double[0], 1, ae_v_len(0,n-1)); 27703 ae_v_addd(&x->ptr.p_double[0], 1, &s->ptr.p_double[0], 1, ae_v_len(0,n-1), *stp); 27715 v = ae_v_dotproduct(&g->ptr.p_double[0], 1, &s->ptr.p_double[0], 1, ae_v_len(0,n-1)); 27717 state->ftest1 = state->finit+*stp*state->dgtest; 27720 * TEST FOR CONVERGENCE. 27722 if( (state->brackt&&(ae_fp_less_eq(*stp,state->stmin)||ae_fp_greater_eq(*stp,state->stmax)))||state->infoc==0 ) 27726 if( (ae_fp_eq(*stp,logit_stpmax)&&ae_fp_less_eq(*f,state->ftest1))&&ae_fp_less_eq(state->dg,state->dgtest) ) 27730 if( ae_fp_eq(*stp,logit_stpmin)&&(ae_fp_greater(*f,state->ftest1)||ae_fp_greater_eq(state->dg,state->dgtest)) ) 27734 if( *nfev>=logit_maxfev ) 27738 if( state->brackt&&ae_fp_less_eq(state->stmax-state->stmin,logit_xtol*state->stmax) ) 27742 if( ae_fp_less_eq(*f,state->ftest1)&&ae_fp_less_eq(ae_fabs(state->dg, _state),-logit_gtol*state->dginit) ) 27748 * CHECK FOR TERMINATION. 27757 * IN THE FIRST STAGE WE SEEK A STEP FOR WHICH THE MODIFIED 27758 * FUNCTION HAS A NONPOSITIVE VALUE AND NONNEGATIVE DERIVATIVE. 27760 if( (state->stage1&&ae_fp_less_eq(*f,state->ftest1))&&ae_fp_greater_eq(state->dg,ae_minreal(logit_ftol, logit_gtol, _state)*state->dginit) ) 27762 state->stage1 = ae_false; 27766 * A MODIFIED FUNCTION IS USED TO PREDICT THE STEP ONLY IF 27767 * WE HAVE NOT OBTAINED A STEP FOR WHICH THE MODIFIED 27768 * FUNCTION HAS A NONPOSITIVE FUNCTION VALUE AND NONNEGATIVE 27769 * DERIVATIVE, AND IF A LOWER FUNCTION VALUE HAS BEEN 27770 * OBTAINED BUT THE DECREASE IS NOT SUFFICIENT. 27772 if( (state->stage1&&ae_fp_less_eq(*f,state->fx))&&ae_fp_greater(*f,state->ftest1) ) 27776 * DEFINE THE MODIFIED FUNCTION AND DERIVATIVE VALUES. 27778 state->fm = *f-*stp*state->dgtest; 27779 state->fxm = state->fx-state->stx*state->dgtest; 27780 state->fym = state->fy-state->sty*state->dgtest; 27781 state->dgm = state->dg-state->dgtest; 27782 state->dgxm = state->dgx-state->dgtest; 27783 state->dgym = state->dgy-state->dgtest; 27786 * CALL CSTEP TO UPDATE THE INTERVAL OF UNCERTAINTY 27787 * AND TO COMPUTE THE NEW STEP. 27789 logit_mnlmcstep(&state->stx, &state->fxm, &state->dgxm, &state->sty, &state->fym, &state->dgym, stp, state->fm, state->dgm, &state->brackt, state->stmin, state->stmax, &state->infoc, _state); 27792 * RESET THE FUNCTION AND GRADIENT VALUES FOR F. 27794 state->fx = state->fxm+state->stx*state->dgtest; 27795 state->fy = state->fym+state->sty*state->dgtest; 27796 state->dgx = state->dgxm+state->dgtest; 27797 state->dgy = state->dgym+state->dgtest; 27803 * CALL MCSTEP TO UPDATE THE INTERVAL OF UNCERTAINTY 27804 * AND TO COMPUTE THE NEW STEP. 27806 logit_mnlmcstep(&state->stx, &state->fx, &state->dgx, &state->sty, &state->fy, &state->dgy, stp, *f, state->dg, &state->brackt, state->stmin, state->stmax, &state->infoc, _state); 27810 * FORCE A SUFFICIENT DECREASE IN THE SIZE OF THE 27811 * INTERVAL OF UNCERTAINTY. 27813 if( state->brackt ) 27815 if( ae_fp_greater_eq(ae_fabs(state->sty-state->stx, _state),p66*state->width1) ) 27817 *stp = state->stx+p5*(state->sty-state->stx); 27819 state->width1 = state->width; 27820 state->width = ae_fabs(state->sty-state->stx, _state); 27833 static void logit_mnlmcstep(double* stx, 27864 * CHECK THE INPUT PARAMETERS FOR ERRORS. 27866 if( ((*brackt&&(ae_fp_less_eq(*stp,ae_minreal(*stx, *sty, _state))||ae_fp_greater_eq(*stp,ae_maxreal(*stx, *sty, _state))))||ae_fp_greater_eq(*dx*(*stp-(*stx)),0))||ae_fp_less(stmax,stmin) ) 27872 * DETERMINE IF THE DERIVATIVES HAVE OPPOSITE SIGN. 27874 sgnd = dp*(*dx/ae_fabs(*dx, _state)); 27877 * FIRST CASE. A HIGHER FUNCTION VALUE. 27878 * THE MINIMUM IS BRACKETED. IF THE CUBIC STEP IS CLOSER 27879 * TO STX THAN THE QUADRATIC STEP, THE CUBIC STEP IS TAKEN, 27880 * ELSE THE AVERAGE OF THE CUBIC AND QUADRATIC STEPS IS TAKEN. 27882 if( ae_fp_greater(fp,*fx) ) 27886 theta = 3*(*fx-fp)/(*stp-(*stx))+(*dx)+dp; 27887 s = ae_maxreal(ae_fabs(theta, _state), ae_maxreal(ae_fabs(*dx, _state), ae_fabs(dp, _state), _state), _state); 27888 gamma = s*ae_sqrt(ae_sqr(theta/s, _state)-*dx/s*(dp/s), _state); 27889 if( ae_fp_less(*stp,*stx) ) 27893 p = gamma-(*dx)+theta; 27894 q = gamma-(*dx)+gamma+dp; 27896 stpc = *stx+r*(*stp-(*stx)); 27897 stpq = *stx+*dx/((*fx-fp)/(*stp-(*stx))+(*dx))/2*(*stp-(*stx)); 27898 if( ae_fp_less(ae_fabs(stpc-(*stx), _state),ae_fabs(stpq-(*stx), _state)) ) 27904 stpf = stpc+(stpq-stpc)/2; 27910 if( ae_fp_less(sgnd,0) ) 27914 * SECOND CASE. A LOWER FUNCTION VALUE AND DERIVATIVES OF 27915 * OPPOSITE SIGN. THE MINIMUM IS BRACKETED. IF THE CUBIC 27916 * STEP IS CLOSER TO STX THAN THE QUADRATIC (SECANT) STEP, 27917 * THE CUBIC STEP IS TAKEN, ELSE THE QUADRATIC STEP IS TAKEN. 27921 theta = 3*(*fx-fp)/(*stp-(*stx))+(*dx)+dp; 27922 s = ae_maxreal(ae_fabs(theta, _state), ae_maxreal(ae_fabs(*dx, _state), ae_fabs(dp, _state), _state), _state); 27923 gamma = s*ae_sqrt(ae_sqr(theta/s, _state)-*dx/s*(dp/s), _state); 27924 if( ae_fp_greater(*stp,*stx) ) 27928 p = gamma-dp+theta; 27929 q = gamma-dp+gamma+(*dx); 27931 stpc = *stp+r*(*stx-(*stp)); 27932 stpq = *stp+dp/(dp-(*dx))*(*stx-(*stp)); 27933 if( ae_fp_greater(ae_fabs(stpc-(*stp), _state),ae_fabs(stpq-(*stp), _state)) ) 27945 if( ae_fp_less(ae_fabs(dp, _state),ae_fabs(*dx, _state)) ) 27949 * THIRD CASE. A LOWER FUNCTION VALUE, DERIVATIVES OF THE 27950 * SAME SIGN, AND THE MAGNITUDE OF THE DERIVATIVE DECREASES. 27951 * THE CUBIC STEP IS ONLY USED IF THE CUBIC TENDS TO INFINITY 27952 * IN THE DIRECTION OF THE STEP OR IF THE MINIMUM OF THE CUBIC 27953 * IS BEYOND STP. OTHERWISE THE CUBIC STEP IS DEFINED TO BE 27954 * EITHER STPMIN OR STPMAX. THE QUADRATIC (SECANT) STEP IS ALSO 27955 * COMPUTED AND IF THE MINIMUM IS BRACKETED THEN THE THE STEP 27956 * CLOSEST TO STX IS TAKEN, ELSE THE STEP FARTHEST AWAY IS TAKEN. 27960 theta = 3*(*fx-fp)/(*stp-(*stx))+(*dx)+dp; 27961 s = ae_maxreal(ae_fabs(theta, _state), ae_maxreal(ae_fabs(*dx, _state), ae_fabs(dp, _state), _state), _state); 27964 * THE CASE GAMMA = 0 ONLY ARISES IF THE CUBIC DOES NOT TEND 27965 * TO INFINITY IN THE DIRECTION OF THE STEP. 27967 gamma = s*ae_sqrt(ae_maxreal(0, ae_sqr(theta/s, _state)-*dx/s*(dp/s), _state), _state); 27968 if( ae_fp_greater(*stp,*stx) ) 27972 p = gamma-dp+theta; 27973 q = gamma+(*dx-dp)+gamma; 27975 if( ae_fp_less(r,0)&&ae_fp_neq(gamma,0) ) 27977 stpc = *stp+r*(*stx-(*stp)); 27981 if( ae_fp_greater(*stp,*stx) ) 27990 stpq = *stp+dp/(dp-(*dx))*(*stx-(*stp)); 27993 if( ae_fp_less(ae_fabs(*stp-stpc, _state),ae_fabs(*stp-stpq, _state)) ) 28004 if( ae_fp_greater(ae_fabs(*stp-stpc, _state),ae_fabs(*stp-stpq, _state)) ) 28018 * FOURTH CASE. A LOWER FUNCTION VALUE, DERIVATIVES OF THE 28019 * SAME SIGN, AND THE MAGNITUDE OF THE DERIVATIVE DOES 28020 * NOT DECREASE. IF THE MINIMUM IS NOT BRACKETED, THE STEP 28021 * IS EITHER STPMIN OR STPMAX, ELSE THE CUBIC STEP IS TAKEN. 28027 theta = 3*(fp-(*fy))/(*sty-(*stp))+(*dy)+dp; 28028 s = ae_maxreal(ae_fabs(theta, _state), ae_maxreal(ae_fabs(*dy, _state), ae_fabs(dp, _state), _state), _state); 28029 gamma = s*ae_sqrt(ae_sqr(theta/s, _state)-*dy/s*(dp/s), _state); 28030 if( ae_fp_greater(*stp,*sty) ) 28034 p = gamma-dp+theta; 28035 q = gamma-dp+gamma+(*dy); 28037 stpc = *stp+r*(*sty-(*stp)); 28042 if( ae_fp_greater(*stp,*stx) ) 28056 * UPDATE THE INTERVAL OF UNCERTAINTY. THIS UPDATE DOES NOT 28057 * DEPEND ON THE NEW STEP OR THE CASE ANALYSIS ABOVE. 28059 if( ae_fp_greater(fp,*fx) ) 28067 if( ae_fp_less(sgnd,0.0) ) 28079 * COMPUTE THE NEW STEP AND SAFEGUARD IT. 28081 stpf = ae_minreal(stmax, stpf, _state); 28082 stpf = ae_maxreal(stmin, stpf, _state); 28084 if( *brackt&&bound ) 28086 if( ae_fp_greater(*sty,*stx) ) 28088 *stp = ae_minreal(*stx+0.66*(*sty-(*stx)), *stp, _state); 28092 *stp = ae_maxreal(*stx+0.66*(*sty-(*stx)), *stp, _state); 28098 ae_bool _logitmodel_init(void* _p, ae_state *_state, ae_bool make_automatic) 28100 logitmodel *p = (logitmodel*)_p; 28101 ae_touch_ptr((void*)p); 28102 if( !ae_vector_init(&p->w, 0, DT_REAL, _state, make_automatic) ) 28108 ae_bool _logitmodel_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 28110 logitmodel *dst = (logitmodel*)_dst; 28111 logitmodel *src = (logitmodel*)_src; 28112 if( !ae_vector_init_copy(&dst->w, &src->w, _state, make_automatic) ) 28118 void _logitmodel_clear(void* _p) 28120 logitmodel *p = (logitmodel*)_p; 28121 ae_touch_ptr((void*)p); 28122 ae_vector_clear(&p->w); 28126 void _logitmodel_destroy(void* _p) 28128 logitmodel *p = (logitmodel*)_p; 28129 ae_touch_ptr((void*)p); 28130 ae_vector_destroy(&p->w); 28134 ae_bool _logitmcstate_init(void* _p, ae_state *_state, ae_bool make_automatic) 28136 logitmcstate *p = (logitmcstate*)_p; 28137 ae_touch_ptr((void*)p); 28142 ae_bool _logitmcstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 28144 logitmcstate *dst = (logitmcstate*)_dst; 28145 logitmcstate *src = (logitmcstate*)_src; 28146 dst->brackt = src->brackt; 28147 dst->stage1 = src->stage1; 28148 dst->infoc = src->infoc; 28150 dst->dgm = src->dgm; 28151 dst->dginit = src->dginit; 28152 dst->dgtest = src->dgtest; 28153 dst->dgx = src->dgx; 28154 dst->dgxm = src->dgxm; 28155 dst->dgy = src->dgy; 28156 dst->dgym = src->dgym; 28157 dst->finit = src->finit; 28158 dst->ftest1 = src->ftest1; 28161 dst->fxm = src->fxm; 28163 dst->fym = src->fym; 28164 dst->stx = src->stx; 28165 dst->sty = src->sty; 28166 dst->stmin = src->stmin; 28167 dst->stmax = src->stmax; 28168 dst->width = src->width; 28169 dst->width1 = src->width1; 28170 dst->xtrapf = src->xtrapf; 28175 void _logitmcstate_clear(void* _p) 28177 logitmcstate *p = (logitmcstate*)_p; 28178 ae_touch_ptr((void*)p); 28182 void _logitmcstate_destroy(void* _p) 28184 logitmcstate *p = (logitmcstate*)_p; 28185 ae_touch_ptr((void*)p); 28189 ae_bool _mnlreport_init(void* _p, ae_state *_state, ae_bool make_automatic) 28191 mnlreport *p = (mnlreport*)_p; 28192 ae_touch_ptr((void*)p); 28197 ae_bool _mnlreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 28199 mnlreport *dst = (mnlreport*)_dst; 28200 mnlreport *src = (mnlreport*)_src; 28201 dst->ngrad = src->ngrad; 28202 dst->nhess = src->nhess; 28207 void _mnlreport_clear(void* _p) 28209 mnlreport *p = (mnlreport*)_p; 28210 ae_touch_ptr((void*)p); 28214 void _mnlreport_destroy(void* _p) 28216 mnlreport *p = (mnlreport*)_p; 28217 ae_touch_ptr((void*)p); 28223 /************************************************************************* 28226 This function creates MCPD (Markov Chains for Population Data) solver. 28228 This solver can be used to find transition matrix P for N-dimensional 28229 prediction problem where transition from X[i] to X[i+1] is modelled as 28231 where X[i] and X[i+1] are N-dimensional population vectors (components of 28232 each X are non-negative), and P is a N*N transition matrix (elements of P 28233 are non-negative, each column sums to 1.0). 28235 Such models arise when when: 28236 * there is some population of individuals 28237 * individuals can have different states 28238 * individuals can transit from one state to another 28239 * population size is constant, i.e. there is no new individuals and no one 28241 * you want to model transitions of individuals from one state into another 28245 Here we give very brief outline of the MCPD. We strongly recommend you to 28246 read examples in the ALGLIB Reference Manual and to read ALGLIB User Guide 28247 on data analysis which is available at http://www.alglib.net/dataanalysis/ 28249 1. User initializes algorithm state with MCPDCreate() call 28251 2. User adds one or more tracks - sequences of states which describe 28252 evolution of a system being modelled from different starting conditions 28254 3. User may add optional boundary, equality and/or linear constraints on 28255 the coefficients of P by calling one of the following functions: 28256 * MCPDSetEC() to set equality constraints 28257 * MCPDSetBC() to set bound constraints 28258 * MCPDSetLC() to set linear constraints 28260 4. Optionally, user may set custom weights for prediction errors (by 28261 default, algorithm assigns non-equal, automatically chosen weights for 28262 errors in the prediction of different components of X). It can be done 28263 with a call of MCPDSetPredictionWeights() function. 28265 5. User calls MCPDSolve() function which takes algorithm state and 28266 pointer (delegate, etc.) to callback function which calculates F/G. 28268 6. User calls MCPDResults() to get solution 28271 N - problem dimension, N>=1 28274 State - structure stores algorithm state 28277 Copyright 23.05.2010 by Bochkanov Sergey 28278 *************************************************************************/ 28279 void mcpdcreate(ae_int_t n, mcpdstate* s, ae_state *_state) 28282 _mcpdstate_clear(s); 28284 ae_assert(n>=1, "MCPDCreate: N<1
", _state); 28285 mcpd_mcpdinit(n, -1, -1, s, _state); 28289 /************************************************************************* 28292 This function is a specialized version of MCPDCreate() function, and we 28293 recommend you to read comments for this function for general information 28296 This function creates MCPD (Markov Chains for Population Data) solver 28297 for "Entry-state
" model, i.e. model where transition from X[i] to X[i+1] 28301 X[i] and X[i+1] are N-dimensional state vectors 28302 P is a N*N transition matrix 28303 and one selected component of X[] is called "entry
" state and is treated 28305 system state always transits from "entry
" state to some another state 28306 system state can not transit from any state into "entry
" state 28307 Such conditions basically mean that row of P which corresponds to "entry
" 28310 Such models arise when: 28311 * there is some population of individuals 28312 * individuals can have different states 28313 * individuals can transit from one state to another 28314 * population size is NOT constant - at every moment of time there is some 28315 (unpredictable) amount of "new" individuals, which can transit into one 28316 of the states at the next turn, but still no one leaves population 28317 * you want to model transitions of individuals from one state into another 28318 * but you do NOT want to predict amount of "new" individuals because it 28319 does not depends on individuals already present (hence system can not 28320 transit INTO entry state - it can only transit FROM it). 28322 This model is discussed in more details in the ALGLIB User Guide (see 28323 http://www.alglib.net/dataanalysis/ for more data). 28326 N - problem dimension, N>=2 28327 EntryState- index of entry state, in 0..N-1 28330 State - structure stores algorithm state 28333 Copyright 23.05.2010 by Bochkanov Sergey 28334 *************************************************************************/ 28335 void mcpdcreateentry(ae_int_t n, 28336 ae_int_t entrystate, 28341 _mcpdstate_clear(s); 28343 ae_assert(n>=2, "MCPDCreateEntry: N<2
", _state); 28344 ae_assert(entrystate>=0, "MCPDCreateEntry: EntryState<0
", _state); 28345 ae_assert(entrystate<n, "MCPDCreateEntry: EntryState>=N
", _state); 28346 mcpd_mcpdinit(n, entrystate, -1, s, _state); 28350 /************************************************************************* 28353 This function is a specialized version of MCPDCreate() function, and we 28354 recommend you to read comments for this function for general information 28357 This function creates MCPD (Markov Chains for Population Data) solver 28358 for "Exit-state
" model, i.e. model where transition from X[i] to X[i+1] 28362 X[i] and X[i+1] are N-dimensional state vectors 28363 P is a N*N transition matrix 28364 and one selected component of X[] is called "exit
" state and is treated 28366 system state can transit from any state into "exit
" state 28367 system state can not transit from "exit
" state into any other state 28368 transition operator discards "exit
" state (makes it zero at each turn) 28369 Such conditions basically mean that column of P which corresponds to 28370 "exit
" state is zero. Multiplication by such P may decrease sum of vector 28373 Such models arise when: 28374 * there is some population of individuals 28375 * individuals can have different states 28376 * individuals can transit from one state to another 28377 * population size is NOT constant - individuals can move into "exit
" state 28378 and leave population at the next turn, but there are no new individuals 28379 * amount of individuals which leave population can be predicted 28380 * you want to model transitions of individuals from one state into another 28381 (including transitions into the "exit
" state) 28383 This model is discussed in more details in the ALGLIB User Guide (see 28384 http://www.alglib.net/dataanalysis/ for more data). 28387 N - problem dimension, N>=2 28388 ExitState- index of exit state, in 0..N-1 28391 State - structure stores algorithm state 28394 Copyright 23.05.2010 by Bochkanov Sergey 28395 *************************************************************************/ 28396 void mcpdcreateexit(ae_int_t n, 28397 ae_int_t exitstate, 28402 _mcpdstate_clear(s); 28404 ae_assert(n>=2, "MCPDCreateExit: N<2
", _state); 28405 ae_assert(exitstate>=0, "MCPDCreateExit: ExitState<0
", _state); 28406 ae_assert(exitstate<n, "MCPDCreateExit: ExitState>=N
", _state); 28407 mcpd_mcpdinit(n, -1, exitstate, s, _state); 28411 /************************************************************************* 28414 This function is a specialized version of MCPDCreate() function, and we 28415 recommend you to read comments for this function for general information 28418 This function creates MCPD (Markov Chains for Population Data) solver 28419 for "Entry-Exit-states
" model, i.e. model where transition from X[i] to 28420 X[i+1] is modelled as 28423 X[i] and X[i+1] are N-dimensional state vectors 28424 P is a N*N transition matrix 28425 one selected component of X[] is called "entry
" state and is treated in a 28427 system state always transits from "entry
" state to some another state 28428 system state can not transit from any state into "entry
" state 28429 and another one component of X[] is called "exit
" state and is treated in 28431 system state can transit from any state into "exit
" state 28432 system state can not transit from "exit
" state into any other state 28433 transition operator discards "exit
" state (makes it zero at each turn) 28434 Such conditions basically mean that: 28435 row of P which corresponds to "entry
" state is zero 28436 column of P which corresponds to "exit
" state is zero 28437 Multiplication by such P may decrease sum of vector components. 28439 Such models arise when: 28440 * there is some population of individuals 28441 * individuals can have different states 28442 * individuals can transit from one state to another 28443 * population size is NOT constant 28444 * at every moment of time there is some (unpredictable) amount of "new" 28445 individuals, which can transit into one of the states at the next turn 28446 * some individuals can move (predictably) into "exit
" state and leave 28447 population at the next turn 28448 * you want to model transitions of individuals from one state into another, 28449 including transitions from the "entry
" state and into the "exit
" state. 28450 * but you do NOT want to predict amount of "new" individuals because it 28451 does not depends on individuals already present (hence system can not 28452 transit INTO entry state - it can only transit FROM it). 28454 This model is discussed in more details in the ALGLIB User Guide (see 28455 http://www.alglib.net/dataanalysis/ for more data). 28458 N - problem dimension, N>=2 28459 EntryState- index of entry state, in 0..N-1 28460 ExitState- index of exit state, in 0..N-1 28463 State - structure stores algorithm state 28466 Copyright 23.05.2010 by Bochkanov Sergey 28467 *************************************************************************/ 28468 void mcpdcreateentryexit(ae_int_t n, 28469 ae_int_t entrystate, 28470 ae_int_t exitstate, 28475 _mcpdstate_clear(s); 28477 ae_assert(n>=2, "MCPDCreateEntryExit: N<2
", _state); 28478 ae_assert(entrystate>=0, "MCPDCreateEntryExit: EntryState<0
", _state); 28479 ae_assert(entrystate<n, "MCPDCreateEntryExit: EntryState>=N
", _state); 28480 ae_assert(exitstate>=0, "MCPDCreateEntryExit: ExitState<0
", _state); 28481 ae_assert(exitstate<n, "MCPDCreateEntryExit: ExitState>=N
", _state); 28482 ae_assert(entrystate!=exitstate, "MCPDCreateEntryExit: EntryState=ExitState
", _state); 28483 mcpd_mcpdinit(n, entrystate, exitstate, s, _state); 28487 /************************************************************************* 28488 This function is used to add a track - sequence of system states at the 28489 different moments of its evolution. 28491 You may add one or several tracks to the MCPD solver. In case you have 28492 several tracks, they won't overwrite each other. For example, if you pass 28493 two tracks, A1-A2-A3 (system at t=A+1, t=A+2 and t=A+3) and B1-B2-B3, then 28494 solver will try to model transitions from t=A+1 to t=A+2, t=A+2 to t=A+3, 28495 t=B+1 to t=B+2, t=B+2 to t=B+3. But it WON'T mix these two tracks - i.e. it 28496 won't try to model transition from t=A+3 to t=B+1. 28500 XY - track, array[K,N]: 28501 * I-th row is a state at t=I 28502 * elements of XY must be non-negative (exception will be 28503 thrown on negative elements) 28504 K - number of points in a track 28505 * if given, only leading K rows of XY are used 28506 * if not given, automatically determined from size of XY 28510 1. Track may contain either proportional or population data: 28511 * with proportional data all rows of XY must sum to 1.0, i.e. we have 28512 proportions instead of absolute population values 28513 * with population data rows of XY contain population counts and generally 28514 do not sum to 1.0 (although they still must be non-negative) 28517 Copyright 23.05.2010 by Bochkanov Sergey 28518 *************************************************************************/ 28519 void mcpdaddtrack(mcpdstate* s, 28520 /* Real */ ae_matrix* xy, 28532 ae_assert(k>=0, "MCPDAddTrack:
K<0
", _state); 28533 ae_assert(xy->cols>=n, "MCPDAddTrack: Cols(XY)<N
", _state); 28534 ae_assert(xy->rows>=k, "MCPDAddTrack: Rows(XY)<
K", _state); 28535 ae_assert(apservisfinitematrix(xy, k, n, _state), "MCPDAddTrack: XY contains infinite
or NaN elements
", _state); 28536 for(i=0; i<=k-1; i++) 28538 for(j=0; j<=n-1; j++) 28540 ae_assert(ae_fp_greater_eq(xy->ptr.pp_double[i][j],0), "MCPDAddTrack: XY contains negative elements
", _state); 28547 if( s->data.rows<s->npairs+k-1 ) 28549 rmatrixresize(&s->data, ae_maxint(2*s->data.rows, s->npairs+k-1, _state), 2*n, _state); 28551 for(i=0; i<=k-2; i++) 28555 for(j=0; j<=n-1; j++) 28557 if( s->states.ptr.p_int[j]>=0 ) 28559 s0 = s0+xy->ptr.pp_double[i][j]; 28561 if( s->states.ptr.p_int[j]<=0 ) 28563 s1 = s1+xy->ptr.pp_double[i+1][j]; 28566 if( ae_fp_greater(s0,0)&&ae_fp_greater(s1,0) ) 28568 for(j=0; j<=n-1; j++) 28570 if( s->states.ptr.p_int[j]>=0 ) 28572 s->data.ptr.pp_double[s->npairs][j] = xy->ptr.pp_double[i][j]/s0; 28576 s->data.ptr.pp_double[s->npairs][j] = 0.0; 28578 if( s->states.ptr.p_int[j]<=0 ) 28580 s->data.ptr.pp_double[s->npairs][n+j] = xy->ptr.pp_double[i+1][j]/s1; 28584 s->data.ptr.pp_double[s->npairs][n+j] = 0.0; 28587 s->npairs = s->npairs+1; 28593 /************************************************************************* 28594 This function is used to add equality constraints on the elements of the 28595 transition matrix P. 28597 MCPD solver has four types of constraints which can be placed on P: 28598 * user-specified equality constraints (optional) 28599 * user-specified bound constraints (optional) 28600 * user-specified general linear constraints (optional) 28601 * basic constraints (always present): 28602 * non-negativity: P[i,j]>=0 28603 * consistency: every column of P sums to 1.0 28605 Final constraints which are passed to the underlying optimizer are 28606 calculated as intersection of all present constraints. For example, you 28607 may specify boundary constraint on P[0,0] and equality one: 28610 Such combination of constraints will be silently reduced to their 28611 intersection, which is P[0,0]=0.5. 28613 This function can be used to place equality constraints on arbitrary 28614 subset of elements of P. Set of constraints is specified by EC, which may 28615 contain either NAN's or finite numbers from [0,1]. NAN denotes absence of 28616 constraint, finite number denotes equality constraint on specific element 28619 You can also use MCPDAddEC() function which allows to ADD equality 28620 constraint for one element of P without changing constraints for other 28623 These functions (MCPDSetEC and MCPDAddEC) interact as follows: 28624 * there is internal matrix of equality constraints which is stored in the 28626 * MCPDSetEC() replaces this matrix by another one (SET) 28627 * MCPDAddEC() modifies one element of this matrix and leaves other ones 28629 * thus MCPDAddEC() call preserves all modifications done by previous 28630 calls, while MCPDSetEC() completely discards all changes done to the 28631 equality constraints. 28635 EC - equality constraints, array[N,N]. Elements of EC can be 28636 either NAN's or finite numbers from [0,1]. NAN denotes 28637 absence of constraints, while finite value denotes 28638 equality constraint on the corresponding element of P. 28642 1. infinite values of EC will lead to exception being thrown. Values less 28643 than 0.0 or greater than 1.0 will lead to error code being returned after 28644 call to MCPDSolve(). 28647 Copyright 23.05.2010 by Bochkanov Sergey 28648 *************************************************************************/ 28649 void mcpdsetec(mcpdstate* s, 28650 /* Real */ ae_matrix* ec, 28659 ae_assert(ec->cols>=n, "MCPDSetEC: Cols(EC)<N
", _state); 28660 ae_assert(ec->rows>=n, "MCPDSetEC: Rows(EC)<N
", _state); 28661 for(i=0; i<=n-1; i++) 28663 for(j=0; j<=n-1; j++) 28665 ae_assert(ae_isfinite(ec->ptr.pp_double[i][j], _state)||ae_isnan(ec->ptr.pp_double[i][j], _state), "MCPDSetEC: EC containts infinite elements
", _state); 28666 s->ec.ptr.pp_double[i][j] = ec->ptr.pp_double[i][j]; 28672 /************************************************************************* 28673 This function is used to add equality constraints on the elements of the 28674 transition matrix P. 28676 MCPD solver has four types of constraints which can be placed on P: 28677 * user-specified equality constraints (optional) 28678 * user-specified bound constraints (optional) 28679 * user-specified general linear constraints (optional) 28680 * basic constraints (always present): 28681 * non-negativity: P[i,j]>=0 28682 * consistency: every column of P sums to 1.0 28684 Final constraints which are passed to the underlying optimizer are 28685 calculated as intersection of all present constraints. For example, you 28686 may specify boundary constraint on P[0,0] and equality one: 28689 Such combination of constraints will be silently reduced to their 28690 intersection, which is P[0,0]=0.5. 28692 This function can be used to ADD equality constraint for one element of P 28693 without changing constraints for other elements. 28695 You can also use MCPDSetEC() function which allows you to specify 28696 arbitrary set of equality constraints in one call. 28698 These functions (MCPDSetEC and MCPDAddEC) interact as follows: 28699 * there is internal matrix of equality constraints which is stored in the 28701 * MCPDSetEC() replaces this matrix by another one (SET) 28702 * MCPDAddEC() modifies one element of this matrix and leaves other ones 28704 * thus MCPDAddEC() call preserves all modifications done by previous 28705 calls, while MCPDSetEC() completely discards all changes done to the 28706 equality constraints. 28710 I - row index of element being constrained 28711 J - column index of element being constrained 28712 C - value (constraint for P[I,J]). Can be either NAN (no 28713 constraint) or finite value from [0,1]. 28717 1. infinite values of C will lead to exception being thrown. Values less 28718 than 0.0 or greater than 1.0 will lead to error code being returned after 28719 call to MCPDSolve(). 28722 Copyright 23.05.2010 by Bochkanov Sergey 28723 *************************************************************************/ 28724 void mcpdaddec(mcpdstate* s, 28732 ae_assert(i>=0, "MCPDAddEC: I<0
", _state); 28733 ae_assert(i<s->n, "MCPDAddEC: I>=N
", _state); 28734 ae_assert(j>=0, "MCPDAddEC: J<0
", _state); 28735 ae_assert(j<s->n, "MCPDAddEC: J>=N
", _state); 28736 ae_assert(ae_isnan(c, _state)||ae_isfinite(c, _state), "MCPDAddEC: C is not finite number
or NAN
", _state); 28737 s->ec.ptr.pp_double[i][j] = c; 28741 /************************************************************************* 28742 This function is used to add bound constraints on the elements of the 28743 transition matrix P. 28745 MCPD solver has four types of constraints which can be placed on P: 28746 * user-specified equality constraints (optional) 28747 * user-specified bound constraints (optional) 28748 * user-specified general linear constraints (optional) 28749 * basic constraints (always present): 28750 * non-negativity: P[i,j]>=0 28751 * consistency: every column of P sums to 1.0 28753 Final constraints which are passed to the underlying optimizer are 28754 calculated as intersection of all present constraints. For example, you 28755 may specify boundary constraint on P[0,0] and equality one: 28758 Such combination of constraints will be silently reduced to their 28759 intersection, which is P[0,0]=0.5. 28761 This function can be used to place bound constraints on arbitrary 28762 subset of elements of P. Set of constraints is specified by BndL/BndU 28763 matrices, which may contain arbitrary combination of finite numbers or 28764 infinities (like -INF<x<=0.5 or 0.1<=x<+INF). 28766 You can also use MCPDAddBC() function which allows to ADD bound constraint 28767 for one element of P without changing constraints for other elements. 28769 These functions (MCPDSetBC and MCPDAddBC) interact as follows: 28770 * there is internal matrix of bound constraints which is stored in the 28772 * MCPDSetBC() replaces this matrix by another one (SET) 28773 * MCPDAddBC() modifies one element of this matrix and leaves other ones 28775 * thus MCPDAddBC() call preserves all modifications done by previous 28776 calls, while MCPDSetBC() completely discards all changes done to the 28777 equality constraints. 28781 BndL - lower bounds constraints, array[N,N]. Elements of BndL can 28782 be finite numbers or -INF. 28783 BndU - upper bounds constraints, array[N,N]. Elements of BndU can 28784 be finite numbers or +INF. 28787 Copyright 23.05.2010 by Bochkanov Sergey 28788 *************************************************************************/ 28789 void mcpdsetbc(mcpdstate* s, 28790 /* Real */ ae_matrix* bndl, 28791 /* Real */ ae_matrix* bndu, 28800 ae_assert(bndl->cols>=n, "MCPDSetBC: Cols(BndL)<N
", _state); 28801 ae_assert(bndl->rows>=n, "MCPDSetBC: Rows(BndL)<N
", _state); 28802 ae_assert(bndu->cols>=n, "MCPDSetBC: Cols(BndU)<N
", _state); 28803 ae_assert(bndu->rows>=n, "MCPDSetBC: Rows(BndU)<N
", _state); 28804 for(i=0; i<=n-1; i++) 28806 for(j=0; j<=n-1; j++) 28808 ae_assert(ae_isfinite(bndl->ptr.pp_double[i][j], _state)||ae_isneginf(bndl->ptr.pp_double[i][j], _state), "MCPDSetBC: BndL containts NAN
or +
INF", _state); 28809 ae_assert(ae_isfinite(bndu->ptr.pp_double[i][j], _state)||ae_isposinf(bndu->ptr.pp_double[i][j], _state), "MCPDSetBC: BndU containts NAN
or -
INF", _state); 28810 s->bndl.ptr.pp_double[i][j] = bndl->ptr.pp_double[i][j]; 28811 s->bndu.ptr.pp_double[i][j] = bndu->ptr.pp_double[i][j]; 28817 /************************************************************************* 28818 This function is used to add bound constraints on the elements of the 28819 transition matrix P. 28821 MCPD solver has four types of constraints which can be placed on P: 28822 * user-specified equality constraints (optional) 28823 * user-specified bound constraints (optional) 28824 * user-specified general linear constraints (optional) 28825 * basic constraints (always present): 28826 * non-negativity: P[i,j]>=0 28827 * consistency: every column of P sums to 1.0 28829 Final constraints which are passed to the underlying optimizer are 28830 calculated as intersection of all present constraints. For example, you 28831 may specify boundary constraint on P[0,0] and equality one: 28834 Such combination of constraints will be silently reduced to their 28835 intersection, which is P[0,0]=0.5. 28837 This function can be used to ADD bound constraint for one element of P 28838 without changing constraints for other elements. 28840 You can also use MCPDSetBC() function which allows to place bound 28841 constraints on arbitrary subset of elements of P. Set of constraints is 28842 specified by BndL/BndU matrices, which may contain arbitrary combination 28843 of finite numbers or infinities (like -INF<x<=0.5 or 0.1<=x<+INF). 28845 These functions (MCPDSetBC and MCPDAddBC) interact as follows: 28846 * there is internal matrix of bound constraints which is stored in the 28848 * MCPDSetBC() replaces this matrix by another one (SET) 28849 * MCPDAddBC() modifies one element of this matrix and leaves other ones 28851 * thus MCPDAddBC() call preserves all modifications done by previous 28852 calls, while MCPDSetBC() completely discards all changes done to the 28853 equality constraints. 28857 I - row index of element being constrained 28858 J - column index of element being constrained 28863 Copyright 23.05.2010 by Bochkanov Sergey 28864 *************************************************************************/ 28865 void mcpdaddbc(mcpdstate* s, 28874 ae_assert(i>=0, "MCPDAddBC: I<0
", _state); 28875 ae_assert(i<s->n, "MCPDAddBC: I>=N
", _state); 28876 ae_assert(j>=0, "MCPDAddBC: J<0
", _state); 28877 ae_assert(j<s->n, "MCPDAddBC: J>=N
", _state); 28878 ae_assert(ae_isfinite(bndl, _state)||ae_isneginf(bndl, _state), "MCPDAddBC: BndL is NAN
or +
INF", _state); 28879 ae_assert(ae_isfinite(bndu, _state)||ae_isposinf(bndu, _state), "MCPDAddBC: BndU is NAN
or -
INF", _state); 28880 s->bndl.ptr.pp_double[i][j] = bndl; 28881 s->bndu.ptr.pp_double[i][j] = bndu; 28885 /************************************************************************* 28886 This function is used to set linear equality/inequality constraints on the 28887 elements of the transition matrix P. 28889 This function can be used to set one or several general linear constraints 28890 on the elements of P. Two types of constraints are supported: 28891 * equality constraints 28892 * inequality constraints (both less-or-equal and greater-or-equal) 28894 Coefficients of constraints are specified by matrix C (one of the 28895 parameters). One row of C corresponds to one constraint. Because 28896 transition matrix P has N*N elements, we need N*N columns to store all 28897 coefficients (they are stored row by row), and one more column to store 28898 right part - hence C has N*N+1 columns. Constraint kind is stored in the 28901 Thus, I-th linear constraint is 28902 P[0,0]*C[I,0] + P[0,1]*C[I,1] + .. + P[0,N-1]*C[I,N-1] + 28903 + P[1,0]*C[I,N] + P[1,1]*C[I,N+1] + ... + 28904 + P[N-1,N-1]*C[I,N*N-1] ?=? C[I,N*N] 28905 where ?=? can be either "=
" (CT[i]=0), "<=
" (CT[i]<0) or ">=
" (CT[i]>0). 28907 Your constraint may involve only some subset of P (less than N*N elements). 28908 For example it can be something like 28909 P[0,0] + P[0,1] = 0.5 28910 In this case you still should pass matrix with N*N+1 columns, but all its 28911 elements (except for C[0,0], C[0,1] and C[0,N*N-1]) will be zero. 28915 C - array[K,N*N+1] - coefficients of constraints 28916 (see above for complete description) 28917 CT - array[K] - constraint types 28918 (see above for complete description) 28919 K - number of equality/inequality constraints, K>=0: 28920 * if given, only leading K elements of C/CT are used 28921 * if not given, automatically determined from sizes of C/CT 28924 Copyright 23.05.2010 by Bochkanov Sergey 28925 *************************************************************************/ 28926 void mcpdsetlc(mcpdstate* s, 28927 /* Real */ ae_matrix* c, 28928 /* Integer */ ae_vector* ct, 28938 ae_assert(c->cols>=n*n+1, "MCPDSetLC: Cols(C)<N*N+1
", _state); 28939 ae_assert(c->rows>=k, "MCPDSetLC: Rows(C)<
K", _state); 28940 ae_assert(ct->cnt>=k, "MCPDSetLC: Len(CT)<
K", _state); 28941 ae_assert(apservisfinitematrix(c, k, n*n+1, _state), "MCPDSetLC: C contains infinite
or NaN values!
", _state); 28942 rmatrixsetlengthatleast(&s->c, k, n*n+1, _state); 28943 ivectorsetlengthatleast(&s->ct, k, _state); 28944 for(i=0; i<=k-1; i++) 28946 for(j=0; j<=n*n; j++) 28948 s->c.ptr.pp_double[i][j] = c->ptr.pp_double[i][j]; 28950 s->ct.ptr.p_int[i] = ct->ptr.p_int[i]; 28956 /************************************************************************* 28957 This function allows to tune amount of Tikhonov regularization being 28958 applied to your problem. 28960 By default, regularizing term is equal to r*||P-prior_P||^2, where r is a 28961 small non-zero value, P is transition matrix, prior_P is identity matrix, 28962 ||X||^2 is a sum of squared elements of X. 28964 This function allows you to change coefficient r. You can also change 28965 prior values with MCPDSetPrior() function. 28969 V - regularization coefficient, finite non-negative value. It 28970 is not recommended to specify zero value unless you are 28971 pretty sure that you want it. 28974 Copyright 23.05.2010 by Bochkanov Sergey 28975 *************************************************************************/ 28976 void mcpdsettikhonovregularizer(mcpdstate* s, double v, ae_state *_state) 28980 ae_assert(ae_isfinite(v, _state), "MCPDSetTikhonovRegularizer: V is infinite
or NAN
", _state); 28981 ae_assert(ae_fp_greater_eq(v,0.0), "MCPDSetTikhonovRegularizer: V is less than
zero", _state); 28986 /************************************************************************* 28987 This function allows to set prior values used for regularization of your 28990 By default, regularizing term is equal to r*||P-prior_P||^2, where r is a 28991 small non-zero value, P is transition matrix, prior_P is identity matrix, 28992 ||X||^2 is a sum of squared elements of X. 28994 This function allows you to change prior values prior_P. You can also 28995 change r with MCPDSetTikhonovRegularizer() function. 28999 PP - array[N,N], matrix of prior values: 29000 1. elements must be real numbers from [0,1] 29001 2. columns must sum to 1.0. 29002 First property is checked (exception is thrown otherwise), 29003 while second one is not checked/enforced. 29006 Copyright 23.05.2010 by Bochkanov Sergey 29007 *************************************************************************/ 29008 void mcpdsetprior(mcpdstate* s, 29009 /* Real */ ae_matrix* pp, 29012 ae_frame _frame_block; 29018 ae_frame_make(_state, &_frame_block); 29019 ae_matrix_init_copy(&_pp, pp, _state, ae_true); 29023 ae_assert(pp->cols>=n, "MCPDSetPrior: Cols(PP)<N
", _state); 29024 ae_assert(pp->rows>=n, "MCPDSetPrior: Rows(PP)<
K", _state); 29025 for(i=0; i<=n-1; i++) 29027 for(j=0; j<=n-1; j++) 29029 ae_assert(ae_isfinite(pp->ptr.pp_double[i][j], _state), "MCPDSetPrior: PP containts infinite elements
", _state); 29030 ae_assert(ae_fp_greater_eq(pp->ptr.pp_double[i][j],0.0)&&ae_fp_less_eq(pp->ptr.pp_double[i][j],1.0), "MCPDSetPrior: PP[i,
j] is less than 0.0
or greater than 1.0
", _state); 29031 s->priorp.ptr.pp_double[i][j] = pp->ptr.pp_double[i][j]; 29034 ae_frame_leave(_state); 29038 /************************************************************************* 29039 This function is used to change prediction weights 29041 MCPD solver scales prediction errors as follows 29042 Error(P) = ||W*(y-P*x)||^2 29044 x is a system state at time t 29045 y is a system state at time t+1 29046 P is a transition matrix 29047 W is a diagonal scaling matrix 29049 By default, weights are chosen in order to minimize relative prediction 29050 error instead of absolute one. For example, if one component of state is 29051 about 0.5 in magnitude and another one is about 0.05, then algorithm will 29052 make corresponding weights equal to 2.0 and 20.0. 29056 PW - array[N], weights: 29057 * must be non-negative values (exception will be thrown otherwise) 29058 * zero values will be replaced by automatically chosen values 29061 Copyright 23.05.2010 by Bochkanov Sergey 29062 *************************************************************************/ 29063 void mcpdsetpredictionweights(mcpdstate* s, 29064 /* Real */ ae_vector* pw, 29072 ae_assert(pw->cnt>=n, "MCPDSetPredictionWeights: Length(PW)<N
", _state); 29073 for(i=0; i<=n-1; i++) 29075 ae_assert(ae_isfinite(pw->ptr.p_double[i], _state), "MCPDSetPredictionWeights: PW containts infinite
or NAN elements
", _state); 29076 ae_assert(ae_fp_greater_eq(pw->ptr.p_double[i],0), "MCPDSetPredictionWeights: PW containts negative elements
", _state); 29077 s->pw.ptr.p_double[i] = pw->ptr.p_double[i]; 29082 /************************************************************************* 29083 This function is used to start solution of the MCPD problem. 29085 After return from this function, you can use MCPDResults() to get solution 29086 and completion code. 29089 Copyright 23.05.2010 by Bochkanov Sergey 29090 *************************************************************************/ 29091 void mcpdsolve(mcpdstate* s, ae_state *_state) 29105 npairs = s->npairs; 29110 s->repterminationtype = 0; 29111 s->repinneriterationscount = 0; 29112 s->repouteriterationscount = 0; 29114 for(k=0; k<=n-1; k++) 29116 for(k2=0; k2<=n-1; k2++) 29118 s->p.ptr.pp_double[k][k2] = _state->v_nan; 29123 * Generate "effective
" weights for prediction and calculate preconditioner 29125 for(i=0; i<=n-1; i++) 29127 if( ae_fp_eq(s->pw.ptr.p_double[i],0) ) 29131 for(j=0; j<=npairs-1; j++) 29133 if( ae_fp_neq(s->data.ptr.pp_double[j][n+i],0) ) 29135 v = v+s->data.ptr.pp_double[j][n+i]; 29141 s->effectivew.ptr.p_double[i] = k/v; 29145 s->effectivew.ptr.p_double[i] = 1.0; 29150 s->effectivew.ptr.p_double[i] = s->pw.ptr.p_double[i]; 29153 for(i=0; i<=n-1; i++) 29155 for(j=0; j<=n-1; j++) 29157 s->h.ptr.p_double[i*n+j] = 2*s->regterm; 29160 for(k=0; k<=npairs-1; k++) 29162 for(i=0; i<=n-1; i++) 29164 for(j=0; j<=n-1; j++) 29166 s->h.ptr.p_double[i*n+j] = s->h.ptr.p_double[i*n+j]+2*ae_sqr(s->effectivew.ptr.p_double[i], _state)*ae_sqr(s->data.ptr.pp_double[k][j], _state); 29170 for(i=0; i<=n-1; i++) 29172 for(j=0; j<=n-1; j++) 29174 if( ae_fp_eq(s->h.ptr.p_double[i*n+j],0) ) 29176 s->h.ptr.p_double[i*n+j] = 1; 29182 * Generate "effective
" BndL/BndU 29184 for(i=0; i<=n-1; i++) 29186 for(j=0; j<=n-1; j++) 29190 * Set default boundary constraints. 29191 * Lower bound is always zero, upper bound is calculated 29192 * with respect to entry/exit states. 29194 s->effectivebndl.ptr.p_double[i*n+j] = 0.0; 29195 if( s->states.ptr.p_int[i]>0||s->states.ptr.p_int[j]<0 ) 29197 s->effectivebndu.ptr.p_double[i*n+j] = 0.0; 29201 s->effectivebndu.ptr.p_double[i*n+j] = 1.0; 29205 * Calculate intersection of the default and user-specified bound constraints. 29206 * This code checks consistency of such combination. 29208 if( ae_isfinite(s->bndl.ptr.pp_double[i][j], _state)&&ae_fp_greater(s->bndl.ptr.pp_double[i][j],s->effectivebndl.ptr.p_double[i*n+j]) ) 29210 s->effectivebndl.ptr.p_double[i*n+j] = s->bndl.ptr.pp_double[i][j]; 29212 if( ae_isfinite(s->bndu.ptr.pp_double[i][j], _state)&&ae_fp_less(s->bndu.ptr.pp_double[i][j],s->effectivebndu.ptr.p_double[i*n+j]) ) 29214 s->effectivebndu.ptr.p_double[i*n+j] = s->bndu.ptr.pp_double[i][j]; 29216 if( ae_fp_greater(s->effectivebndl.ptr.p_double[i*n+j],s->effectivebndu.ptr.p_double[i*n+j]) ) 29218 s->repterminationtype = -3; 29223 * Calculate intersection of the effective bound constraints 29224 * and user-specified equality constraints. 29225 * This code checks consistency of such combination. 29227 if( ae_isfinite(s->ec.ptr.pp_double[i][j], _state) ) 29229 if( ae_fp_less(s->ec.ptr.pp_double[i][j],s->effectivebndl.ptr.p_double[i*n+j])||ae_fp_greater(s->ec.ptr.pp_double[i][j],s->effectivebndu.ptr.p_double[i*n+j]) ) 29231 s->repterminationtype = -3; 29234 s->effectivebndl.ptr.p_double[i*n+j] = s->ec.ptr.pp_double[i][j]; 29235 s->effectivebndu.ptr.p_double[i*n+j] = s->ec.ptr.pp_double[i][j]; 29241 * Generate linear constraints: 29242 * * "default" sums-to-one constraints (not generated for "exit
" states) 29244 rmatrixsetlengthatleast(&s->effectivec, s->ccnt+n, n*n+1, _state); 29245 ivectorsetlengthatleast(&s->effectivect, s->ccnt+n, _state); 29247 for(i=0; i<=s->ccnt-1; i++) 29249 for(j=0; j<=n*n; j++) 29251 s->effectivec.ptr.pp_double[i][j] = s->c.ptr.pp_double[i][j]; 29253 s->effectivect.ptr.p_int[i] = s->ct.ptr.p_int[i]; 29255 for(i=0; i<=n-1; i++) 29257 if( s->states.ptr.p_int[i]>=0 ) 29259 for(k=0; k<=n*n-1; k++) 29261 s->effectivec.ptr.pp_double[ccnt][k] = 0; 29263 for(k=0; k<=n-1; k++) 29265 s->effectivec.ptr.pp_double[ccnt][k*n+i] = 1; 29267 s->effectivec.ptr.pp_double[ccnt][n*n] = 1.0; 29268 s->effectivect.ptr.p_int[ccnt] = 0; 29276 for(i=0; i<=n-1; i++) 29278 for(j=0; j<=n-1; j++) 29280 s->tmpp.ptr.p_double[i*n+j] = (double)1/(double)n; 29283 minbleicrestartfrom(&s->bs, &s->tmpp, _state); 29284 minbleicsetbc(&s->bs, &s->effectivebndl, &s->effectivebndu, _state); 29285 minbleicsetlc(&s->bs, &s->effectivec, &s->effectivect, ccnt, _state); 29286 minbleicsetcond(&s->bs, 0.0, 0.0, mcpd_xtol, 0, _state); 29287 minbleicsetprecdiag(&s->bs, &s->h, _state); 29292 while(minbleiciteration(&s->bs, _state)) 29294 ae_assert(s->bs.needfg, "MCPDSolve:
internal error", _state); 29299 * Calculate regularization term 29303 for(i=0; i<=n-1; i++) 29305 for(j=0; j<=n-1; j++) 29307 s->bs.f = s->bs.f+vv*ae_sqr(s->bs.x.ptr.p_double[i*n+j]-s->priorp.ptr.pp_double[i][j], _state); 29308 s->bs.g.ptr.p_double[i*n+j] = 2*vv*(s->bs.x.ptr.p_double[i*n+j]-s->priorp.ptr.pp_double[i][j]); 29313 * calculate prediction error/gradient for K-th pair 29315 for(k=0; k<=npairs-1; k++) 29317 for(i=0; i<=n-1; i++) 29319 v = ae_v_dotproduct(&s->bs.x.ptr.p_double[i*n], 1, &s->data.ptr.pp_double[k][0], 1, ae_v_len(i*n,i*n+n-1)); 29320 vv = s->effectivew.ptr.p_double[i]; 29321 s->bs.f = s->bs.f+ae_sqr(vv*(v-s->data.ptr.pp_double[k][n+i]), _state); 29322 for(j=0; j<=n-1; j++) 29324 s->bs.g.ptr.p_double[i*n+j] = s->bs.g.ptr.p_double[i*n+j]+2*vv*vv*(v-s->data.ptr.pp_double[k][n+i])*s->data.ptr.pp_double[k][j]; 29335 minbleicresultsbuf(&s->bs, &s->tmpp, &s->br, _state); 29336 for(i=0; i<=n-1; i++) 29338 for(j=0; j<=n-1; j++) 29340 s->p.ptr.pp_double[i][j] = s->tmpp.ptr.p_double[i*n+j]; 29343 s->repterminationtype = s->br.terminationtype; 29344 s->repinneriterationscount = s->br.inneriterationscount; 29345 s->repouteriterationscount = s->br.outeriterationscount; 29346 s->repnfev = s->br.nfev; 29350 /************************************************************************* 29354 State - algorithm state 29357 P - array[N,N], transition matrix 29358 Rep - optimization report. You should check Rep.TerminationType 29359 in order to distinguish successful termination from 29360 unsuccessful one. Speaking short, positive values denote 29361 success, negative ones are failures. 29362 More information about fields of this structure can be 29363 found in the comments on MCPDReport datatype. 29367 Copyright 23.05.2010 by Bochkanov Sergey 29368 *************************************************************************/ 29369 void mcpdresults(mcpdstate* s, 29370 /* Real */ ae_matrix* p, 29377 ae_matrix_clear(p); 29378 _mcpdreport_clear(rep); 29380 ae_matrix_set_length(p, s->n, s->n, _state); 29381 for(i=0; i<=s->n-1; i++) 29383 for(j=0; j<=s->n-1; j++) 29385 p->ptr.pp_double[i][j] = s->p.ptr.pp_double[i][j]; 29388 rep->terminationtype = s->repterminationtype; 29389 rep->inneriterationscount = s->repinneriterationscount; 29390 rep->outeriterationscount = s->repouteriterationscount; 29391 rep->nfev = s->repnfev; 29395 /************************************************************************* 29396 Internal initialization function 29399 Copyright 23.05.2010 by Bochkanov Sergey 29400 *************************************************************************/ 29401 static void mcpd_mcpdinit(ae_int_t n, 29402 ae_int_t entrystate, 29403 ae_int_t exitstate, 29411 ae_assert(n>=1, "MCPDCreate: N<1
", _state); 29413 ae_vector_set_length(&s->states, n, _state); 29414 for(i=0; i<=n-1; i++) 29416 s->states.ptr.p_int[i] = 0; 29418 if( entrystate>=0 ) 29420 s->states.ptr.p_int[entrystate] = 1; 29424 s->states.ptr.p_int[exitstate] = -1; 29427 s->regterm = 1.0E-8; 29429 ae_matrix_set_length(&s->p, n, n, _state); 29430 ae_matrix_set_length(&s->ec, n, n, _state); 29431 ae_matrix_set_length(&s->bndl, n, n, _state); 29432 ae_matrix_set_length(&s->bndu, n, n, _state); 29433 ae_vector_set_length(&s->pw, n, _state); 29434 ae_matrix_set_length(&s->priorp, n, n, _state); 29435 ae_vector_set_length(&s->tmpp, n*n, _state); 29436 ae_vector_set_length(&s->effectivew, n, _state); 29437 ae_vector_set_length(&s->effectivebndl, n*n, _state); 29438 ae_vector_set_length(&s->effectivebndu, n*n, _state); 29439 ae_vector_set_length(&s->h, n*n, _state); 29440 for(i=0; i<=n-1; i++) 29442 for(j=0; j<=n-1; j++) 29444 s->p.ptr.pp_double[i][j] = 0.0; 29445 s->priorp.ptr.pp_double[i][j] = 0.0; 29446 s->bndl.ptr.pp_double[i][j] = _state->v_neginf; 29447 s->bndu.ptr.pp_double[i][j] = _state->v_posinf; 29448 s->ec.ptr.pp_double[i][j] = _state->v_nan; 29450 s->pw.ptr.p_double[i] = 0.0; 29451 s->priorp.ptr.pp_double[i][i] = 1.0; 29453 ae_matrix_set_length(&s->data, 1, 2*n, _state); 29454 for(i=0; i<=2*n-1; i++) 29456 s->data.ptr.pp_double[0][i] = 0.0; 29458 for(i=0; i<=n*n-1; i++) 29460 s->tmpp.ptr.p_double[i] = 0.0; 29462 minbleiccreate(n*n, &s->tmpp, &s->bs, _state); 29466 ae_bool _mcpdstate_init(void* _p, ae_state *_state, ae_bool make_automatic) 29468 mcpdstate *p = (mcpdstate*)_p; 29469 ae_touch_ptr((void*)p); 29470 if( !ae_vector_init(&p->states, 0, DT_INT, _state, make_automatic) ) 29472 if( !ae_matrix_init(&p->data, 0, 0, DT_REAL, _state, make_automatic) ) 29474 if( !ae_matrix_init(&p->ec, 0, 0, DT_REAL, _state, make_automatic) ) 29476 if( !ae_matrix_init(&p->bndl, 0, 0, DT_REAL, _state, make_automatic) ) 29478 if( !ae_matrix_init(&p->bndu, 0, 0, DT_REAL, _state, make_automatic) ) 29480 if( !ae_matrix_init(&p->c, 0, 0, DT_REAL, _state, make_automatic) ) 29482 if( !ae_vector_init(&p->ct, 0, DT_INT, _state, make_automatic) ) 29484 if( !ae_vector_init(&p->pw, 0, DT_REAL, _state, make_automatic) ) 29486 if( !ae_matrix_init(&p->priorp, 0, 0, DT_REAL, _state, make_automatic) ) 29488 if( !_minbleicstate_init(&p->bs, _state, make_automatic) ) 29490 if( !_minbleicreport_init(&p->br, _state, make_automatic) ) 29492 if( !ae_vector_init(&p->tmpp, 0, DT_REAL, _state, make_automatic) ) 29494 if( !ae_vector_init(&p->effectivew, 0, DT_REAL, _state, make_automatic) ) 29496 if( !ae_vector_init(&p->effectivebndl, 0, DT_REAL, _state, make_automatic) ) 29498 if( !ae_vector_init(&p->effectivebndu, 0, DT_REAL, _state, make_automatic) ) 29500 if( !ae_matrix_init(&p->effectivec, 0, 0, DT_REAL, _state, make_automatic) ) 29502 if( !ae_vector_init(&p->effectivect, 0, DT_INT, _state, make_automatic) ) 29504 if( !ae_vector_init(&p->h, 0, DT_REAL, _state, make_automatic) ) 29506 if( !ae_matrix_init(&p->p, 0, 0, DT_REAL, _state, make_automatic) ) 29512 ae_bool _mcpdstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 29514 mcpdstate *dst = (mcpdstate*)_dst; 29515 mcpdstate *src = (mcpdstate*)_src; 29517 if( !ae_vector_init_copy(&dst->states, &src->states, _state, make_automatic) ) 29519 dst->npairs = src->npairs; 29520 if( !ae_matrix_init_copy(&dst->data, &src->data, _state, make_automatic) ) 29522 if( !ae_matrix_init_copy(&dst->ec, &src->ec, _state, make_automatic) ) 29524 if( !ae_matrix_init_copy(&dst->bndl, &src->bndl, _state, make_automatic) ) 29526 if( !ae_matrix_init_copy(&dst->bndu, &src->bndu, _state, make_automatic) ) 29528 if( !ae_matrix_init_copy(&dst->c, &src->c, _state, make_automatic) ) 29530 if( !ae_vector_init_copy(&dst->ct, &src->ct, _state, make_automatic) ) 29532 dst->ccnt = src->ccnt; 29533 if( !ae_vector_init_copy(&dst->pw, &src->pw, _state, make_automatic) ) 29535 if( !ae_matrix_init_copy(&dst->priorp, &src->priorp, _state, make_automatic) ) 29537 dst->regterm = src->regterm; 29538 if( !_minbleicstate_init_copy(&dst->bs, &src->bs, _state, make_automatic) ) 29540 dst->repinneriterationscount = src->repinneriterationscount; 29541 dst->repouteriterationscount = src->repouteriterationscount; 29542 dst->repnfev = src->repnfev; 29543 dst->repterminationtype = src->repterminationtype; 29544 if( !_minbleicreport_init_copy(&dst->br, &src->br, _state, make_automatic) ) 29546 if( !ae_vector_init_copy(&dst->tmpp, &src->tmpp, _state, make_automatic) ) 29548 if( !ae_vector_init_copy(&dst->effectivew, &src->effectivew, _state, make_automatic) ) 29550 if( !ae_vector_init_copy(&dst->effectivebndl, &src->effectivebndl, _state, make_automatic) ) 29552 if( !ae_vector_init_copy(&dst->effectivebndu, &src->effectivebndu, _state, make_automatic) ) 29554 if( !ae_matrix_init_copy(&dst->effectivec, &src->effectivec, _state, make_automatic) ) 29556 if( !ae_vector_init_copy(&dst->effectivect, &src->effectivect, _state, make_automatic) ) 29558 if( !ae_vector_init_copy(&dst->h, &src->h, _state, make_automatic) ) 29560 if( !ae_matrix_init_copy(&dst->p, &src->p, _state, make_automatic) ) 29566 void _mcpdstate_clear(void* _p) 29568 mcpdstate *p = (mcpdstate*)_p; 29569 ae_touch_ptr((void*)p); 29570 ae_vector_clear(&p->states); 29571 ae_matrix_clear(&p->data); 29572 ae_matrix_clear(&p->ec); 29573 ae_matrix_clear(&p->bndl); 29574 ae_matrix_clear(&p->bndu); 29575 ae_matrix_clear(&p->c); 29576 ae_vector_clear(&p->ct); 29577 ae_vector_clear(&p->pw); 29578 ae_matrix_clear(&p->priorp); 29579 _minbleicstate_clear(&p->bs); 29580 _minbleicreport_clear(&p->br); 29581 ae_vector_clear(&p->tmpp); 29582 ae_vector_clear(&p->effectivew); 29583 ae_vector_clear(&p->effectivebndl); 29584 ae_vector_clear(&p->effectivebndu); 29585 ae_matrix_clear(&p->effectivec); 29586 ae_vector_clear(&p->effectivect); 29587 ae_vector_clear(&p->h); 29588 ae_matrix_clear(&p->p); 29592 void _mcpdstate_destroy(void* _p) 29594 mcpdstate *p = (mcpdstate*)_p; 29595 ae_touch_ptr((void*)p); 29596 ae_vector_destroy(&p->states); 29597 ae_matrix_destroy(&p->data); 29598 ae_matrix_destroy(&p->ec); 29599 ae_matrix_destroy(&p->bndl); 29600 ae_matrix_destroy(&p->bndu); 29601 ae_matrix_destroy(&p->c); 29602 ae_vector_destroy(&p->ct); 29603 ae_vector_destroy(&p->pw); 29604 ae_matrix_destroy(&p->priorp); 29605 _minbleicstate_destroy(&p->bs); 29606 _minbleicreport_destroy(&p->br); 29607 ae_vector_destroy(&p->tmpp); 29608 ae_vector_destroy(&p->effectivew); 29609 ae_vector_destroy(&p->effectivebndl); 29610 ae_vector_destroy(&p->effectivebndu); 29611 ae_matrix_destroy(&p->effectivec); 29612 ae_vector_destroy(&p->effectivect); 29613 ae_vector_destroy(&p->h); 29614 ae_matrix_destroy(&p->p); 29618 ae_bool _mcpdreport_init(void* _p, ae_state *_state, ae_bool make_automatic) 29620 mcpdreport *p = (mcpdreport*)_p; 29621 ae_touch_ptr((void*)p); 29626 ae_bool _mcpdreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 29628 mcpdreport *dst = (mcpdreport*)_dst; 29629 mcpdreport *src = (mcpdreport*)_src; 29630 dst->inneriterationscount = src->inneriterationscount; 29631 dst->outeriterationscount = src->outeriterationscount; 29632 dst->nfev = src->nfev; 29633 dst->terminationtype = src->terminationtype; 29638 void _mcpdreport_clear(void* _p) 29640 mcpdreport *p = (mcpdreport*)_p; 29641 ae_touch_ptr((void*)p); 29645 void _mcpdreport_destroy(void* _p) 29647 mcpdreport *p = (mcpdreport*)_p; 29648 ae_touch_ptr((void*)p); 29654 /************************************************************************* 29655 Like MLPCreate0, but for ensembles. 29658 Copyright 18.02.2009 by Bochkanov Sergey 29659 *************************************************************************/ 29660 void mlpecreate0(ae_int_t nin, 29662 ae_int_t ensemblesize, 29663 mlpensemble* ensemble, 29666 ae_frame _frame_block; 29667 multilayerperceptron net; 29669 ae_frame_make(_state, &_frame_block); 29670 _mlpensemble_clear(ensemble); 29671 _multilayerperceptron_init(&net, _state, ae_true); 29673 mlpcreate0(nin, nout, &net, _state); 29674 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29675 ae_frame_leave(_state); 29679 /************************************************************************* 29680 Like MLPCreate1, but for ensembles. 29683 Copyright 18.02.2009 by Bochkanov Sergey 29684 *************************************************************************/ 29685 void mlpecreate1(ae_int_t nin, 29688 ae_int_t ensemblesize, 29689 mlpensemble* ensemble, 29692 ae_frame _frame_block; 29693 multilayerperceptron net; 29695 ae_frame_make(_state, &_frame_block); 29696 _mlpensemble_clear(ensemble); 29697 _multilayerperceptron_init(&net, _state, ae_true); 29699 mlpcreate1(nin, nhid, nout, &net, _state); 29700 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29701 ae_frame_leave(_state); 29705 /************************************************************************* 29706 Like MLPCreate2, but for ensembles. 29709 Copyright 18.02.2009 by Bochkanov Sergey 29710 *************************************************************************/ 29711 void mlpecreate2(ae_int_t nin, 29715 ae_int_t ensemblesize, 29716 mlpensemble* ensemble, 29719 ae_frame _frame_block; 29720 multilayerperceptron net; 29722 ae_frame_make(_state, &_frame_block); 29723 _mlpensemble_clear(ensemble); 29724 _multilayerperceptron_init(&net, _state, ae_true); 29726 mlpcreate2(nin, nhid1, nhid2, nout, &net, _state); 29727 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29728 ae_frame_leave(_state); 29732 /************************************************************************* 29733 Like MLPCreateB0, but for ensembles. 29736 Copyright 18.02.2009 by Bochkanov Sergey 29737 *************************************************************************/ 29738 void mlpecreateb0(ae_int_t nin, 29742 ae_int_t ensemblesize, 29743 mlpensemble* ensemble, 29746 ae_frame _frame_block; 29747 multilayerperceptron net; 29749 ae_frame_make(_state, &_frame_block); 29750 _mlpensemble_clear(ensemble); 29751 _multilayerperceptron_init(&net, _state, ae_true); 29753 mlpcreateb0(nin, nout, b, d, &net, _state); 29754 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29755 ae_frame_leave(_state); 29759 /************************************************************************* 29760 Like MLPCreateB1, but for ensembles. 29763 Copyright 18.02.2009 by Bochkanov Sergey 29764 *************************************************************************/ 29765 void mlpecreateb1(ae_int_t nin, 29770 ae_int_t ensemblesize, 29771 mlpensemble* ensemble, 29774 ae_frame _frame_block; 29775 multilayerperceptron net; 29777 ae_frame_make(_state, &_frame_block); 29778 _mlpensemble_clear(ensemble); 29779 _multilayerperceptron_init(&net, _state, ae_true); 29781 mlpcreateb1(nin, nhid, nout, b, d, &net, _state); 29782 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29783 ae_frame_leave(_state); 29787 /************************************************************************* 29788 Like MLPCreateB2, but for ensembles. 29791 Copyright 18.02.2009 by Bochkanov Sergey 29792 *************************************************************************/ 29793 void mlpecreateb2(ae_int_t nin, 29799 ae_int_t ensemblesize, 29800 mlpensemble* ensemble, 29803 ae_frame _frame_block; 29804 multilayerperceptron net; 29806 ae_frame_make(_state, &_frame_block); 29807 _mlpensemble_clear(ensemble); 29808 _multilayerperceptron_init(&net, _state, ae_true); 29810 mlpcreateb2(nin, nhid1, nhid2, nout, b, d, &net, _state); 29811 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29812 ae_frame_leave(_state); 29816 /************************************************************************* 29817 Like MLPCreateR0, but for ensembles. 29820 Copyright 18.02.2009 by Bochkanov Sergey 29821 *************************************************************************/ 29822 void mlpecreater0(ae_int_t nin, 29826 ae_int_t ensemblesize, 29827 mlpensemble* ensemble, 29830 ae_frame _frame_block; 29831 multilayerperceptron net; 29833 ae_frame_make(_state, &_frame_block); 29834 _mlpensemble_clear(ensemble); 29835 _multilayerperceptron_init(&net, _state, ae_true); 29837 mlpcreater0(nin, nout, a, b, &net, _state); 29838 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29839 ae_frame_leave(_state); 29843 /************************************************************************* 29844 Like MLPCreateR1, but for ensembles. 29847 Copyright 18.02.2009 by Bochkanov Sergey 29848 *************************************************************************/ 29849 void mlpecreater1(ae_int_t nin, 29854 ae_int_t ensemblesize, 29855 mlpensemble* ensemble, 29858 ae_frame _frame_block; 29859 multilayerperceptron net; 29861 ae_frame_make(_state, &_frame_block); 29862 _mlpensemble_clear(ensemble); 29863 _multilayerperceptron_init(&net, _state, ae_true); 29865 mlpcreater1(nin, nhid, nout, a, b, &net, _state); 29866 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29867 ae_frame_leave(_state); 29871 /************************************************************************* 29872 Like MLPCreateR2, but for ensembles. 29875 Copyright 18.02.2009 by Bochkanov Sergey 29876 *************************************************************************/ 29877 void mlpecreater2(ae_int_t nin, 29883 ae_int_t ensemblesize, 29884 mlpensemble* ensemble, 29887 ae_frame _frame_block; 29888 multilayerperceptron net; 29890 ae_frame_make(_state, &_frame_block); 29891 _mlpensemble_clear(ensemble); 29892 _multilayerperceptron_init(&net, _state, ae_true); 29894 mlpcreater2(nin, nhid1, nhid2, nout, a, b, &net, _state); 29895 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29896 ae_frame_leave(_state); 29900 /************************************************************************* 29901 Like MLPCreateC0, but for ensembles. 29904 Copyright 18.02.2009 by Bochkanov Sergey 29905 *************************************************************************/ 29906 void mlpecreatec0(ae_int_t nin, 29908 ae_int_t ensemblesize, 29909 mlpensemble* ensemble, 29912 ae_frame _frame_block; 29913 multilayerperceptron net; 29915 ae_frame_make(_state, &_frame_block); 29916 _mlpensemble_clear(ensemble); 29917 _multilayerperceptron_init(&net, _state, ae_true); 29919 mlpcreatec0(nin, nout, &net, _state); 29920 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29921 ae_frame_leave(_state); 29925 /************************************************************************* 29926 Like MLPCreateC1, but for ensembles. 29929 Copyright 18.02.2009 by Bochkanov Sergey 29930 *************************************************************************/ 29931 void mlpecreatec1(ae_int_t nin, 29934 ae_int_t ensemblesize, 29935 mlpensemble* ensemble, 29938 ae_frame _frame_block; 29939 multilayerperceptron net; 29941 ae_frame_make(_state, &_frame_block); 29942 _mlpensemble_clear(ensemble); 29943 _multilayerperceptron_init(&net, _state, ae_true); 29945 mlpcreatec1(nin, nhid, nout, &net, _state); 29946 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29947 ae_frame_leave(_state); 29951 /************************************************************************* 29952 Like MLPCreateC2, but for ensembles. 29955 Copyright 18.02.2009 by Bochkanov Sergey 29956 *************************************************************************/ 29957 void mlpecreatec2(ae_int_t nin, 29961 ae_int_t ensemblesize, 29962 mlpensemble* ensemble, 29965 ae_frame _frame_block; 29966 multilayerperceptron net; 29968 ae_frame_make(_state, &_frame_block); 29969 _mlpensemble_clear(ensemble); 29970 _multilayerperceptron_init(&net, _state, ae_true); 29972 mlpcreatec2(nin, nhid1, nhid2, nout, &net, _state); 29973 mlpecreatefromnetwork(&net, ensemblesize, ensemble, _state); 29974 ae_frame_leave(_state); 29978 /************************************************************************* 29979 Creates ensemble from network. Only network geometry is copied. 29982 Copyright 17.02.2009 by Bochkanov Sergey 29983 *************************************************************************/ 29984 void mlpecreatefromnetwork(multilayerperceptron* network, 29985 ae_int_t ensemblesize, 29986 mlpensemble* ensemble, 29993 _mlpensemble_clear(ensemble); 29995 ae_assert(ensemblesize>0, "MLPECreate: incorrect ensemble size!
", _state); 30000 mlpcopy(network, &ensemble->network, _state); 30003 * network properties 30005 if( mlpissoftmax(network, _state) ) 30007 ccount = mlpgetinputscount(&ensemble->network, _state); 30011 ccount = mlpgetinputscount(&ensemble->network, _state)+mlpgetoutputscount(&ensemble->network, _state); 30013 wcount = mlpgetweightscount(&ensemble->network, _state); 30014 ensemble->ensemblesize = ensemblesize; 30017 * weights, means, sigmas 30019 ae_vector_set_length(&ensemble->weights, ensemblesize*wcount, _state); 30020 ae_vector_set_length(&ensemble->columnmeans, ensemblesize*ccount, _state); 30021 ae_vector_set_length(&ensemble->columnsigmas, ensemblesize*ccount, _state); 30022 for(i=0; i<=ensemblesize*wcount-1; i++) 30024 ensemble->weights.ptr.p_double[i] = ae_randomreal(_state)-0.5; 30026 for(i=0; i<=ensemblesize-1; i++) 30028 ae_v_move(&ensemble->columnmeans.ptr.p_double[i*ccount], 1, &network->columnmeans.ptr.p_double[0], 1, ae_v_len(i*ccount,(i+1)*ccount-1)); 30029 ae_v_move(&ensemble->columnsigmas.ptr.p_double[i*ccount], 1, &network->columnsigmas.ptr.p_double[0], 1, ae_v_len(i*ccount,(i+1)*ccount-1)); 30033 * temporaries, internal buffers 30035 ae_vector_set_length(&ensemble->y, mlpgetoutputscount(&ensemble->network, _state), _state); 30039 /************************************************************************* 30040 Copying of MLPEnsemble strucure 30043 Ensemble1 - original 30049 Copyright 17.02.2009 by Bochkanov Sergey 30050 *************************************************************************/ 30051 void mlpecopy(mlpensemble* ensemble1, 30052 mlpensemble* ensemble2, 30058 _mlpensemble_clear(ensemble2); 30064 if( mlpissoftmax(&ensemble1->network, _state) ) 30066 ccount = mlpgetinputscount(&ensemble1->network, _state); 30070 ccount = mlpgetinputscount(&ensemble1->network, _state)+mlpgetoutputscount(&ensemble1->network, _state); 30072 wcount = mlpgetweightscount(&ensemble1->network, _state); 30077 ae_vector_set_length(&ensemble2->weights, ensemble1->ensemblesize*wcount, _state); 30078 ae_vector_set_length(&ensemble2->columnmeans, ensemble1->ensemblesize*ccount, _state); 30079 ae_vector_set_length(&ensemble2->columnsigmas, ensemble1->ensemblesize*ccount, _state); 30080 ae_vector_set_length(&ensemble2->y, mlpgetoutputscount(&ensemble1->network, _state), _state); 30085 ensemble2->ensemblesize = ensemble1->ensemblesize; 30086 ae_v_move(&ensemble2->weights.ptr.p_double[0], 1, &ensemble1->weights.ptr.p_double[0], 1, ae_v_len(0,ensemble1->ensemblesize*wcount-1)); 30087 ae_v_move(&ensemble2->columnmeans.ptr.p_double[0], 1, &ensemble1->columnmeans.ptr.p_double[0], 1, ae_v_len(0,ensemble1->ensemblesize*ccount-1)); 30088 ae_v_move(&ensemble2->columnsigmas.ptr.p_double[0], 1, &ensemble1->columnsigmas.ptr.p_double[0], 1, ae_v_len(0,ensemble1->ensemblesize*ccount-1)); 30089 mlpcopy(&ensemble1->network, &ensemble2->network, _state); 30093 /************************************************************************* 30094 Randomization of MLP ensemble 30097 Copyright 17.02.2009 by Bochkanov Sergey 30098 *************************************************************************/ 30099 void mlperandomize(mlpensemble* ensemble, ae_state *_state) 30105 wcount = mlpgetweightscount(&ensemble->network, _state); 30106 for(i=0; i<=ensemble->ensemblesize*wcount-1; i++) 30108 ensemble->weights.ptr.p_double[i] = ae_randomreal(_state)-0.5; 30113 /************************************************************************* 30114 Return ensemble properties (number of inputs and outputs). 30117 Copyright 17.02.2009 by Bochkanov Sergey 30118 *************************************************************************/ 30119 void mlpeproperties(mlpensemble* ensemble, 30128 *nin = mlpgetinputscount(&ensemble->network, _state); 30129 *nout = mlpgetoutputscount(&ensemble->network, _state); 30133 /************************************************************************* 30134 Return normalization type (whether ensemble is SOFTMAX-normalized or not). 30137 Copyright 17.02.2009 by Bochkanov Sergey 30138 *************************************************************************/ 30139 ae_bool mlpeissoftmax(mlpensemble* ensemble, ae_state *_state) 30144 result = mlpissoftmax(&ensemble->network, _state); 30149 /************************************************************************* 30153 Ensemble- neural networks ensemble 30154 X - input vector, array[0..NIn-1]. 30155 Y - (possibly) preallocated buffer; if size of Y is less than 30156 NOut, it will be reallocated. If it is large enough, it 30157 is NOT reallocated, so we can save some time on reallocation. 30161 Y - result. Regression estimate when solving regression task, 30162 vector of posterior probabilities for classification task. 30165 Copyright 17.02.2009 by Bochkanov Sergey 30166 *************************************************************************/ 30167 void mlpeprocess(mlpensemble* ensemble, 30168 /* Real */ ae_vector* x, 30169 /* Real */ ae_vector* y, 30180 if( y->cnt<mlpgetoutputscount(&ensemble->network, _state) ) 30182 ae_vector_set_length(y, mlpgetoutputscount(&ensemble->network, _state), _state); 30184 es = ensemble->ensemblesize; 30185 wc = mlpgetweightscount(&ensemble->network, _state); 30186 if( mlpissoftmax(&ensemble->network, _state) ) 30188 cc = mlpgetinputscount(&ensemble->network, _state); 30192 cc = mlpgetinputscount(&ensemble->network, _state)+mlpgetoutputscount(&ensemble->network, _state); 30194 v = (double)1/(double)es; 30195 nout = mlpgetoutputscount(&ensemble->network, _state); 30196 for(i=0; i<=nout-1; i++) 30198 y->ptr.p_double[i] = 0; 30200 for(i=0; i<=es-1; i++) 30202 ae_v_move(&ensemble->network.weights.ptr.p_double[0], 1, &ensemble->weights.ptr.p_double[i*wc], 1, ae_v_len(0,wc-1)); 30203 ae_v_move(&ensemble->network.columnmeans.ptr.p_double[0], 1, &ensemble->columnmeans.ptr.p_double[i*cc], 1, ae_v_len(0,cc-1)); 30204 ae_v_move(&ensemble->network.columnsigmas.ptr.p_double[0], 1, &ensemble->columnsigmas.ptr.p_double[i*cc], 1, ae_v_len(0,cc-1)); 30205 mlpprocess(&ensemble->network, x, &ensemble->y, _state); 30206 ae_v_addd(&y->ptr.p_double[0], 1, &ensemble->y.ptr.p_double[0], 1, ae_v_len(0,nout-1), v); 30211 /************************************************************************* 30212 'interactive' variant of MLPEProcess for languages like Python which 30213 support constructs like "Y = MLPEProcess(LM,X)
" and interactive mode of the 30216 This function allocates new array on each call, so it is significantly 30217 slower than its 'non-interactive' counterpart, but it is more convenient 30218 when you call it from command line. 30221 Copyright 17.02.2009 by Bochkanov Sergey 30222 *************************************************************************/ 30223 void mlpeprocessi(mlpensemble* ensemble, 30224 /* Real */ ae_vector* x, 30225 /* Real */ ae_vector* y, 30229 ae_vector_clear(y); 30231 mlpeprocess(ensemble, x, y, _state); 30235 /************************************************************************* 30236 Calculation of all types of errors 30239 Copyright 17.02.2009 by Bochkanov Sergey 30240 *************************************************************************/ 30241 void mlpeallerrorsx(mlpensemble* ensemble, 30242 /* Real */ ae_matrix* densexy, 30243 sparsematrix* sparsexy, 30244 ae_int_t datasetsize, 30245 ae_int_t datasettype, 30246 /* Integer */ ae_vector* idx, 30249 ae_int_t subsettype, 30250 ae_shared_pool* buf, 30254 ae_frame _frame_block; 30262 ae_smart_ptr _pbuf; 30266 ae_frame_make(_state, &_frame_block); 30267 ae_smart_ptr_init(&_pbuf, (void**)&pbuf, _state, ae_true); 30268 _modelerrors_init(&rep0, _state, ae_true); 30269 _modelerrors_init(&rep1, _state, ae_true); 30273 * Get network information 30275 nin = mlpgetinputscount(&ensemble->network, _state); 30276 nout = mlpgetoutputscount(&ensemble->network, _state); 30277 iscls = mlpissoftmax(&ensemble->network, _state); 30280 * Retrieve buffer, prepare, process data, recycle buffer 30282 ae_shared_pool_retrieve(buf, &_pbuf, _state); 30285 dserrallocate(nout, &pbuf->tmp0, _state); 30289 dserrallocate(-nout, &pbuf->tmp0, _state); 30291 rvectorsetlengthatleast(&pbuf->x, nin, _state); 30292 rvectorsetlengthatleast(&pbuf->y, nout, _state); 30293 rvectorsetlengthatleast(&pbuf->desiredy, nout, _state); 30294 for(i=subset0; i<=subset1-1; i++) 30297 if( subsettype==0 ) 30301 if( subsettype==1 ) 30303 srcidx = idx->ptr.p_int[i]; 30305 ae_assert(srcidx>=0, "MLPEAllErrorsX:
internal error", _state); 30306 if( datasettype==0 ) 30308 ae_v_move(&pbuf->x.ptr.p_double[0], 1, &densexy->ptr.pp_double[srcidx][0], 1, ae_v_len(0,nin-1)); 30310 if( datasettype==1 ) 30312 sparsegetrow(sparsexy, srcidx, &pbuf->x, _state); 30314 mlpeprocess(ensemble, &pbuf->x, &pbuf->y, _state); 30315 if( mlpissoftmax(&ensemble->network, _state) ) 30317 if( datasettype==0 ) 30319 pbuf->desiredy.ptr.p_double[0] = densexy->ptr.pp_double[srcidx][nin]; 30321 if( datasettype==1 ) 30323 pbuf->desiredy.ptr.p_double[0] = sparseget(sparsexy, srcidx, nin, _state); 30328 if( datasettype==0 ) 30330 ae_v_move(&pbuf->desiredy.ptr.p_double[0], 1, &densexy->ptr.pp_double[srcidx][nin], 1, ae_v_len(0,nout-1)); 30332 if( datasettype==1 ) 30334 for(j=0; j<=nout-1; j++) 30336 pbuf->desiredy.ptr.p_double[j] = sparseget(sparsexy, srcidx, nin+j, _state); 30340 dserraccumulate(&pbuf->tmp0, &pbuf->y, &pbuf->desiredy, _state); 30342 dserrfinish(&pbuf->tmp0, _state); 30343 rep->relclserror = pbuf->tmp0.ptr.p_double[0]; 30344 rep->avgce = pbuf->tmp0.ptr.p_double[1]/ae_log(2, _state); 30345 rep->rmserror = pbuf->tmp0.ptr.p_double[2]; 30346 rep->avgerror = pbuf->tmp0.ptr.p_double[3]; 30347 rep->avgrelerror = pbuf->tmp0.ptr.p_double[4]; 30348 ae_shared_pool_recycle(buf, &_pbuf, _state); 30349 ae_frame_leave(_state); 30353 /************************************************************************* 30354 Calculation of all types of errors on dataset given by sparse matrix 30357 Copyright 10.09.2012 by Bochkanov Sergey 30358 *************************************************************************/ 30359 void mlpeallerrorssparse(mlpensemble* ensemble, 30369 ae_frame _frame_block; 30378 ae_frame_make(_state, &_frame_block); 30384 ae_vector_init(&buf, 0, DT_REAL, _state, ae_true); 30385 ae_vector_init(&workx, 0, DT_REAL, _state, ae_true); 30386 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 30387 ae_vector_init(&dy, 0, DT_REAL, _state, ae_true); 30389 nin = mlpgetinputscount(&ensemble->network, _state); 30390 nout = mlpgetoutputscount(&ensemble->network, _state); 30391 if( mlpissoftmax(&ensemble->network, _state) ) 30393 ae_vector_set_length(&dy, 1, _state); 30394 dserrallocate(nout, &buf, _state); 30398 ae_vector_set_length(&dy, nout, _state); 30399 dserrallocate(-nout, &buf, _state); 30401 for(i=0; i<=npoints-1; i++) 30403 sparsegetrow(xy, i, &workx, _state); 30404 mlpeprocess(ensemble, &workx, &y, _state); 30405 if( mlpissoftmax(&ensemble->network, _state) ) 30407 dy.ptr.p_double[0] = workx.ptr.p_double[nin]; 30411 ae_v_move(&dy.ptr.p_double[0], 1, &workx.ptr.p_double[nin], 1, ae_v_len(0,nout-1)); 30413 dserraccumulate(&buf, &y, &dy, _state); 30415 dserrfinish(&buf, _state); 30416 *relcls = buf.ptr.p_double[0]; 30417 *avgce = buf.ptr.p_double[1]; 30418 *rms = buf.ptr.p_double[2]; 30419 *avg = buf.ptr.p_double[3]; 30420 *avgrel = buf.ptr.p_double[4]; 30421 ae_frame_leave(_state); 30425 /************************************************************************* 30426 Relative classification error on the test set 30431 NPoints - test set size 30434 percent of incorrectly classified cases. 30435 Works both for classifier betwork and for regression networks which 30436 are used as classifiers. 30439 Copyright 17.02.2009 by Bochkanov Sergey 30440 *************************************************************************/ 30441 double mlperelclserror(mlpensemble* ensemble, 30442 /* Real */ ae_matrix* xy, 30446 ae_frame _frame_block; 30450 ae_frame_make(_state, &_frame_block); 30451 _modelerrors_init(&rep, _state, ae_true); 30453 mlpeallerrorsx(ensemble, xy, &ensemble->network.dummysxy, npoints, 0, &ensemble->network.dummyidx, 0, npoints, 0, &ensemble->network.buf, &rep, _state); 30454 result = rep.relclserror; 30455 ae_frame_leave(_state); 30460 /************************************************************************* 30461 Average cross-entropy (in bits per element) on the test set 30466 NPoints - test set size 30469 CrossEntropy/(NPoints*LN(2)). 30470 Zero if ensemble solves regression task. 30473 Copyright 17.02.2009 by Bochkanov Sergey 30474 *************************************************************************/ 30475 double mlpeavgce(mlpensemble* ensemble, 30476 /* Real */ ae_matrix* xy, 30480 ae_frame _frame_block; 30484 ae_frame_make(_state, &_frame_block); 30485 _modelerrors_init(&rep, _state, ae_true); 30487 mlpeallerrorsx(ensemble, xy, &ensemble->network.dummysxy, npoints, 0, &ensemble->network.dummyidx, 0, npoints, 0, &ensemble->network.buf, &rep, _state); 30488 result = rep.avgce; 30489 ae_frame_leave(_state); 30494 /************************************************************************* 30495 RMS error on the test set 30500 NPoints - test set size 30503 root mean square error. 30504 Its meaning for regression task is obvious. As for classification task 30505 RMS error means error when estimating posterior probabilities. 30508 Copyright 17.02.2009 by Bochkanov Sergey 30509 *************************************************************************/ 30510 double mlpermserror(mlpensemble* ensemble, 30511 /* Real */ ae_matrix* xy, 30515 ae_frame _frame_block; 30519 ae_frame_make(_state, &_frame_block); 30520 _modelerrors_init(&rep, _state, ae_true); 30522 mlpeallerrorsx(ensemble, xy, &ensemble->network.dummysxy, npoints, 0, &ensemble->network.dummyidx, 0, npoints, 0, &ensemble->network.buf, &rep, _state); 30523 result = rep.rmserror; 30524 ae_frame_leave(_state); 30529 /************************************************************************* 30530 Average error on the test set 30535 NPoints - test set size 30538 Its meaning for regression task is obvious. As for classification task 30539 it means average error when estimating posterior probabilities. 30542 Copyright 17.02.2009 by Bochkanov Sergey 30543 *************************************************************************/ 30544 double mlpeavgerror(mlpensemble* ensemble, 30545 /* Real */ ae_matrix* xy, 30549 ae_frame _frame_block; 30553 ae_frame_make(_state, &_frame_block); 30554 _modelerrors_init(&rep, _state, ae_true); 30556 mlpeallerrorsx(ensemble, xy, &ensemble->network.dummysxy, npoints, 0, &ensemble->network.dummyidx, 0, npoints, 0, &ensemble->network.buf, &rep, _state); 30557 result = rep.avgerror; 30558 ae_frame_leave(_state); 30563 /************************************************************************* 30564 Average relative error on the test set 30569 NPoints - test set size 30572 Its meaning for regression task is obvious. As for classification task 30573 it means average relative error when estimating posterior probabilities. 30576 Copyright 17.02.2009 by Bochkanov Sergey 30577 *************************************************************************/ 30578 double mlpeavgrelerror(mlpensemble* ensemble, 30579 /* Real */ ae_matrix* xy, 30583 ae_frame _frame_block; 30587 ae_frame_make(_state, &_frame_block); 30588 _modelerrors_init(&rep, _state, ae_true); 30590 mlpeallerrorsx(ensemble, xy, &ensemble->network.dummysxy, npoints, 0, &ensemble->network.dummyidx, 0, npoints, 0, &ensemble->network.buf, &rep, _state); 30591 result = rep.avgrelerror; 30592 ae_frame_leave(_state); 30597 /************************************************************************* 30598 Serializer: allocation 30601 Copyright 19.10.2011 by Bochkanov Sergey 30602 *************************************************************************/ 30603 void mlpealloc(ae_serializer* s, mlpensemble* ensemble, ae_state *_state) 30607 ae_serializer_alloc_entry(s); 30608 ae_serializer_alloc_entry(s); 30609 ae_serializer_alloc_entry(s); 30610 allocrealarray(s, &ensemble->weights, -1, _state); 30611 allocrealarray(s, &ensemble->columnmeans, -1, _state); 30612 allocrealarray(s, &ensemble->columnsigmas, -1, _state); 30613 mlpalloc(s, &ensemble->network, _state); 30617 /************************************************************************* 30618 Serializer: serialization 30621 Copyright 14.03.2011 by Bochkanov Sergey 30622 *************************************************************************/ 30623 void mlpeserialize(ae_serializer* s, 30624 mlpensemble* ensemble, 30629 ae_serializer_serialize_int(s, getmlpeserializationcode(_state), _state); 30630 ae_serializer_serialize_int(s, mlpe_mlpefirstversion, _state); 30631 ae_serializer_serialize_int(s, ensemble->ensemblesize, _state); 30632 serializerealarray(s, &ensemble->weights, -1, _state); 30633 serializerealarray(s, &ensemble->columnmeans, -1, _state); 30634 serializerealarray(s, &ensemble->columnsigmas, -1, _state); 30635 mlpserialize(s, &ensemble->network, _state); 30639 /************************************************************************* 30640 Serializer: unserialization 30643 Copyright 14.03.2011 by Bochkanov Sergey 30644 *************************************************************************/ 30645 void mlpeunserialize(ae_serializer* s, 30646 mlpensemble* ensemble, 30652 _mlpensemble_clear(ensemble); 30656 * check correctness of header 30658 ae_serializer_unserialize_int(s, &i0, _state); 30659 ae_assert(i0==getmlpeserializationcode(_state), "MLPEUnserialize: stream header corrupted
", _state); 30660 ae_serializer_unserialize_int(s, &i1, _state); 30661 ae_assert(i1==mlpe_mlpefirstversion, "MLPEUnserialize: stream header corrupted
", _state); 30666 ae_serializer_unserialize_int(s, &ensemble->ensemblesize, _state); 30667 unserializerealarray(s, &ensemble->weights, _state); 30668 unserializerealarray(s, &ensemble->columnmeans, _state); 30669 unserializerealarray(s, &ensemble->columnsigmas, _state); 30670 mlpunserialize(s, &ensemble->network, _state); 30673 * Allocate termoraries 30675 ae_vector_set_length(&ensemble->y, mlpgetoutputscount(&ensemble->network, _state), _state); 30679 ae_bool _mlpensemble_init(void* _p, ae_state *_state, ae_bool make_automatic) 30681 mlpensemble *p = (mlpensemble*)_p; 30682 ae_touch_ptr((void*)p); 30683 if( !ae_vector_init(&p->weights, 0, DT_REAL, _state, make_automatic) ) 30685 if( !ae_vector_init(&p->columnmeans, 0, DT_REAL, _state, make_automatic) ) 30687 if( !ae_vector_init(&p->columnsigmas, 0, DT_REAL, _state, make_automatic) ) 30689 if( !_multilayerperceptron_init(&p->network, _state, make_automatic) ) 30691 if( !ae_vector_init(&p->y, 0, DT_REAL, _state, make_automatic) ) 30697 ae_bool _mlpensemble_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 30699 mlpensemble *dst = (mlpensemble*)_dst; 30700 mlpensemble *src = (mlpensemble*)_src; 30701 dst->ensemblesize = src->ensemblesize; 30702 if( !ae_vector_init_copy(&dst->weights, &src->weights, _state, make_automatic) ) 30704 if( !ae_vector_init_copy(&dst->columnmeans, &src->columnmeans, _state, make_automatic) ) 30706 if( !ae_vector_init_copy(&dst->columnsigmas, &src->columnsigmas, _state, make_automatic) ) 30708 if( !_multilayerperceptron_init_copy(&dst->network, &src->network, _state, make_automatic) ) 30710 if( !ae_vector_init_copy(&dst->y, &src->y, _state, make_automatic) ) 30716 void _mlpensemble_clear(void* _p) 30718 mlpensemble *p = (mlpensemble*)_p; 30719 ae_touch_ptr((void*)p); 30720 ae_vector_clear(&p->weights); 30721 ae_vector_clear(&p->columnmeans); 30722 ae_vector_clear(&p->columnsigmas); 30723 _multilayerperceptron_clear(&p->network); 30724 ae_vector_clear(&p->y); 30728 void _mlpensemble_destroy(void* _p) 30730 mlpensemble *p = (mlpensemble*)_p; 30731 ae_touch_ptr((void*)p); 30732 ae_vector_destroy(&p->weights); 30733 ae_vector_destroy(&p->columnmeans); 30734 ae_vector_destroy(&p->columnsigmas); 30735 _multilayerperceptron_destroy(&p->network); 30736 ae_vector_destroy(&p->y); 30742 /************************************************************************* 30743 Neural network training using modified Levenberg-Marquardt with exact 30744 Hessian calculation and regularization. Subroutine trains neural network 30745 with restarts from random positions. Algorithm is well suited for small 30746 and medium scale problems (hundreds of weights). 30749 Network - neural network with initialized geometry 30751 NPoints - training set size 30752 Decay - weight decay constant, >=0.001 30753 Decay term 'Decay*||Weights||^2' is added to error 30755 If you don't know what Decay to choose, use 0.001. 30756 Restarts - number of restarts from random position, >0. 30757 If you don't know what Restarts to choose, use 2. 30760 Network - trained neural network. 30761 Info - return code: 30762 * -9, if internal matrix inverse subroutine failed 30763 * -2, if there is a point with class number 30764 outside of [0..NOut-1]. 30765 * -1, if wrong parameters specified 30766 (NPoints<0, Restarts<1). 30767 * 2, if task has been solved. 30768 Rep - training report 30771 Copyright 10.03.2009 by Bochkanov Sergey 30772 *************************************************************************/ 30773 void mlptrainlm(multilayerperceptron* network, 30774 /* Real */ ae_matrix* xy, 30782 ae_frame _frame_block; 30804 minlbfgsreport internalrep; 30805 minlbfgsstate state; 30816 matinvreport invrep; 30817 ae_int_t solverinfo; 30818 densesolverreport solverrep; 30820 ae_frame_make(_state, &_frame_block); 30822 _mlpreport_clear(rep); 30823 ae_vector_init(&g, 0, DT_REAL, _state, ae_true); 30824 ae_vector_init(&d, 0, DT_REAL, _state, ae_true); 30825 ae_matrix_init(&h, 0, 0, DT_REAL, _state, ae_true); 30826 ae_matrix_init(&hmod, 0, 0, DT_REAL, _state, ae_true); 30827 ae_matrix_init(&z, 0, 0, DT_REAL, _state, ae_true); 30828 _minlbfgsreport_init(&internalrep, _state, ae_true); 30829 _minlbfgsstate_init(&state, _state, ae_true); 30830 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 30831 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 30832 ae_vector_init(&wbase, 0, DT_REAL, _state, ae_true); 30833 ae_vector_init(&wdir, 0, DT_REAL, _state, ae_true); 30834 ae_vector_init(&wt, 0, DT_REAL, _state, ae_true); 30835 ae_vector_init(&wx, 0, DT_REAL, _state, ae_true); 30836 ae_vector_init(&wbest, 0, DT_REAL, _state, ae_true); 30837 _matinvreport_init(&invrep, _state, ae_true); 30838 _densesolverreport_init(&solverrep, _state, ae_true); 30840 mlpproperties(network, &nin, &nout, &wcount, _state); 30848 if( npoints<=0||restarts<1 ) 30851 ae_frame_leave(_state); 30854 if( mlpissoftmax(network, _state) ) 30856 for(i=0; i<=npoints-1; i++) 30858 if( ae_round(xy->ptr.pp_double[i][nin], _state)<0||ae_round(xy->ptr.pp_double[i][nin], _state)>=nout ) 30861 ae_frame_leave(_state); 30866 decay = ae_maxreal(decay, mlptrain_mindecay, _state); 30874 rep->ncholesky = 0; 30878 * Prepare task and network. Allocate space. 30880 mlpinitpreprocessor(network, xy, npoints, _state); 30881 ae_vector_set_length(&g, wcount-1+1, _state); 30882 ae_matrix_set_length(&h, wcount-1+1, wcount-1+1, _state); 30883 ae_matrix_set_length(&hmod, wcount-1+1, wcount-1+1, _state); 30884 ae_vector_set_length(&wbase, wcount-1+1, _state); 30885 ae_vector_set_length(&wdir, wcount-1+1, _state); 30886 ae_vector_set_length(&wbest, wcount-1+1, _state); 30887 ae_vector_set_length(&wt, wcount-1+1, _state); 30888 ae_vector_set_length(&wx, wcount-1+1, _state); 30889 ebest = ae_maxrealnumber; 30894 for(pass=1; pass<=restarts; pass++) 30898 * Initialize weights 30900 mlprandomize(network, _state); 30903 * First stage of the hybrid algorithm: LBFGS 30905 ae_v_move(&wbase.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 30906 minlbfgscreate(wcount, ae_minint(wcount, 5, _state), &wbase, &state, _state); 30907 minlbfgssetcond(&state, 0, 0, 0, ae_maxint(25, wcount, _state), _state); 30908 while(minlbfgsiteration(&state, _state)) 30914 ae_v_move(&network->weights.ptr.p_double[0], 1, &state.x.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 30915 mlpgradbatch(network, xy, npoints, &state.f, &state.g, _state); 30920 v = ae_v_dotproduct(&network->weights.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 30921 state.f = state.f+0.5*decay*v; 30922 ae_v_addd(&state.g.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 30927 rep->ngrad = rep->ngrad+1; 30929 minlbfgsresults(&state, &wbase, &internalrep, _state); 30930 ae_v_move(&network->weights.ptr.p_double[0], 1, &wbase.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 30933 * Second stage of the hybrid algorithm: LM 30935 * Initialize H with identity matrix, 30937 * E with regularized error. 30939 mlphessianbatch(network, xy, npoints, &e, &g, &h, _state); 30940 v = ae_v_dotproduct(&network->weights.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 30942 ae_v_addd(&g.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 30943 for(k=0; k<=wcount-1; k++) 30945 h.ptr.pp_double[k][k] = h.ptr.pp_double[k][k]+decay; 30947 rep->nhess = rep->nhess+1; 30954 * 1. HMod = H+lambda*I 30955 * 2. Try to solve (H+Lambda*I)*dx = -g. 30956 * Increase lambda if left part is not positive definite. 30958 for(i=0; i<=wcount-1; i++) 30960 ae_v_move(&hmod.ptr.pp_double[i][0], 1, &h.ptr.pp_double[i][0], 1, ae_v_len(0,wcount-1)); 30961 hmod.ptr.pp_double[i][i] = hmod.ptr.pp_double[i][i]+lambdav; 30963 spd = spdmatrixcholesky(&hmod, wcount, ae_true, _state); 30964 rep->ncholesky = rep->ncholesky+1; 30967 lambdav = lambdav*lambdaup*nu; 30971 spdmatrixcholeskysolve(&hmod, wcount, ae_true, &g, &solverinfo, &solverrep, &wdir, _state); 30974 lambdav = lambdav*lambdaup*nu; 30978 ae_v_muld(&wdir.ptr.p_double[0], 1, ae_v_len(0,wcount-1), -1); 30982 * 1. Save old w in WBase 30983 * 1. Test some stopping criterions 30984 * 2. If error(w+wdir)>error(w), increase lambda 30986 ae_v_add(&network->weights.ptr.p_double[0], 1, &wdir.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 30987 xnorm2 = ae_v_dotproduct(&network->weights.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 30988 stepnorm = ae_v_dotproduct(&wdir.ptr.p_double[0], 1, &wdir.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 30989 stepnorm = ae_sqrt(stepnorm, _state); 30990 enew = mlperror(network, xy, npoints, _state)+0.5*decay*xnorm2; 30991 if( ae_fp_less(stepnorm,lmsteptol*(1+ae_sqrt(xnorm2, _state))) ) 30995 if( ae_fp_greater(enew,e) ) 30997 lambdav = lambdav*lambdaup*nu; 31003 * Optimize using inv(cholesky(H)) as preconditioner 31005 rmatrixtrinverse(&hmod, wcount, ae_true, ae_false, &invinfo, &invrep, _state); 31010 * if matrix can't be inverted then exit with errors 31011 * TODO: make WCount steps in direction suggested by HMod 31014 ae_frame_leave(_state); 31017 ae_v_move(&wbase.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31018 for(i=0; i<=wcount-1; i++) 31020 wt.ptr.p_double[i] = 0; 31022 minlbfgscreatex(wcount, wcount, &wt, 1, 0.0, &state, _state); 31023 minlbfgssetcond(&state, 0, 0, 0, 5, _state); 31024 while(minlbfgsiteration(&state, _state)) 31030 for(i=0; i<=wcount-1; i++) 31032 v = ae_v_dotproduct(&state.x.ptr.p_double[i], 1, &hmod.ptr.pp_double[i][i], 1, ae_v_len(i,wcount-1)); 31033 network->weights.ptr.p_double[i] = wbase.ptr.p_double[i]+v; 31035 mlpgradbatch(network, xy, npoints, &state.f, &g, _state); 31036 for(i=0; i<=wcount-1; i++) 31038 state.g.ptr.p_double[i] = 0; 31040 for(i=0; i<=wcount-1; i++) 31042 v = g.ptr.p_double[i]; 31043 ae_v_addd(&state.g.ptr.p_double[i], 1, &hmod.ptr.pp_double[i][i], 1, ae_v_len(i,wcount-1), v); 31048 * grad(x'*x) = A'*(x0+A*t) 31050 v = ae_v_dotproduct(&network->weights.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31051 state.f = state.f+0.5*decay*v; 31052 for(i=0; i<=wcount-1; i++) 31054 v = decay*network->weights.ptr.p_double[i]; 31055 ae_v_addd(&state.g.ptr.p_double[i], 1, &hmod.ptr.pp_double[i][i], 1, ae_v_len(i,wcount-1), v); 31061 rep->ngrad = rep->ngrad+1; 31063 minlbfgsresults(&state, &wt, &internalrep, _state); 31066 * Accept new position. 31067 * Calculate Hessian 31069 for(i=0; i<=wcount-1; i++) 31071 v = ae_v_dotproduct(&wt.ptr.p_double[i], 1, &hmod.ptr.pp_double[i][i], 1, ae_v_len(i,wcount-1)); 31072 network->weights.ptr.p_double[i] = wbase.ptr.p_double[i]+v; 31074 mlphessianbatch(network, xy, npoints, &e, &g, &h, _state); 31075 v = ae_v_dotproduct(&network->weights.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31077 ae_v_addd(&g.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 31078 for(k=0; k<=wcount-1; k++) 31080 h.ptr.pp_double[k][k] = h.ptr.pp_double[k][k]+decay; 31082 rep->nhess = rep->nhess+1; 31087 lambdav = lambdav*lambdadown; 31094 v = ae_v_dotproduct(&network->weights.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31095 e = 0.5*decay*v+mlperror(network, xy, npoints, _state); 31096 if( ae_fp_less(e,ebest) ) 31099 ae_v_move(&wbest.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31104 * copy WBest to output 31106 ae_v_move(&network->weights.ptr.p_double[0], 1, &wbest.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31107 ae_frame_leave(_state); 31111 /************************************************************************* 31112 Neural network training using L-BFGS algorithm with regularization. 31113 Subroutine trains neural network with restarts from random positions. 31114 Algorithm is well suited for problems of any dimensionality (memory 31115 requirements and step complexity are linear by weights number). 31118 Network - neural network with initialized geometry 31120 NPoints - training set size 31121 Decay - weight decay constant, >=0.001 31122 Decay term 'Decay*||Weights||^2' is added to error 31124 If you don't know what Decay to choose, use 0.001. 31125 Restarts - number of restarts from random position, >0. 31126 If you don't know what Restarts to choose, use 2. 31127 WStep - stopping criterion. Algorithm stops if step size is 31128 less than WStep. Recommended value - 0.01. Zero step 31129 size means stopping after MaxIts iterations. 31130 MaxIts - stopping criterion. Algorithm stops after MaxIts 31131 iterations (NOT gradient calculations). Zero MaxIts 31132 means stopping when step is sufficiently small. 31135 Network - trained neural network. 31136 Info - return code: 31137 * -8, if both WStep=0 and MaxIts=0 31138 * -2, if there is a point with class number 31139 outside of [0..NOut-1]. 31140 * -1, if wrong parameters specified 31141 (NPoints<0, Restarts<1). 31142 * 2, if task has been solved. 31143 Rep - training report 31146 Copyright 09.12.2007 by Bochkanov Sergey 31147 *************************************************************************/ 31148 void mlptrainlbfgs(multilayerperceptron* network, 31149 /* Real */ ae_matrix* xy, 31159 ae_frame _frame_block; 31170 minlbfgsreport internalrep; 31171 minlbfgsstate state; 31173 ae_frame_make(_state, &_frame_block); 31175 _mlpreport_clear(rep); 31176 ae_vector_init(&w, 0, DT_REAL, _state, ae_true); 31177 ae_vector_init(&wbest, 0, DT_REAL, _state, ae_true); 31178 _minlbfgsreport_init(&internalrep, _state, ae_true); 31179 _minlbfgsstate_init(&state, _state, ae_true); 31183 * Test inputs, parse flags, read network geometry 31185 if( ae_fp_eq(wstep,0)&&maxits==0 ) 31188 ae_frame_leave(_state); 31191 if( ((npoints<=0||restarts<1)||ae_fp_less(wstep,0))||maxits<0 ) 31194 ae_frame_leave(_state); 31197 mlpproperties(network, &nin, &nout, &wcount, _state); 31198 if( mlpissoftmax(network, _state) ) 31200 for(i=0; i<=npoints-1; i++) 31202 if( ae_round(xy->ptr.pp_double[i][nin], _state)<0||ae_round(xy->ptr.pp_double[i][nin], _state)>=nout ) 31205 ae_frame_leave(_state); 31210 decay = ae_maxreal(decay, mlptrain_mindecay, _state); 31216 mlpinitpreprocessor(network, xy, npoints, _state); 31217 ae_vector_set_length(&w, wcount-1+1, _state); 31218 ae_vector_set_length(&wbest, wcount-1+1, _state); 31219 ebest = ae_maxrealnumber; 31224 rep->ncholesky = 0; 31227 for(pass=1; pass<=restarts; pass++) 31233 mlprandomize(network, _state); 31234 ae_v_move(&w.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31235 minlbfgscreate(wcount, ae_minint(wcount, 10, _state), &w, &state, _state); 31236 minlbfgssetcond(&state, 0.0, 0.0, wstep, maxits, _state); 31237 while(minlbfgsiteration(&state, _state)) 31239 ae_v_move(&network->weights.ptr.p_double[0], 1, &state.x.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31240 mlpgradnbatch(network, xy, npoints, &state.f, &state.g, _state); 31241 v = ae_v_dotproduct(&network->weights.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31242 state.f = state.f+0.5*decay*v; 31243 ae_v_addd(&state.g.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 31244 rep->ngrad = rep->ngrad+1; 31246 minlbfgsresults(&state, &w, &internalrep, _state); 31247 ae_v_move(&network->weights.ptr.p_double[0], 1, &w.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31250 * Compare with best 31252 v = ae_v_dotproduct(&network->weights.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31253 e = mlperrorn(network, xy, npoints, _state)+0.5*decay*v; 31254 if( ae_fp_less(e,ebest) ) 31256 ae_v_move(&wbest.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31264 ae_v_move(&network->weights.ptr.p_double[0], 1, &wbest.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31265 ae_frame_leave(_state); 31269 /************************************************************************* 31270 Neural network training using early stopping (base algorithm - L-BFGS with 31274 Network - neural network with initialized geometry 31275 TrnXY - training set 31276 TrnSize - training set size, TrnSize>0 31277 ValXY - validation set 31278 ValSize - validation set size, ValSize>0 31279 Decay - weight decay constant, >=0.001 31280 Decay term 'Decay*||Weights||^2' is added to error 31282 If you don't know what Decay to choose, use 0.001. 31283 Restarts - number of restarts, either: 31284 * strictly positive number - algorithm make specified 31285 number of restarts from random position. 31286 * -1, in which case algorithm makes exactly one run 31287 from the initial state of the network (no randomization). 31288 If you don't know what Restarts to choose, choose one 31290 * -1 (deterministic start) 31291 * +1 (one random restart) 31292 * +5 (moderate amount of random restarts) 31295 Network - trained neural network. 31296 Info - return code: 31297 * -2, if there is a point with class number 31298 outside of [0..NOut-1]. 31299 * -1, if wrong parameters specified 31300 (NPoints<0, Restarts<1, ...). 31301 * 2, task has been solved, stopping criterion met - 31302 sufficiently small step size. Not expected (we 31303 use EARLY stopping) but possible and not an 31305 * 6, task has been solved, stopping criterion met - 31306 increasing of validation set error. 31307 Rep - training report 31311 Algorithm stops if validation set error increases for a long enough or 31312 step size is small enought (there are task where validation set may 31313 decrease for eternity). In any case solution returned corresponds to the 31314 minimum of validation set error. 31317 Copyright 10.03.2009 by Bochkanov Sergey 31318 *************************************************************************/ 31319 void mlptraines(multilayerperceptron* network, 31320 /* Real */ ae_matrix* trnxy, 31322 /* Real */ ae_matrix* valxy, 31330 ae_frame _frame_block; 31345 minlbfgsreport internalrep; 31346 minlbfgsstate state; 31348 ae_bool needrandomization; 31350 ae_frame_make(_state, &_frame_block); 31352 _mlpreport_clear(rep); 31353 ae_vector_init(&w, 0, DT_REAL, _state, ae_true); 31354 ae_vector_init(&wbest, 0, DT_REAL, _state, ae_true); 31355 ae_vector_init(&wfinal, 0, DT_REAL, _state, ae_true); 31356 _minlbfgsreport_init(&internalrep, _state, ae_true); 31357 _minlbfgsstate_init(&state, _state, ae_true); 31362 * Test inputs, parse flags, read network geometry 31364 if( ((trnsize<=0||valsize<=0)||(restarts<1&&restarts!=-1))||ae_fp_less(decay,0) ) 31367 ae_frame_leave(_state); 31372 needrandomization = ae_false; 31377 needrandomization = ae_true; 31379 mlpproperties(network, &nin, &nout, &wcount, _state); 31380 if( mlpissoftmax(network, _state) ) 31382 for(i=0; i<=trnsize-1; i++) 31384 if( ae_round(trnxy->ptr.pp_double[i][nin], _state)<0||ae_round(trnxy->ptr.pp_double[i][nin], _state)>=nout ) 31387 ae_frame_leave(_state); 31391 for(i=0; i<=valsize-1; i++) 31393 if( ae_round(valxy->ptr.pp_double[i][nin], _state)<0||ae_round(valxy->ptr.pp_double[i][nin], _state)>=nout ) 31396 ae_frame_leave(_state); 31406 mlpinitpreprocessor(network, trnxy, trnsize, _state); 31407 ae_vector_set_length(&w, wcount-1+1, _state); 31408 ae_vector_set_length(&wbest, wcount-1+1, _state); 31409 ae_vector_set_length(&wfinal, wcount-1+1, _state); 31410 efinal = ae_maxrealnumber; 31411 for(i=0; i<=wcount-1; i++) 31413 wfinal.ptr.p_double[i] = 0; 31419 rep->ncholesky = 0; 31422 for(pass=1; pass<=restarts; pass++) 31428 if( needrandomization ) 31430 mlprandomize(network, _state); 31432 ebest = mlperror(network, valxy, valsize, _state); 31433 ae_v_move(&wbest.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31436 ae_v_move(&w.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31437 minlbfgscreate(wcount, ae_minint(wcount, 10, _state), &w, &state, _state); 31438 minlbfgssetcond(&state, 0.0, 0.0, wstep, 0, _state); 31439 minlbfgssetxrep(&state, ae_true, _state); 31440 while(minlbfgsiteration(&state, _state)) 31444 * Calculate gradient 31448 ae_v_move(&network->weights.ptr.p_double[0], 1, &state.x.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31449 mlpgradnbatch(network, trnxy, trnsize, &state.f, &state.g, _state); 31450 v = ae_v_dotproduct(&network->weights.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31451 state.f = state.f+0.5*decay*v; 31452 ae_v_addd(&state.g.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 31453 rep->ngrad = rep->ngrad+1; 31459 if( state.xupdated ) 31461 ae_v_move(&network->weights.ptr.p_double[0], 1, &state.x.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31462 e = mlperror(network, valxy, valsize, _state); 31463 if( ae_fp_less(e,ebest) ) 31466 ae_v_move(&wbest.ptr.p_double[0], 1, &network->weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31469 if( itcnt>30&&ae_fp_greater(itcnt,1.5*itbest) ) 31477 minlbfgsresults(&state, &w, &internalrep, _state); 31480 * Compare with final answer 31482 if( ae_fp_less(ebest,efinal) ) 31484 ae_v_move(&wfinal.ptr.p_double[0], 1, &wbest.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31492 ae_v_move(&network->weights.ptr.p_double[0], 1, &wfinal.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 31493 ae_frame_leave(_state); 31497 /************************************************************************* 31498 Cross-validation estimate of generalization error. 31500 Base algorithm - L-BFGS. 31503 Network - neural network with initialized geometry. Network is 31504 not changed during cross-validation - it is used only 31505 as a representative of its architecture. 31507 SSize - training set size 31508 Decay - weight decay, same as in MLPTrainLBFGS 31509 Restarts - number of restarts, >0. 31510 restarts are counted for each partition separately, so 31511 total number of restarts will be Restarts*FoldsCount. 31512 WStep - stopping criterion, same as in MLPTrainLBFGS 31513 MaxIts - stopping criterion, same as in MLPTrainLBFGS 31514 FoldsCount - number of folds in k-fold cross-validation, 31515 2<=FoldsCount<=SSize. 31516 recommended value: 10. 31519 Info - return code, same as in MLPTrainLBFGS 31520 Rep - report, same as in MLPTrainLM/MLPTrainLBFGS 31521 CVRep - generalization error estimates 31524 Copyright 09.12.2007 by Bochkanov Sergey 31525 *************************************************************************/ 31526 void mlpkfoldcvlbfgs(multilayerperceptron* network, 31527 /* Real */ ae_matrix* xy, 31533 ae_int_t foldscount, 31536 mlpcvreport* cvrep, 31541 _mlpreport_clear(rep); 31542 _mlpcvreport_clear(cvrep); 31544 mlptrain_mlpkfoldcvgeneral(network, xy, npoints, decay, restarts, foldscount, ae_false, wstep, maxits, info, rep, cvrep, _state); 31548 /************************************************************************* 31549 Cross-validation estimate of generalization error. 31551 Base algorithm - Levenberg-Marquardt. 31554 Network - neural network with initialized geometry. Network is 31555 not changed during cross-validation - it is used only 31556 as a representative of its architecture. 31558 SSize - training set size 31559 Decay - weight decay, same as in MLPTrainLBFGS 31560 Restarts - number of restarts, >0. 31561 restarts are counted for each partition separately, so 31562 total number of restarts will be Restarts*FoldsCount. 31563 FoldsCount - number of folds in k-fold cross-validation, 31564 2<=FoldsCount<=SSize. 31565 recommended value: 10. 31568 Info - return code, same as in MLPTrainLBFGS 31569 Rep - report, same as in MLPTrainLM/MLPTrainLBFGS 31570 CVRep - generalization error estimates 31573 Copyright 09.12.2007 by Bochkanov Sergey 31574 *************************************************************************/ 31575 void mlpkfoldcvlm(multilayerperceptron* network, 31576 /* Real */ ae_matrix* xy, 31580 ae_int_t foldscount, 31583 mlpcvreport* cvrep, 31588 _mlpreport_clear(rep); 31589 _mlpcvreport_clear(cvrep); 31591 mlptrain_mlpkfoldcvgeneral(network, xy, npoints, decay, restarts, foldscount, ae_true, 0.0, 0, info, rep, cvrep, _state); 31595 /************************************************************************* 31596 This function estimates generalization error using cross-validation on the 31597 current dataset with current training settings. 31599 FOR USERS OF COMMERCIAL EDITION: 31601 ! Commercial version of ALGLIB includes two important improvements of 31603 ! * multicore support (C++ and C# computational cores) 31604 ! * SSE support (C++ computational core) 31606 ! Second improvement gives constant speedup (2-3X). First improvement 31607 ! gives close-to-linear speedup on multicore systems. Following 31608 ! operations can be executed in parallel: 31609 ! * FoldsCount cross-validation rounds (always) 31610 ! * NRestarts training sessions performed within each of 31611 ! cross-validation rounds (if NRestarts>1) 31612 ! * gradient calculation over large dataset (if dataset is large enough) 31614 ! In order to use multicore features you have to: 31615 ! * use commercial version of ALGLIB 31616 ! * call this function with "smp_
" prefix, which indicates that 31617 ! multicore code will be used (for multicore support) 31619 ! In order to use SSE features you have to: 31620 ! * use commercial version of ALGLIB on Intel processors 31621 ! * use C++ computational core 31623 ! This note is given for users of commercial edition; if you use GPL 31624 ! edition, you still will be able to call smp-version of this function, 31625 ! but all computations will be done serially. 31627 ! We recommend you to carefully read ALGLIB Reference Manual, section 31628 ! called 'SMP support', before using parallel version of this function. 31632 Network - neural network. It must have same number of inputs and 31633 output/classes as was specified during creation of the 31634 trainer object. Network is not changed during cross- 31635 validation and is not trained - it is used only as 31636 representative of its architecture. I.e., we estimate 31637 generalization properties of ARCHITECTURE, not some 31639 NRestarts - number of restarts, >=0: 31640 * NRestarts>0 means that for each cross-validation 31641 round specified number of random restarts is 31642 performed, with best network being chosen after 31644 * NRestarts=0 is same as NRestarts=1 31645 FoldsCount - number of folds in k-fold cross-validation: 31646 * 2<=FoldsCount<=size of dataset 31647 * recommended value: 10. 31648 * values larger than dataset size will be silently 31649 truncated down to dataset size 31652 Rep - structure which contains cross-validation estimates: 31653 * Rep.RelCLSError - fraction of misclassified cases. 31654 * Rep.AvgCE - acerage cross-entropy 31655 * Rep.RMSError - root-mean-square error 31656 * Rep.AvgError - average error 31657 * Rep.AvgRelError - average relative error 31659 NOTE: when no dataset was specified with MLPSetDataset/SetSparseDataset(), 31660 or subset with only one point was given, zeros are returned as 31663 NOTE: this method performs FoldsCount cross-validation rounds, each one 31664 with NRestarts random starts. Thus, FoldsCount*NRestarts networks 31665 are trained in total. 31667 NOTE: Rep.RelCLSError/Rep.AvgCE are zero on regression problems. 31669 NOTE: on classification problems Rep.RMSError/Rep.AvgError/Rep.AvgRelError 31670 contain errors in prediction of posterior probabilities. 31673 Copyright 23.07.2012 by Bochkanov Sergey 31674 *************************************************************************/ 31675 void mlpkfoldcv(mlptrainer* s, 31676 multilayerperceptron* network, 31677 ae_int_t nrestarts, 31678 ae_int_t foldscount, 31682 ae_frame _frame_block; 31683 ae_shared_pool pooldatacv; 31684 mlpparallelizationcv datacv; 31685 mlpparallelizationcv *sdatacv; 31686 ae_smart_ptr _sdatacv; 31702 ae_frame_make(_state, &_frame_block); 31703 _mlpreport_clear(rep); 31704 ae_shared_pool_init(&pooldatacv, _state, ae_true); 31705 _mlpparallelizationcv_init(&datacv, _state, ae_true); 31706 ae_smart_ptr_init(&_sdatacv, (void**)&sdatacv, _state, ae_true); 31707 ae_matrix_init(&cvy, 0, 0, DT_REAL, _state, ae_true); 31708 ae_vector_init(&folds, 0, DT_INT, _state, ae_true); 31709 ae_vector_init(&buf, 0, DT_REAL, _state, ae_true); 31710 ae_vector_init(&dy, 0, DT_REAL, _state, ae_true); 31711 _hqrndstate_init(&rs, _state, ae_true); 31713 if( !mlpissoftmax(network, _state) ) 31729 ae_assert(ntype==ttype, "MLPKFoldCV:
type of input network is not similar to network
type in trainer
object", _state); 31730 ae_assert(s->npoints>=0, "MLPKFoldCV: possible trainer S is not initialized(S.NPoints<0)
", _state); 31731 mlpproperties(network, &nin, &nout, &wcount, _state); 31732 ae_assert(s->nin==nin, "MLPKFoldCV: number of inputs
in trainer is not equal to number of inputs
in network
", _state); 31733 ae_assert(s->nout==nout, "MLPKFoldCV: number of outputs
in trainer is not equal to number of outputs
in network
", _state); 31734 ae_assert(nrestarts>=0, "MLPKFoldCV: NRestarts<0
", _state); 31735 ae_assert(foldscount>=2, "MLPKFoldCV: FoldsCount<2
", _state); 31736 if( foldscount>s->npoints ) 31738 foldscount = s->npoints; 31740 rep->relclserror = 0; 31744 rep->avgrelerror = 0; 31745 hqrndrandomize(&rs, _state); 31748 rep->ncholesky = 0; 31749 if( s->npoints==0||s->npoints==1 ) 31751 ae_frame_leave(_state); 31756 * Read network geometry, test parameters 31760 rowsize = nin+nout; 31761 ae_vector_set_length(&dy, nout, _state); 31762 dserrallocate(-nout, &buf, _state); 31767 ae_vector_set_length(&dy, 1, _state); 31768 dserrallocate(nout, &buf, _state); 31774 ae_vector_set_length(&folds, s->npoints, _state); 31775 for(i=0; i<=s->npoints-1; i++) 31777 folds.ptr.p_int[i] = i*foldscount/s->npoints; 31779 for(i=0; i<=s->npoints-2; i++) 31781 j = i+hqrnduniformi(&rs, s->npoints-i, _state); 31784 k = folds.ptr.p_int[i]; 31785 folds.ptr.p_int[i] = folds.ptr.p_int[j]; 31786 folds.ptr.p_int[j] = k; 31789 ae_matrix_set_length(&cvy, s->npoints, nout, _state); 31792 * Initialize SEED-value for shared pool 31795 mlpcopy(network, &datacv.network, _state); 31796 ae_vector_set_length(&datacv.subset, s->npoints, _state); 31797 ae_vector_set_length(&datacv.xyrow, rowsize, _state); 31798 ae_vector_set_length(&datacv.y, nout, _state); 31801 * Create shared pool 31803 ae_shared_pool_set_seed(&pooldatacv, &datacv, sizeof(datacv), _mlpparallelizationcv_init, _mlpparallelizationcv_init_copy, _mlpparallelizationcv_destroy, _state); 31808 mlptrain_mthreadcv(s, rowsize, nrestarts, &folds, 0, foldscount, &cvy, &pooldatacv, _state); 31811 * Calculate value for NGrad 31813 ae_shared_pool_first_recycled(&pooldatacv, &_sdatacv, _state); 31814 while(sdatacv!=NULL) 31816 rep->ngrad = rep->ngrad+sdatacv->ngrad; 31817 ae_shared_pool_next_recycled(&pooldatacv, &_sdatacv, _state); 31821 * Connect of results and calculate cross-validation error 31823 for(i=0; i<=s->npoints-1; i++) 31825 if( s->datatype==0 ) 31827 ae_v_move(&datacv.xyrow.ptr.p_double[0], 1, &s->densexy.ptr.pp_double[i][0], 1, ae_v_len(0,rowsize-1)); 31829 if( s->datatype==1 ) 31831 sparsegetrow(&s->sparsexy, i, &datacv.xyrow, _state); 31833 ae_v_move(&datacv.y.ptr.p_double[0], 1, &cvy.ptr.pp_double[i][0], 1, ae_v_len(0,nout-1)); 31836 ae_v_move(&dy.ptr.p_double[0], 1, &datacv.xyrow.ptr.p_double[nin], 1, ae_v_len(0,nout-1)); 31840 dy.ptr.p_double[0] = datacv.xyrow.ptr.p_double[nin]; 31842 dserraccumulate(&buf, &datacv.y, &dy, _state); 31844 dserrfinish(&buf, _state); 31845 rep->relclserror = buf.ptr.p_double[0]; 31846 rep->avgce = buf.ptr.p_double[1]; 31847 rep->rmserror = buf.ptr.p_double[2]; 31848 rep->avgerror = buf.ptr.p_double[3]; 31849 rep->avgrelerror = buf.ptr.p_double[4]; 31850 ae_frame_leave(_state); 31854 /************************************************************************* 31855 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 31856 *************************************************************************/ 31857 void _pexec_mlpkfoldcv(mlptrainer* s, 31858 multilayerperceptron* network, 31859 ae_int_t nrestarts, 31860 ae_int_t foldscount, 31861 mlpreport* rep, ae_state *_state) 31863 mlpkfoldcv(s,network,nrestarts,foldscount,rep, _state); 31867 /************************************************************************* 31868 Creation of the network trainer object for regression networks 31871 NIn - number of inputs, NIn>=1 31872 NOut - number of outputs, NOut>=1 31875 S - neural network trainer object. 31876 This structure can be used to train any regression 31877 network with NIn inputs and NOut outputs. 31880 Copyright 23.07.2012 by Bochkanov Sergey 31881 *************************************************************************/ 31882 void mlpcreatetrainer(ae_int_t nin, 31888 _mlptrainer_clear(s); 31890 ae_assert(nin>=1, "MLPCreateTrainer: NIn<1.
", _state); 31891 ae_assert(nout>=1, "MLPCreateTrainer: NOut<1.
", _state); 31894 s->rcpar = ae_true; 31895 s->lbfgsfactor = mlptrain_defaultlbfgsfactor; 31897 mlpsetcond(s, 0, 0, _state); 31900 mlpsetalgobatch(s, _state); 31904 /************************************************************************* 31905 Creation of the network trainer object for classification networks 31908 NIn - number of inputs, NIn>=1 31909 NClasses - number of classes, NClasses>=2 31912 S - neural network trainer object. 31913 This structure can be used to train any classification 31914 network with NIn inputs and NOut outputs. 31917 Copyright 23.07.2012 by Bochkanov Sergey 31918 *************************************************************************/ 31919 void mlpcreatetrainercls(ae_int_t nin, 31925 _mlptrainer_clear(s); 31927 ae_assert(nin>=1, "MLPCreateTrainerCls: NIn<1.
", _state); 31928 ae_assert(nclasses>=2, "MLPCreateTrainerCls: NClasses<2.
", _state); 31930 s->nout = nclasses; 31931 s->rcpar = ae_false; 31932 s->lbfgsfactor = mlptrain_defaultlbfgsfactor; 31934 mlpsetcond(s, 0, 0, _state); 31937 mlpsetalgobatch(s, _state); 31941 /************************************************************************* 31942 This function sets "current dataset
" of the trainer object to one passed 31947 XY - training set, see below for information on the 31948 training set format. This function checks correctness 31949 of the dataset (no NANs/INFs, class numbers are 31950 correct) and throws exception when incorrect dataset 31952 NPoints - points count, >=0. 31956 This function uses two different dataset formats - one for regression 31957 networks, another one for classification networks. 31959 For regression networks with NIn inputs and NOut outputs following dataset 31961 * dataset is given by NPoints*(NIn+NOut) matrix 31962 * each row corresponds to one example 31963 * first NIn columns are inputs, next NOut columns are outputs 31965 For classification networks with NIn inputs and NClasses clases following 31966 datasetformat is used: 31967 * dataset is given by NPoints*(NIn+1) matrix 31968 * each row corresponds to one example 31969 * first NIn columns are inputs, last column stores class number (from 0 to 31973 Copyright 23.07.2012 by Bochkanov Sergey 31974 *************************************************************************/ 31975 void mlpsetdataset(mlptrainer* s, 31976 /* Real */ ae_matrix* xy, 31985 ae_assert(s->nin>=1, "MLPSetDataset: possible parameter S is not initialized
or spoiled(S.NIn<=0).
", _state); 31986 ae_assert(npoints>=0, "MLPSetDataset: NPoint<0
", _state); 31987 ae_assert(npoints<=xy->rows, "MLPSetDataset: invalid size of matrix XY(NPoint more then rows of matrix XY)
", _state); 31989 s->npoints = npoints; 31996 ae_assert(s->nout>=1, "MLPSetDataset: possible parameter S is not initialized
or is spoiled(NOut<1
for regression).
", _state); 31997 ndim = s->nin+s->nout; 31998 ae_assert(ndim<=xy->cols, "MLPSetDataset: invalid size of matrix XY(too few columns
in matrix XY).
", _state); 31999 ae_assert(apservisfinitematrix(xy, npoints, ndim, _state), "MLPSetDataset: parameter XY contains Infinite
or NaN.
", _state); 32003 ae_assert(s->nout>=2, "MLPSetDataset: possible parameter S is not initialized
or is spoiled(NClasses<2
for classifier).
", _state); 32005 ae_assert(ndim<=xy->cols, "MLPSetDataset: invalid size of matrix XY(too few columns
in matrix XY).
", _state); 32006 ae_assert(apservisfinitematrix(xy, npoints, ndim, _state), "MLPSetDataset: parameter XY contains Infinite
or NaN.
", _state); 32007 for(i=0; i<=npoints-1; i++) 32009 ae_assert(ae_round(xy->ptr.pp_double[i][s->nin], _state)>=0&&ae_round(xy->ptr.pp_double[i][s->nin], _state)<s->nout, "MLPSetDataset: invalid parameter XY(
in classifier used nonexistent
class number: either XY[.,NIn]<0
or XY[.,NIn]>=NClasses).
", _state); 32012 rmatrixsetlengthatleast(&s->densexy, npoints, ndim, _state); 32013 for(i=0; i<=npoints-1; i++) 32015 for(j=0; j<=ndim-1; j++) 32017 s->densexy.ptr.pp_double[i][j] = xy->ptr.pp_double[i][j]; 32023 /************************************************************************* 32024 This function sets "current dataset
" of the trainer object to one passed 32025 by user (sparse matrix is used to store dataset). 32029 XY - training set, see below for information on the 32030 training set format. This function checks correctness 32031 of the dataset (no NANs/INFs, class numbers are 32032 correct) and throws exception when incorrect dataset 32033 is passed. Any sparse storage format can be used: 32035 NPoints - points count, >=0 32039 This function uses two different dataset formats - one for regression 32040 networks, another one for classification networks. 32042 For regression networks with NIn inputs and NOut outputs following dataset 32044 * dataset is given by NPoints*(NIn+NOut) matrix 32045 * each row corresponds to one example 32046 * first NIn columns are inputs, next NOut columns are outputs 32048 For classification networks with NIn inputs and NClasses clases following 32049 datasetformat is used: 32050 * dataset is given by NPoints*(NIn+1) matrix 32051 * each row corresponds to one example 32052 * first NIn columns are inputs, last column stores class number (from 0 to 32056 Copyright 23.07.2012 by Bochkanov Sergey 32057 *************************************************************************/ 32058 void mlpsetsparsedataset(mlptrainer* s, 32072 * Check correctness of the data 32074 ae_assert(s->nin>0, "MLPSetSparseDataset: possible parameter S is not initialized
or spoiled(S.NIn<=0).
", _state); 32075 ae_assert(npoints>=0, "MLPSetSparseDataset: NPoint<0
", _state); 32076 ae_assert(npoints<=sparsegetnrows(xy, _state), "MLPSetSparseDataset: invalid size of sparse matrix XY(NPoint more then rows of matrix XY)
", _state); 32083 ae_assert(s->nout>=1, "MLPSetSparseDataset: possible parameter S is not initialized
or is spoiled(NOut<1
for regression).
", _state); 32084 ae_assert(s->nin+s->nout<=sparsegetncols(xy, _state), "MLPSetSparseDataset: invalid size of sparse matrix XY(too few columns
in sparse matrix XY).
", _state); 32085 while(sparseenumerate(xy, &t0, &t1, &i, &j, &v, _state)) 32087 if( i<npoints&&j<s->nin+s->nout ) 32089 ae_assert(ae_isfinite(v, _state), "MLPSetSparseDataset: sparse matrix XY contains Infinite
or NaN.
", _state); 32095 ae_assert(s->nout>=2, "MLPSetSparseDataset: possible parameter S is not initialized
or is spoiled(NClasses<2
for classifier).
", _state); 32096 ae_assert(s->nin+1<=sparsegetncols(xy, _state), "MLPSetSparseDataset: invalid size of sparse matrix XY(too few columns
in sparse matrix XY).
", _state); 32097 while(sparseenumerate(xy, &t0, &t1, &i, &j, &v, _state)) 32099 if( i<npoints&&j<=s->nin ) 32103 ae_assert(ae_isfinite(v, _state), "MLPSetSparseDataset: sparse matrix XY contains Infinite
or NaN.
", _state); 32107 ae_assert((ae_isfinite(v, _state)&&ae_round(v, _state)>=0)&&ae_round(v, _state)<s->nout, "MLPSetSparseDataset: invalid sparse matrix XY(
in classifier used nonexistent
class number: either XY[.,NIn]<0
or XY[.,NIn]>=NClasses).
", _state); 32118 s->npoints = npoints; 32119 sparsecopytocrs(xy, &s->sparsexy, _state); 32123 /************************************************************************* 32124 This function sets weight decay coefficient which is used for training. 32128 Decay - weight decay coefficient, >=0. Weight decay term 32129 'Decay*||Weights||^2' is added to error function. If 32130 you don't know what Decay to choose, use 1.0E-3. 32131 Weight decay can be set to zero, in this case network 32132 is trained without weight decay. 32134 NOTE: by default network uses some small nonzero value for weight decay. 32137 Copyright 23.07.2012 by Bochkanov Sergey 32138 *************************************************************************/ 32139 void mlpsetdecay(mlptrainer* s, double decay, ae_state *_state) 32143 ae_assert(ae_isfinite(decay, _state), "MLPSetDecay: parameter Decay contains Infinite
or NaN.
", _state); 32144 ae_assert(ae_fp_greater_eq(decay,0), "MLPSetDecay: Decay<0.
", _state); 32149 /************************************************************************* 32150 This function sets stopping criteria for the optimizer. 32154 WStep - stopping criterion. Algorithm stops if step size is 32155 less than WStep. Recommended value - 0.01. Zero step 32156 size means stopping after MaxIts iterations. 32158 MaxIts - stopping criterion. Algorithm stops after MaxIts 32159 epochs (full passes over entire dataset). Zero MaxIts 32160 means stopping when step is sufficiently small. 32163 NOTE: by default, WStep=0.005 and MaxIts=0 are used. These values are also 32164 used when MLPSetCond() is called with WStep=0 and MaxIts=0. 32166 NOTE: these stopping criteria are used for all kinds of neural training - 32167 from "conventional
" networks to early stopping ensembles. When used 32168 for "conventional
" networks, they are used as the only stopping 32169 criteria. When combined with early stopping, they used as ADDITIONAL 32170 stopping criteria which can terminate early stopping algorithm. 32173 Copyright 23.07.2012 by Bochkanov Sergey 32174 *************************************************************************/ 32175 void mlpsetcond(mlptrainer* s, 32182 ae_assert(ae_isfinite(wstep, _state), "MLPSetCond: parameter WStep contains Infinite
or NaN.
", _state); 32183 ae_assert(ae_fp_greater_eq(wstep,0), "MLPSetCond: WStep<0.
", _state); 32184 ae_assert(maxits>=0, "MLPSetCond: MaxIts<0.
", _state); 32185 if( ae_fp_neq(wstep,0)||maxits!=0 ) 32188 s->maxits = maxits; 32198 /************************************************************************* 32199 This function sets training algorithm: batch training using L-BFGS will be 32203 * the most robust for small-scale problems, but may be too slow for large 32205 * perfoms full pass through the dataset before performing step 32206 * uses conditions specified by MLPSetCond() for stopping 32207 * is default one used by trainer object 32213 Copyright 23.07.2012 by Bochkanov Sergey 32214 *************************************************************************/ 32215 void mlpsetalgobatch(mlptrainer* s, ae_state *_state) 32223 /************************************************************************* 32224 This function trains neural network passed to this function, using current 32225 dataset (one which was passed to MLPSetDataset() or MLPSetSparseDataset()) 32226 and current training settings. Training from NRestarts random starting 32227 positions is performed, best network is chosen. 32229 Training is performed using current training algorithm. 32231 FOR USERS OF COMMERCIAL EDITION: 32233 ! Commercial version of ALGLIB includes two important improvements of 32235 ! * multicore support (C++ and C# computational cores) 32236 ! * SSE support (C++ computational core) 32238 ! Second improvement gives constant speedup (2-3X). First improvement 32239 ! gives close-to-linear speedup on multicore systems. Following 32240 ! operations can be executed in parallel: 32241 ! * NRestarts training sessions performed within each of 32242 ! cross-validation rounds (if NRestarts>1) 32243 ! * gradient calculation over large dataset (if dataset is large enough) 32245 ! In order to use multicore features you have to: 32246 ! * use commercial version of ALGLIB 32247 ! * call this function with "smp_
" prefix, which indicates that 32248 ! multicore code will be used (for multicore support) 32250 ! In order to use SSE features you have to: 32251 ! * use commercial version of ALGLIB on Intel processors 32252 ! * use C++ computational core 32254 ! This note is given for users of commercial edition; if you use GPL 32255 ! edition, you still will be able to call smp-version of this function, 32256 ! but all computations will be done serially. 32258 ! We recommend you to carefully read ALGLIB Reference Manual, section 32259 ! called 'SMP support', before using parallel version of this function. 32263 Network - neural network. It must have same number of inputs and 32264 output/classes as was specified during creation of the 32266 NRestarts - number of restarts, >=0: 32267 * NRestarts>0 means that specified number of random 32268 restarts are performed, best network is chosen after 32270 * NRestarts=0 means that current state of the network 32271 is used for training. 32274 Network - trained network 32276 NOTE: when no dataset was specified with MLPSetDataset/SetSparseDataset(), 32277 network is filled by zero values. Same behavior for functions 32278 MLPStartTraining and MLPContinueTraining. 32280 NOTE: this method uses sum-of-squares error function for training. 32283 Copyright 23.07.2012 by Bochkanov Sergey 32284 *************************************************************************/ 32285 void mlptrainnetwork(mlptrainer* s, 32286 multilayerperceptron* network, 32287 ae_int_t nrestarts, 32291 ae_frame _frame_block; 32297 ae_shared_pool trnpool; 32299 ae_frame_make(_state, &_frame_block); 32300 _mlpreport_clear(rep); 32301 ae_shared_pool_init(&trnpool, _state, ae_true); 32303 ae_assert(s->npoints>=0, "MLPTrainNetwork: parameter S is not initialized
or is spoiled(S.NPoints<0)
", _state); 32304 if( !mlpissoftmax(network, _state) ) 32320 ae_assert(ntype==ttype, "MLPTrainNetwork:
type of input network is not similar to network
type in trainer
object", _state); 32321 mlpproperties(network, &nin, &nout, &wcount, _state); 32322 ae_assert(s->nin==nin, "MLPTrainNetwork: number of inputs
in trainer is not equal to number of inputs
in network
", _state); 32323 ae_assert(s->nout==nout, "MLPTrainNetwork: number of outputs
in trainer is not equal to number of outputs
in network
", _state); 32324 ae_assert(nrestarts>=0, "MLPTrainNetwork: NRestarts<0.
", _state); 32329 mlptrain_mlptrainnetworkx(s, nrestarts, -1, &s->subset, -1, &s->subset, 0, network, rep, ae_true, &trnpool, _state); 32330 ae_frame_leave(_state); 32334 /************************************************************************* 32335 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 32336 *************************************************************************/ 32337 void _pexec_mlptrainnetwork(mlptrainer* s, 32338 multilayerperceptron* network, 32339 ae_int_t nrestarts, 32340 mlpreport* rep, ae_state *_state) 32342 mlptrainnetwork(s,network,nrestarts,rep, _state); 32346 /************************************************************************* 32347 IMPORTANT: this is an "expert
" version of the MLPTrain() function. We do 32348 not recommend you to use it unless you are pretty sure that you 32349 need ability to monitor training progress. 32351 This function performs step-by-step training of the neural network. Here 32352 "step-by-step
" means that training starts with MLPStartTraining() call, 32353 and then user subsequently calls MLPContinueTraining() to perform one more 32354 iteration of the training. 32356 After call to this function trainer object remembers network and is ready 32357 to train it. However, no training is performed until first call to 32358 MLPContinueTraining() function. Subsequent calls to MLPContinueTraining() 32359 will advance training progress one iteration further. 32363 > ...initialize network and trainer object.... 32365 > MLPStartTraining(Trainer, Network, True) 32366 > while MLPContinueTraining(Trainer, Network) do 32367 > ...visualize training progress... 32372 Network - neural network. It must have same number of inputs and 32373 output/classes as was specified during creation of the 32375 RandomStart - randomize network before training or not: 32376 * True means that network is randomized and its 32377 initial state (one which was passed to the trainer 32379 * False means that training is started from the 32380 current state of the network 32383 Network - neural network which is ready to training (weights are 32384 initialized, preprocessor is initialized using current 32387 NOTE: this method uses sum-of-squares error function for training. 32389 NOTE: it is expected that trainer object settings are NOT changed during 32390 step-by-step training, i.e. no one changes stopping criteria or 32391 training set during training. It is possible and there is no defense 32392 against such actions, but algorithm behavior in such cases is 32393 undefined and can be unpredictable. 32396 Copyright 23.07.2012 by Bochkanov Sergey 32397 *************************************************************************/ 32398 void mlpstarttraining(mlptrainer* s, 32399 multilayerperceptron* network, 32400 ae_bool randomstart, 32410 ae_assert(s->npoints>=0, "MLPStartTraining: parameter S is not initialized
or is spoiled(S.NPoints<0)
", _state); 32411 if( !mlpissoftmax(network, _state) ) 32427 ae_assert(ntype==ttype, "MLPStartTraining:
type of input network is not similar to network
type in trainer
object", _state); 32428 mlpproperties(network, &nin, &nout, &wcount, _state); 32429 ae_assert(s->nin==nin, "MLPStartTraining: number of inputs
in trainer is not equal to number of inputs
in the network.
", _state); 32430 ae_assert(s->nout==nout, "MLPStartTraining: number of outputs
in trainer is not equal to number of outputs
in the network.
", _state); 32433 * Initialize temporaries 32435 mlptrain_initmlptrnsession(network, randomstart, s, &s->session, _state); 32440 mlptrain_mlpstarttrainingx(s, randomstart, -1, &s->subset, -1, &s->session, _state); 32445 mlpcopytunableparameters(&s->session.network, network, _state); 32449 /************************************************************************* 32450 IMPORTANT: this is an "expert
" version of the MLPTrain() function. We do 32451 not recommend you to use it unless you are pretty sure that you 32452 need ability to monitor training progress. 32454 FOR USERS OF COMMERCIAL EDITION: 32456 ! Commercial version of ALGLIB includes two important improvements of 32458 ! * multicore support (C++ and C# computational cores) 32459 ! * SSE support (C++ computational core) 32461 ! Second improvement gives constant speedup (2-3X). First improvement 32462 ! gives close-to-linear speedup on multicore systems. Following 32463 ! operations can be executed in parallel: 32464 ! * gradient calculation over large dataset (if dataset is large enough) 32466 ! In order to use multicore features you have to: 32467 ! * use commercial version of ALGLIB 32468 ! * call this function with "smp_
" prefix, which indicates that 32469 ! multicore code will be used (for multicore support) 32471 ! In order to use SSE features you have to: 32472 ! * use commercial version of ALGLIB on Intel processors 32473 ! * use C++ computational core 32475 ! This note is given for users of commercial edition; if you use GPL 32476 ! edition, you still will be able to call smp-version of this function, 32477 ! but all computations will be done serially. 32479 ! We recommend you to carefully read ALGLIB Reference Manual, section 32480 ! called 'SMP support', before using parallel version of this function. 32482 This function performs step-by-step training of the neural network. Here 32483 "step-by-step
" means that training starts with MLPStartTraining() call, 32484 and then user subsequently calls MLPContinueTraining() to perform one more 32485 iteration of the training. 32487 This function performs one more iteration of the training and returns 32488 either True (training continues) or False (training stopped). In case True 32489 was returned, Network weights are updated according to the current state 32490 of the optimization progress. In case False was returned, no additional 32491 updates is performed (previous update of the network weights moved us to 32492 the final point, and no additional updates is needed). 32496 > [initialize network and trainer object] 32498 > MLPStartTraining(Trainer, Network, True) 32499 > while MLPContinueTraining(Trainer, Network) do 32500 > [visualize training progress] 32505 Network - neural network structure, which is used to store 32506 current state of the training process. 32509 Network - weights of the neural network are rewritten by the 32510 current approximation. 32512 NOTE: this method uses sum-of-squares error function for training. 32514 NOTE: it is expected that trainer object settings are NOT changed during 32515 step-by-step training, i.e. no one changes stopping criteria or 32516 training set during training. It is possible and there is no defense 32517 against such actions, but algorithm behavior in such cases is 32518 undefined and can be unpredictable. 32520 NOTE: It is expected that Network is the same one which was passed to 32521 MLPStartTraining() function. However, THIS function checks only 32523 * that number of network inputs is consistent with trainer object 32525 * that number of network outputs/classes is consistent with trainer 32527 * that number of network weights is the same as number of weights in 32528 the network passed to MLPStartTraining() function 32529 Exception is thrown when these conditions are violated. 32531 It is also expected that you do not change state of the network on 32532 your own - the only party who has right to change network during its 32533 training is a trainer object. Any attempt to interfere with trainer 32534 may lead to unpredictable results. 32538 Copyright 23.07.2012 by Bochkanov Sergey 32539 *************************************************************************/ 32540 ae_bool mlpcontinuetraining(mlptrainer* s, 32541 multilayerperceptron* network, 32552 ae_assert(s->npoints>=0, "MLPContinueTraining: parameter S is not initialized
or is spoiled(S.NPoints<0)
", _state); 32561 if( !mlpissoftmax(network, _state) ) 32569 ae_assert(ntype==ttype, "MLPContinueTraining:
type of input network is not similar to network
type in trainer
object.
", _state); 32570 mlpproperties(network, &nin, &nout, &wcount, _state); 32571 ae_assert(s->nin==nin, "MLPContinueTraining: number of inputs
in trainer is not equal to number of inputs
in the network.
", _state); 32572 ae_assert(s->nout==nout, "MLPContinueTraining: number of outputs
in trainer is not equal to number of outputs
in the network.
", _state); 32573 result = mlptrain_mlpcontinuetrainingx(s, &s->subset, -1, &s->ngradbatch, &s->session, _state); 32576 ae_v_move(&network->weights.ptr.p_double[0], 1, &s->session.network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 32582 /************************************************************************* 32583 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 32584 *************************************************************************/ 32585 ae_bool _pexec_mlpcontinuetraining(mlptrainer* s, 32586 multilayerperceptron* network, ae_state *_state) 32588 return mlpcontinuetraining(s,network, _state); 32592 /************************************************************************* 32593 Training neural networks ensemble using bootstrap aggregating (bagging). 32594 Modified Levenberg-Marquardt algorithm is used as base training method. 32597 Ensemble - model with initialized geometry 32599 NPoints - training set size 32600 Decay - weight decay coefficient, >=0.001 32601 Restarts - restarts, >0. 32604 Ensemble - trained model 32605 Info - return code: 32606 * -2, if there is a point with class number 32607 outside of [0..NClasses-1]. 32608 * -1, if incorrect parameters was passed 32609 (NPoints<0, Restarts<1). 32610 * 2, if task has been solved. 32611 Rep - training report. 32612 OOBErrors - out-of-bag generalization error estimate 32615 Copyright 17.02.2009 by Bochkanov Sergey 32616 *************************************************************************/ 32617 void mlpebagginglm(mlpensemble* ensemble, 32618 /* Real */ ae_matrix* xy, 32624 mlpcvreport* ooberrors, 32629 _mlpreport_clear(rep); 32630 _mlpcvreport_clear(ooberrors); 32632 mlptrain_mlpebagginginternal(ensemble, xy, npoints, decay, restarts, 0.0, 0, ae_true, info, rep, ooberrors, _state); 32636 /************************************************************************* 32637 Training neural networks ensemble using bootstrap aggregating (bagging). 32638 L-BFGS algorithm is used as base training method. 32641 Ensemble - model with initialized geometry 32643 NPoints - training set size 32644 Decay - weight decay coefficient, >=0.001 32645 Restarts - restarts, >0. 32646 WStep - stopping criterion, same as in MLPTrainLBFGS 32647 MaxIts - stopping criterion, same as in MLPTrainLBFGS 32650 Ensemble - trained model 32651 Info - return code: 32652 * -8, if both WStep=0 and MaxIts=0 32653 * -2, if there is a point with class number 32654 outside of [0..NClasses-1]. 32655 * -1, if incorrect parameters was passed 32656 (NPoints<0, Restarts<1). 32657 * 2, if task has been solved. 32658 Rep - training report. 32659 OOBErrors - out-of-bag generalization error estimate 32662 Copyright 17.02.2009 by Bochkanov Sergey 32663 *************************************************************************/ 32664 void mlpebagginglbfgs(mlpensemble* ensemble, 32665 /* Real */ ae_matrix* xy, 32673 mlpcvreport* ooberrors, 32678 _mlpreport_clear(rep); 32679 _mlpcvreport_clear(ooberrors); 32681 mlptrain_mlpebagginginternal(ensemble, xy, npoints, decay, restarts, wstep, maxits, ae_false, info, rep, ooberrors, _state); 32685 /************************************************************************* 32686 Training neural networks ensemble using early stopping. 32689 Ensemble - model with initialized geometry 32691 NPoints - training set size 32692 Decay - weight decay coefficient, >=0.001 32693 Restarts - restarts, >0. 32696 Ensemble - trained model 32697 Info - return code: 32698 * -2, if there is a point with class number 32699 outside of [0..NClasses-1]. 32700 * -1, if incorrect parameters was passed 32701 (NPoints<0, Restarts<1). 32702 * 6, if task has been solved. 32703 Rep - training report. 32704 OOBErrors - out-of-bag generalization error estimate 32707 Copyright 10.03.2009 by Bochkanov Sergey 32708 *************************************************************************/ 32709 void mlpetraines(mlpensemble* ensemble, 32710 /* Real */ ae_matrix* xy, 32718 ae_frame _frame_block; 32729 modelerrors moderr; 32734 ae_frame_make(_state, &_frame_block); 32736 _mlpreport_clear(rep); 32737 ae_matrix_init(&trnxy, 0, 0, DT_REAL, _state, ae_true); 32738 ae_matrix_init(&valxy, 0, 0, DT_REAL, _state, ae_true); 32739 _mlpreport_init(&tmprep, _state, ae_true); 32740 _modelerrors_init(&moderr, _state, ae_true); 32742 nin = mlpgetinputscount(&ensemble->network, _state); 32743 nout = mlpgetoutputscount(&ensemble->network, _state); 32744 wcount = mlpgetweightscount(&ensemble->network, _state); 32745 if( (npoints<2||restarts<1)||ae_fp_less(decay,0) ) 32748 ae_frame_leave(_state); 32751 if( mlpissoftmax(&ensemble->network, _state) ) 32753 for(i=0; i<=npoints-1; i++) 32755 if( ae_round(xy->ptr.pp_double[i][nin], _state)<0||ae_round(xy->ptr.pp_double[i][nin], _state)>=nout ) 32758 ae_frame_leave(_state); 32768 if( mlpissoftmax(&ensemble->network, _state) ) 32778 ae_matrix_set_length(&trnxy, npoints, ccount, _state); 32779 ae_matrix_set_length(&valxy, npoints, ccount, _state); 32782 rep->ncholesky = 0; 32787 for(k=0; k<=ensemble->ensemblesize-1; k++) 32797 for(i=0; i<=npoints-1; i++) 32799 if( ae_fp_less(ae_randomreal(_state),0.66) ) 32803 * Assign sample to training set 32805 ae_v_move(&trnxy.ptr.pp_double[trnsize][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,ccount-1)); 32806 trnsize = trnsize+1; 32812 * Assign sample to validation set 32814 ae_v_move(&valxy.ptr.pp_double[valsize][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,ccount-1)); 32815 valsize = valsize+1; 32819 while(!(trnsize!=0&&valsize!=0)); 32824 mlptraines(&ensemble->network, &trnxy, trnsize, &valxy, valsize, decay, restarts, &tmpinfo, &tmprep, _state); 32828 ae_frame_leave(_state); 32835 ae_v_move(&ensemble->weights.ptr.p_double[k*wcount], 1, &ensemble->network.weights.ptr.p_double[0], 1, ae_v_len(k*wcount,(k+1)*wcount-1)); 32836 ae_v_move(&ensemble->columnmeans.ptr.p_double[k*pcount], 1, &ensemble->network.columnmeans.ptr.p_double[0], 1, ae_v_len(k*pcount,(k+1)*pcount-1)); 32837 ae_v_move(&ensemble->columnsigmas.ptr.p_double[k*pcount], 1, &ensemble->network.columnsigmas.ptr.p_double[0], 1, ae_v_len(k*pcount,(k+1)*pcount-1)); 32838 rep->ngrad = rep->ngrad+tmprep.ngrad; 32839 rep->nhess = rep->nhess+tmprep.nhess; 32840 rep->ncholesky = rep->ncholesky+tmprep.ncholesky; 32842 mlpeallerrorsx(ensemble, xy, &ensemble->network.dummysxy, npoints, 0, &ensemble->network.dummyidx, 0, npoints, 0, &ensemble->network.buf, &moderr, _state); 32843 rep->relclserror = moderr.relclserror; 32844 rep->avgce = moderr.avgce; 32845 rep->rmserror = moderr.rmserror; 32846 rep->avgerror = moderr.avgerror; 32847 rep->avgrelerror = moderr.avgrelerror; 32848 ae_frame_leave(_state); 32852 /************************************************************************* 32853 This function trains neural network ensemble passed to this function using 32854 current dataset and early stopping training algorithm. Each early stopping 32855 round performs NRestarts random restarts (thus, EnsembleSize*NRestarts 32856 training rounds is performed in total). 32858 FOR USERS OF COMMERCIAL EDITION: 32860 ! Commercial version of ALGLIB includes two important improvements of 32862 ! * multicore support (C++ and C# computational cores) 32863 ! * SSE support (C++ computational core) 32865 ! Second improvement gives constant speedup (2-3X). First improvement 32866 ! gives close-to-linear speedup on multicore systems. Following 32867 ! operations can be executed in parallel: 32868 ! * EnsembleSize training sessions performed for each of ensemble 32869 ! members (always parallelized) 32870 ! * NRestarts training sessions performed within each of training 32871 ! sessions (if NRestarts>1) 32872 ! * gradient calculation over large dataset (if dataset is large enough) 32874 ! In order to use multicore features you have to: 32875 ! * use commercial version of ALGLIB 32876 ! * call this function with "smp_
" prefix, which indicates that 32877 ! multicore code will be used (for multicore support) 32879 ! In order to use SSE features you have to: 32880 ! * use commercial version of ALGLIB on Intel processors 32881 ! * use C++ computational core 32883 ! This note is given for users of commercial edition; if you use GPL 32884 ! edition, you still will be able to call smp-version of this function, 32885 ! but all computations will be done serially. 32887 ! We recommend you to carefully read ALGLIB Reference Manual, section 32888 ! called 'SMP support', before using parallel version of this function. 32891 S - trainer object; 32892 Ensemble - neural network ensemble. It must have same number of 32893 inputs and outputs/classes as was specified during 32894 creation of the trainer object. 32895 NRestarts - number of restarts, >=0: 32896 * NRestarts>0 means that specified number of random 32897 restarts are performed during each ES round; 32898 * NRestarts=0 is silently replaced by 1. 32901 Ensemble - trained ensemble; 32902 Rep - it contains all type of errors. 32904 NOTE: this training method uses BOTH early stopping and weight decay! So, 32905 you should select weight decay before starting training just as you 32906 select it before training "conventional
" networks. 32908 NOTE: when no dataset was specified with MLPSetDataset/SetSparseDataset(), 32909 or single-point dataset was passed, ensemble is filled by zero 32912 NOTE: this method uses sum-of-squares error function for training. 32915 Copyright 22.08.2012 by Bochkanov Sergey 32916 *************************************************************************/ 32917 void mlptrainensemblees(mlptrainer* s, 32918 mlpensemble* ensemble, 32919 ae_int_t nrestarts, 32923 ae_frame _frame_block; 32928 ae_shared_pool esessions; 32930 modelerrors tmprep; 32932 ae_frame_make(_state, &_frame_block); 32933 _mlpreport_clear(rep); 32934 ae_shared_pool_init(&esessions, _state, ae_true); 32935 _sinteger_init(&sgrad, _state, ae_true); 32936 _modelerrors_init(&tmprep, _state, ae_true); 32938 ae_assert(s->npoints>=0, "MLPTrainEnsembleES: parameter S is not initialized
or is spoiled(S.NPoints<0)
", _state); 32939 if( !mlpeissoftmax(ensemble, _state) ) 32955 ae_assert(ntype==ttype, "MLPTrainEnsembleES:
internal error -
type of input network is not similar to network
type in trainer
object", _state); 32956 nin = mlpgetinputscount(&ensemble->network, _state); 32957 ae_assert(s->nin==nin, "MLPTrainEnsembleES: number of inputs
in trainer is not equal to number of inputs
in ensemble network
", _state); 32958 nout = mlpgetoutputscount(&ensemble->network, _state); 32959 ae_assert(s->nout==nout, "MLPTrainEnsembleES: number of outputs
in trainer is not equal to number of outputs
in ensemble network
", _state); 32960 ae_assert(nrestarts>=0, "MLPTrainEnsembleES: NRestarts<0.
", _state); 32963 * Initialize parameter Rep 32965 rep->relclserror = 0; 32969 rep->avgrelerror = 0; 32972 rep->ncholesky = 0; 32977 ivectorsetlengthatleast(&s->subset, s->npoints, _state); 32978 ivectorsetlengthatleast(&s->valsubset, s->npoints, _state); 32983 * NOTE: ESessions is not initialized because MLPTrainEnsembleX 32984 * needs uninitialized pool. 32987 mlptrain_mlptrainensemblex(s, ensemble, 0, ensemble->ensemblesize, nrestarts, 0, &sgrad, ae_true, &esessions, _state); 32988 rep->ngrad = sgrad.val; 32991 * Calculate errors. 32993 if( s->datatype==0 ) 32995 mlpeallerrorsx(ensemble, &s->densexy, &s->sparsexy, s->npoints, 0, &ensemble->network.dummyidx, 0, s->npoints, 0, &ensemble->network.buf, &tmprep, _state); 32997 if( s->datatype==1 ) 32999 mlpeallerrorsx(ensemble, &s->densexy, &s->sparsexy, s->npoints, 1, &ensemble->network.dummyidx, 0, s->npoints, 0, &ensemble->network.buf, &tmprep, _state); 33001 rep->relclserror = tmprep.relclserror; 33002 rep->avgce = tmprep.avgce; 33003 rep->rmserror = tmprep.rmserror; 33004 rep->avgerror = tmprep.avgerror; 33005 rep->avgrelerror = tmprep.avgrelerror; 33006 ae_frame_leave(_state); 33010 /************************************************************************* 33011 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. 33012 *************************************************************************/ 33013 void _pexec_mlptrainensemblees(mlptrainer* s, 33014 mlpensemble* ensemble, 33015 ae_int_t nrestarts, 33016 mlpreport* rep, ae_state *_state) 33018 mlptrainensemblees(s,ensemble,nrestarts,rep, _state); 33022 /************************************************************************* 33023 Internal cross-validation subroutine 33024 *************************************************************************/ 33025 static void mlptrain_mlpkfoldcvgeneral(multilayerperceptron* n, 33026 /* Real */ ae_matrix* xy, 33030 ae_int_t foldscount, 33031 ae_bool lmalgorithm, 33036 mlpcvreport* cvrep, 33039 ae_frame _frame_block; 33044 multilayerperceptron network; 33056 mlpreport internalrep; 33060 ae_frame_make(_state, &_frame_block); 33062 _mlpreport_clear(rep); 33063 _mlpcvreport_clear(cvrep); 33064 _multilayerperceptron_init(&network, _state, ae_true); 33065 ae_matrix_init(&cvset, 0, 0, DT_REAL, _state, ae_true); 33066 ae_matrix_init(&testset, 0, 0, DT_REAL, _state, ae_true); 33067 ae_vector_init(&folds, 0, DT_INT, _state, ae_true); 33068 _mlpreport_init(&internalrep, _state, ae_true); 33069 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 33070 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 33074 * Read network geometry, test parameters 33076 mlpproperties(n, &nin, &nout, &wcount, _state); 33077 if( mlpissoftmax(n, _state) ) 33087 if( (npoints<=0||foldscount<2)||foldscount>npoints ) 33090 ae_frame_leave(_state); 33093 mlpcopy(n, &network, _state); 33096 * K-fold out cross-validation. 33097 * First, estimate generalization error 33099 ae_matrix_set_length(&testset, npoints-1+1, rowlen-1+1, _state); 33100 ae_matrix_set_length(&cvset, npoints-1+1, rowlen-1+1, _state); 33101 ae_vector_set_length(&x, nin-1+1, _state); 33102 ae_vector_set_length(&y, nout-1+1, _state); 33103 mlptrain_mlpkfoldsplit(xy, npoints, nclasses, foldscount, ae_false, &folds, _state); 33104 cvrep->relclserror = 0; 33106 cvrep->rmserror = 0; 33107 cvrep->avgerror = 0; 33108 cvrep->avgrelerror = 0; 33111 rep->ncholesky = 0; 33113 for(fold=0; fold<=foldscount-1; fold++) 33121 for(i=0; i<=npoints-1; i++) 33123 if( folds.ptr.p_int[i]==fold ) 33125 ae_v_move(&testset.ptr.pp_double[tssize][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,rowlen-1)); 33130 ae_v_move(&cvset.ptr.pp_double[cvssize][0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,rowlen-1)); 33131 cvssize = cvssize+1; 33136 * Train on CV training set 33140 mlptrainlm(&network, &cvset, cvssize, decay, restarts, info, &internalrep, _state); 33144 mlptrainlbfgs(&network, &cvset, cvssize, decay, restarts, wstep, maxits, info, &internalrep, _state); 33148 cvrep->relclserror = 0; 33150 cvrep->rmserror = 0; 33151 cvrep->avgerror = 0; 33152 cvrep->avgrelerror = 0; 33153 ae_frame_leave(_state); 33156 rep->ngrad = rep->ngrad+internalrep.ngrad; 33157 rep->nhess = rep->nhess+internalrep.nhess; 33158 rep->ncholesky = rep->ncholesky+internalrep.ncholesky; 33161 * Estimate error using CV test set 33163 if( mlpissoftmax(&network, _state) ) 33167 * classification-only code 33169 cvrep->relclserror = cvrep->relclserror+mlpclserror(&network, &testset, tssize, _state); 33170 cvrep->avgce = cvrep->avgce+mlperrorn(&network, &testset, tssize, _state); 33172 for(i=0; i<=tssize-1; i++) 33174 ae_v_move(&x.ptr.p_double[0], 1, &testset.ptr.pp_double[i][0], 1, ae_v_len(0,nin-1)); 33175 mlpprocess(&network, &x, &y, _state); 33176 if( mlpissoftmax(&network, _state) ) 33180 * Classification-specific code 33182 k = ae_round(testset.ptr.pp_double[i][nin], _state); 33183 for(j=0; j<=nout-1; j++) 33187 cvrep->rmserror = cvrep->rmserror+ae_sqr(y.ptr.p_double[j]-1, _state); 33188 cvrep->avgerror = cvrep->avgerror+ae_fabs(y.ptr.p_double[j]-1, _state); 33189 cvrep->avgrelerror = cvrep->avgrelerror+ae_fabs(y.ptr.p_double[j]-1, _state); 33194 cvrep->rmserror = cvrep->rmserror+ae_sqr(y.ptr.p_double[j], _state); 33195 cvrep->avgerror = cvrep->avgerror+ae_fabs(y.ptr.p_double[j], _state); 33203 * Regression-specific code 33205 for(j=0; j<=nout-1; j++) 33207 cvrep->rmserror = cvrep->rmserror+ae_sqr(y.ptr.p_double[j]-testset.ptr.pp_double[i][nin+j], _state); 33208 cvrep->avgerror = cvrep->avgerror+ae_fabs(y.ptr.p_double[j]-testset.ptr.pp_double[i][nin+j], _state); 33209 if( ae_fp_neq(testset.ptr.pp_double[i][nin+j],0) ) 33211 cvrep->avgrelerror = cvrep->avgrelerror+ae_fabs((y.ptr.p_double[j]-testset.ptr.pp_double[i][nin+j])/testset.ptr.pp_double[i][nin+j], _state); 33218 if( mlpissoftmax(&network, _state) ) 33220 cvrep->relclserror = cvrep->relclserror/npoints; 33221 cvrep->avgce = cvrep->avgce/(ae_log(2, _state)*npoints); 33223 cvrep->rmserror = ae_sqrt(cvrep->rmserror/(npoints*nout), _state); 33224 cvrep->avgerror = cvrep->avgerror/(npoints*nout); 33227 cvrep->avgrelerror = cvrep->avgrelerror/relcnt; 33230 ae_frame_leave(_state); 33234 /************************************************************************* 33235 Subroutine prepares K-fold split of the training set. 33238 "NClasses>0
" means that we have classification task. 33239 "NClasses<0
" means regression task with -NClasses real outputs. 33240 *************************************************************************/ 33241 static void mlptrain_mlpkfoldsplit(/* Real */ ae_matrix* xy, 33244 ae_int_t foldscount, 33245 ae_bool stratifiedsplits, 33246 /* Integer */ ae_vector* folds, 33249 ae_frame _frame_block; 33255 ae_frame_make(_state, &_frame_block); 33256 ae_vector_clear(folds); 33257 _hqrndstate_init(&rs, _state, ae_true); 33263 ae_assert(npoints>0, "MLPKFoldSplit: wrong NPoints!
", _state); 33264 ae_assert(nclasses>1||nclasses<0, "MLPKFoldSplit: wrong NClasses!
", _state); 33265 ae_assert(foldscount>=2&&foldscount<=npoints, "MLPKFoldSplit: wrong FoldsCount!
", _state); 33266 ae_assert(!stratifiedsplits, "MLPKFoldSplit: stratified splits are not supported!
", _state); 33271 hqrndrandomize(&rs, _state); 33272 ae_vector_set_length(folds, npoints-1+1, _state); 33273 for(i=0; i<=npoints-1; i++) 33275 folds->ptr.p_int[i] = i*foldscount/npoints; 33277 for(i=0; i<=npoints-2; i++) 33279 j = i+hqrnduniformi(&rs, npoints-i, _state); 33282 k = folds->ptr.p_int[i]; 33283 folds->ptr.p_int[i] = folds->ptr.p_int[j]; 33284 folds->ptr.p_int[j] = k; 33287 ae_frame_leave(_state); 33291 static void mlptrain_mthreadcv(mlptrainer* s, 33293 ae_int_t nrestarts, 33294 /* Integer */ ae_vector* folds, 33297 /* Real */ ae_matrix* cvy, 33298 ae_shared_pool* pooldatacv, 33301 ae_frame _frame_block; 33302 mlpparallelizationcv *datacv; 33303 ae_smart_ptr _datacv; 33306 ae_frame_make(_state, &_frame_block); 33307 ae_smart_ptr_init(&_datacv, (void**)&datacv, _state, ae_true); 33309 if( fold==dfold-1 ) 33315 ae_shared_pool_retrieve(pooldatacv, &_datacv, _state); 33316 datacv->subsetsize = 0; 33317 for(i=0; i<=s->npoints-1; i++) 33319 if( folds->ptr.p_int[i]!=fold ) 33321 datacv->subset.ptr.p_int[datacv->subsetsize] = i; 33322 datacv->subsetsize = datacv->subsetsize+1; 33327 * Train on CV training set 33329 mlptrain_mlptrainnetworkx(s, nrestarts, -1, &datacv->subset, datacv->subsetsize, &datacv->subset, 0, &datacv->network, &datacv->rep, ae_true, &datacv->trnpool, _state); 33330 datacv->ngrad = datacv->ngrad+datacv->rep.ngrad; 33333 * Estimate error using CV test set 33335 for(i=0; i<=s->npoints-1; i++) 33337 if( folds->ptr.p_int[i]==fold ) 33339 if( s->datatype==0 ) 33341 ae_v_move(&datacv->xyrow.ptr.p_double[0], 1, &s->densexy.ptr.pp_double[i][0], 1, ae_v_len(0,rowsize-1)); 33343 if( s->datatype==1 ) 33345 sparsegetrow(&s->sparsexy, i, &datacv->xyrow, _state); 33347 mlpprocess(&datacv->network, &datacv->xyrow, &datacv->y, _state); 33348 ae_v_move(&cvy->ptr.pp_double[i][0], 1, &datacv->y.ptr.p_double[0], 1, ae_v_len(0,s->nout-1)); 33351 ae_shared_pool_recycle(pooldatacv, &_datacv, _state); 33355 ae_assert(fold<dfold-1, "MThreadCV:
internal error(Fold>DFold-1).
", _state); 33356 mlptrain_mthreadcv(s, rowsize, nrestarts, folds, fold, (fold+dfold)/2, cvy, pooldatacv, _state); 33357 mlptrain_mthreadcv(s, rowsize, nrestarts, folds, (fold+dfold)/2, dfold, cvy, pooldatacv, _state); 33359 ae_frame_leave(_state); 33363 static void mlptrain_mlptrainnetworkx(mlptrainer* s, 33364 ae_int_t nrestarts, 33366 /* Integer */ ae_vector* trnsubset, 33367 ae_int_t trnsubsetsize, 33368 /* Integer */ ae_vector* valsubset, 33369 ae_int_t valsubsetsize, 33370 multilayerperceptron* network, 33372 ae_bool isrootcall, 33373 ae_shared_pool* sessions, 33376 ae_frame _frame_block; 33377 modelerrors modrep; 33380 ae_int_t ngradbatch; 33395 ae_bool randomizenetwork; 33396 double bestrmserror; 33397 smlptrnsession *psession; 33398 ae_smart_ptr _psession; 33400 ae_frame_make(_state, &_frame_block); 33401 _modelerrors_init(&modrep, _state, ae_true); 33402 _mlpreport_init(&rep0, _state, ae_true); 33403 _mlpreport_init(&rep1, _state, ae_true); 33404 ae_smart_ptr_init(&_psession, (void**)&psession, _state, ae_true); 33406 mlpproperties(network, &nin, &nout, &wcount, _state); 33409 * Process root call 33415 * Check correctness of parameters 33417 ae_assert(algokind==0||algokind==-1, "MLPTrainNetworkX: unexpected AlgoKind
", _state); 33418 ae_assert(s->npoints>=0, "MLPTrainNetworkX:
internal error - parameter S is not initialized
or is spoiled(S.NPoints<0)
", _state); 33427 if( !mlpissoftmax(network, _state) ) 33435 ae_assert(ntype==ttype, "MLPTrainNetworkX:
internal error -
type of the training network is not similar to network
type in trainer
object", _state); 33436 ae_assert(s->nin==nin, "MLPTrainNetworkX:
internal error - number of inputs
in trainer is not equal to number of inputs
in the training network.
", _state); 33437 ae_assert(s->nout==nout, "MLPTrainNetworkX:
internal error - number of outputs
in trainer is not equal to number of outputs
in the training network.
", _state); 33438 ae_assert(nrestarts>=0, "MLPTrainNetworkX:
internal error - NRestarts<0.
", _state); 33439 ae_assert(trnsubset->cnt>=trnsubsetsize, "MLPTrainNetworkX:
internal error - parameter TrnSubsetSize more than input subset size(Length(TrnSubset)<TrnSubsetSize)
", _state); 33440 for(i=0; i<=trnsubsetsize-1; i++) 33442 ae_assert(trnsubset->ptr.p_int[i]>=0&&trnsubset->ptr.p_int[i]<=s->npoints-1, "MLPTrainNetworkX:
internal error - parameter TrnSubset contains incorrect
index(TrnSubset[I]<0
or TrnSubset[I]>S.NPoints-1)
", _state); 33444 ae_assert(valsubset->cnt>=valsubsetsize, "MLPTrainNetworkX:
internal error - parameter ValSubsetSize more than input subset size(Length(ValSubset)<ValSubsetSize)
", _state); 33445 for(i=0; i<=valsubsetsize-1; i++) 33447 ae_assert(valsubset->ptr.p_int[i]>=0&&valsubset->ptr.p_int[i]<=s->npoints-1, "MLPTrainNetworkX:
internal error - parameter ValSubset contains incorrect
index(ValSubset[I]<0
or ValSubset[I]>S.NPoints-1)
", _state); 33453 randomizenetwork = nrestarts>0; 33454 mlptrain_initmlptrnsessions(network, randomizenetwork, s, sessions, _state); 33455 mlptrain_mlptrainnetworkx(s, nrestarts, algokind, trnsubset, trnsubsetsize, valsubset, valsubsetsize, network, rep, ae_false, sessions, _state); 33458 * Choose best network 33460 bestrmserror = ae_maxrealnumber; 33461 ae_shared_pool_first_recycled(sessions, &_psession, _state); 33462 while(psession!=NULL) 33464 if( ae_fp_less(psession->bestrmserror,bestrmserror) ) 33466 mlpimporttunableparameters(network, &psession->bestparameters, _state); 33467 bestrmserror = psession->bestrmserror; 33469 ae_shared_pool_next_recycled(sessions, &_psession, _state); 33475 if( s->datatype==0 ) 33477 mlpallerrorssubset(network, &s->densexy, s->npoints, trnsubset, trnsubsetsize, &modrep, _state); 33479 if( s->datatype==1 ) 33481 mlpallerrorssparsesubset(network, &s->sparsexy, s->npoints, trnsubset, trnsubsetsize, &modrep, _state); 33483 rep->relclserror = modrep.relclserror; 33484 rep->avgce = modrep.avgce; 33485 rep->rmserror = modrep.rmserror; 33486 rep->avgerror = modrep.avgerror; 33487 rep->avgrelerror = modrep.avgrelerror; 33492 ae_frame_leave(_state); 33497 * Split problem, if we have more than 1 restart 33503 * Divide problem with NRestarts into two: NR0 and NR1. 33506 nr1 = nrestarts-nr0; 33507 mlptrain_mlptrainnetworkx(s, nr0, algokind, trnsubset, trnsubsetsize, valsubset, valsubsetsize, network, &rep0, ae_false, sessions, _state); 33508 mlptrain_mlptrainnetworkx(s, nr1, algokind, trnsubset, trnsubsetsize, valsubset, valsubsetsize, network, &rep1, ae_false, sessions, _state); 33511 * Aggregate results 33513 rep->ngrad = rep0.ngrad+rep1.ngrad; 33514 rep->nhess = rep0.nhess+rep1.nhess; 33515 rep->ncholesky = rep0.ncholesky+rep1.ncholesky; 33520 ae_frame_leave(_state); 33525 * Execution with NRestarts=1 or NRestarts=0: 33526 * * NRestarts=1 means that network is restarted from random position 33527 * * NRestarts=0 means that network is not randomized 33529 ae_assert(nrestarts==0||nrestarts==1, "MLPTrainNetworkX:
internal error", _state); 33532 rep->ncholesky = 0; 33533 ae_shared_pool_retrieve(sessions, &_psession, _state); 33534 if( ((s->datatype==0||s->datatype==1)&&s->npoints>0)&&trnsubsetsize!=0 ) 33538 * Train network using combination of early stopping and step-size 33539 * and step-count based criteria. Network state with best value of 33540 * validation set error is stored in WBuf0. When validation set is 33541 * zero, most recent state of network is stored. 33543 rndstart = nrestarts!=0; 33549 mlptrain_mlpstarttrainingx(s, rndstart, algokind, trnsubset, trnsubsetsize, psession, _state); 33550 if( s->datatype==0 ) 33552 ebest = mlperrorsubset(&psession->network, &s->densexy, s->npoints, valsubset, valsubsetsize, _state); 33554 if( s->datatype==1 ) 33556 ebest = mlperrorsparsesubset(&psession->network, &s->sparsexy, s->npoints, valsubset, valsubsetsize, _state); 33558 ae_v_move(&psession->wbuf0.ptr.p_double[0], 1, &psession->network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 33559 while(mlptrain_mlpcontinuetrainingx(s, trnsubset, trnsubsetsize, &ngradbatch, psession, _state)) 33561 if( s->datatype==0 ) 33563 eval = mlperrorsubset(&psession->network, &s->densexy, s->npoints, valsubset, valsubsetsize, _state); 33565 if( s->datatype==1 ) 33567 eval = mlperrorsparsesubset(&psession->network, &s->sparsexy, s->npoints, valsubset, valsubsetsize, _state); 33569 if( ae_fp_less_eq(eval,ebest)||valsubsetsize==0 ) 33571 ae_v_move(&psession->wbuf0.ptr.p_double[0], 1, &psession->network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 33575 if( itcnt>30&&ae_fp_greater(itcnt,1.5*itbest) ) 33581 ae_v_move(&psession->network.weights.ptr.p_double[0], 1, &psession->wbuf0.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 33582 rep->ngrad = ngradbatch; 33586 for(i=0; i<=wcount-1; i++) 33588 psession->network.weights.ptr.p_double[i] = 0; 33593 * Evaluate network performance and update PSession.BestParameters/BestRMSError 33596 if( s->datatype==0 ) 33598 mlpallerrorssubset(&psession->network, &s->densexy, s->npoints, trnsubset, trnsubsetsize, &modrep, _state); 33600 if( s->datatype==1 ) 33602 mlpallerrorssparsesubset(&psession->network, &s->sparsexy, s->npoints, trnsubset, trnsubsetsize, &modrep, _state); 33604 if( ae_fp_less(modrep.rmserror,psession->bestrmserror) ) 33606 mlpexporttunableparameters(&psession->network, &psession->bestparameters, &pcount, _state); 33607 psession->bestrmserror = modrep.rmserror; 33611 * Move session back to pool 33613 ae_shared_pool_recycle(sessions, &_psession, _state); 33614 ae_frame_leave(_state); 33618 static void mlptrain_mlptrainensemblex(mlptrainer* s, 33619 mlpensemble* ensemble, 33622 ae_int_t nrestarts, 33623 ae_int_t trainingmethod, 33625 ae_bool isrootcall, 33626 ae_shared_pool* esessions, 33629 ae_frame _frame_block; 33637 ae_int_t trnsubsetsize; 33638 ae_int_t valsubsetsize; 33642 mlpetrnsession *psession; 33643 ae_smart_ptr _psession; 33646 ae_frame_make(_state, &_frame_block); 33647 _sinteger_init(&ngrad0, _state, ae_true); 33648 _sinteger_init(&ngrad1, _state, ae_true); 33649 ae_smart_ptr_init(&_psession, (void**)&psession, _state, ae_true); 33650 _hqrndstate_init(&rs, _state, ae_true); 33652 nin = mlpgetinputscount(&ensemble->network, _state); 33653 nout = mlpgetoutputscount(&ensemble->network, _state); 33654 wcount = mlpgetweightscount(&ensemble->network, _state); 33655 if( mlpissoftmax(&ensemble->network, _state) ) 33669 * Handle degenerate case 33673 for(i=idx0; i<=idx1-1; i++) 33675 for(j=0; j<=wcount-1; j++) 33677 ensemble->weights.ptr.p_double[i*wcount+j] = 0.0; 33679 for(j=0; j<=pcount-1; j++) 33681 ensemble->columnmeans.ptr.p_double[i*pcount+j] = 0.0; 33682 ensemble->columnsigmas.ptr.p_double[i*pcount+j] = 1.0; 33685 ae_frame_leave(_state); 33690 * Process root call 33697 * * prepare MLPETrnSessions 33698 * * fill ensemble by zeros (helps to detect errors) 33700 mlptrain_initmlpetrnsessions(&ensemble->network, s, esessions, _state); 33701 for(i=idx0; i<=idx1-1; i++) 33703 for(j=0; j<=wcount-1; j++) 33705 ensemble->weights.ptr.p_double[i*wcount+j] = 0.0; 33707 for(j=0; j<=pcount-1; j++) 33709 ensemble->columnmeans.ptr.p_double[i*pcount+j] = 0.0; 33710 ensemble->columnsigmas.ptr.p_double[i*pcount+j] = 0.0; 33715 * Train in non-root mode and exit 33717 mlptrain_mlptrainensemblex(s, ensemble, idx0, idx1, nrestarts, trainingmethod, ngrad, ae_false, esessions, _state); 33718 ae_frame_leave(_state); 33727 k0 = (idx1-idx0)/2; 33730 mlptrain_mlptrainensemblex(s, ensemble, idx0, idx0+k0, nrestarts, trainingmethod, &ngrad0, ae_false, esessions, _state); 33731 mlptrain_mlptrainensemblex(s, ensemble, idx0+k0, idx1, nrestarts, trainingmethod, &ngrad1, ae_false, esessions, _state); 33732 ngrad->val = ngrad0.val+ngrad1.val; 33733 ae_frame_leave(_state); 33738 * Retrieve and prepare session 33740 ae_shared_pool_retrieve(esessions, &_psession, _state); 33745 hqrndrandomize(&rs, _state); 33746 for(k=idx0; k<=idx1-1; k++) 33754 if( trainingmethod==0 ) 33760 for(i=0; i<=s->npoints-1; i++) 33762 if( ae_fp_less(ae_randomreal(_state),0.66) ) 33766 * Assign sample to training set 33768 psession->trnsubset.ptr.p_int[trnsubsetsize] = i; 33769 trnsubsetsize = trnsubsetsize+1; 33775 * Assign sample to validation set 33777 psession->valsubset.ptr.p_int[valsubsetsize] = i; 33778 valsubsetsize = valsubsetsize+1; 33782 while(!(trnsubsetsize!=0&&valsubsetsize!=0)); 33784 if( trainingmethod==1 ) 33787 trnsubsetsize = s->npoints; 33788 for(i=0; i<=s->npoints-1; i++) 33790 psession->trnsubset.ptr.p_int[i] = hqrnduniformi(&rs, s->npoints, _state); 33797 mlptrain_mlptrainnetworkx(s, nrestarts, -1, &psession->trnsubset, trnsubsetsize, &psession->valsubset, valsubsetsize, &psession->network, &psession->mlprep, ae_true, &psession->mlpsessions, _state); 33798 ngrad->val = ngrad->val+psession->mlprep.ngrad; 33803 ae_v_move(&ensemble->weights.ptr.p_double[k*wcount], 1, &psession->network.weights.ptr.p_double[0], 1, ae_v_len(k*wcount,(k+1)*wcount-1)); 33804 ae_v_move(&ensemble->columnmeans.ptr.p_double[k*pcount], 1, &psession->network.columnmeans.ptr.p_double[0], 1, ae_v_len(k*pcount,(k+1)*pcount-1)); 33805 ae_v_move(&ensemble->columnsigmas.ptr.p_double[k*pcount], 1, &psession->network.columnsigmas.ptr.p_double[0], 1, ae_v_len(k*pcount,(k+1)*pcount-1)); 33811 ae_shared_pool_recycle(esessions, &_psession, _state); 33812 ae_frame_leave(_state); 33816 /************************************************************************* 33817 This function performs step-by-step training of the neural network. Here 33818 "step-by-step
" means that training starts with MLPStartTrainingX call, 33819 and then user subsequently calls MLPContinueTrainingX to perform one more 33820 iteration of the training. 33822 After call to this function trainer object remembers network and is ready 33823 to train it. However, no training is performed until first call to 33824 MLPContinueTraining() function. Subsequent calls to MLPContinueTraining() 33825 will advance traing progress one iteration further. 33829 Copyright 13.08.2012 by Bochkanov Sergey 33830 *************************************************************************/ 33831 static void mlptrain_mlpstarttrainingx(mlptrainer* s, 33832 ae_bool randomstart, 33834 /* Integer */ ae_vector* subset, 33835 ae_int_t subsetsize, 33836 smlptrnsession* session, 33851 ae_assert(s->npoints>=0, "MLPStartTrainingX:
internal error - parameter S is not initialized
or is spoiled(S.NPoints<0)
", _state); 33852 ae_assert(algokind==0||algokind==-1, "MLPStartTrainingX: unexpected AlgoKind
", _state); 33861 if( !mlpissoftmax(&session->network, _state) ) 33869 ae_assert(ntype==ttype, "MLPStartTrainingX:
internal error -
type of the resulting network is not similar to network
type in trainer
object", _state); 33870 mlpproperties(&session->network, &nin, &nout, &wcount, _state); 33871 ae_assert(s->nin==nin, "MLPStartTrainingX: number of inputs
in trainer is not equal to number of inputs
in the network.
", _state); 33872 ae_assert(s->nout==nout, "MLPStartTrainingX: number of outputs
in trainer is not equal to number of outputs
in the network.
", _state); 33873 ae_assert(subset->cnt>=subsetsize, "MLPStartTrainingX:
internal error - parameter SubsetSize more than input subset size(Length(Subset)<SubsetSize)
", _state); 33874 for(i=0; i<=subsetsize-1; i++) 33876 ae_assert(subset->ptr.p_int[i]>=0&&subset->ptr.p_int[i]<=s->npoints-1, "MLPStartTrainingX:
internal error - parameter Subset contains incorrect
index(Subset[I]<0
or Subset[I]>S.NPoints-1)
", _state); 33882 minlbfgssetcond(&session->optimizer, 0.0, 0.0, s->wstep, s->maxits, _state); 33883 if( s->npoints>0&&subsetsize!=0 ) 33887 mlprandomize(&session->network, _state); 33889 minlbfgsrestartfrom(&session->optimizer, &session->network.weights, _state); 33893 for(i=0; i<=wcount-1; i++) 33895 session->network.weights.ptr.p_double[i] = 0; 33900 session->algoused = s->algokind; 33901 if( s->algokind==1 ) 33903 session->minibatchsize = s->minibatchsize; 33908 session->algoused = 0; 33910 hqrndrandomize(&session->generator, _state); 33911 ae_vector_set_length(&session->rstate.ia, 15+1, _state); 33912 ae_vector_set_length(&session->rstate.ra, 1+1, _state); 33913 session->rstate.stage = -1; 33917 /************************************************************************* 33918 This function performs step-by-step training of the neural network. Here 33919 "step-by-step
" means that training starts with MLPStartTrainingX call, 33920 and then user subsequently calls MLPContinueTrainingX to perform one more 33921 iteration of the training. 33923 This function performs one more iteration of the training and returns 33924 either True (training continues) or False (training stopped). In case True 33925 was returned, Network weights are updated according to the current state 33926 of the optimization progress. In case False was returned, no additional 33927 updates is performed (previous update of the network weights moved us to 33928 the final point, and no additional updates is needed). 33932 > [initialize network and trainer object] 33934 > MLPStartTraining(Trainer, Network, True) 33935 > while MLPContinueTraining(Trainer, Network) do 33936 > [visualize training progress] 33941 Copyright 13.08.2012 by Bochkanov Sergey 33942 *************************************************************************/ 33943 static ae_bool mlptrain_mlpcontinuetrainingx(mlptrainer* s, 33944 /* Integer */ ae_vector* subset, 33945 ae_int_t subsetsize, 33946 ae_int_t* ngradbatch, 33947 smlptrnsession* session, 33961 ae_int_t trnsetsize; 33963 ae_int_t minibatchcount; 33964 ae_int_t minibatchidx; 33973 * Reverse communication preparations 33974 * I know it looks ugly, but it works the same way 33975 * anywhere from C++ to Python. 33977 * This code initializes locals by: 33978 * * random values determined during code 33979 * generation - on first subroutine call 33980 * * values from previous call - on subsequent calls 33982 if( session->rstate.stage>=0 ) 33984 nin = session->rstate.ia.ptr.p_int[0]; 33985 nout = session->rstate.ia.ptr.p_int[1]; 33986 wcount = session->rstate.ia.ptr.p_int[2]; 33987 twcount = session->rstate.ia.ptr.p_int[3]; 33988 ntype = session->rstate.ia.ptr.p_int[4]; 33989 ttype = session->rstate.ia.ptr.p_int[5]; 33990 i = session->rstate.ia.ptr.p_int[6]; 33991 j = session->rstate.ia.ptr.p_int[7]; 33992 k = session->rstate.ia.ptr.p_int[8]; 33993 trnsetsize = session->rstate.ia.ptr.p_int[9]; 33994 epoch = session->rstate.ia.ptr.p_int[10]; 33995 minibatchcount = session->rstate.ia.ptr.p_int[11]; 33996 minibatchidx = session->rstate.ia.ptr.p_int[12]; 33997 cursize = session->rstate.ia.ptr.p_int[13]; 33998 idx0 = session->rstate.ia.ptr.p_int[14]; 33999 idx1 = session->rstate.ia.ptr.p_int[15]; 34000 decay = session->rstate.ra.ptr.p_double[0]; 34001 v = session->rstate.ra.ptr.p_double[1]; 34016 minibatchcount = 497; 34017 minibatchidx = -271; 34024 if( session->rstate.stage==0 ) 34034 * Check correctness of inputs 34036 ae_assert(s->npoints>=0, "MLPContinueTrainingX:
internal error - parameter S is not initialized
or is spoiled(S.NPoints<0).
", _state); 34045 if( !mlpissoftmax(&session->network, _state) ) 34053 ae_assert(ntype==ttype, "MLPContinueTrainingX:
internal error -
type of the resulting network is not similar to network
type in trainer
object.
", _state); 34054 mlpproperties(&session->network, &nin, &nout, &wcount, _state); 34055 ae_assert(s->nin==nin, "MLPContinueTrainingX:
internal error - number of inputs
in trainer is not equal to number of inputs
in the network.
", _state); 34056 ae_assert(s->nout==nout, "MLPContinueTrainingX:
internal error - number of outputs
in trainer is not equal to number of outputs
in the network.
", _state); 34057 ae_assert(subset->cnt>=subsetsize, "MLPContinueTrainingX:
internal error - parameter SubsetSize more than input subset size(Length(Subset)<SubsetSize).
", _state); 34058 for(i=0; i<=subsetsize-1; i++) 34060 ae_assert(subset->ptr.p_int[i]>=0&&subset->ptr.p_int[i]<=s->npoints-1, "MLPContinueTrainingX:
internal error - parameter Subset contains incorrect
index(Subset[I]<0
or Subset[I]>S.NPoints-1).
", _state); 34064 * Quick exit on empty training set 34066 if( s->npoints==0||subsetsize==0 ) 34073 * Minibatch training 34075 if( session->algoused==1 ) 34077 ae_assert(ae_false, "MINIBATCH TRAINING IS NOT IMPLEMENTED YET
", _state); 34081 * Last option: full batch training 34085 if( !minlbfgsiteration(&session->optimizer, _state) ) 34089 if( !session->optimizer.xupdated ) 34093 ae_v_move(&session->network.weights.ptr.p_double[0], 1, &session->optimizer.x.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 34094 session->rstate.stage = 0; 34098 ae_v_move(&session->network.weights.ptr.p_double[0], 1, &session->optimizer.x.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 34099 if( s->datatype==0 ) 34101 mlpgradbatchsubset(&session->network, &s->densexy, s->npoints, subset, subsetsize, &session->optimizer.f, &session->optimizer.g, _state); 34103 if( s->datatype==1 ) 34105 mlpgradbatchsparsesubset(&session->network, &s->sparsexy, s->npoints, subset, subsetsize, &session->optimizer.f, &session->optimizer.g, _state); 34109 * Increment number of operations performed on batch gradient 34111 *ngradbatch = *ngradbatch+1; 34112 v = ae_v_dotproduct(&session->network.weights.ptr.p_double[0], 1, &session->network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1)); 34113 session->optimizer.f = session->optimizer.f+0.5*decay*v; 34114 ae_v_addd(&session->optimizer.g.ptr.p_double[0], 1, &session->network.weights.ptr.p_double[0], 1, ae_v_len(0,wcount-1), decay); 34117 minlbfgsresultsbuf(&session->optimizer, &session->network.weights, &session->optimizerrep, _state); 34126 session->rstate.ia.ptr.p_int[0] = nin; 34127 session->rstate.ia.ptr.p_int[1] = nout; 34128 session->rstate.ia.ptr.p_int[2] = wcount; 34129 session->rstate.ia.ptr.p_int[3] = twcount; 34130 session->rstate.ia.ptr.p_int[4] = ntype; 34131 session->rstate.ia.ptr.p_int[5] = ttype; 34132 session->rstate.ia.ptr.p_int[6] = i; 34133 session->rstate.ia.ptr.p_int[7] = j; 34134 session->rstate.ia.ptr.p_int[8] = k; 34135 session->rstate.ia.ptr.p_int[9] = trnsetsize; 34136 session->rstate.ia.ptr.p_int[10] = epoch; 34137 session->rstate.ia.ptr.p_int[11] = minibatchcount; 34138 session->rstate.ia.ptr.p_int[12] = minibatchidx; 34139 session->rstate.ia.ptr.p_int[13] = cursize; 34140 session->rstate.ia.ptr.p_int[14] = idx0; 34141 session->rstate.ia.ptr.p_int[15] = idx1; 34142 session->rstate.ra.ptr.p_double[0] = decay; 34143 session->rstate.ra.ptr.p_double[1] = v; 34148 /************************************************************************* 34149 Internal bagging subroutine. 34152 Copyright 19.02.2009 by Bochkanov Sergey 34153 *************************************************************************/ 34154 static void mlptrain_mlpebagginginternal(mlpensemble* ensemble, 34155 /* Real */ ae_matrix* xy, 34161 ae_bool lmalgorithm, 34164 mlpcvreport* ooberrors, 34167 ae_frame _frame_block; 34171 ae_vector oobcntbuf; 34188 ae_frame_make(_state, &_frame_block); 34190 _mlpreport_clear(rep); 34191 _mlpcvreport_clear(ooberrors); 34192 ae_matrix_init(&xys, 0, 0, DT_REAL, _state, ae_true); 34193 ae_vector_init(&s, 0, DT_BOOL, _state, ae_true); 34194 ae_matrix_init(&oobbuf, 0, 0, DT_REAL, _state, ae_true); 34195 ae_vector_init(&oobcntbuf, 0, DT_INT, _state, ae_true); 34196 ae_vector_init(&x, 0, DT_REAL, _state, ae_true); 34197 ae_vector_init(&y, 0, DT_REAL, _state, ae_true); 34198 ae_vector_init(&dy, 0, DT_REAL, _state, ae_true); 34199 ae_vector_init(&dsbuf, 0, DT_REAL, _state, ae_true); 34200 _mlpreport_init(&tmprep, _state, ae_true); 34201 _hqrndstate_init(&rs, _state, ae_true); 34203 nin = mlpgetinputscount(&ensemble->network, _state); 34204 nout = mlpgetoutputscount(&ensemble->network, _state); 34205 wcount = mlpgetweightscount(&ensemble->network, _state); 34210 if( (!lmalgorithm&&ae_fp_eq(wstep,0))&&maxits==0 ) 34213 ae_frame_leave(_state); 34216 if( ((npoints<=0||restarts<1)||ae_fp_less(wstep,0))||maxits<0 ) 34219 ae_frame_leave(_state); 34222 if( mlpissoftmax(&ensemble->network, _state) ) 34224 for(i=0; i<=npoints-1; i++) 34226 if( ae_round(xy->ptr.pp_double[i][nin], _state)<0||ae_round(xy->ptr.pp_double[i][nin], _state)>=nout ) 34229 ae_frame_leave(_state); 34236 * allocate temporaries 34241 rep->ncholesky = 0; 34242 ooberrors->relclserror = 0; 34243 ooberrors->avgce = 0; 34244 ooberrors->rmserror = 0; 34245 ooberrors->avgerror = 0; 34246 ooberrors->avgrelerror = 0; 34247 if( mlpissoftmax(&ensemble->network, _state) ) 34257 ae_matrix_set_length(&xys, npoints, ccnt, _state); 34258 ae_vector_set_length(&s, npoints, _state); 34259 ae_matrix_set_length(&oobbuf, npoints, nout, _state); 34260 ae_vector_set_length(&oobcntbuf, npoints, _state); 34261 ae_vector_set_length(&x, nin, _state); 34262 ae_vector_set_length(&y, nout, _state); 34263 if( mlpissoftmax(&ensemble->network, _state) ) 34265 ae_vector_set_length(&dy, 1, _state); 34269 ae_vector_set_length(&dy, nout, _state); 34271 for(i=0; i<=npoints-1; i++) 34273 for(j=0; j<=nout-1; j++) 34275 oobbuf.ptr.pp_double[i][j] = 0; 34278 for(i=0; i<=npoints-1; i++) 34280 oobcntbuf.ptr.p_int[i] = 0; 34284 * main bagging cycle 34286 hqrndrandomize(&rs, _state); 34287 for(k=0; k<=ensemble->ensemblesize-1; k++) 34293 for(i=0; i<=npoints-1; i++) 34295 s.ptr.p_bool[i] = ae_false; 34297 for(i=0; i<=npoints-1; i++) 34299 j = hqrnduniformi(&rs, npoints, _state); 34300 s.ptr.p_bool[j] = ae_true; 34301 ae_v_move(&xys.ptr.pp_double[i][0], 1, &xy->ptr.pp_double[j][0], 1, ae_v_len(0,ccnt-1)); 34309 mlptrainlm(&ensemble->network, &xys, npoints, decay, restarts, info, &tmprep, _state); 34313 mlptrainlbfgs(&ensemble->network, &xys, npoints, decay, restarts, wstep, maxits, info, &tmprep, _state); 34317 ae_frame_leave(_state); 34324 rep->ngrad = rep->ngrad+tmprep.ngrad; 34325 rep->nhess = rep->nhess+tmprep.nhess; 34326 rep->ncholesky = rep->ncholesky+tmprep.ncholesky; 34327 ae_v_move(&ensemble->weights.ptr.p_double[k*wcount], 1, &ensemble->network.weights.ptr.p_double[0], 1, ae_v_len(k*wcount,(k+1)*wcount-1)); 34328 ae_v_move(&ensemble->columnmeans.ptr.p_double[k*pcnt], 1, &ensemble->network.columnmeans.ptr.p_double[0], 1, ae_v_len(k*pcnt,(k+1)*pcnt-1)); 34329 ae_v_move(&ensemble->columnsigmas.ptr.p_double[k*pcnt], 1, &ensemble->network.columnsigmas.ptr.p_double[0], 1, ae_v_len(k*pcnt,(k+1)*pcnt-1)); 34334 for(i=0; i<=npoints-1; i++) 34336 if( !s.ptr.p_bool[i] ) 34338 ae_v_move(&x.ptr.p_double[0], 1, &xy->ptr.pp_double[i][0], 1, ae_v_len(0,nin-1)); 34339 mlpprocess(&ensemble->network, &x, &y, _state); 34340 ae_v_add(&oobbuf.ptr.pp_double[i][0], 1, &y.ptr.p_double[0], 1, ae_v_len(0,nout-1)); 34341 oobcntbuf.ptr.p_int[i] = oobcntbuf.ptr.p_int[i]+1; 34349 if( mlpissoftmax(&ensemble->network, _state) ) 34351 dserrallocate(nout, &dsbuf, _state); 34355 dserrallocate(-nout, &dsbuf, _state); 34357 for(i=0; i<=npoints-1; i++) 34359 if( oobcntbuf.ptr.p_int[i]!=0 ) 34361 v = (double)1/(double)oobcntbuf.ptr.p_int[i]; 34362 ae_v_moved(&y.ptr.p_double[0], 1, &oobbuf.ptr.pp_double[i][0], 1, ae_v_len(0,nout-1), v); 34363 if( mlpissoftmax(&ensemble->network, _state) ) 34365 dy.ptr.p_double[0] = xy->ptr.pp_double[i][nin]; 34369 ae_v_moved(&dy.ptr.p_double[0], 1, &xy->ptr.pp_double[i][nin], 1, ae_v_len(0,nout-1), v); 34371 dserraccumulate(&dsbuf, &y, &dy, _state); 34374 dserrfinish(&dsbuf, _state); 34375 ooberrors->relclserror = dsbuf.ptr.p_double[0]; 34376 ooberrors->avgce = dsbuf.ptr.p_double[1]; 34377 ooberrors->rmserror = dsbuf.ptr.p_double[2]; 34378 ooberrors->avgerror = dsbuf.ptr.p_double[3]; 34379 ooberrors->avgrelerror = dsbuf.ptr.p_double[4]; 34380 ae_frame_leave(_state); 34384 /************************************************************************* 34385 This function initializes temporaries needed for training session. 34389 Copyright 01.07.2013 by Bochkanov Sergey 34390 *************************************************************************/ 34391 static void mlptrain_initmlptrnsession(multilayerperceptron* networktrained, 34392 ae_bool randomizenetwork, 34393 mlptrainer* trainer, 34394 smlptrnsession* session, 34397 ae_frame _frame_block; 34402 ae_vector dummysubset; 34404 ae_frame_make(_state, &_frame_block); 34405 ae_vector_init(&dummysubset, 0, DT_INT, _state, ae_true); 34410 * * copy input network to Session.Network 34411 * * re-initialize preprocessor and weights if RandomizeNetwork=True 34413 mlpcopy(networktrained, &session->network, _state); 34414 if( randomizenetwork ) 34416 ae_assert(trainer->datatype==0||trainer->datatype==1, "InitTemporaries: unexpected Trainer.DataType
", _state); 34417 if( trainer->datatype==0 ) 34419 mlpinitpreprocessorsubset(&session->network, &trainer->densexy, trainer->npoints, &dummysubset, -1, _state); 34421 if( trainer->datatype==1 ) 34423 mlpinitpreprocessorsparsesubset(&session->network, &trainer->sparsexy, trainer->npoints, &dummysubset, -1, _state); 34425 mlprandomize(&session->network, _state); 34426 session->randomizenetwork = ae_true; 34430 session->randomizenetwork = ae_false; 34434 * Determine network geometry and initialize optimizer 34436 mlpproperties(&session->network, &nin, &nout, &wcount, _state); 34437 minlbfgscreate(wcount, ae_minint(wcount, trainer->lbfgsfactor, _state), &session->network.weights, &session->optimizer, _state); 34438 minlbfgssetxrep(&session->optimizer, ae_true, _state); 34443 ae_vector_set_length(&session->wbuf0, wcount, _state); 34444 ae_vector_set_length(&session->wbuf1, wcount, _state); 34447 * Initialize session result 34449 mlpexporttunableparameters(&session->network, &session->bestparameters, &pcount, _state); 34450 session->bestrmserror = ae_maxrealnumber; 34451 ae_frame_leave(_state); 34455 /************************************************************************* 34456 This function initializes temporaries needed for training session. 34458 *************************************************************************/ 34459 static void mlptrain_initmlptrnsessions(multilayerperceptron* networktrained, 34460 ae_bool randomizenetwork, 34461 mlptrainer* trainer, 34462 ae_shared_pool* sessions, 34465 ae_frame _frame_block; 34466 ae_vector dummysubset; 34471 ae_frame_make(_state, &_frame_block); 34472 ae_vector_init(&dummysubset, 0, DT_INT, _state, ae_true); 34473 _smlptrnsession_init(&t, _state, ae_true); 34474 ae_smart_ptr_init(&_p, (void**)&p, _state, ae_true); 34476 if( ae_shared_pool_is_initialized(sessions) ) 34480 * Pool was already initialized. 34481 * Clear sessions stored in the pool. 34483 ae_shared_pool_first_recycled(sessions, &_p, _state); 34486 ae_assert(mlpsamearchitecture(&p->network, networktrained, _state), "InitMLPTrnSessions:
internal consistency
error", _state); 34487 p->bestrmserror = ae_maxrealnumber; 34488 ae_shared_pool_next_recycled(sessions, &_p, _state); 34495 * Prepare session and seed pool 34497 mlptrain_initmlptrnsession(networktrained, randomizenetwork, trainer, &t, _state); 34498 ae_shared_pool_set_seed(sessions, &t, sizeof(t), _smlptrnsession_init, _smlptrnsession_init_copy, _smlptrnsession_destroy, _state); 34500 ae_frame_leave(_state); 34504 /************************************************************************* 34505 This function initializes temporaries needed for ensemble training. 34507 *************************************************************************/ 34508 static void mlptrain_initmlpetrnsession(multilayerperceptron* individualnetwork, 34509 mlptrainer* trainer, 34510 mlpetrnsession* session, 34513 ae_frame _frame_block; 34514 ae_vector dummysubset; 34516 ae_frame_make(_state, &_frame_block); 34517 ae_vector_init(&dummysubset, 0, DT_INT, _state, ae_true); 34522 * * copy input network to Session.Network 34523 * * re-initialize preprocessor and weights if RandomizeNetwork=True 34525 mlpcopy(individualnetwork, &session->network, _state); 34526 mlptrain_initmlptrnsessions(individualnetwork, ae_true, trainer, &session->mlpsessions, _state); 34527 ivectorsetlengthatleast(&session->trnsubset, trainer->npoints, _state); 34528 ivectorsetlengthatleast(&session->valsubset, trainer->npoints, _state); 34529 ae_frame_leave(_state); 34533 /************************************************************************* 34534 This function initializes temporaries needed for training session. 34536 *************************************************************************/ 34537 static void mlptrain_initmlpetrnsessions(multilayerperceptron* individualnetwork, 34538 mlptrainer* trainer, 34539 ae_shared_pool* sessions, 34542 ae_frame _frame_block; 34545 ae_frame_make(_state, &_frame_block); 34546 _mlpetrnsession_init(&t, _state, ae_true); 34548 if( !ae_shared_pool_is_initialized(sessions) ) 34550 mlptrain_initmlpetrnsession(individualnetwork, trainer, &t, _state); 34551 ae_shared_pool_set_seed(sessions, &t, sizeof(t), _mlpetrnsession_init, _mlpetrnsession_init_copy, _mlpetrnsession_destroy, _state); 34553 ae_frame_leave(_state); 34557 ae_bool _mlpreport_init(void* _p, ae_state *_state, ae_bool make_automatic) 34559 mlpreport *p = (mlpreport*)_p; 34560 ae_touch_ptr((void*)p); 34565 ae_bool _mlpreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 34567 mlpreport *dst = (mlpreport*)_dst; 34568 mlpreport *src = (mlpreport*)_src; 34569 dst->relclserror = src->relclserror; 34570 dst->avgce = src->avgce; 34571 dst->rmserror = src->rmserror; 34572 dst->avgerror = src->avgerror; 34573 dst->avgrelerror = src->avgrelerror; 34574 dst->ngrad = src->ngrad; 34575 dst->nhess = src->nhess; 34576 dst->ncholesky = src->ncholesky; 34581 void _mlpreport_clear(void* _p) 34583 mlpreport *p = (mlpreport*)_p; 34584 ae_touch_ptr((void*)p); 34588 void _mlpreport_destroy(void* _p) 34590 mlpreport *p = (mlpreport*)_p; 34591 ae_touch_ptr((void*)p); 34595 ae_bool _mlpcvreport_init(void* _p, ae_state *_state, ae_bool make_automatic) 34597 mlpcvreport *p = (mlpcvreport*)_p; 34598 ae_touch_ptr((void*)p); 34603 ae_bool _mlpcvreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 34605 mlpcvreport *dst = (mlpcvreport*)_dst; 34606 mlpcvreport *src = (mlpcvreport*)_src; 34607 dst->relclserror = src->relclserror; 34608 dst->avgce = src->avgce; 34609 dst->rmserror = src->rmserror; 34610 dst->avgerror = src->avgerror; 34611 dst->avgrelerror = src->avgrelerror; 34616 void _mlpcvreport_clear(void* _p) 34618 mlpcvreport *p = (mlpcvreport*)_p; 34619 ae_touch_ptr((void*)p); 34623 void _mlpcvreport_destroy(void* _p) 34625 mlpcvreport *p = (mlpcvreport*)_p; 34626 ae_touch_ptr((void*)p); 34630 ae_bool _smlptrnsession_init(void* _p, ae_state *_state, ae_bool make_automatic) 34632 smlptrnsession *p = (smlptrnsession*)_p; 34633 ae_touch_ptr((void*)p); 34634 if( !ae_vector_init(&p->bestparameters, 0, DT_REAL, _state, make_automatic) ) 34636 if( !_multilayerperceptron_init(&p->network, _state, make_automatic) ) 34638 if( !_minlbfgsstate_init(&p->optimizer, _state, make_automatic) ) 34640 if( !_minlbfgsreport_init(&p->optimizerrep, _state, make_automatic) ) 34642 if( !ae_vector_init(&p->wbuf0, 0, DT_REAL, _state, make_automatic) ) 34644 if( !ae_vector_init(&p->wbuf1, 0, DT_REAL, _state, make_automatic) ) 34646 if( !ae_vector_init(&p->allminibatches, 0, DT_INT, _state, make_automatic) ) 34648 if( !ae_vector_init(&p->currentminibatch, 0, DT_INT, _state, make_automatic) ) 34650 if( !_rcommstate_init(&p->rstate, _state, make_automatic) ) 34652 if( !_hqrndstate_init(&p->generator, _state, make_automatic) ) 34658 ae_bool _smlptrnsession_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 34660 smlptrnsession *dst = (smlptrnsession*)_dst; 34661 smlptrnsession *src = (smlptrnsession*)_src; 34662 if( !ae_vector_init_copy(&dst->bestparameters, &src->bestparameters, _state, make_automatic) ) 34664 dst->bestrmserror = src->bestrmserror; 34665 dst->randomizenetwork = src->randomizenetwork; 34666 if( !_multilayerperceptron_init_copy(&dst->network, &src->network, _state, make_automatic) ) 34668 if( !_minlbfgsstate_init_copy(&dst->optimizer, &src->optimizer, _state, make_automatic) ) 34670 if( !_minlbfgsreport_init_copy(&dst->optimizerrep, &src->optimizerrep, _state, make_automatic) ) 34672 if( !ae_vector_init_copy(&dst->wbuf0, &src->wbuf0, _state, make_automatic) ) 34674 if( !ae_vector_init_copy(&dst->wbuf1, &src->wbuf1, _state, make_automatic) ) 34676 if( !ae_vector_init_copy(&dst->allminibatches, &src->allminibatches, _state, make_automatic) ) 34678 if( !ae_vector_init_copy(&dst->currentminibatch, &src->currentminibatch, _state, make_automatic) ) 34680 if( !_rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic) ) 34682 dst->algoused = src->algoused; 34683 dst->minibatchsize = src->minibatchsize; 34684 if( !_hqrndstate_init_copy(&dst->generator, &src->generator, _state, make_automatic) ) 34690 void _smlptrnsession_clear(void* _p) 34692 smlptrnsession *p = (smlptrnsession*)_p; 34693 ae_touch_ptr((void*)p); 34694 ae_vector_clear(&p->bestparameters); 34695 _multilayerperceptron_clear(&p->network); 34696 _minlbfgsstate_clear(&p->optimizer); 34697 _minlbfgsreport_clear(&p->optimizerrep); 34698 ae_vector_clear(&p->wbuf0); 34699 ae_vector_clear(&p->wbuf1); 34700 ae_vector_clear(&p->allminibatches); 34701 ae_vector_clear(&p->currentminibatch); 34702 _rcommstate_clear(&p->rstate); 34703 _hqrndstate_clear(&p->generator); 34707 void _smlptrnsession_destroy(void* _p) 34709 smlptrnsession *p = (smlptrnsession*)_p; 34710 ae_touch_ptr((void*)p); 34711 ae_vector_destroy(&p->bestparameters); 34712 _multilayerperceptron_destroy(&p->network); 34713 _minlbfgsstate_destroy(&p->optimizer); 34714 _minlbfgsreport_destroy(&p->optimizerrep); 34715 ae_vector_destroy(&p->wbuf0); 34716 ae_vector_destroy(&p->wbuf1); 34717 ae_vector_destroy(&p->allminibatches); 34718 ae_vector_destroy(&p->currentminibatch); 34719 _rcommstate_destroy(&p->rstate); 34720 _hqrndstate_destroy(&p->generator); 34724 ae_bool _mlpetrnsession_init(void* _p, ae_state *_state, ae_bool make_automatic) 34726 mlpetrnsession *p = (mlpetrnsession*)_p; 34727 ae_touch_ptr((void*)p); 34728 if( !ae_vector_init(&p->trnsubset, 0, DT_INT, _state, make_automatic) ) 34730 if( !ae_vector_init(&p->valsubset, 0, DT_INT, _state, make_automatic) ) 34732 if( !ae_shared_pool_init(&p->mlpsessions, _state, make_automatic) ) 34734 if( !_mlpreport_init(&p->mlprep, _state, make_automatic) ) 34736 if( !_multilayerperceptron_init(&p->network, _state, make_automatic) ) 34742 ae_bool _mlpetrnsession_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 34744 mlpetrnsession *dst = (mlpetrnsession*)_dst; 34745 mlpetrnsession *src = (mlpetrnsession*)_src; 34746 if( !ae_vector_init_copy(&dst->trnsubset, &src->trnsubset, _state, make_automatic) ) 34748 if( !ae_vector_init_copy(&dst->valsubset, &src->valsubset, _state, make_automatic) ) 34750 if( !ae_shared_pool_init_copy(&dst->mlpsessions, &src->mlpsessions, _state, make_automatic) ) 34752 if( !_mlpreport_init_copy(&dst->mlprep, &src->mlprep, _state, make_automatic) ) 34754 if( !_multilayerperceptron_init_copy(&dst->network, &src->network, _state, make_automatic) ) 34760 void _mlpetrnsession_clear(void* _p) 34762 mlpetrnsession *p = (mlpetrnsession*)_p; 34763 ae_touch_ptr((void*)p); 34764 ae_vector_clear(&p->trnsubset); 34765 ae_vector_clear(&p->valsubset); 34766 ae_shared_pool_clear(&p->mlpsessions); 34767 _mlpreport_clear(&p->mlprep); 34768 _multilayerperceptron_clear(&p->network); 34772 void _mlpetrnsession_destroy(void* _p) 34774 mlpetrnsession *p = (mlpetrnsession*)_p; 34775 ae_touch_ptr((void*)p); 34776 ae_vector_destroy(&p->trnsubset); 34777 ae_vector_destroy(&p->valsubset); 34778 ae_shared_pool_destroy(&p->mlpsessions); 34779 _mlpreport_destroy(&p->mlprep); 34780 _multilayerperceptron_destroy(&p->network); 34784 ae_bool _mlptrainer_init(void* _p, ae_state *_state, ae_bool make_automatic) 34786 mlptrainer *p = (mlptrainer*)_p; 34787 ae_touch_ptr((void*)p); 34788 if( !ae_matrix_init(&p->densexy, 0, 0, DT_REAL, _state, make_automatic) ) 34790 if( !_sparsematrix_init(&p->sparsexy, _state, make_automatic) ) 34792 if( !_smlptrnsession_init(&p->session, _state, make_automatic) ) 34794 if( !ae_vector_init(&p->subset, 0, DT_INT, _state, make_automatic) ) 34796 if( !ae_vector_init(&p->valsubset, 0, DT_INT, _state, make_automatic) ) 34802 ae_bool _mlptrainer_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 34804 mlptrainer *dst = (mlptrainer*)_dst; 34805 mlptrainer *src = (mlptrainer*)_src; 34806 dst->nin = src->nin; 34807 dst->nout = src->nout; 34808 dst->rcpar = src->rcpar; 34809 dst->lbfgsfactor = src->lbfgsfactor; 34810 dst->decay = src->decay; 34811 dst->wstep = src->wstep; 34812 dst->maxits = src->maxits; 34813 dst->datatype = src->datatype; 34814 dst->npoints = src->npoints; 34815 if( !ae_matrix_init_copy(&dst->densexy, &src->densexy, _state, make_automatic) ) 34817 if( !_sparsematrix_init_copy(&dst->sparsexy, &src->sparsexy, _state, make_automatic) ) 34819 if( !_smlptrnsession_init_copy(&dst->session, &src->session, _state, make_automatic) ) 34821 dst->ngradbatch = src->ngradbatch; 34822 if( !ae_vector_init_copy(&dst->subset, &src->subset, _state, make_automatic) ) 34824 dst->subsetsize = src->subsetsize; 34825 if( !ae_vector_init_copy(&dst->valsubset, &src->valsubset, _state, make_automatic) ) 34827 dst->valsubsetsize = src->valsubsetsize; 34828 dst->algokind = src->algokind; 34829 dst->minibatchsize = src->minibatchsize; 34834 void _mlptrainer_clear(void* _p) 34836 mlptrainer *p = (mlptrainer*)_p; 34837 ae_touch_ptr((void*)p); 34838 ae_matrix_clear(&p->densexy); 34839 _sparsematrix_clear(&p->sparsexy); 34840 _smlptrnsession_clear(&p->session); 34841 ae_vector_clear(&p->subset); 34842 ae_vector_clear(&p->valsubset); 34846 void _mlptrainer_destroy(void* _p) 34848 mlptrainer *p = (mlptrainer*)_p; 34849 ae_touch_ptr((void*)p); 34850 ae_matrix_destroy(&p->densexy); 34851 _sparsematrix_destroy(&p->sparsexy); 34852 _smlptrnsession_destroy(&p->session); 34853 ae_vector_destroy(&p->subset); 34854 ae_vector_destroy(&p->valsubset); 34858 ae_bool _mlpparallelizationcv_init(void* _p, ae_state *_state, ae_bool make_automatic) 34860 mlpparallelizationcv *p = (mlpparallelizationcv*)_p; 34861 ae_touch_ptr((void*)p); 34862 if( !_multilayerperceptron_init(&p->network, _state, make_automatic) ) 34864 if( !_mlpreport_init(&p->rep, _state, make_automatic) ) 34866 if( !ae_vector_init(&p->subset, 0, DT_INT, _state, make_automatic) ) 34868 if( !ae_vector_init(&p->xyrow, 0, DT_REAL, _state, make_automatic) ) 34870 if( !ae_vector_init(&p->y, 0, DT_REAL, _state, make_automatic) ) 34872 if( !ae_shared_pool_init(&p->trnpool, _state, make_automatic) ) 34878 ae_bool _mlpparallelizationcv_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic) 34880 mlpparallelizationcv *dst = (mlpparallelizationcv*)_dst; 34881 mlpparallelizationcv *src = (mlpparallelizationcv*)_src; 34882 if( !_multilayerperceptron_init_copy(&dst->network, &src->network, _state, make_automatic) ) 34884 if( !_mlpreport_init_copy(&dst->rep, &src->rep, _state, make_automatic) ) 34886 if( !ae_vector_init_copy(&dst->subset, &src->subset, _state, make_automatic) ) 34888 dst->subsetsize = src->subsetsize; 34889 if( !ae_vector_init_copy(&dst->xyrow, &src->xyrow, _state, make_automatic) ) 34891 if( !ae_vector_init_copy(&dst->y, &src->y, _state, make_automatic) ) 34893 dst->ngrad = src->ngrad; 34894 if( !ae_shared_pool_init_copy(&dst->trnpool, &src->trnpool, _state, make_automatic) ) 34900 void _mlpparallelizationcv_clear(void* _p) 34902 mlpparallelizationcv *p = (mlpparallelizationcv*)_p; 34903 ae_touch_ptr((void*)p); 34904 _multilayerperceptron_clear(&p->network); 34905 _mlpreport_clear(&p->rep); 34906 ae_vector_clear(&p->subset); 34907 ae_vector_clear(&p->xyrow); 34908 ae_vector_clear(&p->y); 34909 ae_shared_pool_clear(&p->trnpool); 34913 void _mlpparallelizationcv_destroy(void* _p) 34915 mlpparallelizationcv *p = (mlpparallelizationcv*)_p; 34916 ae_touch_ptr((void*)p); 34917 _multilayerperceptron_destroy(&p->network); 34918 _mlpreport_destroy(&p->rep); 34919 ae_vector_destroy(&p->subset); 34920 ae_vector_destroy(&p->xyrow); 34921 ae_vector_destroy(&p->y); 34922 ae_shared_pool_destroy(&p->trnpool); 34928 /************************************************************************* 34929 Principal components analysis 34931 Subroutine builds orthogonal basis where first axis corresponds to 34932 direction with maximum variance, second axis maximizes variance in subspace 34933 orthogonal to first axis and so on. 34935 It should be noted that, unlike LDA, PCA does not use class labels. 34938 X - dataset, array[0..NPoints-1,0..NVars-1]. 34939 matrix contains ONLY INDEPENDENT VARIABLES. 34940 NPoints - dataset size, NPoints>=0 34941 NVars - number of independent variables, NVars>=1 34943 ÂÛÕÎÄÍÛÅ ÏÀÐÀÌÅÒÐÛ: 34944 Info - return code: 34945 * -4, if SVD subroutine haven't converged 34946 * -1, if wrong parameters has been passed (NPoints<0, 34948 * 1, if task is solved 34949 S2 - array[0..NVars-1]. variance values corresponding 34951 V - array[0..NVars-1,0..NVars-1] 34952 matrix, whose columns store basis vectors. 34955 Copyright 25.08.2008 by Bochkanov Sergey 34956 *************************************************************************/ 34957 void pcabuildbasis(/* Real */ ae_matrix* x, 34961 /* Real */ ae_vector* s2, 34962 /* Real */ ae_matrix* v, 34965 ae_frame _frame_block; 34978 ae_frame_make(_state, &_frame_block); 34980 ae_vector_clear(s2); 34981 ae_matrix_clear(v); 34982 ae_matrix_init(&a, 0, 0, DT_REAL, _state, ae_true); 34983 ae_matrix_init(&u, 0, 0, DT_REAL, _state, ae_true); 34984 ae_matrix_init(&vt, 0, 0, DT_REAL, _state, ae_true); 34985 ae_vector_init(&m, 0, DT_REAL, _state, ae_true); 34986 ae_vector_init(&t, 0, DT_REAL, _state, ae_true); 34992 if( npoints<0||nvars<1 ) 34995 ae_frame_leave(_state); 35001 * Special case: NPoints=0 35005 ae_vector_set_length(s2, nvars-1+1, _state); 35006 ae_matrix_set_length(v, nvars-1+1, nvars-1+1, _state); 35007 for(i=0; i<=nvars-1; i++) 35009 s2->ptr.p_double[i] = 0; 35011 for(i=0; i<=nvars-1; i++) 35013 for(j=0; j<=nvars-1; j++) 35017 v->ptr.pp_double[i][j] = 1; 35021 v->ptr.pp_double[i][j] = 0; 35025 ae_frame_leave(_state); 35032 ae_vector_set_length(&m, nvars-1+1, _state); 35033 ae_vector_set_length(&t, npoints-1+1, _state); 35034 for(j=0; j<=nvars-1; j++) 35036 ae_v_move(&t.ptr.p_double[0], 1, &x->ptr.pp_double[0][j], x->stride, ae_v_len(0,npoints-1)); 35037 samplemoments(&t, npoints, &mean, &variance, &skewness, &kurtosis, _state); 35038 m.ptr.p_double[j] = mean; 35042 * Center, apply SVD, prepare output 35044 ae_matrix_set_length(&a, ae_maxint(npoints, nvars, _state)-1+1, nvars-1+1, _state); 35045 for(i=0; i<=npoints-1; i++) 35047 ae_v_move(&a.ptr.pp_double[i][0], 1, &x->ptr.pp_double[i][0], 1, ae_v_len(0,nvars-1)); 35048 ae_v_sub(&a.ptr.pp_double[i][0], 1, &m.ptr.p_double[0], 1, ae_v_len(0,nvars-1)); 35050 for(i=npoints; i<=nvars-1; i++) 35052 for(j=0; j<=nvars-1; j++) 35054 a.ptr.pp_double[i][j] = 0; 35057 if( !rmatrixsvd(&a, ae_maxint(npoints, nvars, _state), nvars, 0, 1, 2, s2, &u, &vt, _state) ) 35060 ae_frame_leave(_state); 35065 for(i=0; i<=nvars-1; i++) 35067 s2->ptr.p_double[i] = ae_sqr(s2->ptr.p_double[i], _state)/(npoints-1); 35070 ae_matrix_set_length(v, nvars-1+1, nvars-1+1, _state); 35071 copyandtranspose(&vt, 0, nvars-1, 0, nvars-1, v, 0, nvars-1, 0, nvars-1, _state); 35072 ae_frame_leave(_state);
void mlprandomize(multilayerperceptron *network, ae_state *_state)
void mlpgradnbatch(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t ssize, double &e, real_1d_array &grad)
alglib_impl::multilayerperceptron * c_ptr()
void _mlpcvreport_clear(void *_p)
struct alglib_impl::ae_state ae_state
void mcpdcreateentryexit(const ae_int_t n, const ae_int_t entrystate, const ae_int_t exitstate, mcpdstate &s)
ae_int_t mlpgetlayerscount(const multilayerperceptron &network)
void mlpcreatetrainer(const ae_int_t nin, const ae_int_t nout, mlptrainer &s)
void mlpecreatec2(ae_int_t nin, ae_int_t nhid1, ae_int_t nhid2, ae_int_t nout, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void mlpsetdataset(const mlptrainer &s, const real_2d_array &xy, const ae_int_t npoints)
void mlpcreatetrainercls(const ae_int_t nin, const ae_int_t nclasses, mlptrainer &s)
void dserrfinish(ae_vector *buf, ae_state *_state)
void mlpeunserialize(std::string &s_in, mlpensemble &obj)
void _pexec_clusterizerrunahc(clusterizerstate *s, ahcreport *rep, ae_state *_state)
ae_bool ae_fp_greater_eq(double v1, double v2)
double smp_mlprmserrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
ae_bool _mlpreport_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
double mnlrmserror(const logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints)
double mlperrorsparsesubset(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t setsize, const integer_1d_array &subset, const ae_int_t subsetsize)
void mlpkfoldcvlm(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints, const double decay, const ae_int_t restarts, const ae_int_t foldscount, ae_int_t &info, mlpreport &rep, mlpcvreport &cvrep)
alglib_impl::logitmodel * c_ptr()
void ae_serializer_init(ae_serializer *serializer)
alglib_impl::multilayerperceptron * p_struct
void mlpecreate1(ae_int_t nin, ae_int_t nhid, ae_int_t nout, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void _cvreport_clear(void *_p)
void mlpecreate0(const ae_int_t nin, const ae_int_t nout, const ae_int_t ensemblesize, mlpensemble &ensemble)
double mlperrorsubset(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t setsize, const integer_1d_array &subset, const ae_int_t subsetsize)
void mlpcreateb0(const ae_int_t nin, const ae_int_t nout, const double b, const double d, multilayerperceptron &network)
void smp_mlptrainnetwork(const mlptrainer &s, const multilayerperceptron &network, const ae_int_t nrestarts, mlpreport &rep)
void rmatrixsyrk(const ae_int_t n, const ae_int_t k, const double alpha, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, const ae_int_t optypea, const double beta, const real_2d_array &c, const ae_int_t ic, const ae_int_t jc, const bool isupper)
void mlpeproperties(const mlpensemble &ensemble, ae_int_t &nin, ae_int_t &nout)
void dfprocessi(decisionforest *df, ae_vector *x, ae_vector *y, ae_state *_state)
alglib_impl::mlpcvreport * p_struct
double mlpavgrelerror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
ae_bool _linearmodel_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void mlpserialize(ae_serializer *s, multilayerperceptron *network, ae_state *_state)
double mlperror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void mlpecreateb1(const ae_int_t nin, const ae_int_t nhid, const ae_int_t nout, const double b, const double d, const ae_int_t ensemblesize, mlpensemble &ensemble)
void mlpecreatefromnetwork(const multilayerperceptron &network, const ae_int_t ensemblesize, mlpensemble &ensemble)
void mlpcreatec1(ae_int_t nin, ae_int_t nhid, ae_int_t nout, multilayerperceptron *network, ae_state *_state)
void mlpealloc(ae_serializer *s, mlpensemble *ensemble, ae_state *_state)
alglib_impl::mcpdreport * p_struct
void mcpdcreate(ae_int_t n, mcpdstate *s, ae_state *_state)
void rankdatacentered(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nfeatures)
ae_int_t _pexec_mlpclserror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void dsoptimalsplit2fast(real_1d_array &a, integer_1d_array &c, integer_1d_array &tiesbuf, integer_1d_array &cntbuf, real_1d_array &bufr, integer_1d_array &bufi, const ae_int_t n, const ae_int_t nc, const double alpha, ae_int_t &info, double &threshold, double &rms, double &cvrms)
void mnltrainh(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, ae_int_t &info, logitmodel &lm, mnlreport &rep)
ae_bool _lrreport_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void smp_mlpgradbatchsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t ssize, double &e, real_1d_array &grad)
double rms(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=nullptr, MultidimArray< double > *Contributions=nullptr)
void mlpecreatec0(ae_int_t nin, ae_int_t nout, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void lrbuildzs(ae_matrix *xy, ae_vector *s, ae_int_t npoints, ae_int_t nvars, ae_int_t *info, linearmodel *lm, lrreport *ar, ae_state *_state)
ae_bool _logitmodel_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
double smp_mlpavgerror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
virtual ~_multilayerperceptron_owner()
void mlpeserialize(mlpensemble &obj, std::string &s_out)
_mlptrainer_owner & operator=(const _mlptrainer_owner &rhs)
double _pexec_mlpavgrelerrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
void mlpstarttraining(mlptrainer *s, multilayerperceptron *network, ae_bool randomstart, ae_state *_state)
ae_int_t ae_serializer_get_alloc_size(ae_serializer *serializer)
void smp_clusterizergetdistances(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nfeatures, const ae_int_t disttype, real_2d_array &d)
void ae_serializer_sstart_str(ae_serializer *serializer, std::string *buf)
void smp_mlpkfoldcv(const mlptrainer &s, const multilayerperceptron &network, const ae_int_t nrestarts, const ae_int_t foldscount, mlpreport &rep)
ae_bool _mcpdreport_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void lrpack(ae_vector *v, ae_int_t nvars, linearmodel *lm, ae_state *_state)
_decisionforest_owner & operator=(const _decisionforest_owner &rhs)
double lravgrelerror(const linearmodel &lm, const real_2d_array &xy, const ae_int_t npoints)
double dfavgerror(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints)
void mnlprocess(const logitmodel &lm, const real_1d_array &x, real_1d_array &y)
bool mlpeissoftmax(const mlpensemble &ensemble)
void mlpcreatec2(const ae_int_t nin, const ae_int_t nhid1, const ae_int_t nhid2, const ae_int_t nout, multilayerperceptron &network)
integer_1d_array cvdefects
double _pexec_mlpavgerrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
alglib_impl::mlpensemble * c_ptr()
void _pexec_mlpgradbatchsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t ssize, double *e, ae_vector *grad, ae_state *_state)
ae_bool _dfreport_init(void *_p, ae_state *_state, ae_bool make_automatic)
alglib_impl::logitmodel * p_struct
void mlptrainlbfgs(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, double decay, ae_int_t restarts, double wstep, ae_int_t maxits, ae_int_t *info, mlpreport *rep, ae_state *_state)
void mlpeprocessi(const mlpensemble &ensemble, const real_1d_array &x, real_1d_array &y)
void filterlrma(ae_vector *x, ae_int_t n, ae_int_t k, ae_state *_state)
double ae_fabs(double x, ae_state *state)
double smp_mlprmserror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
_clusterizerstate_owner & operator=(const _clusterizerstate_owner &rhs)
double dsgetmeanmindistance(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_state *_state)
void mlpgradbatchsubset(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t setsize, const integer_1d_array &idx, const ae_int_t subsetsize, double &e, real_1d_array &grad)
void dssplitk(ae_vector *a, ae_vector *c, ae_int_t n, ae_int_t nc, ae_int_t kmax, ae_int_t *info, ae_vector *thresholds, ae_int_t *ni, double *cve, ae_state *_state)
void mlpgradnbatch(multilayerperceptron *network, ae_matrix *xy, ae_int_t ssize, double *e, ae_vector *grad, ae_state *_state)
double mlpavgrelerror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
void dstie(ae_vector *a, ae_int_t n, ae_vector *ties, ae_int_t *tiecount, ae_vector *p1, ae_vector *p2, ae_state *_state)
virtual ~_mlpcvreport_owner()
void clusterizerrunahc(clusterizerstate *s, ahcreport *rep, ae_state *_state)
alglib_impl::ahcreport * p_struct
void * ae_malloc(size_t size, ae_state *state)
void kmeansgenerate(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t k, ae_int_t restarts, ae_int_t *info, ae_matrix *c, ae_vector *xyc, ae_state *_state)
ae_int_t & terminationtype
ae_bool _mlpcvreport_init(void *_p, ae_state *_state, ae_bool make_automatic)
double lrprocess(const linearmodel &lm, const real_1d_array &x)
double mlpavgerrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
alglib_impl::modelerrors * c_ptr()
_multilayerperceptron_owner()
void filterema(real_1d_array &x, const ae_int_t n, const double alpha)
void _pexec_mlpkfoldcv(mlptrainer *s, multilayerperceptron *network, ae_int_t nrestarts, ae_int_t foldscount, mlpreport *rep, ae_state *_state)
union alglib_impl::ae_matrix::@12 ptr
alglib_impl::mlptrainer * p_struct
double smp_mlperror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
void mlpecreateb1(ae_int_t nin, ae_int_t nhid, ae_int_t nout, double b, double d, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
double _pexec_mlperrorsparsesubset(multilayerperceptron *network, sparsematrix *xy, ae_int_t setsize, ae_vector *subset, ae_int_t subsetsize, ae_state *_state)
alglib_impl::lrreport * c_ptr()
void dserraccumulate(ae_vector *buf, ae_vector *y, ae_vector *desiredy, ae_state *_state)
void mlpactivationfunction(double net, ae_int_t k, double *f, double *df, double *d2f, ae_state *_state)
void clusterizersetpoints(clusterizerstate *s, ae_matrix *xy, ae_int_t npoints, ae_int_t nfeatures, ae_int_t disttype, ae_state *_state)
void mlpproperties(multilayerperceptron *network, ae_int_t *nin, ae_int_t *nout, ae_int_t *wcount, ae_state *_state)
void dfserialize(decisionforest &obj, std::string &s_out)
ae_bool _mlpcvreport_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void ae_frame_make(ae_state *state, ae_frame *tmp)
void _pexec_clusterizergetdistances(ae_matrix *xy, ae_int_t npoints, ae_int_t nfeatures, ae_int_t disttype, ae_matrix *d, ae_state *_state)
void _logitmodel_clear(void *_p)
double mlprelclserrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
void lrbuild(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, ae_int_t &info, linearmodel &lm, lrreport &ar)
double mnlavgrelerror(const logitmodel &lm, const real_2d_array &xy, const ae_int_t ssize)
void dfbuildrandomdecisionforestx1(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, const ae_int_t ntrees, const ae_int_t nrndvars, const double r, ae_int_t &info, decisionforest &df, dfreport &rep)
void mlpcreate1(ae_int_t nin, ae_int_t nhid, ae_int_t nout, multilayerperceptron *network, ae_state *_state)
void _linearmodel_clear(void *_p)
void clusterizersetkmeanslimits(const clusterizerstate &s, const ae_int_t restarts, const ae_int_t maxits)
void _pexec_mlpallerrorssubset(multilayerperceptron *network, ae_matrix *xy, ae_int_t setsize, ae_vector *subset, ae_int_t subsetsize, modelerrors *rep, ae_state *_state)
ae_int_t mlpgetoutputscount(const multilayerperceptron &network)
virtual ~_mcpdstate_owner()
double mnlavgce(const logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints)
double mlpgetweight(const multilayerperceptron &network, const ae_int_t k0, const ae_int_t i0, const ae_int_t k1, const ae_int_t i1)
void mlpcreate2(ae_int_t nin, ae_int_t nhid1, ae_int_t nhid2, ae_int_t nout, multilayerperceptron *network, ae_state *_state)
_mcpdstate_owner & operator=(const _mcpdstate_owner &rhs)
void filterema(ae_vector *x, ae_int_t n, double alpha, ae_state *_state)
void lrbuildzs(const real_2d_array &xy, const real_1d_array &s, const ae_int_t npoints, const ae_int_t nvars, ae_int_t &info, linearmodel &lm, lrreport &ar)
void _mlptrainer_clear(void *_p)
void mlpecreateb0(ae_int_t nin, ae_int_t nout, double b, double d, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void mlpsetdecay(mlptrainer *s, double decay, ae_state *_state)
alglib_impl::mlpcvreport * c_ptr()
bool mlpissoftmax(const multilayerperceptron &network)
void mlpserialize(multilayerperceptron &obj, std::string &s_out)
bool mlpcontinuetraining(const mlptrainer &s, const multilayerperceptron &network)
void _pexec_mlpallerrorssparsesubset(multilayerperceptron *network, sparsematrix *xy, ae_int_t setsize, ae_vector *subset, ae_int_t subsetsize, modelerrors *rep, ae_state *_state)
void _mlpreport_clear(void *_p)
void _mnlreport_clear(void *_p)
void mlpallerrorssubset(multilayerperceptron *network, ae_matrix *xy, ae_int_t setsize, ae_vector *subset, ae_int_t subsetsize, modelerrors *rep, ae_state *_state)
void mlphessiannbatch(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t ssize, double &e, real_1d_array &grad, real_2d_array &h)
ae_bool _mcpdstate_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void mlptrainensemblees(mlptrainer *s, mlpensemble *ensemble, ae_int_t nrestarts, mlpreport *rep, ae_state *_state)
void mlpkfoldcv(mlptrainer *s, multilayerperceptron *network, ae_int_t nrestarts, ae_int_t foldscount, mlpreport *rep, ae_state *_state)
double _pexec_mlperror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void mlpgradbatchsparsesubset(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t setsize, const integer_1d_array &idx, const ae_int_t subsetsize, double &e, real_1d_array &grad)
void mlpcreatec2(ae_int_t nin, ae_int_t nhid1, ae_int_t nhid2, ae_int_t nout, multilayerperceptron *network, ae_state *_state)
double smp_mlprelclserrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
double mlpavgcesparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
void dfprocess(decisionforest *df, ae_vector *x, ae_vector *y, ae_state *_state)
ae_bool apservisfinitematrix(ae_matrix *x, ae_int_t m, ae_int_t n, ae_state *_state)
double lravgrelerror(linearmodel *lm, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void _ahcreport_clear(void *_p)
void mlpunserialize(std::string &s_in, multilayerperceptron &obj)
double smp_mlprelclserror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
ae_int_t mlpgetinputscount(multilayerperceptron *network, ae_state *_state)
void ae_serializer_ustart_str(ae_serializer *serializer, const std::string *buf)
void mlpsetcond(const mlptrainer &s, const double wstep, const ae_int_t maxits)
void mlpsetalgobatch(const mlptrainer &s)
void mlperandomize(const mlpensemble &ensemble)
void mlpgrad(const multilayerperceptron &network, const real_1d_array &x, const real_1d_array &desiredy, double &e, real_1d_array &grad)
void mcpdaddtrack(mcpdstate *s, ae_matrix *xy, ae_int_t k, ae_state *_state)
void mlpecreatec0(const ae_int_t nin, const ae_int_t nout, const ae_int_t ensemblesize, mlpensemble &ensemble)
alglib_impl::decisionforest * p_struct
double _pexec_mlprmserror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
_multilayerperceptron_owner & operator=(const _multilayerperceptron_owner &rhs)
void mlptrainensemblees(const mlptrainer &s, const mlpensemble &ensemble, const ae_int_t nrestarts, mlpreport &rep)
void clusterizerseparatedbycorr(const ahcreport &rep, const double r, ae_int_t &k, integer_1d_array &cidx, integer_1d_array &cz)
void mlpebagginglm(mlpensemble *ensemble, ae_matrix *xy, ae_int_t npoints, double decay, ae_int_t restarts, ae_int_t *info, mlpreport *rep, mlpcvreport *ooberrors, ae_state *_state)
ae_bool _cvreport_init(void *_p, ae_state *_state, ae_bool make_automatic)
ae_int_t mlpgetlayersize(const multilayerperceptron &network, const ae_int_t k)
double mnlrelclserror(const logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints)
void mlpeprocessi(mlpensemble *ensemble, ae_vector *x, ae_vector *y, ae_state *_state)
void dfbuildrandomdecisionforestx1(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t nclasses, ae_int_t ntrees, ae_int_t nrndvars, double r, ae_int_t *info, decisionforest *df, dfreport *rep, ae_state *_state)
void mlpcreater0(ae_int_t nin, ae_int_t nout, double a, double b, multilayerperceptron *network, ae_state *_state)
ae_int_t mlpgetweightscount(const multilayerperceptron &network)
double _pexec_mlprmserrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
double mnlavgerror(const logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints)
void ae_serializer_stop(ae_serializer *serializer)
mlpcvreport & operator=(const mlpcvreport &rhs)
void mlperandomize(mlpensemble *ensemble, ae_state *_state)
void ae_state_clear(ae_state *state)
const alglib_impl::ae_matrix * c_ptr() const
ae_bool _modelerrors_init(void *_p, ae_state *_state, ae_bool make_automatic)
void mlprandomize(const multilayerperceptron &network)
void clusterizergetkclusters(const ahcreport &rep, const ae_int_t k, integer_1d_array &cidx, integer_1d_array &cz)
ae_bool ae_fp_eq(double v1, double v2)
void mcpdsetbc(mcpdstate *s, ae_matrix *bndl, ae_matrix *bndu, ae_state *_state)
double mlprmserror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void mcpdaddtrack(const mcpdstate &s, const real_2d_array &xy, const ae_int_t k)
alglib_impl::dfreport * c_ptr()
void dfserialize(ae_serializer *s, decisionforest *forest, ae_state *_state)
alglib_impl::dfreport * p_struct
void mlpsetoutputscaling(multilayerperceptron *network, ae_int_t i, double mean, double sigma, ae_state *_state)
void mlptraines(const multilayerperceptron &network, const real_2d_array &trnxy, const ae_int_t trnsize, const real_2d_array &valxy, const ae_int_t valsize, const double decay, const ae_int_t restarts, ae_int_t &info, mlpreport &rep)
void mlpkfoldcv(const mlptrainer &s, const multilayerperceptron &network, const ae_int_t nrestarts, const ae_int_t foldscount, mlpreport &rep)
void mcpdsolve(mcpdstate *s, ae_state *_state)
ae_int_t mnlclserror(const logitmodel &lm, const real_2d_array &xy, const ae_int_t npoints)
void mlprandomizefull(const multilayerperceptron &network)
lrreport & operator=(const lrreport &rhs)
double mlprelclserrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
void mlpecreater1(ae_int_t nin, ae_int_t nhid, ae_int_t nout, double a, double b, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
_mcpdreport_owner & operator=(const _mcpdreport_owner &rhs)
void mlpgetinputscaling(const multilayerperceptron &network, const ae_int_t i, double &mean, double &sigma)
alglib_impl::mcpdreport * c_ptr()
ae_bool _mnlreport_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void mlpsetcond(mlptrainer *s, double wstep, ae_int_t maxits, ae_state *_state)
void lrbuildz(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t *info, linearmodel *lm, lrreport *ar, ae_state *_state)
void mlphessianbatch(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t ssize, double &e, real_1d_array &grad, real_2d_array &h)
alglib_impl::modelerrors * p_struct
void _multilayerperceptron_clear(void *_p)
void mlpecreate2(const ae_int_t nin, const ae_int_t nhid1, const ae_int_t nhid2, const ae_int_t nout, const ae_int_t ensemblesize, mlpensemble &ensemble)
ae_bool ae_matrix_init(ae_matrix *dst, ae_int_t rows, ae_int_t cols, ae_datatype datatype, ae_state *state, ae_bool make_automatic)
void mcpdcreateentryexit(ae_int_t n, ae_int_t entrystate, ae_int_t exitstate, mcpdstate *s, ae_state *_state)
double dfavgrelerror(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints)
void dsoptimalsplit2(const real_1d_array &a, const integer_1d_array &c, const ae_int_t n, ae_int_t &info, double &threshold, double &pal, double &pbl, double &par, double &pbr, double &cve)
void mcpdcreateexit(const ae_int_t n, const ae_int_t exitstate, mcpdstate &s)
void dfalloc(ae_serializer *s, decisionforest *forest, ae_state *_state)
alglib_impl::mlpreport * p_struct
mnlreport & operator=(const mnlreport &rhs)
void clusterizerrunkmeans(clusterizerstate *s, ae_int_t k, kmeansreport *rep, ae_state *_state)
alglib_impl::mlpensemble * p_struct
double mlpavgerrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
double mnlavgerror(logitmodel *lm, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
double mlperrorn(multilayerperceptron *network, ae_matrix *xy, ae_int_t ssize, ae_state *_state)
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
void pcabuildbasis(const real_2d_array &x, const ae_int_t npoints, const ae_int_t nvars, ae_int_t &info, real_1d_array &s2, real_2d_array &v)
ae_bool _clusterizerstate_init(void *_p, ae_state *_state, ae_bool make_automatic)
void _mcpdreport_clear(void *_p)
void dstiefasti(ae_vector *a, ae_vector *b, ae_int_t n, ae_vector *ties, ae_int_t *tiecount, ae_vector *bufr, ae_vector *bufi, ae_state *_state)
void mcpdcreate(const ae_int_t n, mcpdstate &s)
logitmodel & operator=(const logitmodel &rhs)
virtual ~_mcpdreport_owner()
void mcpdaddec(const mcpdstate &s, const ae_int_t i, const ae_int_t j, const double c)
_mlpensemble_owner & operator=(const _mlpensemble_owner &rhs)
void mcpdsetpredictionweights(mcpdstate *s, ae_vector *pw, ae_state *_state)
void mlpecreatec1(const ae_int_t nin, const ae_int_t nhid, const ae_int_t nout, const ae_int_t ensemblesize, mlpensemble &ensemble)
linearmodel & operator=(const linearmodel &rhs)
void mlpgradn(multilayerperceptron *network, ae_vector *x, ae_vector *desiredy, double *e, ae_vector *grad, ae_state *_state)
void mlpgrad(multilayerperceptron *network, ae_vector *x, ae_vector *desiredy, double *e, ae_vector *grad, ae_state *_state)
void ae_serializer_clear(ae_serializer *serializer)
void mlpecreater0(ae_int_t nin, ae_int_t nout, double a, double b, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void mcpdsetbc(const mcpdstate &s, const real_2d_array &bndl, const real_2d_array &bndu)
ae_bool _lrreport_init(void *_p, ae_state *_state, ae_bool make_automatic)
void mlpsetdataset(mlptrainer *s, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
alglib_impl::mlptrainer * c_ptr()
void mlpgetoutputscaling(multilayerperceptron *network, ae_int_t i, double *mean, double *sigma, ae_state *_state)
void _pexec_mlptrainensemblees(mlptrainer *s, mlpensemble *ensemble, ae_int_t nrestarts, mlpreport *rep, ae_state *_state)
void mlpallerrorssparsesubset(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t setsize, const integer_1d_array &subset, const ae_int_t subsetsize, modelerrors &rep)
alglib_impl::clusterizerstate * c_ptr()
void mlpecreater2(const ae_int_t nin, const ae_int_t nhid1, const ae_int_t nhid2, const ae_int_t nout, const double a, const double b, const ae_int_t ensemblesize, mlpensemble &ensemble)
void mlpecreate2(ae_int_t nin, ae_int_t nhid1, ae_int_t nhid2, ae_int_t nout, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void fisherldan(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, ae_int_t &info, real_2d_array &w)
void dsnormalize(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t *info, ae_vector *means, ae_vector *sigmas, ae_state *_state)
void clusterizersetahcalgo(const clusterizerstate &s, const ae_int_t algo)
void threshold(double *phi, unsigned long nvox, double limit)
mlptrainer & operator=(const mlptrainer &rhs)
double mlperelclserror(mlpensemble *ensemble, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
ae_bool _linearmodel_init(void *_p, ae_state *_state, ae_bool make_automatic)
void mlpsetdecay(const mlptrainer &s, const double decay)
void dsnormalizec(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t *info, ae_vector *means, ae_vector *sigmas, ae_state *_state)
ae_bool _kmeansreport_init(void *_p, ae_state *_state, ae_bool make_automatic)
double mlprelclserror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
mcpdstate & operator=(const mcpdstate &rhs)
virtual ~_ahcreport_owner()
void mcpdcreateentry(ae_int_t n, ae_int_t entrystate, mcpdstate *s, ae_state *_state)
double mnlavgrelerror(logitmodel *lm, ae_matrix *xy, ae_int_t ssize, ae_state *_state)
ae_int_t ae_v_len(ae_int_t a, ae_int_t b)
virtual ~_mlpreport_owner()
void mlptrainnetwork(mlptrainer *s, multilayerperceptron *network, ae_int_t nrestarts, mlpreport *rep, ae_state *_state)
virtual ~decisionforest()
void mnlprocessi(logitmodel *lm, ae_vector *x, ae_vector *y, ae_state *_state)
ae_bool _dfreport_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void mcpdaddbc(const mcpdstate &s, const ae_int_t i, const ae_int_t j, const double bndl, const double bndu)
multilayerperceptron & operator=(const multilayerperceptron &rhs)
void mlpactivationfunction(const double net, const ae_int_t k, double &f, double &df, double &d2f)
double mlpeavgrelerror(const mlpensemble &ensemble, const real_2d_array &xy, const ae_int_t npoints)
ae_int_t mlpclserror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void dsoptimalsplit2fast(ae_vector *a, ae_vector *c, ae_vector *tiesbuf, ae_vector *cntbuf, ae_vector *bufr, ae_vector *bufi, ae_int_t n, ae_int_t nc, double alpha, ae_int_t *info, double *threshold, double *rms, double *cvrms, ae_state *_state)
void mlpetraines(mlpensemble *ensemble, ae_matrix *xy, ae_int_t npoints, double decay, ae_int_t restarts, ae_int_t *info, mlpreport *rep, ae_state *_state)
virtual ~_mlpensemble_owner()
double dfavgrelerror(decisionforest *df, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
double smp_mlperrorsubset(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t setsize, const integer_1d_array &subset, const ae_int_t subsetsize)
void tagsort(ae_vector *a, ae_int_t n, ae_vector *p1, ae_vector *p2, ae_state *_state)
void mlpkfoldcvlm(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, double decay, ae_int_t restarts, ae_int_t foldscount, ae_int_t *info, mlpreport *rep, mlpcvreport *cvrep, ae_state *_state)
double mlpeavgerror(mlpensemble *ensemble, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void mcpdsetprior(mcpdstate *s, ae_matrix *pp, ae_state *_state)
void smp_mlpgradbatchsparsesubset(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t setsize, const integer_1d_array &idx, const ae_int_t subsetsize, double &e, real_1d_array &grad)
double mlperror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
void kmeansgenerateinternal(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t k, ae_int_t maxits, ae_int_t restarts, ae_int_t *info, ae_matrix *ccol, ae_bool needccol, ae_matrix *crow, ae_bool needcrow, ae_vector *xyc, ae_state *_state)
double mlpavgerror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
double mlprelclserror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
ae_bool _ahcreport_init(void *_p, ae_state *_state, ae_bool make_automatic)
void mlpecreate0(ae_int_t nin, ae_int_t nout, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void _clusterizerstate_clear(void *_p)
void lrbuildz(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, ae_int_t &info, linearmodel &lm, lrreport &ar)
void mlpgradbatch(multilayerperceptron *network, ae_matrix *xy, ae_int_t ssize, double *e, ae_vector *grad, ae_state *_state)
double dfrelclserror(decisionforest *df, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
double mlperrorsubset(multilayerperceptron *network, ae_matrix *xy, ae_int_t setsize, ae_vector *subset, ae_int_t subsetsize, ae_state *_state)
ae_bool _mnlreport_init(void *_p, ae_state *_state, ae_bool make_automatic)
void mlpcreate1(const ae_int_t nin, const ae_int_t nhid, const ae_int_t nout, multilayerperceptron &network)
double mlpgetweight(multilayerperceptron *network, ae_int_t k0, ae_int_t i0, ae_int_t k1, ae_int_t i1, ae_state *_state)
void ae_v_move(double *vdst, ae_int_t stride_dst, const double *vsrc, ae_int_t stride_src, ae_int_t n)
ae_int_t mlpgetlayerscount(multilayerperceptron *network, ae_state *_state)
void mlpgetinputscaling(multilayerperceptron *network, ae_int_t i, double *mean, double *sigma, ae_state *_state)
void mlpallerrorssubset(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t setsize, const integer_1d_array &subset, const ae_int_t subsetsize, modelerrors &rep)
void mlpecreateb2(ae_int_t nin, ae_int_t nhid1, ae_int_t nhid2, ae_int_t nout, double b, double d, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void fisherlda(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, ae_int_t &info, real_1d_array &w)
ae_int_t & terminationtype
void mlpeproperties(mlpensemble *ensemble, ae_int_t *nin, ae_int_t *nout, ae_state *_state)
alglib_impl::mcpdstate * c_ptr()
void clusterizercreate(clusterizerstate *s, ae_state *_state)
double smp_mlpavgrelerrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
void ae_vector_clear(ae_vector *dst)
void mlpgetneuroninfo(const multilayerperceptron &network, const ae_int_t k, const ae_int_t i, ae_int_t &fkind, double &threshold)
void mlphessianbatch(multilayerperceptron *network, ae_matrix *xy, ae_int_t ssize, double *e, ae_vector *grad, ae_matrix *h, ae_state *_state)
void mlphessiannbatch(multilayerperceptron *network, ae_matrix *xy, ae_int_t ssize, double *e, ae_vector *grad, ae_matrix *h, ae_state *_state)
double dfrmserror(decisionforest *df, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
_lrreport_owner & operator=(const _lrreport_owner &rhs)
void rmatrixcopy(const ae_int_t m, const ae_int_t n, const real_2d_array &a, const ae_int_t ia, const ae_int_t ja, real_2d_array &b, const ae_int_t ib, const ae_int_t jb)
double mlpeavgrelerror(mlpensemble *ensemble, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void dsoptimalsplit2(ae_vector *a, ae_vector *c, ae_int_t n, ae_int_t *info, double *threshold, double *pal, double *pbl, double *par, double *pbr, double *cve, ae_state *_state)
ae_bool mlpeissoftmax(mlpensemble *ensemble, ae_state *_state)
void clusterizergetkclusters(ahcreport *rep, ae_int_t k, ae_vector *cidx, ae_vector *cz, ae_state *_state)
void _lrreport_clear(void *_p)
ae_bool ae_fp_less(double v1, double v2)
void mlpunserialize(ae_serializer *s, multilayerperceptron *network, ae_state *_state)
virtual ~multilayerperceptron()
double _pexec_mlperrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
void mlpprocessi(const multilayerperceptron &network, const real_1d_array &x, real_1d_array &y)
void mlpcreate2(const ae_int_t nin, const ae_int_t nhid1, const ae_int_t nhid2, const ae_int_t nout, multilayerperceptron &network)
mlpensemble & operator=(const mlpensemble &rhs)
ae_bool _multilayerperceptron_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void lrbuild(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t *info, linearmodel *lm, lrreport *ar, ae_state *_state)
double dfavgce(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints)
double mlpeavgce(mlpensemble *ensemble, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void mcpdcreateentry(const ae_int_t n, const ae_int_t entrystate, mcpdstate &s)
double smp_mlperrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
void mlpgradbatchsparsesubset(multilayerperceptron *network, sparsematrix *xy, ae_int_t setsize, ae_vector *idx, ae_int_t subsetsize, double *e, ae_vector *grad, ae_state *_state)
void mlpcreater1(const ae_int_t nin, const ae_int_t nhid, const ae_int_t nout, const double a, const double b, multilayerperceptron &network)
double mlpermserror(mlpensemble *ensemble, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void mlpsetweight(multilayerperceptron *network, ae_int_t k0, ae_int_t i0, ae_int_t k1, ae_int_t i1, double w, ae_state *_state)
void mlpkfoldcvlbfgs(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints, const double decay, const ae_int_t restarts, const double wstep, const ae_int_t maxits, const ae_int_t foldscount, ae_int_t &info, mlpreport &rep, mlpcvreport &cvrep)
void _kmeansreport_clear(void *_p)
ae_bool _modelerrors_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void filtersma(real_1d_array &x, const ae_int_t n, const ae_int_t k)
alglib_impl::mcpdstate * p_struct
void mcpdresults(mcpdstate *s, ae_matrix *p, mcpdreport *rep, ae_state *_state)
virtual ~_logitmodel_owner()
void mcpdsetec(mcpdstate *s, ae_matrix *ec, ae_state *_state)
void mcpdsettikhonovregularizer(mcpdstate *s, double v, ae_state *_state)
void mlpsetalgobatch(mlptrainer *s, ae_state *_state)
void mlpgetoutputscaling(const multilayerperceptron &network, const ae_int_t i, double &mean, double &sigma)
void mlpcreatec0(ae_int_t nin, ae_int_t nout, multilayerperceptron *network, ae_state *_state)
alglib_impl::mnlreport * c_ptr()
void clusterizercreate(clusterizerstate &s)
void mlpstarttraining(const mlptrainer &s, const multilayerperceptron &network, const bool randomstart)
_dfreport_owner & operator=(const _dfreport_owner &rhs)
void mlpcreateb2(ae_int_t nin, ae_int_t nhid1, ae_int_t nhid2, ae_int_t nout, double b, double d, multilayerperceptron *network, ae_state *_state)
ae_bool ae_fp_neq(double v1, double v2)
void mnlpack(const real_2d_array &a, const ae_int_t nvars, const ae_int_t nclasses, logitmodel &lm)
double mlpavgerror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void mcpdaddbc(mcpdstate *s, ae_int_t i, ae_int_t j, double bndl, double bndu, ae_state *_state)
ae_bool mlpissoftmax(multilayerperceptron *network, ae_state *_state)
void mnlprocess(logitmodel *lm, ae_vector *x, ae_vector *y, ae_state *_state)
void ae_touch_ptr(void *p)
virtual ~_mnlreport_owner()
decisionforest & operator=(const decisionforest &rhs)
void smp_mlpallerrorssparsesubset(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t setsize, const integer_1d_array &subset, const ae_int_t subsetsize, modelerrors &rep)
void mlpcreateb2(const ae_int_t nin, const ae_int_t nhid1, const ae_int_t nhid2, const ae_int_t nout, const double b, const double d, multilayerperceptron &network)
void mlpcreatetrainercls(ae_int_t nin, ae_int_t nclasses, mlptrainer *s, ae_state *_state)
ae_bool _mlpensemble_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void mlpecreatec2(const ae_int_t nin, const ae_int_t nhid1, const ae_int_t nhid2, const ae_int_t nout, const ae_int_t ensemblesize, mlpensemble &ensemble)
ae_bool _multilayerperceptron_init(void *_p, ae_state *_state, ae_bool make_automatic)
void mnltrainh(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t nclasses, ae_int_t *info, logitmodel *lm, mnlreport *rep, ae_state *_state)
double ae_maxreal(double m1, double m2, ae_state *state)
void lrpack(const real_1d_array &v, const ae_int_t nvars, linearmodel &lm)
ae_bool _kmeansreport_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
double smp_mlpavgce(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
alglib_impl::linearmodel * c_ptr()
void mlpcreateb0(ae_int_t nin, ae_int_t nout, double b, double d, multilayerperceptron *network, ae_state *_state)
void mcpdaddec(mcpdstate *s, ae_int_t i, ae_int_t j, double c, ae_state *_state)
void clusterizersetdistances(clusterizerstate *s, ae_matrix *d, ae_int_t npoints, ae_bool isupper, ae_state *_state)
void mlpetraines(const mlpensemble &ensemble, const real_2d_array &xy, const ae_int_t npoints, const double decay, const ae_int_t restarts, ae_int_t &info, mlpreport &rep)
void mlpebagginglbfgs(const mlpensemble &ensemble, const real_2d_array &xy, const ae_int_t npoints, const double decay, const ae_int_t restarts, const double wstep, const ae_int_t maxits, ae_int_t &info, mlpreport &rep, mlpcvreport &ooberrors)
void lrbuilds(ae_matrix *xy, ae_vector *s, ae_int_t npoints, ae_int_t nvars, ae_int_t *info, linearmodel *lm, lrreport *ar, ae_state *_state)
ae_bool ae_vector_set_length(ae_vector *dst, ae_int_t newsize, ae_state *state)
void mlpcreateb1(ae_int_t nin, ae_int_t nhid, ae_int_t nout, double b, double d, multilayerperceptron *network, ae_state *_state)
virtual ~_kmeansreport_owner()
void mlpsetneuroninfo(multilayerperceptron *network, ae_int_t k, ae_int_t i, ae_int_t fkind, double threshold, ae_state *_state)
void mlpcreateb1(const ae_int_t nin, const ae_int_t nhid, const ae_int_t nout, const double b, const double d, multilayerperceptron &network)
double _pexec_mlpavgerror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void ae_v_sub(double *vdst, ae_int_t stride_dst, const double *vsrc, ae_int_t stride_src, ae_int_t n)
void mlpsetinputscaling(const multilayerperceptron &network, const ae_int_t i, const double mean, const double sigma)
void mlpkfoldcvlbfgs(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, double decay, ae_int_t restarts, double wstep, ae_int_t maxits, ae_int_t foldscount, ae_int_t *info, mlpreport *rep, mlpcvreport *cvrep, ae_state *_state)
double mlperrorsparsesubset(multilayerperceptron *network, sparsematrix *xy, ae_int_t setsize, ae_vector *subset, ae_int_t subsetsize, ae_state *_state)
void dfbuildrandomdecisionforest(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t nclasses, const ae_int_t ntrees, const double r, ae_int_t &info, decisionforest &df, dfreport &rep)
virtual ~clusterizerstate()
ae_bool _mcpdreport_init(void *_p, ae_state *_state, ae_bool make_automatic)
alglib_impl::clusterizerstate * p_struct
double mlpeavgce(const mlpensemble &ensemble, const real_2d_array &xy, const ae_int_t npoints)
void lrbuilds(const real_2d_array &xy, const real_1d_array &s, const ae_int_t npoints, const ae_int_t nvars, ae_int_t &info, linearmodel &lm, lrreport &ar)
void mlpgradbatch(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t ssize, double &e, real_1d_array &grad)
void mlpgradbatchsubset(multilayerperceptron *network, ae_matrix *xy, ae_int_t setsize, ae_vector *idx, ae_int_t subsetsize, double *e, ae_vector *grad, ae_state *_state)
void _mlpensemble_clear(void *_p)
void _pexec_mlpgradbatchsubset(multilayerperceptron *network, ae_matrix *xy, ae_int_t setsize, ae_vector *idx, ae_int_t subsetsize, double *e, ae_vector *grad, ae_state *_state)
double smp_mlpavgrelerror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
void smp_mlpgradbatchsubset(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t setsize, const integer_1d_array &idx, const ae_int_t subsetsize, double &e, real_1d_array &grad)
virtual ~_linearmodel_owner()
double ae_log(double x, ae_state *state)
double mlpavgcesparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
struct alglib_impl::ae_vector ae_vector
ae_bool _apbuffers_init(void *_p, ae_state *_state, ae_bool make_automatic)
void mnlunpack(logitmodel *lm, ae_matrix *a, ae_int_t *nvars, ae_int_t *nclasses, ae_state *_state)
void mlpgetneuroninfo(multilayerperceptron *network, ae_int_t k, ae_int_t i, ae_int_t *fkind, double *threshold, ae_state *_state)
double mlpavgrelerrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
const alglib_impl::ae_vector * c_ptr() const
void mlpecreater0(const ae_int_t nin, const ae_int_t nout, const double a, const double b, const ae_int_t ensemblesize, mlpensemble &ensemble)
double mlperrorn(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t ssize)
double mnlavgce(logitmodel *lm, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
double ae_minreal(double m1, double m2, ae_state *state)
void mlpprocessi(multilayerperceptron *network, ae_vector *x, ae_vector *y, ae_state *_state)
struct alglib_impl::ae_shared_pool ae_shared_pool
void mcpdcreateexit(ae_int_t n, ae_int_t exitstate, mcpdstate *s, ae_state *_state)
void mlpecreateb0(const ae_int_t nin, const ae_int_t nout, const double b, const double d, const ae_int_t ensemblesize, mlpensemble &ensemble)
ae_bool _mcpdstate_init(void *_p, ae_state *_state, ae_bool make_automatic)
double mlperrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
void fisherldan(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t nclasses, ae_int_t *info, ae_matrix *w, ae_state *_state)
alglib_impl::linearmodel * p_struct
ae_bool mlpcontinuetraining(mlptrainer *s, multilayerperceptron *network, ae_state *_state)
double mlprmserrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
ae_int_t smp_mlpclserror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
double mnlrmserror(logitmodel *lm, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void lrunpack(const linearmodel &lm, real_1d_array &v, ae_int_t &nvars)
alglib_impl::kmeansreport * p_struct
ae_bool _pexec_mlpcontinuetraining(mlptrainer *s, multilayerperceptron *network, ae_state *_state)
void mlpprocess(const multilayerperceptron &network, const real_1d_array &x, real_1d_array &y)
void mlptrainlm(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, double decay, ae_int_t restarts, ae_int_t *info, mlpreport *rep, ae_state *_state)
dfreport & operator=(const dfreport &rhs)
double dfrelclserror(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints)
_mnlreport_owner & operator=(const _mnlreport_owner &rhs)
struct alglib_impl::ae_matrix ae_matrix
void mlpeserialize(ae_serializer *s, mlpensemble *ensemble, ae_state *_state)
virtual ~_dfreport_owner()
void mlprandomizefull(multilayerperceptron *network, ae_state *_state)
void _pexec_mlpgradbatchsparsesubset(multilayerperceptron *network, sparsematrix *xy, ae_int_t setsize, ae_vector *idx, ae_int_t subsetsize, double *e, ae_vector *grad, ae_state *_state)
ae_int_t ae_iabs(ae_int_t x, ae_state *state)
void dfprocessi(const decisionforest &df, const real_1d_array &x, real_1d_array &y)
void _pexec_mlpgradbatch(multilayerperceptron *network, ae_matrix *xy, ae_int_t ssize, double *e, ae_vector *grad, ae_state *_state)
void mlpeprocess(mlpensemble *ensemble, ae_vector *x, ae_vector *y, ae_state *_state)
void ae_state_init(ae_state *state)
void mcpdsetlc(const mcpdstate &s, const real_2d_array &c, const integer_1d_array &ct, const ae_int_t k)
double lrrmserror(const linearmodel &lm, const real_2d_array &xy, const ae_int_t npoints)
double lrprocess(linearmodel *lm, ae_vector *x, ae_state *_state)
void touchint(ae_int_t *a, ae_state *_state)
double mlperelclserror(const mlpensemble &ensemble, const real_2d_array &xy, const ae_int_t npoints)
void rmatrixsetlengthatleast(ae_matrix *x, ae_int_t m, ae_int_t n, ae_state *_state)
double ae_sqrt(double x, ae_state *state)
alglib_impl::mlpreport * c_ptr()
void ae_assert(ae_bool cond, const char *msg, ae_state *state)
union alglib_impl::ae_vector::@11 ptr
void mlpallerrorssparsesubset(multilayerperceptron *network, sparsematrix *xy, ae_int_t setsize, ae_vector *subset, ae_int_t subsetsize, modelerrors *rep, ae_state *_state)
void _dfreport_clear(void *_p)
void kmeansgenerate(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nvars, const ae_int_t k, const ae_int_t restarts, ae_int_t &info, real_2d_array &c, integer_1d_array &xyc)
double _pexec_mlprelclserrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
void mlpcreater2(const ae_int_t nin, const ae_int_t nhid1, const ae_int_t nhid2, const ae_int_t nout, const double a, const double b, multilayerperceptron &network)
double _pexec_mlpavgrelerror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
ae_bool _mlpreport_init(void *_p, ae_state *_state, ae_bool make_automatic)
double _pexec_mlprelclserror(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void ae_serializer_alloc_start(ae_serializer *serializer)
void mlpgradbatchsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t ssize, double &e, real_1d_array &grad)
const char *volatile error_msg
double mlpavgce(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
void mlpprocess(multilayerperceptron *network, ae_vector *x, ae_vector *y, ae_state *_state)
void _decisionforest_clear(void *_p)
_linearmodel_owner & operator=(const _linearmodel_owner &rhs)
alglib_impl::kmeansreport * c_ptr()
clusterizerstate & operator=(const clusterizerstate &rhs)
void mlptrainlbfgs(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints, const double decay, const ae_int_t restarts, const double wstep, const ae_int_t maxits, ae_int_t &info, mlpreport &rep)
ae_int_t mlpgetinputscount(const multilayerperceptron &network)
mcpdreport & operator=(const mcpdreport &rhs)
void dserrallocate(ae_int_t nclasses, ae_vector *buf, ae_state *_state)
void samplemoments(const real_1d_array &x, const ae_int_t n, double &mean, double &variance, double &skewness, double &kurtosis)
void mlpecreateb2(const ae_int_t nin, const ae_int_t nhid1, const ae_int_t nhid2, const ae_int_t nout, const double b, const double d, const ae_int_t ensemblesize, mlpensemble &ensemble)
void smp_clusterizerrunahc(const clusterizerstate &s, ahcreport &rep)
void fisherlda(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t nclasses, ae_int_t *info, ae_vector *w, ae_state *_state)
double smp_mlpavgerrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
ae_bool _cvreport_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void _mcpdstate_clear(void *_p)
ae_bool _decisionforest_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void mlpcreater2(ae_int_t nin, ae_int_t nhid1, ae_int_t nhid2, ae_int_t nout, double a, double b, multilayerperceptron *network, ae_state *_state)
void rmatrixenforcesymmetricity(const real_2d_array &a, const ae_int_t n, const bool isupper)
#define ae_machineepsilon
void mlpcreatec0(const ae_int_t nin, const ae_int_t nout, multilayerperceptron &network)
double mlpermserror(const mlpensemble &ensemble, const real_2d_array &xy, const ae_int_t npoints)
void clusterizersetpoints(const clusterizerstate &s, const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nfeatures, const ae_int_t disttype)
void pcabuildbasis(ae_matrix *x, ae_int_t npoints, ae_int_t nvars, ae_int_t *info, ae_vector *s2, ae_matrix *v, ae_state *_state)
ae_bool _mlpensemble_init(void *_p, ae_state *_state, ae_bool make_automatic)
void mlpproperties(const multilayerperceptron &network, ae_int_t &nin, ae_int_t &nout, ae_int_t &wcount)
void mlpeprocess(const mlpensemble &ensemble, const real_1d_array &x, real_1d_array &y)
void mcpdsetec(const mcpdstate &s, const real_2d_array &ec)
modelerrors & operator=(const modelerrors &rhs)
ae_bool _clusterizerstate_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void mcpdsetprior(const mcpdstate &s, const real_2d_array &pp)
void clusterizerrunkmeans(const clusterizerstate &s, const ae_int_t k, kmeansreport &rep)
ae_int_t mlpclserror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
void mnlunpack(const logitmodel &lm, real_2d_array &a, ae_int_t &nvars, ae_int_t &nclasses)
void mlpecreatec1(ae_int_t nin, ae_int_t nhid, ae_int_t nout, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void clusterizerseparatedbydist(const ahcreport &rep, const double r, ae_int_t &k, integer_1d_array &cidx, integer_1d_array &cz)
void mlptrainnetwork(const mlptrainer &s, const multilayerperceptron &network, const ae_int_t nrestarts, mlpreport &rep)
void clusterizergetdistances(ae_matrix *xy, ae_int_t npoints, ae_int_t nfeatures, ae_int_t disttype, ae_matrix *d, ae_state *_state)
double lravgerror(linearmodel *lm, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void mlpeunserialize(ae_serializer *s, mlpensemble *ensemble, ae_state *_state)
void lrunpack(linearmodel *lm, ae_vector *v, ae_int_t *nvars, ae_state *_state)
void dsoptimalsplitk(ae_vector *a, ae_vector *c, ae_int_t n, ae_int_t nc, ae_int_t kmax, ae_int_t *info, ae_vector *thresholds, ae_int_t *ni, double *cve, ae_state *_state)
ae_bool ae_vector_init(ae_vector *dst, ae_int_t size, ae_datatype datatype, ae_state *state, ae_bool make_automatic)
void mlpcreate0(ae_int_t nin, ae_int_t nout, multilayerperceptron *network, ae_state *_state)
void smp_mlpallerrorssubset(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t setsize, const integer_1d_array &subset, const ae_int_t subsetsize, modelerrors &rep)
void mlpcreatetrainer(ae_int_t nin, ae_int_t nout, mlptrainer *s, ae_state *_state)
ae_bool ae_isfinite(double x, ae_state *state)
double ae_sqr(double x, ae_state *state)
alglib_impl::decisionforest * c_ptr()
void clusterizerseparatedbydist(ahcreport *rep, double r, ae_int_t *k, ae_vector *cidx, ae_vector *cz, ae_state *_state)
double mlpavgce(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
void clusterizerrunahc(const clusterizerstate &s, ahcreport &rep)
double lravgerror(const linearmodel &lm, const real_2d_array &xy, const ae_int_t npoints)
double dfavgce(decisionforest *df, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
_mlpreport_owner & operator=(const _mlpreport_owner &rhs)
void clusterizergetdistances(const real_2d_array &xy, const ae_int_t npoints, const ae_int_t nfeatures, const ae_int_t disttype, real_2d_array &d)
double mlperrorsparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
ae_bool _mlptrainer_init(void *_p, ae_state *_state, ae_bool make_automatic)
double dfavgerror(decisionforest *df, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
alglib_impl::ahcreport * c_ptr()
void mcpdsetpredictionweights(const mcpdstate &s, const real_1d_array &pw)
void dfunserialize(ae_serializer *s, decisionforest *forest, ae_state *_state)
void mlpcreater0(const ae_int_t nin, const ae_int_t nout, const double a, const double b, multilayerperceptron &network)
double smp_mlpavgcesparse(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t npoints)
_modelerrors_owner & operator=(const _modelerrors_owner &rhs)
ae_int_t mlpgetlayersize(multilayerperceptron *network, ae_int_t k, ae_state *_state)
ae_int_t & inneriterationscount
mlpreport & operator=(const mlpreport &rhs)
void clusterizerseparatedbycorr(ahcreport *rep, double r, ae_int_t *k, ae_vector *cidx, ae_vector *cz, ae_state *_state)
ae_bool _ahcreport_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
ae_int_t mlpgetoutputscount(multilayerperceptron *network, ae_state *_state)
void mnlprocessi(const logitmodel &lm, const real_1d_array &x, real_1d_array &y)
void tagsortfasti(ae_vector *a, ae_vector *b, ae_vector *bufa, ae_vector *bufb, ae_int_t n, ae_state *_state)
void mcpdsetlc(mcpdstate *s, ae_matrix *c, ae_vector *ct, ae_int_t k, ae_state *_state)
double mlprmserrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
ae_int_t & outeriterationscount
void ae_v_addd(double *vdst, ae_int_t stride_dst, const double *vsrc, ae_int_t stride_src, ae_int_t n, double alpha)
ae_bool ae_vector_init_copy(ae_vector *dst, ae_vector *src, ae_state *state, ae_bool make_automatic)
ae_bool _mlptrainer_init_copy(void *_dst, void *_src, ae_state *_state, ae_bool make_automatic)
void smp_mlpgradbatch(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t ssize, double &e, real_1d_array &grad)
void mlpecreater1(const ae_int_t nin, const ae_int_t nhid, const ae_int_t nout, const double a, const double b, const ae_int_t ensemblesize, mlpensemble &ensemble)
void mcpdsolve(const mcpdstate &s)
void mlpsetneuroninfo(const multilayerperceptron &network, const ae_int_t k, const ae_int_t i, const ae_int_t fkind, const double threshold)
ae_bool ae_fp_less_eq(double v1, double v2)
void dfbuildrandomdecisionforest(ae_matrix *xy, ae_int_t npoints, ae_int_t nvars, ae_int_t nclasses, ae_int_t ntrees, double r, ae_int_t *info, decisionforest *df, dfreport *rep, ae_state *_state)
kmeansreport & operator=(const kmeansreport &rhs)
virtual ~_mlptrainer_owner()
void dfunserialize(std::string &s_in, decisionforest &obj)
ae_int_t ae_round(double x, ae_state *state)
void clusterizersetkmeanslimits(clusterizerstate *s, ae_int_t restarts, ae_int_t maxits, ae_state *_state)
_ahcreport_owner & operator=(const _ahcreport_owner &rhs)
void mlpebagginglbfgs(mlpensemble *ensemble, ae_matrix *xy, ae_int_t npoints, double decay, ae_int_t restarts, double wstep, ae_int_t maxits, ae_int_t *info, mlpreport *rep, mlpcvreport *ooberrors, ae_state *_state)
void mlpsetsparsedataset(mlptrainer *s, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
void mcpdresults(const mcpdstate &s, real_2d_array &p, mcpdreport &rep)
void mlpcreate0(const ae_int_t nin, const ae_int_t nout, multilayerperceptron &network)
void mnlpack(ae_matrix *a, ae_int_t nvars, ae_int_t nclasses, logitmodel *lm, ae_state *_state)
virtual ~_decisionforest_owner()
void mlpecreater2(ae_int_t nin, ae_int_t nhid1, ae_int_t nhid2, ae_int_t nout, double a, double b, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
void mlpgradbatchsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t ssize, double *e, ae_vector *grad, ae_state *_state)
alglib_impl::ae_int_t ae_int_t
void mlptraines(multilayerperceptron *network, ae_matrix *trnxy, ae_int_t trnsize, ae_matrix *valxy, ae_int_t valsize, double decay, ae_int_t restarts, ae_int_t *info, mlpreport *rep, ae_state *_state)
void filtersma(ae_vector *x, ae_int_t n, ae_int_t k, ae_state *_state)
double _pexec_mlpavgcesparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
void ae_frame_leave(ae_state *state)
alglib_impl::sparsematrix * c_ptr()
void ae_matrix_clear(ae_matrix *dst)
void filterlrma(real_1d_array &x, const ae_int_t n, const ae_int_t k)
alglib_impl::lrreport * p_struct
void mlpgradn(const multilayerperceptron &network, const real_1d_array &x, const real_1d_array &desiredy, double &e, real_1d_array &grad)
void dfprocess(const decisionforest &df, const real_1d_array &x, real_1d_array &y)
void mlptrainlm(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints, const double decay, const ae_int_t restarts, ae_int_t &info, mlpreport &rep)
double dfrmserror(const decisionforest &df, const real_2d_array &xy, const ae_int_t npoints)
ae_int_t mnlclserror(logitmodel *lm, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
double mlpavgrelerrorsparse(multilayerperceptron *network, sparsematrix *xy, ae_int_t npoints, ae_state *_state)
void mlpsetoutputscaling(const multilayerperceptron &network, const ae_int_t i, const double mean, const double sigma)
bool smp_mlpcontinuetraining(const mlptrainer &s, const multilayerperceptron &network)
ae_bool ae_fp_greater(double v1, double v2)
ae_bool ae_matrix_set_length(ae_matrix *dst, ae_int_t rows, ae_int_t cols, ae_state *state)
double mnlrelclserror(logitmodel *lm, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
ae_bool _decisionforest_init(void *_p, ae_state *_state, ae_bool make_automatic)
void clusterizersetahcalgo(clusterizerstate *s, ae_int_t algo, ae_state *_state)
ae_bool _logitmodel_init(void *_p, ae_state *_state, ae_bool make_automatic)
void mlpecreate1(const ae_int_t nin, const ae_int_t nhid, const ae_int_t nout, const ae_int_t ensemblesize, mlpensemble &ensemble)
double lrrmserror(linearmodel *lm, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
_kmeansreport_owner & operator=(const _kmeansreport_owner &rhs)
void mcpdsettikhonovregularizer(const mcpdstate &s, const double v)
ae_int_t mlpgetweightscount(multilayerperceptron *network, ae_state *_state)
void _modelerrors_clear(void *_p)
void mlpebagginglm(const mlpensemble &ensemble, const real_2d_array &xy, const ae_int_t npoints, const double decay, const ae_int_t restarts, ae_int_t &info, mlpreport &rep, mlpcvreport &ooberrors)
void mlpcreatec1(const ae_int_t nin, const ae_int_t nhid, const ae_int_t nout, multilayerperceptron &network)
virtual ~_modelerrors_owner()
void mlpalloc(ae_serializer *s, multilayerperceptron *network, ae_state *_state)
ql0001_ & zero(ctemp+1),(cvec+1),(a+1),(b+1),(bl+1),(bu+1),(x+1),(w+1), &iout, ifail, &zero,(w+3), &lwar2,(iw+1), &leniw, &glob_grd.epsmac
void mlpsetinputscaling(multilayerperceptron *network, ae_int_t i, double mean, double sigma, ae_state *_state)
void mlpsetweight(const multilayerperceptron &network, const ae_int_t k0, const ae_int_t i0, const ae_int_t k1, const ae_int_t i1, const double w)
void smp_mlptrainensemblees(const mlptrainer &s, const mlpensemble &ensemble, const ae_int_t nrestarts, mlpreport &rep)
double mlpeavgerror(const mlpensemble &ensemble, const real_2d_array &xy, const ae_int_t npoints)
double smp_mlperrorsparsesubset(const multilayerperceptron &network, const sparsematrix &xy, const ae_int_t setsize, const integer_1d_array &subset, const ae_int_t subsetsize)
ae_int_t ae_minint(ae_int_t m1, ae_int_t m2, ae_state *state)
void mlpecreatefromnetwork(multilayerperceptron *network, ae_int_t ensemblesize, mlpensemble *ensemble, ae_state *_state)
virtual ~_lrreport_owner()
alglib_impl::mnlreport * p_struct
ahcreport & operator=(const ahcreport &rhs)
double _pexec_mlperrorsubset(multilayerperceptron *network, ae_matrix *xy, ae_int_t setsize, ae_vector *subset, ae_int_t subsetsize, ae_state *_state)
double mlprmserror(const multilayerperceptron &network, const real_2d_array &xy, const ae_int_t npoints)
void mlpcreater1(ae_int_t nin, ae_int_t nhid, ae_int_t nout, double a, double b, multilayerperceptron *network, ae_state *_state)
void clusterizersetdistances(const clusterizerstate &s, const real_2d_array &d, const ae_int_t npoints, const bool isupper)
double _pexec_mlpavgce(multilayerperceptron *network, ae_matrix *xy, ae_int_t npoints, ae_state *_state)
_logitmodel_owner & operator=(const _logitmodel_owner &rhs)
_mlpcvreport_owner & operator=(const _mlpcvreport_owner &rhs)
double ae_v_dotproduct(const double *v0, ae_int_t stride0, const double *v1, ae_int_t stride1, ae_int_t n)
void _cvreport_destroy(void *_p)
void _pexec_mlptrainnetwork(mlptrainer *s, multilayerperceptron *network, ae_int_t nrestarts, mlpreport *rep, ae_state *_state)
void mlpsetsparsedataset(const mlptrainer &s, const sparsematrix &xy, const ae_int_t npoints)