Wyrażenia matematyczne

Podczas laboratorium zaimplementujemy kilka klas pozwalających na reprezentację prostych wyrażeń matematycznych (funkcji jednej lub kilku zmiennych) jako grafów. Podobna reprezentacja jest rdzeniem funkcji oferowanych na przykład przez https://live.sympy.org/ lub https://www.derivative-calculator.net/. Nie będziemy jednak “parsowali” wyrażeń, czyli budowali grafowej reprezentacji na podstawie specyfikacji tekstowej. Zamiast tego, wyrażenia będą budowane za pomocą odpowiednio skonstruowanego kodu.

Założona funkcjonalność:

  • budowa wyrażeń
  • obliczanie wartości wyrażeń/funkcji dla różnych wartości zmiennych
  • wydruk wyrażeń
  • symboliczne obliczanie pochodnych [zadanie domowe]

Jakie klasy będą potrzebne

Przeanalizujmy wyrażenie $ 2x^3 + x^2 -2x + 7 $

Jego elementami są:

  • stałe (np 2 i 7)
  • zmienne (x)
  • funkcja potęgowa ($x^3$, $x^2$) – Power(arg,p)
  • operacja mnożenia Prod(args…)
  • operacja dodawania Sum(args…)

Wyrażenie $ 2x^3 + x^2 -2x + 7 $ może być zapisane jako Sum(Prod(2,Power(x,3)),Power(x,2),Prod(-2,x),7). Zakładając, że każdy z tych elementów będzie obiektem, otrzymamy reprezentację w postaci acyklicznego grafu, jak na poniższym rysunku. Węzłami grafu są stałe, zmienne, operacje i funkcje, natomiast krawędzie odpowiadają argumentom poszczególnych operacji.

W zasadzie jest to drzewo, którego liśćmi są zmienne i stałe. Ponieważ zmienne mogą powtarzać się, liście będące zmiennymi zostały złączone

Przykładowa reprezentacja wyrażenia 2x^3 + x^2-2x+7

Zaimplementujemy więc klasy, jak na poniższym diagramie i dodamy wspólnego przodka, abstrakcyjną klasę Node. Niebieskie linie to asocjacje/agregacje łączące węzły nadrzędne (opreacje, funkcje) i ich argumenty.

  • Argumentem Power jest jakieś wyrażenie, czyli Node.
  • Sum może mieć więcej argumentów, stąd agregacja elementów Node
  • Prod (product) to iloczyn większej liczby czynników Node

Klasy

Implementujemy klasy

Node

abstract public class Node {
    int sign=1;
    Node minus(){
        sign = -1;
        return this;
    }
    Node plus(){
        sign = 1;
        return this;
    }
    int getSign(){return sign;}
 
    /**
     * Oblicza wartość wyrażenia dla danych wartości zmiennych
     * występujących w wyrażeniu
     */
    abstract double evaluate();
 
    /**
     *
     * zwraca tekstową reprezentację wyrażenia
     */
    public String toString(){return "";}
 
    /**
     * 
     * Zwraca liczbę argumentów węzła
     */
    int getArgumentsCount(){return 0;}
 
}

W klasie Node wprowadzono atrybut sign znak, dziedziczony przez klasy potomne. Potraktujmy to następująco. Załóżmy, że reprezentacją tekstową węzła jest abcd

  • jeśli sign<0 reprezentacją tekstową będzie -(abcd) [w nawiasach]
  • jeśli sign>=0 będzie to po prostu abcd [bez nawiasów]

Constant

public class Constant extends Node {
    double value;
    Constant(double value){
        this.sign = value<0?-1:1;
        this.value = value<0?-value:value;
    }
 
 
    @Override
    double evaluate() {
        return sign*value;
    }
 
    @Override
    public String toString() {
        String sgn=sign<0?"-":"";
//        return sgn+Double.toString(value);
        DecimalFormat format = new DecimalFormat("0.#####",new DecimalFormatSymbols(Locale.US));
        return sgn+format.format(value);
    }
}

Stosując DecimalFormat pozbędziemy się niepotrzebnych zer na końcu wartości double.

Variable

Klasa Variable reprezentuje zmienną, która może być użyta w wyrażeniach.

public class Variable extends Node {
    String name;
    Double value;
    Variable(String name){
        this.name = name;
    }
    void setValue(double d){
        value = d;
        // value = d<0?-value:value;
        // sign = d<0?-1:1;
    }
 
 
    @Override
    double evaluate() {
         //return sign*value;
         return value;
    }
 
 
    @Override
    public String toString() {
        String sgn=sign<0?"-":"";
        return sgn+name;
    }
 
}

Power

Power jest jedyną zaimplementowaną funkcją. Zauważmy, że $Power(x,-1)=\frac{1}{x}$. Argumentem Power nie musi być pojedyncza zmienna. Może to być np.: Power(Sum(x,2),-2), czyli $\frac{1}{(x+2)^2}$

W kodzie pokazano przykładową implementację toString() z próbą wstawienia nawiasów w takich przypadkach, jak $-(-x^5)$ lub $(x+1)^2$

public class Power extends Node {
    double p;
    Node arg;
    Power(Node n,double p){
        arg = n;
        this.p = p;
    }
 
    @Override
    double evaluate() {
        double argVal = arg.evaluate();
        return Math.pow(argVal,p);
    }
 
 
    int getArgumentsCount(){return 1;}
 
 
    @Override
    public String toString() {
        StringBuilder b = new StringBuilder();
        if(sign<0)b.append("-");
        int argSign = arg.getSign();
        int cnt = arg.getArgumentsCount();
        boolean useBracket = false;
        if(argSign<0 ||cnt>1)useBracket = true;
        String argString = arg.toString();
        if(useBracket)b.append("(");
        b.append(argString);
        if(useBracket)b.append(")");
        b.append("^");
        b.append(p);
        return b.toString();
    }
 
}

Sum

