EMMA Coverage Report (generated Wed Sep 07 21:54:19 EEST 2005)
[all classes][PIANOS.generator]

COVERAGE SUMMARY FOR SOURCE FILE [Acceptation.java]

nameclass, %method, %block, %line, %
Acceptation.java100% (1/1)95%  (18/19)89%  (3877/4354)93%  (651,5/702)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Acceptation100% (1/1)95%  (18/19)89%  (3877/4354)93%  (651,5/702)
Acceptation (): void 0%   (0/1)0%   (0/3)0%   (0/1)
generateLikelihoodFormulaGlobal (Variable, Set): ArrayList 100% (1/1)70%  (118/169)79%  (23/29)
generateLikelihoodFormulaTwoDimensional (Variable, Set, boolean): ArrayList 100% (1/1)73%  (270/371)77%  (42,5/55)
<static initializer> 100% (1/1)75%  (6/8)75%  (0,8/1)
generateLikelihoodFormulaOneDimensional (Variable, Set): ArrayList 100% (1/1)76%  (145/191)80%  (26,3/33)
generateSpatialDeps (Variable, String, boolean): ArrayList 100% (1/1)77%  (186/243)78%  (25/32)
generateAcceptationFormula (Variable): ArrayList 100% (1/1)78%  (29/37)89%  (6,2/7)
topologicalSort (ArrayList): ArrayList 100% (1/1)79%  (15/19)88%  (3,5/4)
generateAcceptationFormulaOneDimensional (Variable): ArrayList 100% (1/1)83%  (373/447)94%  (63/67)
generateAcceptationFormulaTwoDimensional (Variable): ArrayList 100% (1/1)86%  (342/400)94%  (55,6/59)
generateUpdateOneFunctional (Variable): ArrayList 100% (1/1)93%  (54/58)96%  (9,6/10)
generateNewValueCode (Variable): ArrayList 100% (1/1)94%  (176/188)95%  (21,9/23)
generateTransitionFormula (Variable): ArrayList 100% (1/1)96%  (347/362)98%  (62/63)
generateAcceptationCode (Variable, String): ArrayList 100% (1/1)96%  (658/685)96%  (125,8/131)
generateNewValueForOneFunctional (Variable, Set): ArrayList 100% (1/1)96%  (297/309)98%  (41/42)
generateAcceptationFormulaGlobal (Variable): ArrayList 100% (1/1)99%  (340/343)99%  (56,5/57)
acceptationAffectedOf (Variable, Variable): ArrayList 100% (1/1)100% (200/200)100% (32/32)
generateNewValuesFunctionalCode (Variable): ArrayList 100% (1/1)100% (315/315)100% (55/55)
setTopologicalList (ArrayList): void 100% (1/1)100% (6/6)100% (2/2)

