Ausdrücke

csv-Eingabedateien können in der Wertespalte Ausdrücke mit folgenden Funktionen enthalten

------------------------------------------------------
Liste der möglichen Funktionen in Ausdrücken
Die Parmeter werden dabei durch Leerstellen getrennt:
Funktion         Beschreibung
----------------+-------------------------------------
and(a b ...)     a und b und ...
at($V 3 4)       Wert aus Schlüsselwerttabelle $V an Position 3, 4
                 $V(3 4) Abkürzung für at($V 3 4)
ceil(x)          nächst größere Ganzzahl
check_undef(n)   check undef values in input files 0: no, 1: yes (default)i
checksum($V 1 3) prüfe, ob Summe über Dimensionen 1 und 3 jeweils 1 (+/_ Tol)
constant(k v)    constant($GPmin 0,3) überschreibe constant.csv: GPmin;0.3
                 constant($GPmin)          Konstante als Zahl
                 constant('FMT_ANZAHLdef') Konstante als string
                 auch in Prognose/Notiz oder sikurs.ini/TRACECMD
cos(x)           Cosinus
cut(n)           reduziere GKZ um n Stellen vor Zugriff auf reftyp
                 (für sher differenzierte Gebiete)
dim()            Anzahl Spalten ohne Kontrollzahl
eq(a b)          a gleich b ?
eval(option('var' 0)) Ausführen Inhalt Trace-Variable 'var', z.B. Notiz:
                 !option($var option($key 0))
eval_file('pragma')) Ausführen Inhalt Datei pragma.txt, z.B.
                 #! list(2)
exp(x)           Exponentialfunktion y=e^x, e=2,718...
expand(0/1)      Expansion Eingabedatei ins Versions-Unterverzeichnis,
                 damit Tools Ausdrücke wie 2001..2010 verarbeiten können
                 expand(0) verhindert automatische Expansion von Dateien mit Ausdrücken,
                           sinnvoll, z.B. wenn Datei sehr groß
                 expand(1) erzwingt Expansion Datei,
                           sinnvoll, z.B. wenn zuvol Ausdruck 2030..2100 am Ende enthält
floor(x)         nächst kleinere Ganzzahl
gauss(x m s)     Gauss'sche Normalverteilung
                 mit Erwartungswert m und Standardabweichung s
gem()            Summe aktuelles Gebiet gem Vorjahr in eckgem.csv
gem(gkz)         Summe Gebiet gkz Vorjahr in eckgem.csv
getenv('list' [0]) C++ getenv("list") mit default 0
gt(a b)          a größer b ?
hadwiger(x F MODE MEAN VAR) Hadwiger-Funktion zur Nachbildung von Geburtenraten mit
                 x    Altersgruppe (wert wird für ag+0.5 berechnet)
                 F    Gesamtfertilität
                 MODE Modalwert
                 MEAN Mittelwert
                 VAR  Varianz    (VARiance)
if(b t f)        Wenn b wahr, dann t, sonst f
ix(i)            Wert der Indexspalte i (1,2,...)
                 $5 ist Abkürzung für ix(5)
let($V e)        neue Variable $V mit Wert e (siehe Beispiel zudq, eckgem)
line(x m n)      Gerade y = m*x + n
line2p(x x1 y1 x2 y2) Gerade Zweipunktform zwischen (x1 y1) und (x2 y2)
list(n)          Protokoll Eingabedatei
                 0 kein
                 1 alle Eingabezeilen
                 2 mit p-code expressions
log(x)           Natürlicher Logarithmus (zur Basis e=2,718...)
log10(x)         Logarithmus zur Basis 10
lt(a b)          a kleiner b ?
max(a b ...)     Maximum
min(a b ...)     Minimum
not(a)           nicht a
option($BSL)     lese Option BSL
option($BSL 2)   setze Option $BSL 2
                 auch in Prognose/Notiz oder sikurs.ini/TRACECMD
or(a b ...)      a or b or ...
pi()             3,14...
pow(2 3)         2^3 = exp(3*log(2)) = 8
print('a' $A)    Ausgabe Parameter ins Protokoll (z.B. zum Test von read, option, constant)
                 auch in Prognose/Notiz oder sikurs.ini/TRACECMD
rand()           (Pseudo-)Zufallszahl im Bereich 0..1
rand(x)          (Pseudo-)Zufallszahl im Bereich 0..x
read('fn')       lese Schlüsselwerttabelle aus 'fn.csv'
read('f' 2011)   lese 'f.csv' Zeilen mit 2011 in Spalte 1
read('f' 3 5)    lese 'f.csv' Zeilen mit 3 in Spalte 1 und 5 ins Spalte 2
sin(x)           Sinus
skip(n)          Beende in SIKURS-Perl-Hauptprogramm das lesen (von reftyp.csv)
                 0: nicht, 1: leise, 2: mit Message Box
