Interval.cpp
gehe zur Dokumentation dieser Datei
00001 
00028 // ------------------------------------------------------------------
00029 // Mutabor 2.win, 1997, R.Krauße
00030 // Intervallberechnungen
00031 // ------------------------------------------------------------------
00032 
00033 #include "Global.h"
00034 #include "GrafKern.h"
00035 #include "Interval.h"
00036 #include "Hilfs.h"
00037 
00038 static double get_intervall_wert (const char * name)
00039 {
00040 
00041         struct intervall *lauf;
00042 
00043         for (lauf = list_of_intervalle; lauf; lauf = lauf -> next) {
00044                 if ( ! strcmp (name, lauf->name)) {
00045                         switch (lauf -> intervall_typ) {
00046 
00047                         default: /* und */
00048 
00049                         case intervall_komplex:
00050                                 fatal_error (0, mutC_STR(__FILE__), __LINE__);
00051 
00052                                 break;
00053 
00054                         case intervall_absolut:
00055                                 return lauf->u.intervall_absolut.intervall_wert ;
00056 
00057                                 /* break; */
00058                         }
00059                 }
00060         }
00061 
00062         fatal_error(26,mutC_STR(name)); /* Intrvall n.dekl. */
00063 
00064         return 0.0; /* to prevent warnings */
00065 }
00066 
00067 
00068 double get_wert_komplex_intervall (struct komplex_intervall * intervall)
00069 
00070 {
00071         double ret = 1.0;
00072 
00073         for ( ; intervall ; intervall = intervall -> next )
00074         {
00075                 double help = get_intervall_wert (intervall -> name);
00076 
00077                 if (help > 0)
00078                         ret *= pow (help, intervall -> faktor);
00079                 else {
00080                         fatal_error(46, mutC_STR(intervall -> name));
00081                         /* unzul. Intervallwert */
00082                 }
00083 
00084         }
00085 
00086         return ret;
00087 }
00088 
00089 
00090 
00091 /**************************************************************
00092 
00093             Hier werden die Intervalle aufgelöst.
00094             Nach dem Parsing ist nur die Syntax-Struktur
00095             vorhanden, aber keine fertig ausgerechneten Intervalle.
00096 
00097             Es wird ein azyklischer Graph der Intervalle und ihrer
00098             UnterIntervalle gebildet, der dann nach den
00099             depth-first-search traversiert wird.
00100             Dabei bekommt jedes Intervall seinen AbsolutFaktor berechnet.
00101 
00102 ****************************************************************/
00103 
00104 static int anzahl_intervalle;       /* so viele Intervalle wurden gelesen */
00105 
00106 static struct intervall ** intervalle;    /* Feld von Intervallen zum schnelleren Zugriff
00107 
00108                                   als ueber Listen */
00109 
00110 static char * visited;         /* Traversierungsmerker */
00111 
00112 static char * matrix;          /* Adjazenzmatrix (auf sie darf nur ueber
00113 
00114                                   das folgende Makro zugegriffen werden !*/
00115 
00116 #define adjazent(a,b) matrix [ (a) * anzahl_intervalle * sizeof (char) \
00117                              + (b) * sizeof (char)]
00118 
00119 int intervall_list_laenge (struct intervall *list)
00120 {
00121         if (list) return 1 + intervall_list_laenge (list -> next);
00122 
00123         return 0;
00124 }
00125 
00126 
00127 
00128 static void belege_intervalle (struct intervall **intervalle, struct intervall * liste)
00129 {
00130         while (liste)
00131         {
00132                 *intervalle = liste;
00133                 intervalle++;
00134                 liste = liste->next;
00135         }
00136 }
00137 
00138 static int intervall_nummer (const char *name)
00139 {
00140         int i;
00141 
00142         for (i=0; i<anzahl_intervalle; i++)
00143                 if ( ! strcmp (name, intervalle[i]->name)) return i;
00144 
00145         fatal_error(26,mutC_STR(name)); /* Ton n.dekl. */
00146 
00147         return 0; /* to prevent warnings */
00148 }
00149 
00150 static void test_zyklen (int startknoten)
00151 {
00152         int i;
00153 
00154         for (i=0; i<anzahl_intervalle; i++) {
00155                 if (adjazent (startknoten, i)) {
00156                         if (visited [i]) {
00157                                 fatal_error(67,mutC_STR(intervalle [startknoten]->name),
00158                                             intervalle [i]->name);
00159                         }
00160 
00161                         visited [i] = 1;
00162 
00163                         test_zyklen (i);
00164                         visited [i] = 0;
00165                 }
00166         }
00167 }
00168 
00169 static void berechne_intervall_endgueltig (int k)
00170 {
00171         int b;
00172         double help;
00173 
00174         switch (intervalle[k]->intervall_typ) {
00175 
00176         case intervall_absolut:         /* hier nichts zu tun */
00177                 break;
00178 
00179         case intervall_komplex: {
00180 
00181                 struct komplex_intervall * lauf;
00182 
00183                 for (lauf = intervalle[k]->u.intervall_komplex.komplex_liste;
00184                                 lauf;
00185                                 lauf = lauf -> next) {
00186                         b = intervall_nummer (lauf -> name);
00187                         berechne_intervall_endgueltig (b);
00188                 }
00189 
00190                 help = get_wert_komplex_intervall (intervalle[k]->u.intervall_komplex.komplex_liste);
00191 
00192                 intervalle[k]->intervall_typ = intervall_absolut;
00193                 intervalle[k]->u.intervall_absolut.intervall_wert = help;
00194         }
00195 
00196         break;
00197 
00198         default:
00199                 fatal_error(0,_C_STR(_("loop")));
00200         }
00201 }
00202 
00203 void berechne_intervalle_absolut (struct intervall * list_of_intervalle)
00204 
00205 {
00206         int i,j,k;
00207 
00208         anzahl_intervalle = intervall_list_laenge (list_of_intervalle);
00209 
00210         intervalle = (intervall* *) xalloca (sizeof(struct intervall *) * anzahl_intervalle);
00211         visited = (char*) xalloca (sizeof(char) * anzahl_intervalle);
00212         matrix = (char*) xalloca (sizeof(char) * anzahl_intervalle * anzahl_intervalle);
00213 
00214 
00215         /* Feld mit intervallen initialisieren (zum schnelleren Zugriff) */
00216 
00217         belege_intervalle (intervalle, list_of_intervalle);
00218 
00219         /* Adjazenzmatrix initialisieren (Kein Intervall hängt vom anderen ab) */
00220 
00221         for (i=0; i<anzahl_intervalle; i++)
00222         {
00223                 for (j=0; j<anzahl_intervalle; j++) {
00224                         adjazent (i,j) = 0;
00225                 }
00226         }
00227 
00228         /* Adjazenzmatrix initialisieren (Abhängigkeiten eintragen) */
00229 
00230         for (i=0; i<anzahl_intervalle; i++)
00231         {
00232                 if (intervalle[i]->intervall_typ == intervall_absolut)  /* alles ok */ ;
00233                 else if (intervalle[i]->intervall_typ == intervall_komplex) {
00234 
00235                         struct komplex_intervall * lauf;
00236 
00237                         for (lauf = intervalle[i]->u.intervall_komplex.komplex_liste;
00238                                         lauf;
00239                                         lauf = lauf -> next) {
00240                                 adjazent (i, intervall_nummer (lauf -> name)) = 1;
00241                         }
00242                 } else {
00243                         fatal_error(0,_C_STR(_("loop")));
00244                 }
00245         }
00246 
00247 #ifdef DEBUG_ANZEIGE_3
00248         /* Adjazenzmatrix anzeigen */
00249 
00250         printf ("Matrix:\n");
00251 
00252         for (i=0; i<anzahl_intervalle; i++)
00253         {
00254                 printf ("%s -> ", intervalle[i]->name);
00255 
00256                 for (j=0; j<anzahl_intervalle; j++) {
00257                         if (adjazent (i,j))
00258                                 printf ("%s  ", intervalle[j]->name);
00259                 }
00260 
00261                 printf ("\n");
00262         }
00263 
00264         printf ("\n");
00265 
00266 #endif
00267 
00268         /* auf Zyklenfreiheit Pruefen */
00269 
00270         for (k=0; k<anzahl_intervalle; k++)
00271                 visited [k] = 0;
00272 
00273         for (k=0; k<anzahl_intervalle; k++)
00274         {
00275                 visited [k] = 1;
00276                 test_zyklen (k);
00277                 visited [k] = 0;
00278         }
00279 
00280         /* Toene endgueltig berechnen */
00281 
00282         for (k=0; k<anzahl_intervalle; k++)
00283                 berechne_intervall_endgueltig (k);
00284 
00285 #ifdef DEBUG_ANZEIGE_3
00286         /* Adjazenzmatrix anzeigen */
00287 
00288         printf ("Matrix:\n");
00289 
00290         for (i=0; i<anzahl_intervalle; i++)
00291         {
00292                 printf ("%s -> ", intervalle[i]->name);
00293 
00294                 for (j=0; j<anzahl_intervalle; j++) {
00295                         if (adjazent (i,j))
00296                                 printf ("%s  ", intervalle[j]->name);
00297                 }
00298 
00299                 printf ("\n");
00300         }
00301 
00302         printf ("\n");
00303 
00304 #endif
00305 
00306         xde_alloca (intervalle);
00307         xde_alloca (visited);
00308         xde_alloca (matrix);
00309 
00310 }
00311 
00312 /*****************************************/
00313 
00314 void check_komplex_intervall (struct komplex_intervall * liste,
00315 
00316                               const char * konstrukt_name)
00317 {
00318         for ( ; liste ; liste = liste -> next )
00319         {
00320 
00321                 struct intervall * help = get_intervall (liste -> name, list_of_intervalle);
00322 
00323                 if (help == NULL) {
00324                         fatal_error (32, mutC_STR(liste -> name), mutC_STR(konstrukt_name));
00325                         return;
00326                 }
00327 
00328                 if (help -> intervall_typ != intervall_absolut) {
00329                         fatal_error (0, _T(__FILE__), __LINE__);
00330                         return;
00331                 }
00332         }
00333 }
00334 
00335 
00336 

Erzeugt am Sun Aug 21 2011 10:51:52 für Mutabor von doxygen 1.7.4