root/applications/robust/robustlib.h @ 1324

Revision 1324, 67.3 kB (checked in by sindj, 13 years ago)

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