Klasa Sum jest wyrażeniem reprezentującą sumę argumentów. Zawiera listę węzłów List<Node> args = new ArrayList<>();

Teoretycznie, lista argumentów może liczyć 0,1,2,… elementów. Metoda add() dodaje składniki do listy

public class Sum extends Node {
 
    List<Node> args = new ArrayList<>();
 
    Sum(){}
 
    Sum(Node n1, Node n2){
        args.add(n1);
        args.add(n2);
    }
 
 
    Sum add(Node n){
        args.add(n);
        return this;
    }
 
    Sum add(double c){
        args.add(new Constant(c));
        return this;
    }
 
    Sum add(double c, Node n) {
        Node mul = new Prod(c,n);
        args.add(mul);
        return this;
    }
 
    @Override
    double evaluate() {
        double result =0;
        oblicz sumę wartości zwróconych przez wywołanie evaluate skłądników sumy
        return sign*result;
    }
 
    int getArgumentsCount(){return args.size();}
 
    public String toString(){
        StringBuilder b =  new StringBuilder();
        if(sign<0)b.append("-(");
 
        //zaimplementuj
 
        if(sign<0)b.append(")");
        return b.toString();
    }
 
 
}

Prod

Prod to iloczyn (ang. product). Reprezentuje wyrażenie będące iloczynem czynników. Metoda mul() dodaje czynnik do listy.

public class Prod extends Node {
    List<Node> args = new ArrayList<>();
 
    Prod(){}
 
    Prod(Node n1){
        args.add(n1);
    }
    Prod(double c){
        wywołaj konstruktor jednoargumentowy przekazując new Constant(c)
    }
 
    Prod(Node n1, Node n2){
        args.add(n1);
        args.add(n2);
    }
    Prod(double c, Node n){
        wywołaj konstruktor dwuargumentowy
    }
 
 
 
    Prod mul(Node n){
        args.add(n);
        return this;
    }
 
    Prod mul(double c){
        ???
    }
 
 
    @Override
    double evaluate() {
        double result =1;
        // oblicz iloczyn czynników wołąjąc ich metodę evaluate
        return sign*result;
    }
    int getArgumentsCount(){return args.size();}
 
 
    public String toString(){
        StringBuilder b =  new StringBuilder();
        if(sign<0)b.append("-");
        // ...
        zaimplementuj
        return b.toString();
    }
 
 
}

Testujemy implementację

Test 1

    static void buildAndPrint(){
        Variable x = new Variable("x");
        Node exp = new Sum()
                .add(2.1,new Power(x,3))
                .add(new Power(x,2))
                .add(-2,x)
                .add(7);
        System.out.println(exp.toString());
 
    }

Oczekiwany wynik: 2.1*x^3 + x^2 + (-2)*x + 7

Test 2

    static void buildAndEvaluate(){
        Variable x = new Variable("x");
        Node exp = new Sum()
                .add(new Power(x,3))
                .add(-2,new Power(x,2))
                .add(-1,x)
                .add(2);
        for(double v=-5;v<5;v+=0.1){
            x.setValue(v);
            System.out.printf(Locale.US,"f(%f)=%f\n",v,exp.evaluate());
        }

Sprawdź, jakie są pierwiastki? Możesz użyć

Test 3

    static void defineCircle(){
        Variable x = new Variable("x");
        Variable y = new Variable("y");
        Node circle = new Sum()
                .add(new Power(x,2))
                .add(new Power(y,2))
                .add(8,x)
                .add(4,y)
                .add(16);
        System.out.println(circle.toString());
 
        double xv = 100*(Math.random()-.5);
        double yv = 100*(Math.random()-.5);
        x.setValue(xv);
        y.setValue(yv);
        double fv = circle.evaluate();
        System.out.print(String.format("Punkt (%f,%f) leży %s koła %s",xv,yv,(fv<0?"wewnątrz":"na zewnątrz"),circle.toString()));
}

Znajdź i wypisz 100 punktów leżących wewnątrz okręgu…. Oczywiście napisz kod, który je znajduje ;-)

Symboliczne obliczanie pochodnych

Zadanie do realizacji w domu.

Pochodna wyrażenia jest również wyrażeniem… Dodajmy metodę diff() w klasie Node

    abstract Node diff(Variable var);

Dodajmy jeszcze metodę

    abstract boolean isZero();

która będzie służyła do optymalizacji wywołań (pomijamy wyrażenia o wartości 0).

Pochodne

Constant

Zawsze pochodną stałej jest zero.

    @Override
    Node diff(Variable var) {
        return new Constant(0);
    }

Variable

Pochodna $\frac{d}{dx}(x)=1$, natomiast $\frac{d}{dx}(y)=0$

    Node diff(Variable var) {
        if(var.name.equals(name))return new Constant(sign);
        else return new Constant(0);
    }

Power

Z definicji $\frac{d}{dx}(x^n)=nx^{n-1}$, ale tak naprawdę powinniśmy potraktować to jako złożenie funkcji $Power(arg(x)),p$, stąd

$$\frac{d}{dx}(arg(x)^n) = n\cdot arg(x)^{n-1}\cdot \frac{d}{dx}arg(x)$$

    Node diff(Variable var) {
        Prod r =  new Prod(sign*p,new Power(arg,p-1));
        r.mul(arg.diff(var));
        return r;
    }

Sum

Pochodna sumy jest sumą pochodnych. Najprostsza implementacja jest podana poniżej.

    Node diffVanilla(Variable var) {
        Sum r = new Sum();
        for(Node n:args){
            r.add(n.diff(var));
        }
        return r;
    }

Niestety, dużo pochodnych składowych będzie zerowych. Stąd propozycja usprawnienia przez sprawdzenie przed dodaniem, czy wyrażenie nie jest zerem.

Prod

Ogólny algorytm iloczynu jest podany np. tu https://en.wikipedia.org/wiki/Product_rule. Zauważmy, że stosuje się to także do funkcji stałych (w projekcie Constant):

