root/applications/robust/robustlib.h @ 1272

Revision 1272, 39.9 kB (checked in by sindj, 13 years ago)

Dodelano pocitani, odstranena chyba se zapornymi pravdepodobnostmi. 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 <limits>
12#include <vector>
13#include <list>
14#include <set>
15#include <algorithm>
16       
17using namespace bdm;
18using namespace std;
19using namespace itpp;
20
21const double max_range = 1000.0;//numeric_limits<double>::max()/10e-10;
22
23enum actions {MERGE, SPLIT};
24
25class polyhedron;
26class vertex;
27
28/*
29class t_simplex
30{
31public:
32        set<vertex*> minima;
33
34        set<vertex*> simplex;
35
36        t_simplex(vertex* origin_vertex)
37        {
38                simplex.insert(origin_vertex);
39                minima.insert(origin_vertex);
40        }
41};*/
42
43class emlig;
44
45
46/// A class describing a single polyhedron of the split complex. From a collection of such classes a Hasse diagram
47/// of the structure in the exponent of a Laplace-Inverse-Gamma density will be created.
48class polyhedron
49{
50        /// A property having a value of 1 usually, with higher value only if the polyhedron arises as a coincidence of
51        /// more than just the necessary number of conditions. For example if a newly created line passes through an already
52        /// existing point, the points multiplicity will rise by 1.
53        int multiplicity;       
54
55        int split_state;
56
57        int merge_state;
58
59       
60
61public:
62        emlig* my_emlig;
63
64        /// A list of polyhedrons parents within the Hasse diagram.
65        list<polyhedron*> parents;
66
67        /// A list of polyhedrons children withing the Hasse diagram.
68        list<polyhedron*> children;
69
70        /// All the vertices of the given polyhedron
71        set<vertex*> vertices;
72
73        /// A list used for storing children that lie in the positive region related to a certain condition
74        list<polyhedron*> positivechildren;
75
76        /// A list used for storing children that lie in the negative region related to a certain condition
77        list<polyhedron*> negativechildren;
78
79        /// Children intersecting the condition
80        list<polyhedron*> neutralchildren;
81
82        list<polyhedron*> totallyneutralgrandchildren;
83
84        list<polyhedron*> totallyneutralchildren;
85
86        set<vertex*> positiveneutralvertices;
87
88        set<vertex*> negativeneutralvertices;
89
90        bool totally_neutral;
91
92        list<polyhedron*> mergechildren;
93
94        polyhedron* positiveparent;
95
96        polyhedron* negativeparent;
97
98        polyhedron* next_poly;
99
100        polyhedron* prev_poly;
101
102        int message_counter;
103
104        /// List of triangulation polyhedrons of the polyhedron given by their relative vertices.
105        list<set<vertex*>> triangulation;
106
107        /// A list of relative addresses serving for Hasse diagram construction.
108        list<int> kids_rel_addresses;
109
110        /// Default constructor
111        polyhedron()
112        {
113                multiplicity = 1;
114
115                message_counter = 0;
116
117                totally_neutral = NULL;
118        }
119       
120        /// Setter for raising multiplicity
121        void raise_multiplicity()
122        {
123                multiplicity++;
124        }
125
126        /// Setter for lowering multiplicity
127        void lower_multiplicity()
128        {
129                multiplicity--;
130        }
131       
132        /// An obligatory operator, when the class is used within a C++ STL structure like a vector
133        int operator==(polyhedron polyhedron2)
134        {
135                return true;
136        }
137
138        /// An obligatory operator, when the class is used within a C++ STL structure like a vector
139        int operator<(polyhedron polyhedron2)
140        {
141                return false;
142        }
143
144       
145
146        void set_state(double state_indicator, actions action)
147        {
148                switch(action)
149                {
150                        case MERGE:
151                                merge_state = (int)sign(state_indicator);                       
152                        break;
153                        case SPLIT:
154                                split_state = (int)sign(state_indicator);
155                        break;
156                }
157        }
158
159        int get_state(actions action)
160        {
161                switch(action)
162                {
163                        case MERGE:
164                                return merge_state;                     
165                        break;
166                        case SPLIT:
167                                return split_state;
168                        break;
169                }
170        }
171
172        int number_of_children()
173        {
174                return children.size();
175        }
176
177       
178        void triangulate(bool should_integrate);
179
180       
181};
182
183/// A class for representing 0-dimensional polyhedron - a vertex. It will be located in the bottom row of the Hasse
184/// diagram representing a complex of polyhedrons. It has its coordinates in the parameter space.
185class vertex : public polyhedron
186{
187        /// A dynamic array representing coordinates of the vertex
188        vec coordinates;       
189
190       
191
192public:
193
194
195
196        /// Default constructor
197        vertex();
198
199        /// Constructor of a vertex from a set of coordinates
200        vertex(vec coordinates)
201        {
202                this->coordinates = coordinates;
203
204                vertices.insert(this);
205
206                set<vertex*> vert_simplex;
207
208                vert_simplex.insert(this);
209
210                triangulation.push_back(vert_simplex);
211        }
212
213        /// A method that widens the set of coordinates of given vertex. It is used when a complex in a parameter
214        /// space of certain dimension is established, but the dimension is not known when the vertex is created.
215        void push_coordinate(double coordinate)
216        {
217                coordinates = concat(coordinates,coordinate);
218        }
219
220        /// A method obtaining the set of coordinates of a vertex. These coordinates are not obtained as a pointer
221        /// (not given by reference), but a new copy is created (they are given by value).
222        vec get_coordinates()
223        {               
224                return coordinates;
225        }
226
227               
228};
229
230/// A class representing a polyhedron in a top row of the complex. Such polyhedron has a condition that differitiates
231/// it from polyhedrons in other rows.
232class toprow : public polyhedron
233{
234       
235public:
236        double probability;
237
238        /// A condition used for determining the function of a Laplace-Inverse-Gamma density resulting from Bayesian estimation
239        vec condition;
240
241        int condition_order;
242
243        /// Default constructor
244        toprow(){};
245
246        /// Constructor creating a toprow from the condition
247        toprow(vec condition, int condition_order)
248        {
249                this->condition = condition;
250                this->condition_order = condition_order;
251        }
252
253        double integrate_simplex(set<vertex*> simplex, char c);
254
255};
256
257class condition
258{       
259public:
260        vec value;     
261
262        int multiplicity;
263
264        condition(vec value)
265        {
266                this->value = value;
267                multiplicity = 1;
268        }
269};
270
271
272
273class c_statistic
274{
275
276public:
277        polyhedron* end_poly;
278        polyhedron* start_poly;
279
280        vector<polyhedron*> rows;
281
282        vector<polyhedron*> row_ends;
283
284        c_statistic()
285        {
286                end_poly   = new polyhedron();
287                start_poly = new polyhedron();
288        };
289
290        void append_polyhedron(int row, polyhedron* appended_start, polyhedron* appended_end)
291        {
292                if(row>((int)rows.size())-1)
293                {
294                        if(row>rows.size())
295                        {
296                                throw new exception("You are trying to append a polyhedron whose children are not in the statistic yet!");
297                                return;
298                        }
299
300                        rows.push_back(end_poly);
301                        row_ends.push_back(end_poly);
302                }
303
304                // POSSIBLE FAILURE: the function is not checking if start and end are connected
305
306                if(rows[row] != end_poly)
307                {
308                        appended_start->prev_poly = row_ends[row];
309                        row_ends[row]->next_poly = appended_start;                     
310                                               
311                }
312                else if((row>0 && rows[row-1]!=end_poly)||row==0)
313                {
314                        appended_start->prev_poly = start_poly;
315                        rows[row]= appended_start;                     
316                }
317                else
318                {
319                        throw new exception("Wrong polyhedron insertion into statistic: missing intermediary polyhedron!");
320                }
321
322                appended_end->next_poly = end_poly;
323                row_ends[row] = appended_end;
324        }
325
326        void append_polyhedron(int row, polyhedron* appended_poly)
327        {
328                append_polyhedron(row,appended_poly,appended_poly);
329        }
330
331        void insert_polyhedron(int row, polyhedron* inserted_poly, polyhedron* following_poly)
332        {               
333                if(following_poly != end_poly)
334                {
335                        inserted_poly->next_poly = following_poly;
336                        inserted_poly->prev_poly = following_poly->prev_poly;
337
338                        if(following_poly->prev_poly == start_poly)
339                        {
340                                rows[row] = inserted_poly;
341                        }
342                        else
343                        {                               
344                                inserted_poly->prev_poly->next_poly = inserted_poly;                                                           
345                        }
346
347                        following_poly->prev_poly = inserted_poly;
348                }
349                else
350                {
351                        this->append_polyhedron(row, inserted_poly);
352                }               
353       
354        }
355
356
357       
358
359        void delete_polyhedron(int row, polyhedron* deleted_poly)
360        {
361                if(deleted_poly->prev_poly != start_poly)
362                {
363                        deleted_poly->prev_poly->next_poly = deleted_poly->next_poly;
364                }
365                else
366                {
367                        rows[row] = deleted_poly->next_poly;
368                }
369
370                if(deleted_poly->next_poly!=end_poly)
371                {
372                        deleted_poly->next_poly->prev_poly = deleted_poly->prev_poly;
373                }
374                else
375                {
376                        row_ends[row] = deleted_poly->prev_poly;
377                }
378
379               
380
381                deleted_poly->next_poly = NULL;
382                deleted_poly->prev_poly = NULL;                                 
383        }
384
385        int size()
386        {
387                return rows.size();
388        }
389
390        polyhedron* get_end()
391        {
392                return end_poly;
393        }
394
395        polyhedron* get_start()
396        {
397                return start_poly;
398        }
399
400        int row_size(int row)
401        {
402                if(this->size()>row && row>=0)
403                {
404                        int row_size = 0;
405                       
406                        for(polyhedron* row_poly = rows[row]; row_poly!=end_poly; row_poly=row_poly->next_poly)
407                        {
408                                row_size++;
409                        }
410
411                        return row_size;
412                }
413                else
414                {
415                        throw new exception("There is no row to obtain size from!");
416                }
417        }
418};
419
420class my_ivec : public ivec
421{
422public:
423        my_ivec():ivec(){};
424
425        my_ivec(ivec origin):ivec()
426        {
427                this->ins(0,origin);
428        }
429
430        bool operator>(const my_ivec &second) const
431        {
432                int size1 = this->size();
433                int size2 = second.size();
434                 
435                int counter1 = 0;
436                while(0==0)
437                {
438                        if((*this)[counter1]==0)
439                        {
440                                size1--;
441                        }
442                       
443                        if((*this)[counter1]!=0)
444                                break;
445
446                        counter1++;
447                }
448
449                int counter2 = 0;
450                while(0==0)
451                {
452                        if(second[counter2]==0)
453                        {
454                                size2--;
455                        }
456                       
457                        if(second[counter2]!=0)
458                                break;
459
460                        counter2++;
461                }
462
463                if(size1!=size2)
464                {
465                        return size1>size2;
466                }
467                else
468                {
469                        for(int i = 0;i<size1;i++)
470                        {
471                                if((*this)[counter1+i]!=second[counter2+i])
472                                {
473                                        return (*this)[counter1+i]>second[counter2+i];
474                                }
475                        }
476
477                        return false;
478                }
479        }
480
481       
482        bool operator==(const my_ivec &second) const
483        {
484                int size1 = this->size();
485                int size2 = second.size();
486                 
487                int counter = 0;
488                while(0==0)
489                {
490                        if((*this)[counter]==0)
491                {
492                        size1--;
493                }
494                       
495                if((*this)[counter]!=0)
496                        break;
497
498                counter++;
499                }
500
501                counter = 0;
502                while(0==0)
503                {
504                        if(second[counter]==0)
505                        {
506                                size2--;
507                        }
508                       
509                        if(second[counter]!=0)
510                                break;
511
512                        counter++;
513                }
514
515                if(size1!=size2)
516                {
517                        return false;
518                }
519                else
520                {
521                        for(int i=0;i<size1;i++)
522                        {
523                                if((*this)[size()-1-i]!=second[second.size()-1-i])
524                                {
525                                        return false;
526                                }
527                        }
528
529                        return true;
530                }
531        }
532
533        bool operator<(const my_ivec &second) const
534        {
535                return !(((*this)>second)||((*this)==second));
536        }
537
538        bool operator!=(const my_ivec &second) const
539        {
540                return !((*this)==second);
541        }
542
543        bool operator<=(const my_ivec &second) const
544        {
545                return !((*this)>second);
546        }
547
548        bool operator>=(const my_ivec &second) const
549        {
550                return !((*this)<second);
551        }
552
553        my_ivec right(my_ivec original)
554        {
555               
556        }
557};
558
559
560
561
562
563//! Conditional(e) Multicriteria-Laplace-Inverse-Gamma distribution density
564class emlig // : eEF
565{
566
567        /// A statistic in a form of a Hasse diagram representing a complex of convex polyhedrons obtained as a result
568        /// of data update from Bayesian estimation or set by the user if this emlig is a prior density
569       
570
571        vector<list<polyhedron*>> for_splitting;
572               
573        vector<list<polyhedron*>> for_merging;
574
575        list<condition*> conditions;
576
577        double normalization_factor;
578
579        void alter_toprow_conditions(vec condition, bool should_be_added)
580        {
581                for(polyhedron* horiz_ref = statistic.rows[statistic.size()-1];horiz_ref!=statistic.get_end();horiz_ref=horiz_ref->next_poly)
582                {
583                        double product = 0;
584
585                        set<vertex*>::iterator vertex_ref = horiz_ref->vertices.begin();
586
587                        do
588                        {
589                                product = (*vertex_ref)->get_coordinates()*condition;
590                        }
591                        while(product == 0);
592
593                        if((product>0 && should_be_added)||(product<0 && !should_be_added))
594                        {
595                                ((toprow*) horiz_ref)->condition += condition;
596                        }
597                        else
598                        {
599                                ((toprow*) horiz_ref)->condition -= condition;
600                        }                               
601                }
602        }
603
604
605
606        void send_state_message(polyhedron* sender, vec toadd, vec toremove, int level)
607        {                       
608
609                bool shouldmerge = (toremove.size() != 0);
610                bool shouldsplit    = (toadd.size() != 0);
611               
612                if(shouldsplit||shouldmerge)
613                {
614                        for(list<polyhedron*>::iterator parent_iterator = sender->parents.begin();parent_iterator!=sender->parents.end();parent_iterator++)
615                        {
616                                polyhedron* current_parent = *parent_iterator;
617
618                                current_parent->message_counter++;
619
620                                bool is_last = (current_parent->message_counter == current_parent->number_of_children());
621
622                                if(shouldmerge)
623                                {
624                                        int child_state  = sender->get_state(MERGE);
625                                        int parent_state = current_parent->get_state(MERGE);
626
627                                        if(parent_state == 0)
628                                        {
629                                                current_parent->set_state(child_state, MERGE);
630
631                                                if(child_state == 0)
632                                                {
633                                                        current_parent->mergechildren.push_back(sender);
634                                                }
635                                        }
636                                        else
637                                        {
638                                                if(child_state == 0)
639                                                {
640                                                        if(parent_state > 0)
641                                                        {
642                                                                sender->positiveparent = current_parent;
643                                                        }
644                                                        else
645                                                        {
646                                                                sender->negativeparent = current_parent;
647                                                        }
648                                                }
649                                        }
650
651                                        if(is_last)
652                                        {
653                                                if(parent_state > 0)
654                                                {
655                                                        for(list<polyhedron*>::iterator merge_child = current_parent->mergechildren.begin(); merge_child != current_parent->mergechildren.end();merge_child++)
656                                                        {
657                                                                (*merge_child)->positiveparent = current_parent;
658                                                        }
659                                                }
660
661                                                if(parent_state < 0)
662                                                {
663                                                        for(list<polyhedron*>::iterator merge_child = current_parent->mergechildren.begin(); merge_child != current_parent->mergechildren.end();merge_child++)
664                                                        {
665                                                                (*merge_child)->negativeparent = current_parent;
666                                                        }
667                                                }
668
669                                                if(parent_state == 0)
670                                                {
671                                                        for_merging[level+1].push_back(current_parent);
672                                                }
673
674                                                current_parent->mergechildren.clear();
675                                        }
676
677                                       
678                                }
679
680                                if(shouldsplit)
681                                        {
682                                                current_parent->totallyneutralgrandchildren.insert(current_parent->totallyneutralgrandchildren.end(),sender->totallyneutralchildren.begin(),sender->totallyneutralchildren.end());
683
684                                                switch(sender->get_state(SPLIT))
685                                                {
686                                                case 1:
687                                                        current_parent->positivechildren.push_back(sender);
688                                                        current_parent->positiveneutralvertices.insert(sender->vertices.begin(),sender->vertices.end());
689                                                break;
690                                                case 0:
691                                                        current_parent->neutralchildren.push_back(sender);
692                                                        current_parent->positiveneutralvertices.insert(sender->positiveneutralvertices.begin(),sender->positiveneutralvertices.end());
693                                                        current_parent->negativeneutralvertices.insert(sender->negativeneutralvertices.begin(),sender->negativeneutralvertices.end());
694
695                                                        if(current_parent->totally_neutral == NULL)
696                                                        {
697                                                                current_parent->totally_neutral = sender->totally_neutral;
698                                                        }
699                                                        else
700                                                        {
701                                                                current_parent->totally_neutral = current_parent->totally_neutral && sender->totally_neutral;
702                                                        }
703
704                                                        if(sender->totally_neutral)
705                                                        {
706                                                                current_parent->totallyneutralchildren.push_back(sender);
707                                                        }
708                                                       
709                                                break;
710                                                case -1:
711                                                        current_parent->negativechildren.push_back(sender);
712                                                        current_parent->negativeneutralvertices.insert(sender->vertices.begin(),sender->vertices.end());
713                                                break;
714                                                }
715
716                                                if(is_last)
717                                                {
718                                                        unique(current_parent->totallyneutralgrandchildren.begin(),current_parent->totallyneutralgrandchildren.end());
719
720                                                        if((current_parent->negativechildren.size()>0&&current_parent->positivechildren.size()>0)||
721                                                                                                                (current_parent->neutralchildren.size()>0&&current_parent->totally_neutral==false))
722                                                        {                                                               
723                                                               
724                                                                        for_splitting[level+1].push_back(current_parent);
725                                                               
726                                                                        current_parent->set_state(0, SPLIT);
727                                                        }
728                                                        else
729                                                        {
730                                                               
731
732                                                                if(current_parent->negativechildren.size()>0)
733                                                                {
734                                                                        current_parent->set_state(-1, SPLIT);
735
736                                                                        ((toprow*)current_parent)->condition-=toadd;
737
738                                                                       
739                                                                }
740                                                                else if(current_parent->positivechildren.size()>0)
741                                                                {
742                                                                        current_parent->set_state(1, SPLIT);
743
744                                                                        ((toprow*)current_parent)->condition+=toadd;                                                                   
745                                                                }
746                                                                else
747                                                                {
748                                                                        current_parent->raise_multiplicity();                                                           
749                                                                }
750
751                                                                ((toprow*)current_parent)->condition_order++;
752
753                                                                if(level == number_of_parameters - 1)
754                                                                {
755                                                                        toprow* cur_par_toprow = ((toprow*)current_parent);
756                                                                        cur_par_toprow->probability = 0.0;
757                                                                       
758                                                                        for(list<set<vertex*>>::iterator t_ref = current_parent->triangulation.begin();t_ref!=current_parent->triangulation.end();t_ref++)
759                                                                        {
760                                                                                cur_par_toprow->probability += cur_par_toprow->integrate_simplex(*t_ref,'C');
761                                                                        }                                                                       
762                                                                }
763
764                                                                current_parent->positivechildren.clear();
765                                                                current_parent->negativechildren.clear();
766                                                                current_parent->neutralchildren.clear();
767                                                                current_parent->totallyneutralchildren.clear();
768                                                                current_parent->totallyneutralgrandchildren.clear();
769                                                                current_parent->positiveneutralvertices.clear();
770                                                                current_parent->negativeneutralvertices.clear();
771                                                                current_parent->totally_neutral = NULL;
772                                                                current_parent->kids_rel_addresses.clear();
773                                                                current_parent->message_counter = 0;
774                                                        }
775                                                }
776                                        }
777
778                                        if(is_last)
779                                        {
780                                                send_state_message(current_parent,toadd,toremove,level+1);
781                                        }
782                       
783                        }
784                       
785                }               
786        }
787       
788public: 
789        c_statistic statistic;
790
791        vector<set<my_ivec>> correction_factors;
792
793        int number_of_parameters;
794
795        /// A default constructor creates an emlig with predefined statistic representing only the range of the given
796        /// parametric space, where the number of parameters of the needed model is given as a parameter to the constructor.
797        emlig(int number_of_parameters)
798        {       
799                this->number_of_parameters = number_of_parameters;
800
801                create_statistic(number_of_parameters);         
802        }
803
804        /// A constructor for creating an emlig when the user wants to create the statistic by himself. The creation of a
805        /// statistic is needed outside the constructor. Used for a user defined prior distribution on the parameters.
806        emlig(c_statistic statistic)
807        {
808                this->statistic = statistic;           
809        }
810
811        void step_me(int marker)
812        {
813                for(int i = 0;i<statistic.size();i++)
814                {
815                        for(polyhedron* horiz_ref = statistic.rows[i];horiz_ref!=statistic.get_end();horiz_ref=horiz_ref->next_poly)
816                        {
817                                char* string = "Checkpoint";
818                        }
819                }
820        }
821
822        int statistic_rowsize(int row)
823        {
824                return statistic.row_size(row);
825        }
826
827        void add_condition(vec toadd)
828        {
829                vec null_vector = "";
830
831                add_and_remove_condition(toadd, null_vector);
832        }
833
834
835        void remove_condition(vec toremove)
836        {               
837                vec null_vector = "";
838
839                add_and_remove_condition(null_vector, toremove);
840       
841        }
842
843
844        void add_and_remove_condition(vec toadd, vec toremove)
845        {
846                bool should_remove = (toremove.size() != 0);
847                bool should_add    = (toadd.size() != 0);
848
849                for_splitting.clear();
850                for_merging.clear();
851
852                for(int i = 0;i<statistic.size();i++)
853                {
854                        list<polyhedron*> empty_split;
855                        list<polyhedron*> empty_merge;
856
857                        for_splitting.push_back(empty_split);
858                        for_merging.push_back(empty_merge);
859                }
860
861                list<condition*>::iterator toremove_ref = conditions.end();
862                bool condition_should_be_added = false;
863
864                for(list<condition*>::iterator ref = conditions.begin();ref!=conditions.end();ref++)
865                {
866                        if(should_remove)
867                        {
868                                if((*ref)->value == toremove)
869                                {
870                                        if((*ref)->multiplicity>1)
871                                        {
872                                                (*ref)->multiplicity--;
873
874                                                alter_toprow_conditions(toremove,false);
875
876                                                should_remove = false;
877                                        }
878                                        else
879                                        {
880                                                toremove_ref = ref;                                                     
881                                        }
882                                }
883                        }
884
885                        if(should_add)
886                        {
887                                if((*ref)->value == toadd)
888                                {
889                                        (*ref)->multiplicity++;
890
891                                        alter_toprow_conditions(toadd,true);
892
893                                        should_add = false;
894                                }
895                                else
896                                {
897                                        condition_should_be_added = true;
898                                }
899                        }
900                }
901
902                if(toremove_ref!=conditions.end())
903                {
904                        conditions.erase(toremove_ref);
905                }
906
907                if(condition_should_be_added)
908                {
909                        conditions.push_back(new condition(toadd));
910                }
911
912               
913               
914                for(polyhedron* horizontal_position = statistic.rows[0];horizontal_position!=statistic.get_end();horizontal_position=horizontal_position->next_poly)
915                {               
916                        vertex* current_vertex = (vertex*)horizontal_position;
917                       
918                        if(should_add||should_remove)
919                        {
920                                vec appended_vec = current_vertex->get_coordinates();
921                                appended_vec.ins(0,-1.0);
922
923                                if(should_add)
924                                {
925                                        double local_condition = toadd*appended_vec;
926
927                                        current_vertex->set_state(local_condition,SPLIT);
928
929                                        if(local_condition == 0)
930                                        {
931                                                current_vertex->totally_neutral = true;
932
933                                                current_vertex->raise_multiplicity();
934
935                                                current_vertex->negativeneutralvertices.insert(current_vertex);
936                                                current_vertex->positiveneutralvertices.insert(current_vertex);
937                                        }                                       
938                                }
939                       
940                                if(should_remove)
941                                {
942                                        double local_condition = toremove*appended_vec;
943
944                                        current_vertex->set_state(local_condition,MERGE);
945
946                                        if(local_condition == 0)
947                                        {
948                                                for_merging[0].push_back(current_vertex);
949                                        }
950                                }                               
951                        }
952
953                        send_state_message(current_vertex, toadd, toremove, 0);         
954                       
955                }
956
957                if(should_add)
958                {
959                        int k = 1;
960
961                        vector<list<polyhedron*>>::iterator beginning_ref = ++for_splitting.begin();
962
963                        for(vector<list<polyhedron*>>::iterator vert_ref = beginning_ref;vert_ref<for_splitting.end();vert_ref++)
964                        {                       
965
966                                for(list<polyhedron*>::reverse_iterator split_ref = vert_ref->rbegin();split_ref != vert_ref->rend();split_ref++)
967                                {
968                                        polyhedron* new_totally_neutral_child;
969
970                                        polyhedron* current_polyhedron = (*split_ref);
971                                       
972                                        if(vert_ref == beginning_ref)
973                                        {
974                                                vec coordinates1 = ((vertex*)(*(current_polyhedron->children.begin())))->get_coordinates();                                             
975                                                vec coordinates2 = ((vertex*)(*(++current_polyhedron->children.begin())))->get_coordinates();
976                                               
977                                                vec extended_coord2 = coordinates2;
978                                                extended_coord2.ins(0,-1.0);
979
980                                                double t = (-toadd*extended_coord2)/((toadd(1,toadd.size()-1)*(coordinates1-coordinates2)));
981
982                                                vec new_coordinates = coordinates2+t*(coordinates1-coordinates2);                                       
983
984                                                // cout << "c1:" << coordinates1 << endl << "c2:" << coordinates2 << endl << "nc:" << new_coordinates << endl;
985
986                                                vertex* neutral_vertex = new vertex(new_coordinates);                                           
987
988                                                new_totally_neutral_child = neutral_vertex;
989                                        }
990                                        else
991                                        {
992                                                toprow* neutral_toprow = new toprow();
993
994                                                neutral_toprow->condition       = zeros(number_of_parameters+1);
995                                                neutral_toprow->condition_order = ((toprow*)current_polyhedron)->condition_order+1;
996
997                                                new_totally_neutral_child = neutral_toprow;
998                                        }
999
1000                                        new_totally_neutral_child->my_emlig = this;
1001                                       
1002                                        new_totally_neutral_child->children.insert(new_totally_neutral_child->children.end(),
1003                                                                                                                current_polyhedron->totallyneutralgrandchildren.begin(),
1004                                                                                                                                current_polyhedron->totallyneutralgrandchildren.end());
1005
1006                                        for(list<polyhedron*>::iterator grand_ref = current_polyhedron->totallyneutralgrandchildren.begin(); grand_ref != current_polyhedron->totallyneutralgrandchildren.end();grand_ref++)
1007                                        {
1008                                                (*grand_ref)->parents.push_back(new_totally_neutral_child);
1009
1010                                                new_totally_neutral_child->vertices.insert((*grand_ref)->vertices.begin(),(*grand_ref)->vertices.end());
1011                                        }
1012
1013                                        // cout << ((toprow*)current_polyhedron)->condition << endl << toadd << endl;
1014
1015                                        toprow* positive_poly = new toprow(((toprow*)current_polyhedron)->condition+toadd, ((toprow*)current_polyhedron)->condition_order+1);
1016                                        toprow* negative_poly = new toprow(((toprow*)current_polyhedron)->condition-toadd, ((toprow*)current_polyhedron)->condition_order+1);
1017
1018                                        positive_poly->my_emlig = this;
1019                                        negative_poly->my_emlig = this;
1020
1021                                        for(list<polyhedron*>::iterator parent_ref = current_polyhedron->parents.begin();parent_ref!=current_polyhedron->parents.end();parent_ref++)
1022                                        {
1023                                                (*parent_ref)->totallyneutralgrandchildren.push_back(new_totally_neutral_child);
1024
1025                                                (*parent_ref)->neutralchildren.remove(current_polyhedron);
1026                                                (*parent_ref)->children.remove(current_polyhedron);
1027
1028                                                (*parent_ref)->children.push_back(positive_poly);
1029                                                (*parent_ref)->children.push_back(negative_poly);
1030                                                (*parent_ref)->positivechildren.push_back(positive_poly);
1031                                                (*parent_ref)->negativechildren.push_back(negative_poly);
1032                                        }
1033
1034                                        positive_poly->parents.insert(positive_poly->parents.end(),
1035                                                                                                current_polyhedron->parents.begin(),
1036                                                                                                                current_polyhedron->parents.end());
1037
1038                                        negative_poly->parents.insert(negative_poly->parents.end(),
1039                                                                                                current_polyhedron->parents.begin(),
1040                                                                                                                current_polyhedron->parents.end());
1041
1042                                        positive_poly->children.push_back(new_totally_neutral_child);
1043                                        negative_poly->children.push_back(new_totally_neutral_child);
1044
1045                                        new_totally_neutral_child->parents.push_back(positive_poly);
1046                                        new_totally_neutral_child->parents.push_back(negative_poly);
1047
1048                                        for(list<polyhedron*>::iterator child_ref = current_polyhedron->positivechildren.begin();child_ref!=current_polyhedron->positivechildren.end();child_ref++)
1049                                        {
1050                                                (*child_ref)->parents.remove(current_polyhedron);
1051                                                (*child_ref)->parents.push_back(positive_poly);                                         
1052                                        }                                       
1053
1054                                        positive_poly->children.insert(positive_poly->children.end(),
1055                                                                                                current_polyhedron->positivechildren.begin(),
1056                                                                                                                        current_polyhedron->positivechildren.end());
1057
1058                                        for(list<polyhedron*>::iterator child_ref = current_polyhedron->negativechildren.begin();child_ref!=current_polyhedron->negativechildren.end();child_ref++)
1059                                        {
1060                                                (*child_ref)->parents.remove(current_polyhedron);
1061                                                (*child_ref)->parents.push_back(negative_poly);
1062                                        }
1063
1064                                        negative_poly->children.insert(negative_poly->children.end(),
1065                                                                                                current_polyhedron->negativechildren.begin(),
1066                                                                                                                        current_polyhedron->negativechildren.end());
1067
1068                                        positive_poly->vertices.insert(current_polyhedron->positiveneutralvertices.begin(),current_polyhedron->positiveneutralvertices.end());
1069                                        positive_poly->vertices.insert(new_totally_neutral_child->vertices.begin(),new_totally_neutral_child->vertices.end());
1070
1071                                        negative_poly->vertices.insert(current_polyhedron->negativeneutralvertices.begin(),current_polyhedron->negativeneutralvertices.end());
1072                                        negative_poly->vertices.insert(new_totally_neutral_child->vertices.begin(),new_totally_neutral_child->vertices.end());
1073                                                               
1074                                        new_totally_neutral_child->triangulate(false);
1075
1076                                        positive_poly->triangulate(k==for_splitting.size()-1);
1077                                        negative_poly->triangulate(k==for_splitting.size()-1);
1078                                       
1079                                        statistic.append_polyhedron(k-1, new_totally_neutral_child);                                   
1080                                       
1081                                        statistic.insert_polyhedron(k, positive_poly, current_polyhedron);
1082                                        statistic.insert_polyhedron(k, negative_poly, current_polyhedron);                                     
1083
1084                                        statistic.delete_polyhedron(k, current_polyhedron);
1085
1086                                        delete current_polyhedron;
1087                                }
1088
1089                                k++;
1090                        }
1091                }
1092
1093               
1094                vector<int> sizevector;
1095                for(int s = 0;s<statistic.size();s++)
1096                {
1097                        sizevector.push_back(statistic.row_size(s));
1098                }
1099
1100                /*
1101                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)
1102                {
1103                        cout << ((toprow*)topr_ref)->condition << endl;
1104                }
1105                */
1106
1107        }
1108
1109        void set_correction_factors(int order)
1110                {
1111                        for(int remaining_order = correction_factors.size();!(remaining_order>order);remaining_order++)
1112                        {
1113                                set<my_ivec> factor_templates;
1114                                set<my_ivec> final_factors;
1115
1116                               
1117                                for(int i = 1;i!=number_of_parameters-order+1;i++)
1118                                {                                       
1119                                        my_ivec new_template = my_ivec();
1120                                        new_template.ins(0,1);
1121                                        new_template.ins(1,i);
1122                                        factor_templates.insert(new_template);
1123
1124                                       
1125                                        for(int j = 1;j<remaining_order;j++)
1126                                        {
1127                                               
1128                                                for(set<my_ivec>::iterator fac_ref = factor_templates.begin();fac_ref!=factor_templates.end();fac_ref++)
1129                                                {
1130                                                        ivec current_template = (*fac_ref);
1131                                                       
1132                                                        current_template[0]+=1;
1133                                                        current_template.ins(current_template.size(),i);
1134
1135                                                       
1136                                                        if(current_template[0]==remaining_order)
1137                                                        {
1138                                                                final_factors.insert(current_template.right(current_template.size()-1));
1139                                                        }
1140                                                        else
1141                                                        {
1142                                                                factor_templates.insert(current_template);
1143                                                        }
1144                                                }
1145                                        }
1146                                }       
1147
1148                                correction_factors.push_back(final_factors);                   
1149
1150                        }
1151                }
1152
1153protected:
1154
1155        /// A method for creating plain default statistic representing only the range of the parameter space.
1156    void create_statistic(int number_of_parameters)
1157        {
1158                for(int i = 0;i<number_of_parameters;i++)
1159                {
1160                        vec condition_vec = zeros(number_of_parameters+1);
1161                        condition_vec[i+1]  = 1;
1162
1163                        condition* new_condition = new condition(condition_vec);
1164                       
1165                        conditions.push_back(new_condition);
1166                }
1167
1168                // An empty vector of coordinates.
1169                vec origin_coord;       
1170
1171                // We create an origin - this point will have all the coordinates zero, but now it has an empty vector of coords.
1172                vertex *origin = new vertex(origin_coord);
1173
1174                origin->my_emlig = this;
1175               
1176                /*
1177                // As a statistic, we have to create a vector of vectors of polyhedron pointers. It will then represent the Hasse
1178                // diagram. First we create a vector of polyhedrons..
1179                list<polyhedron*> origin_vec;
1180
1181                // ..we fill it with the origin..
1182                origin_vec.push_back(origin);
1183
1184                // ..and we fill the statistic with the created vector.
1185                statistic.push_back(origin_vec);
1186                */
1187
1188                statistic = *(new c_statistic());               
1189               
1190                statistic.append_polyhedron(0, origin);
1191
1192                // Now we have a statistic for a zero dimensional space. Regarding to how many dimensional space we need to
1193                // describe, we have to widen the descriptional default statistic. We use an iterative procedure as follows:
1194                for(int i=0;i<number_of_parameters;i++)
1195                {
1196                        // We first will create two new vertices. These will be the borders of the parameter space in the dimension
1197                        // of newly added parameter. Therefore they will have all coordinates except the last one zero. We get the
1198                        // right amount of zero cooridnates by reading them from the origin
1199                        vec origin_coord = origin->get_coordinates();                                           
1200
1201                        // And we incorporate the nonzero coordinates into the new cooordinate vectors
1202                        vec origin_coord1 = concat(origin_coord,-max_range); 
1203                        vec origin_coord2 = concat(origin_coord,max_range);                             
1204                                       
1205
1206                        // Now we create the points
1207                        vertex* new_point1 = new vertex(origin_coord1);
1208                        vertex* new_point2 = new vertex(origin_coord2);
1209
1210                        new_point1->my_emlig = this;
1211                        new_point2->my_emlig = this;
1212                       
1213                        //*********************************************************************************************************
1214                        // The algorithm for recursive build of a new Hasse diagram representing the space structure from the old
1215                        // diagram works so that you create two copies of the old Hasse diagram, you shift them up one level (points
1216                        // will be segments, segments will be areas etc.) and you connect each one of the original copied polyhedrons
1217                        // with its offspring by a parent-child relation. Also each of the segments in the first (second) copy is
1218                        // connected to the first (second) newly created vertex by a parent-child relation.
1219                        //*********************************************************************************************************
1220
1221
1222                        /*
1223                        // Create the vectors of vectors of pointers to polyhedrons to hold the copies of the old Hasse diagram
1224                        vector<vector<polyhedron*>> new_statistic1;
1225                        vector<vector<polyhedron*>> new_statistic2;
1226                        */
1227
1228                        c_statistic* new_statistic1 = new c_statistic();
1229                        c_statistic* new_statistic2 = new c_statistic();
1230
1231                       
1232                        // Copy the statistic by rows                   
1233                        for(int j=0;j<statistic.size();j++)
1234                        {
1235                               
1236
1237                                // an element counter
1238                                int element_number = 0;
1239
1240                                /*
1241                                vector<polyhedron*> supportnew_1;
1242                                vector<polyhedron*> supportnew_2;
1243
1244                                new_statistic1.push_back(supportnew_1);
1245                                new_statistic2.push_back(supportnew_2);
1246                                */
1247
1248                                // for each polyhedron in the given row
1249                                for(polyhedron* horiz_ref = statistic.rows[j];horiz_ref!=statistic.get_end();horiz_ref=horiz_ref->next_poly)
1250                                {       
1251                                        // Append an extra zero coordinate to each of the vertices for the new dimension
1252                                        // If vert_ref is at the first index => we loop through vertices
1253                                        if(j == 0)
1254                                        {
1255                                                // cast the polyhedron pointer to a vertex pointer and push a zero to its vector of coordinates
1256                                                ((vertex*) horiz_ref)->push_coordinate(0);
1257                                        }
1258                                        /*
1259                                        else
1260                                        {
1261                                                ((toprow*) (*horiz_ref))->condition.ins(0,0);
1262                                        }*/
1263
1264                                        // if it has parents
1265                                        if(!horiz_ref->parents.empty())
1266                                        {
1267                                                // save the relative address of this child in a vector kids_rel_addresses of all its parents.
1268                                                // This information will later be used for copying the whole Hasse diagram with each of the
1269                                                // relations contained within.
1270                                                for(list<polyhedron*>::iterator parent_ref = horiz_ref->parents.begin();parent_ref != horiz_ref->parents.end();parent_ref++)
1271                                                {
1272                                                        (*parent_ref)->kids_rel_addresses.push_back(element_number);                                                   
1273                                                }                                               
1274                                        }
1275
1276                                        // **************************************************************************************************
1277                                        // Here we begin creating a new polyhedron, which will be a copy of the old one. Each such polyhedron
1278                                        // will be created as a toprow, but this information will be later forgotten and only the polyhedrons
1279                                        // in the top row of the Hasse diagram will be considered toprow for later use.
1280                                        // **************************************************************************************************
1281
1282                                        // First we create vectors specifying a toprow condition. In the case of a preconstructed statistic
1283                                        // this condition will be a vector of zeros. There are two vectors, because we need two copies of
1284                                        // the original Hasse diagram.
1285                                        vec vec1(number_of_parameters+1);
1286                                        vec1.zeros();
1287
1288                                        vec vec2(number_of_parameters+1);
1289                                        vec2.zeros();
1290
1291                                        // We create a new toprow with the previously specified condition.
1292                                        toprow* current_copy1 = new toprow(vec1, 0);
1293                                        toprow* current_copy2 = new toprow(vec2, 0);
1294
1295                                        current_copy1->my_emlig = this;
1296                                        current_copy2->my_emlig = this;
1297
1298                                        // The vertices of the copies will be inherited, because there will be a parent/child relation
1299                                        // between each polyhedron and its offspring (comming from the copy) and a parent has all the
1300                                        // vertices of its child plus more.
1301                                        for(set<vertex*>::iterator vertex_ref = horiz_ref->vertices.begin();vertex_ref!=horiz_ref->vertices.end();vertex_ref++)
1302                                        {
1303                                                current_copy1->vertices.insert(*vertex_ref);
1304                                                current_copy2->vertices.insert(*vertex_ref);                                           
1305                                        }
1306                                       
1307                                        // The only new vertex of the offspring should be the newly created point.
1308                                        current_copy1->vertices.insert(new_point1);
1309                                        current_copy2->vertices.insert(new_point2);                                     
1310                                       
1311                                        // This method guarantees that each polyhedron is already triangulated, therefore its triangulation
1312                                        // is only one set of vertices and it is the set of all its vertices.
1313                                        set<vertex*> t_simplex1;
1314                                        set<vertex*> t_simplex2;
1315
1316                                        t_simplex1.insert(current_copy1->vertices.begin(),current_copy1->vertices.end());
1317                                        t_simplex2.insert(current_copy2->vertices.begin(),current_copy2->vertices.end());
1318                                       
1319                                        current_copy1->triangulation.push_back(t_simplex1);
1320                                        current_copy2->triangulation.push_back(t_simplex2);                                     
1321                                       
1322                                        // Now we have copied the polyhedron and we have to copy all of its relations. Because we are copying
1323                                        // in the Hasse diagram from bottom up, we always have to copy the parent/child relations to all the
1324                                        // kids and when we do that and know the child, in the child we will remember the parent we came from.
1325                                        // This way all the parents/children relations are saved in both the parent and the child.
1326                                        if(!horiz_ref->kids_rel_addresses.empty())
1327                                        {
1328                                                for(list<int>::iterator kid_ref = horiz_ref->kids_rel_addresses.begin();kid_ref!=horiz_ref->kids_rel_addresses.end();kid_ref++)
1329                                                {       
1330                                                        polyhedron* new_kid1 = new_statistic1->rows[j-1];
1331                                                        polyhedron* new_kid2 = new_statistic2->rows[j-1];
1332
1333                                                        // THIS IS NOT EFFECTIVE: It could be improved by having the list indexed for new_statistic, but
1334                                                        // not indexed for statistic. Hopefully this will not cause a big slowdown - happens only offline.
1335                                                        if(*kid_ref)
1336                                                        {
1337                                                                for(int k = 1;k<=(*kid_ref);k++)
1338                                                                {
1339                                                                        new_kid1=new_kid1->next_poly;
1340                                                                        new_kid2=new_kid2->next_poly;
1341                                                                }
1342                                                        }
1343                                                       
1344                                                        // find the child and save the relation to the parent
1345                                                        current_copy1->children.push_back(new_kid1);
1346                                                        current_copy2->children.push_back(new_kid2);
1347
1348                                                        // in the child save the parents' address
1349                                                        new_kid1->parents.push_back(current_copy1);
1350                                                        new_kid2->parents.push_back(current_copy2);
1351                                                }                                               
1352
1353                                                // Here we clear the parents kids_rel_addresses vector for later use (when we need to widen the
1354                                                // Hasse diagram again)
1355                                                horiz_ref->kids_rel_addresses.clear();
1356                                        }
1357                                        // If there were no children previously, we are copying a polyhedron that has been a vertex before.
1358                                        // In this case it is a segment now and it will have a relation to its mother (copywise) and to the
1359                                        // newly created point. Here we create the connection to the new point, again from both sides.
1360                                        else
1361                                        {
1362                                                // Add the address of the new point in the former vertex
1363                                                current_copy1->children.push_back(new_point1);
1364                                                current_copy2->children.push_back(new_point2);
1365
1366                                                // Add the address of the former vertex in the new point
1367                                                new_point1->parents.push_back(current_copy1);
1368                                                new_point2->parents.push_back(current_copy2);
1369                                        }
1370
1371                                        // Save the mother in its offspring
1372                                        current_copy1->children.push_back(horiz_ref);
1373                                        current_copy2->children.push_back(horiz_ref);
1374
1375                                        // Save the offspring in its mother
1376                                        horiz_ref->parents.push_back(current_copy1);
1377                                        horiz_ref->parents.push_back(current_copy2);   
1378                                                               
1379                                       
1380                                        // Add the copies into the relevant statistic. The statistic will later be appended to the previous
1381                                        // Hasse diagram
1382                                        new_statistic1->append_polyhedron(j,current_copy1);
1383                                        new_statistic2->append_polyhedron(j,current_copy2);
1384                                       
1385                                        // Raise the count in the vector of polyhedrons
1386                                        element_number++;                       
1387                                       
1388                                }
1389                               
1390                        }
1391
1392                        /*
1393                        statistic.begin()->push_back(new_point1);
1394                        statistic.begin()->push_back(new_point2);
1395                        */
1396
1397                        statistic.append_polyhedron(0, new_point1);
1398                        statistic.append_polyhedron(0, new_point2);
1399
1400                        // Merge the new statistics into the old one. This will either be the final statistic or we will
1401                        // reenter the widening loop.
1402                        for(int j=0;j<new_statistic1->size();j++)
1403                        {
1404                                /*
1405                                if(j+1==statistic.size())
1406                                {
1407                                        list<polyhedron*> support;
1408                                        statistic.push_back(support);
1409                                }
1410                               
1411                                (statistic.begin()+j+1)->insert((statistic.begin()+j+1)->end(),new_statistic1[j].begin(),new_statistic1[j].end());
1412                                (statistic.begin()+j+1)->insert((statistic.begin()+j+1)->end(),new_statistic2[j].begin(),new_statistic2[j].end());
1413                                */
1414                                statistic.append_polyhedron(j+1,new_statistic1->rows[j],new_statistic1->row_ends[j]);
1415                                statistic.append_polyhedron(j+1,new_statistic2->rows[j],new_statistic2->row_ends[j]);
1416                        }                       
1417                }
1418
1419                /*
1420                vector<list<toprow*>> toprow_statistic;
1421                int line_count = 0;
1422
1423                for(vector<list<polyhedron*>>::iterator polyhedron_ref = ++statistic.begin(); polyhedron_ref!=statistic.end();polyhedron_ref++)
1424                {
1425                        list<toprow*> support_list;
1426                        toprow_statistic.push_back(support_list);                                               
1427
1428                        for(list<polyhedron*>::iterator polyhedron_ref2 = polyhedron_ref->begin(); polyhedron_ref2 != polyhedron_ref->end(); polyhedron_ref2++)
1429                        {
1430                                toprow* support_top = (toprow*)(*polyhedron_ref2);
1431
1432                                toprow_statistic[line_count].push_back(support_top);
1433                        }
1434
1435                        line_count++;
1436                }*/
1437
1438                /*
1439                vector<int> sizevector;
1440                for(int s = 0;s<statistic.size();s++)
1441                {
1442                        sizevector.push_back(statistic.row_size(s));
1443                }
1444                */
1445               
1446        }
1447
1448
1449       
1450       
1451};
1452
1453/*
1454
1455//! Robust Bayesian AR model for Multicriteria-Laplace-Inverse-Gamma density
1456class RARX : public BM
1457{
1458private:
1459
1460        emlig posterior;
1461
1462public:
1463        RARX():BM()
1464        {
1465        };
1466
1467        void bayes(const itpp::vec &yt, const itpp::vec &cond = empty_vec)
1468        {
1469               
1470        }
1471
1472};*/
1473
1474
1475
1476#endif //TRAGE_H
Note: See TracBrowser for help on using the browser.