C++Guns – RoboBlog blogging the bot

27.04.2017

C++ Guns - Record the result of a boolean expression

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

Habt ihr euch schon immer einmal gefragt, welche Bedingung in einer if() denn letztlich wahr wurde? Hier ist ein einfacher Weg das zu protokollieren.


inline bool test(const bool b, bool& p) {
  p = b;
  return b;
};

void func() {
  double x = 7;

// I thinks this is the best
    bool p1 = x>5;
    bool p2 = x<10;
    if(p1 and p2) {

// Or choose from this
//  bool p1 = false, p2 = false;
//  if(p=x>5 and p2=x<10) {
//  if(test(x>5, p1) and test(x<10, p2)) {
    if(p1) {
      cout << "p1 was true\n";
    }
    if(p2) {
      cout << "p2 was true\n";
    }
  }
}

Thanks to Juan Jimenez.

26.04.2017

C++ Guns - Fortran forall

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

Diesen Post möchte ich mit einem kürzlich aufgetretenen Problem in Fortran beginnen.
In Fortran gibt es das forall keyword. Damit ist es möglich Schleifen zu bauen, wie die do Schleife, nur dass es möglich ist, forall Schleifen parallel abzuarbeiten.
Eine Vorraussetzung dafür ist folgende: Wenn data der Vector ist, auf den parallel gearbeitet werden soll, dann müssen die Operationen auf data(i) und data(j) mit i != j unabhängig voneinander sein.
Das ist, für das Beispiel, welches ich hier vorstellen möchte, der Fall.

Beispiel: Jeder Punkt im Array soll transformiert, und in einem neuen Array abgespeichert werden. Hier ist die erste native Implementation:


program LLL
  use naaaah
  implicit none
  integer :: i
  type(Point2D), allocatable :: data(:), data2(:)
  real :: x
  
  allocate(data(100))
  allocate(data2(100))
  
  forall(i=1:size(data))
    x = data(i)%x * cos(data(i)%y)
    data2(i)%x = x
    data2(i)%y = data(i)%y
  end forall
end program

Und die Compiler Fehlermeldung

x = data(i)%x * cos(data(i)%y)
Warning: The FORALL with index ‘i’ is not used on the left side of the assignment at (1) and so might cause multiple assignment to this object

Das ist vollkommen richtig, WENN die forall Schleife parallel ausgeführt wird, so wird parallel auf x geschrieben. Aber x ist nur ein scalar. Daher der Fehler. Abhilfe würde schaffen, x als Array zu declarieren. Aber hier gehen bei HPC sofort alle roten Alarmglocken an und die Notbremse wird gezogen.
Okay.
Untersuchen wir jetzt das Stück Code mal nach dem "Was aber nicht Wie" Prinzip. WAS soll der Code machen? Hm keine Ahnung. WIE macht er es? Er multipliziert x in Abhängigkeit von y. Okay das ist alles, was man wissen muss, um den Code umzuschreiben. Nennen wir die neue Funktion, welche obige Multiplikation ausführt als "toLLL". Damit sieht der Code so aus:


pure function toLLL(point) result(LLLPoint)
  implicit none
  type(Point2D), intent(in) :: point
  type(Point2D) LLLpoint
  
  LLLpoint%x = point%x * cos(point%y*DEGRAD)
  LLLpoint%y = point%y
end function

forall(i=1:size(data))
  data2(i) = toLLL(data(i))
end forall

Nun compiliert der Code ohne Fehler! Warum? Weil die vermeintliche Variable x nicht mehr temporär vorkommt. Lass es mich nochmal verdeutlichen. Im alten Code hatten wir so etwas:


xTemp = xalt*fac;
xneu = xTemp

Und im neuen Code haben wir so etwas


xneu= xalt*fac;

Es gibt also keine temporäre Zwischenvariablen die irgendwie von Hand verwaltet werden müsste. PLUS, der Code ist lesbarer geworden. PLUS der Code ist performanter, da er u.U. parallel ausgeführt werden kann. Ich will nicht behaupten, dass durch das Einführen einer neuen Funktion der Code mehr Richtung Funktionale Programmierung geht. Aber er ist definitiv besser. Das wäre es erst, wenn die Funktion toLLL als Funktionsparamter mit übergeben würde. Hier ist die Grenze von Fortran erreicht. Ohne Templates muss für jede generische Variante von Point2D eine neue Funktion toLLL geschrieben werden. Und das inlinen über mehrere Compilations Units hinweg ist auch nicht möglich.