1package PIANOS.generator;
2 
3import PIANOS.datastructures.*;
4import PIANOS.exceptions.*;
5import PIANOS.io.*;
6 
7import java.util.*;
8import java.io.*;
9 
10/**
11 * Generates calculations needed when generating the Fortarn module "main".
12 */
13public class Acceptation {
14    
15    private static ArrayList<Variable> topologicalList;
16    
17    /**
18     * Sets the topological variable list that is used when calculating the correct
19     * new-value-generation order for functional parameters. This method must be called before any
20     * other methods of this class are called.
21     *
22     * @param  list A list of all variables in the current model in topolocial order.
23     */
24    public static void setTopologicalList(ArrayList<Variable> list) {
25        // This method has to be called before any other methods!
26        topologicalList = new ArrayList<Variable>(list);
27    }
28    
29    
30    /**
31     * Generates code that fetches a proposed new value for a parameter from its buffer or if the buffer
32     * is empty, calls the subroutine "generate".
33     *
34     * @param  variable A parameter for which the new value code is generated.We assume that it
35     * is indexed by "one_dim(1)" if it is global, by "one_dim(i)" if it is one-dimensional and by
36     * "two_dim(i, j)" if it is two-dimensional.
37     */
38    public static ArrayList<String> generateNewValueCode(Variable variable) {
39        ArrayList<String> result=new ArrayList<String>();
40        
41        assert variable.isFunctional() == false;
42        assert variable.isData() == false || variable.getMissingValueCount() > 0;
43        
44        String name = variable.getName();
45        result.add("IF (" + name + " % buffer_index > SIZE(" + name + " % buffer) .OR. " + name + " % buffer_index < 1) THEN");
46        result.add("CALL generate('" + name + "', " + name + " % buffer)");
47        result.add(name + " % buffer_index = 1");
48        result.add("END IF");
49        result.add("");
50        
51        String indexing="";
52        if (variable.getEntity() == null) {
53            indexing = "one_dim(1)";
54        } else if (variable.getEntity().isMatrix() == false) {
55            indexing = "one_dim(i)";
56        } else {
57            indexing = "two_dim(i, j)";
58        }
59        
60        assert variable.getStrategy() != null;
61        if (variable.getStrategy().equals("random walk")) {
62            result.add(name + " % " + indexing + " % new_value = " + name + " % " + indexing + " % value + "
63                    + name + " % buffer(" + name + " % buffer_index)");
64        } else {
65            result.add(name + " % " + indexing + " % new_value = " + name + " % buffer(" + name + " % buffer_index)");
66        }
67        
68        result.add(name + " % buffer_index = " + name +" % buffer_index + 1");
69        
70        return result;
71    }
72    
73    
74    /**
75     * Generates code that decides whether the new value is accepted and makes the necessary
76     * changes: updates the value of the current parameter and all functional parameters depending
77     * on it.
78     *
79     * @param  variable A parameter for which the acceptation code is generated. We assume that it
80     * is indexed by "one_dim(1)" if it is global, by "one_dim(i)" if it is one-dimensional and by
81     * "two_dim(i, j)" if it is two-dimensional.
82     */
83    public static ArrayList<String> generateAcceptationCode(Variable variable, String strategy) throws InvalidModelException{
84        
85        assert variable.isFunctional() == false;
86        assert variable.isData() == false || variable.getMissingValueCount() > 0;
87        
88        ArrayList<String> result=new ArrayList<String>();
89        
90        String name = variable.getName();
91        
92        String indexing="";
93        if (variable.getEntity() == null) {
94            indexing = "one_dim(1)";
95        } else if (variable.getEntity().isMatrix() == false) {
96            indexing = "one_dim(i)";
97        } else {
98            indexing = "two_dim(i, j)";
99        }
100        
101        result.add("IF (p_acc > prob(prob_index)) THEN");
102        result.add(name + " % " + indexing + " % value = " + name + " % " + indexing + " % new_value");
103        result.add(name + " % " + indexing + " % successful_changes = " + name +" % " + indexing +
104                " % successful_changes + 1");
105        result.add("");
106        if (strategy.equals("random")){
107            result.add("IF ("+ name +" % "+ indexing +" % successful_changes == "+
108                    name +" % "+ indexing +" % update_count) THEN");
109            result.add("parameters_achieved = parameters_achieved + 1");
110            result.add("END IF");
111        }
112        // here we must update all the functionals depending on variable
113        // like blah % value = blah % new value
114        // problem: spatial case! (we need to _calculate_ the new value)
115        
116        // 1) functional, non-spatial
117        ArrayList<Variable> allAffected = new ArrayList<Variable>(variable.getAffectsList());
118        for (int i=0; i<allAffected.size(); i++) {
119            Variable depending = allAffected.get(i);
120            
121            if (!depending.isFunctional())
122                continue;
123            if(depending.isSpatial())
124                continue;
125            
126            allAffected.addAll(depending.getAffectsList());
127            
128            LinkedList<Variable> depdeps = depending.getDependsList();
129            
130            boolean spatialDependencies = false;
131            for (Variable depdep : depdeps){
132                if (depdep.isSpatial() && allAffected.contains(depdep))
133                    spatialDependencies = true;
134            }
135            
136            // code for depending...
137            if (spatialDependencies == false) {
138                result.addAll(acceptationAffectedOf(variable, depending));
139            }
140            
141        }
142        
143        // 2) functional, spatial
144        // Here we update the spatial parameters of _neighbour_squares_ by using the new value of
145        // the current variable of the current square.
146        
147        allAffected = new ArrayList<Variable>(variable.getAffectsList());
148        for (int i=0; i<allAffected.size(); i++) {
149            Variable depending = allAffected.get(i);
150            
151            if (!depending.isFunctional())
152                continue;
153            LinkedList<Variable> depdeps = depending.getDependsList();
154            
155            boolean spatialDependencies = false;
156            for (Variable depdep : depdeps){
157                if (depdep.isSpatial() && allAffected.contains(depdep))
158                    spatialDependencies = true;
159            }
160            
161            /* now, if this variable (depending) has spatial dependencies:
162             * 1. depending is not spatial. (spatial variables have only one non-spatial dep)
163             * 2. depending has not been updated yet in the previous loop.
164             * 3. the spatial dependencies of depending have their new values calculated
165             *    previously in this loop.
166             * So we can safely update it as we did before
167             * (and the path of other functionals leading from it)
168             * TROUBLE. If this depending is affected by a global, we must add loops and
169             * we shouldn't even be doing this neighbour-thing.
170             * How to recognize that the new value for depending has been already calculated
171             * while considering this global? ... Maybe we should look at the dependsList of depending.
172             * not really. Just checking that variable.getEntity() == null should suffice.
173             * IS IT ALWAYS like this? can we always skip the neighbouring process with variables
174             * that are global?
175             */
176            
177            
178            if (spatialDependencies){
179                if (variable.getEntity() == null){
180                    result.addAll(acceptationAffectedOf(variable, depending)); 
181                } else{
182                    boolean spatialY;
183                    if (depending.getEntity().isMatrix() == false){
184                        indexing = " % one_dim(neighbour)";
185                        spatialY = true;
186                    } else{
187                        if (depending.getEntity().getXCoordinate().isSpatial()){
188                            indexing = " % two_dim(i, neighbour)";
189                            spatialY = false;
190                        } else{
191                            indexing = " % two_dim(neighbour, j)";
192                            spatialY = true;
193                        }
194                    }   
195 
196                    if (spatialY){
197                        result.add("DO k = 1, spatial(i, 1)");
198                        result.add("neighbour = spatial(i,  k +1)");
199                    } else{
200                        result.add("DO k = 1, spatial(j, 1)");
201                        result.add("neighbour = spatial(j,  k +1)");
202                    }
203                        
204                    result.addAll(generateSpatialDeps(depending, indexing, spatialY));
205                    result.add("END DO");
206                        
207                        
208                 
209                } // end of not global variable
210            } // end of spatial deps
211            if(!depending.isSpatial()) // updated already
212                continue;
213            
214            for (Variable affected: depending.getAffectsList()){
215                if (!allAffected.contains(affected))
216                    allAffected.add(affected);
217            }
218            
219            // adding further forks...
220            // Spatial variables are direct, but the functionals
221            // that depend on them have not been updated yet.
222            
223            /* ok, now update the spatial variable.
224             * it's either COUNT(&variable)
225             * or SUM(&variable)
226             * (since it depends on variable)
227             */
228            String depname = depending.getName();
229            
230            String[] depEquation = depending.getEquation().getEquation();
231            boolean sum = false;
232            if (depEquation[0].startsWith("SUM"))
233                sum = true;
234            else
235                continue;
236            // count stays the same, squares don't get shot even if birds do :-)
237            
238            if (variable.getEntity().isMatrix() == false &&
239                    depending.getEntity().isMatrix() == false) {
240                // one-dim affecting an one-dim spatial, possible
241                
242                
243                result.add("! 1 to number of neighbours");
244                result.add("DO k = 1, spatial(i, 1)");
245                if (variable.isInteger())
246                    result.add("sum_int = 0");
247                else
248                    result.add("sum_real = 0");
249                result.add("neighbour = spatial(i, k + 1)");
250                result.add("! updating " + depname + " % one_dim(spatial(i, k + 1))");
251                result.add("DO h = 1, spatial(neighbour, 1)"); // neighbours of neighbour
252                if (variable.isInteger())
253                    result.add("sum_int = sum_int + "+ name +" % one_dim(spatial(neighbour, h + 1)) % value");
254                else
255                    result.add("sum_real = sum_real + "+ name +" % one_dim(spatial(neighbour, h + 1)) % value");
256                
257                result.add("END DO");
258                if (variable.isInteger())
259                    result.add(depname + " % one_dim(neighbour) % value = sum_int");
260                else
261                    result.add(depname + " % one_dim(neighbour) % value = sum_real");
262                result.add("END DO");
263                
264            } else if (variable.getEntity().isMatrix() == false &&
265                    depending.getEntity().isMatrix() == true) {
266                // one-dim affecting a two-dim spatial, impossible?
267                throw new InvalidModelException("Acceptation: A one-dim variable is affecting a two-dim spatial!");
268                
269            } else {
270                
271                // both 2-dimensional, possible (the same entity)
272                // two dimensional sum case...
273                // when variable and dep have the same number of dimensions
274                
275                String correct_sum = "";
276                if (variable.isInteger()) {
277                    correct_sum = "sum_int";
278                } else correct_sum = "sum_real";
279                if (variable.getEntity().getYCoordinate().isSpatial()){
280                    result.add("! 1 to number of neighbours");
281                    result.add("DO k = 1, spatial(i, 1)");
282                    result.add(correct_sum + " = 0");
283                    result.add("neighbour = spatial(i, k + 1)");
284                    result.add("! updating " + depname + " % two_dim(spatial(i, k + 1), j)");
285                    result.add("DO h = 1, spatial(neighbour, 1)"); // neighbours of neighbour
286                    result.add(correct_sum + " = " + correct_sum + " + " + name + " % two_dim(spatial(neighbour, h + 1), j) % value");
287                    result.add("END DO");
288                    result.add(depname + " % two_dim(neighbour, j) % value = " + correct_sum);
289                    result.add("END DO");
290                } else{
291                    result.add("! 1 to number of neighbours");
292                    result.add("DO k = 1, spatial(j, 1)");
293                    result.add(correct_sum + " = 0");
294                    result.add("neighbour = spatial(j, k + 1)");
295                    result.add("! updating " + depname + " % two_dim(i, spatial(j, k + 1))");
296                    result.add("DO h = 1, spatial(neighbour, 1)"); // neighbours of neighbour
297                    result.add(correct_sum + " = " + correct_sum + " + " + name + " % two_dim(i, spatial(neighbour, h + 1)) % value");
298                    result.add("END DO");
299                    result.add(depname + " % two_dim(i, neighbour) % value = " + correct_sum);
300                    result.add("END DO");
301                    
302                }
303            }
304        }
305        
306        
307        
308        
309        result.add("END IF");
310        result.add("prob_index = prob_index + 1");
311        result.add("IF (prob_index > SIZE(prob) .OR. prob_index < 1) THEN");
312        result.add("CALL G05FAF(0.0_dp, 1.0_dp, SIZE(prob), prob)");
313        result.add("prob_index = 1");
314        result.add("END IF");
315        
316        return result;
317    }
318    
319    /**
320     * Sets correct indexing for functional variables with
321     * spatial dependencies. Used for updating neighbouring square functional properties after
322     * the spatial functional variable target has been updated.
323     * For example: q = sum(&x) and p = q/2.0.
324     * When x is updated (the spatial target)
325     * first q is calculated for all neighbours of x,
326     * then all neighbours of x get a new p to match their new q values.
327     */
328    
329    private static ArrayList<String> generateSpatialDeps(Variable functional, String indexing, boolean spatialY){
330        ArrayList<String> result = new ArrayList<String>();
331        String[] equation = functional.getEquation().getEquation();
332        
333        
334        Variable[] parameters = functional.getEquation().getParameters();
335        
336        
337        // DEBUG
338        /*
339        System.out.println("GENERATOR DEBUG: generateSpatialDeps for " + functional.getName());
340        System.out.print("newToBeUsed contains:");
341        for (Variable n : newToBeUsed){
342            System.out.print(n.getName() + " ");
343        }
344        System.out.println();
345         */
346        
347        // check the equation of depending
348        for (int i=0; i<parameters.length; i++) {
349            // dealing with Variable parameters[i]
350            
351            //System.out.println("GENERATOR DEBUG: dealing with " + parameters[i].getName());
352            if (parameters[i].getEntity() == null) { // global
353                for (int j=0; j<equation.length; j++) {
354                    if (equation[j].equals(parameters[i].getName())) {
355                        equation[j] += " % one_dim(1) % value";
356                    }
357                } // end looping the equation
358            } else if (parameters[i].getEntity().isMatrix() == false) { // one-dimensional
359                if (parameters[i].getEntity().equals(functional.getEntity().getXCoordinate())) {
360                    for (int j=0; j<equation.length; j++) {
361                        if (equation[j].equals(parameters[i].getName())) {
362                            if (spatialY)
363                                equation[j] += " % one_dim(j) % value";
364                            else
365                                equation[j] += " % one_dim(neighbour) % value";
366                        }
367                    } // end looping the equation
368                } else { // either the same entity or equals y-coordinate
369                    for (int j=0; j<equation.length; j++) {
370                        if (equation[j].equals(parameters[i].getName())) {
371                            if (spatialY)
372                                equation[j] += " % one_dim(neighbour) % value";
373                            else
374                                equation[j] += " % one_dim(i) % value";
375                        }
376                    } // end looping the equation
377                }
378                
379            } else { // two-dimensional
380                for (int j=0; j<equation.length; j++) {
381                    if (equation[j].equals(parameters[i].getName())) {
382                        if (spatialY)
383                            equation[j] += " % two_dim(neighbour, j) % value";
384                        else
385                            equation[j] += " % two_dim(i, neighbour) % value";
386                    }
387                } // end looping the equation
388            }
389        } // end looping the parameters[]
390        
391        String finalEquation = "";
392        for (int k=0; k<equation.length; k++) {
393            finalEquation = finalEquation + equation[k];
394        }
395        
396        result.add(functional.getName() + indexing + " % value = " + finalEquation);
397        
398        return result;
399        
400    }
401    
402    private static ArrayList<String> acceptationAffectedOf(Variable variable, Variable depending){
403        ArrayList<String> result = new ArrayList<String>();
404        if (variable.getEntity() == null && depending.getEntity() == null) {
405            result.addAll(generateUpdateOneFunctional(depending));
406        } else if (variable.getEntity() == null &&
407                depending.getEntity().isMatrix() == false) {
408            result.add("DO i2 = 1, " + depending.getEntity().getSize());
409            result.addAll(generateUpdateOneFunctional(depending));
410            result.add("END DO");
411        } else if (variable.getEntity() == null &&
412                depending.getEntity().isMatrix()) {
413            result.add("DO i2 = 1, " + depending.getEntity().getYCoordinate().getSize());
414            result.add("DO j2 = 1, " + depending.getEntity().getXCoordinate().getSize());
415            result.addAll(generateUpdateOneFunctional(depending));
416            result.add("END DO");
417            result.add("END DO");
418        } else if (variable.getEntity().isMatrix() == false &&
419                depending.getEntity().isMatrix() == false) {
420            result.add("i2 = i");
421            result.addAll(generateUpdateOneFunctional(depending));
422        } else if (variable.getEntity().isMatrix() == false &&
423                depending.getEntity().isMatrix() == true) {
424            if (variable.getEntity().equals(depending.getEntity().getYCoordinate())) {
425                result.add("i2 = i");
426                result.add("DO j2 = 1, " +
427                        depending.getEntity().getXCoordinate().getSize());
428                result.addAll(generateUpdateOneFunctional(depending));
429                result.add("END DO");
430            } else {
431                result.add("j2 = i");
432                result.add("DO i2 = 1, " +
433                        depending.getEntity().getYCoordinate().getSize());
434                result.addAll(generateUpdateOneFunctional(depending));
435                result.add("END DO");
436            }
437        } else {
438            result.add("i2 = i");
439            result.add("j2 = j");
440            result.addAll(generateUpdateOneFunctional(depending));
441        }
442        return result;
443    }
444    
445    private static ArrayList<String> generateUpdateOneFunctional(Variable depending) {
446        
447        // This generates the code that replaces the value by new_value for one particular variable
448        
449        // depending is indexed: (1), (i) or (i2, j2).
450        
451        assert depending.isFunctional() == true;
452        
453        ArrayList<String> result=new ArrayList<String>();
454        String indexing = "";
455        
456        if (depending.getEntity() == null) {
457            indexing = "one_dim(1)";
458        } else if (depending.getEntity().isMatrix() == false){
459            indexing = "one_dim(i2)";
460        } else indexing = "two_dim(i2, j2)";
461        
462        result.add(depending.getName() + " % " + indexing + " % value = " +
463                depending.getName() + " % " + indexing + " % new_value");
464        
465        return result;
466        
467    }
468    
469    
470    private static ArrayList<Variable> topologicalSort(ArrayList<Variable> sortThis) {
471        // This method sorts the list sortThis topologically.
472        // We assume that the variables are introduced in topological order in the model specification.
473        assert topologicalList != null;
474        
475        ArrayList<Variable> result = new ArrayList<Variable>(topologicalList);
476        result.retainAll(sortThis);
477        return result;
478    }
479    
480    private static ArrayList<String> generateNewValueForOneFunctional(Variable functional,
481            Set<Variable> newToBeUsed) throws InvalidModelException {
482        // this is a different approach to generateNewValuesFunctionalCode
483        
484        // We assume that functional is indexed by one_dim(1), one_dim(i2) or two_dim(i2, j2)
485        // and generate the code that calculates the new value and places it to new_value.
486        
487        // Note that the spatial functional parameters don't need new values here, so this method is not called.
488        
489        ArrayList<String> result = new ArrayList<String>();
490        
491        //String[] equation = functional.getEquation().getEquation(); A BUG!
492        
493        String[] equation = functional.getEquation().getEquation();
494        
495        /* the equation in parts: for example:
496        3 * alpha + EXP(beta+gamma) ->
497        3 *
498        alpha
499        + EXP(
500        beta
501        +
502        gamma
503        )
504         */
505        
506        Variable[] parameters = functional.getEquation().getParameters();
507        
508        
509        // DEBUG
510        /*
511        System.out.println("GENERATOR DEBUG: generateNewValueForOneFunctional for " + functional.getName());
512        System.out.print("newToBeUsed contains:");
513        for (Variable n : newToBeUsed){
514            System.out.print(n.getName() + " ");
515        }
516        System.out.println();
517         */
518        
519        //result.add("! DEBUG: a mysterious bug resides here somewhere.");
520        // check the equation of depending
521        for (int i=0; i<parameters.length; i++) {
522            // dealing with Variable parameters[i]
523            
524            //System.out.println("GENERATOR DEBUG: dealing with " + parameters[i].getName());
525            if (parameters[i].getEntity() == null) { // global
526                for (int j=0; j<equation.length; j++) {
527                    if (equation[j].equals(parameters[i].getName())) {
528                        if (newToBeUsed.contains(parameters[i])) {
529                            //System.out.println("here 1");
530                            equation[j] += " % one_dim(1) % new_value";
531                        } else {
532                            //System.out.println("here 2");
533                            equation[j] += " % one_dim(1) % value";
534                        }
535                    }
536                } // end looping the equation
537            } else if (parameters[i].getEntity().isMatrix() == false) { // one-dimensional
538                if (parameters[i].getEntity().equals(functional.getEntity().getXCoordinate())) {
539                    for (int j=0; j<equation.length; j++) {
540                        if (equation[j].equals(parameters[i].getName())) {
541                            if (newToBeUsed.contains(parameters[i])) {
542                                //System.out.println("here 3");
543                                equation[j] += " % one_dim(j2) % new_value";
544                            } else {
545                                //System.out.println("here 4");
546                                equation[j] += " % one_dim(j2) % value";
547                            }
548                        }
549                    } // end looping the equation
550                } else { // either the same entity or equals y-coordinate
551                    for (int j=0; j<equation.length; j++) {
552                        if (equation[j].equals(parameters[i].getName())) {
553                            if (newToBeUsed.contains(parameters[i])) {
554                                //System.out.println("here 5");
555                                equation[j] += " % one_dim(i2) % new_value";
556                            } else {
557                                //System.out.println("here 6");
558                                equation[j] += " % one_dim(i2) % value";
559                            }
560                        }
561                    } // end looping the equation
562                }
563                
564            } else { // two-dimensional
565                for (int j=0; j<equation.length; j++) {
566                    if (equation[j].equals(parameters[i].getName())) {
567                        if (newToBeUsed.contains(parameters[i])) {
568                            //System.out.println("here 7");
569                            equation[j] += " % two_dim(i2, j2) % new_value";
570                        } else {
571                            //System.out.println("here 8");
572                            equation[j] += " % two_dim(i2, j2) % value";
573                        }
574                    }
575                } // end looping the equation
576            }
577        } // end looping the parameters[]
578        
579        String finalEquation = "";
580        for (int k=0; k<equation.length; k++) {
581            finalEquation = finalEquation + equation[k];
582        }
583        
584        if (functional.getEntity() == null) {
585            result.add(functional.getName() + " % one_dim(1) % new_value = " + finalEquation);
586        } else if (functional.getEntity().isMatrix() == false) {
587            result.add(functional.getName() + " % one_dim(i2) % new_value = " + finalEquation);
588        } else result.add(functional.getName() + " % two_dim(i2, j2) % new_value = " + finalEquation);
589        
590        return result;
591    }
592    
593    /**
594     * Generates code that calculates new values for all the functional parameters depending on
595     * the current parameter.
596     *
597     * @param  variable The current parameter. We assume that it
598     * is indexed by "one_dim(1)" if it is global, by "one_dim(i)" if it is one-dimensional and by
599     * "two_dim(i, j)" if it is two-dimensional. Note that the new values for "SUM"-parameters are
600     * not calculated here.
601     */
602    public static ArrayList<String> generateNewValuesFunctionalCode(Variable variable)
603    throws InvalidModelException {
604        
605        ArrayList<String> result = new ArrayList<String>();
606        ArrayList<Variable> allAffected = new ArrayList<Variable>(variable.getAffectsList());
607        Set<Variable> newToBeUsed = new HashSet<Variable>();
608        newToBeUsed.add(variable);
609        
610        //System.out.println("GENERATOR DEBUG: generateNewValuesFunctionalCode for " + variable.getName());
611        
612        for (int iterator = 0; iterator < allAffected.size(); iterator++) {
613            Variable depending = allAffected.get(iterator);
614            
615            //System.out.println("GENERATOR DEBUG: depending (phase 1) is : " + depending.getName());
616            // not functional
617            if (depending.isFunctional() == false) continue;
618            
619            // the spatial parameters won't need new values here and no new dependencies are added
620            if (depending.isSpatial() == true) continue;
621            
622            // add further affected variables to all_depending
623            allAffected.addAll(depending.getAffectsList());
624            newToBeUsed.add(depending);
625        }
626        
627        // DEBUG
628        /*
629        if (allAffected == null) {
630            System.out.println("GENERATOR DEBUG: allAffected is null.");
631        }*/
632        
633        allAffected = topologicalSort(allAffected);
634        
635        for (int iterator = 0; iterator < allAffected.size(); iterator++) {
636            
637            Variable depending = allAffected.get(iterator);
638            
639            //System.out.println("GENERATOR DEBUG: depending (phase 2) is : " + depending.getName());
640            
641            // not functional
642            if (depending.isFunctional() == false) continue;
643            if (depending.isSpatial()) continue; // we don't need to calculate new values for them
644            
645            result.add("");
646            result.add("! calculating new value(s) for " + depending.getName());
647            result.add("");
648            
649            if (variable.getEntity() == null && depending.getEntity() == null) {
650                // no loops
651                result.addAll(generateNewValueForOneFunctional(depending, newToBeUsed));
652                return result;
653            }
654            
655            if (variable.getEntity() == null && depending.getEntity().isMatrix() == false){
656                // one loop
657                result.add("DO i2 = 1, " + depending.getEntity().getSize());
658                result.addAll(generateNewValueForOneFunctional(depending, newToBeUsed));
659                result.add("END DO");
660                return result;
661            }
662            
663            if (variable.getEntity() == null && depending.getEntity().isMatrix() == true) {
664                // two loops
665                result.add("DO i2 = 1, " + depending.getEntity().getYCoordinate().getSize());
666                result.add("DO j2 = 1, " + depending.getEntity().getXCoordinate().getSize());
667                result.addAll(generateNewValueForOneFunctional(depending, newToBeUsed));
668                result.add("END DO");
669                result.add("END DO");
670                return result;
671            }
672            
673            if (variable.getEntity().isMatrix() == false && depending.getEntity().isMatrix() == false) {
674                // no loops
675                result.add("i2 = i");
676                result.addAll(generateNewValueForOneFunctional(depending, newToBeUsed));
677                return result;
678            }
679            
680            if (variable.getEntity().isMatrix() == false && depending.getEntity().isMatrix() == true) {
681                // one loop
682                if (variable.getEntity().equals(depending.getEntity().getYCoordinate())) {
683                    result.add("i2 = i");
684                    result.add("DO j2 = 1, " + depending.getEntity().getXCoordinate().getSize());
685                    result.addAll(generateNewValueForOneFunctional(depending, newToBeUsed));
686                    result.add("END DO");
687                    return result;
688                } else {
689                    result.add("j2 = i");
690                    result.add("DO i2 = 1, " + depending.getEntity().getYCoordinate().getSize());
691                    result.addAll(generateNewValueForOneFunctional(depending, newToBeUsed));
692                    result.add("END DO");
693                    return result;
694                }
695            }
696            
697            if (variable.getEntity().isMatrix() == true && depending.getEntity().isMatrix() == true) {
698                // no loops
699                result.add("i2 = i");
700                result.add("j2 = j");
701                result.addAll(generateNewValueForOneFunctional(depending, newToBeUsed));
702                return result;
703            }
704        }
705        
706        return result;
707    }
708    
709    
710    /**
711     * Generates code that calculates the acceptance probability for the current parameter.
712     *
713     * @param  variable The current parameter. We assume that it
714     * is indexed by "one_dim(1)" if it is global, by "one_dim(i)" if it is one-dimensional and by
715     * "two_dim(i, j)" if it is two-dimensional.
716     */
717    public static ArrayList<String> generateAcceptationFormula(Variable variable)
718    throws InvalidModelException, IllegalParametersException, MissingFunctionException {
719        
720        /* The idea:
721         
722        1. probability for this parameter
723        2. probabilities for all affected variables
724        3. q-probabilities.
725         
726        Note: This method DOES NOT generate:
727        - the loops (acceptation for all x's for example)
728        - generating proposals
729        - acceptation
730        - updating functional parameters
731        or anything like that.
732         */
733        
734        assert variable.isFunctional() == false;
735        assert variable.isData() == false || variable.getMissingValueCount() > 0;
736        
737        if (variable.getEntity() == null) {
738            return generateAcceptationFormulaGlobal(variable);
739        } else if (variable.getEntity().isMatrix() == false) {
740            return generateAcceptationFormulaOneDimensional(variable);
741        } else {
742            return generateAcceptationFormulaTwoDimensional(variable);
743        }
744        
745    }
746    
747    private static ArrayList<String> generateAcceptationFormulaGlobal(Variable variable)
748    throws InvalidModelException, IllegalParametersException, MissingFunctionException {
749        
750        //System.out.println("GENERATOR DEBUG: generateAcceptationFormulaGlobal");
751        /*
752          This variable is global.
753          It is indexed like variable % one_dim(1).
754         
755          All affecting variables must also be global.
756         */
757        
758        ArrayList<String> result = new ArrayList<String>();
759        
760        int parameterCount = variable.getDistribution().getNumberOfParameters();
761        
762        String[] indices = new String[parameterCount+2];
763        
764        // 1. P(variable') / P(variable)
765        
766        // DEBUG
767        //System.out.println("GENERATOR DEBUG: 1. P(" + variable.getName() + "') / P(" + variable.getName() + ")");
768        
769        result.add("");
770        result.add("!  P(" + variable.getName() + "') / P(" + variable.getName() + ")");
771        result.add("");
772        
773        result.add("p_acc = 1");
774        
775        for (int i=0; i<parameterCount; i++) {
776            Object parameter = variable.getDistribution().getParameter(i);
777            
778            if (parameter instanceof Integer) {
779                indices[i] = ((Integer)parameter).toString();
780                continue;
781            } else if (parameter instanceof Double) {
782                // we must add _dp to the real constants
783                indices[i] = ((Double)parameter).toString()+"_dp";
784                continue;
785            }
786            // now we know that the parameter is a Variable.
787            
788            Variable varParameter=(Variable)parameter;
789            // it must be global
790            indices[i] = varParameter.getName()+" % one_dim(1) % value";
791        }
792        indices[parameterCount] = variable.getName() + " % one_dim(1) % new_value";
793        indices[parameterCount+1] = "new_frequency";
794        
795        // P(variable')
796        
797        // DEBUG
798        /*
799          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
800          for (int print=0; print<indices.length; print++)
801          {
802          System.out.println(indices[print]);
803          }
804         */
805        
806        ArrayList<String> toAdd=variable.getDistribution().getFreqCode(indices);
807        result.addAll(toAdd);
808        
809        indices[parameterCount] = variable.getName() + " % one_dim(1) % value";
810        indices[parameterCount+1] = "frequency";
811        
812        // P(variable)
813        
814        // DEBUG
815        /*
816          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
817          for (int print=0; print<indices.length; print++)
818          {
819          System.out.println(indices[print]);
820          }
821         */
822        
823        toAdd=variable.getDistribution().getFreqCode(indices);
824        result.addAll(toAdd);
825        
826        result.add("p_acc = p_acc * new_frequency / frequency");
827        
828        // 2) P(x | variable') / P(x | variable) for all x that depend on variable
829        
830        // DEBUG
831        /*
832          System.out.println("GENERATOR DEBUG: Phase 2. P( depending | " + variable.getName() +
833          ") / P( depending | " + variable.getName() + "')");
834         */
835        
836        ArrayList<Variable> allAffected = new ArrayList<Variable>(variable.getAffectsList());
837        Set<Variable> newToBeUsed = new HashSet<Variable>();
838        newToBeUsed.add(variable);
839        
840        Set<Variable> handledAlready = new HashSet<Variable>();
841 
842        for (int iterator = 0; iterator < allAffected.size(); iterator++) {
843            Variable depending = allAffected.get(iterator);
844            
845            if (depending.isSpatial()) continue;
846            
847            // functional but not spatial
848            if (depending.isFunctional()) {
849                // add further affected variables to all_depending
850                allAffected.addAll(depending.getAffectsList());
851                newToBeUsed.add(depending);
852                continue;
853            }
854 
855            if (depending.equals(variable)) continue; // no loops please
856            
857            // not functional
858            
859            // DEBUG
860            /*
861            System.out.println("GENERATOR DEBUG: Phase 2, in detail: P( " + depending.getName() + " | "
862                + variable.getName() + "') / P( " + depending.getName() + " | " + variable.getName() + ")");
863             */
864            
865            if (handledAlready.contains(depending)) continue; // no duplicates
866 
867            result.add("");
868            result.add("! P( " + depending.getName() + " | "
869                    + variable.getName() + "') / P( " + depending.getName() + " | " + variable.getName() + ")");
870            result.add("");
871 
872            handledAlready.add(depending);
873            
874            // now variable is global, so depending may be global, one-dimensional or two-dimensional
875            
876            if (depending.getEntity() == null) {
877                // depending is global
878                result.addAll(generateLikelihoodFormulaGlobal(depending, newToBeUsed));
879                
880            } else if (depending.getEntity().isMatrix() == false) {
881                // depending is one-dimensional
882                
883                // we have to generate a loop
884                result.add("DO i=1, "+depending.getEntity().getSize());
885                result.addAll(generateLikelihoodFormulaOneDimensional(depending, newToBeUsed));
886                result.add("END DO");
887            }
888            
889            else {
890                // depending is two-dimensional
891                
892                // we have to generate two loops
893                result.add("DO i=1, "+depending.getEntity().getYCoordinate().getSize());
894                result.add("DO j=1, "+depending.getEntity().getXCoordinate().getSize());
895                result.addAll(generateLikelihoodFormulaTwoDimensional(depending, newToBeUsed, true));
896                result.add("END DO");
897                result.add("END DO");
898            }
899        }
900        
901        result.addAll(generateTransitionFormula(variable));
902        return result;
903    }
904    
905    private static ArrayList<String> generateAcceptationFormulaOneDimensional(Variable variable)
906    throws InvalidModelException, IllegalParametersException, MissingFunctionException {
907        
908        //System.out.println("GENERATOR DEBUG: generateAcceptationFormulaOneDimensional");
909        /*
910          This variable belongs to an one-dimensional entity.
911          It is indexed like variable % one_dim(i).
912         
913          All affecting variables must be either global
914          or belong to the same one-dimensional entity.
915         
916          All affected variables must belong to the same one-dimensional
917          entity or to the two-dimensional child entity of variable's entity.
918         */
919        
920        // DEBUG
921        /*
922          System.out.println("GENERATOR DEBUG: called generateAcceptationFormulaOneDimensional with " +
923          variable.getName());
924         */
925        
926        ArrayList<String> result = new ArrayList<String>();
927        
928        int parameterCount = variable.getDistribution().getNumberOfParameters();
929        
930        String[] indices = new String[parameterCount+2];
931        
932        // DEBUG
933        //System.out.println("GENERATOR DEBUG: 1. P(" + variable.getName() + ") / P(" + variable.getName() + "')");
934        
935        result.add("");
936        result.add("!  P(" + variable.getName() + "') / P(" + variable.getName() + ")");
937        result.add("");
938        
939        result.add("p_acc = 1");
940        
941        for (int i=0; i<parameterCount; i++) {
942            Object parameter = variable.getDistribution().getParameter(i);
943            
944            if (parameter instanceof Integer) {
945                indices[i] = ((Integer)parameter).toString();
946                continue;
947            } else if (parameter instanceof Double) {
948                // we must add _dp to the real constants
949                indices[i] = ((Double)parameter).toString()+"_dp";
950                continue;
951            }
952            // now we know that the parameter is a Variable.
953            
954            Variable varParameter=(Variable)parameter;
955            
956            if (varParameter.getEntity() == null) {
957                indices[i] = varParameter.getName() + " % one_dim(1) % value";
958            } else if (varParameter.getEntity().equals(variable.getEntity())) {
959                indices[i] = varParameter.getName() + " % one_dim(i) % value";
960            } else throw new InvalidModelException("Variable " +
961                    varParameter.getName() + " affects variable " + variable.getName());
962        }
963        indices[parameterCount] = variable.getName()+" % one_dim(i) % new_value";
964        indices[parameterCount+1] = "new_frequency";
965        
966        // P(variable')
967        
968        // DEBUG
969        /*
970          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
971          for (int print=0; print<indices.length; print++)
972          {
973          System.out.println(indices[print]);
974          }
975         */
976        
977        ArrayList<String> toAdd = variable.getDistribution().getFreqCode(indices);
978        result.addAll(toAdd);
979        
980        indices[parameterCount] = variable.getName()+" % one_dim(i) % value";
981        indices[parameterCount+1] = "frequency";
982        
983        // P(variable)
984        
985        // DEBUG
986        /*
987          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
988          for (int print=0; print<indices.length; print++)
989          {
990          System.out.println(indices[print]);
991          }
992         */
993        
994        toAdd = variable.getDistribution().getFreqCode(indices);
995        result.addAll(toAdd);
996        
997        result.add("p_acc = p_acc * new_frequency / frequency");
998        
999        // 2) P(x | variable') / P(x | variable) for all x that depend on variable
1000        
1001        // DEBUG
1002        /*
1003          System.out.println("GENERATOR DEBUG: Phase 2. P( depending | " + variable.getName() +
1004          ") / P( depending | " + variable.getName() + "')");
1005         */
1006        
1007        result.add("");
1008        
1009        ArrayList<Variable> allAffected = new ArrayList<Variable>(variable.getAffectsList());
1010        Set<Variable> newToBeUsed = new HashSet<Variable>();
1011        newToBeUsed.add(variable);
1012        
1013        Set<Variable> handledAlready = new HashSet<Variable>();
1014 
1015        for (int iterator = 0; iterator < allAffected.size(); iterator++) {
1016            Variable depending = allAffected.get(iterator);
1017            
1018            if (depending.isSpatial()) continue;
1019            
1020            // functional
1021            if (depending.isFunctional()) {
1022                
1023                // add further affeced variables to all_depending
1024                allAffected.addAll(depending.getAffectsList());
1025                newToBeUsed.add(depending);
1026                continue;
1027            }
1028 
1029            if (depending.equals(variable)) continue; // no loops please
1030 
1031            if (handledAlready.contains(depending)) continue; // no duplicates
1032            
1033            // not functional
1034            
1035            // DEBUG
1036            /*
1037            System.out.println("GENERATOR DEBUG: Phase 2, in detail: P( " + depending.getName() + " | "
1038                + variable.getName() + "') / P( " + depending.getName() + " | " + variable.getName() + ")");
1039             */
1040            
1041            result.add("");
1042            result.add("! P( " + depending.getName() + " | "
1043                    + variable.getName() + "') / P( " + depending.getName() + " | " + variable.getName() + ")");
1044            result.add("");
1045            
1046            // now variable is one-dimensional, so depending may be one-dimensional or two-dimensional
1047            
1048            handledAlready.add(depending);
1049 
1050            if (depending.getEntity() == null) {
1051                throw new InvalidModelException("One-dimensional variable " +
1052                        variable.getName() + " affects global variable " + depending.getName());
1053            } else if (depending.getEntity().isMatrix() == false) {
1054                // depending is one-dimensional
1055                
1056                // depending's entity must be the same as variable's entity.
1057                if (!depending.getEntity().equals(variable.getEntity())) {
1058                    throw new InvalidModelException("Variable " +
1059                            variable.getName() + " affects variable " + depending.getName());
1060                }
1061                
1062                result.addAll(generateLikelihoodFormulaOneDimensional(depending, newToBeUsed));
1063            } else {
1064                // depending is two-dimensional
1065                
1066                // we have to generate a loop
1067                if (depending.getEntity().getXCoordinate().equals(variable.getEntity())) {
1068                    result.add("DO j=1, "+depending.getEntity().getYCoordinate().getSize());
1069                    
1070                    // depending is indexed depending % two_dim(j, i)
1071                    result.addAll(generateLikelihoodFormulaTwoDimensional(depending, newToBeUsed, false));
1072                    result.add("END DO");
1073                    
1074                } else if (depending.getEntity().getYCoordinate().equals(variable.getEntity())) {
1075                    result.add("DO j=1, "+depending.getEntity().getXCoordinate().getSize());
1076                    
1077                    // depending is indexed depending % two_dim(i, j)
1078                    result.addAll(generateLikelihoodFormulaTwoDimensional(depending, newToBeUsed, true));
1079                    result.add("END DO");
1080                } else {
1081                    throw new InvalidModelException("Variable " +
1082                            variable.getName() + " affects variable " + depending.getName());
1083                }
1084            }
1085        }
1086        result.addAll(generateTransitionFormula(variable));
1087        return result;
1088    }
1089    
1090    private static ArrayList<String> generateAcceptationFormulaTwoDimensional(Variable variable)
1091    throws InvalidModelException, IllegalParametersException, MissingFunctionException {
1092        
1093        //System.out.println("GENERATOR DEBUG: generateAcceptationFormulaTwoDimensional");
1094        /*
1095          This variable belongs to a two-dimensional entity.
1096          It is indexed like variable % two_dim(i, j).
1097         
1098          All affecting variables may be global,
1099          belong to the vertical entity, belong to the horizontal entity,
1100          or belong to the same two-dimensional entity.
1101         
1102          All affected variables must belong to the same entity.
1103         */
1104        
1105        ArrayList<String> result = new ArrayList<String>();
1106        
1107        int parameterCount = variable.getDistribution().getNumberOfParameters();
1108        
1109        String[] indices = new String[parameterCount+2];
1110        
1111        // 1. P(variable') / P(variable)
1112        
1113        // DEBUG
1114        //System.out.println("GENERATOR DEBUG: 1. P(" + variable.getName() + ") / P(" + variable.getName() + "')");
1115        
1116        result.add("");
1117        result.add("!  P(" + variable.getName() + "') / P(" + variable.getName() + ")");
1118        result.add("");
1119        
1120        result.add("p_acc = 1");
1121        
1122        for (int i=0; i<parameterCount; i++) {
1123            //int type = variable.getDistribution().getParameter(i);
1124            Object parameter = variable.getDistribution().getParameter(i);
1125            
1126            if (parameter instanceof Integer) {
1127                indices[i] = ((Integer)parameter).toString();
1128                continue;
1129            } else if (parameter instanceof Double) {
1130                // we must add _dp to the real constants
1131                indices[i] = ((Double)parameter).toString()+"_dp";
1132                continue;
1133            }
1134            // now we know that the parameter is a Variable.
1135            
1136            Variable varParameter=(Variable)parameter;
1137            
1138            if (varParameter.getEntity() == null) {
1139                indices[i] = varParameter.getName()+" % one_dim(1) % value";
1140            } else if (varParameter.getEntity().equals(variable.getEntity().getYCoordinate())) {
1141                indices[i] = varParameter.getName()+" % one_dim(i) % value";
1142            } else if (varParameter.getEntity().equals(variable.getEntity().getXCoordinate())) {
1143                indices[i] = varParameter.getName()+" % one_dim(j) % value";
1144            } else if (varParameter.getEntity().equals(variable.getEntity())) {
1145                indices[i] = varParameter.getName()+" % two_dim(i, j) % value";
1146            }
1147        }
1148        indices[parameterCount] = variable.getName()+" % two_dim(i, j) % new_value";
1149        indices[parameterCount+1] = "new_frequency";
1150        
1151        // P(variable')
1152        
1153        // DEBUG
1154        /*
1155          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1156          for (int print=0; print<indices.length; print++)
1157          {
1158          System.out.println(indices[print]);
1159          }
1160         */
1161        
1162        ArrayList<String> toAdd=variable.getDistribution().getFreqCode(indices);
1163        result.addAll(toAdd);
1164        
1165        indices[parameterCount] = variable.getName()+" % two_dim(i, j) % value";
1166        indices[parameterCount+1] = "frequency";
1167        
1168        // P(variable)
1169        
1170        // DEBUG
1171        /*
1172          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1173          for (int print=0; print<indices.length; print++)
1174          {
1175          System.out.println(indices[print]);
1176          }
1177         */
1178        
1179        toAdd=variable.getDistribution().getFreqCode(indices);
1180        result.addAll(toAdd);
1181        
1182        result.add("p_acc = p_acc * new_frequency / frequency");
1183        
1184        // 2) P(x | variable') / P(x | variable) for all x that depend on variable
1185        
1186        // DEBUG
1187        /*
1188          System.out.println("GENERATOR DEBUG: Phase 2. P( depending | " + variable.getName() +
1189          ") / P( depending | " + variable.getName() + "')");
1190         */
1191        
1192        ArrayList<Variable> allAffected = new ArrayList<Variable>(variable.getAffectsList());
1193        Set<Variable> newToBeUsed = new HashSet<Variable>();
1194        newToBeUsed.add(variable);
1195 
1196        Set<Variable> handledAlready = new HashSet<Variable>();
1197        
1198        for (int iterator = 0; iterator < allAffected.size(); iterator++) {
1199            Variable depending = allAffected.get(iterator);
1200            
1201            if (depending.isSpatial()) continue;
1202 
1203            // functional
1204            if (depending.isFunctional()) {
1205                // add further affeced variables to all_depending
1206                allAffected.addAll(depending.getAffectsList());
1207                newToBeUsed.add(depending);
1208                continue;
1209            }
1210        
1211            
1212            if (depending.equals(variable)) continue; // no loops please
1213 
1214            if (handledAlready.contains(depending)) continue; // no duplicates
1215 
1216            // not functional
1217            
1218            // DEBUG
1219            /*
1220                System.out.println("GENERATOR DEBUG: Phase 2, in detail: P( " + depending.getName() + " | "
1221                    + variable.getName() + ") / P( " + depending.getName() + " | " + variable.getName() + "')");
1222             */
1223            
1224            result.add("");
1225            result.add("! P( " + depending.getName() + " | "
1226                    + variable.getName() + "') / P( " + depending.getName() + " | " + variable.getName() + ")");
1227            result.add("");
1228 
1229            handledAlready.add(depending);
1230            
1231            // now variable is two-dimensional, so depending must be two-dimensional
1232            
1233            if (depending.getEntity() == null) {
1234                throw new InvalidModelException("Two-dimensional variable " +
1235                        variable.getName() + " affects global variable " + depending.getName());
1236            } else if (depending.getEntity().isMatrix() == false) {
1237                throw new InvalidModelException("Two-dimensional variable " +
1238                        variable.getName() + " affects one-dimensional variable " + depending.getName());
1239            } else if (depending.getEntity().equals(variable.getEntity()) == false) {
1240                throw new InvalidModelException("Variable " +
1241                        variable.getName() + " affects " + depending.getName() + " belonging to a different entity");
1242            } else {
1243                // depending is two-dimensional and its entity is the same as variable's
1244                
1245                result.addAll(generateLikelihoodFormulaTwoDimensional(depending, newToBeUsed, true));
1246            }
1247        }
1248        
1249        result.addAll(generateTransitionFormula(variable));
1250        
1251        return result;
1252    }
1253    
1254    private static ArrayList<String> generateLikelihoodFormulaGlobal(Variable depending, Set<Variable> newToBeUsed)
1255    throws IllegalParametersException, InvalidModelException, MissingFunctionException {
1256        
1257        //System.out.println("GENERATOR DEBUG: generateLikelihoodFormulaGlobal");
1258        // This method returns code that calculates the likelihood of depending, when using new values of variables in newToBeUsed
1259        ArrayList<String> result = new ArrayList<String>();
1260        String[] indices;
1261        int parameterCount = depending.getDistribution().getNumberOfParameters();
1262        indices = new String[parameterCount+2];
1263        
1264        for (int i=0; i<parameterCount; i++) {
1265            Object parameter = depending.getDistribution().getParameter(i);
1266            
1267            if (parameter instanceof Integer) {
1268                indices[i] = ((Integer)parameter).toString();
1269                continue;
1270            } else if (parameter instanceof Double) {
1271                // we must add _dp to the real constants
1272                indices[i] = ((Double)parameter).toString()+"_dp";
1273                continue;
1274            }
1275            // now we know that the parameter is a Variable.
1276            
1277            Variable varParameter=(Variable)parameter;
1278            
1279            if (varParameter.getEntity() != null) {
1280                throw new InvalidModelException("Variable " +
1281                        varParameter.getName() + " affects variable " + depending.getName());
1282            }
1283            
1284            if (newToBeUsed.contains(varParameter)) {
1285                indices[i] = varParameter.getName() + "% one_dim(1) % new_value";
1286            } else {
1287                indices[i] = varParameter.getName()+" % one_dim(1) % value";
1288            }
1289        }
1290        indices[parameterCount] = depending.getName()+" % one_dim(1)";
1291        indices[parameterCount+1] = "new_frequency";
1292        
1293        // P(depending | variable')
1294        
1295        // DEBUG
1296        /*
1297          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1298          for (int print=0; print<indices.length; print++) {
1299          System.out.println(indices[print]);
1300          }
1301         */
1302        
1303        ArrayList<String> toAdd=depending.getDistribution().getFreqCode(indices);
1304        result.addAll(toAdd);
1305        
1306        for (int i=0; i<parameterCount; i++) {
1307            indices[i] = indices[i].replace("% new_value", "% value");
1308        }
1309        
1310        indices[parameterCount+1] = "frequency";
1311        
1312        // P(depending | variable)
1313        
1314        // DEBUG
1315        /*
1316          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1317          for (int print=0; print<indices.length; print++) {
1318          System.out.println(indices[print]);
1319          }
1320         */
1321        
1322        toAdd=depending.getDistribution().getFreqCode(indices);
1323        result.addAll(toAdd);
1324        
1325        result.add("p_acc = p_acc * new_frequency / frequency");
1326        
1327        return result;
1328    }
1329    
1330    private static ArrayList<String> generateLikelihoodFormulaOneDimensional(Variable depending,
1331            Set<Variable> newToBeUsed) throws IllegalParametersException, InvalidModelException,
1332            MissingFunctionException {
1333        
1334        //System.out.println("GENERATOR DEBUG: generateLikelihoodFormulaOneDimensional");
1335        ArrayList<String> result = new ArrayList<String>();
1336        String[] indices;
1337        int parameterCount = depending.getDistribution().getNumberOfParameters();
1338        indices = new String[parameterCount+2];
1339        
1340        for (int i=0; i<parameterCount; i++) {
1341            Object parameter = depending.getDistribution().getParameter(i);
1342            
1343            if (parameter instanceof Integer) {
1344                indices[i] = ((Integer)parameter).toString();
1345                continue;
1346            } else if (parameter instanceof Double) {
1347                // we must add _dp to the real constants
1348                indices[i] = ((Double)parameter).toString()+"_dp";
1349                continue;
1350            }
1351            // now we know that the parameter is a Variable.
1352            
1353            Variable varParameter=(Variable)parameter;
1354            
1355            boolean useNew = false;
1356            
1357            if (newToBeUsed.contains(varParameter)) useNew = true;
1358            
1359            if (varParameter.getEntity() == null) {
1360                if (useNew)
1361                    indices[i] = varParameter.getName() + " % one_dim(1) % new_value";
1362                else
1363                    indices[i] = varParameter.getName() + " % one_dim(1) % value";
1364            } else if (varParameter.getEntity().equals(depending.getEntity())) {
1365                if (useNew)
1366                    indices[i] = varParameter.getName() + " % one_dim(i) % new_value";
1367                else
1368                    indices[i] = varParameter.getName() + " % one_dim(i) % value";
1369            }
1370        }
1371        indices[parameterCount] = depending.getName()+" % one_dim(i) % value";
1372        indices[parameterCount+1] = "new_frequency";
1373        
1374        // P(depending | variable')
1375        
1376        // DEBUG
1377        /*
1378          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1379          for (int print=0; print<indices.length; print++) {
1380          System.out.println(indices[print]);
1381          }
1382         */
1383        
1384        ArrayList<String> toAdd=depending.getDistribution().getFreqCode(indices);
1385        result.addAll(toAdd);
1386        
1387        for (int i=0; i<parameterCount; i++) {
1388            indices[i] = indices[i].replace("% new_value", "% value");
1389        }
1390        indices[parameterCount+1] = "frequency";
1391        
1392        // P(depending | variable)
1393        
1394        // DEBUG
1395        /*
1396          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1397          for (int print=0; print<indices.length; print++) {
1398          System.out.println(indices[print]);
1399          }
1400         */
1401        
1402        toAdd = depending.getDistribution().getFreqCode(indices);
1403        result.addAll(toAdd);
1404        
1405        result.add("p_acc = p_acc * new_frequency / frequency");
1406        
1407        return result;
1408    }
1409    
1410    private static ArrayList<String> generateLikelihoodFormulaTwoDimensional(Variable depending,
1411            Set<Variable> newToBeUsed, boolean ij) throws IllegalParametersException,
1412            InvalidModelException, MissingFunctionException  {
1413        
1414        //System.out.println("GENERATOR DEBUG: generateLikelihoodFormulaTwoDimensional");
1415        ArrayList<String> result = new ArrayList<String>();
1416        String[] indices;
1417        int parameterCount = depending.getDistribution().getNumberOfParameters();
1418        indices = new String[parameterCount+2];
1419        
1420        for (int i=0; i<parameterCount; i++) {
1421            Object parameter = depending.getDistribution().getParameter(i);
1422            
1423            if (parameter instanceof Integer) {
1424                indices[i] = ((Integer)parameter).toString();
1425                continue;
1426            } else if (parameter instanceof Double) {
1427                // we must add _dp to the real constants
1428                indices[i] = ((Double)parameter).toString()+"_dp";
1429                continue;
1430            }
1431            // now we know that the parameter is a Variable.
1432            
1433            Variable varParameter=(Variable)parameter;
1434            
1435            boolean useNew = false;
1436            
1437            if (newToBeUsed.contains(varParameter)) {
1438                useNew = true;
1439            }
1440            indices[i] = varParameter.getName();
1441            if (varParameter.getEntity() == null) {
1442                if (useNew)
1443                    indices[i] += " % one_dim(1) % new_value";
1444                else
1445                    indices[i] += " % one_dim(1) % value";
1446            } else if (varParameter.getEntity().equals(depending.getEntity().getYCoordinate())) {
1447                if (ij) {
1448                    indices[i] += " % one_dim(i)";
1449                } else indices[i] += " % one_dim(j)";
1450                if (useNew)
1451                    indices[i] += " % new_value";
1452                else
1453                    indices[i] += " % value";
1454            } else if (varParameter.getEntity().equals(depending.getEntity().getXCoordinate())) {
1455                if (ij) {
1456                    indices[i] += " % one_dim(j)";
1457                } else indices[i] += " % one_dim(i)";
1458                if (useNew)
1459                    indices[i] += " % new_value";
1460                else
1461                    indices[i] += " % value";
1462            } else if (varParameter.getEntity().equals(depending.getEntity())) {
1463                if (useNew && ij)
1464                    indices[i] += " % two_dim(i, j) % new_value";
1465                else if (useNew && !ij)
1466                    indices[i] += " % two_dim(j, i) % new_value";
1467                else if (!useNew && ij)
1468                    indices[i] +=" % two_dim(i, j) % value";
1469                else
1470                    indices[i] +=" % two_dim(j, i) % value";
1471            }
1472        }
1473        if (ij) {
1474            indices[parameterCount] = depending.getName()+" % two_dim(i, j) % value";
1475        } else indices[parameterCount] = depending.getName()+" % two_dim(j, i) % value";
1476        indices[parameterCount+1] = "new_frequency";
1477        
1478        // P(depending | variable')
1479        
1480        // DEBUG
1481        /*
1482          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1483          for (int print=0; print<indices.length; print++) {
1484          System.out.println(indices[print]);
1485          }
1486         */
1487        
1488        ArrayList<String> toAdd = depending.getDistribution().getFreqCode(indices);
1489        result.addAll(toAdd);
1490        
1491        // DEBUG
1492        /*
1493        System.out.println("GENERATOR DEBUG: indices is (before):");
1494        for (int i=0; i<parameterCount; i++) {
1495            System.out.println(indices[i]);
1496        }
1497         */
1498        
1499        for (int i=0; i<parameterCount; i++) {
1500            indices[i] = indices[i].replace("% new_value", "% value");
1501        }
1502        indices[parameterCount+1] = "frequency";
1503        
1504        // DEBUG
1505        /*
1506        System.out.println("GENERATOR DEBUG: indices is (after ):");
1507        for (int i=0; i<parameterCount; i++) {
1508            System.out.println(indices[i]);
1509        }
1510         */
1511        
1512        // P(depending | variable)
1513        
1514        // DEBUG
1515        /*
1516          System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1517          for (int print=0; print<indices.length; print++) {
1518          System.out.println(indices[print]);
1519          }
1520         */
1521        
1522        toAdd = depending.getDistribution().getFreqCode(indices);
1523        result.addAll(toAdd);
1524        
1525        result.add("p_acc = p_acc * new_frequency / frequency");
1526        
1527        return result;
1528    }
1529    
1530    private static ArrayList<String> generateTransitionFormula(Variable variable)
1531    throws IllegalParametersException, InvalidModelException, MissingFunctionException {
1532        // DEBUG
1533        /*
1534        System.out.println("GENERATOR DEBUG: Phase 3: q( " + variable.getName() + "', " + variable.getName() +
1535            ") / q(" + variable.getName() + ", " + variable.getName() + "')");
1536         */
1537        
1538        ArrayList<String> result = new ArrayList<String>();
1539        result.add("");
1540        result.add("! q(" + variable.getName() + "', " + variable.getName() +
1541                ") / q(" + variable.getName() + ", " + variable.getName() + "')");
1542        result.add("");
1543        
1544        String indexing = "";
1545        if (variable.getEntity() == null) {
1546            indexing = "one_dim(1)";
1547        } else if (variable.getEntity().isMatrix() == false){
1548            indexing = "one_dim(i)";
1549        } else indexing = "two_dim(i, j)";
1550        
1551        
1552        ArrayList<String> toAdd = new ArrayList<String>();
1553        
1554        if (variable.getStrategy() == "random walk") {
1555            // random walk proposal strategy
1556            
1557            if (variable.isInteger()) {
1558                result.add("transition_int = " + variable.getName() + " % " + indexing +
1559                        " % new_value - " + variable.getName() + " % " + indexing + " % value");
1560            } else {
1561                result.add("transition_real = " + variable.getName() + " % " + indexing +
1562                        " % new_value - " + variable.getName() + " % " + indexing +" % value");
1563            }
1564            
1565            int parameterCount = variable.getProposal().getNumberOfParameters();
1566            String[] indices = new String[parameterCount+2];
1567            
1568            for (int i=0; i<parameterCount; i++) {
1569                Object parameter = variable.getProposal().getParameter(i);
1570                
1571                if (parameter instanceof Integer) {
1572                    indices[i] = ((Integer)parameter).toString();
1573                    continue;
1574                } else if (parameter instanceof Double) {
1575                    // we must add _dp to the real constants
1576                    indices[i] = ((Double)parameter).toString()+"_dp";
1577                    continue;
1578                } else {
1579                    throw new InvalidModelException("Error in the proposal distribution of parameter " +
1580                            variable.getName() + ". Only constants can appear in proposal distributions.");
1581                }
1582            }
1583            
1584            if (variable.isInteger()) {
1585                indices[parameterCount] = "-transition_int";
1586            } else {
1587                indices[parameterCount] = "-transition_real";
1588            }
1589            indices[parameterCount+1] = "frequency";
1590            
1591            // DEBUG
1592            /*
1593            System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1594            for (int print=0; print<indices.length; print++) {
1595                System.out.println(indices[print]);
1596            }
1597             */
1598            
1599            toAdd = variable.getProposal().getFreqCode(indices);
1600            result.addAll(toAdd);
1601            
1602            if (variable.isInteger()) {
1603                indices[parameterCount] = "transition_int";
1604            } else {
1605                indices[parameterCount] = "transition_real";
1606            }
1607            indices[parameterCount+1] = "new_frequency";
1608            
1609            
1610            // DEBUG
1611                /*
1612                  System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1613                  for (int print=0; print<indices.length; print++)
1614                  {
1615                  System.out.println(indices[print]);
1616                  }
1617                 */
1618            
1619            toAdd = variable.getProposal().getFreqCode(indices);
1620            result.addAll(toAdd);
1621            
1622            result.add("p_acc = p_acc * frequency / new_frequency");
1623        } else {
1624            // fixed proposal strategy
1625            
1626            int parameterCount = variable.getProposal().getNumberOfParameters();
1627            String[] indices = new String[parameterCount+2];
1628            
1629            for (int i=0; i<parameterCount; i++) {
1630                Object parameter = variable.getProposal().getParameter(i);
1631                
1632                if (parameter instanceof Integer) {
1633                    indices[i] = ((Integer)parameter).toString();
1634                    continue;
1635                } else if (parameter instanceof Double) {
1636                    // we must add _dp to the real constants
1637                    indices[i] = ((Double)parameter).toString()+"_dp";
1638                    continue;
1639                }
1640            }
1641            
1642            indices[parameterCount] = variable.getName() + " % " + indexing +" % value";
1643            
1644            indices[parameterCount+1] = "frequency";
1645            
1646            // DEBUG
1647            /*
1648                System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1649                for (int print=0; print<indices.length; print++) {
1650                    System.out.println(indices[print]);
1651                }
1652             */
1653            
1654            toAdd = variable.getProposal().getFreqCode(indices);
1655            result.addAll(toAdd);
1656            indices[parameterCount] = variable.getName() + " % " + indexing +" % new_value";
1657            indices[parameterCount+1] = "new_frequency";
1658            
1659            // DEBUG
1660            /*
1661                System.out.println("GENERATOR DEBUG: About to call getFreqCode with parameters: ");
1662                for (int print=0; print<indices.length; print++) {
1663                    System.out.println(indices[print]);
1664                }
1665             */
1666            
1667            toAdd = variable.getProposal().getFreqCode(indices);
1668            result.addAll(toAdd);
1669            
1670            result.add("p_acc = p_acc * frequency / new_frequency");
1671        }
1672        
1673        return result;
1674    }
1675}
1676 

[all classes][PIANOS.generator]
EMMA 2.0.5312 (C) Vladimir Roubtsov