$$\frac{d}{dx}(2\cdot f(x))=\frac{d}{dx}(2)\cdot f(x) + 2\cdot \frac{d}{dx}f(x)$$ $$=0\cdot f(x) + 2\cdot \frac{d}{dx} f(x)$$

Stąd najprostsza implementacja ma postać:

    Node diffVanilla(Variable var) {
        Sum r = new Sum();
        for(int i=0;i<args.size();i++){
            Prod m= new Prod();
            for(int j=0;j<args.size();j++){
                Node f = args.get(j);
                if(j==i)m.mul(f.diff(var));
                else m.mul(f);
            }
            r.add(m);
        }
        return r;
    }

Niestety, w jej wyniku może powstać sporo wyrażeń zerowych…

Testy

Test 1

static void diffPoly() {
        Variable x = new Variable("x");
        Node exp = new Sum()
                .add(2,new Power(x,3))
                .add(new Power(x,2))
                .add(-2,x)
                .add(7);
        System.out.print("exp=");
        System.out.println(exp.toString());
 
        Node d = exp.diff(x);
        System.out.print("d(exp)/dx=");
        System.out.println(d.toString());
 
    }

Wynik

exp=2*x^3 + x^2 + (-2)*x + 7
d(exp)/dx=0*x^3 + 2*3*x^2*1 + 2*x^1*1 + 0*x + (-2)*1 + 0

Test 2

    static void diffCircle() {
        Variable x = new Variable("x");
        Variable y = new Variable("y");
        Node circle = new Sum()
                .add(new Power(x,2))
                .add(new Power(y,2))
                .add(8,x)
                .add(4,y)
                .add(16);
        System.out.print("f(x,y)=");
        System.out.println(circle.toString());
 
        Node dx = circle.diff(x);
        System.out.print("d f(x,y)/dx=");
        System.out.println(dx.toString());
        System.out.print("d f(x,y)/dy=");
        Node dy = circle.diff(y);
        System.out.println(dy.toString());
 
    }

Wynik

f(x,y)=x^2 + y^2 + 8*x + 4*y + 16
d f(x,y)/dx=2*x^1*1 + 2*y^1*0 + 0*x + 8*1 + 0*y + 4*0 + 0
d f(x,y)/dy=2*x^1*0 + 2*y^1*1 + 0*x + 8*0 + 0*y + 4*1 + 0

Dodaj rozszerzenia i optymalizacje

Pomijaj przy sumowaniu wyrażenia zerowe Przed utworzeniem węzłów Sum i Prod umieść wyrażenia na listach.

  • Jeżeli lista jest pusta, zwróć new Constant(0)
  • Jeżeli lista zawiera jeden element, po prostu zwróć go

Wynik dla circle:

f(x,y)=x^2 + y^2 + 8*x + 4*y + 16
d f(x,y)/dx=2*x^1*1 + 8*1
d f(x,y)/dy=2*y^1*1 + 4*1

Dodaj metodę simplify() , która zastąpi iloczyn stałych pojedynczą stałą. Spłaszcz strukturę Constant()*Product(args) do pojedynczego iloczynu.

exp=2*x^3 + x^2 + (-2)*x + 7
d(exp)/dx=6*x^2 + 2*x^1 + (-2)
f(x,y)=x^2 + y^2 + 8*x + 4*y + 16
d f(x,y)/dx=2*x^1 + 8
d f(x,y)/dy=2*y^1 + 4

Dodaj klasy odpowiadające innym funkcjom, np. exp(), log(), sin(), cos(), itd… A w przyszłości może uda się rozwinąć program do postaci podobnej do https://www.derivative-calculator.net/

expand (opcjonalne)

:!: Dla zainteresowanych

Zaimplementuj metodę expand() na podstawie https://en.wikipedia.org/wiki/Multinomial_theorem

Na pewno interesującym problemem jest tu generacja wszystkich krotek $(k_1,k_2,\dots,k_m)$ spełniających $k_1+\dots+k_m=n$

Implementacja metody gradientu prostego

:!: Dla zainteresowanych. Nie jest to zadanie do wykonania, ale gotowy kod do poeksperymentowania…

O metodzie możesz przeczytać tu https://pl.wikipedia.org/wiki/Metoda_gradientu_prostego.

Jest to podstawowa metoda stosowana w uczeniu maszynowym. Zmiennymi są wagi modelu, w kolejnych iteracjach są one uaktualniane, aby zminimalizować funkcję celu.

W przypadku wielu klasycznych algorytmów funkcja celu jest funkcją wypukłą i metoda zmierza do minimum globalnego. Dla sieci neuronowych z reguły funkcja ma wiele minimów lokalnych i proces optymalizacji może zmierzać do jednego z nich.

Kluczowym elementem współczesnych implementacji jest symboliczne wyznaczenie pochodnych w postaci grafu obliczeniowego, który może być wykonywany na GPU.