In C++ gibt es natürlich die selbe Art von Problem, aber sie können leicht gelöst werden. Von Hand geschriebene Schleifen funktionieren natürlich immer. Aber, sobald Parallelisierung in's Spiel kommt. Egal auf welcher Art und Weise auch immer, ist es nicht mehr so einfach wie früher. Parallelisierung bedeutet auf viele Kleinigkeiten achten, auf die man vorher nicht achten musste. Aber wir leben ja nicht im Mittelalter. Wie haben Programme, welche die Checks für uns durchführen. Wir müssen sie nur benutzen.
Ein Beispiel dafür wäre std::transform Hier wird keine Schleife mehr explizit aufgeschrieben. Es wird nur noch gesagt WAS getan werden sollen. Das transformieren von data mit Funktion toLLL nach data2.
Hier das komplette C++ Programm


#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>

using namespace std;

constexpr const double DEGRAD = M_PI/180.0;

struct Point2D {
  double x, y;
};

Point2D toLLL(const Point2D& point) {
  return {point.x*cos(point.y*DEGRAD), point.y};
}
  

int main() {
  vector<Point2D> data(180), data2(180);
  for(size_t i=0; i < 180; ++i) {
    data[i].x = 180;
    data[i].y = -90.0+i;
  }
  
  transform(std::execution::par, begin(data), end(data), begin(data2), toLLL);
  
  for(const Point2D& p : data2) {
    cout << p.x << " " << p.y << "\n";
  }
}

Der ersten Parameter von transform bestimmt, ob der Datensatz parallel oder sequentiell abgearbeitet werden soll. Das Einführen der Funktion toLLL verhindert temporäre Variablen, und die Funktion wird als Parameter übergeben. Das generalisieren der Funktion toLLL auf einem Point Datentyp mit beliebiger Dimension und fundamentalen Type (int,float) ist nun leicht. Beispiel:


template<class Point>
Point toLLL(const Point& point) {
  Point LLLpoint = point;
  LLLpoint[0] *= cos(LLLpoint[1]*DEGRAD);
  return LLLpoint;
}

14.04.2017

Garten - Es grünt

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

Im Vordergarten fing es an zu grünen. Leider nicht überall da, wo ich gesät haben, und auch nicht so dicht wie erhofft. Beim bewässern mit der Gießkanne hab ich wohl viele Samen weg geschwemmt. Und bei der anderen kahlen Stelle hat Sushi gebuddelt. Nunja.

rasengruent

Im Hintergarten hab ich auch alles weggerupft was nicht hingehört und neue Samen ausgetragen. Ein paar alte Grashalme stehen noch rum. Hoffentlich werden sie nicht zum Problem. Aber mehr hoffe ich, dass der Schattenrasen sich auch wirklich im Schatten wohl fühlt.

hintergartensamen

Ein letzter vergammelter Apfel war im Baum noch von letztem Jahr zu finden.

apfelvergammelt

Und ansonsten grünt es bei uns. In Grün, Blass und Lila.

gruenfarben

01.04.2017

Silberlinge und Lichtschranken

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

Die Lichtschranken endgültig zum laufen zu bringen hat zwar ewig gedaurt, aber der Erfolg ist Unser! Eigentlich war es nur eine nicht angeschlossene Abschirmung, falsche Belegung der Klemmen und mal weiss mit weiss vertauscht. Dann war der Verstärker einer Lichtschranke noch zu stark eingestellt, aber ich konnte ihn mit einem 220kOhm Widerstand dämpfen.

Zur Belohnung durften die Silberlinge noch einmal auftreten. Doch bei der Zugzusammenstellung ist dem Lokführer ein Denkfehler unterlaufen...

zuzusammenstellungsfail

Es ist jetzt auch bekannt wo kleine Lokomotiven schlafen ;)

