close Warning: Can't synchronize with repository "(default)" (/var/svn/mms does not appear to be a Subversion repository.). Look in the Trac log for more information.

Ticket #79: funLinCom.tol

File funLinCom.tol, 9.0 KB (added by irobles, 15 years ago)
Line 
1//////////////////////////////////////////////////////////////////////////////
2Real CheckModel(Set algSetNode)
3//////////////////////////////////////////////////////////////////////////////
4{
5  Text nameOutput = GetNameModel(algSetNode);
6  @MMS.Model model = MMS::GetModel([[nameOutput,GetVersion(?)]]);
7  Set outputs = model::GetOutputs(?);
8  Set EvalSet(outputs, Real (NameBlock output){
9    Serie outputSer = output::GetData(?);
10    Date iniOutput = Max(First(outputSer),output::GetModelBegin(?));
11    Date endOutput = Min(Last(outputSer),output::GetModelEnd(?));
12    Set setExpTerm = output::GetExpTerms(?);
13    Set EvalSet(setExpTerm, Real (NameBlock ET){
14      Serie serExpTerm = ET::GetData(?);
15      Serie subSerExpTerm = SubSer(serExpTerm,iniOutput,endOutput);
16      If(And(
17           AvrS(subSerExpTerm)==0,
18           StDsS(subSerExpTerm)==0,
19           CheckPriorExpTerm(model,ET)==0,
20           CheckHierExpTerm(model,ET)==0
21           )
22        ,
23        ET::SetIsActive(0)
24        ,
25        ET::SetIsActive(1)
26      );
27      Real 1
28    });
29 
30    Real 1
31  });
32
33  Real 1
34       
35};
36//////////////////////////////////////////////////////////////////////////////
37PutDescription("Chequea el modelo. Quita los inputs que son cero",
38CheckModel);
39//////////////////////////////////////////////////////////////////////////////
40
41//////////////////////////////////////////////////////////////////////////////
42Real CheckPriorExpTerm(NameBlock model,NameBlock ET)
43//////////////////////////////////////////////////////////////////////////////
44{
45  Set priors = model::GetPriors(?);
46  If(IsEmpty(priors),0,
47    {
48    Set hasprior = EvalSet(priors, Real (NameBlock prior){
49      //Set setElements = prior::GetElements(?);
50      //Set priorElements = EvalSet(setElements, Real (NameBlock element){
51        //Real (prior::GetElement::GetParent(?)::GetName(?)==ET::GetName(?))
52 
53      //});
54      Real If(prior::GetElement(?)::GetParent(?)::GetName(?)==ET::GetName(?),
55        1,0)
56    });
57 
58    SetSum(hasprior)
59    }
60  )
61       
62};
63//////////////////////////////////////////////////////////////////////////////
64PutDescription("Chequea el modelo.
65Comprueba si un termino explicativo tiene priors",
66CheckPriorExpTerm);
67//////////////////////////////////////////////////////////////////////////////
68
69
70//////////////////////////////////////////////////////////////////////////////
71Real CheckHierExpTerm(NameBlock model,NameBlock ET)
72//////////////////////////////////////////////////////////////////////////////
73{
74  Set hierarchies = model::GetHierarchies(?);
75
76  If(IsEmpty(hierarchies),0,
77    {
78    Set hashierarchie = EvalSet(hierarchies, Real (NameBlock hierarchie){
79      Set setElements = hierarchie::GetElements(?);
80      Set hierarchieElements = EvalSet(setElements, Real (NameBlock element){
81        Real (element::GetParent(?)::GetName(?)==ET::GetName(?))
82 
83      });
84      SetSum(hierarchieElements)
85    });
86 
87    SetSum(hashierarchie)
88    }
89  )     
90};
91//////////////////////////////////////////////////////////////////////////////
92PutDescription("Chequea el modelo.
93Comprueba si un termino explicativo tiene jerarquias",
94CheckHierExpTerm);
95//////////////////////////////////////////////////////////////////////////////
96
97//////////////////////////////////////////////////////////////////////////////
98Real LinComWarning(NameBlock model)
99//////////////////////////////////////////////////////////////////////////////
100{
101  WriteLn("Entrando en lincomwarning");
102  Set outputs = model::GetOutputs(?);
103
104  WriteLn("Cogiendo outputs en lincomwarning");
105
106  Real SetProd(EvalSet(outputs,Real (NameBlock output)
107  {
108    // Para cada output definido en el modelo, sacamos sus fechas de domino,
109    // diferencia y terminos explicativos
110    Serie outputSer = output::GetData(?);
111    WriteLn("Cogiendo datos de outputs en lincomwarning");
112
113    Date iniCalc = Max(First(outputSer),output::GetModelBegin(?));
114    Date endCalc = Min(Last(outputSer),output::GetModelEnd(?));
115    Polyn dif    = output::GetARIMA(?)::GetDif(?);
116    Set expTerms = model::GetExpTerms(?);
117
118    // Para cada término explicativo, miro que sea no nulo, que no tenga prior
119    // y en tal caso devuelvo la serie input, si no lo eliminamos del calculo
120    Set series = EvalSet(expTerms,Serie (NameBlock expTerm)
121    {
122     
123      Serie serExpTerm = expTerm::GetData(?);
124    WriteLn("Cogiendo datos de terminos explicativos en lincomwarning");
125         
126      Serie subSerExpTerm = SubSer(serExpTerm,iniCalc,endCalc);
127      Serie Case(
128        And(Or(
129           CheckPriorExpTerm(model,expTerm)>=1,
130           CheckHierExpTerm(model,expTerm)>=1
131           ),Not(MaxS(subSerExpTerm)==1/0))
132        ,
133        {
134          expTerm::SetIsActive(1);
135          UnknownSerie
136        },
137        Or(And(MaxS(subSerExpTerm)==0,
138           MinS(subSerExpTerm)==0),MaxS(subSerExpTerm)==1/0),
139        {
140          expTerm::SetIsActive(0);
141          UnknownSerie
142        }
143        ,
144        1
145        ,
146        {
147          expTerm::SetIsActive(1);
148          Eval("Serie "+expTerm::GetName(?)+" = subSerExpTerm")
149        }
150      )
151
152    }) - [[ Serie UnknownSerie ]];
153
154
155    // Paso las series input a matriz
156    Matrix inputs = SerSetMat(series);
157    Matrix matrix = inputs*Tra(inputs);
158    Matrix inputs:= UnknownMatrix;//--> Ahorro de memoria en matrices grandes
159
160    // Antes que SVD, llamo a GaussInverse, mucho mas rapida, si devuelve
161    // una matriz de 0x0 entonces es que no tiene inversa (hay combinacion
162    // lineal), y entonces llamo a SVD. Está escrito asi para ahorrar memoria
163
164    Set svd  = {
165      Matrix gaussInv = GaussInverse(matrix);
166      Set svd = If( And(EQ(Rows(gaussInv),0),EQ(Columns(gaussInv),0)),
167        //SVD(matrix),
168        RoundSVD(SVD(matrix),False,0.5,10^(-12)),
169        Empty
170      );
171      Matrix matrix:= UnknownMatrix;//--> Ahorro de memoria en matrices grandes
172      Set svd
173    };
174
175    Real If(Not(Card(svd)), Real False,
176    {
177      // Saco la última columna de la segunda matriz de autovectores
178      Matrix  lastCol = SubCol(svd[3],[[ Columns(svd[3]) ]]);
179      Set svd := Empty;//--> Ahorro de memoria en matrices grandes
180
181      // Miro los elementos no nulos, que son las ecuaciones de los
182      // parametros que hacen c.l.
183      Matrix  LogicLC = Not(Not(lastCol));
184
185      // Transformamos LogicLC en set para buscar
186      Set indices = BinGroup("<<",MatSet(LogicLC));
187
188      // Selecionamos las series con indice no nulo
189      Real c = 0;
190      Set lcw = EvalSet(series,Text (Serie x)
191      {
192        Real c := c+1;
193        Text If(indices[c], Name(x), "")
194      }) - [[ "" ]];
195
196      Text txt2File = TxtListItemQuote(lcw,","+NL);
197
198      // Sacamos los input que tienen combinacion lineal en traza y en fichero
199      // .log, por si lo ejecutas en remoto sin tolbase
200      Text WriteLn("[LinComWarning] THERE ARE "+IntText(Card(lcw))+" LINEAR"
201        +"COMBINATIONS OF INPUT SERIES CHECK LOG DIRECTORY!!"+NL+NL+NL+
202        txt2File+NL+NL+NL,
203        Text "E");
204
205      Set EvalSet(lcw,Real (Text nameParameter){
206        NameBlock expTermPrior = model::GetExpTerm(nameParameter);
207        Set parameterPrior = expTermPrior::GetParameters(?);
208        Set EvalSet(parameterPrior, Real (NameBlock parameterPrior)
209        {
210           Text parameterName = parameterPrior::GetIndex(?);
211           Real model::CreatePrior(
212            [[
213              Text _.element = parameterName;
214              Real _.average = 0;
215              Real _.sigma = 10
216            ]]
217            )
218        });
219        Real 1
220      });
221
222      Text logRoute = PathProject+"log/lincom/lincom_"+
223        model::GetName(?)+
224        FormatDate(Now) +".log";
225
226      Text WriteFile(logRoute,txt2File);
227
228      Real 1//Stop
229    })
230  }))
231};
232//////////////////////////////////////////////////////////////////////////////
233PutDescription("Combprueba si existen combinaciones lineales en la estrategia
234 que recibe como argumento",
235LinComWarning);
236//////////////////////////////////////////////////////////////////////////////
237
238
239//////////////////////////////////////////////////////////////////////////////
240Set RoundSVD(Set svd,Real trasposed, Real minSparse, Real tolerance)
241//////////////////////////////////////////////////////////////////////////////
242{/*
243Set svd = SVD(matrix);
244Real trasposed = False;
245Real minSparse = 0.5;
246Real tolerance = 10^(-12);
247*/
248  Set EvalSet(svd,Matrix (Matrix matrix)
249  {
250    VMatrix vmatrix = Mat2VMat(
251      matrix,     // matrix to transform
252      trasposed,  // does it trasposed?
253      minSparse,  // minSparse
254      tolerance); // tolerance
255                             
256    Matrix VMat2Mat(vmatrix) 
257  })
258};
259//////////////////////////////////////////////////////////////////////////////
260PutDescription("It rounds an exit of SVD function to avoid negligible values.
261It needs:
262  matrix     --> matrix to transform
263  trasposed  --> does it trasposed? (True or False)
264  minSparse  --> minSparse use 0.5 by default
265  tolerance  --> round use 10^(-10) by default
266",
267RoundSVD);
268//////////////////////////////////////////////////////////////////////////////