sqrt(x)          Quadratwurzel
tan(x)           Tangens
weibull(t T b t0) Weibull-Verteilung
                 t  Altersgruppe
                 T  Charakteristische Lebensdauer, bei der 63.2% der Einh. ausgefallen sind
                 b  Formparameter, Steigung der Ausgleichsgeraden im Weibull-Netz
                 t0 ausfallfreie Zeit

Beispiel:
Bei K5 benötigt man die Datei
zuvl2012.csv:
Außenquelltyp;Zieltyp-Außenzuwanderung;BG;GG;AG;Anzahl
1;1;1;1;00;30
...
3;4;2;2;99;3
Die Dateien zudq und zuaq entfallen.
Der Benutzer kann dann wie folgt die Wirkung von K1 bis K4 erzielen
K1
zuvl2012.csv:
# zuv2012 funktioniert für alle Folgejahre
let($ZUVOL read('zuvol' $JAHR))
let($ZUDQ  read('zudq'));
checksum($ZUDQ 0);
print('zudq' $ZUDQ);
let($ZUAQ, read('zuaq'));
checksum($ZUAQ 1 3 4 5);
print('zuaq' ZUAQ);
1..$NTYA;1..$NTYZZA;1..$NBG;1..$NGG;0..$NAG-1;$ZUVOL*$ZUDQ($1 $3 $4 $5)*ZUAQ($1 $2 $3 $4 $5)

zuvol.csv:
#Jahr;Zuzug
2012;70000
2013;71002
2014;71875

zudq.csv:
#TYA;BG;GG;AG;Quote
1;1;1;00;0,0012
...
3;2;2;99;0,0032

zuaq.csv:
#TYA;TYZZA;BG;GG;AG;Quote
1;1;1;1;00;0,0003
...
3;4;2;2;99;0,0004
            
K2
zuvl2012.csv:
# zuv2012 funktioniert für alle Folgejahre
let($ZUVOL read('zuvol' $JAHR))
let($ZUDQ  read('zudq'));
checksum($ZUDQ 1);
print('zudq' $ZUDQ);
let($ZUAQ  read('zuaq'));
checksum($ZUAQ 1 3 4 5);
print('zuaq' $ZUAQ)
1..$NTYA;1..$NTYZZA;1..$NBG;1..$NGG;0..$NAG-1;$ZUVOL($1)*$ZUDQ($1 $3 $4 $5)*ZUAQ($1 $2 $3 $4 $5)

zuvol.csv:
#Jahr;TYA;Zuzug
2012;1;30000
2012;2;40000
2012;3;20000
2013;1;30012
...
2014;3;20007
            
zudq.csv und zuaq.csv wie bei K1
K3
zuvl2012.csv:
# zuv2012 funktioniert für alle Folgejahre
let($ZUVOL read('zuvol' $JAHR))
let($ZUDQ  read('zudq'));
checksum($ZUDQ 1 2);
print('zuaq' $ZUAQ);
let($ZUAQ  read('zuaq'));
checksum($ZUAQ 1 3 4 5);
print('zuaq' $ZUAQ);
1..$NTYA;1..$NTYZZA;1..$NBG;1..$NGG;0..$NAG-1;$ZUVOL($1 $3)*$ZUDQ($1 $3 $4 $5)*ZUAQ($1 $2 $3 $4 $5)

zuvol.csv:
#Jahr;TYA;BG;Zuzug
2012;1;1;15000
2012;1;2;15000
2012;2;1;20000
2012;2;2;20000
2012;3;1;10000
2012;3;2;10000
2013;1;1;15012
...
2014;3;2;10007
            
zudq.csv und zuaq.csv wie kei K1
K4
zuvl2012.csv:
# zuv2012 funktioniert für alle Folgejahre
let($ZUVOL read('zuvol' $JAHR))
let($ZUDQ  read('zudq'));
checksum($ZUDQ 1 2 3);
print('zudq' $ZUDQ);
let($ZUAQ  read('zuaq'));
checksum($ZUAQ 1 3 4 5);
print('zuaq' $ZUAQ);
1..$NTYA;1..$NTYZZA;1..$NBG;1..$NGG;0..$NAG-1;$ZUVOL($1 $3 $4)*$ZUDQ($1 $3 $4 $5)*ZUAQ($1 $2 $3 $4 $5)

zuvol.csv:
#Jahr;TYA;BG;GG;Zuzug
2012;1;1;1; 7500
2012;1;1;1; 7500
2012;1;2;1; 7500
2012;1;2;2; 7500
2012;2;1;1;10000
2012;2;1;2;10000
2012;2;2;1;10000
2012;2;2;2;10000
2012;3;1;1; 5000
2012;3;1;2; 5000
2012;3;2;1; 5000
2012;3;2;2; 5000
2013;1;1;1; 7512
...
2014;3;2;2; 5007