loksschalfen

30.03.2017

C++ Guns - FVCRTTPPP

Filed under: Allgemein — Tags: — Thomas @ 11:03

Die Idee ist von Stephen C. Dewhurst [1] die Abkürzung von mir

FVCRTTPPP - Fancy Variadic Curiously Recurring Template Template Parameter Pack Pattern

Praxisbeispiel:


using FVCRTTPPPScalar = Scalar<int, Ctr, Eq, Rel, Stream>; ! A countable, equal compareable, relational-able, streamable, scalar integer type.
FVCRTTPPPScalar x = 0;

[1] http://stevedewhurst.com/once_weakly/once-weakly20170328/once-weakly20170328.pdf

29.03.2017

Biologie++ - RNA Folding with Four-Russians Speedup

Filed under: Allgemein — Tags: — Thomas @ 12:03

Der normale dynamic programing Zuker Algorithmus von Faltungen von Sequenzen hat eine Laufzeit von O(n^4), mit zuätzlichen Cache noch O(n^3). Mit der allgemeinen Four-Russians Speedup Methode für dynamic programing Algorithmen ist eine Laufzeit von O(n^3/log n) möglich. Für kleines n also absolut irrelevant. Für großes n halbiert, oder drittelt sogar die Laufzeit. Was dann aber immer noch unheimlich zu lange ist.
Aber was ist die Idee dahinter?
Als erstes wird festgestellt, dass es nicht möglich ist, die Four-Russians Technik auf die klassische Implementation des Zuker anzuwenden. Da die Auswertungsreihenfolge der Matrizen nicht passt. Also wird die Reihenfolge erst mal umgestellt. Erst kommt eine Schleife die nicht von der derzeitigen Spalte j in der Matrix abhängt. Und dann kommt eine 3fach Schleife die abhängt.
In der innersten Schleife findet nun die Optimierung statt. Die Schleife sieht so aus:

S(i,j)=max( S(i,j), S(i,k-1)+S(k,j) )

Für fixes i,j iteriert nur k von i+1 zu j-1. Die Idee ist nun, Indizes zu Gruppe der Größe q zusammen zu fassen. So dass die innerste Schleife nur noch n/q oft läuft.
Nun ja wenn sie meinen. Um das Maximum zu ermitteln, muss man so oder so jeden Wert in der Matrix in diesem Bereich anfassen. Wie die das verhindern wollen, das lese ich aus dem Paper nicht raus.
Zeitverschwendung.

[1] A Simple, Practical and Complete Time Algorithm for RNA Folding Using the Four-Russians Speedup - Yelena Frid and Dan Gusfield

27.03.2017

Biologie++ - Silver Assembly

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

Im Glas rekombinationsmthoden haben eine Einschritt Erstellung von großen DNA Sequenezen
von mehreren einzelnen ermöglicht. Obwohl synthetische biologische Schaltungen im Prinzip
auf der selben Art erstellt werden können, enthalten sie normalerweise sich wiederholende Sequenzteile,
wie promoters und terminator, die bei der Recombination stören.
Wir benutzen ein Computer gestützten Ansatz um biologische, synthetische inaktive unique nucleotide
sequences (UNSes) zu designen, die das genaue Erstellen erleichtern.
Wichtig: unsere designten UNSes machen es möglich Teile zu assemblieren die wiederholende
terminator und insulator Sequenzen enthalten. Und damit isolierte, funktionale genetische Schaltungen
in Bakterien und Säugetierzellen zu erstellen.
...

In vitro recombination methods have enabled one-
step construction of large DNA sequences from
multiple parts. Although synthetic biological
circuits can in principle be assembled in the same
fashion, they typically contain repeated sequence
elements such as standard promoters and termin-
ators that interfere with homologous recombination.
Here we use a computational approach to design
synthetic, biologically inactive unique nucleotide
sequences (UNSes) that facilitate accurate ordered
assembly. Importantly, our designed UNSes make it
possible to assemble parts with repeated terminator
and insulator sequences, and thereby create
insulated functional genetic circuits in bacteria and
mammalian cells. Using UNS-guided assembly to construct
repeating promoter-gene-terminator parts, we systematically varied gene expression to
optimize production of a deoxychromoviridans bio-
synthetic pathway in Escherichia coli. We then used
this system to construct complex eukaryotic AND-
logic gates for genomic integration into embryonic
stem cells. Construction was performed by using
a standardized series of UNS-bearing BioBrick-
compatible vectors, which enable modular assembly
and facilitate reuse of individual parts. UNS-guided
isothermal assembly is broadly applicable to the
construction and optimization of genetic circuits
and particularly those requiring tight insulation,
such as complex biosynthetic pathways, sensors,
counters and logic gates.

