Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/ALGLIB/mlpe.cs @ 2636

Last change on this file since 2636 was 2563, checked in by gkronber, 15 years ago

Updated ALGLIB to latest version. #751 (Plugin for for data-modeling with ANN (integrated into CEDMA))

File size: 53.4 KB
Line 
1/*************************************************************************
2Copyright (c) 2007-2008, Sergey Bochkanov (ALGLIB project).
3
4>>> SOURCE LICENSE >>>
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation (www.fsf.org); either version 2 of the
8License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15A copy of the GNU General Public License is available at
16http://www.fsf.org/licensing/licenses
17
18>>> END OF LICENSE >>>
19*************************************************************************/
20
21using System;
22
23namespace alglib
24{
25    public class mlpe
26    {
27        /*************************************************************************
28        Neural networks ensemble
29        *************************************************************************/
30        public struct mlpensemble
31        {
32            public int[] structinfo;
33            public int ensemblesize;
34            public int nin;
35            public int nout;
36            public int wcount;
37            public bool issoftmax;
38            public bool postprocessing;
39            public double[] weights;
40            public double[] columnmeans;
41            public double[] columnsigmas;
42            public int serializedlen;
43            public double[] serializedmlp;
44            public double[] tmpweights;
45            public double[] tmpmeans;
46            public double[] tmpsigmas;
47            public double[] neurons;
48            public double[] dfdnet;
49            public double[] y;
50        };
51
52
53
54
55        public const int mlpntotaloffset = 3;
56        public const int mlpevnum = 9;
57
58
59        /*************************************************************************
60        Like MLPCreate0, but for ensembles.
61
62          -- ALGLIB --
63             Copyright 18.02.2009 by Bochkanov Sergey
64        *************************************************************************/
65        public static void mlpecreate0(int nin,
66            int nout,
67            int ensemblesize,
68            ref mlpensemble ensemble)
69        {
70            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
71
72            mlpbase.mlpcreate0(nin, nout, ref net);
73            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
74        }
75
76
77        /*************************************************************************
78        Like MLPCreate1, but for ensembles.
79
80          -- ALGLIB --
81             Copyright 18.02.2009 by Bochkanov Sergey
82        *************************************************************************/
83        public static void mlpecreate1(int nin,
84            int nhid,
85            int nout,
86            int ensemblesize,
87            ref mlpensemble ensemble)
88        {
89            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
90
91            mlpbase.mlpcreate1(nin, nhid, nout, ref net);
92            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
93        }
94
95
96        /*************************************************************************
97        Like MLPCreate2, but for ensembles.
98
99          -- ALGLIB --
100             Copyright 18.02.2009 by Bochkanov Sergey
101        *************************************************************************/
102        public static void mlpecreate2(int nin,
103            int nhid1,
104            int nhid2,
105            int nout,
106            int ensemblesize,
107            ref mlpensemble ensemble)
108        {
109            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
110
111            mlpbase.mlpcreate2(nin, nhid1, nhid2, nout, ref net);
112            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
113        }
114
115
116        /*************************************************************************
117        Like MLPCreateB0, but for ensembles.
118
119          -- ALGLIB --
120             Copyright 18.02.2009 by Bochkanov Sergey
121        *************************************************************************/
122        public static void mlpecreateb0(int nin,
123            int nout,
124            double b,
125            double d,
126            int ensemblesize,
127            ref mlpensemble ensemble)
128        {
129            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
130
131            mlpbase.mlpcreateb0(nin, nout, b, d, ref net);
132            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
133        }
134
135
136        /*************************************************************************
137        Like MLPCreateB1, but for ensembles.
138
139          -- ALGLIB --
140             Copyright 18.02.2009 by Bochkanov Sergey
141        *************************************************************************/
142        public static void mlpecreateb1(int nin,
143            int nhid,
144            int nout,
145            double b,
146            double d,
147            int ensemblesize,
148            ref mlpensemble ensemble)
149        {
150            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
151
152            mlpbase.mlpcreateb1(nin, nhid, nout, b, d, ref net);
153            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
154        }
155
156
157        /*************************************************************************
158        Like MLPCreateB2, but for ensembles.
159
160          -- ALGLIB --
161             Copyright 18.02.2009 by Bochkanov Sergey
162        *************************************************************************/
163        public static void mlpecreateb2(int nin,
164            int nhid1,
165            int nhid2,
166            int nout,
167            double b,
168            double d,
169            int ensemblesize,
170            ref mlpensemble ensemble)
171        {
172            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
173
174            mlpbase.mlpcreateb2(nin, nhid1, nhid2, nout, b, d, ref net);
175            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
176        }
177
178
179        /*************************************************************************
180        Like MLPCreateR0, but for ensembles.
181
182          -- ALGLIB --
183             Copyright 18.02.2009 by Bochkanov Sergey
184        *************************************************************************/
185        public static void mlpecreater0(int nin,
186            int nout,
187            double a,
188            double b,
189            int ensemblesize,
190            ref mlpensemble ensemble)
191        {
192            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
193
194            mlpbase.mlpcreater0(nin, nout, a, b, ref net);
195            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
196        }
197
198
199        /*************************************************************************
200        Like MLPCreateR1, but for ensembles.
201
202          -- ALGLIB --
203             Copyright 18.02.2009 by Bochkanov Sergey
204        *************************************************************************/
205        public static void mlpecreater1(int nin,
206            int nhid,
207            int nout,
208            double a,
209            double b,
210            int ensemblesize,
211            ref mlpensemble ensemble)
212        {
213            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
214
215            mlpbase.mlpcreater1(nin, nhid, nout, a, b, ref net);
216            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
217        }
218
219
220        /*************************************************************************
221        Like MLPCreateR2, but for ensembles.
222
223          -- ALGLIB --
224             Copyright 18.02.2009 by Bochkanov Sergey
225        *************************************************************************/
226        public static void mlpecreater2(int nin,
227            int nhid1,
228            int nhid2,
229            int nout,
230            double a,
231            double b,
232            int ensemblesize,
233            ref mlpensemble ensemble)
234        {
235            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
236
237            mlpbase.mlpcreater2(nin, nhid1, nhid2, nout, a, b, ref net);
238            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
239        }
240
241
242        /*************************************************************************
243        Like MLPCreateC0, but for ensembles.
244
245          -- ALGLIB --
246             Copyright 18.02.2009 by Bochkanov Sergey
247        *************************************************************************/
248        public static void mlpecreatec0(int nin,
249            int nout,
250            int ensemblesize,
251            ref mlpensemble ensemble)
252        {
253            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
254
255            mlpbase.mlpcreatec0(nin, nout, ref net);
256            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
257        }
258
259
260        /*************************************************************************
261        Like MLPCreateC1, but for ensembles.
262
263          -- ALGLIB --
264             Copyright 18.02.2009 by Bochkanov Sergey
265        *************************************************************************/
266        public static void mlpecreatec1(int nin,
267            int nhid,
268            int nout,
269            int ensemblesize,
270            ref mlpensemble ensemble)
271        {
272            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
273
274            mlpbase.mlpcreatec1(nin, nhid, nout, ref net);
275            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
276        }
277
278
279        /*************************************************************************
280        Like MLPCreateC2, but for ensembles.
281
282          -- ALGLIB --
283             Copyright 18.02.2009 by Bochkanov Sergey
284        *************************************************************************/
285        public static void mlpecreatec2(int nin,
286            int nhid1,
287            int nhid2,
288            int nout,
289            int ensemblesize,
290            ref mlpensemble ensemble)
291        {
292            mlpbase.multilayerperceptron net = new mlpbase.multilayerperceptron();
293
294            mlpbase.mlpcreatec2(nin, nhid1, nhid2, nout, ref net);
295            mlpecreatefromnetwork(ref net, ensemblesize, ref ensemble);
296        }
297
298
299        /*************************************************************************
300        Creates ensemble from network. Only network geometry is copied.
301
302          -- ALGLIB --
303             Copyright 17.02.2009 by Bochkanov Sergey
304        *************************************************************************/
305        public static void mlpecreatefromnetwork(ref mlpbase.multilayerperceptron network,
306            int ensemblesize,
307            ref mlpensemble ensemble)
308        {
309            int i = 0;
310            int ccount = 0;
311            int rlen = 0;
312            int i_ = 0;
313            int i1_ = 0;
314
315            System.Diagnostics.Debug.Assert(ensemblesize>0, "MLPECreate: incorrect ensemble size!");
316           
317            //
318            // network properties
319            //
320            mlpbase.mlpproperties(ref network, ref ensemble.nin, ref ensemble.nout, ref ensemble.wcount);
321            if( mlpbase.mlpissoftmax(ref network) )
322            {
323                ccount = ensemble.nin;
324            }
325            else
326            {
327                ccount = ensemble.nin+ensemble.nout;
328            }
329            ensemble.postprocessing = false;
330            ensemble.issoftmax = mlpbase.mlpissoftmax(ref network);
331            ensemble.ensemblesize = ensemblesize;
332           
333            //
334            // structure information
335            //
336            ensemble.structinfo = new int[network.structinfo[0]-1+1];
337            for(i=0; i<=network.structinfo[0]-1; i++)
338            {
339                ensemble.structinfo[i] = network.structinfo[i];
340            }
341           
342            //
343            // weights, means, sigmas
344            //
345            ensemble.weights = new double[ensemblesize*ensemble.wcount-1+1];
346            ensemble.columnmeans = new double[ensemblesize*ccount-1+1];
347            ensemble.columnsigmas = new double[ensemblesize*ccount-1+1];
348            for(i=0; i<=ensemblesize*ensemble.wcount-1; i++)
349            {
350                ensemble.weights[i] = AP.Math.RandomReal()-0.5;
351            }
352            for(i=0; i<=ensemblesize-1; i++)
353            {
354                i1_ = (0) - (i*ccount);
355                for(i_=i*ccount; i_<=(i+1)*ccount-1;i_++)
356                {
357                    ensemble.columnmeans[i_] = network.columnmeans[i_+i1_];
358                }
359                i1_ = (0) - (i*ccount);
360                for(i_=i*ccount; i_<=(i+1)*ccount-1;i_++)
361                {
362                    ensemble.columnsigmas[i_] = network.columnsigmas[i_+i1_];
363                }
364            }
365           
366            //
367            // serialized part
368            //
369            mlpbase.mlpserialize(ref network, ref ensemble.serializedmlp, ref ensemble.serializedlen);
370           
371            //
372            // temporaries, internal buffers
373            //
374            ensemble.tmpweights = new double[ensemble.wcount-1+1];
375            ensemble.tmpmeans = new double[ccount-1+1];
376            ensemble.tmpsigmas = new double[ccount-1+1];
377            ensemble.neurons = new double[ensemble.structinfo[mlpntotaloffset]-1+1];
378            ensemble.dfdnet = new double[ensemble.structinfo[mlpntotaloffset]-1+1];
379            ensemble.y = new double[ensemble.nout-1+1];
380        }
381
382
383        /*************************************************************************
384        Copying of MLPEnsemble strucure
385
386        INPUT PARAMETERS:
387            Ensemble1 -   original
388
389        OUTPUT PARAMETERS:
390            Ensemble2 -   copy
391
392          -- ALGLIB --
393             Copyright 17.02.2009 by Bochkanov Sergey
394        *************************************************************************/
395        public static void mlpecopy(ref mlpensemble ensemble1,
396            ref mlpensemble ensemble2)
397        {
398            int i = 0;
399            int ssize = 0;
400            int ccount = 0;
401            int ntotal = 0;
402            int nin = 0;
403            int nout = 0;
404            int wcount = 0;
405            int i_ = 0;
406
407           
408            //
409            // Unload info
410            //
411            ssize = ensemble1.structinfo[0];
412            if( ensemble1.issoftmax )
413            {
414                ccount = ensemble1.nin;
415            }
416            else
417            {
418                ccount = ensemble1.nin+ensemble1.nout;
419            }
420            ntotal = ensemble1.structinfo[mlpntotaloffset];
421           
422            //
423            // Allocate space
424            //
425            ensemble2.structinfo = new int[ssize-1+1];
426            ensemble2.weights = new double[ensemble1.ensemblesize*ensemble1.wcount-1+1];
427            ensemble2.columnmeans = new double[ensemble1.ensemblesize*ccount-1+1];
428            ensemble2.columnsigmas = new double[ensemble1.ensemblesize*ccount-1+1];
429            ensemble2.tmpweights = new double[ensemble1.wcount-1+1];
430            ensemble2.tmpmeans = new double[ccount-1+1];
431            ensemble2.tmpsigmas = new double[ccount-1+1];
432            ensemble2.serializedmlp = new double[ensemble1.serializedlen-1+1];
433            ensemble2.neurons = new double[ntotal-1+1];
434            ensemble2.dfdnet = new double[ntotal-1+1];
435            ensemble2.y = new double[ensemble1.nout-1+1];
436           
437            //
438            // Copy
439            //
440            ensemble2.nin = ensemble1.nin;
441            ensemble2.nout = ensemble1.nout;
442            ensemble2.wcount = ensemble1.wcount;
443            ensemble2.ensemblesize = ensemble1.ensemblesize;
444            ensemble2.issoftmax = ensemble1.issoftmax;
445            ensemble2.postprocessing = ensemble1.postprocessing;
446            ensemble2.serializedlen = ensemble1.serializedlen;
447            for(i=0; i<=ssize-1; i++)
448            {
449                ensemble2.structinfo[i] = ensemble1.structinfo[i];
450            }
451            for(i_=0; i_<=ensemble1.ensemblesize*ensemble1.wcount-1;i_++)
452            {
453                ensemble2.weights[i_] = ensemble1.weights[i_];
454            }
455            for(i_=0; i_<=ensemble1.ensemblesize*ccount-1;i_++)
456            {
457                ensemble2.columnmeans[i_] = ensemble1.columnmeans[i_];
458            }
459            for(i_=0; i_<=ensemble1.ensemblesize*ccount-1;i_++)
460            {
461                ensemble2.columnsigmas[i_] = ensemble1.columnsigmas[i_];
462            }
463            for(i_=0; i_<=ensemble1.serializedlen-1;i_++)
464            {
465                ensemble2.serializedmlp[i_] = ensemble1.serializedmlp[i_];
466            }
467        }
468
469
470        /*************************************************************************
471        Serialization of MLPEnsemble strucure
472
473        INPUT PARAMETERS:
474            Ensemble-   original
475
476        OUTPUT PARAMETERS:
477            RA      -   array of real numbers which stores ensemble,
478                        array[0..RLen-1]
479            RLen    -   RA lenght
480
481          -- ALGLIB --
482             Copyright 17.02.2009 by Bochkanov Sergey
483        *************************************************************************/
484        public static void mlpeserialize(ref mlpensemble ensemble,
485            ref double[] ra,
486            ref int rlen)
487        {
488            int i = 0;
489            int ssize = 0;
490            int ntotal = 0;
491            int ccount = 0;
492            int hsize = 0;
493            int offs = 0;
494            int i_ = 0;
495            int i1_ = 0;
496
497            hsize = 13;
498            ssize = ensemble.structinfo[0];
499            if( ensemble.issoftmax )
500            {
501                ccount = ensemble.nin;
502            }
503            else
504            {
505                ccount = ensemble.nin+ensemble.nout;
506            }
507            ntotal = ensemble.structinfo[mlpntotaloffset];
508            rlen = hsize+ssize+ensemble.ensemblesize*ensemble.wcount+2*ccount*ensemble.ensemblesize+ensemble.serializedlen;
509           
510            //
511            //  RA format:
512            //  [0]     RLen
513            //  [1]     Version (MLPEVNum)
514            //  [2]     EnsembleSize
515            //  [3]     NIn
516            //  [4]     NOut
517            //  [5]     WCount
518            //  [6]     IsSoftmax 0/1
519            //  [7]     PostProcessing 0/1
520            //  [8]     sizeof(StructInfo)
521            //  [9]     NTotal (sizeof(Neurons), sizeof(DFDNET))
522            //  [10]    CCount (sizeof(ColumnMeans), sizeof(ColumnSigmas))
523            //  [11]    data offset
524            //  [12]    SerializedLen
525            //
526            //  [..]    StructInfo
527            //  [..]    Weights
528            //  [..]    ColumnMeans
529            //  [..]    ColumnSigmas
530            //
531            ra = new double[rlen-1+1];
532            ra[0] = rlen;
533            ra[1] = mlpevnum;
534            ra[2] = ensemble.ensemblesize;
535            ra[3] = ensemble.nin;
536            ra[4] = ensemble.nout;
537            ra[5] = ensemble.wcount;
538            if( ensemble.issoftmax )
539            {
540                ra[6] = 1;
541            }
542            else
543            {
544                ra[6] = 0;
545            }
546            if( ensemble.postprocessing )
547            {
548                ra[7] = 1;
549            }
550            else
551            {
552                ra[7] = 9;
553            }
554            ra[8] = ssize;
555            ra[9] = ntotal;
556            ra[10] = ccount;
557            ra[11] = hsize;
558            ra[12] = ensemble.serializedlen;
559            offs = hsize;
560            for(i=offs; i<=offs+ssize-1; i++)
561            {
562                ra[i] = ensemble.structinfo[i-offs];
563            }
564            offs = offs+ssize;
565            i1_ = (0) - (offs);
566            for(i_=offs; i_<=offs+ensemble.ensemblesize*ensemble.wcount-1;i_++)
567            {
568                ra[i_] = ensemble.weights[i_+i1_];
569            }
570            offs = offs+ensemble.ensemblesize*ensemble.wcount;
571            i1_ = (0) - (offs);
572            for(i_=offs; i_<=offs+ensemble.ensemblesize*ccount-1;i_++)
573            {
574                ra[i_] = ensemble.columnmeans[i_+i1_];
575            }
576            offs = offs+ensemble.ensemblesize*ccount;
577            i1_ = (0) - (offs);
578            for(i_=offs; i_<=offs+ensemble.ensemblesize*ccount-1;i_++)
579            {
580                ra[i_] = ensemble.columnsigmas[i_+i1_];
581            }
582            offs = offs+ensemble.ensemblesize*ccount;
583            i1_ = (0) - (offs);
584            for(i_=offs; i_<=offs+ensemble.serializedlen-1;i_++)
585            {
586                ra[i_] = ensemble.serializedmlp[i_+i1_];
587            }
588            offs = offs+ensemble.serializedlen;
589        }
590
591
592        /*************************************************************************
593        Unserialization of MLPEnsemble strucure
594
595        INPUT PARAMETERS:
596            RA      -   real array which stores ensemble
597
598        OUTPUT PARAMETERS:
599            Ensemble-   restored structure
600
601          -- ALGLIB --
602             Copyright 17.02.2009 by Bochkanov Sergey
603        *************************************************************************/
604        public static void mlpeunserialize(ref double[] ra,
605            ref mlpensemble ensemble)
606        {
607            int i = 0;
608            int ssize = 0;
609            int ntotal = 0;
610            int ccount = 0;
611            int hsize = 0;
612            int offs = 0;
613            int i_ = 0;
614            int i1_ = 0;
615
616            System.Diagnostics.Debug.Assert((int)Math.Round(ra[1])==mlpevnum, "MLPEUnserialize: incorrect array!");
617           
618            //
619            // load info
620            //
621            hsize = 13;
622            ensemble.ensemblesize = (int)Math.Round(ra[2]);
623            ensemble.nin = (int)Math.Round(ra[3]);
624            ensemble.nout = (int)Math.Round(ra[4]);
625            ensemble.wcount = (int)Math.Round(ra[5]);
626            ensemble.issoftmax = (int)Math.Round(ra[6])==1;
627            ensemble.postprocessing = (int)Math.Round(ra[7])==1;
628            ssize = (int)Math.Round(ra[8]);
629            ntotal = (int)Math.Round(ra[9]);
630            ccount = (int)Math.Round(ra[10]);
631            offs = (int)Math.Round(ra[11]);
632            ensemble.serializedlen = (int)Math.Round(ra[12]);
633           
634            //
635            //  Allocate arrays
636            //
637            ensemble.structinfo = new int[ssize-1+1];
638            ensemble.weights = new double[ensemble.ensemblesize*ensemble.wcount-1+1];
639            ensemble.columnmeans = new double[ensemble.ensemblesize*ccount-1+1];
640            ensemble.columnsigmas = new double[ensemble.ensemblesize*ccount-1+1];
641            ensemble.tmpweights = new double[ensemble.wcount-1+1];
642            ensemble.tmpmeans = new double[ccount-1+1];
643            ensemble.tmpsigmas = new double[ccount-1+1];
644            ensemble.neurons = new double[ntotal-1+1];
645            ensemble.dfdnet = new double[ntotal-1+1];
646            ensemble.serializedmlp = new double[ensemble.serializedlen-1+1];
647            ensemble.y = new double[ensemble.nout-1+1];
648           
649            //
650            // load data
651            //
652            for(i=offs; i<=offs+ssize-1; i++)
653            {
654                ensemble.structinfo[i-offs] = (int)Math.Round(ra[i]);
655            }
656            offs = offs+ssize;
657            i1_ = (offs) - (0);
658            for(i_=0; i_<=ensemble.ensemblesize*ensemble.wcount-1;i_++)
659            {
660                ensemble.weights[i_] = ra[i_+i1_];
661            }
662            offs = offs+ensemble.ensemblesize*ensemble.wcount;
663            i1_ = (offs) - (0);
664            for(i_=0; i_<=ensemble.ensemblesize*ccount-1;i_++)
665            {
666                ensemble.columnmeans[i_] = ra[i_+i1_];
667            }
668            offs = offs+ensemble.ensemblesize*ccount;
669            i1_ = (offs) - (0);
670            for(i_=0; i_<=ensemble.ensemblesize*ccount-1;i_++)
671            {
672                ensemble.columnsigmas[i_] = ra[i_+i1_];
673            }
674            offs = offs+ensemble.ensemblesize*ccount;
675            i1_ = (offs) - (0);
676            for(i_=0; i_<=ensemble.serializedlen-1;i_++)
677            {
678                ensemble.serializedmlp[i_] = ra[i_+i1_];
679            }
680            offs = offs+ensemble.serializedlen;
681        }
682
683
684        /*************************************************************************
685        Randomization of MLP ensemble
686
687          -- ALGLIB --
688             Copyright 17.02.2009 by Bochkanov Sergey
689        *************************************************************************/
690        public static void mlperandomize(ref mlpensemble ensemble)
691        {
692            int i = 0;
693
694            for(i=0; i<=ensemble.ensemblesize*ensemble.wcount-1; i++)
695            {
696                ensemble.weights[i] = AP.Math.RandomReal()-0.5;
697            }
698        }
699
700
701        /*************************************************************************
702        Return ensemble properties (number of inputs and outputs).
703
704          -- ALGLIB --
705             Copyright 17.02.2009 by Bochkanov Sergey
706        *************************************************************************/
707        public static void mlpeproperties(ref mlpensemble ensemble,
708            ref int nin,
709            ref int nout)
710        {
711            nin = ensemble.nin;
712            nout = ensemble.nout;
713        }
714
715
716        /*************************************************************************
717        Return normalization type (whether ensemble is SOFTMAX-normalized or not).
718
719          -- ALGLIB --
720             Copyright 17.02.2009 by Bochkanov Sergey
721        *************************************************************************/
722        public static bool mlpeissoftmax(ref mlpensemble ensemble)
723        {
724            bool result = new bool();
725
726            result = ensemble.issoftmax;
727            return result;
728        }
729
730
731        /*************************************************************************
732        Procesing
733
734        INPUT PARAMETERS:
735            Ensemble-   neural networks ensemble
736            X       -   input vector,  array[0..NIn-1].
737
738        OUTPUT PARAMETERS:
739            Y       -   result. Regression estimate when solving regression  task,
740                        vector of posterior probabilities for classification task.
741                        Subroutine does not allocate memory for this vector, it is
742                        responsibility of a caller to allocate it. Array  must  be
743                        at least [0..NOut-1].
744
745          -- ALGLIB --
746             Copyright 17.02.2009 by Bochkanov Sergey
747        *************************************************************************/
748        public static void mlpeprocess(ref mlpensemble ensemble,
749            ref double[] x,
750            ref double[] y)
751        {
752            int i = 0;
753            int es = 0;
754            int wc = 0;
755            int cc = 0;
756            double v = 0;
757            int i_ = 0;
758            int i1_ = 0;
759
760            es = ensemble.ensemblesize;
761            wc = ensemble.wcount;
762            if( ensemble.issoftmax )
763            {
764                cc = ensemble.nin;
765            }
766            else
767            {
768                cc = ensemble.nin+ensemble.nout;
769            }
770            v = (double)(1)/(double)(es);
771            for(i=0; i<=ensemble.nout-1; i++)
772            {
773                y[i] = 0;
774            }
775            for(i=0; i<=es-1; i++)
776            {
777                i1_ = (i*wc) - (0);
778                for(i_=0; i_<=wc-1;i_++)
779                {
780                    ensemble.tmpweights[i_] = ensemble.weights[i_+i1_];
781                }
782                i1_ = (i*cc) - (0);
783                for(i_=0; i_<=cc-1;i_++)
784                {
785                    ensemble.tmpmeans[i_] = ensemble.columnmeans[i_+i1_];
786                }
787                i1_ = (i*cc) - (0);
788                for(i_=0; i_<=cc-1;i_++)
789                {
790                    ensemble.tmpsigmas[i_] = ensemble.columnsigmas[i_+i1_];
791                }
792                mlpbase.mlpinternalprocessvector(ref ensemble.structinfo, ref ensemble.tmpweights, ref ensemble.tmpmeans, ref ensemble.tmpsigmas, ref ensemble.neurons, ref ensemble.dfdnet, ref x, ref ensemble.y);
793                for(i_=0; i_<=ensemble.nout-1;i_++)
794                {
795                    y[i_] = y[i_] + v*ensemble.y[i_];
796                }
797            }
798        }
799
800
801        /*************************************************************************
802        Relative classification error on the test set
803
804        INPUT PARAMETERS:
805            Ensemble-   ensemble
806            XY      -   test set
807            NPoints -   test set size
808
809        RESULT:
810            percent of incorrectly classified cases.
811            Works both for classifier betwork and for regression networks which
812        are used as classifiers.
813
814          -- ALGLIB --
815             Copyright 17.02.2009 by Bochkanov Sergey
816        *************************************************************************/
817        public static double mlperelclserror(ref mlpensemble ensemble,
818            ref double[,] xy,
819            int npoints)
820        {
821            double result = 0;
822            double relcls = 0;
823            double avgce = 0;
824            double rms = 0;
825            double avg = 0;
826            double avgrel = 0;
827
828            mlpeallerrors(ref ensemble, ref xy, npoints, ref relcls, ref avgce, ref rms, ref avg, ref avgrel);
829            result = relcls;
830            return result;
831        }
832
833
834        /*************************************************************************
835        Average cross-entropy (in bits per element) on the test set
836
837        INPUT PARAMETERS:
838            Ensemble-   ensemble
839            XY      -   test set
840            NPoints -   test set size
841
842        RESULT:
843            CrossEntropy/(NPoints*LN(2)).
844            Zero if ensemble solves regression task.
845
846          -- ALGLIB --
847             Copyright 17.02.2009 by Bochkanov Sergey
848        *************************************************************************/
849        public static double mlpeavgce(ref mlpensemble ensemble,
850            ref double[,] xy,
851            int npoints)
852        {
853            double result = 0;
854            double relcls = 0;
855            double avgce = 0;
856            double rms = 0;
857            double avg = 0;
858            double avgrel = 0;
859
860            mlpeallerrors(ref ensemble, ref xy, npoints, ref relcls, ref avgce, ref rms, ref avg, ref avgrel);
861            result = avgce;
862            return result;
863        }
864
865
866        /*************************************************************************
867        RMS error on the test set
868
869        INPUT PARAMETERS:
870            Ensemble-   ensemble
871            XY      -   test set
872            NPoints -   test set size
873
874        RESULT:
875            root mean square error.
876            Its meaning for regression task is obvious. As for classification task
877        RMS error means error when estimating posterior probabilities.
878
879          -- ALGLIB --
880             Copyright 17.02.2009 by Bochkanov Sergey
881        *************************************************************************/
882        public static double mlpermserror(ref mlpensemble ensemble,
883            ref double[,] xy,
884            int npoints)
885        {
886            double result = 0;
887            double relcls = 0;
888            double avgce = 0;
889            double rms = 0;
890            double avg = 0;
891            double avgrel = 0;
892
893            mlpeallerrors(ref ensemble, ref xy, npoints, ref relcls, ref avgce, ref rms, ref avg, ref avgrel);
894            result = rms;
895            return result;
896        }
897
898
899        /*************************************************************************
900        Average error on the test set
901
902        INPUT PARAMETERS:
903            Ensemble-   ensemble
904            XY      -   test set
905            NPoints -   test set size
906
907        RESULT:
908            Its meaning for regression task is obvious. As for classification task
909        it means average error when estimating posterior probabilities.
910
911          -- ALGLIB --
912             Copyright 17.02.2009 by Bochkanov Sergey
913        *************************************************************************/
914        public static double mlpeavgerror(ref mlpensemble ensemble,
915            ref double[,] xy,
916            int npoints)
917        {
918            double result = 0;
919            double relcls = 0;
920            double avgce = 0;
921            double rms = 0;
922            double avg = 0;
923            double avgrel = 0;
924
925            mlpeallerrors(ref ensemble, ref xy, npoints, ref relcls, ref avgce, ref rms, ref avg, ref avgrel);
926            result = avg;
927            return result;
928        }
929
930
931        /*************************************************************************
932        Average relative error on the test set
933
934        INPUT PARAMETERS:
935            Ensemble-   ensemble
936            XY      -   test set
937            NPoints -   test set size
938
939        RESULT:
940            Its meaning for regression task is obvious. As for classification task
941        it means average relative error when estimating posterior probabilities.
942
943          -- ALGLIB --
944             Copyright 17.02.2009 by Bochkanov Sergey
945        *************************************************************************/
946        public static double mlpeavgrelerror(ref mlpensemble ensemble,
947            ref double[,] xy,
948            int npoints)
949        {
950            double result = 0;
951            double relcls = 0;
952            double avgce = 0;
953            double rms = 0;
954            double avg = 0;
955            double avgrel = 0;
956
957            mlpeallerrors(ref ensemble, ref xy, npoints, ref relcls, ref avgce, ref rms, ref avg, ref avgrel);
958            result = avgrel;
959            return result;
960        }
961
962
963        /*************************************************************************
964        Training neural networks ensemble using  bootstrap  aggregating (bagging).
965        Modified Levenberg-Marquardt algorithm is used as base training method.
966
967        INPUT PARAMETERS:
968            Ensemble    -   model with initialized geometry
969            XY          -   training set
970            NPoints     -   training set size
971            Decay       -   weight decay coefficient, >=0.001
972            Restarts    -   restarts, >0.
973
974        OUTPUT PARAMETERS:
975            Ensemble    -   trained model
976            Info        -   return code:
977                            * -2, if there is a point with class number
978                                  outside of [0..NClasses-1].
979                            * -1, if incorrect parameters was passed
980                                  (NPoints<0, Restarts<1).
981                            *  2, if task has been solved.
982            Rep         -   training report.
983            OOBErrors   -   out-of-bag generalization error estimate
984
985          -- ALGLIB --
986             Copyright 17.02.2009 by Bochkanov Sergey
987        *************************************************************************/
988        public static void mlpebagginglm(ref mlpensemble ensemble,
989            ref double[,] xy,
990            int npoints,
991            double decay,
992            int restarts,
993            ref int info,
994            ref mlptrain.mlpreport rep,
995            ref mlptrain.mlpcvreport ooberrors)
996        {
997            mlpebagginginternal(ref ensemble, ref xy, npoints, decay, restarts, 0.0, 0, true, ref info, ref rep, ref ooberrors);
998        }
999
1000
1001        /*************************************************************************
1002        Training neural networks ensemble using  bootstrap  aggregating (bagging).
1003        L-BFGS algorithm is used as base training method.
1004
1005        INPUT PARAMETERS:
1006            Ensemble    -   model with initialized geometry
1007            XY          -   training set
1008            NPoints     -   training set size
1009            Decay       -   weight decay coefficient, >=0.001
1010            Restarts    -   restarts, >0.
1011            WStep       -   stopping criterion, same as in MLPTrainLBFGS
1012            MaxIts      -   stopping criterion, same as in MLPTrainLBFGS
1013
1014        OUTPUT PARAMETERS:
1015            Ensemble    -   trained model
1016            Info        -   return code:
1017                            * -8, if both WStep=0 and MaxIts=0
1018                            * -2, if there is a point with class number
1019                                  outside of [0..NClasses-1].
1020                            * -1, if incorrect parameters was passed
1021                                  (NPoints<0, Restarts<1).
1022                            *  2, if task has been solved.
1023            Rep         -   training report.
1024            OOBErrors   -   out-of-bag generalization error estimate
1025
1026          -- ALGLIB --
1027             Copyright 17.02.2009 by Bochkanov Sergey
1028        *************************************************************************/
1029        public static void mlpebagginglbfgs(ref mlpensemble ensemble,
1030            ref double[,] xy,
1031            int npoints,
1032            double decay,
1033            int restarts,
1034            double wstep,
1035            int maxits,
1036            ref int info,
1037            ref mlptrain.mlpreport rep,
1038            ref mlptrain.mlpcvreport ooberrors)
1039        {
1040            mlpebagginginternal(ref ensemble, ref xy, npoints, decay, restarts, wstep, maxits, false, ref info, ref rep, ref ooberrors);
1041        }
1042
1043
1044        /*************************************************************************
1045        Training neural networks ensemble using early stopping.
1046
1047        INPUT PARAMETERS:
1048            Ensemble    -   model with initialized geometry
1049            XY          -   training set
1050            NPoints     -   training set size
1051            Decay       -   weight decay coefficient, >=0.001
1052            Restarts    -   restarts, >0.
1053
1054        OUTPUT PARAMETERS:
1055            Ensemble    -   trained model
1056            Info        -   return code:
1057                            * -2, if there is a point with class number
1058                                  outside of [0..NClasses-1].
1059                            * -1, if incorrect parameters was passed
1060                                  (NPoints<0, Restarts<1).
1061                            *  6, if task has been solved.
1062            Rep         -   training report.
1063            OOBErrors   -   out-of-bag generalization error estimate
1064
1065          -- ALGLIB --
1066             Copyright 10.03.2009 by Bochkanov Sergey
1067        *************************************************************************/
1068        public static void mlpetraines(ref mlpensemble ensemble,
1069            ref double[,] xy,
1070            int npoints,
1071            double decay,
1072            int restarts,
1073            ref int info,
1074            ref mlptrain.mlpreport rep)
1075        {
1076            int i = 0;
1077            int k = 0;
1078            int ccount = 0;
1079            int pcount = 0;
1080            double[,] trnxy = new double[0,0];
1081            double[,] valxy = new double[0,0];
1082            int trnsize = 0;
1083            int valsize = 0;
1084            mlpbase.multilayerperceptron network = new mlpbase.multilayerperceptron();
1085            int tmpinfo = 0;
1086            mlptrain.mlpreport tmprep = new mlptrain.mlpreport();
1087            int i_ = 0;
1088            int i1_ = 0;
1089
1090            if( npoints<2 | restarts<1 | (double)(decay)<(double)(0) )
1091            {
1092                info = -1;
1093                return;
1094            }
1095            if( ensemble.issoftmax )
1096            {
1097                for(i=0; i<=npoints-1; i++)
1098                {
1099                    if( (int)Math.Round(xy[i,ensemble.nin])<0 | (int)Math.Round(xy[i,ensemble.nin])>=ensemble.nout )
1100                    {
1101                        info = -2;
1102                        return;
1103                    }
1104                }
1105            }
1106            info = 6;
1107           
1108            //
1109            // allocate
1110            //
1111            if( ensemble.issoftmax )
1112            {
1113                ccount = ensemble.nin+1;
1114                pcount = ensemble.nin;
1115            }
1116            else
1117            {
1118                ccount = ensemble.nin+ensemble.nout;
1119                pcount = ensemble.nin+ensemble.nout;
1120            }
1121            trnxy = new double[npoints-1+1, ccount-1+1];
1122            valxy = new double[npoints-1+1, ccount-1+1];
1123            mlpbase.mlpunserialize(ref ensemble.serializedmlp, ref network);
1124            rep.ngrad = 0;
1125            rep.nhess = 0;
1126            rep.ncholesky = 0;
1127           
1128            //
1129            // train networks
1130            //
1131            for(k=0; k<=ensemble.ensemblesize-1; k++)
1132            {
1133               
1134                //
1135                // Split set
1136                //
1137                do
1138                {
1139                    trnsize = 0;
1140                    valsize = 0;
1141                    for(i=0; i<=npoints-1; i++)
1142                    {
1143                        if( (double)(AP.Math.RandomReal())<(double)(0.66) )
1144                        {
1145                           
1146                            //
1147                            // Assign sample to training set
1148                            //
1149                            for(i_=0; i_<=ccount-1;i_++)
1150                            {
1151                                trnxy[trnsize,i_] = xy[i,i_];
1152                            }
1153                            trnsize = trnsize+1;
1154                        }
1155                        else
1156                        {
1157                           
1158                            //
1159                            // Assign sample to validation set
1160                            //
1161                            for(i_=0; i_<=ccount-1;i_++)
1162                            {
1163                                valxy[valsize,i_] = xy[i,i_];
1164                            }
1165                            valsize = valsize+1;
1166                        }
1167                    }
1168                }
1169                while( ! (trnsize!=0 & valsize!=0) );
1170               
1171                //
1172                // Train
1173                //
1174                mlptrain.mlptraines(ref network, ref trnxy, trnsize, ref valxy, valsize, decay, restarts, ref tmpinfo, ref tmprep);
1175                if( tmpinfo<0 )
1176                {
1177                    info = tmpinfo;
1178                    return;
1179                }
1180               
1181                //
1182                // save results
1183                //
1184                i1_ = (0) - (k*ensemble.wcount);
1185                for(i_=k*ensemble.wcount; i_<=(k+1)*ensemble.wcount-1;i_++)
1186                {
1187                    ensemble.weights[i_] = network.weights[i_+i1_];
1188                }
1189                i1_ = (0) - (k*pcount);
1190                for(i_=k*pcount; i_<=(k+1)*pcount-1;i_++)
1191                {
1192                    ensemble.columnmeans[i_] = network.columnmeans[i_+i1_];
1193                }
1194                i1_ = (0) - (k*pcount);
1195                for(i_=k*pcount; i_<=(k+1)*pcount-1;i_++)
1196                {
1197                    ensemble.columnsigmas[i_] = network.columnsigmas[i_+i1_];
1198                }
1199                rep.ngrad = rep.ngrad+tmprep.ngrad;
1200                rep.nhess = rep.nhess+tmprep.nhess;
1201                rep.ncholesky = rep.ncholesky+tmprep.ncholesky;
1202            }
1203        }
1204
1205
1206        /*************************************************************************
1207        Calculation of all types of errors
1208
1209          -- ALGLIB --
1210             Copyright 17.02.2009 by Bochkanov Sergey
1211        *************************************************************************/
1212        private static void mlpeallerrors(ref mlpensemble ensemble,
1213            ref double[,] xy,
1214            int npoints,
1215            ref double relcls,
1216            ref double avgce,
1217            ref double rms,
1218            ref double avg,
1219            ref double avgrel)
1220        {
1221            int i = 0;
1222            double[] buf = new double[0];
1223            double[] workx = new double[0];
1224            double[] y = new double[0];
1225            double[] dy = new double[0];
1226            int i_ = 0;
1227            int i1_ = 0;
1228
1229            workx = new double[ensemble.nin-1+1];
1230            y = new double[ensemble.nout-1+1];
1231            if( ensemble.issoftmax )
1232            {
1233                dy = new double[0+1];
1234                bdss.dserrallocate(ensemble.nout, ref buf);
1235            }
1236            else
1237            {
1238                dy = new double[ensemble.nout-1+1];
1239                bdss.dserrallocate(-ensemble.nout, ref buf);
1240            }
1241            for(i=0; i<=npoints-1; i++)
1242            {
1243                for(i_=0; i_<=ensemble.nin-1;i_++)
1244                {
1245                    workx[i_] = xy[i,i_];
1246                }
1247                mlpeprocess(ref ensemble, ref workx, ref y);
1248                if( ensemble.issoftmax )
1249                {
1250                    dy[0] = xy[i,ensemble.nin];
1251                }
1252                else
1253                {
1254                    i1_ = (ensemble.nin) - (0);
1255                    for(i_=0; i_<=ensemble.nout-1;i_++)
1256                    {
1257                        dy[i_] = xy[i,i_+i1_];
1258                    }
1259                }
1260                bdss.dserraccumulate(ref buf, ref y, ref dy);
1261            }
1262            bdss.dserrfinish(ref buf);
1263            relcls = buf[0];
1264            avgce = buf[1];
1265            rms = buf[2];
1266            avg = buf[3];
1267            avgrel = buf[4];
1268        }
1269
1270
1271        /*************************************************************************
1272        Internal bagging subroutine.
1273
1274          -- ALGLIB --
1275             Copyright 19.02.2009 by Bochkanov Sergey
1276        *************************************************************************/
1277        private static void mlpebagginginternal(ref mlpensemble ensemble,
1278            ref double[,] xy,
1279            int npoints,
1280            double decay,
1281            int restarts,
1282            double wstep,
1283            int maxits,
1284            bool lmalgorithm,
1285            ref int info,
1286            ref mlptrain.mlpreport rep,
1287            ref mlptrain.mlpcvreport ooberrors)
1288        {
1289            double[,] xys = new double[0,0];
1290            bool[] s = new bool[0];
1291            double[,] oobbuf = new double[0,0];
1292            int[] oobcntbuf = new int[0];
1293            double[] x = new double[0];
1294            double[] y = new double[0];
1295            double[] dy = new double[0];
1296            double[] dsbuf = new double[0];
1297            int nin = 0;
1298            int nout = 0;
1299            int ccnt = 0;
1300            int pcnt = 0;
1301            int i = 0;
1302            int j = 0;
1303            int k = 0;
1304            double v = 0;
1305            mlptrain.mlpreport tmprep = new mlptrain.mlpreport();
1306            mlpbase.multilayerperceptron network = new mlpbase.multilayerperceptron();
1307            int i_ = 0;
1308            int i1_ = 0;
1309
1310           
1311            //
1312            // Test for inputs
1313            //
1314            if( !lmalgorithm & (double)(wstep)==(double)(0) & maxits==0 )
1315            {
1316                info = -8;
1317                return;
1318            }
1319            if( npoints<=0 | restarts<1 | (double)(wstep)<(double)(0) | maxits<0 )
1320            {
1321                info = -1;
1322                return;
1323            }
1324            if( ensemble.issoftmax )
1325            {
1326                for(i=0; i<=npoints-1; i++)
1327                {
1328                    if( (int)Math.Round(xy[i,ensemble.nin])<0 | (int)Math.Round(xy[i,ensemble.nin])>=ensemble.nout )
1329                    {
1330                        info = -2;
1331                        return;
1332                    }
1333                }
1334            }
1335           
1336            //
1337            // allocate temporaries
1338            //
1339            info = 2;
1340            rep.ngrad = 0;
1341            rep.nhess = 0;
1342            rep.ncholesky = 0;
1343            ooberrors.relclserror = 0;
1344            ooberrors.avgce = 0;
1345            ooberrors.rmserror = 0;
1346            ooberrors.avgerror = 0;
1347            ooberrors.avgrelerror = 0;
1348            nin = ensemble.nin;
1349            nout = ensemble.nout;
1350            if( ensemble.issoftmax )
1351            {
1352                ccnt = nin+1;
1353                pcnt = nin;
1354            }
1355            else
1356            {
1357                ccnt = nin+nout;
1358                pcnt = nin+nout;
1359            }
1360            xys = new double[npoints-1+1, ccnt-1+1];
1361            s = new bool[npoints-1+1];
1362            oobbuf = new double[npoints-1+1, nout-1+1];
1363            oobcntbuf = new int[npoints-1+1];
1364            x = new double[nin-1+1];
1365            y = new double[nout-1+1];
1366            if( ensemble.issoftmax )
1367            {
1368                dy = new double[0+1];
1369            }
1370            else
1371            {
1372                dy = new double[nout-1+1];
1373            }
1374            for(i=0; i<=npoints-1; i++)
1375            {
1376                for(j=0; j<=nout-1; j++)
1377                {
1378                    oobbuf[i,j] = 0;
1379                }
1380            }
1381            for(i=0; i<=npoints-1; i++)
1382            {
1383                oobcntbuf[i] = 0;
1384            }
1385            mlpbase.mlpunserialize(ref ensemble.serializedmlp, ref network);
1386           
1387            //
1388            // main bagging cycle
1389            //
1390            for(k=0; k<=ensemble.ensemblesize-1; k++)
1391            {
1392               
1393                //
1394                // prepare dataset
1395                //
1396                for(i=0; i<=npoints-1; i++)
1397                {
1398                    s[i] = false;
1399                }
1400                for(i=0; i<=npoints-1; i++)
1401                {
1402                    j = AP.Math.RandomInteger(npoints);
1403                    s[j] = true;
1404                    for(i_=0; i_<=ccnt-1;i_++)
1405                    {
1406                        xys[i,i_] = xy[j,i_];
1407                    }
1408                }
1409               
1410                //
1411                // train
1412                //
1413                if( lmalgorithm )
1414                {
1415                    mlptrain.mlptrainlm(ref network, ref xys, npoints, decay, restarts, ref info, ref tmprep);
1416                }
1417                else
1418                {
1419                    mlptrain.mlptrainlbfgs(ref network, ref xys, npoints, decay, restarts, wstep, maxits, ref info, ref tmprep);
1420                }
1421                if( info<0 )
1422                {
1423                    return;
1424                }
1425               
1426                //
1427                // save results
1428                //
1429                rep.ngrad = rep.ngrad+tmprep.ngrad;
1430                rep.nhess = rep.nhess+tmprep.nhess;
1431                rep.ncholesky = rep.ncholesky+tmprep.ncholesky;
1432                i1_ = (0) - (k*ensemble.wcount);
1433                for(i_=k*ensemble.wcount; i_<=(k+1)*ensemble.wcount-1;i_++)
1434                {
1435                    ensemble.weights[i_] = network.weights[i_+i1_];
1436                }
1437                i1_ = (0) - (k*pcnt);
1438                for(i_=k*pcnt; i_<=(k+1)*pcnt-1;i_++)
1439                {
1440                    ensemble.columnmeans[i_] = network.columnmeans[i_+i1_];
1441                }
1442                i1_ = (0) - (k*pcnt);
1443                for(i_=k*pcnt; i_<=(k+1)*pcnt-1;i_++)
1444                {
1445                    ensemble.columnsigmas[i_] = network.columnsigmas[i_+i1_];
1446                }
1447               
1448                //
1449                // OOB estimates
1450                //
1451                for(i=0; i<=npoints-1; i++)
1452                {
1453                    if( !s[i] )
1454                    {
1455                        for(i_=0; i_<=nin-1;i_++)
1456                        {
1457                            x[i_] = xy[i,i_];
1458                        }
1459                        mlpbase.mlpprocess(ref network, ref x, ref y);
1460                        for(i_=0; i_<=nout-1;i_++)
1461                        {
1462                            oobbuf[i,i_] = oobbuf[i,i_] + y[i_];
1463                        }
1464                        oobcntbuf[i] = oobcntbuf[i]+1;
1465                    }
1466                }
1467            }
1468           
1469            //
1470            // OOB estimates
1471            //
1472            if( ensemble.issoftmax )
1473            {
1474                bdss.dserrallocate(nout, ref dsbuf);
1475            }
1476            else
1477            {
1478                bdss.dserrallocate(-nout, ref dsbuf);
1479            }
1480            for(i=0; i<=npoints-1; i++)
1481            {
1482                if( oobcntbuf[i]!=0 )
1483                {
1484                    v = (double)(1)/(double)(oobcntbuf[i]);
1485                    for(i_=0; i_<=nout-1;i_++)
1486                    {
1487                        y[i_] = v*oobbuf[i,i_];
1488                    }
1489                    if( ensemble.issoftmax )
1490                    {
1491                        dy[0] = xy[i,nin];
1492                    }
1493                    else
1494                    {
1495                        i1_ = (nin) - (0);
1496                        for(i_=0; i_<=nout-1;i_++)
1497                        {
1498                            dy[i_] = v*xy[i,i_+i1_];
1499                        }
1500                    }
1501                    bdss.dserraccumulate(ref dsbuf, ref y, ref dy);
1502                }
1503            }
1504            bdss.dserrfinish(ref dsbuf);
1505            ooberrors.relclserror = dsbuf[0];
1506            ooberrors.avgce = dsbuf[1];
1507            ooberrors.rmserror = dsbuf[2];
1508            ooberrors.avgerror = dsbuf[3];
1509            ooberrors.avgrelerror = dsbuf[4];
1510        }
1511    }
1512}
Note: See TracBrowser for help on using the repository browser.