W poniższym przykładzie minimalizowana jest funkcja celu $$f(x_0,\dots,x_{n-1})=\sum_{i=0}^{n-1}a_i x_i^2$$ Jej współczynniki $a_i$ oraz początkowe wartości zmiennych $x_i$ są losowane, stąd za każdym razem przebieg będzie inny. Dla konkretnej funkcji celu mozna/należy eksperymentalnie dobrać liczbę iteracji maxIter oraz stałą uczenia learningRate.

    static void testOptimization(){
        // rozmiar problemu
        int n=10;
        // hiperparametry
        int maxIter=1000;
        double learningRate=0.1;
 
        Random rand = new Random();
        // Utwórz zmienne
        List<Variable> vars= new ArrayList<>();
        for(int i=0;i<n;i++){
            vars.add(new Variable("var"+i));
        }
 
        // Zdefiniuj funkcję celu jako sum(a_i*x_i^2)
        Sum goal = new Sum();
        for(int i=0;i<n;i++){
            double a = rand.nextDouble();
            Node b = new Power(vars.get(i),2);
            goal.add(new Prod(new Constant(a),b));
        }
 
        // Wyznacz symbolicznie gradienty funkcji celu względem zmiennych x_i
        ArrayList<Node> grads = new ArrayList<>();
        for(int i=0;i<vars.size();i++){
            grads.add(goal.diff(vars.get(i)));
        }
 
        // Wylosuj poczatkowe wartosci zmiennych z przedziału [-500,500]
        for(int i=0;i<vars.size();i++){
            vars.get(i).setValue(rand.nextDouble()*1000-500);
        }
 
        // iteracja
        double[]grad_values = new double[n];
        for(int iter=0;iter<maxIter;iter++){
 
            // oblicz wartosc funkcji celu
            double goal_value = goal.evaluate();
            System.out.printf(Locale.US,"[%d] goal:%f\n",iter,goal_value);
 
            // oblicz wartosci gradientów
            // symboliczne gradienty korzystają z tych samych zmiennych, co funkcja celu
            for(int i=0;i<n;i++){
                grad_values[i] = grads.get(i).evaluate();
            }
 
            // uaktualnij wartosci zmiennych wg. wzoru x_i = x_i-lr*gradient_i
            for(int i=0;i<n;i++){
                Variable v = vars.get(i);
                v.setValue(v.getValue()-learningRate*grad_values[i]);
            }
        }
        double goal_value = goal.evaluate();
        System.out.printf(Locale.US,"[at end] goal:%f",goal_value);
    }

Poniżej przykładowy wynik (bardzo udany, często są znacznie gorsze). Oczywiście rozwiązaniem jest wektor z samymi zerami. Jeśli chcesz możesz wydrukować wartości rozwiązania w kolejnych iteracjach.