[1] Rapid construction of insulated genetic circuits via synthetic sequence-guided isothermal assembly. Silver et al.

25.03.2017

Garten - Rasen gesät

Filed under: Allgemein — Tags: — Thomas @ 17:03

Hoffentlich grünt es bald.

Rasensamen - hoffentlich nicht zu viele

Rasensamen - hoffentlich nicht zu viele

So sieht er aus. Der Garten vorne am Haus. Ein paar kahle Stellen und eigentlich nichts besonderes. Hinten trage ich gerade die verwurzelte, kieshaltige Oberflächenerde ab. Hoffentlich wird es was.

Kahle Flecken

Kahle Flecken

Die ersten Solarblumen sind gewachsen. Strecken sich der Sonne entgegen, welche sich, aus irgendeinem Grund, in meinem Garten, immer aus einer anderen Richtung zeigt.

Solarblume (Winterling)

Solarblume (Winterling)

C++ Guns - Dangling Reference II

Filed under: Allgemein — Tags: — Thomas @ 01:03

Für die, die es immer noch nicht kapiert haben: Hier noch ein einfachereres Beispiel. Temporäre Objekte, alles klar? Speichert keine Referenzen, es gibt kein Grund das zu tun. Sonst schießt ich euch in den Fuß. In jede Zehe einzeln.


bool alive = true;

struct Foo {
  Foo() { }
  ~Foo() { alive = false; }
};

struct Bar {
  const Foo& dangling;
  
  Bar(const Foo& foo) : dangling(foo) { }
  
  void func() {
    if(alive) {
      cout << "dangling is okay\n";
    } else {
      cout << "dangling is dangling\n";
    }
  }
};

int main() {
  Bar bar{Foo{}};
  bar.func();
  return 0;
}

23.03.2017

Gleiswendel - Theoretische Gedanken II

Filed under: Allgemein — Tags: — Thomas @ 15:03

Ein paar Gedanken kamen noch.
Ich glaube die angesetzte Durchfahrtshöhe ist zu gering. Wenn noch eine Lage Kork (h=5mm) zur Schalldämmung verbaut wird, tendiere ich doch ehr zu einem noch breiteren Kreis. Eine Schalldämmung ist für mich ein Muss. Es dröhnen die Loks ja doch stark, gerade in kleinen Räumen. Intersannt ist auch die Idee, statt dem Kreis ein Oval zu nehmen. Das bietet einige Vorteile. Zu einem kann die Steigung auf geraden Strecken höher sein, zum anderen kann der normale Kreis verbaut werden. Statt ihn mit kleinen geraden Gleisstücken aufzuweiten. So kann der Gleiswendel mit einer Tiefe von 90cm und einer Breite von z.B. 1.8m gleichzeitig als normaler großer Arbeitstisch fungieren. Nur bekommt man die eignen Füße nicht drunter.

Dünne Sperrholzplatten die als viertel Kreis ausgeschnitten werden, sollte doch gut sein. Dazu insgesamt 16 dicke (12mm) Gewindestangen die vertikal rund herum angeordnet werden. Acht außen und acht innen. Auf die Gewindestangen können Muttern geschraubt werden, welche wiederrum die Sperrholzplatten halten. So kann die Steigung durch drehen der Mutter eingestellt werden. Ein Problem ist, wie man die einzelnen Platten untereinander und an die Muttern verbindet. Zusätzliche Sperrholzplatten würde die Durchfahrtshöhe vergrößern. Aber ich denke anders geht es nicht sinnvoll.

« Newer PostsOlder Posts »

Powered by WordPress