zudq.csv:
#TYA;BG;GG;AG;Quote
1;1;1;00;0,0012
...
9;2;2;99;0,0032
            
zudq.csv und zuaq.csv wie kei K1
K4+
Beispiel mit Altersquoten
zuvl2010.csv:
# zuvl2010.csv funktioniert wegen $JAHR für alle Folgejahre
let ($ZV read('zuv' $JAHR))
print('zuv' $ZV)
let ($AQ read('zuaq'))
checksum($AQ 1)
print('zuaq' $AQ)
1..$NTYA;1..$NTYZZA;1..$NBG;1..$NGG;0..$NAG-1;$ZV($1 $2 $3 $4)*$AQ($5)

zuv.csv:
#jhr;tya;tyzza;bg;gg;Anzahl
2010;1;1;1;1;10
2010;1;1;1;2;10
2011;1;1;1;1;20
2011;1;1;1;2;20
...

zuaq.csv:
#ag;quote
0;0,3
1;0,4
2;0,3
            

Wenn zudq und zuaq jahresspezifisch sein sollen, ersetzt man ober einfach zudq in zudq2012 und zuaq in zuaq2012

Mit diesem Schema kann der Benutzer auch andere ein- oder mehrstufige Verfahren für die Aufteilung eines Zuzugsvolumens umsetzen.
Wenn z.B. Anzahl Typen Außenzuwanderung = 1 ist, dann kann man auf zuaq.csv verzichten. Bie K3 sieht dann zuvl wie folgt aus:

zuvl2012.csv:
let($ZUVOL read('zuvol'))
let($ZUDQ  read('zudq'));
checksum($ZUDQ 1 2);
1..$NTYA;1..$NTYZZA;1..$NBG;1..$NGG;0..$NAG-1;$ZUVOL(2012)*$ZUDQ($1 $3 $4 $5)
print('zuvol' $ZUVOL)
Die 4 Zeilen kann man wie folgt lesen:
  1. lese die Datei zuvol.csv und speichere sie in der Variablen $ZUVOL
  2. lese die Datei zudq.csv und speichere die Werte in der Variablen $ZUDQ
  3. prüfe ob die Werte des Aggregats über die Spalten 1 (TYA) und 2 (BG) bis auf eine Toleranz gleich 1 ist
    Eine genauere Prüfung als die Summe wäre:
    checksum($ZUDQ 1 2)
    mir folgender Bedeutung:
    aggregiere auf die Spalten 1 (TYA) und 2 (BG)
    Prüfe, ob alle Werte des Aggreats(TYA, BG) den Wert 1 (bis auf eine Toleranz) haben
  4. Die Werte an den Indices 1..$NTYA, 1..$NTYZZA, 1..$NBG, 1..$NGG, 0..$NAG-1 sind
    $ZUVOL(2012), d.h. der Werte von zuvol.csv mit Index 2012 mal
    $ZUDQ($1 $3 $4 $5), d.h. der Werte von zudq.csv mit den Indices
    $1: TYA, $3: BG, $4: GG, $5 AG
  5. Testausgabe String 'zuvol' und den Inhalt von $ZUVOL ins Protokoll
Für die Bausteine K muss man nur noch den Faktor $ZUVOL(2012) variieren:
K1$ZUVOL(2012)globaler Zuzug des Jahres 2012
K2$ZUVOL(2012 $1)Zuzug des Außentyps des Jahres 2012
K3$ZUVOL(2012 $1 $3)Zuzug des Außentyps, Bevölkerungsgruppe des Jahres 2012
K4$ZUVOL(2012 $1 $3 $4)Zuzug des Außentyps, Bevölkerungsgruppe, Geschlechtsgruppe des Jahres 2012

Im Verzeichnis ../sikurs/beispiel/regtest sind die Testdateien zuvl1992.csv zudq1992.csv zuaq.csv.
(siehe Programmquellen JZUVO)

Diese Ausdrücke in csv-Dateien können nur von der SIKURS-Prognose verarbeitet werden. Erkennt die Prognose einen Ausdruck, so schreibt sie die expandierte Datei in das Versionsunterverzeichnis.
Die SIKURS Tools suchen Dateien zuerst im Versionsunterverzeichnis, wo sie dann die expandierte Datei ohne Ausdrücke findet und somit indirekt die Ausdrücke auch verarbeiten kann.
Bei list(1) oder expand(0) wird keine Expansion ins Unterverzeichnis angestoßen. Deshalb sollte man sie als Pseudokommentare schreiben

#! list(1)
#! expand(0)
Man kann mehrere Pseudokommetare in eine Zeile schreiben:
#! check_undef(0) constant('GPmin' '0') cut(0) expand(1) let($V 42) list(1) skip(1)
Der Ausdruck constant('GPmin' '0') macht an verschiedenen Stellen sinn: