C++Guns – RoboBlog blogging the bot

10.04.2015

Bug of the day 1

Filed under: Allgemein — Tags: — Thomas @ 08:04

Der bug of the day kommt diesmal von mir!

Ich hab mir von eine Hand voll 3D Punkten neue Z Werte berechnet.
Aber hab den Z Wert im Punkt nie aktualisiert.
Und anstatt in der Ausgabedatei nun Bloedsinn steht oder lauter 0 Eintraege,
finden sich dort Werte die mit einen berechneten immer ein bis zwei Stellen am Anfang überein stimmen.
Fortran ist seltsam.
Ghosts updates mit einem leichten Fuzzy Faktor.
Da schwappen die Bits wohl von einen ins andere CPU Register über ;)

09.04.2015

Polymorphie virtual abstract pure deconstrutor WTF?

Filed under: Allgemein — Tags: — Thomas @ 08:04

Okay ich fasse mal zusammen. Ich sehe 3 Fälle, vom einfachsten zum schwersten.

1) Ganz normal Klassen ableiten.

class Base {
public:
  ~Base() {
    cout << "~TestClass\n";
  }
};

class Derived : public TestClass {
public:
  ~Derived() {
    cout << "~Derived\n";
  }
};

int main() {
  {
  cout << "a\n";
  Derived a;
  }
  cout << "b\n";
  Derived *b = new Derived();
  delete b;
}
Ausgabe:
a                                                                                                                
~Derived                                                                                                         
~Base
b
~Derived
~Base

Der Destructor wird immer aufgerufen.
2) Mit Polymorphie (Pointer ist vom Type Base)

class Base {
public:
  virtual ~Base() {
    cout << "~TestClass\n";
  }
};

class Derived : public TestClass {
public:
  virtual ~Derived() {
    cout << "~Derived\n";
  }
};

int main() {
  {
  cout << "a\n";
  Derived a;
  }
  cout << "b\n";
  Base *b = new Derived();
  delete b;
}
Ausgabe:
a                                                                                                                
~Derived                                                                                                         
~Base
b
~Derived
~Base

Der Destructor wird immer aufgerufen.

3) Mit Polymorphie und class Derived als abstracte Klasse


class Base {
public:
  virtual ~Base() = 0;
};

Base::~Base() {
    cout << "~Base\n";
}

class Derived : public Base {
public:
  virtual ~Derived() {
    cout << "~Derived\n";
  }
};

int main() {
  {
  cout << "a\n";
  Derived a;
  }
  cout << "b\n";
  Base *b = new Derived();
  delete b;
}
Ausgabe:
a                                                                                                                
~Derived                                                                                                         
~Base
b
~Derived
~Base

Der Destructor wird immer aufgerufen.
Der Destructor von Base ist zwar abstract, es gibt aber eine default Implementation, die im Zweifel garnichts macht. Es muss immer eine Implementation der Spezialfunktionen, wie dem Destructor, geben. Wird keine explicit angegeben, erstellt automatisch der Compiler eine. (Ausser man declariert ihn mit "=0" als abstract).

Wozu das ganze? Abstrace Klassen können nicht instanziiert werden, sie dienen wirklich nur als ein abstractes Interface. Sollte man es dennoch versuchen, bekommt man folgende Compilerfehler:

error: cannot declare variable ‘c’ to be of abstract type ‘Base’
 Base c;
 note:   because the following virtual functions are pure within ‘Base’:
 virtual ~Base() = 0;

PS: Wird das virtual keyword mal vergessen, wird der Base Destructor im ungünstigen Fall nicht aufgerufen ;)

Hf

20.03.2015

Kleine Sonnenfinsternis

Filed under: Allgemein — Thomas @ 10:03

sonnenfinsternis1

sonnenfinsternis2

sonnenfinsternis3

sonnenfinsternis4

sonnenfinsternis5

sonnenfinsternis6

sonnenfinsternis7

sonnenfinsternis8

sonnenfinsternis9

sonnenfinsternis10

sonnenfinsternis11

sonnenfinsternis12

sonnenfinsternis13

sonnenfinsternis14

sonnenfinsternis15

sonnenfinsternis16

sonnenfinsternis17

sonnenfinsternis18

17.03.2015

2qm 2015 Gleisbildstellwerk

Filed under: Allgemein — Tags: , — Thomas @ 20:03

Hier ein provisorisches Gleisbildstellwerk. So oder so ähnlich könnte es aufgebaut sein.

Neue Version. Ein Abstellgleis musste weichen. Es wurde alles zu eng. Entkupplungsknopf eingezeichnet und Block-Signal eingefügt.

gleisstellbild_22.3.2015

Alte Version:

gleisstellbild

11.03.2015

Wikipedia's Kellerautomat

Filed under: Allgemein — Tags: , — Thomas @ 23:03

Wikipedia's Kellerautomat Beispiel in C ist total falsch (Stand 11.03.2015).
Nicht nur, dass es im feinsten C programmiert ist, was kein Mensch versteht. Es wird nicht mal ein Kellerautomat implementiert. Die Konfiguration eines Kellerautomats hängt von seinem Zustand, dem zu lesenden Zeichen und dem Zeichen auf dem Stack (Keller) ab.
In dem Beispiel wird aber nur das zu lesende Zeichen und der Stack benutzt. Es gibt kein expliziten Zustand des Automaten. Vielmehr wird der Zustand in dem Kellerspeicher gespeichert. Was nicht Sinn der Sache ist. Das Beispiel verwirrt also mehr, als dass es nutzt.

Ich habe den Beispielcode nach C++ Qt übersetzt und so auch den Fehler gefunden.


#include < QCoreApplication >
#include < QTextStream >
#include < QString >
#include < QDebug >
#include < QStack > 
#include < QMap >


int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    
    QStack stack;
    QTextStream ss(stdin);
    QByteArray s;

    /* Eingabestring */
    qDebug() << "Bitte Ausdruck eingeben:";

    ss >> s;
    // Wir benutzen in der  Zustandsuebergangsfunktion das Null Byte als Indikator fuer das Ende vom String.
    // Fuege es manuell in den String ein.
    s += '\0';

    /* Start-state auf Stack pushen */
    stack.push(0);

    /*
     Ein einfacher Kellerautomat ("pushdown automaton")

     Symbol   | (       | )     | \0
     ---------+---------+--------+-----------
     State 0  | PUSH 1  | ERROR  | ACCEPT
     State 1  | PUSH 1  | POP    | ERROR
    */

    enum class Actions {PUSH, POP, ERROR, ACCEPT};
    QMap< QPair< int, char>, Actions> states;
    states.insert(qMakePair(0, '('),  Actions::PUSH);
    states.insert(qMakePair(0, ')'),  Actions::ERROR);
    states.insert(qMakePair(0, '\0'), Actions::ACCEPT);
    states.insert(qMakePair(1, '('),  Actions::PUSH);
    states.insert(qMakePair(1, ')'),  Actions::POP);
    states.insert(qMakePair(1, '\0'), Actions::ERROR);


    /* Ausführungsschleife */
    bool finish = false;
    for(int i=0; i < s.size() && finish == false ; i++) {
        /* Aktion auf Basis des Eingabesymbols ermitteln */
        auto key = qMakePair(stack.top(), s.at(i));
        Actions action = states.value(key, Actions::ERROR);

        /* Ausführen der Aktionen */
        switch(action) {
        case Actions::ERROR: {
            qDebug() << "Unerwartetes Zeichen \"" << s.at(i) << "\"an Position" << i+1;
            finish = true;
            break;
        }
        case Actions::ACCEPT: {
            qDebug() << "Ausdruck akzeptiert!";
            finish = true;
            break;
        }
        case Actions::POP: {
            stack.pop();
            break;
        }
        case Actions::PUSH: {
            stack.push(1);
            break;
        }
        default:
            qDebug() << "internal error";
        }
    }

    return 0;
}

26.02.2015

rosettacode - Simple moving variance

Filed under: Allgemein — Tags: , — Thomas @ 11:02

As mentioned in my earlier post original C++ rosettacode sucks.
Here is my example for a simple moving variance and standard deviation. One has to add only a few lines of code:


in add()
...
    sum2 = sum2 - oldValue*oldValue + value*value;
...

double var() const {
    return sum2/size - avg()*avg();
}

double std() const {
    return std::sqrt(var());
}
Data1 Period 3
Added 1 avg:        1 var:        0 std: 0
Added 2 avg:      1.5 var:     0.25 std: 0.5
Added 3 avg:        2 var: 0.666667 std: 0.816497
Added 4 avg:        3 var: 0.666667 std: 0.816497
Added 5 avg:        4 var: 0.666667 std: 0.816497
Added 5 avg:  4.66667 var: 0.222222 std: 0.471405
Added 4 avg:  4.66667 var: 0.222222 std: 0.471405
Added 3 avg:        4 var: 0.666667 std: 0.816497
Added 2 avg:        3 var: 0.666667 std: 0.816497
Added 1 avg:        2 var: 0.666667 std: 0.816497

Data2 Period 8
Added 2 avg:        2 var:        0 std: 0
Added 4 avg:        3 var:        1 std: 1
Added 4 avg:  3.33333 var: 0.888889 std: 0.942809
Added 4 avg:      3.5 var:     0.75 std: 0.866025
Added 5 avg:      3.8 var:     0.96 std: 0.979796
Added 5 avg:        4 var:        1 std: 1
Added 7 avg:  4.42857 var:  1.95918 std: 1.39971
Added 9 avg:        5 var:        4 std: 2

ToDo: add Skewness and Kurtosis

23.02.2015

c++ CYK implementation

Filed under: Allgemein — Tags: — Thomas @ 14:02

Die Wikipedia Artikel zum Cocke-Younger-Kasami-Algorithmu kann man vergessen. Man kapiert nichts. Hab auf youtube ein 15min Video [1] von Benny Neugebauer dazu gefunden. Wunderbar, alles gleich verstanden :)
Hab ihn mal schnell in C++ implementiert. Hier die Hauptschleife:


    /*
    Für j = 2 ... n
      Für i = 1 ... n - j + 1
        Für k = 1 ... j - 1
          Setze V_{i,j} := V_{i,j} + { l | \exists B,C in N ((l -> BC) in P and B in V_{i,k} and C in V_{i + k, j - k}) \}

    Falls S \in V_{1,n}, stoppe und gib "w wird von G erzeugt" aus
    Stoppe und gib "w wird nicht von G erzeugt" aus
    */
    for(size_t row=1; row < n; row++) {
//        cout << "row " << row << "\n";
        for(size_t col=0; col < n-row; col++) {
//            cout << "col " << col << "\n";
            for(size_t k=0; k < row; k++) {
                const auto &e1 = V.at(k, col);
                const auto &e2 = V.at(row-k-1, col+k+1);

                for(size_t i=0; i < e1.size(); i++) {
                    for(size_t j=0; j < e2.size(); j++) {
//                        cout << "Check " << e1.at(i) << " " << e2.at(j) << "\n";
                        const Production::String toTest({e1.at(i), e2.at(j)});
                        for(const Production& p : P) {
                            if(p.right == toTest) {
                                // uniq append
                                if(contains(V.at(row, col), p.left) == false) {
                                    V.at(row, col).push_back(p.left);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

Für jeden Matrixeintrag in der oberen linken Dreiecksmatrix:
Für jeden Eintrag oberhalt in der Spalte und Diagonal nach oben:
Schaue nach ob die Konkatenation der beiden Einträge in der rechten Seite der Produktionsregeln vorkommen:
Ja) Linke Seite der Produktion in die Matrix eintragen.

Steht am Ende in der letzten Zeile, erste Spalte das Startsymbol, dann kann das Wort erkannt werden.

CYK.zip

[1] https://www.youtube.com/watch?v=JugIgxUyA4Q

18.02.2015

rosettacode - Simple moving average

Filed under: Allgemein — Tags: , , — Thomas @ 12:02

http://rosettacode.org/wiki/Averages/Simple_moving_average#C.2B.2B

The original rosetta C example shows the usage of variable function arguments. The C++ example shows how to implement a circular buffer. They are confusing and inefficient. My Version shows how to implement a simple moving average using modern c++ techniques.


#include < iostream >
#include < vector >

class SMA {
public:
    SMA(int period) : values(period), sum(0.0), idx(0), size(0) {
    }

    void add(double value) {
        const size_t period = values.size();
        // here is the magic. Update sum and vector in place
        sum = sum - values[idx] + value;
        values[idx] = value;

        // this implements the circular buffer
        idx = (idx+1)%period;
        if(size+1 <= period) {
            ++size;
        }
    }

    double avg() const {
        return sum/size;
    }

private:
    // store the last seen values
    std::vector values;
    // store the sum. so we dont have to recalculate it every time
    double sum;
    // the next element in the buffer we can override
    int idx;
    // ho many values was allready inserted. This is usually the same as the given periodb
    size_t size;
};

int main() {
    SMA foo(3);
    SMA bar(5);

    std::vector data = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };

    for(auto &val : data) {
        foo.add(val);
        std::cout << "Added " << val << " avg: " << foo.avg() << std::endl;
    }
    std::cout << std::endl;

    for(auto &val : data) {
        bar.add(val);
        std::cout << "Added " << val << " avg: " << bar.avg() << std::endl;
    }

    return 0;
}


Flussschlauch

Filed under: Allgemein — Thomas @ 10:02
Original Fluss Daten

Original Fluss Daten

Original Vermaschung

Original Vermaschung

Original Vermaschung

Original Vermaschung

With intersecting

With intersecting

Remove intersecting

Remove intersecting

refine + without intersecting

refine + without intersecting

Neuer Ansatz: cross Segmente die sich schneiden kürzen

Neuer Ansatz: cross Segmente die sich schneiden kürzen

refine + cross segmente kürzen

refine + cross segmente kürzen

refine + verbessert

refine + verbessert

need more nodes

need more nodes

Flussschleife interpoliert

Flussschleife interpoliert

0.5m refine Flussschleife interpoliert

0.5m refine Flussschleife interpoliert

11.02.2015

replace templates with c++14 auto

Filed under: Allgemein — Tags: — Thomas @ 21:02

#include < iostream >

template< class T >
T func1(T t) { return t; }

auto func2(auto t) { return t; }

int main() {
  std::cout << func1(1) << func1(2.2) << func2(3) << func2(4.4);
}

autoauto.cpp:6:18: note: deduced return type only available with -std=c++1y or -std=gnu++1y

g++ --std=c++14 autoauto.cpp 
./a.out 
12.234.4
« Newer PostsOlder Posts »

Powered by WordPress