[0] goal:497945.411139
[1] goal:358421.084154
[2] goal:261261.945738
[3] goal:193012.852980
[4] goal:144625.847295
[5] goal:109985.516384
[6] goal:84935.043961
[7] goal:66631.223694
[8] goal:53116.025550
[9] goal:43031.027181
[10] goal:35426.331320
[11] goal:29632.149331
[12] goal:25172.079663
[13] goal:21704.227883
[14] goal:18980.992937
[15] goal:16821.424551
[16] goal:15092.089356
[17] goal:13693.727905
[18] goal:12551.876689
[19] goal:11610.222737
[20] goal:10825.854697
[21] goal:10165.839926
[22] goal:9604.736015
[23] goal:9122.766116
[24] goal:8704.469798
[25] goal:8337.697383
[26] goal:8012.854503
[27] goal:7722.330436
[28] goal:7460.062523
[29] goal:7221.202133
[30] goal:7001.856962
[31] goal:6798.891146
[32] goal:6609.769403
[33] goal:6432.434965
[34] goal:6265.213551
[35] goal:6106.737536
[36] goal:5955.885852
[37] goal:5811.736192
[38] goal:5673.526897
[39] goal:5540.626461
[40] goal:5412.509076
[41] goal:5288.734975
[42] goal:5168.934585
[43] goal:5052.795730
[44] goal:4940.053275
[45] goal:4830.480728
[46] goal:4723.883416
[47] goal:4620.092930
[48] goal:4518.962598
[49] goal:4420.363779
[50] goal:4324.182846
[51] goal:4230.318695
[52] goal:4138.680713
[53] goal:4049.187102
[54] goal:3961.763501
[55] goal:3876.341844
[56] goal:3792.859423
[57] goal:3711.258105
[58] goal:3631.483691
[59] goal:3553.485375
[60] goal:3477.215298
[61] goal:3402.628175
[62] goal:3329.680984
[63] goal:3258.332703
[64] goal:3188.544092
[65] goal:3120.277506
[66] goal:3053.496740
[67] goal:2988.166896
[68] goal:2924.254268
[69] goal:2861.726251
[70] goal:2800.551250
[71] goal:2740.698617
[72] goal:2682.138585
[73] goal:2624.842215
[74] goal:2568.781350
[75] goal:2513.928574
[76] goal:2460.257174
[77] goal:2407.741111
[78] goal:2356.354986
[79] goal:2306.074019
[80] goal:2256.874024
[81] goal:2208.731386
[82] goal:2161.623042
[83] goal:2115.526466
[84] goal:2070.419647
[85] goal:2026.281077
[86] goal:1983.089737
[87] goal:1940.825080
[88] goal:1899.467022
[89] goal:1858.995924
[90] goal:1819.392589
[91] goal:1780.638243
[92] goal:1742.714527
[93] goal:1705.603490
[94] goal:1669.287573
[95] goal:1633.749605
[96] goal:1598.972792
[97] goal:1564.940705
[98] goal:1531.637280
[99] goal:1499.046798
[100] goal:1467.153887
[101] goal:1435.943510
[102] goal:1405.400956
[103] goal:1375.511837
[104] goal:1346.262076
[105] goal:1317.637902
[106] goal:1289.625846
[107] goal:1262.212729
[108] goal:1235.385659
[109] goal:1209.132025
[110] goal:1183.439489
[111] goal:1158.295979
[112] goal:1133.689687
[113] goal:1109.609061
[114] goal:1086.042797
[115] goal:1062.979840
[116] goal:1040.409370
[117] goal:1018.320804
[118] goal:996.703788
[119] goal:975.548192
[120] goal:954.844103
[121] goal:934.581826
[122] goal:914.751874
[123] goal:895.344965
[124] goal:876.352018
[125] goal:857.764147
[126] goal:839.572661
[127] goal:821.769055
[128] goal:804.345008
[129] goal:787.292377
[130] goal:770.603199
[131] goal:754.269678
[132] goal:738.284191
[133] goal:722.639277
[134] goal:707.327635
[135] goal:692.342124
[136] goal:677.675756
[137] goal:663.321693
[138] goal:649.273247
[139] goal:635.523871
[140] goal:622.067161
[141] goal:608.896850
[142] goal:596.006808
[143] goal:583.391036
[144] goal:571.043663
[145] goal:558.958946
[146] goal:547.131266
[147] goal:535.555123
[148] goal:524.225138
[149] goal:513.136045
[150] goal:502.282695
[151] goal:491.660047
[152] goal:481.263168
[153] goal:471.087234
[154] goal:461.127522
[155] goal:451.379411
[156] goal:441.838382
[157] goal:432.500011
[158] goal:423.359968
[159] goal:414.414018
[160] goal:405.658017
[161] goal:397.087908
[162] goal:388.699724
[163] goal:380.489582
[164] goal:372.453682
[165] goal:364.588305
[166] goal:356.889813
[167] goal:349.354647
[168] goal:341.979322
[169] goal:334.760430
[170] goal:327.694634
[171] goal:320.778670
[172] goal:314.009344
[173] goal:307.383531
[174] goal:300.898171
[175] goal:294.550271
[176] goal:288.336904
[177] goal:282.255201
[178] goal:276.302359
[179] goal:270.475633
[180] goal:264.772337
[181] goal:259.189843
[182] goal:253.725579
[183] goal:248.377028
[184] goal:243.141726
[185] goal:238.017265
[186] goal:233.001285
[187] goal:228.091477
[188] goal:223.285583
[189] goal:218.581393
[190] goal:213.976744
[191] goal:209.469518
[192] goal:205.057644
[193] goal:200.739094
[194] goal:196.511886
[195] goal:192.374076
[196] goal:188.323766
[197] goal:184.359095
[198] goal:180.478244
[199] goal:176.679433
[200] goal:172.960917
[201] goal:169.320993
[202] goal:165.757991
[203] goal:162.270277
[204] goal:158.856253
[205] goal:155.514354
[206] goal:152.243050
[207] goal:149.040842
[208] goal:145.906263
[209] goal:142.837879
[210] goal:139.834284
[211] goal:136.894105
[212] goal:134.015997
[213] goal:131.198642
[214] goal:128.440753
[215] goal:125.741068
[216] goal:123.098353
[217] goal:120.511401
[218] goal:117.979029
[219] goal:115.500081
[220] goal:113.073424
[221] goal:110.697951
[222] goal:108.372577
[223] goal:106.096240
[224] goal:103.867902
[225] goal:101.686546
[226] goal:99.551177
[227] goal:97.460821
[228] goal:95.414525
[229] goal:93.411357
[230] goal:91.450403
[231] goal:89.530770
[232] goal:87.651584
[233] goal:85.811988
[234] goal:84.011144
[235] goal:82.248233
[236] goal:80.522453
[237] goal:78.833017
[238] goal:77.179158
[239] goal:75.560122
[240] goal:73.975174
[241] goal:72.423592
[242] goal:70.904672
[243] goal:69.417722
[244] goal:67.962068
[245] goal:66.537047
[246] goal:65.142012
[247] goal:63.776330
[248] goal:62.439381
[249] goal:61.130557
[250] goal:59.849264
[251] goal:58.594922
[252] goal:57.366960
[253] goal:56.164821
[254] goal:54.987961
[255] goal:53.835846
[256] goal:52.707952
[257] goal:51.603770
[258] goal:50.522798
[259] goal:49.464547
[260] goal:48.428537
[261] goal:47.414299
[262] goal:46.421374
[263] goal:45.449311
[264] goal:44.497671
[265] goal:43.566024
[266] goal:42.653947
[267] goal:41.761027
[268] goal:40.886862
[269] goal:40.031054
[270] goal:39.193219
[271] goal:38.372975
[272] goal:37.569954
[273] goal:36.783791
[274] goal:36.014132
[275] goal:35.260629
[276] goal:34.522941
[277] goal:33.800735
[278] goal:33.093685
[279] goal:32.401472
[280] goal:31.723783
[281] goal:31.060313
[282] goal:30.410761
[283] goal:29.774836
[284] goal:29.152250
[285] goal:28.542722
[286] goal:27.945977
[287] goal:27.361746
[288] goal:26.789767
[289] goal:26.229781
[290] goal:25.681535
[291] goal:25.144783
[292] goal:24.619283
[293] goal:24.104798
[294] goal:23.601097
[295] goal:23.107952
[296] goal:22.625142
[297] goal:22.152449
[298] goal:21.689661
[299] goal:21.236569
[300] goal:20.792970
[301] goal:20.358663
[302] goal:19.933454
[303] goal:19.517152
[304] goal:19.109569
[305] goal:18.710521
[306] goal:18.319830
[307] goal:17.937321
[308] goal:17.562820
[309] goal:17.196160
[310] goal:16.837176
[311] goal:16.485708
[312] goal:16.141596
[313] goal:15.804687
[314] goal:15.474829
[315] goal:15.151875
[316] goal:14.835679
[317] goal:14.526099
[318] goal:14.222997
[319] goal:13.926236
[320] goal:13.635684
[321] goal:13.351210
[322] goal:13.072687
[323] goal:12.799990
[324] goal:12.532996
[325] goal:12.271586
[326] goal:12.015642
[327] goal:11.765051
[328] goal:11.519700
[329] goal:11.279478
[330] goal:11.044279
[331] goal:10.813996
[332] goal:10.588528
[333] goal:10.367772
[334] goal:10.151631
[335] goal:9.940007
[336] goal:9.732805
[337] goal:9.529934
[338] goal:9.331302
[339] goal:9.136820
[340] goal:8.946402
[341] goal:8.759962
[342] goal:8.577417
[343] goal:8.398685
[344] goal:8.223686
[345] goal:8.052343
[346] goal:7.884579
[347] goal:7.720318
[348] goal:7.559487
[349] goal:7.402015
[350] goal:7.247831
[351] goal:7.096866
[352] goal:6.949053
[353] goal:6.804326
[354] goal:6.662620
[355] goal:6.523873
[356] goal:6.388021
[357] goal:6.255005
[358] goal:6.124765
[359] goal:5.997243
[360] goal:5.872382
[361] goal:5.750127
[362] goal:5.630423
[363] goal:5.513216
[364] goal:5.398455
[365] goal:5.286087
[366] goal:5.176064
[367] goal:5.068336
[368] goal:4.962855
[369] goal:4.859575
[370] goal:4.758448
[371] goal:4.659430
[372] goal:4.562477
[373] goal:4.467546
[374] goal:4.374595
[375] goal:4.283581
[376] goal:4.194465
[377] goal:4.107207
[378] goal:4.021768
[379] goal:3.938111
[380] goal:3.856197
[381] goal:3.775990
[382] goal:3.697456
[383] goal:3.620558
[384] goal:3.545262
[385] goal:3.471536
[386] goal:3.399346
[387] goal:3.328660
[388] goal:3.259448
[389] goal:3.191677
[390] goal:3.125318
[391] goal:3.060342
[392] goal:2.996719
[393] goal:2.934421
[394] goal:2.873422
[395] goal:2.813692
[396] goal:2.755207
[397] goal:2.697940
[398] goal:2.641865
[399] goal:2.586959
[400] goal:2.533195
[401] goal:2.480551
[402] goal:2.429003
[403] goal:2.378529
[404] goal:2.329105
[405] goal:2.280710
[406] goal:2.233323
[407] goal:2.186922
[408] goal:2.141487
[409] goal:2.096998
[410] goal:2.053435
[411] goal:2.010778
[412] goal:1.969009
[413] goal:1.928110
[414] goal:1.888061
[415] goal:1.848846
[416] goal:1.810447
[417] goal:1.772846
[418] goal:1.736029
[419] goal:1.699977
[420] goal:1.664675
[421] goal:1.630107
[422] goal:1.596259
[423] goal:1.563114
[424] goal:1.530659
[425] goal:1.498880
[426] goal:1.467761
[427] goal:1.437289
[428] goal:1.407451
[429] goal:1.378233
[430] goal:1.349623
[431] goal:1.321608
[432] goal:1.294176
[433] goal:1.267314
[434] goal:1.241010
[435] goal:1.215253
[436] goal:1.190032
[437] goal:1.165335
[438] goal:1.141151
[439] goal:1.117470
[440] goal:1.094281
[441] goal:1.071575
[442] goal:1.049340
[443] goal:1.027567
[444] goal:1.006247
[445] goal:0.985370
[446] goal:0.964927
[447] goal:0.944908
[448] goal:0.925306
[449] goal:0.906110
[450] goal:0.887314
[451] goal:0.868908
[452] goal:0.850885
[453] goal:0.833236
[454] goal:0.815953
[455] goal:0.799030
[456] goal:0.782458
[457] goal:0.766230
[458] goal:0.750340
[459] goal:0.734779
[460] goal:0.719542
[461] goal:0.704621
[462] goal:0.690010
[463] goal:0.675702
[464] goal:0.661692
[465] goal:0.647972
[466] goal:0.634538
[467] goal:0.621382
[468] goal:0.608500
[469] goal:0.595884
[470] goal:0.583531
[471] goal:0.571435
[472] goal:0.559589
[473] goal:0.547989
[474] goal:0.536630
[475] goal:0.525507
[476] goal:0.514615
[477] goal:0.503949
[478] goal:0.493504
[479] goal:0.483276
[480] goal:0.473260
[481] goal:0.463453
[482] goal:0.453848
[483] goal:0.444443
[484] goal:0.435233
[485] goal:0.426215
[486] goal:0.417383
[487] goal:0.408735
[488] goal:0.400266
[489] goal:0.391972
[490] goal:0.383851
[491] goal:0.375899
[492] goal:0.368111
[493] goal:0.360485
[494] goal:0.353017
[495] goal:0.345704
[496] goal:0.338542
[497] goal:0.331530
[498] goal:0.324662
[499] goal:0.317937
[500] goal:0.311352
[501] goal:0.304903
[502] goal:0.298588
[503] goal:0.292404
[504] goal:0.286348
[505] goal:0.280417
[506] goal:0.274610
[507] goal:0.268923
[508] goal:0.263354
[509] goal:0.257900
[510] goal:0.252560
[511] goal:0.247330
[512] goal:0.242209
[513] goal:0.237194
[514] goal:0.232282
[515] goal:0.227473
[516] goal:0.222763
[517] goal:0.218151
[518] goal:0.213635
[519] goal:0.209212
[520] goal:0.204881
[521] goal:0.200639
[522] goal:0.196486
[523] goal:0.192418
[524] goal:0.188435
[525] goal:0.184534
[526] goal:0.180715
[527] goal:0.176974
[528] goal:0.173311
[529] goal:0.169724
[530] goal:0.166211
[531] goal:0.162771
[532] goal:0.159402
[533] goal:0.156103
[534] goal:0.152873
[535] goal:0.149709
[536] goal:0.146611
[537] goal:0.143577
[538] goal:0.140606
[539] goal:0.137696
[540] goal:0.134847
[541] goal:0.132056
[542] goal:0.129324
[543] goal:0.126648
[544] goal:0.124028
[545] goal:0.121461
[546] goal:0.118948
[547] goal:0.116487
[548] goal:0.114077
[549] goal:0.111717
[550] goal:0.109406
[551] goal:0.107143
[552] goal:0.104926
[553] goal:0.102756
[554] goal:0.100630
[555] goal:0.098548
[556] goal:0.096510
[557] goal:0.094513
[558] goal:0.092558
[559] goal:0.090644
[560] goal:0.088769
[561] goal:0.086933
[562] goal:0.085135
[563] goal:0.083374
[564] goal:0.081650
[565] goal:0.079961
[566] goal:0.078308
[567] goal:0.076688
[568] goal:0.075102
[569] goal:0.073549
[570] goal:0.072028
[571] goal:0.070539
[572] goal:0.069080
[573] goal:0.067651
[574] goal:0.066253
[575] goal:0.064883
[576] goal:0.063541
[577] goal:0.062227
[578] goal:0.060941
[579] goal:0.059680
[580] goal:0.058447
[581] goal:0.057238
[582] goal:0.056055
[583] goal:0.054896
[584] goal:0.053761
[585] goal:0.052650
[586] goal:0.051561
[587] goal:0.050495
[588] goal:0.049451
[589] goal:0.048429
[590] goal:0.047428
[591] goal:0.046447
[592] goal:0.045487
[593] goal:0.044547
[594] goal:0.043626
[595] goal:0.042725
[596] goal:0.041841
[597] goal:0.040977
[598] goal:0.040130
[599] goal:0.039300
[600] goal:0.038488
[601] goal:0.037693
[602] goal:0.036913
[603] goal:0.036151
[604] goal:0.035403
[605] goal:0.034672
[606] goal:0.033955
[607] goal:0.033254
[608] goal:0.032566
[609] goal:0.031893
[610] goal:0.031234
[611] goal:0.030589
[612] goal:0.029957
[613] goal:0.029338
[614] goal:0.028732
[615] goal:0.028138
[616] goal:0.027556
[617] goal:0.026987
[618] goal:0.026429
[619] goal:0.025883
[620] goal:0.025349
[621] goal:0.024825
[622] goal:0.024312
[623] goal:0.023810
[624] goal:0.023318
[625] goal:0.022836
[626] goal:0.022364
[627] goal:0.021902
[628] goal:0.021450
[629] goal:0.021007
[630] goal:0.020573
[631] goal:0.020148
[632] goal:0.019731
[633] goal:0.019324
[634] goal:0.018925
[635] goal:0.018534
[636] goal:0.018151
[637] goal:0.017776
[638] goal:0.017409
[639] goal:0.017049
[640] goal:0.016697
[641] goal:0.016352
[642] goal:0.016014
[643] goal:0.015684
[644] goal:0.015360
[645] goal:0.015043
[646] goal:0.014732
[647] goal:0.014428
[648] goal:0.014130
[649] goal:0.013838
[650] goal:0.013552
[651] goal:0.013272
[652] goal:0.012998
[653] goal:0.012730
[654] goal:0.012467
[655] goal:0.012209
[656] goal:0.011957
[657] goal:0.011710
[658] goal:0.011468
[659] goal:0.011232
[660] goal:0.011000
[661] goal:0.010773
[662] goal:0.010550
[663] goal:0.010332
[664] goal:0.010119
[665] goal:0.009910
[666] goal:0.009705
[667] goal:0.009505
[668] goal:0.009309
[669] goal:0.009117
[670] goal:0.008928
[671] goal:0.008744
[672] goal:0.008563
[673] goal:0.008387
[674] goal:0.008213
[675] goal:0.008044
[676] goal:0.007878
[677] goal:0.007715
[678] goal:0.007556
[679] goal:0.007400
[680] goal:0.007247
[681] goal:0.007098
[682] goal:0.006951
[683] goal:0.006808
[684] goal:0.006667
[685] goal:0.006529
[686] goal:0.006395
[687] goal:0.006263
[688] goal:0.006133
[689] goal:0.006007
[690] goal:0.005883
[691] goal:0.005761
[692] goal:0.005642
[693] goal:0.005526
[694] goal:0.005412
[695] goal:0.005300
[696] goal:0.005191
[697] goal:0.005084
[698] goal:0.004979
[699] goal:0.004876
[700] goal:0.004775
[701] goal:0.004677
[702] goal:0.004580
[703] goal:0.004486
[704] goal:0.004393
[705] goal:0.004302
[706] goal:0.004214
[707] goal:0.004127
[708] goal:0.004042
[709] goal:0.003958
[710] goal:0.003876
[711] goal:0.003796
[712] goal:0.003718
[713] goal:0.003641
[714] goal:0.003566
[715] goal:0.003493
[716] goal:0.003421
[717] goal:0.003350
[718] goal:0.003281
[719] goal:0.003213
[720] goal:0.003147
[721] goal:0.003082
[722] goal:0.003018
[723] goal:0.002956
[724] goal:0.002895
[725] goal:0.002835
[726] goal:0.002777
[727] goal:0.002719
[728] goal:0.002663
[729] goal:0.002608
[730] goal:0.002555
[731] goal:0.002502
[732] goal:0.002450
[733] goal:0.002400
[734] goal:0.002350
[735] goal:0.002302
[736] goal:0.002254
[737] goal:0.002208
[738] goal:0.002162
[739] goal:0.002118
[740] goal:0.002074
[741] goal:0.002031
[742] goal:0.001989
[743] goal:0.001948
[744] goal:0.001908
[745] goal:0.001869
[746] goal:0.001830
[747] goal:0.001792
[748] goal:0.001755
[749] goal:0.001719
[750] goal:0.001684
[751] goal:0.001649
[752] goal:0.001615
[753] goal:0.001582
[754] goal:0.001549
[755] goal:0.001517
[756] goal:0.001486
[757] goal:0.001455
[758] goal:0.001425
[759] goal:0.001396
[760] goal:0.001367
[761] goal:0.001339
[762] goal:0.001311
[763] goal:0.001284
[764] goal:0.001258
[765] goal:0.001232
[766] goal:0.001206
[767] goal:0.001181
[768] goal:0.001157
[769] goal:0.001133
[770] goal:0.001110
[771] goal:0.001087
[772] goal:0.001064
[773] goal:0.001042
[774] goal:0.001021
[775] goal:0.001000
[776] goal:0.000979
[777] goal:0.000959
[778] goal:0.000939
[779] goal:0.000920
[780] goal:0.000901
[781] goal:0.000882
[782] goal:0.000864
[783] goal:0.000846
[784] goal:0.000829
[785] goal:0.000812
[786] goal:0.000795
[787] goal:0.000779
[788] goal:0.000763
[789] goal:0.000747
[790] goal:0.000731
[791] goal:0.000716
[792] goal:0.000702
[793] goal:0.000687
[794] goal:0.000673
[795] goal:0.000659
[796] goal:0.000645
[797] goal:0.000632
[798] goal:0.000619
[799] goal:0.000606
[800] goal:0.000594
[801] goal:0.000582
[802] goal:0.000570
[803] goal:0.000558
[804] goal:0.000546
[805] goal:0.000535
[806] goal:0.000524
[807] goal:0.000513
[808] goal:0.000503
[809] goal:0.000492
[810] goal:0.000482
[811] goal:0.000472
[812] goal:0.000462
[813] goal:0.000453
[814] goal:0.000444
[815] goal:0.000434
[816] goal:0.000426
[817] goal:0.000417
[818] goal:0.000408
[819] goal:0.000400
[820] goal:0.000391
[821] goal:0.000383
[822] goal:0.000376
[823] goal:0.000368
[824] goal:0.000360
[825] goal:0.000353
[826] goal:0.000345
[827] goal:0.000338
[828] goal:0.000331
[829] goal:0.000325
[830] goal:0.000318
[831] goal:0.000311
[832] goal:0.000305
[833] goal:0.000299
[834] goal:0.000292
[835] goal:0.000286
[836] goal:0.000281
[837] goal:0.000275
[838] goal:0.000269
[839] goal:0.000264
[840] goal:0.000258
[841] goal:0.000253
[842] goal:0.000248
[843] goal:0.000242
[844] goal:0.000237
[845] goal:0.000233
[846] goal:0.000228
[847] goal:0.000223
[848] goal:0.000218
[849] goal:0.000214
[850] goal:0.000210
[851] goal:0.000205
[852] goal:0.000201
[853] goal:0.000197
[854] goal:0.000193
[855] goal:0.000189
[856] goal:0.000185
[857] goal:0.000181
[858] goal:0.000177
[859] goal:0.000174
[860] goal:0.000170
[861] goal:0.000167
[862] goal:0.000163
[863] goal:0.000160
[864] goal:0.000157
[865] goal:0.000153
[866] goal:0.000150
[867] goal:0.000147
[868] goal:0.000144
[869] goal:0.000141
[870] goal:0.000138
[871] goal:0.000135
[872] goal:0.000133
[873] goal:0.000130
[874] goal:0.000127
[875] goal:0.000124
[876] goal:0.000122
[877] goal:0.000119
[878] goal:0.000117
[879] goal:0.000115
[880] goal:0.000112
[881] goal:0.000110
[882] goal:0.000108
[883] goal:0.000105
[884] goal:0.000103
[885] goal:0.000101
[886] goal:0.000099
[887] goal:0.000097
[888] goal:0.000095
[889] goal:0.000093
[890] goal:0.000091
[891] goal:0.000089
[892] goal:0.000087
[893] goal:0.000086
[894] goal:0.000084
[895] goal:0.000082
[896] goal:0.000080
[897] goal:0.000079
[898] goal:0.000077
[899] goal:0.000076
[900] goal:0.000074
[901] goal:0.000072
[902] goal:0.000071
[903] goal:0.000069
[904] goal:0.000068
[905] goal:0.000067
[906] goal:0.000065
[907] goal:0.000064
[908] goal:0.000063
[909] goal:0.000061
[910] goal:0.000060
[911] goal:0.000059
[912] goal:0.000058
[913] goal:0.000056
[914] goal:0.000055
[915] goal:0.000054
[916] goal:0.000053
[917] goal:0.000052
[918] goal:0.000051
[919] goal:0.000050
[920] goal:0.000049
[921] goal:0.000048
[922] goal:0.000047
[923] goal:0.000046
[924] goal:0.000045
[925] goal:0.000044
[926] goal:0.000043
[927] goal:0.000042
[928] goal:0.000041
[929] goal:0.000040
[930] goal:0.000040
[931] goal:0.000039
[932] goal:0.000038
[933] goal:0.000037
[934] goal:0.000036
[935] goal:0.000036
[936] goal:0.000035
[937] goal:0.000034
[938] goal:0.000034
[939] goal:0.000033
[940] goal:0.000032
[941] goal:0.000031
[942] goal:0.000031
[943] goal:0.000030
[944] goal:0.000030
[945] goal:0.000029
[946] goal:0.000028
[947] goal:0.000028
[948] goal:0.000027
[949] goal:0.000027
[950] goal:0.000026
[951] goal:0.000026
[952] goal:0.000025
[953] goal:0.000025
[954] goal:0.000024
[955] goal:0.000024
[956] goal:0.000023
[957] goal:0.000023
[958] goal:0.000022
[959] goal:0.000022
[960] goal:0.000021
[961] goal:0.000021
[962] goal:0.000020
[963] goal:0.000020
[964] goal:0.000020
[965] goal:0.000019
[966] goal:0.000019
[967] goal:0.000018
[968] goal:0.000018
[969] goal:0.000018
[970] goal:0.000017
[971] goal:0.000017
[972] goal:0.000017
[973] goal:0.000016
[974] goal:0.000016
[975] goal:0.000016
[976] goal:0.000015
[977] goal:0.000015
[978] goal:0.000015
[979] goal:0.000014
[980] goal:0.000014
[981] goal:0.000014
[982] goal:0.000013
[983] goal:0.000013
[984] goal:0.000013
[985] goal:0.000013
[986] goal:0.000012
[987] goal:0.000012
[988] goal:0.000012
[989] goal:0.000012
[990] goal:0.000011
[991] goal:0.000011
[992] goal:0.000011
[993] goal:0.000011
[994] goal:0.000010
[995] goal:0.000010
[996] goal:0.000010
[997] goal:0.000010
[998] goal:0.000010
[999] goal:0.000009
[at end] goal:0.000009
pz1/lab5.txt · Last modified: 2024/10/30 12:20 by pszwed
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0