root/applications/robust/robustlib.h @ 1320

Revision 1320, 63.5 kB (checked in by sindj, 13 years ago)

Rozdelano samplovani z emlig. Zbyva dodelat vypocet v jednotlivych simplexech triangulace. JS

Line 
1/*!
2  \file
3  \brief Robust Bayesian auto-regression model
4  \author Jan Sindelar.
5*/
6
7#ifndef ROBUST_H
8#define ROBUST_H
9
10//#include <stat/exp_family.h>
11#include <itpp/itbase.h>
12#include <map>
13#include <limits>
14#include <vector>
15#include <list>
16#include <set>
17#include <algorithm>
18       
19//using namespace bdm;
20using namespace std;
21using namespace itpp;
22
23const double max_range = 10;//numeric_limits<double>::max()/10e-10;
24
25/// An enumeration of possible actions performed on the polyhedrons. We can merge them or split them.
26enum actions {MERGE, SPLIT};
27
28// Forward declaration of polyhedron, vertex and emlig
29class polyhedron;
30class vertex;
31class emlig;
32
33/*
34class t_simplex
35{
36public:
37        set<vertex*> minima;
38
39        set<vertex*> simplex;
40
41        t_simplex(vertex* origin_vertex)
42        {
43                simplex.insert(origin_vertex);
44                minima.insert(origin_vertex);
45        }
46};*/
47
48/// A class representing a single condition that can be added to the emlig. A condition represents data entries in a statistical model.
49class condition
50{       
51public:
52        /// Value of the condition representing the data
53        vec value;     
54
55        /// Mulitplicity of the given condition may represent multiple occurences of same data entry.
56        int multiplicity;
57
58        /// Default constructor of condition class takes the value of data entry and creates a condition with multiplicity 1 (first occurence of the data).
59        condition(vec value)
60        {
61                this->value = value;
62                multiplicity = 1;
63        }
64};
65
66
67/// A class describing a single polyhedron of the split complex. From a collection of such classes a Hasse diagram
68/// of the structure in the exponent of a Laplace-Inverse-Gamma density will be created.
69class polyhedron
70{
71        /// A property having a value of 1 usually, with higher value only if the polyhedron arises as a coincidence of
72        /// more than just the necessary number of conditions. For example if a newly created line passes through an already
73        /// existing point, the points multiplicity will rise by 1.
74        int multiplicity;       
75
76        /// A property representing the position of the polyhedron related to current condition with relation to which we
77        /// are splitting the parameter space (new data has arrived). This property is setup within a classification procedure and
78        /// is only valid while the new condition is being added. It has to be reset when new condition is added and new classification
79        /// has to be performed.
80        int split_state;
81
82        /// A property representing the position of the polyhedron related to current condition with relation to which we
83        /// are merging the parameter space (data is being deleted usually due to a moving window model which is more adaptive and
84        /// steps in for the forgetting in a classical Gaussian AR model). This property is setup within a classification procedure and
85        /// is only valid while the new condition is being removed. It has to be reset when new condition is removed and new classification
86        /// has to be performed.
87        int merge_state;
88
89                       
90
91public:
92        /// A pointer to the multi-Laplace inverse gamma distribution this polyhedron belongs to.
93        emlig* my_emlig;
94
95        /// A list of polyhedrons parents within the Hasse diagram.
96        list<polyhedron*> parents;
97
98        /// A list of polyhedrons children withing the Hasse diagram.
99        list<polyhedron*> children;
100
101        /// All the vertices of the given polyhedron
102        set<vertex*> vertices;
103
104        /// The conditions that gave birth to the polyhedron. If some of them is removed, the polyhedron ceases to exist.
105        set<condition*> parentconditions;
106
107        /// A list used for storing children that lie in the positive region related to a certain condition
108        list<polyhedron*> positivechildren;
109
110        /// A list used for storing children that lie in the negative region related to a certain condition
111        list<polyhedron*> negativechildren;
112
113        /// Children intersecting the condition
114        list<polyhedron*> neutralchildren;
115
116        /// A set of grandchildren of the polyhedron that when new condition is added lie exactly on the condition hyperplane. These grandchildren
117        /// behave differently from other grandchildren, when the polyhedron is split. New grandchild is not necessarily created on the crossection of
118        /// the polyhedron and new condition.
119        set<polyhedron*> totallyneutralgrandchildren;
120
121        /// A set of children of the polyhedron that when new condition is added lie exactly on the condition hyperplane. These children
122        /// behave differently from other children, when the polyhedron is split. New child is not necessarily created on the crossection of
123        /// the polyhedron and new condition.
124        set<polyhedron*> totallyneutralchildren;
125
126        /// Reverse relation to the totallyneutralgrandchildren set is needed for merging of already existing polyhedrons to keep
127        /// totallyneutralgrandchildren list up to date.
128        set<polyhedron*> grandparents;
129
130        /// Vertices of the polyhedron classified as positive related to an added condition. When the polyhderon is split by the new condition,
131        /// these vertices will belong to the positive part of the splitted polyhedron.
132        set<vertex*> positiveneutralvertices;
133
134        /// Vertices of the polyhedron classified as negative related to an added condition. When the polyhderon is split by the new condition,
135        /// these vertices will belong to the negative part of the splitted polyhedron.
136        set<vertex*> negativeneutralvertices;
137
138        /// A bool specifying if the polyhedron lies exactly on the newly added condition or not.
139        bool totally_neutral;
140
141        /// When two polyhedrons are merged, there always exists a child lying on the former border of the polyhedrons. This child manages the merge
142        /// of the two polyhedrons. This property gives us the address of the mediator child.
143        polyhedron* mergechild;
144
145        /// If the polyhedron serves as a mergechild for two of its parents, we need to have the address of the parents to access them. This
146        /// is the pointer to the positive parent being merged.
147        polyhedron* positiveparent;
148
149        /// If the polyhedron serves as a mergechild for two of its parents, we need to have the address of the parents to access them. This
150        /// is the pointer to the negative parent being merged.
151        polyhedron* negativeparent;     
152
153        /// Adressing withing the statistic. Next_poly is a pointer to the next polyhedron in the statistic on the same level (if this is a point,
154        /// next_poly will be a point etc.).
155        polyhedron* next_poly;
156
157        /// Adressing withing the statistic. Prev_poly is a pointer to the previous polyhedron in the statistic on the same level (if this is a point,
158        /// next_poly will be a point etc.).
159        polyhedron* prev_poly;
160
161        /// A property counting the number of messages obtained from children within a classification procedure of position of the polyhedron related
162        /// an added/removed condition. If the message counter reaches the number of children, we know the polyhedrons' position has been fully classified.
163        int message_counter;
164
165        /// List of triangulation polyhedrons of the polyhedron given by their relative vertices.
166        map<double,set<vertex*>> triangulation;
167
168        /// A list of relative addresses serving for Hasse diagram construction.
169        list<int> kids_rel_addresses;
170
171        /// Default constructor
172        polyhedron()
173        {
174                multiplicity = 1;
175
176                message_counter = 0;
177
178                totally_neutral = NULL;
179
180                mergechild = NULL;             
181        }
182       
183        /// Setter for raising multiplicity
184        void raise_multiplicity()
185        {
186                multiplicity++;
187        }
188
189        /// Setter for lowering multiplicity
190        void lower_multiplicity()
191        {
192                multiplicity--;
193        }
194
195        int get_multiplicity()
196        {
197                return multiplicity;
198        }
199       
200        /// An obligatory operator, when the class is used within a C++ STL structure like a vector
201        int operator==(polyhedron polyhedron2)
202        {
203                return true;
204        }
205
206        /// An obligatory operator, when the class is used within a C++ STL structure like a vector
207        int operator<(polyhedron polyhedron2)
208        {
209                return false;
210        }
211
212       
213        /// A setter of state of current polyhedron relative to the action specified in the argument. The three possible states of the
214        /// polyhedron are -1 - NEGATIVE, 0 - NEUTRAL, 1 - POSITIVE. Neutral state means that either the state has been reset or the polyhedron is
215        /// ready to be split/merged.
216        int set_state(double state_indicator, actions action)
217        {
218                switch(action)
219                {
220                        case MERGE:
221                                merge_state = (int)sign(state_indicator);
222                                return merge_state;                     
223                        case SPLIT:
224                                split_state = (int)sign(state_indicator);
225                                return split_state;             
226                }
227        }
228
229        /// A getter of state of current polyhedron relative to the action specified in the argument. The three possible states of the
230        /// polyhedron are -1 - NEGATIVE, 0 - NEUTRAL, 1 - POSITIVE. Neutral state means that either the state has been reset or the polyhedron is
231        /// ready to be split/merged.
232        int get_state(actions action)
233        {
234                switch(action)
235                {
236                        case MERGE:
237                                return merge_state;                     
238                        break;
239                        case SPLIT:
240                                return split_state;
241                        break;
242                }
243        }
244
245        /// Method for obtaining the number of children of given polyhedron.
246        int number_of_children()
247        {
248                return children.size();
249        }
250
251        /// A method for triangulation of given polyhedron.
252        void triangulate(bool should_integrate);       
253};
254
255
256/// A class for representing 0-dimensional polyhedron - a vertex. It will be located in the bottom row of the Hasse
257/// diagram representing a complex of polyhedrons. It has its coordinates in the parameter space.
258class vertex : public polyhedron
259{
260        /// A dynamic array representing coordinates of the vertex
261        vec coordinates;
262
263public:
264        /// A property specifying the value of the density (ted nevim, jestli je to jakoby log nebo ne) above the vertex.
265        double function_value;
266
267        /// Default constructor
268        vertex();
269
270        /// Constructor of a vertex from a set of coordinates
271        vertex(vec coordinates)
272        {
273                this->coordinates   = coordinates;
274
275                vertices.insert(this);
276
277                set<vertex*> vert_simplex;
278
279                vert_simplex.insert(this);
280
281                triangulation.insert(pair<double,set<vertex*>>(0,vert_simplex));
282        }
283
284        /// A method that widens the set of coordinates of given vertex. It is used when a complex in a parameter
285        /// space of certain dimension is established, but the dimension is not known when the vertex is created.
286        void push_coordinate(double coordinate)
287        {
288                coordinates  = concat(coordinates,coordinate);         
289        }
290
291        /// A method obtaining the set of coordinates of a vertex. These coordinates are not obtained as a pointer
292        /// (not given by reference), but a new copy is created (they are given by value).
293        vec get_coordinates()
294        {
295                return coordinates;
296        }
297               
298};
299
300
301/// A class representing a polyhedron in a top row of the complex. Such polyhedron has a condition that differen   tiates
302/// it from polyhedrons in other rows.
303class toprow : public polyhedron
304{
305       
306public:
307        double probability;
308
309        vertex* minimal_vertex;
310
311        /// A condition used for determining the function of a Laplace-Inverse-Gamma density resulting from Bayesian estimation
312        vec condition_sum;
313
314        int condition_order;
315
316        /// Default constructor
317        toprow(){};
318
319        /// Constructor creating a toprow from the condition
320        toprow(condition *condition, int condition_order)
321        {
322                this->condition_sum   = condition->value;
323                this->condition_order = condition_order;
324        }
325
326        toprow(vec condition_sum, int condition_order)
327        {
328                this->condition_sum   = condition_sum;
329                this->condition_order = condition_order;
330        }
331
332        double integrate_simplex(set<vertex*> simplex, char c);
333
334};
335
336
337
338
339
340
341class c_statistic
342{
343
344public:
345        polyhedron* end_poly;
346        polyhedron* start_poly;
347
348        vector<polyhedron*> rows;
349
350        vector<polyhedron*> row_ends;
351
352        c_statistic()
353        {
354                end_poly   = new polyhedron();
355                start_poly = new polyhedron();
356        };
357
358        void append_polyhedron(int row, polyhedron* appended_start, polyhedron* appended_end)
359        {
360                if(row>((int)rows.size())-1)
361                {
362                        if(row>rows.size())
363                        {
364                                throw new exception("You are trying to append a polyhedron whose children are not in the statistic yet!");
365                                return;
366                        }
367
368                        rows.push_back(end_poly);
369                        row_ends.push_back(end_poly);
370                }
371
372                // POSSIBLE FAILURE: the function is not checking if start and end are connected
373
374                if(rows[row] != end_poly)
375                {
376                        appended_start->prev_poly = row_ends[row];
377                        row_ends[row]->next_poly = appended_start;                     
378                                               
379                }
380                else if((row>0 && rows[row-1]!=end_poly)||row==0)
381                {
382                        appended_start->prev_poly = start_poly;
383                        rows[row]= appended_start;                     
384                }
385                else
386                {
387                        throw new exception("Wrong polyhedron insertion into statistic: missing intermediary polyhedron!");
388                }
389
390                appended_end->next_poly = end_poly;
391                row_ends[row] = appended_end;
392        }
393
394        void append_polyhedron(int row, polyhedron* appended_poly)
395        {
396                append_polyhedron(row,appended_poly,appended_poly);
397        }
398
399        void insert_polyhedron(int row, polyhedron* inserted_poly, polyhedron* following_poly)
400        {               
401                if(following_poly != end_poly)
402                {
403                        inserted_poly->next_poly = following_poly;
404                        inserted_poly->prev_poly = following_poly->prev_poly;
405
406                        if(following_poly->prev_poly == start_poly)
407                        {
408                                rows[row] = inserted_poly;
409                        }
410                        else
411                        {                               
412                                inserted_poly->prev_poly->next_poly = inserted_poly;                                                           
413                        }
414
415                        following_poly->prev_poly = inserted_poly;
416                }
417                else
418                {
419                        this->append_polyhedron(row, inserted_poly);
420                }               
421       
422        }
423
424
425       
426
427        void delete_polyhedron(int row, polyhedron* deleted_poly)
428        {
429                if(deleted_poly->prev_poly != start_poly)
430                {
431                        deleted_poly->prev_poly->next_poly = deleted_poly->next_poly;
432                }
433                else
434                {
435                        rows[row] = deleted_poly->next_poly;
436                }
437
438                if(deleted_poly->next_poly!=end_poly)
439                {
440                        deleted_poly->next_poly->prev_poly = deleted_poly->prev_poly;
441                }
442                else
443                {
444                        row_ends[row] = deleted_poly->prev_poly;
445                }
446
447               
448
449                deleted_poly->next_poly = NULL;
450                deleted_poly->prev_poly = NULL;                                 
451        }
452
453        int size()
454        {
455                return rows.size();
456        }
457
458        polyhedron* get_end()
459        {
460                return end_poly;
461        }
462
463        polyhedron* get_start()
464        {
465                return start_poly;
466        }
467
468        int row_size(int row)
469        {
470                if(this->size()>row && row>=0)
471                {
472                        int row_size = 0;
473                       
474                        for(polyhedron* row_poly = rows[row]; row_poly!=end_poly; row_poly=row_poly->next_poly)
475                        {
476                                row_size++;
477                        }
478
479                        return row_size;
480                }
481                else
482                {
483                        throw new exception("There is no row to obtain size from!");
484                }
485        }
486};
487
488
489class my_ivec : public ivec
490{
491public:
492        my_ivec():ivec(){};
493
494        my_ivec(ivec origin):ivec()
495        {
496                this->ins(0,origin);
497        }
498
499        bool operator>(const my_ivec &second) const
500        {
501                return max(*this)>max(second);
502               
503                /*
504                int size1 = this->size();
505                int size2 = second.size();             
506                 
507                int counter1 = 0;
508                while(0==0)
509                {
510                        if((*this)[counter1]==0)
511                        {
512                                size1--;
513                        }
514                       
515                        if((*this)[counter1]!=0)
516                                break;
517
518                        counter1++;
519                }
520
521                int counter2 = 0;
522                while(0==0)
523                {
524                        if(second[counter2]==0)
525                        {
526                                size2--;
527                        }
528                       
529                        if(second[counter2]!=0)
530                                break;
531
532                        counter2++;
533                }
534
535                if(size1!=size2)
536                {
537                        return size1>size2;
538                }
539                else
540                {
541                        for(int i = 0;i<size1;i++)
542                        {
543                                if((*this)[counter1+i]!=second[counter2+i])
544                                {
545                                        return (*this)[counter1+i]>second[counter2+i];
546                                }
547                        }
548
549                        return false;
550                }*/
551        }
552
553       
554        bool operator==(const my_ivec &second) const
555        {
556                return max(*this)==max(second);
557               
558                /*
559                int size1 = this->size();
560                int size2 = second.size();             
561                 
562                int counter = 0;
563                while(0==0)
564                {
565                        if((*this)[counter]==0)
566                {
567                        size1--;
568                }
569                       
570                if((*this)[counter]!=0)
571                        break;
572
573                counter++;
574                }
575
576                counter = 0;
577                while(0==0)
578                {
579                        if(second[counter]==0)
580                        {
581                                size2--;
582                        }
583                       
584                        if(second[counter]!=0)
585                                break;
586
587                        counter++;
588                }
589
590                if(size1!=size2)
591                {
592                        return false;
593                }
594                else
595                {
596                        for(int i=0;i<size1;i++)
597                        {
598                                if((*this)[size()-1-i]!=second[second.size()-1-i])
599                                {
600                                        return false;
601                                }
602                        }
603
604                        return true;
605                }*/
606        }
607
608        bool operator<(const my_ivec &second) const
609        {
610                return !(((*this)>second)||((*this)==second));
611        }
612
613        bool operator!=(const my_ivec &second) const
614        {
615                return !((*this)==second);
616        }
617
618        bool operator<=(const my_ivec &second) const
619        {
620                return !((*this)>second);
621        }
622
623        bool operator>=(const my_ivec &second) const
624        {
625                return !((*this)<second);
626        }
627
628        my_ivec right(my_ivec original)
629        {
630               
631        }
632};
633
634
635
636
637
638
639
640//! Conditional(e) Multicriteria-Laplace-Inverse-Gamma distribution density
641class emlig // : eEF
642{
643
644        /// A statistic in a form of a Hasse diagram representing a complex of convex polyhedrons obtained as a result
645        /// of data update from Bayesian estimation or set by the user if this emlig is a prior density
646       
647
648        vector<list<polyhedron*>> for_splitting;
649               
650        vector<list<polyhedron*>> for_merging;
651
652        list<condition*> conditions;
653
654        double normalization_factor;
655
656       
657
658        void alter_toprow_conditions(condition *condition, bool should_be_added)
659        {
660                for(polyhedron* horiz_ref = statistic.rows[statistic.size()-1];horiz_ref!=statistic.get_end();horiz_ref=horiz_ref->next_poly)
661                {
662                        set<vertex*>::iterator vertex_ref = horiz_ref->vertices.begin();
663
664                        do
665                        {
666                                vertex_ref++;
667                        }
668                        while((*vertex_ref)->parentconditions.find(condition)==(*vertex_ref)->parentconditions.end());
669
670                        double product = (*vertex_ref)->get_coordinates()*condition->value;
671
672                        if(should_be_added)
673                        {
674                                ((toprow*) horiz_ref)->condition_order++;
675
676                                if(product>0)
677                                {
678                                        ((toprow*) horiz_ref)->condition_sum += condition->value;
679                                }
680                                else
681                                {
682                                        ((toprow*) horiz_ref)->condition_sum -= condition->value;
683                                }
684                        }
685                        else
686                        { 
687                                ((toprow*) horiz_ref)->condition_order--;
688
689                                if(product<0)                   
690                                {
691                                        ((toprow*) horiz_ref)->condition_sum += condition->value;
692                                }
693                                else
694                                {
695                                        ((toprow*) horiz_ref)->condition_sum -= condition->value;
696                                }
697                        }                               
698                }
699        }
700
701
702
703        void send_state_message(polyhedron* sender, condition *toadd, condition *toremove, int level)
704        {                       
705
706                bool shouldmerge    = (toremove != NULL);
707                bool shouldsplit    = (toadd != NULL);
708               
709                if(shouldsplit||shouldmerge)
710                {
711                        for(list<polyhedron*>::iterator parent_iterator = sender->parents.begin();parent_iterator!=sender->parents.end();parent_iterator++)
712                        {
713                                polyhedron* current_parent = *parent_iterator;
714
715                                current_parent->message_counter++;
716
717                                bool is_last  = (current_parent->message_counter == current_parent->number_of_children());
718                                bool is_first = (current_parent->message_counter == 1);
719
720                                if(shouldmerge)
721                                {
722                                        int child_state  = sender->get_state(MERGE);
723                                        int parent_state = current_parent->get_state(MERGE);
724
725                                        if(parent_state == 0||is_first)
726                                        {
727                                                parent_state = current_parent->set_state(child_state, MERGE);                                           
728                                        }                                       
729
730                                        if(child_state == 0)
731                                        {
732                                                if(current_parent->mergechild == NULL)
733                                                {
734                                                        current_parent->mergechild = sender;
735                                                }                                                       
736                                        }                                       
737
738                                        if(is_last)
739                                        {                                               
740                                                if(parent_state == 1)
741                                                {
742                                                        ((toprow*)current_parent)->condition_sum-=toremove->value;
743                                                        ((toprow*)current_parent)->condition_order--;
744                                                }
745
746                                                if(parent_state == -1)
747                                                {
748                                                        ((toprow*)current_parent)->condition_sum+=toremove->value;
749                                                        ((toprow*)current_parent)->condition_order--;
750                                                }
751                                               
752                                                if(current_parent->mergechild != NULL)
753                                                {
754                                                        if(current_parent->mergechild->get_multiplicity()==1)
755                                                        {
756                                                                if(parent_state > 0)
757                                                                {                                                       
758                                                                        current_parent->mergechild->positiveparent = current_parent;                                                   
759                                                                }
760
761                                                                if(parent_state < 0)
762                                                                {                                                       
763                                                                        current_parent->mergechild->negativeparent = current_parent;                                                   
764                                                                }
765                                                        }                                                       
766                                                }                                               
767                                                else
768                                                {
769                                                        //current_parent->set_state(0,MERGE);   
770
771                                                        if(level == number_of_parameters - 1)
772                                                        {
773                                                                toprow* cur_par_toprow = ((toprow*)current_parent);
774                                                                cur_par_toprow->probability = 0.0;
775                                                               
776                                                                map<double,set<vertex*>> new_triangulation;
777
778                                                                for(map<double,set<vertex*>>::iterator t_ref = current_parent->triangulation.begin();t_ref!=current_parent->triangulation.end();t_ref++)
779                                                                {
780                                                                        double cur_prob = cur_par_toprow->integrate_simplex((*t_ref).second,'C');
781                                                                       
782                                                                        cur_par_toprow->probability += cur_prob;
783
784                                                                        new_triangulation.insert(pair<double,set<vertex*>>(cur_prob,(*t_ref).second));
785                                                                }
786
787                                                                current_parent->triangulation.clear();
788                                                                current_parent->triangulation.insert(new_triangulation.begin(),new_triangulation.end());
789                                                        }
790                                                }
791
792                                                if(parent_state == 0)
793                                                {
794                                                        for_merging[level+1].push_back(current_parent);
795                                                        //current_parent->parentconditions.erase(toremove);
796                                                }                                               
797
798                                                                                               
799                                        }                                       
800                                }
801
802                                if(shouldsplit)
803                                {
804                                        current_parent->totallyneutralgrandchildren.insert(sender->totallyneutralchildren.begin(),sender->totallyneutralchildren.end());
805
806                                        for(set<polyhedron*>::iterator tot_child_ref = sender->totallyneutralchildren.begin();tot_child_ref!=sender->totallyneutralchildren.end();tot_child_ref++)
807                                        {
808                                                (*tot_child_ref)->grandparents.insert(current_parent);
809                                        }
810
811                                        switch(sender->get_state(SPLIT))
812                                        {
813                                        case 1:
814                                                current_parent->positivechildren.push_back(sender);
815                                                current_parent->positiveneutralvertices.insert(sender->vertices.begin(),sender->vertices.end());
816                                        break;
817                                        case 0:
818                                                current_parent->neutralchildren.push_back(sender);
819                                                current_parent->positiveneutralvertices.insert(sender->positiveneutralvertices.begin(),sender->positiveneutralvertices.end());
820                                                current_parent->negativeneutralvertices.insert(sender->negativeneutralvertices.begin(),sender->negativeneutralvertices.end());
821
822                                                if(current_parent->totally_neutral == NULL)
823                                                {
824                                                        current_parent->totally_neutral = sender->totally_neutral;
825                                                }
826                                                else
827                                                {
828                                                        current_parent->totally_neutral = current_parent->totally_neutral && sender->totally_neutral;
829                                                }
830
831                                                if(sender->totally_neutral)
832                                                {
833                                                        current_parent->totallyneutralchildren.insert(sender);
834                                                }
835                                                       
836                                        break;
837                                        case -1:
838                                                current_parent->negativechildren.push_back(sender);
839                                                current_parent->negativeneutralvertices.insert(sender->vertices.begin(),sender->vertices.end());
840                                        break;
841                                        }
842
843                                        if(is_last)
844                                        {
845                                               
846                                                /// \TODO Nechapu druhou podminku, zda se mi ze je to spatne.. Nemela by byt jen prvni? Nebo se jedna o nastaveni totalni neutrality?
847                                                if((current_parent->negativechildren.size()>0&&current_parent->positivechildren.size()>0)||
848                                                                                                        (current_parent->neutralchildren.size()>0&&current_parent->totally_neutral==false))
849                                                {
850                                                        for_splitting[level+1].push_back(current_parent);                                               
851                                                               
852                                                        current_parent->set_state(0, SPLIT);
853                                                }
854                                                else
855                                                {
856                                                        if(current_parent->negativechildren.size()>0)
857                                                        {
858                                                                current_parent->set_state(-1, SPLIT);
859
860                                                                ((toprow*)current_parent)->condition_sum-=toadd->value;
861                                                                       
862                                                        }
863                                                        else if(current_parent->positivechildren.size()>0)
864                                                        {
865                                                                current_parent->set_state(1, SPLIT);
866
867                                                                ((toprow*)current_parent)->condition_sum+=toadd->value;                                                                 
868                                                        }
869                                                        else
870                                                        {
871                                                                current_parent->raise_multiplicity();                                                           
872                                                        }
873
874                                                        ((toprow*)current_parent)->condition_order++;
875
876                                                        if(level == number_of_parameters - 1)
877                                                        {
878                                                                toprow* cur_par_toprow = ((toprow*)current_parent);
879                                                                cur_par_toprow->probability = 0.0;
880                                                                       
881                                                                map<double,set<vertex*>> new_triangulation;
882                                                               
883                                                                for(map<double,set<vertex*>>::iterator t_ref = current_parent->triangulation.begin();t_ref!=current_parent->triangulation.end();t_ref++)
884                                                                {
885                                                                        double cur_prob = cur_par_toprow->integrate_simplex((*t_ref).second,'C');
886                                                                       
887                                                                        cur_par_toprow->probability += cur_prob;
888
889                                                                        new_triangulation.insert(pair<double,set<vertex*>>(cur_prob,(*t_ref).second));
890                                                                }
891
892                                                                current_parent->triangulation.clear();
893                                                                current_parent->triangulation.insert(new_triangulation.begin(),new_triangulation.end());
894                                                        }
895
896                                                        if(current_parent->mergechild == NULL)
897                                                        {
898                                                                current_parent->positivechildren.clear();
899                                                                current_parent->negativechildren.clear();
900                                                                current_parent->neutralchildren.clear();
901                                                                current_parent->totallyneutralchildren.clear();
902                                                                current_parent->totallyneutralgrandchildren.clear();
903                                                                // current_parent->grandparents.clear();
904                                                                current_parent->positiveneutralvertices.clear();
905                                                                current_parent->negativeneutralvertices.clear();
906                                                                current_parent->totally_neutral = NULL;
907                                                                current_parent->kids_rel_addresses.clear();
908                                                        }                                                       
909                                                }
910                                        }
911                                }
912
913                                if(is_last)
914                                {
915                                        current_parent->mergechild = NULL;
916                                        current_parent->message_counter = 0;
917
918                                        send_state_message(current_parent,toadd,toremove,level+1);
919                                }
920                       
921                        }
922                       
923                }               
924        }
925       
926public: 
927        c_statistic statistic;
928
929        vertex* minimal_vertex;
930
931        double likelihood_value;
932
933        vector<multiset<my_ivec>> correction_factors;
934
935        int number_of_parameters;
936
937        /// A default constructor creates an emlig with predefined statistic representing only the range of the given
938        /// parametric space, where the number of parameters of the needed model is given as a parameter to the constructor.
939        emlig(int number_of_parameters)
940        {       
941                this->number_of_parameters = number_of_parameters;
942
943                create_statistic(number_of_parameters);
944
945                likelihood_value = numeric_limits<double>::max();
946        }
947
948        /// A constructor for creating an emlig when the user wants to create the statistic by himself. The creation of a
949        /// statistic is needed outside the constructor. Used for a user defined prior distribution on the parameters.
950        emlig(c_statistic statistic)
951        {
952                this->statistic = statistic;   
953
954                likelihood_value = numeric_limits<double>::max();
955        }
956
957        void step_me(int marker)
958        {
959               
960                for(int i = 0;i<statistic.size();i++)
961                {
962                        int zero = 0;
963                        int one  = 0;
964                        int two  = 0;
965
966                        for(polyhedron* horiz_ref = statistic.rows[i];horiz_ref!=statistic.get_end();horiz_ref=horiz_ref->next_poly)
967                        {
968                               
969                                /*
970                                if(i==statistic.size()-1)
971                                {
972                                        //cout << ((toprow*)horiz_ref)->condition_sum << "   " << ((toprow*)horiz_ref)->probability << endl;
973                                        cout << "Order:" << ((toprow*)horiz_ref)->condition_order << endl;
974                                }
975                                if(i==0)
976                                {
977                                        cout << ((vertex*)horiz_ref)->get_coordinates() << endl;
978                                }
979                                */
980
981                                char* string = "Checkpoint";
982
983                                if((*horiz_ref).parentconditions.size()==0)
984                                {
985                                        zero++;
986                                }
987                                else if((*horiz_ref).parentconditions.size()==1)
988                                {
989                                        one++;                                 
990                                }
991                                else
992                                {
993                                        two++;
994                                }
995                               
996                        }
997                }
998               
999
1000                /*
1001                list<vec> table_entries;
1002                for(polyhedron* horiz_ref = statistic.rows[statistic.size()-1];horiz_ref!=statistic.row_ends[statistic.size()-1];horiz_ref=horiz_ref->next_poly)
1003                {
1004                        toprow *current_toprow = (toprow*)(horiz_ref);
1005                        for(list<set<vertex*>>::iterator tri_ref = current_toprow->triangulation.begin();tri_ref!=current_toprow->triangulation.end();tri_ref++)
1006                        {
1007                                for(set<vertex*>::iterator vert_ref = (*tri_ref).begin();vert_ref!=(*tri_ref).end();vert_ref++)
1008                                {
1009                                        vec table_entry = vec();
1010                                       
1011                                        table_entry.ins(0,(*vert_ref)->get_coordinates()*current_toprow->condition.get(1,current_toprow->condition.size()-1)-current_toprow->condition.get(0,0));
1012                                       
1013                                        table_entry.ins(0,(*vert_ref)->get_coordinates());
1014
1015                                        table_entries.push_back(table_entry);
1016                                }
1017                        }                       
1018                }
1019
1020                unique(table_entries.begin(),table_entries.end());
1021
1022                               
1023               
1024                for(list<vec>::iterator entry_ref = table_entries.begin();entry_ref!=table_entries.end();entry_ref++)
1025                {
1026                        ofstream myfile;
1027                        myfile.open("robust_data.txt", ios::out | ios::app);
1028                        if (myfile.is_open())
1029                        {
1030                                for(int i = 0;i<(*entry_ref).size();i++)
1031                                {
1032                                        myfile << (*entry_ref)[i] << ";";
1033                                }
1034                                myfile << endl;
1035                       
1036                                myfile.close();
1037                        }
1038                        else
1039                        {
1040                                cout << "File problem." << endl;
1041                        }
1042                }
1043                */
1044               
1045
1046                return;
1047        }
1048
1049        int statistic_rowsize(int row)
1050        {
1051                return statistic.row_size(row);
1052        }
1053
1054        void add_condition(vec toadd)
1055        {
1056                vec null_vector = "";
1057
1058                add_and_remove_condition(toadd, null_vector);
1059        }
1060
1061
1062        void remove_condition(vec toremove)
1063        {               
1064                vec null_vector = "";
1065
1066                add_and_remove_condition(null_vector, toremove);
1067       
1068        }
1069
1070        void add_and_remove_condition(vec toadd, vec toremove)
1071        {
1072                step_me(0);
1073               
1074                likelihood_value = numeric_limits<double>::max();
1075
1076                bool should_remove = (toremove.size() != 0);
1077                bool should_add    = (toadd.size() != 0);
1078
1079                for_splitting.clear();
1080                for_merging.clear();
1081
1082                for(int i = 0;i<statistic.size();i++)
1083                {
1084                        list<polyhedron*> empty_split;
1085                        list<polyhedron*> empty_merge;
1086
1087                        for_splitting.push_back(empty_split);
1088                        for_merging.push_back(empty_merge);
1089                }
1090
1091                list<condition*>::iterator toremove_ref = conditions.end();
1092                bool condition_should_be_added = should_add;
1093
1094                for(list<condition*>::iterator ref = conditions.begin();ref!=conditions.end();ref++)
1095                {
1096                        if(should_remove)
1097                        {
1098                                if((*ref)->value == toremove)
1099                                {
1100                                        if((*ref)->multiplicity>1)
1101                                        {
1102                                                (*ref)->multiplicity--;
1103
1104                                                alter_toprow_conditions(*ref,false);
1105
1106                                                should_remove = false;
1107                                        }
1108                                        else
1109                                        {
1110                                                toremove_ref = ref;                                                     
1111                                        }
1112                                }
1113                        }
1114
1115                        if(should_add)
1116                        {
1117                                if((*ref)->value == toadd)
1118                                {
1119                                        (*ref)->multiplicity++;
1120
1121                                        alter_toprow_conditions(*ref,true);
1122
1123                                        should_add = false;
1124
1125                                        condition_should_be_added = false;
1126                                }                               
1127                        }
1128                }       
1129
1130                condition* condition_to_remove = NULL;
1131
1132                if(toremove_ref!=conditions.end())
1133                {
1134                        condition_to_remove = *toremove_ref;
1135                        conditions.erase(toremove_ref);                 
1136                }
1137
1138                condition* condition_to_add = NULL;
1139
1140                if(condition_should_be_added)
1141                {
1142                        condition* new_condition = new condition(toadd);
1143                       
1144                        conditions.push_back(new_condition);
1145                        condition_to_add = new_condition;
1146                }               
1147               
1148                for(polyhedron* horizontal_position = statistic.rows[0];horizontal_position!=statistic.get_end();horizontal_position=horizontal_position->next_poly)
1149                {               
1150                        vertex* current_vertex = (vertex*)horizontal_position;
1151                       
1152                        if(should_add||should_remove)
1153                        {
1154                                vec appended_coords = current_vertex->get_coordinates();
1155                                appended_coords.ins(0,-1.0);                           
1156
1157                                if(should_add)
1158                                {
1159                                        double local_condition = 0;// = toadd*(appended_coords.first/=appended_coords.second);
1160
1161                                        local_condition = appended_coords*toadd;
1162
1163                                        current_vertex->set_state(local_condition,SPLIT);
1164
1165                                        /// \TODO There should be a rounding error tolerance used here to insure we are not having too many points because of rounding error.
1166                                        if(local_condition == 0)
1167                                        {
1168                                                current_vertex->totally_neutral = true;
1169
1170                                                current_vertex->raise_multiplicity();
1171
1172                                                current_vertex->negativeneutralvertices.insert(current_vertex);
1173                                                current_vertex->positiveneutralvertices.insert(current_vertex);
1174                                        }                                       
1175                                }
1176                       
1177                                if(should_remove)
1178                                {                                       
1179                                        set<condition*>::iterator cond_ref;
1180                                       
1181                                        for(cond_ref = current_vertex->parentconditions.begin();cond_ref!=current_vertex->parentconditions.end();cond_ref++)
1182                                        {
1183                                                if(*cond_ref == condition_to_remove)
1184                                                {
1185                                                        break;
1186                                                }
1187                                        }
1188
1189                                        if(cond_ref!=current_vertex->parentconditions.end())
1190                                        {
1191                                                current_vertex->parentconditions.erase(cond_ref);
1192                                                current_vertex->set_state(0,MERGE);
1193                                                for_merging[0].push_back(current_vertex);
1194                                        }
1195                                        else
1196                                        {
1197                                                double local_condition = toremove*appended_coords;
1198                                                current_vertex->set_state(local_condition,MERGE);
1199                                        }
1200                                }                               
1201                        }
1202
1203                        send_state_message(current_vertex, condition_to_add, condition_to_remove, 0);           
1204                       
1205                }
1206
1207               
1208               
1209                if(should_remove)
1210                {
1211                        for(int i = 0;i<for_merging.size();i++)
1212                        {
1213                                for(list<polyhedron*>::iterator merge_ref = for_merging[i].begin();merge_ref!=for_merging[i].end();merge_ref++)
1214                                {
1215                                        cout << (*merge_ref)->get_state(MERGE) << ",";
1216                                }
1217
1218                                cout << endl;
1219                        }
1220
1221                        set<vertex*> vertices_to_be_reduced;                   
1222                       
1223                        int k = 1;
1224
1225                        for(vector<list<polyhedron*>>::iterator vert_ref = for_merging.begin();vert_ref<for_merging.end();vert_ref++)
1226                        {
1227                                for(list<polyhedron*>::reverse_iterator merge_ref = vert_ref->rbegin();merge_ref!=vert_ref->rend();merge_ref++)
1228                                {
1229                                        if((*merge_ref)->get_multiplicity()>1)
1230                                        {
1231                                                if(k==1)
1232                                                {
1233                                                        vertices_to_be_reduced.insert((vertex*)(*merge_ref));
1234                                                }
1235                                                else
1236                                                {
1237                                                        (*merge_ref)->lower_multiplicity();
1238                                                }
1239                                        }
1240                                        else
1241                                        {
1242                                                toprow* current_positive = (toprow*)(*merge_ref)->positiveparent;
1243                                                toprow* current_negative = (toprow*)(*merge_ref)->negativeparent;
1244
1245                                                //current_positive->condition_sum -= toremove;
1246                                                //current_positive->condition_order--;
1247
1248                                                current_positive->parentconditions.erase(condition_to_remove);
1249                                               
1250                                                current_positive->children.insert(current_positive->children.end(),current_negative->children.begin(),current_negative->children.end());
1251                                                current_positive->children.remove(*merge_ref);
1252
1253                                                for(list<polyhedron*>::iterator child_ref = current_negative->children.begin();child_ref!=current_negative->children.end();child_ref++)
1254                                                {
1255                                                        (*child_ref)->parents.remove(current_negative);
1256                                                        (*child_ref)->parents.push_back(current_positive);                                                                                                     
1257                                                }
1258
1259                                                // current_positive->parents.insert(current_positive->parents.begin(),current_negative->parents.begin(),current_negative->parents.end());
1260                                                // unique(current_positive->parents.begin(),current_positive->parents.end());
1261
1262                                                for(list<polyhedron*>::iterator parent_ref = current_negative->parents.begin();parent_ref!=current_negative->parents.end();parent_ref++)
1263                                                {
1264                                                        (*parent_ref)->children.remove(current_negative);
1265
1266                                                        switch(current_negative->get_state(SPLIT))
1267                                                        {
1268                                                        case -1:
1269                                                                (*parent_ref)->negativechildren.remove(current_negative);
1270                                                                break;
1271                                                        case 0:
1272                                                                (*parent_ref)->neutralchildren.remove(current_negative);                                                               
1273                                                                break;
1274                                                        case 1:
1275                                                                (*parent_ref)->positivechildren.remove(current_negative);
1276                                                                break;
1277                                                        }
1278                                                        //(*parent_ref)->children.push_back(current_positive);
1279                                                }
1280
1281                                                if(current_positive->get_state(SPLIT)!=0&&current_negative->get_state(SPLIT)==0)
1282                                                {
1283                                                        for(list<polyhedron*>::iterator parent_ref = current_positive->parents.begin();parent_ref!=current_positive->parents.end();parent_ref++)
1284                                                        {
1285                                                                if(current_positive->get_state(SPLIT)==1)
1286                                                                {
1287                                                                        (*parent_ref)->positivechildren.remove(current_positive);
1288                                                                }
1289                                                                else
1290                                                                {
1291                                                                        (*parent_ref)->negativechildren.remove(current_positive);
1292                                                                }
1293
1294                                                                (*parent_ref)->neutralchildren.push_back(current_positive);
1295                                                        }
1296
1297                                                        current_positive->set_state(0,SPLIT);
1298                                                        for_splitting[k].push_back(current_positive);
1299                                                }
1300                                               
1301                                                if((current_positive->get_state(SPLIT)==0&&!current_positive->totally_neutral)||(current_negative->get_state(SPLIT)==0&&!current_negative->totally_neutral))
1302                                                {
1303                                                        current_positive->negativechildren.insert(current_positive->negativechildren.end(),current_negative->negativechildren.begin(),current_negative->negativechildren.end());                                               
1304                                                       
1305                                                        current_positive->positivechildren.insert(current_positive->positivechildren.end(),current_negative->positivechildren.begin(),current_negative->positivechildren.end());
1306                                                                                                       
1307                                                        current_positive->neutralchildren.insert(current_positive->neutralchildren.end(),current_negative->neutralchildren.begin(),current_negative->neutralchildren.end());
1308                                               
1309                                                        switch((*merge_ref)->get_state(SPLIT))
1310                                                        {
1311                                                        case -1:
1312                                                                current_positive->negativechildren.remove(*merge_ref);
1313                                                                break;
1314                                                        case 0:
1315                                                                current_positive->neutralchildren.remove(*merge_ref);
1316                                                                break;
1317                                                        case 1:
1318                                                                current_positive->positivechildren.remove(*merge_ref);
1319                                                                break;
1320                                                        }
1321
1322                                                        current_positive->totallyneutralchildren.insert(current_negative->totallyneutralchildren.begin(),current_negative->totallyneutralchildren.end());
1323                                                       
1324                                                        current_positive->totallyneutralchildren.erase(*merge_ref);
1325
1326                                                        current_positive->totallyneutralgrandchildren.insert(current_negative->totallyneutralgrandchildren.begin(),current_negative->totallyneutralgrandchildren.end());
1327
1328                                                        current_positive->negativeneutralvertices.insert(current_negative->negativeneutralvertices.begin(),current_negative->negativeneutralvertices.end());
1329                                                        current_positive->positiveneutralvertices.insert(current_negative->positiveneutralvertices.begin(),current_negative->positiveneutralvertices.end());
1330                                                }
1331                                                else
1332                                                {
1333                                                        if(!current_positive->totally_neutral)
1334                                                        {
1335                                                                current_positive->positivechildren.clear();
1336                                                                current_positive->negativechildren.clear();
1337                                                                current_positive->neutralchildren.clear();
1338                                                                current_positive->totallyneutralchildren.clear();
1339                                                                current_positive->totallyneutralgrandchildren.clear();                                                         
1340                                                                current_positive->positiveneutralvertices.clear();
1341                                                                current_positive->negativeneutralvertices.clear();
1342                                                                current_positive->totally_neutral = NULL;
1343                                                                current_positive->kids_rel_addresses.clear();                                                           
1344                                                        }
1345                                               
1346                                                }
1347
1348                                                                                               
1349                                               
1350                                                current_positive->vertices.insert(current_negative->vertices.begin(),current_negative->vertices.end());
1351                                               
1352                                               
1353                                                for(set<vertex*>::iterator vert_ref = (*merge_ref)->vertices.begin();vert_ref!=(*merge_ref)->vertices.end();vert_ref++)
1354                                                {
1355                                                        if((*vert_ref)->get_multiplicity()==1)
1356                                                        {
1357                                                                current_positive->vertices.erase(*vert_ref);
1358                                                               
1359                                                                if((current_positive->get_state(SPLIT)==0&&!current_positive->totally_neutral)||(current_negative->get_state(SPLIT)==0&&!current_negative->totally_neutral))
1360                                                                {
1361                                                                        current_positive->negativeneutralvertices.erase(*vert_ref);
1362                                                                        current_positive->positiveneutralvertices.erase(*vert_ref);
1363                                                                }
1364                                                        }
1365                                                }
1366                                               
1367                                                if(current_negative->get_state(SPLIT)==0&&!current_negative->totally_neutral)
1368                                                {
1369                                                        for_splitting[k].remove(current_negative);     
1370                                                }
1371
1372                                                if(current_positive->totally_neutral)
1373                                                {
1374                                                        if(!current_negative->totally_neutral)
1375                                                        {
1376                                                                for(set<polyhedron*>::iterator grand_ref = current_positive->grandparents.begin();grand_ref!=current_positive->grandparents.end();grand_ref++)
1377                                                                {
1378                                                                        (*grand_ref)->totallyneutralgrandchildren.erase(current_positive);
1379                                                                }                                                               
1380                                                        }
1381                                                        else
1382                                                        {
1383                                                                for(set<polyhedron*>::iterator grand_ref = current_negative->grandparents.begin();grand_ref!=current_negative->grandparents.end();grand_ref++)
1384                                                                {
1385                                                                        (*grand_ref)->totallyneutralgrandchildren.erase(current_negative);
1386                                                                        (*grand_ref)->totallyneutralgrandchildren.insert(current_positive);
1387                                                                }                                                               
1388                                                        }
1389                                                }
1390                                                else
1391                                                {
1392                                                        if(current_negative->totally_neutral)
1393                                                        {
1394                                                                for(set<polyhedron*>::iterator grand_ref = current_negative->grandparents.begin();grand_ref!=current_negative->grandparents.end();grand_ref++)
1395                                                                {
1396                                                                        (*grand_ref)->totallyneutralgrandchildren.erase(current_negative);                                                                     
1397                                                                }
1398                                                        }                                                       
1399                                                }
1400
1401                                                current_positive->grandparents.clear();
1402
1403                                               
1404                                               
1405                                                current_positive->totally_neutral = (current_positive->totally_neutral && current_negative->totally_neutral);
1406
1407                                                current_positive->triangulate(k==for_splitting.size()-1);
1408                                               
1409                                                statistic.delete_polyhedron(k,current_negative);
1410
1411                                                delete current_negative;
1412
1413                                                for(list<polyhedron*>::iterator child_ref = (*merge_ref)->children.begin();child_ref!=(*merge_ref)->children.end();child_ref++)
1414                                                {
1415                                                        (*child_ref)->parents.remove(*merge_ref);
1416                                                }
1417
1418                                                /*
1419                                                for(list<polyhedron*>::iterator parent_ref = (*merge_ref)->parents.begin();parent_ref!=(*merge_ref)->parents.end();parent_ref++)
1420                                                {
1421                                                        (*parent_ref)->positivechildren.remove(*merge_ref);
1422                                                        (*parent_ref)->negativechildren.remove(*merge_ref);
1423                                                        (*parent_ref)->neutralchildren.remove(*merge_ref);
1424                                                        (*parent_ref)->children.remove(*merge_ref);
1425                                                }
1426                                                */
1427
1428                                                for(set<polyhedron*>::iterator grand_ch_ref = (*merge_ref)->totallyneutralgrandchildren.begin();grand_ch_ref!=(*merge_ref)->totallyneutralgrandchildren.end();grand_ch_ref++)
1429                                                {
1430                                                        (*grand_ch_ref)->grandparents.erase(*merge_ref);
1431                                                }
1432
1433                                               
1434                                                for(set<polyhedron*>::iterator grand_p_ref = (*merge_ref)->grandparents.begin();grand_p_ref!=(*merge_ref)->grandparents.end();grand_p_ref++)
1435                                                {
1436                                                        (*grand_p_ref)->totallyneutralgrandchildren.erase(*merge_ref);
1437                                                }
1438                                               
1439                                                for_splitting[k-1].remove(*merge_ref);
1440
1441                                                statistic.delete_polyhedron(k-1,*merge_ref);
1442
1443                                                if(k==1)
1444                                                {
1445                                                        vertices_to_be_reduced.insert((vertex*)(*merge_ref));
1446                                                }
1447                                                else
1448                                                {
1449                                                        delete *merge_ref;
1450                                                }
1451                                        }
1452                                }                       
1453                       
1454                                k++;
1455
1456                        }
1457
1458                        for(set<vertex*>::iterator vert_ref = vertices_to_be_reduced.begin();vert_ref!=vertices_to_be_reduced.end();vert_ref++)
1459                        {
1460                                if((*vert_ref)->get_multiplicity()>1)
1461                                {
1462                                        (*vert_ref)->lower_multiplicity();
1463                                }
1464                                else
1465                                {
1466                                        delete *vert_ref;
1467                                }
1468                        }
1469
1470                        delete condition_to_remove;
1471                }
1472               
1473                vector<int> sizevector;
1474                for(int s = 0;s<statistic.size();s++)
1475                {
1476                        sizevector.push_back(statistic.row_size(s));
1477                        cout << statistic.row_size(s) << ", ";
1478                }
1479
1480                cout << endl;
1481
1482                if(should_add)
1483                {
1484                        int k = 1;
1485
1486                        vector<list<polyhedron*>>::iterator beginning_ref = ++for_splitting.begin();
1487
1488                        for(vector<list<polyhedron*>>::iterator vert_ref = beginning_ref;vert_ref<for_splitting.end();vert_ref++)
1489                        {                       
1490
1491                                for(list<polyhedron*>::reverse_iterator split_ref = vert_ref->rbegin();split_ref != vert_ref->rend();split_ref++)
1492                                {
1493                                        polyhedron* new_totally_neutral_child;
1494
1495                                        polyhedron* current_polyhedron = (*split_ref);
1496                                       
1497                                        if(vert_ref == beginning_ref)
1498                                        {
1499                                                vec coordinates1 = ((vertex*)(*(current_polyhedron->children.begin())))->get_coordinates();                                             
1500                                                vec coordinates2 = ((vertex*)(*(++current_polyhedron->children.begin())))->get_coordinates();
1501                                               
1502                                                vec extended_coord2 = coordinates2;
1503                                                extended_coord2.ins(0,-1.0);                                           
1504
1505                                                double t = (-toadd*extended_coord2)/(toadd(1,toadd.size()-1)*(coordinates1-coordinates2));                                             
1506
1507                                                vec new_coordinates = (1-t)*coordinates2+t*coordinates1;                                               
1508
1509                                                // cout << "c1:" << coordinates1 << endl << "c2:" << coordinates2 << endl << "nc:" << new_coordinates << endl;
1510
1511                                                vertex* neutral_vertex = new vertex(new_coordinates);                                           
1512
1513                                                new_totally_neutral_child = neutral_vertex;
1514                                        }
1515                                        else
1516                                        {
1517                                                toprow* neutral_toprow = new toprow();
1518                                               
1519                                                neutral_toprow->condition_sum   = ((toprow*)current_polyhedron)->condition_sum; // tohle tu bylo driv: zeros(number_of_parameters+1);
1520                                                neutral_toprow->condition_order = ((toprow*)current_polyhedron)->condition_order+1;
1521
1522                                                new_totally_neutral_child = neutral_toprow;
1523                                        }
1524
1525                                        new_totally_neutral_child->parentconditions.insert(current_polyhedron->parentconditions.begin(),current_polyhedron->parentconditions.end());
1526                                        new_totally_neutral_child->parentconditions.insert(condition_to_add);
1527
1528                                        new_totally_neutral_child->my_emlig = this;
1529                                       
1530                                        new_totally_neutral_child->children.insert(new_totally_neutral_child->children.end(),
1531                                                                                                                current_polyhedron->totallyneutralgrandchildren.begin(),
1532                                                                                                                                current_polyhedron->totallyneutralgrandchildren.end());
1533
1534                                       
1535
1536                                        // cout << ((toprow*)current_polyhedron)->condition << endl << toadd << endl;
1537
1538                                        toprow* positive_poly = new toprow(((toprow*)current_polyhedron)->condition_sum+toadd, ((toprow*)current_polyhedron)->condition_order+1);
1539                                        toprow* negative_poly = new toprow(((toprow*)current_polyhedron)->condition_sum-toadd, ((toprow*)current_polyhedron)->condition_order+1);
1540
1541                                        positive_poly->my_emlig = this;
1542                                        negative_poly->my_emlig = this;
1543
1544                                        positive_poly->parentconditions.insert(current_polyhedron->parentconditions.begin(),current_polyhedron->parentconditions.end());
1545                                        negative_poly->parentconditions.insert(current_polyhedron->parentconditions.begin(),current_polyhedron->parentconditions.end());
1546
1547                                        for(set<polyhedron*>::iterator grand_ref = current_polyhedron->totallyneutralgrandchildren.begin(); grand_ref != current_polyhedron->totallyneutralgrandchildren.end();grand_ref++)
1548                                        {
1549                                                (*grand_ref)->parents.push_back(new_totally_neutral_child);
1550                                               
1551                                                // tohle tu nebylo. ma to tu byt?
1552                                                //positive_poly->totallyneutralgrandchildren.insert(*grand_ref);
1553                                                //negative_poly->totallyneutralgrandchildren.insert(*grand_ref);
1554
1555                                                //(*grand_ref)->grandparents.insert(positive_poly);
1556                                                //(*grand_ref)->grandparents.insert(negative_poly);
1557
1558                                                new_totally_neutral_child->vertices.insert((*grand_ref)->vertices.begin(),(*grand_ref)->vertices.end());
1559                                        }
1560
1561                                        positive_poly->children.push_back(new_totally_neutral_child);
1562                                        negative_poly->children.push_back(new_totally_neutral_child);
1563                                       
1564
1565                                        for(list<polyhedron*>::iterator parent_ref = current_polyhedron->parents.begin();parent_ref!=current_polyhedron->parents.end();parent_ref++)
1566                                        {
1567                                                (*parent_ref)->totallyneutralgrandchildren.insert(new_totally_neutral_child);
1568                                                // new_totally_neutral_child->grandparents.insert(*parent_ref);
1569
1570                                                (*parent_ref)->neutralchildren.remove(current_polyhedron);
1571                                                (*parent_ref)->children.remove(current_polyhedron);
1572
1573                                                (*parent_ref)->children.push_back(positive_poly);
1574                                                (*parent_ref)->children.push_back(negative_poly);
1575                                                (*parent_ref)->positivechildren.push_back(positive_poly);
1576                                                (*parent_ref)->negativechildren.push_back(negative_poly);
1577                                        }
1578
1579                                        positive_poly->parents.insert(positive_poly->parents.end(),
1580                                                                                                current_polyhedron->parents.begin(),
1581                                                                                                                current_polyhedron->parents.end());
1582
1583                                        negative_poly->parents.insert(negative_poly->parents.end(),
1584                                                                                                current_polyhedron->parents.begin(),
1585                                                                                                                current_polyhedron->parents.end());
1586
1587                                       
1588
1589                                        new_totally_neutral_child->parents.push_back(positive_poly);
1590                                        new_totally_neutral_child->parents.push_back(negative_poly);
1591
1592                                        for(list<polyhedron*>::iterator child_ref = current_polyhedron->positivechildren.begin();child_ref!=current_polyhedron->positivechildren.end();child_ref++)
1593                                        {
1594                                                (*child_ref)->parents.remove(current_polyhedron);
1595                                                (*child_ref)->parents.push_back(positive_poly);                                         
1596                                        }                                       
1597
1598                                        positive_poly->children.insert(positive_poly->children.end(),
1599                                                                                                current_polyhedron->positivechildren.begin(),
1600                                                                                                                        current_polyhedron->positivechildren.end());
1601
1602                                        for(list<polyhedron*>::iterator child_ref = current_polyhedron->negativechildren.begin();child_ref!=current_polyhedron->negativechildren.end();child_ref++)
1603                                        {
1604                                                (*child_ref)->parents.remove(current_polyhedron);
1605                                                (*child_ref)->parents.push_back(negative_poly);
1606                                        }
1607
1608                                        negative_poly->children.insert(negative_poly->children.end(),
1609                                                                                                current_polyhedron->negativechildren.begin(),
1610                                                                                                                        current_polyhedron->negativechildren.end());
1611
1612                                        positive_poly->vertices.insert(current_polyhedron->positiveneutralvertices.begin(),current_polyhedron->positiveneutralvertices.end());
1613                                        positive_poly->vertices.insert(new_totally_neutral_child->vertices.begin(),new_totally_neutral_child->vertices.end());
1614
1615                                        negative_poly->vertices.insert(current_polyhedron->negativeneutralvertices.begin(),current_polyhedron->negativeneutralvertices.end());
1616                                        negative_poly->vertices.insert(new_totally_neutral_child->vertices.begin(),new_totally_neutral_child->vertices.end());
1617                                                               
1618                                        new_totally_neutral_child->triangulate(false);
1619
1620                                        positive_poly->triangulate(k==for_splitting.size()-1);
1621                                        negative_poly->triangulate(k==for_splitting.size()-1);
1622                                       
1623                                        statistic.append_polyhedron(k-1, new_totally_neutral_child);                                   
1624                                       
1625                                        statistic.insert_polyhedron(k, positive_poly, current_polyhedron);
1626                                        statistic.insert_polyhedron(k, negative_poly, current_polyhedron);                                     
1627
1628                                        statistic.delete_polyhedron(k, current_polyhedron);
1629
1630                                        delete current_polyhedron;
1631                                }
1632
1633                                k++;
1634                        }
1635                }
1636
1637               
1638                sizevector.clear();
1639                for(int s = 0;s<statistic.size();s++)
1640                {
1641                        sizevector.push_back(statistic.row_size(s));
1642                        cout << statistic.row_size(s) << ", ";
1643                }
1644               
1645                cout << endl;
1646
1647                /*
1648                for(polyhedron* topr_ref = statistic.rows[statistic.size()-1];topr_ref!=statistic.row_ends[statistic.size()-1]->next_poly;topr_ref=topr_ref->next_poly)
1649                {
1650                        cout << ((toprow*)topr_ref)->condition << endl;
1651                }
1652                */
1653
1654                // step_me(0);
1655
1656        }
1657
1658        void set_correction_factors(int order)
1659                {
1660                        for(int remaining_order = correction_factors.size();remaining_order<order;remaining_order++)
1661                        {
1662                                multiset<my_ivec> factor_templates;
1663                                multiset<my_ivec> final_factors;                               
1664
1665                                my_ivec orig_template = my_ivec();                             
1666
1667                                for(int i = 1;i<number_of_parameters-remaining_order+1;i++)
1668                                {                                       
1669                                        bool in_cycle = false;
1670                                        for(int j = 0;j<=remaining_order;j++)                                   {
1671                                               
1672                                                multiset<my_ivec>::iterator fac_ref = factor_templates.begin();
1673
1674                                                do
1675                                                {
1676                                                        my_ivec current_template;
1677                                                        if(!in_cycle)
1678                                                        {
1679                                                                current_template = orig_template;
1680                                                                in_cycle = true;
1681                                                        }
1682                                                        else
1683                                                        {
1684                                                                current_template = (*fac_ref);
1685                                                                fac_ref++;
1686                                                        }                                                       
1687                                                       
1688                                                        current_template.ins(current_template.size(),i);
1689
1690                                                        // cout << "template:" << current_template << endl;
1691                                                       
1692                                                        if(current_template.size()==remaining_order+1)
1693                                                        {
1694                                                                final_factors.insert(current_template);
1695                                                        }
1696                                                        else
1697                                                        {
1698                                                                factor_templates.insert(current_template);
1699                                                        }
1700                                                }
1701                                                while(fac_ref!=factor_templates.end());
1702                                        }
1703                                }       
1704
1705                                correction_factors.push_back(final_factors);                   
1706
1707                        }
1708                }
1709
1710
1711
1712        mat sample_mat(int n)
1713        {
1714                mat sample_mat;
1715                map<double,toprow*> ordered_toprows;
1716
1717                /// \TODO tady je to spatne, tady nesmi byt conditions.size(), viz RARX.bayes()
1718                if(conditions.size()-2-number_of_parameters>=0)
1719                {
1720                        double sum = 0;
1721
1722                        for(polyhedron* top_ref = statistic.rows[number_of_parameters-1];top_ref!=statistic.end_poly;top_ref=top_ref->next_poly)
1723                        {
1724                                toprow* current_top = (toprow*)top_ref;
1725
1726                                sum+=current_top->probability;
1727                                ordered_toprows.insert(pair<double,toprow*>(sum,current_top));
1728                        }
1729                }
1730                else
1731                {
1732                        throw new exception("You are trying to sample from density that is not determined (parameters can't be integrated out)!");
1733                }
1734
1735                while(sample_mat.cols()<n)
1736                {
1737                        double rnumber = randu();
1738
1739                        toprow* sampled_toprow = ordered_toprows.upper_bound(rnumber)->second;
1740
1741                        rnumber = randu();
1742
1743                        map<double,set<vertex*>>::iterator tri_ref = sampled_toprow->triangulation.begin()
1744                        double sum = 0;
1745
1746                        for(tri_ref = sampled_toprow->triangulation.begin();tri_ref!=sampled_toprow->triangulation.end();tri_ref++)
1747                        {
1748                                sum += (*tri_ref).first;
1749
1750                                if(sum/sampled_toprow->probability >= rnumber)
1751                                        break;
1752                        }
1753
1754
1755                }
1756
1757                return sample_mat;
1758        }
1759
1760protected:
1761
1762        /// A method for creating plain default statistic representing only the range of the parameter space.
1763    void create_statistic(int number_of_parameters)
1764        {
1765                /*
1766                for(int i = 0;i<number_of_parameters;i++)
1767                {
1768                        vec condition_vec = zeros(number_of_parameters+1);
1769                        condition_vec[i+1]  = 1;
1770
1771                        condition* new_condition = new condition(condition_vec);
1772                       
1773                        conditions.push_back(new_condition);
1774                }
1775                */
1776
1777                // An empty vector of coordinates.
1778                vec origin_coord;       
1779
1780                // We create an origin - this point will have all the coordinates zero, but now it has an empty vector of coords.
1781                vertex *origin = new vertex(origin_coord);
1782
1783                origin->my_emlig = this;
1784               
1785                /*
1786                // As a statistic, we have to create a vector of vectors of polyhedron pointers. It will then represent the Hasse
1787                // diagram. First we create a vector of polyhedrons..
1788                list<polyhedron*> origin_vec;
1789
1790                // ..we fill it with the origin..
1791                origin_vec.push_back(origin);
1792
1793                // ..and we fill the statistic with the created vector.
1794                statistic.push_back(origin_vec);
1795                */
1796
1797                statistic = *(new c_statistic());               
1798               
1799                statistic.append_polyhedron(0, origin);
1800
1801                // Now we have a statistic for a zero dimensional space. Regarding to how many dimensional space we need to
1802                // describe, we have to widen the descriptional default statistic. We use an iterative procedure as follows:
1803                for(int i=0;i<number_of_parameters;i++)
1804                {
1805                        // We first will create two new vertices. These will be the borders of the parameter space in the dimension
1806                        // of newly added parameter. Therefore they will have all coordinates except the last one zero. We get the
1807                        // right amount of zero cooridnates by reading them from the origin
1808                        vec origin_coord = origin->get_coordinates();                                           
1809
1810                        // And we incorporate the nonzero coordinates into the new cooordinate vectors
1811                        vec origin_coord1 = concat(origin_coord,-max_range); 
1812                        vec origin_coord2 = concat(origin_coord,max_range);                             
1813                                       
1814
1815                        // Now we create the points
1816                        vertex* new_point1 = new vertex(origin_coord1);
1817                        vertex* new_point2 = new vertex(origin_coord2);
1818
1819                        new_point1->my_emlig = this;
1820                        new_point2->my_emlig = this;
1821                       
1822                        //*********************************************************************************************************
1823                        // The algorithm for recursive build of a new Hasse diagram representing the space structure from the old
1824                        // diagram works so that you create two copies of the old Hasse diagram, you shift them up one level (points
1825                        // will be segments, segments will be areas etc.) and you connect each one of the original copied polyhedrons
1826                        // with its offspring by a parent-child relation. Also each of the segments in the first (second) copy is
1827                        // connected to the first (second) newly created vertex by a parent-child relation.
1828                        //*********************************************************************************************************
1829
1830
1831                        /*
1832                        // Create the vectors of vectors of pointers to polyhedrons to hold the copies of the old Hasse diagram
1833                        vector<vector<polyhedron*>> new_statistic1;
1834                        vector<vector<polyhedron*>> new_statistic2;
1835                        */
1836
1837                        c_statistic* new_statistic1 = new c_statistic();
1838                        c_statistic* new_statistic2 = new c_statistic();
1839
1840                       
1841                        // Copy the statistic by rows                   
1842                        for(int j=0;j<statistic.size();j++)
1843                        {
1844                               
1845
1846                                // an element counter
1847                                int element_number = 0;
1848
1849                                /*
1850                                vector<polyhedron*> supportnew_1;
1851                                vector<polyhedron*> supportnew_2;
1852
1853                                new_statistic1.push_back(supportnew_1);
1854                                new_statistic2.push_back(supportnew_2);
1855                                */
1856
1857                                // for each polyhedron in the given row
1858                                for(polyhedron* horiz_ref = statistic.rows[j];horiz_ref!=statistic.get_end();horiz_ref=horiz_ref->next_poly)
1859                                {       
1860                                        // Append an extra zero coordinate to each of the vertices for the new dimension
1861                                        // If vert_ref is at the first index => we loop through vertices
1862                                        if(j == 0)
1863                                        {
1864                                                // cast the polyhedron pointer to a vertex pointer and push a zero to its vector of coordinates
1865                                                ((vertex*) horiz_ref)->push_coordinate(0);
1866                                        }
1867                                        /*
1868                                        else
1869                                        {
1870                                                ((toprow*) (*horiz_ref))->condition.ins(0,0);
1871                                        }*/
1872
1873                                        // if it has parents
1874                                        if(!horiz_ref->parents.empty())
1875                                        {
1876                                                // save the relative address of this child in a vector kids_rel_addresses of all its parents.
1877                                                // This information will later be used for copying the whole Hasse diagram with each of the
1878                                                // relations contained within.
1879                                                for(list<polyhedron*>::iterator parent_ref = horiz_ref->parents.begin();parent_ref != horiz_ref->parents.end();parent_ref++)
1880                                                {
1881                                                        (*parent_ref)->kids_rel_addresses.push_back(element_number);                                                   
1882                                                }                                               
1883                                        }
1884
1885                                        // **************************************************************************************************
1886                                        // Here we begin creating a new polyhedron, which will be a copy of the old one. Each such polyhedron
1887                                        // will be created as a toprow, but this information will be later forgotten and only the polyhedrons
1888                                        // in the top row of the Hasse diagram will be considered toprow for later use.
1889                                        // **************************************************************************************************
1890
1891                                        // First we create vectors specifying a toprow condition. In the case of a preconstructed statistic
1892                                        // this condition will be a vector of zeros. There are two vectors, because we need two copies of
1893                                        // the original Hasse diagram.
1894                                        vec vec1(number_of_parameters+1);
1895                                        vec1.zeros();
1896
1897                                        vec vec2(number_of_parameters+1);
1898                                        vec2.zeros();
1899
1900                                        // We create a new toprow with the previously specified condition.
1901                                        toprow* current_copy1 = new toprow(vec1, 0);
1902                                        toprow* current_copy2 = new toprow(vec2, 0);
1903
1904                                        current_copy1->my_emlig = this;
1905                                        current_copy2->my_emlig = this;
1906
1907                                        // The vertices of the copies will be inherited, because there will be a parent/child relation
1908                                        // between each polyhedron and its offspring (comming from the copy) and a parent has all the
1909                                        // vertices of its child plus more.
1910                                        for(set<vertex*>::iterator vertex_ref = horiz_ref->vertices.begin();vertex_ref!=horiz_ref->vertices.end();vertex_ref++)
1911                                        {
1912                                                current_copy1->vertices.insert(*vertex_ref);
1913                                                current_copy2->vertices.insert(*vertex_ref);                                           
1914                                        }
1915                                       
1916                                        // The only new vertex of the offspring should be the newly created point.
1917                                        current_copy1->vertices.insert(new_point1);
1918                                        current_copy2->vertices.insert(new_point2);                                     
1919                                       
1920                                        // This method guarantees that each polyhedron is already triangulated, therefore its triangulation
1921                                        // is only one set of vertices and it is the set of all its vertices.
1922                                        set<vertex*> t_simplex1;
1923                                        set<vertex*> t_simplex2;
1924
1925                                        t_simplex1.insert(current_copy1->vertices.begin(),current_copy1->vertices.end());
1926                                        t_simplex2.insert(current_copy2->vertices.begin(),current_copy2->vertices.end());
1927                                       
1928                                        current_copy1->triangulation.insert(pair<double,set<vertex*>>(0,t_simplex1));
1929                                        current_copy2->triangulation.insert(pair<double,set<vertex*>>(0,t_simplex2));                                   
1930                                       
1931                                        // Now we have copied the polyhedron and we have to copy all of its relations. Because we are copying
1932                                        // in the Hasse diagram from bottom up, we always have to copy the parent/child relations to all the
1933                                        // kids and when we do that and know the child, in the child we will remember the parent we came from.
1934                                        // This way all the parents/children relations are saved in both the parent and the child.
1935                                        if(!horiz_ref->kids_rel_addresses.empty())
1936                                        {
1937                                                for(list<int>::iterator kid_ref = horiz_ref->kids_rel_addresses.begin();kid_ref!=horiz_ref->kids_rel_addresses.end();kid_ref++)
1938                                                {       
1939                                                        polyhedron* new_kid1 = new_statistic1->rows[j-1];
1940                                                        polyhedron* new_kid2 = new_statistic2->rows[j-1];
1941
1942                                                        // THIS IS NOT EFFECTIVE: It could be improved by having the list indexed for new_statistic, but
1943                                                        // not indexed for statistic. Hopefully this will not cause a big slowdown - happens only offline.
1944                                                        if(*kid_ref)
1945                                                        {
1946                                                                for(int k = 1;k<=(*kid_ref);k++)
1947                                                                {
1948                                                                        new_kid1=new_kid1->next_poly;
1949                                                                        new_kid2=new_kid2->next_poly;
1950                                                                }
1951                                                        }
1952                                                       
1953                                                        // find the child and save the relation to the parent
1954                                                        current_copy1->children.push_back(new_kid1);
1955                                                        current_copy2->children.push_back(new_kid2);
1956
1957                                                        // in the child save the parents' address
1958                                                        new_kid1->parents.push_back(current_copy1);
1959                                                        new_kid2->parents.push_back(current_copy2);
1960                                                }                                               
1961
1962                                                // Here we clear the parents kids_rel_addresses vector for later use (when we need to widen the
1963                                                // Hasse diagram again)
1964                                                horiz_ref->kids_rel_addresses.clear();
1965                                        }
1966                                        // If there were no children previously, we are copying a polyhedron that has been a vertex before.
1967                                        // In this case it is a segment now and it will have a relation to its mother (copywise) and to the
1968                                        // newly created point. Here we create the connection to the new point, again from both sides.
1969                                        else
1970                                        {
1971                                                // Add the address of the new point in the former vertex
1972                                                current_copy1->children.push_back(new_point1);
1973                                                current_copy2->children.push_back(new_point2);
1974
1975                                                // Add the address of the former vertex in the new point
1976                                                new_point1->parents.push_back(current_copy1);
1977                                                new_point2->parents.push_back(current_copy2);
1978                                        }
1979
1980                                        // Save the mother in its offspring
1981                                        current_copy1->children.push_back(horiz_ref);
1982                                        current_copy2->children.push_back(horiz_ref);
1983
1984                                        // Save the offspring in its mother
1985                                        horiz_ref->parents.push_back(current_copy1);
1986                                        horiz_ref->parents.push_back(current_copy2);   
1987                                                               
1988                                       
1989                                        // Add the copies into the relevant statistic. The statistic will later be appended to the previous
1990                                        // Hasse diagram
1991                                        new_statistic1->append_polyhedron(j,current_copy1);
1992                                        new_statistic2->append_polyhedron(j,current_copy2);
1993                                       
1994                                        // Raise the count in the vector of polyhedrons
1995                                        element_number++;                       
1996                                       
1997                                }
1998                               
1999                        }
2000
2001                        /*
2002                        statistic.begin()->push_back(new_point1);
2003                        statistic.begin()->push_back(new_point2);
2004                        */
2005
2006                        statistic.append_polyhedron(0, new_point1);
2007                        statistic.append_polyhedron(0, new_point2);
2008
2009                        // Merge the new statistics into the old one. This will either be the final statistic or we will
2010                        // reenter the widening loop.
2011                        for(int j=0;j<new_statistic1->size();j++)
2012                        {
2013                                /*
2014                                if(j+1==statistic.size())
2015                                {
2016                                        list<polyhedron*> support;
2017                                        statistic.push_back(support);
2018                                }
2019                               
2020                                (statistic.begin()+j+1)->insert((statistic.begin()+j+1)->end(),new_statistic1[j].begin(),new_statistic1[j].end());
2021                                (statistic.begin()+j+1)->insert((statistic.begin()+j+1)->end(),new_statistic2[j].begin(),new_statistic2[j].end());
2022                                */
2023                                statistic.append_polyhedron(j+1,new_statistic1->rows[j],new_statistic1->row_ends[j]);
2024                                statistic.append_polyhedron(j+1,new_statistic2->rows[j],new_statistic2->row_ends[j]);
2025                        }                       
2026                }
2027
2028                /*
2029                vector<list<toprow*>> toprow_statistic;
2030                int line_count = 0;
2031
2032                for(vector<list<polyhedron*>>::iterator polyhedron_ref = ++statistic.begin(); polyhedron_ref!=statistic.end();polyhedron_ref++)
2033                {
2034                        list<toprow*> support_list;
2035                        toprow_statistic.push_back(support_list);                                               
2036
2037                        for(list<polyhedron*>::iterator polyhedron_ref2 = polyhedron_ref->begin(); polyhedron_ref2 != polyhedron_ref->end(); polyhedron_ref2++)
2038                        {
2039                                toprow* support_top = (toprow*)(*polyhedron_ref2);
2040
2041                                toprow_statistic[line_count].push_back(support_top);
2042                        }
2043
2044                        line_count++;
2045                }*/
2046
2047                /*
2048                vector<int> sizevector;
2049                for(int s = 0;s<statistic.size();s++)
2050                {
2051                        sizevector.push_back(statistic.row_size(s));
2052                }
2053                */
2054               
2055        }
2056
2057
2058       
2059       
2060};
2061
2062
2063
2064//! Robust Bayesian AR model for Multicriteria-Laplace-Inverse-Gamma density
2065class RARX //: public BM
2066{
2067private:
2068
2069       
2070
2071        int window_size;       
2072
2073        list<vec> conditions;
2074
2075public:
2076        emlig* posterior;
2077
2078        RARX(int number_of_parameters, const int window_size)//:BM()
2079        {
2080                posterior = new emlig(number_of_parameters);
2081
2082                this->window_size = window_size;               
2083        };
2084
2085        void bayes(const itpp::vec &yt, const itpp::vec &cond = "")
2086        {
2087                conditions.push_back(yt);               
2088
2089                //posterior->step_me(0);
2090               
2091                /// \TODO tohle je spatne, tady musi byt jiny vypocet poctu podminek, kdyby nejaka byla multiplicitni, tak tohle bude spatne
2092                if(conditions.size()>window_size && window_size!=0)
2093                {                       
2094                        posterior->add_and_remove_condition(yt,conditions.front());
2095                        conditions.pop_front();
2096
2097                        //posterior->step_me(1);
2098                }
2099                else
2100                {
2101                        posterior->add_condition(yt);
2102                }
2103                               
2104        }
2105
2106};
2107
2108
2109
2110#endif //TRAGE_H
Note: See TracBrowser for help on using the browser.