root/applications/robust/robustlib.h @ 1271

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

Juchuu, pocita to. Odstraneny nektere chyby. Zbyva odstranit chybu s negativnimi 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        polyhedron* end_poly;
276        polyhedron* start_poly;
277
278public: 
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        c_statistic statistic;
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
790        vector<set<my_ivec>> correction_factors;
791
792        int number_of_parameters;
793
794        /// A default constructor creates an emlig with predefined statistic representing only the range of the given
795        /// parametric space, where the number of parameters of the needed model is given as a parameter to the constructor.
796        emlig(int number_of_parameters)
797        {       
798                this->number_of_parameters = number_of_parameters;
799
800                create_statistic(number_of_parameters);         
801        }
802
803        /// A constructor for creating an emlig when the user wants to create the statistic by himself. The creation of a
804        /// statistic is needed outside the constructor. Used for a user defined prior distribution on the parameters.
805        emlig(c_statistic statistic)
806        {
807                this->statistic = statistic;           
808        }
809
810        void step_me(int marker)
811        {
812                for(int i = 0;i<statistic.size();i++)
813                {
814                        for(polyhedron* horiz_ref = statistic.rows[i];horiz_ref!=statistic.get_end();horiz_ref=horiz_ref->next_poly)
815                        {
816                                char* string = "Checkpoint";
817                        }
818                }
819        }
820
821        int statistic_rowsize(int row)
822        {
823                return statistic.row_size(row);
824        }
825
826        void add_condition(vec toadd)
827        {
828                vec null_vector = "";
829
830                add_and_remove_condition(toadd, null_vector);
831        }
832
833
834        void remove_condition(vec toremove)
835        {               
836                vec null_vector = "";
837
838                add_and_remove_condition(null_vector, toremove);
839       
840        }
841
842
843        void add_and_remove_condition(vec toadd, vec toremove)
844        {
845                bool should_remove = (toremove.size() != 0);
846                bool should_add    = (toadd.size() != 0);
847
848                for_splitting.clear();
849                for_merging.clear();
850
851                for(int i = 0;i<statistic.size();i++)
852                {
853                        list<polyhedron*> empty_split;
854                        list<polyhedron*> empty_merge;
855
856                        for_splitting.push_back(empty_split);
857                        for_merging.push_back(empty_merge);
858                }
859
860                list<condition*>::iterator toremove_ref = conditions.end();
861                bool condition_should_be_added = false;
862
863                for(list<condition*>::iterator ref = conditions.begin();ref!=conditions.end();ref++)
864                {
865                        if(should_remove)
866                        {
867                                if((*ref)->value == toremove)
868                                {
869                                        if((*ref)->multiplicity>1)
870                                        {
871                                                (*ref)->multiplicity--;
872
873                                                alter_toprow_conditions(toremove,false);
874
875                                                should_remove = false;
876                                        }
877                                        else
878                                        {
879                                                toremove_ref = ref;                                                     
880                                        }
881                                }
882                        }
883
884                        if(should_add)
885                        {
886                                if((*ref)->value == toadd)
887                                {
888                                        (*ref)->multiplicity++;
889
890                                        alter_toprow_conditions(toadd,true);
891
892                                        should_add = false;
893                                }
894                                else
895                                {
896                                        condition_should_be_added = true;
897                                }
898                        }
899                }
900
901                if(toremove_ref!=conditions.end())
902                {
903                        conditions.erase(toremove_ref);
904                }
905
906                if(condition_should_be_added)
907                {
908                        conditions.push_back(new condition(toadd));
909                }
910
911               
912               
913                for(polyhedron* horizontal_position = statistic.rows[0];horizontal_position!=statistic.get_end();horizontal_position=horizontal_position->next_poly)
914                {               
915                        vertex* current_vertex = (vertex*)horizontal_position;
916                       
917                        if(should_add||should_remove)
918                        {
919                                vec appended_vec = current_vertex->get_coordinates();
920                                appended_vec.ins(0,-1.0);
921
922                                if(should_add)
923                                {
924                                        double local_condition = toadd*appended_vec;
925
926                                        current_vertex->set_state(local_condition,SPLIT);
927
928                                        if(local_condition == 0)
929                                        {
930                                                current_vertex->totally_neutral = true;
931
932                                                current_vertex->raise_multiplicity();
933
934                                                current_vertex->negativeneutralvertices.insert(current_vertex);
935                                                current_vertex->positiveneutralvertices.insert(current_vertex);
936                                        }                                       
937                                }
938                       
939                                if(should_remove)
940                                {
941                                        double local_condition = toremove*appended_vec;
942
943                                        current_vertex->set_state(local_condition,MERGE);
944
945                                        if(local_condition == 0)
946                                        {
947                                                for_merging[0].push_back(current_vertex);
948                                        }
949                                }                               
950                        }
951
952                        send_state_message(current_vertex, toadd, toremove, 0);         
953                       
954                }
955
956                if(should_add)
957                {
958                        int k = 1;
959
960                        vector<list<polyhedron*>>::iterator beginning_ref = ++for_splitting.begin();
961
962                        for(vector<list<polyhedron*>>::iterator vert_ref = beginning_ref;vert_ref<for_splitting.end();vert_ref++)
963                        {                       
964
965                                for(list<polyhedron*>::reverse_iterator split_ref = vert_ref->rbegin();split_ref != vert_ref->rend();split_ref++)
966                                {
967                                        polyhedron* new_totally_neutral_child;
968
969                                        polyhedron* current_polyhedron = (*split_ref);
970                                       
971                                        if(vert_ref == beginning_ref)
972                                        {
973                                                vec coordinates1 = ((vertex*)(*(current_polyhedron->children.begin())))->get_coordinates();                                             
974                                                vec coordinates2 = ((vertex*)(*(++current_polyhedron->children.begin())))->get_coordinates();
975                                               
976                                                vec extended_coord2 = coordinates2;
977                                                extended_coord2.ins(0,-1.0);
978
979                                                double t = (-toadd*extended_coord2)/((toadd(1,toadd.size()-1)*(coordinates1-coordinates2)));
980
981                                                vec new_coordinates = coordinates2+t*(coordinates1-coordinates2);                                       
982
983                                                // cout << "c1:" << coordinates1 << endl << "c2:" << coordinates2 << endl << "nc:" << new_coordinates << endl;
984
985                                                vertex* neutral_vertex = new vertex(new_coordinates);                                           
986
987                                                new_totally_neutral_child = neutral_vertex;
988                                        }
989                                        else
990                                        {
991                                                toprow* neutral_toprow = new toprow();
992
993                                                neutral_toprow->condition       = zeros(number_of_parameters+1);
994                                                neutral_toprow->condition_order = ((toprow*)current_polyhedron)->condition_order+1;
995
996                                                new_totally_neutral_child = neutral_toprow;
997                                        }
998
999                                        new_totally_neutral_child->my_emlig = this;
1000                                       
1001                                        new_totally_neutral_child->children.insert(new_totally_neutral_child->children.end(),
1002                                                                                                                current_polyhedron->totallyneutralgrandchildren.begin(),
1003                                                                                                                                current_polyhedron->totallyneutralgrandchildren.end());
1004
1005                                        for(list<polyhedron*>::iterator grand_ref = current_polyhedron->totallyneutralgrandchildren.begin(); grand_ref != current_polyhedron->totallyneutralgrandchildren.end();grand_ref++)
1006                                        {
1007                                                (*grand_ref)->parents.push_back(new_totally_neutral_child);
1008
1009                                                new_totally_neutral_child->vertices.insert((*grand_ref)->vertices.begin(),(*grand_ref)->vertices.end());
1010                                        }
1011
1012                                        // cout << ((toprow*)current_polyhedron)->condition << endl << toadd << endl;
1013
1014                                        toprow* positive_poly = new toprow(((toprow*)current_polyhedron)->condition+toadd, ((toprow*)current_polyhedron)->condition_order+1);
1015                                        toprow* negative_poly = new toprow(((toprow*)current_polyhedron)->condition-toadd, ((toprow*)current_polyhedron)->condition_order+1);
1016
1017                                        positive_poly->my_emlig = this;
1018                                        negative_poly->my_emlig = this;
1019
1020                                        for(list<polyhedron*>::iterator parent_ref = current_polyhedron->parents.begin();parent_ref!=current_polyhedron->parents.end();parent_ref++)
1021                                        {
1022                                                (*parent_ref)->totallyneutralgrandchildren.push_back(new_totally_neutral_child);
1023
1024                                                (*parent_ref)->neutralchildren.remove(current_polyhedron);
1025                                                (*parent_ref)->children.remove(current_polyhedron);
1026
1027                                                (*parent_ref)->children.push_back(positive_poly);
1028                                                (*parent_ref)->children.push_back(negative_poly);
1029                                                (*parent_ref)->positivechildren.push_back(positive_poly);
1030                                                (*parent_ref)->negativechildren.push_back(negative_poly);
1031                                        }
1032
1033                                        positive_poly->parents.insert(positive_poly->parents.end(),
1034                                                                                                current_polyhedron->parents.begin(),
1035                                                                                                                current_polyhedron->parents.end());
1036
1037                                        negative_poly->parents.insert(negative_poly->parents.end(),
1038                                                                                                current_polyhedron->parents.begin(),
1039                                                                                                                current_polyhedron->parents.end());
1040
1041                                        positive_poly->children.push_back(new_totally_neutral_child);
1042                                        negative_poly->children.push_back(new_totally_neutral_child);
1043
1044                                        new_totally_neutral_child->parents.push_back(positive_poly);
1045                                        new_totally_neutral_child->parents.push_back(negative_poly);
1046
1047                                        for(list<polyhedron*>::iterator child_ref = current_polyhedron->positivechildren.begin();child_ref!=current_polyhedron->positivechildren.end();child_ref++)
1048                                        {
1049                                                (*child_ref)->parents.remove(current_polyhedron);
1050                                                (*child_ref)->parents.push_back(positive_poly);                                         
1051                                        }                                       
1052
1053                                        positive_poly->children.insert(positive_poly->children.end(),
1054                                                                                                current_polyhedron->positivechildren.begin(),
1055                                                                                                                        current_polyhedron->positivechildren.end());
1056
1057                                        for(list<polyhedron*>::iterator child_ref = current_polyhedron->negativechildren.begin();child_ref!=current_polyhedron->negativechildren.end();child_ref++)
1058                                        {
1059                                                (*child_ref)->parents.remove(current_polyhedron);
1060                                                (*child_ref)->parents.push_back(negative_poly);
1061                                        }
1062
1063                                        negative_poly->children.insert(negative_poly->children.end(),
1064                                                                                                current_polyhedron->negativechildren.begin(),
1065                                                                                                                        current_polyhedron->negativechildren.end());
1066
1067                                        positive_poly->vertices.insert(current_polyhedron->positiveneutralvertices.begin(),current_polyhedron->positiveneutralvertices.end());
1068                                        positive_poly->vertices.insert(new_totally_neutral_child->vertices.begin(),new_totally_neutral_child->vertices.end());
1069
1070                                        negative_poly->vertices.insert(current_polyhedron->negativeneutralvertices.begin(),current_polyhedron->negativeneutralvertices.end());
1071                                        negative_poly->vertices.insert(new_totally_neutral_child->vertices.begin(),new_totally_neutral_child->vertices.end());
1072                                                               
1073                                        new_totally_neutral_child->triangulate(false);
1074
1075                                        positive_poly->triangulate(k==for_splitting.size()-1);
1076                                        negative_poly->triangulate(k==for_splitting.size()-1);
1077                                       
1078                                        statistic.append_polyhedron(k-1, new_totally_neutral_child);                                   
1079                                       
1080                                        statistic.insert_polyhedron(k, positive_poly, current_polyhedron);
1081                                        statistic.insert_polyhedron(k, negative_poly, current_polyhedron);                                     
1082
1083                                        statistic.delete_polyhedron(k, current_polyhedron);
1084
1085                                        delete current_polyhedron;
1086                                }
1087
1088                                k++;
1089                        }
1090                }
1091
1092               
1093                vector<int> sizevector;
1094                for(int s = 0;s<statistic.size();s++)
1095                {
1096                        sizevector.push_back(statistic.row_size(s));
1097                }
1098
1099                /*
1100                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)
1101                {
1102                        cout << ((toprow*)topr_ref)->condition << endl;
1103                }
1104                */
1105
1106        }
1107
1108        void set_correction_factors(int order)
1109                {
1110                        for(int remaining_order = correction_factors.size();!(remaining_order>order);remaining_order++)
1111                        {
1112                                set<my_ivec> factor_templates;
1113                                set<my_ivec> final_factors;
1114
1115                               
1116                                for(int i = 1;i!=number_of_parameters-order+1;i++)
1117                                {                                       
1118                                        my_ivec new_template = my_ivec();
1119                                        new_template.ins(0,1);
1120                                        new_template.ins(1,i);
1121                                        factor_templates.insert(new_template);
1122
1123                                       
1124                                        for(int j = 1;j<remaining_order;j++)
1125                                        {
1126                                               
1127                                                for(set<my_ivec>::iterator fac_ref = factor_templates.begin();fac_ref!=factor_templates.end();fac_ref++)
1128                                                {
1129                                                        ivec current_template = (*fac_ref);
1130                                                       
1131                                                        current_template[0]+=1;
1132                                                        current_template.ins(current_template.size(),i);
1133
1134                                                       
1135                                                        if(current_template[0]==remaining_order)
1136                                                        {
1137                                                                final_factors.insert(current_template.right(current_template.size()-1));
1138                                                        }
1139                                                        else
1140                                                        {
1141                                                                factor_templates.insert(current_template);
1142                                                        }
1143                                                }
1144                                        }
1145                                }       
1146
1147                                correction_factors.push_back(final_factors);                   
1148
1149                        }
1150                }
1151
1152protected:
1153
1154        /// A method for creating plain default statistic representing only the range of the parameter space.
1155    void create_statistic(int number_of_parameters)
1156        {
1157                for(int i = 0;i<number_of_parameters;i++)
1158                {
1159                        vec condition_vec = zeros(number_of_parameters+1);
1160                        condition_vec[i+1]  = 1;
1161
1162                        condition* new_condition = new condition(condition_vec);
1163                       
1164                        conditions.push_back(new_condition);
1165                }
1166
1167                // An empty vector of coordinates.
1168                vec origin_coord;       
1169
1170                // We create an origin - this point will have all the coordinates zero, but now it has an empty vector of coords.
1171                vertex *origin = new vertex(origin_coord);
1172
1173                origin->my_emlig = this;
1174               
1175                /*
1176                // As a statistic, we have to create a vector of vectors of polyhedron pointers. It will then represent the Hasse
1177                // diagram. First we create a vector of polyhedrons..
1178                list<polyhedron*> origin_vec;
1179
1180                // ..we fill it with the origin..
1181                origin_vec.push_back(origin);
1182
1183                // ..and we fill the statistic with the created vector.
1184                statistic.push_back(origin_vec);
1185                */
1186
1187                statistic = *(new c_statistic());               
1188               
1189                statistic.append_polyhedron(0, origin);
1190
1191                // Now we have a statistic for a zero dimensional space. Regarding to how many dimensional space we need to
1192                // describe, we have to widen the descriptional default statistic. We use an iterative procedure as follows:
1193                for(int i=0;i<number_of_parameters;i++)
1194                {
1195                        // We first will create two new vertices. These will be the borders of the parameter space in the dimension
1196                        // of newly added parameter. Therefore they will have all coordinates except the last one zero. We get the
1197                        // right amount of zero cooridnates by reading them from the origin
1198                        vec origin_coord = origin->get_coordinates();                                           
1199
1200                        // And we incorporate the nonzero coordinates into the new cooordinate vectors
1201                        vec origin_coord1 = concat(origin_coord,-max_range); 
1202                        vec origin_coord2 = concat(origin_coord,max_range);                             
1203                                       
1204
1205                        // Now we create the points
1206                        vertex* new_point1 = new vertex(origin_coord1);
1207                        vertex* new_point2 = new vertex(origin_coord2);
1208
1209                        new_point1->my_emlig = this;
1210                        new_point2->my_emlig = this;
1211                       
1212                        //*********************************************************************************************************
1213                        // The algorithm for recursive build of a new Hasse diagram representing the space structure from the old
1214                        // diagram works so that you create two copies of the old Hasse diagram, you shift them up one level (points
1215                        // will be segments, segments will be areas etc.) and you connect each one of the original copied polyhedrons
1216                        // with its offspring by a parent-child relation. Also each of the segments in the first (second) copy is
1217                        // connected to the first (second) newly created vertex by a parent-child relation.
1218                        //*********************************************************************************************************
1219
1220
1221                        /*
1222                        // Create the vectors of vectors of pointers to polyhedrons to hold the copies of the old Hasse diagram
1223                        vector<vector<polyhedron*>> new_statistic1;
1224                        vector<vector<polyhedron*>> new_statistic2;
1225                        */
1226
1227                        c_statistic* new_statistic1 = new c_statistic();
1228                        c_statistic* new_statistic2 = new c_statistic();
1229
1230                       
1231                        // Copy the statistic by rows                   
1232                        for(int j=0;j<statistic.size();j++)
1233                        {
1234                               
1235
1236                                // an element counter
1237                                int element_number = 0;
1238
1239                                /*
1240                                vector<polyhedron*> supportnew_1;
1241                                vector<polyhedron*> supportnew_2;
1242
1243                                new_statistic1.push_back(supportnew_1);
1244                                new_statistic2.push_back(supportnew_2);
1245                                */
1246
1247                                // for each polyhedron in the given row
1248                                for(polyhedron* horiz_ref = statistic.rows[j];horiz_ref!=statistic.get_end();horiz_ref=horiz_ref->next_poly)
1249                                {       
1250                                        // Append an extra zero coordinate to each of the vertices for the new dimension
1251                                        // If vert_ref is at the first index => we loop through vertices
1252                                        if(j == 0)
1253                                        {
1254                                                // cast the polyhedron pointer to a vertex pointer and push a zero to its vector of coordinates
1255                                                ((vertex*) horiz_ref)->push_coordinate(0);
1256                                        }
1257                                        /*
1258                                        else
1259                                        {
1260                                                ((toprow*) (*horiz_ref))->condition.ins(0,0);
1261                                        }*/
1262
1263                                        // if it has parents
1264                                        if(!horiz_ref->parents.empty())
1265                                        {
1266                                                // save the relative address of this child in a vector kids_rel_addresses of all its parents.
1267                                                // This information will later be used for copying the whole Hasse diagram with each of the
1268                                                // relations contained within.
1269                                                for(list<polyhedron*>::iterator parent_ref = horiz_ref->parents.begin();parent_ref != horiz_ref->parents.end();parent_ref++)
1270                                                {
1271                                                        (*parent_ref)->kids_rel_addresses.push_back(element_number);                                                   
1272                                                }                                               
1273                                        }
1274
1275                                        // **************************************************************************************************
1276                                        // Here we begin creating a new polyhedron, which will be a copy of the old one. Each such polyhedron
1277                                        // will be created as a toprow, but this information will be later forgotten and only the polyhedrons
1278                                        // in the top row of the Hasse diagram will be considered toprow for later use.
1279                                        // **************************************************************************************************
1280
1281                                        // First we create vectors specifying a toprow condition. In the case of a preconstructed statistic
1282                                        // this condition will be a vector of zeros. There are two vectors, because we need two copies of
1283                                        // the original Hasse diagram.
1284                                        vec vec1(number_of_parameters+1);
1285                                        vec1.zeros();
1286
1287                                        vec vec2(number_of_parameters+1);
1288                                        vec2.zeros();
1289
1290                                        // We create a new toprow with the previously specified condition.
1291                                        toprow* current_copy1 = new toprow(vec1, 0);
1292                                        toprow* current_copy2 = new toprow(vec2, 0);
1293
1294                                        current_copy1->my_emlig = this;
1295                                        current_copy2->my_emlig = this;
1296
1297                                        // The vertices of the copies will be inherited, because there will be a parent/child relation
1298                                        // between each polyhedron and its offspring (comming from the copy) and a parent has all the
1299                                        // vertices of its child plus more.
1300                                        for(set<vertex*>::iterator vertex_ref = horiz_ref->vertices.begin();vertex_ref!=horiz_ref->vertices.end();vertex_ref++)
1301                                        {
1302                                                current_copy1->vertices.insert(*vertex_ref);
1303                                                current_copy2->vertices.insert(*vertex_ref);                                           
1304                                        }
1305                                       
1306                                        // The only new vertex of the offspring should be the newly created point.
1307                                        current_copy1->vertices.insert(new_point1);
1308                                        current_copy2->vertices.insert(new_point2);                                     
1309                                       
1310                                        // This method guarantees that each polyhedron is already triangulated, therefore its triangulation
1311                                        // is only one set of vertices and it is the set of all its vertices.
1312                                        set<vertex*> t_simplex1;
1313                                        set<vertex*> t_simplex2;
1314
1315                                        t_simplex1.insert(current_copy1->vertices.begin(),current_copy1->vertices.end());
1316                                        t_simplex2.insert(current_copy2->vertices.begin(),current_copy2->vertices.end());
1317                                       
1318                                        current_copy1->triangulation.push_back(t_simplex1);
1319                                        current_copy2->triangulation.push_back(t_simplex2);                                     
1320                                       
1321                                        // Now we have copied the polyhedron and we have to copy all of its relations. Because we are copying
1322                                        // in the Hasse diagram from bottom up, we always have to copy the parent/child relations to all the
1323                                        // kids and when we do that and know the child, in the child we will remember the parent we came from.
1324                                        // This way all the parents/children relations are saved in both the parent and the child.
1325                                        if(!horiz_ref->kids_rel_addresses.empty())
1326                                        {
1327                                                for(list<int>::iterator kid_ref = horiz_ref->kids_rel_addresses.begin();kid_ref!=horiz_ref->kids_rel_addresses.end();kid_ref++)
1328                                                {       
1329                                                        polyhedron* new_kid1 = new_statistic1->rows[j-1];
1330                                                        polyhedron* new_kid2 = new_statistic2->rows[j-1];
1331
1332                                                        // THIS IS NOT EFFECTIVE: It could be improved by having the list indexed for new_statistic, but
1333                                                        // not indexed for statistic. Hopefully this will not cause a big slowdown - happens only offline.
1334                                                        if(*kid_ref)
1335                                                        {
1336                                                                for(int k = 1;k<=(*kid_ref);k++)
1337                                                                {
1338                                                                        new_kid1=new_kid1->next_poly;
1339                                                                        new_kid2=new_kid2->next_poly;
1340                                                                }
1341                                                        }
1342                                                       
1343                                                        // find the child and save the relation to the parent
1344                                                        current_copy1->children.push_back(new_kid1);
1345                                                        current_copy2->children.push_back(new_kid2);
1346
1347                                                        // in the child save the parents' address
1348                                                        new_kid1->parents.push_back(current_copy1);
1349                                                        new_kid2->parents.push_back(current_copy2);
1350                                                }                                               
1351
1352                                                // Here we clear the parents kids_rel_addresses vector for later use (when we need to widen the
1353                                                // Hasse diagram again)
1354                                                horiz_ref->kids_rel_addresses.clear();
1355                                        }
1356                                        // If there were no children previously, we are copying a polyhedron that has been a vertex before.
1357                                        // In this case it is a segment now and it will have a relation to its mother (copywise) and to the
1358                                        // newly created point. Here we create the connection to the new point, again from both sides.
1359                                        else
1360                                        {
1361                                                // Add the address of the new point in the former vertex
1362                                                current_copy1->children.push_back(new_point1);
1363                                                current_copy2->children.push_back(new_point2);
1364
1365                                                // Add the address of the former vertex in the new point
1366                                                new_point1->parents.push_back(current_copy1);
1367                                                new_point2->parents.push_back(current_copy2);
1368                                        }
1369
1370                                        // Save the mother in its offspring
1371                                        current_copy1->children.push_back(horiz_ref);
1372                                        current_copy2->children.push_back(horiz_ref);
1373
1374                                        // Save the offspring in its mother
1375                                        horiz_ref->parents.push_back(current_copy1);
1376                                        horiz_ref->parents.push_back(current_copy2);   
1377                                                               
1378                                       
1379                                        // Add the copies into the relevant statistic. The statistic will later be appended to the previous
1380                                        // Hasse diagram
1381                                        new_statistic1->append_polyhedron(j,current_copy1);
1382                                        new_statistic2->append_polyhedron(j,current_copy2);
1383                                       
1384                                        // Raise the count in the vector of polyhedrons
1385                                        element_number++;                       
1386                                       
1387                                }
1388                               
1389                        }
1390
1391                        /*
1392                        statistic.begin()->push_back(new_point1);
1393                        statistic.begin()->push_back(new_point2);
1394                        */
1395
1396                        statistic.append_polyhedron(0, new_point1);
1397                        statistic.append_polyhedron(0, new_point2);
1398
1399                        // Merge the new statistics into the old one. This will either be the final statistic or we will
1400                        // reenter the widening loop.
1401                        for(int j=0;j<new_statistic1->size();j++)
1402                        {
1403                                /*
1404                                if(j+1==statistic.size())
1405                                {
1406                                        list<polyhedron*> support;
1407                                        statistic.push_back(support);
1408                                }
1409                               
1410                                (statistic.begin()+j+1)->insert((statistic.begin()+j+1)->end(),new_statistic1[j].begin(),new_statistic1[j].end());
1411                                (statistic.begin()+j+1)->insert((statistic.begin()+j+1)->end(),new_statistic2[j].begin(),new_statistic2[j].end());
1412                                */
1413                                statistic.append_polyhedron(j+1,new_statistic1->rows[j],new_statistic1->row_ends[j]);
1414                                statistic.append_polyhedron(j+1,new_statistic2->rows[j],new_statistic2->row_ends[j]);
1415                        }                       
1416                }
1417
1418                /*
1419                vector<list<toprow*>> toprow_statistic;
1420                int line_count = 0;
1421
1422                for(vector<list<polyhedron*>>::iterator polyhedron_ref = ++statistic.begin(); polyhedron_ref!=statistic.end();polyhedron_ref++)
1423                {
1424                        list<toprow*> support_list;
1425                        toprow_statistic.push_back(support_list);                                               
1426
1427                        for(list<polyhedron*>::iterator polyhedron_ref2 = polyhedron_ref->begin(); polyhedron_ref2 != polyhedron_ref->end(); polyhedron_ref2++)
1428                        {
1429                                toprow* support_top = (toprow*)(*polyhedron_ref2);
1430
1431                                toprow_statistic[line_count].push_back(support_top);
1432                        }
1433
1434                        line_count++;
1435                }*/
1436
1437                /*
1438                vector<int> sizevector;
1439                for(int s = 0;s<statistic.size();s++)
1440                {
1441                        sizevector.push_back(statistic.row_size(s));
1442                }
1443                */
1444               
1445        }
1446
1447
1448       
1449       
1450};
1451
1452/*
1453
1454//! Robust Bayesian AR model for Multicriteria-Laplace-Inverse-Gamma density
1455class RARX : public BM
1456{
1457private:
1458
1459        emlig posterior;
1460
1461public:
1462        RARX():BM()
1463        {
1464        };
1465
1466        void bayes(const itpp::vec &yt, const itpp::vec &cond = empty_vec)
1467        {
1468               
1469        }
1470
1471};*/
1472
1473
1474
1475#endif //TRAGE_H
Note: See TracBrowser for help on using the browser.