Introduction
Introduction Statistics Contact Development Disclaimer Help
tFirst commit - numeric - C++ library with numerical algorithms
git clone git://src.adamsgaard.dk/numeric
Log
Files
Refs
LICENSE
---
commit 13bf8126e1c48f251437e9bb2b1701ecd525efdb
Author: Anders Damsgaard Christensen <[email protected]>
Date: Sun, 14 Oct 2012 11:07:41 +0200
First commit
Diffstat:
A ODEs/Makefile | 24 ++++++++++++++++++++++++
A ODEs/main.cpp | 53 ++++++++++++++++++++++++++++++
A ODEs/plot.gp | 9 +++++++++
A ODEs/rkdriver.cpp | 46 +++++++++++++++++++++++++++++…
A ODEs/rkstep.cpp | 20 ++++++++++++++++++++
A QR-dec/Makefile | 58 ++++++++++++++++++++++++++++++
A QR-dec/header.h | 17 +++++++++++++++++
A QR-dec/main.cpp | 173 +++++++++++++++++++++++++++++…
A QR-dec/plotall.gp | 9 +++++++++
A QR-dec/qrfunc.cpp | 90 +++++++++++++++++++++++++++++…
A QR-dec/qrfunc.h | 49 +++++++++++++++++++++++++++++…
A README.rst | 4 ++++
A eigen/Makefile | 69 ++++++++++++++++++++++++++++++
A eigen/header.h | 20 ++++++++++++++++++++
A eigen/jacobi.cpp | 103 +++++++++++++++++++++++++++++…
A eigen/jacobi.h | 39 +++++++++++++++++++++++++++++…
A eigen/main.cpp | 88 +++++++++++++++++++++++++++++…
A exam/Makefile | 155 +++++++++++++++++++++++++++++…
A exam/README.rst | 89 +++++++++++++++++++++++++++++…
A exam/check.cpp | 11 +++++++++++
A exam/check.h | 7 +++++++
A exam/functions.h | 25 +++++++++++++++++++++++++
A exam/html/Makefile.html | 182 +++++++++++++++++++++++++++++…
A exam/html/README.html | 406 +++++++++++++++++++++++++++++…
A exam/html/check.cpp.html | 39 +++++++++++++++++++++++++++++…
A exam/html/check.h.html | 32 +++++++++++++++++++++++++++++…
A exam/html/functions.h.html | 52 +++++++++++++++++++++++++++++…
A exam/html/mainA.cpp.html | 87 +++++++++++++++++++++++++++++…
A exam/html/mainB.cpp.html | 78 +++++++++++++++++++++++++++++…
A exam/html/mainC.cpp.html | 78 +++++++++++++++++++++++++++++…
A exam/html/mainD.cpp.html | 96 +++++++++++++++++++++++++++++…
A exam/html/ode.cpp.html | 191 +++++++++++++++++++++++++++++…
A exam/html/ode.h.html | 114 +++++++++++++++++++++++++++++…
A exam/html/plotA.gp.html | 32 +++++++++++++++++++++++++++++…
A exam/html/plotB.gp.html | 32 +++++++++++++++++++++++++++++…
A exam/html/plotC.gp.html | 33 +++++++++++++++++++++++++++++…
A exam/html/plotD.gp.html | 33 +++++++++++++++++++++++++++++…
A exam/html/typedefs.h.html | 41 +++++++++++++++++++++++++++++…
A exam/html/vector_arithmetic.h.html | 116 ++++++++++++++++++++++++++++++
A exam/mainA.cpp | 59 +++++++++++++++++++++++++++++…
A exam/mainB.cpp | 50 +++++++++++++++++++++++++++++…
A exam/mainC.cpp | 50 +++++++++++++++++++++++++++++…
A exam/mainD.cpp | 68 +++++++++++++++++++++++++++++…
A exam/ode.cpp | 163 +++++++++++++++++++++++++++++…
A exam/ode.h | 87 +++++++++++++++++++++++++++++…
A exam/plotA.gp | 8 ++++++++
A exam/plotB.gp | 8 ++++++++
A exam/plotC.gp | 9 +++++++++
A exam/plotD.gp | 9 +++++++++
A exam/typedefs.h | 15 +++++++++++++++
A exam/vector_arithmetic.h | 89 +++++++++++++++++++++++++++++…
A hello/Makefile | 71 +++++++++++++++++++++++++++++…
A hello/hello.B.cpp | 6 ++++++
A hello/hello_user.A.cpp | 19 +++++++++++++++++++
A hello/main.B.cpp | 14 ++++++++++++++
A hello/main.B.h | 8 ++++++++
A hello/your_username.B.cpp | 14 ++++++++++++++
A integration/Makefile | 71 +++++++++++++++++++++++++++++…
A integration/functions.h | 27 +++++++++++++++++++++++++++
A integration/header.h | 18 ++++++++++++++++++
A integration/integrator.cpp | 120 +++++++++++++++++++++++++++++…
A integration/integrator.h | 68 +++++++++++++++++++++++++++++…
A integration/main.cpp | 57 +++++++++++++++++++++++++++++…
A leastsq/Makefile | 67 +++++++++++++++++++++++++++++…
A leastsq/data.A.txt | 7 +++++++
A leastsq/data.B.txt | 10 ++++++++++
A leastsq/file_o.cpp | 25 +++++++++++++++++++++++++
A leastsq/header.h | 21 +++++++++++++++++++++
A leastsq/lsfit.cpp | 61 +++++++++++++++++++++++++++++…
A leastsq/lsfit.h | 41 +++++++++++++++++++++++++++++…
A leastsq/main.cpp | 89 +++++++++++++++++++++++++++++…
A leastsq/plotall.gp | 17 +++++++++++++++++
A leastsq/qrfunc.cpp | 90 +++++++++++++++++++++++++++++…
A leastsq/qrfunc.h | 49 +++++++++++++++++++++++++++++…
A matrixmul/Makefile | 150 +++++++++++++++++++++++++++++…
A matrixmul/c-arrofarrs.c | 72 +++++++++++++++++++++++++++++…
A matrixmul/c-linarr.c | 58 ++++++++++++++++++++++++++++++
A matrixmul/cpp-linvectors.cpp | 49 +++++++++++++++++++++++++++++…
A matrixmul/cpp-vectorofvectors.cpp | 49 +++++++++++++++++++++++++++++…
A matrixmul/julia.jl | 13 +++++++++++++
A matrixmul/lua-arrofarrs.lua | 30 ++++++++++++++++++++++++++++++
A matrixmul/lua-linarr.lua | 25 +++++++++++++++++++++++++
A matrixmul/octave.m | 14 ++++++++++++++
A matrixmul/plot.gp | 9 +++++++++
A matrixmul/python-numpy.py | 16 ++++++++++++++++
A montecarlo/Makefile | 89 +++++++++++++++++++++++++++++…
A montecarlo/functions.h | 20 ++++++++++++++++++++
A montecarlo/header.h | 18 ++++++++++++++++++
A montecarlo/main.cpp | 62 +++++++++++++++++++++++++++++…
A montecarlo/montecarlo.cpp | 88 +++++++++++++++++++++++++++++…
A montecarlo/montecarlo.h | 58 ++++++++++++++++++++++++++++++
A montecarlo/plot.gp | 17 +++++++++++++++++
A notes.rst | 398 +++++++++++++++++++++++++++++…
A notes/book.pdf | 0
A notes/eigen.pdf | 0
A notes/fft.pdf | 0
A notes/integration.pdf | 0
A notes/interp.pdf | 0
A notes/krylov.pdf | 0
A notes/leastsq.pdf | 0
A notes/lineq.pdf | 0
A notes/montecarlo.pdf | 0
A notes/odes.pdf | 0
A notes/roots.pdf | 0
A notes/sfun.pdf | 0
A optimization/Makefile | 69 ++++++++++++++++++++++++++++++
A optimization/downhill_simplex.cpp | 173 +++++++++++++++++++++++++++++…
A optimization/downhill_simplex.h | 61 +++++++++++++++++++++++++++++…
A optimization/functions.h | 24 ++++++++++++++++++++++++
A optimization/header.h | 12 ++++++++++++
A optimization/main.B.cpp | 93 +++++++++++++++++++++++++++++…
A optimization/main.cpp | 68 +++++++++++++++++++++++++++++…
A roots/Makefile | 74 +++++++++++++++++++++++++++++…
A roots/functions.h | 84 +++++++++++++++++++++++++++++…
A roots/header.h | 20 ++++++++++++++++++++
A roots/main.cpp | 79 +++++++++++++++++++++++++++++…
A roots/newton.cpp | 89 +++++++++++++++++++++++++++++…
A roots/qrfunc.cpp | 90 +++++++++++++++++++++++++++++…
A roots/qrfunc.h | 49 +++++++++++++++++++++++++++++…
119 files changed, 6605 insertions(+), 0 deletions(-)
---
diff --git a/ODEs/Makefile b/ODEs/Makefile
t@@ -0,0 +1,24 @@
+#!/bin/env make
+
+SHELL = /bin/sh
+CC = g++
+CFLAGS = -Wall -O3
+OBJ = rkdriver.o rkstep.o
+BIN = ode
+
+all: $(BIN) ODE.output ode.png
+
+ODE.output: $(BIN)
+ ./$(BIN) > ODE.output
+
+$(BIN): main.o rkdriver.o rkstep.o
+ $(CC) $(CFLAGS) -o $(BIN) main.o $(OBJ)
+
+clean:
+ rm -f $(BIN) *.txt *~ *.output *.png *.o
+
+%.png: plot.gp
+ gnuplot < $<
+
+edit:
+ vim -p Makefile *.cpp *.gp
diff --git a/ODEs/main.cpp b/ODEs/main.cpp
t@@ -0,0 +1,53 @@
+#include <iomanip>
+#include <cstdlib> // Exit function
+#include <string.h>
+#include <cmath>
+#include <vector>
+
+// File I/O
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+// this function gives the sign
+bool sign(double n)
+{ return n >= 0; };
+
+void rkdriver(void f(int, double, vector<double>*, vector<double>*),int n, vec…
+
+// this function simulates a cannonball
+void func1(int n, double x, vector<double>* y, vector<double>* dydx){
+ int A = sign((*y)[2]);
+ int B = sign((*y)[3]);
+ double k = 0.02;
+ double g = 9.82;
+ (*dydx)[0]=(*y)[2];
+ (*dydx)[1]=(*y)[3];
+ (*dydx)[2]=sqrt((*y)[2]*(*y)[2]+(*y)[3]*(*y)[3])*-A*k;
+ (*dydx)[3]=-g-sqrt((*y)[2]*(*y)[2]+(*y)[3]*(*y)[3])*B*k;
+};
+
+int main () {
+
+ int n=4; // Number of equations
+ int max=10000; // Maximum "iterations"
+ double a=0, b=15, h=0.01, acc=0.001, eps=0.001;
+ vector<double> tlist(max); //
+ vector<vector<double> > ylist(max,vector<double>(n));
+ tlist[0]=a; ylist[0][0]=0; ylist[0][1]=0; ylist[0][2]=100;
+ ylist[0][3]=100;
+
+ rkdriver(&func1,n,&tlist,&ylist,b,h,acc,eps,max);
+
+ // Printing the output
+ int it = 0;
+ while(tlist[it]<b) {
+ cout << tlist[it] << " ";
+ for (int j = 0; j<n;j++) cout << ylist[it][j] << " ";
+ cout << endl;
+ it++;
+ };
+
+};
+
diff --git a/ODEs/plot.gp b/ODEs/plot.gp
t@@ -0,0 +1,9 @@
+set term png enhanced
+set output "ode.png"
+set size 1.0,1.0
+set xlabel 'x'
+set ylabel 'y'
+set title "Projectile trajectory"
+plot [0:1500] [-100:500] \
+ "ODE.output" u 2:3 w p title 'data'
+
diff --git a/ODEs/rkdriver.cpp b/ODEs/rkdriver.cpp
t@@ -0,0 +1,46 @@
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include <vector>
+using namespace std;
+
+void rkstep(void f(int,double,vector<double>*,vector<double>*),int n, double t…
+
+// Main driver function
+void rkdriver(void f(int, double, vector<double>*, vector<double>*),int n, vec…
+
+ int i=0; //iterator
+ double t = (*tlist)[0];
+ double a = t;
+ vector<double> dy(n);
+ vector<double> y1(n);
+
+ while((*tlist)[i]<b) {
+ double t=(*tlist)[i];
+ vector<double> y=(*ylist)[i];
+ if(t+h>b) h=b-t;
+ rkstep(f,n,t,&y,h,&y1,&dy);
+ double err=0; for(int j=0;j<n;j++)err+=dy[j]*dy[j];
+ err=sqrt(err);
+ double normy=0; for(int j=0;j<n;j++)normy+=y1[j]*y1[j];
+ normy=sqrt(normy);
+ double tol=(normy*eps+acc)*sqrt(h/(b-a));
+
+ if(tol>err){ // accept step and go on
+ i++;
+ if(i>max-1) {
+ cout << "Reached max step \nIncrease max step to go further \n";
+ exit(1);
+ };
+
+ (*tlist)[i]=t+h;
+
+ for(int j=0;j<n;j++) (*ylist)[i][j]=y1[j];
+ };
+
+ if(err>0) h = h*pow(tol/err,0.25)*0.95;
+ else h = 2*h;
+ }//end while
+};
diff --git a/ODEs/rkstep.cpp b/ODEs/rkstep.cpp
t@@ -0,0 +1,20 @@
+#include <stdlib.h>
+#include <cmath>
+#include <vector>
+
+using namespace std;
+
+// Stepper function
+void rkstep(
+ void f(int, double, vector<double>*, vector<double>*),
+ int n, double t, vector<double>* y, double h, vector<double>* y1, vect…
+{
+ vector<double> k0(n);
+ vector<double> y12(n);
+ vector<double> k12(n);
+ (*f)(n,t,y,&k0);
+ for(int i = 0;i<n;i++) y12[i] = (*y)[i]+k0[i]*h/2;
+ (*f)(n,(t+h/2),&y12,&k12);
+ for(int i = 0;i<n;i++) (*y1)[i] = (*y)[i]+k12[i]*h;
+ for(int i = 0;i<n;i++) (*dy)[i] = (k0[i]-k12[i])*1*(h)/2;
+};
diff --git a/QR-dec/Makefile b/QR-dec/Makefile
t@@ -0,0 +1,58 @@
+# Define compiler
+CC=g++
+
+# Define compiler flags (show all warnings)
+CPPFLAGS=-Wall
+
+# Define linker flags
+LDFLAGS=
+
+# Define extra libraries to be dynamically linked
+LDLIBS+=-larmadillo
+
+# Compile optimized code
+CPPFLAGS+=-O2
+
+# Compile debuggable code
+#CPPFLAGS+=-g
+
+# Compile profilable code
+#CPPFLAGS+=-pg
+#LDFLAGS+=-pg
+
+# Define linker
+LD=g++
+
+# Filenames of source code
+SRC=$(shell ls *.cpp)
+
+# Filenames of object files
+OBJ=$(SRC:.cpp=.o)
+
+# Remove file type extension for binary filename
+BIN=qr
+
+# The default "all" depends on A and B
+
+plot.png: performance.dat
+ gnuplot plotall.gp
+
+%.dat: $(BIN)
+ ./$(BIN)
+
+$(BIN): $(OBJ)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ) -o $(BIN) $(LDLIBS)
+ @# Execute program and redirect stdout to file
+ @#./$(BIN) > out.txt
+
+clean:
+ @# Remove object files
+ rm -f $(OBJ)
+ @# Remove binary
+ rm -f $(BIN)
+ @# Remove datafiles and plot
+ rm -f *.dat *.png
+edit:
+ vim -p Makefile *.cpp *.h *.gp
+
diff --git a/QR-dec/header.h b/QR-dec/header.h
t@@ -0,0 +1,17 @@
+// Make sure header is only included once
+#ifndef header_h_
+#define header_h_
+
+// Define whether the program should output values of matrices
+const bool verbose = false;
+
+// Choose vector length variable type
+typedef int Lengthtype;
+
+// Choose floating-point precision
+typedef double Floattype;
+
+// Prototype functions
+void check(const bool statement);
+
+#endif
diff --git a/QR-dec/main.cpp b/QR-dec/main.cpp
t@@ -0,0 +1,173 @@
+#include <iostream>
+#include <fstream>
+#include <ctime>
+#include <armadillo>
+#include "header.h"
+#include "qrfunc.h"
+
+int main(int argc, char* argv[])
+{
+ // Namespace declarations
+ using std::cout;
+
+ // Timer variables
+ double tic1, toc1, tic2, toc2;
+
+ // Create 2D matrices from Armadillo templates
+ Lengthtype width;
+ if (argc == 1) // If no command line argument is given...
+ width = 4; // Matrices are 4x4.
+ else
+ width = atoi(argv[1]); // Else the specified size
+
+ const Lengthtype height = width;
+ cout << "\nInitializing " << width << " by " << height << " matrices.\n";
+ arma::mat A = arma::randu<arma::mat>(width, height);
+
+ // QR decomposition is performed upon initialization of QR class
+ tic1 = clock(); // Start clock1
+ QR qr(A);
+ toc1 = clock(); // Stop clock1
+
+ //// QR decomposition check
+ cout << "\n\033[1;33m--- QR decomposition check ---\033[0m\n";
+ if (verbose == true) {
+ // Display values to stdout
+ qr.A.print("Original A:");
+ }
+
+ // Check QR decomposition
+ if (verbose == true) {
+ qr.Q.print("Q, after QR dec:");
+ qr.Q.t().print("Q^T:");
+ qr.R.print("R, after QR dec:");
+ cout << '\n';
+ }
+
+ // Check that matrix is orthogonal
+ arma::mat QTQ = qr.Q.t()*qr.Q;
+ Floattype checksum = arma::sum(arma::sum(QTQ));
+ if (verbose == true) {
+ QTQ.print("Q^T Q:");
+ cout << "sum = " << checksum << '\n';
+ }
+ cout << "Check: Q^T Q = 1: \t";
+ check(checksum-(Floattype)height < 1e-12f);
+
+ cout << "Check: QR = A by ||QR-A|| = 0: ";
+ checksum = sum(sum((qr.Q*qr.R)-qr.A));
+ check(checksum < 1e-12f);
+
+
+ //// Solving linear equations
+ cout << "\n\033[1;33m--- Solving linear equations: Ax=b ---\033[0m\n";
+ cout << "Solving QRx=b.\n";
+ arma::vec b = arma::randu<arma::vec>(qr.size());
+
+ // Perform back-substitution of QR system
+ if (verbose == true) {
+ b.print("Vector b:");
+ }
+
+ arma::vec x = qr.backsub(b);
+
+ if (verbose == true) {
+ x.print("Solution, x:");
+ }
+
+ cout << "Check: Ax = b by |Ax-b| = 0: ";
+ checksum = arma::sum(arma::sum(qr.A*x - b));
+ check(checksum < 1e-12f);
+
+ //// Calculating the determinant
+ cout << "\n\033[1;33m--- Determinant of A ---\033[0m\n";
+ cout << "|det(A)| = " << qr.det() << '\n';
+
+ //// Calculating the inverse
+ cout << "\n\033[1;33m--- Inverse of A ---\033[0m\n";
+ arma::mat Ainv = qr.inverse();
+ if (verbose == true)
+ Ainv.print("A^(-1):");
+ cout << "Check: (A^(-1))^(-1) = A: ";
+ QR qrinv(Ainv);
+ arma::mat Ainvinv = qrinv.inverse();
+ bool equal = true; // Elementwise comparison of values
+ for (Lengthtype i=0; i<width; ++i) {
+ for (Lengthtype j=0; j<height; ++j) {
+ if (fabs(A(i,j)-Ainvinv(i,j)) > 1e12f) {
+ equal = false;
+ cout << "At (" << i << "," << j << ") = "
+ << "A = " << A(i,j)
+ << ", (A^(-1))^(-1) = " << Ainvinv(i,j) << '\n';
+ }
+ }
+ }
+ check(equal);
+
+ //// Use the Armadillo built-in QR decomposition
+ tic2 = clock(); // Start clock2
+ arma::mat Q, R;
+ arma::qr(Q, R, A);
+ toc2 = clock(); // Stop clock2
+
+ //// Statistics
+ // Print resulting time of homegrown function and Armadillo function
+ cout << "\n\033[1;33m--- Performance comparison ---\033[0m\n";
+ double t1 = (toc1 - tic1)/(CLOCKS_PER_SEC);
+ double t2 = (toc2 - tic2)/(CLOCKS_PER_SEC);
+ cout << "Homegrown implementation: \t" << t1 << " s \n"
+ << "Armadillo implementation: \t" << t2 << " s \n";
+
+ cout << "Benchmarking performance across a range of sizes...\n";
+
+ // Write results to file
+ std::ofstream outstream;
+ // Open outfile for write
+ outstream.open("performance.dat");
+ double homegrown_time, armadillo_time;
+
+ // Define sizes
+ Lengthtype dims[] = {32, 64, 128, 256, 512, 1024, 2048};
+ Lengthtype ndims = sizeof(dims)/sizeof(int); // Number of entries in dims
+
+ // Loop through sizes and record performance
+ for (Lengthtype i=0; i<ndims; ++i) {
+ cout << " " << dims[i] << std::flush;
+ // Generate input matrix
+ arma::mat An = arma::randu<arma::mat>(dims[i],dims[i]);
+
+ // Homegrown implementation
+ tic1 = clock();
+ QR qrn = QR(An);
+ toc1 = clock();
+
+ // Armadillo implementation
+ tic2 = clock();
+ arma::mat Qn, Rn;
+ arma::qr(Qn, Rn, An);
+ toc2 = clock();
+
+ // Record time spent
+ homegrown_time = (toc1 - tic1)/(CLOCKS_PER_SEC);
+ armadillo_time = (toc2 - tic2)/(CLOCKS_PER_SEC);
+
+ // Write time to file in three columns
+ outstream << dims[i] << '\t' << homegrown_time << '\t' << armadillo_time <…
+ }
+
+ cout << '\n';
+ // Close file
+ outstream.close();
+
+ // Return successfully
+ return 0;
+}
+
+void check(const bool statement)
+{
+ using std::cout;
+ if (statement == true)
+ cout << "\t\033[0;32mPassed\033[0m\n";
+ else
+ cout << "\t\033[1;31mFail!!\033[0m\n";
+}
diff --git a/QR-dec/plotall.gp b/QR-dec/plotall.gp
t@@ -0,0 +1,9 @@
+set terminal png # Set output file format
+set output "plot.png" # Set output filename
+set key top left
+set xlabel "Matrix width and height"
+set ylabel "Execution time [s]"
+set title "Performance comparison of QR decomposition"
+set log xy
+set grid
+plot "performance.dat" u 1:2 title "Homegrown" w lp, "performance.dat" u 1:3 t…
diff --git a/QR-dec/qrfunc.cpp b/QR-dec/qrfunc.cpp
t@@ -0,0 +1,90 @@
+#include <iostream>
+#include <armadillo>
+#include "header.h"
+#include "qrfunc.h"
+
+// QR decomposition constructor
+QR::QR(arma::mat &A)
+ : n(A.n_cols),
+ A(A),
+ Q(A)
+{
+ // Initialize output structures
+ R = arma::zeros<arma::mat> (n,n);
+
+ // Perform QR decomposition straight away
+ decomp();
+}
+
+// Class deconstructor (equivalent to compiler destructor)
+QR::~QR() { };
+
+// Return system size
+Lengthtype QR::size()
+{
+ return n;
+}
+
+// QR decomposition function of Armadillo matrix.
+// Returns right matrix R, and modifies A into Q.
+// Uses Gram-Schmidt orthogonalization
+void QR::decomp()
+{
+ Floattype r, s;
+ Lengthtype j;
+ for (Lengthtype i=0; i<n; ++i) {
+ r = dot(Q.col(i), Q.col(i));
+ R(i,i) = sqrt(r);
+ Q.col(i) /= sqrt(r); // Normalization
+ for (j=i+1; j<n; ++j) {
+ s = dot(Q.col(i), Q.col(j));
+ Q.col(j) -= s*Q.col(i); // Orthogonalization
+ R(i,j) = s;
+ }
+ }
+}
+
+// Solve the square system of linear equations with back
+// substitution. T is an upper triangular matrix.
+arma::vec QR::backsub(arma::vec &b)
+{
+ Floattype tmpsum;
+ arma::vec x = Q.t() * b;
+ for (Lengthtype i=n-1; i>=0; --i) {
+ tmpsum = 0.0f;
+ for (Lengthtype k=i+1; k<n; ++k)
+ tmpsum += R(i,k) * x(k);
+
+ x(i) = 1.0f/R(i,i) * (x(i) - tmpsum);
+ }
+ return x;
+}
+
+// Calculate the (absolute value of the) determinant of
+// matrix A given the Q and R components.
+// det(A) = det(Q) * det(R), |det(Q) = 1|
+// => |det(A)| = |det(R)|
+Floattype QR::det()
+{
+ Floattype determinant = 1.0f;
+ for (Lengthtype i=0; i<n; ++i)
+ determinant *= R(i,i);
+ return fabs(determinant);
+}
+
+// Calculate the inverse of matrix A given the Q and R
+// components.
+arma::mat QR::inverse()
+{
+ arma::mat inv = arma::zeros<arma::mat> (n, n);
+ // In vector z, all elements are equal to 0, except z(i) = 1
+ arma::vec z = arma::zeros<arma::mat> (n);
+
+ for (Lengthtype i=0; i<n; ++i) {
+ z(i) = 1.0f; // Element i changed to 1
+ inv.col(i) = backsub(z);
+ z(i) = 0.0f; // Element i changed back to 0
+ }
+
+ return inv;
+}
diff --git a/QR-dec/qrfunc.h b/QR-dec/qrfunc.h
t@@ -0,0 +1,49 @@
+// Make sure header is only included once
+#ifndef qrfunc_h_
+#define qrfunc_h_
+
+#include <armadillo>
+#include "header.h"
+
+// QR structure
+class QR {
+ private:
+ // System size
+ const Lengthtype n;
+
+ public:
+ //// Data
+
+ // Input data
+ arma::mat A;
+
+ // QR decomposition matrices
+ arma::mat Q;
+ arma::mat R;
+
+ //// Prototype functions
+
+ // Constructor prototype
+ QR(arma::mat &A);
+
+ // Destructor
+ ~QR();
+
+ // Return system size
+ Lengthtype size();
+
+ // QR decomposition of Armadillo matrix A, returning R
+ // and modified A (=Q)
+ void decomp();
+
+ // Backsubstitution of triangular system
+ arma::vec backsub(arma::vec &b);
+
+ // Absolute value of the determinant of matrix R
+ Floattype det();
+
+ // Inverse of matrix A
+ arma::mat inverse();
+};
+
+#endif
diff --git a/README.rst b/README.rst
t@@ -0,0 +1,4 @@
+numeric
+=======
+
+Routines written in C++ to handle various numerical routines. Code is written …
diff --git a/eigen/Makefile b/eigen/Makefile
t@@ -0,0 +1,69 @@
+# Define compiler
+CC=g++
+
+# Define compiler flags (show all warnings)
+CPPFLAGS=-Wall
+
+# Define linker flags
+LDFLAGS=
+
+# Define extra libraries to be dynamically linked
+LDLIBS+=-larmadillo
+
+# Compile optimized code
+#CPPFLAGS+=-O2
+
+# Compile debuggable code
+#CPPFLAGS+=-g
+
+# Compile profilable code
+#CPPFLAGS+=-pg
+#LDFLAGS+=-pg
+
+# Define linker
+LD=g++
+
+# Filenames of source code
+SRC=$(shell ls *.cpp)
+
+# Filenames of object files
+OBJ=$(SRC:.cpp=.o)
+
+# Remove file type extension for binary filename
+BIN=eigen
+
+# The default "all" depends on A and B
+
+#all: A B
+A:
+ ./eigen 11
+
+#A: plot.A.png
+
+#B: plot.B.png
+
+#plot.%.png: fit.A.dat fit.B.dat data.A.txt data.B.txt
+# gnuplot plotall.gp
+
+#fit.A.dat: $(BIN)
+# ./$(BIN) data.A.txt fit.A.dat
+
+#fit.B.dat: $(BIN)
+# ./$(BIN) data.B.txt fit.B.dat
+
+$(BIN): $(OBJ)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ) -o $(BIN) $(LDLIBS)
+ @# Execute program and redirect stdout to file
+ @#./$(BIN) > out.txt
+
+clean:
+ @# Remove object files
+ rm -f $(OBJ)
+ @# Remove binary
+ rm -f $(BIN)
+ @# Remove datafiles and plot
+ #rm -f *.dat *.png
+edit:
+ vim -p Makefile *.cpp *.h *.gp
+
diff --git a/eigen/header.h b/eigen/header.h
t@@ -0,0 +1,20 @@
+// Make sure header is only included once
+#ifndef HEADER_H_
+#define HEADER_H_
+
+// Define whether the program should output values of matrices
+const bool verbose = false;
+//const bool verbose = true;
+
+// Choose vector length variable type
+typedef int Lengthtype;
+
+// Choose floating-point precision
+//typedef float Floattype;
+typedef double Floattype;
+//typedef long double Floattype;
+
+// Prototype for checking function
+void check(const bool statement);
+
+#endif
diff --git a/eigen/jacobi.cpp b/eigen/jacobi.cpp
t@@ -0,0 +1,103 @@
+#include <iostream>
+#include <cmath>
+#include <armadillo>
+#include "header.h"
+#include "jacobi.h"
+
+// Constructor: Perform rotation straight away
+Jacobi::Jacobi(const arma::Mat<Floattype> &A)
+ : n(A.n_rows), At(A), e(n), V(n,n)
+{
+ // Initialize diagonal vector to be filled with eigenvalues
+ e = A.diag();
+
+ // Set main diagonal values to 1, off-diagonal values to 0
+ V.eye();
+
+ Lengthtype p, q, i; // Iterator vars
+ int changed;
+ Lengthtype rotations = 0; // Number of rotations performed
+
+ // Cell value variables, used as local storage for mat/vec vals.
+ Floattype app, aqq, apq, phi, c, s, app1, aqq1;
+ Floattype aip, api, aiq, aqi, vip, viq;
+
+ do {
+ changed = 0;
+ for (p=0; p<n; ++p) { // Row iteration
+ for (q=p+1; q<n; ++q) { // Cols right of diagonal
+
+ // Initialize cell-relevant data
+ app = e(p);
+ aqq = e(q);
+ apq = At(p,q);
+ phi = 0.5f * atan2(2.0f * apq, aqq-app);
+ c = cos(phi);
+ s = sin(phi);
+ app1 = c*c * app - 2.0f * s * c * apq + s*s * aqq;
+ aqq1 = s*s * app + 2.0f * s * c * apq + c*c * aqq;
+
+ if (app1 != app || aqq1 != aqq) {
+ changed = 1;
+ ++rotations;
+ e(p) = app1;
+ e(q) = aqq1;
+ At(p,q) = 0.0f;
+
+ for (i = 0; i<p; ++i) {
+ aip = At(i,p);
+ aiq = At(i,q);
+ At(i,p) = c * aip - s * aiq;
+ At(i,q) = c * aiq + s * aip;
+ }
+
+ for (i=p+1; i<q; ++i) {
+ api = At(p,i);
+ aiq = At(i,q);
+ At(p,i) = c * api - s * aiq;
+ At(i,q) = c * aiq + s * api;
+ }
+
+ for (i=q+1; i<n; ++i) {
+ api = At(p,i);
+ aqi = At(q,i);
+ At(p,i) = c * api - s * aqi;
+ At(q,i) = c * aqi + s * api;
+ }
+
+ for (i=0; i<n; ++i) {
+ vip = V(i,p);
+ viq = V(i,q);
+ V(i,p) = c * vip - s * viq;
+ V(i,q) = c * viq + s * vip;
+ }
+
+ } // if end
+ } // q loop end
+ } // p loop end
+ } while (changed != 0); // do-while end
+
+ // Make transformed matrix symmetric
+ At = arma::symmatu(At);
+
+ if (verbose == true)
+ std::cout << "\nPerformed " << rotations << " Jacobi rotations.\n";
+}
+
+// Return transformed matrix
+arma::Mat<Floattype> Jacobi::trans()
+{
+ return At;
+}
+
+// Return matrix of eigenvectors
+arma::Mat<Floattype> Jacobi::eigenvectors()
+{
+ return V;
+}
+
+// Return vector of eigenvalues
+arma::Col<Floattype> Jacobi::eigenvalues()
+{
+ return e;
+}
diff --git a/eigen/jacobi.h b/eigen/jacobi.h
t@@ -0,0 +1,39 @@
+// Make sure header is only included once per object
+#ifndef JACOBI_H_
+#define JACOBI_H_
+
+#include <armadillo>
+#include "header.h"
+
+// lsfit structure
+class Jacobi {
+ private:
+ const Lengthtype n; // Matrix width and height
+
+ // Transformed matrix A: At
+ arma::Mat<Floattype> At;
+
+ // Diagonal
+ arma::Col<Floattype> e;
+
+ // Matrix of eigenvectors
+ arma::Mat<Floattype> V;
+
+ public:
+
+ // Constructor. Arguments: input matrix
+ Jacobi(const arma::Mat<Floattype> &A);
+
+ // Destructor
+ //~Jacobi();
+
+ // Return transformed matrix
+ arma::Mat<Floattype> trans();
+
+ // Return matrix of eigenvectors
+ arma::Mat<Floattype> eigenvectors();
+
+ // Return vector of eigenvalues
+ arma::Col<Floattype> eigenvalues();
+};
+#endif
diff --git a/eigen/main.cpp b/eigen/main.cpp
t@@ -0,0 +1,88 @@
+#include <iostream>
+#include <armadillo>
+#include "header.h"
+#include "jacobi.h"
+
+int main(int argc, char* argv[])
+{
+ // Namespace declarations
+ using std::cout;
+
+ // Define matrix size
+ Lengthtype msize = 6;
+ if (argc == 2) {
+ if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
+ cout << "Usage: " << argv[0] << " [matrix size]\n"
+ << "If matrix size is not specified, "
+ << "the matrix width and length will be "
+ << msize << ".\n";
+ return 1;
+ }
+ msize = atoi(argv[1]); // Use specified matrix size
+ }
+
+ // Calculate machine precision
+ Floattype eps = 1.0f;
+ while (1.0f + eps != 1.0f)
+ eps /= 2.0f;
+ //cout << "Machine precision of '" << typeid(eps).name()
+ // << "' type is: eps = " << eps << '\n';
+
+ Floattype checksum;
+ // Generate input matrix A, which is symmetric
+ cout << "\n\033[1;33m--- Input data check ---\033[0m\n";
+ arma::Mat<Floattype> A = symmatu(arma::randu< arma::Mat<Floattype> > (msize,…
+ checksum = arma::sum(arma::sum(A - A.t()));
+ cout << "Symmetry check: A = A^T: ";
+ check(checksum < eps);
+ if (verbose == true) {
+ A.print("Original matrix:");
+ }
+
+ // Perform Jacobi diagonalization of matrix A
+ Jacobi Diag = Jacobi(A);
+
+ cout << "\n\033[1;33m--- Diagonalization check ---\033[0m\n";
+ if (verbose == true)
+ Diag.trans().print("Transformed matrix (At):");
+ cout << "Check: V V^T = 1: \t";
+ checksum = arma::sum(arma::sum(Diag.eigenvectors().t() * Diag.eigenvectors()…
+ check(fabs(checksum - (Floattype)msize) < eps*msize*msize);
+ if (verbose == true) {
+ Diag.eigenvalues().print("Eigenvalues (e):");
+ Diag.eigenvectors().print("Eigenvectors (V):");
+ Diag.eigenvectors().t().print("V^T");
+ (Diag.eigenvectors() * Diag.eigenvectors().t()).print("V V^T");
+ (Diag.eigenvectors().t() * A * Diag.eigenvectors()).print("V^T A V");
+ (Diag.eigenvectors().t() * Diag.trans() * Diag.eigenvectors()).print("V^T …
+ }
+
+ // Armadillo implementation
+ arma::Mat<Floattype> V_a (msize, msize);
+ arma::Col<Floattype> e_a (msize);
+ arma::eig_sym(e_a, V_a, A);
+ if (verbose == true) {
+ e_a.print("Armadillo eigenvalues:");
+ V_a.print("Armadillo eigenvectors:");
+ }
+ cout << "\n\033[1;33m--- Armadillo comparison ---\033[0m\n";
+ checksum = arma::sum(arma::sum(V_a - Diag.eigenvectors()));
+ cout << "Eigenvectors identical:\t";
+ check(checksum < eps*msize*msize*2);
+ checksum = arma::sum(arma::sum(e_a - Diag.eigenvalues()));
+ cout << "Eigenvalues identical: \t";
+ check(checksum < eps*msize*2);
+
+
+ // Return successfully
+ return 0;
+}
+
+void check(const bool statement)
+{
+ using std::cout;
+ if (statement == true)
+ cout << "\t\033[0;32mPassed\033[0m\n";
+ else
+ cout << "\t\033[1;31mFail!!\033[0m\n";
+}
diff --git a/exam/Makefile b/exam/Makefile
t@@ -0,0 +1,155 @@
+# Define compiler
+#CXX=g++
+
+# Define compiler flags (show all warnings)
+CXXFLAGS=-Wall
+#CXXFLAGS=-std=c++0x
+
+# Define linker flags
+#LDFLAGS=-fopenmp
+
+# Compile optimized code
+CXXFLAGS+=-O2
+
+# Compile debuggable code
+#CXXFLAGS+=-g
+
+# Compile profilable code
+#CXXFLAGS+=-pg
+#LDFLAGS+=-pg
+
+# Define linker
+LD=g++
+
+# All source code files
+SRC=$(shell ls *.cpp)
+
+
+# Filenames of source code
+SHARED_SRC=ode.cpp check.cpp
+SHARED_HEADERS=typedefs.h ode.h functions.h check.h
+SRC_A=mainA.cpp $(SHARED_SRC)
+HEAD_A=$(SHARED_HEADERS)
+SRC_B=mainB.cpp $(SHARED_SRC)
+HEAD_B=$(SHARED_HEADERS)
+SRC_C=mainC.cpp $(SHARED_SRC)
+HEAD_C=$(SHARED_HEADERS)
+SRC_D=mainD.cpp $(SHARED_SRC)
+HEAD_D=$(SHARED_HEADERS)
+
+# Filenames of object files
+OBJ_A=$(SRC_A:.cpp=.o)
+OBJ_B=$(SRC_B:.cpp=.o)
+OBJ_C=$(SRC_C:.cpp=.o)
+OBJ_D=$(SRC_D:.cpp=.o)
+
+# Remove file type extension for binary filename
+BIN_A=odeA
+BIN_B=odeB
+BIN_C=odeC
+BIN_D=odeD
+
+# Define editor and options for `make edit`
+EDITOR=vim -p
+
+
+# The default "all" depends on A and B
+all: A B C D
+
+A: plotA.png
+
+B: plotB.png
+
+C: plotC.png
+
+D: plotD.png
+
+plotA.png: funcA.dat plotA.gp
+ # Gnuplot: plotA.png
+ @gnuplot plotA.gp
+
+plotB.png: funcB.dat plotB.gp
+ # Gnuplot: plotB.png
+ @gnuplot plotB.gp
+
+plotC.png: funcC.dat plotC.gp
+ # Gnuplot: plotC.png
+ @gnuplot plotC.gp
+
+plotD.png: funcD.dat plotD.gp
+ # Gnuplot: plotD.png
+ @gnuplot plotD.gp
+
+funcA.dat: $(BIN_A)
+ @./$(BIN_A)
+
+funcB.dat: $(BIN_B)
+ @./$(BIN_B)
+
+funcC.dat: $(BIN_C)
+ @./$(BIN_C)
+
+funcD.dat: $(BIN_D)
+ @./$(BIN_D)
+
+$(BIN_A): $(OBJ_A) $(HEAD_A)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ_A) -o $@ $(LDLIBS)
+
+$(BIN_B): $(OBJ_B) $(HEAD_B)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ_B) -o $@ $(LDLIBS)
+
+$(BIN_C): $(OBJ_C) $(HEAD_C)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ_C) -o $@ $(LDLIBS)
+
+$(BIN_D): $(OBJ_D) $(HEAD_D)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ_D) -o $@ $(LDLIBS)
+
+clean: cleanA cleanB cleanC cleanD
+
+cleanA:
+ @# Remove object files
+ rm -f $(OBJ_A)
+ @# Remove binaries
+ rm -f $(BIN_A)
+ @# Remove datafiles and plot
+ rm -f funcA.dat plotA.png
+
+cleanB:
+ @# Remove object files
+ rm -f $(OBJ_B)
+ @# Remove binaries
+ rm -f $(BIN_B)
+ @# Remove datafiles and plot
+ rm -f funcB.dat plotB.png
+
+cleanC:
+ @# Remove object files
+ rm -f $(OBJ_C)
+ @# Remove binaries
+ rm -f $(BIN_C)
+ @# Remove datafiles and plot
+ rm -f funcC.dat plotC.png
+
+cleanD:
+ @# Remove object files
+ rm -f $(OBJ_D)
+ @# Remove binaries
+ rm -f $(BIN_D)
+ # Removing datafile and plot
+ @rm -f funcD.dat plotD.png
+
+htmlfiles: html/mainA.cpp.html html/mainB.cpp.html html/mainC.cpp.html html/ma…
+ # Generating HTML files
+ rst2html2 README.rst > html/README.html
+
+html/%.html: %
+ vim $< +TOhtml +"w $@" +"qall!"
+
+
+edit:
+ @$(EDITOR) Makefile README.rst *.cpp *.h *.gp
+
diff --git a/exam/README.rst b/exam/README.rst
t@@ -0,0 +1,89 @@
+============================================
+README: ODE integration with complex numbers
+============================================
+Exam exercise for *Numerical Methods* by Anders D. Christensen (mail_)
+
+File description
+----------------
+- ``Makefile``: Description for GNU Make, handles compilation and execution.
+- ``README.rst`` (this file): Description of numeric implementation and usage.
+ Written with reStructuredText syntax.
+- ``check.cpp``: Function for displaying the state of a condition to stdout.
+- ``check.h``: Prototype for the check-function.
+- ``functions.h``: Input functions to be evaluated.
+- ``mainA.cpp``: Main source code file for part A.
+- ``ode.cpp``: Constructor and functions for the ODE class, including Runge-Ku…
+ stepper and driver.
+- ``ode.h``: Header file with the ODE class. This file must be included in all
+ programs that want to utilize the ODE functionality.
+- ``plot.gp``: Script for plotting all graphs with Gnuplot.
+- ``typedefs.h``: Header file containing definitions of two main types,
+ ``Inttype``, a whole-number type, and ``Floattype``, a floating point number
+ type. The type definitions can be changed to different lengths and precision…
+ The program can be compiled for verbose output by changing the ``verbose``
+ variable.
+- ``vector_arithmetic.h``: Operator overloading functions for the ``std::vecto…
+ class.
+
+Problem descriptions
+--------------------
+The four generated executables each demonstrate the ODE solvers functionality …
+performing the following tasks. The results consist of the console output and
+the corresponding plot with filename ``plot<Character>.png``.
+- *A*: Construct an ODE solver that can handle functions with complex values.
+Demonstrate that it solves the real component correctly, by stepping along
+a path in the real range.
+- *B*: Demonstrate that the ODE solver can solve the imaginary component by
+stepping along a path in the imaginary range.
+- *C*: Demonstrate the solution of a set of complex equations by stepping
+through the complex plane.
+- *D*: For an integration path in the complex plane, visualize how the
+requirements of absolute- and relative precision are related to the number of
+integration steps, for a given floating point precision.
+
+Implementation
+--------------
+This exercise was written in object-oriented C++ for easy reuse. For
+portability, all included classes are from the standard template library.
+
+The necessary ``std::vector`` arithmetic operations where overloaded to support
+element-wise operations, such as vector-scalar multiplication, vector-vector
+addition, etc. This approach was preferred over using ``std::valarray``, since…
+is not dynamically expandable.
+
+When creating a new ODE object, the user specifies the end-points of the linear
+range, where the specified system of ordinary differential equations with
+complex values will be solved. The range end-points are complex numbers
+themselves, and the user can thus specify whether the integrator steps through…
+range of real values, imaginary values, or both components in the complex plan…
+
+The solver steps through the specified range by an adaptive step size, which is
+also a complex number. The user specifies the fraction of the range to be used
+as a start value for the step. The default value is 0.01.
+
+The ODE class contains functions for writing the ODE solution to stdout
+(``ODE::print``) or to a text file (``ODE::write``). The output format is the
+following; the first column is the real part of x, second column the imaginary
+part. The subsequent columns do in turn consist of real- and imaginary parts …
+the variables in the ODE.
+
+The program requires a modern C++ compiler, GNU Make and Gnuplot. It has been
+tested with GCC, Clang and llvm.
+
+Compiliation and execution
+--------------------------
+To make and execute the program, go to the root folder and type `make`. This
+will compile and execute the programs for part A-D, and plot output graphs. If
+desired, individual parts can be compiled and executed using `make <Character>…
+
+To view the source code in a browser with vim's syntax highlighting, type `make
+html`, and view the files in the `html` folder. The generation of HTML files
+requires a newer vim for the source code files, and Docutils for the readme.
+
+All output and objects can be removed using `make clean`.
+
+
+
+.. _mail: mailto:[email protected]
+
+#vim: set tw=80
diff --git a/exam/check.cpp b/exam/check.cpp
t@@ -0,0 +1,11 @@
+// Function used for reporting the condition of a
+// statement to stdout using ANSI colors.
+#include <iostream>
+
+void check(const bool statement)
+{
+ if (statement == true)
+ std::cout << "\t\033[0;32mPassed\033[0m\n";
+ else
+ std::cout << "\t\033[1;31mFail!!\033[0m\n";
+}
diff --git a/exam/check.h b/exam/check.h
t@@ -0,0 +1,7 @@
+#ifndef CHECK_H_
+#define CHECK_H_
+
+// Prototype for checking function
+void check(const bool statement);
+
+#endif
diff --git a/exam/functions.h b/exam/functions.h
t@@ -0,0 +1,25 @@
+// Make sure file is only included once per object
+#ifndef FUNCTIONS_H_
+#define FUNCTIONS_H_
+
+#include <vector>
+#include <complex>
+#include "typedefs.h"
+
+
+//// ODEs with real+complex parts.
+//// Return the derivatives at the point x,vec(y)
+
+std::vector<std::complex<Floattype> >
+ func1(const std::complex<Floattype> z,
+ const std::vector<std::complex<Floattype> > &y)
+{
+ std::vector<std::complex<Floattype> > dydz(2);
+ dydz[0].real() = y[1].real();
+ dydz[0].imag() = y[1].imag();
+ dydz[1].real() = -y[0].real();
+ dydz[1].imag() = 0.5f*y[0].imag();
+ return dydz;
+}
+
+#endif
diff --git a/exam/html/Makefile.html b/exam/html/Makefile.html
t@@ -0,0 +1,182 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/Makefile.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="make">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Special { color: #ff40ff; }
+.Constant { color: #ffff00; }
+.Statement { color: #ffff00; }
+.Identifier { color: #00ffff; }
+.Comment { color: #00ffff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="Comment"># Define compiler</span>
+<span class="lnr"> 2 </span><span class="Comment">#CXX=g++</span>
+<span class="lnr"> 3 </span>
+<span class="lnr"> 4 </span><span class="Comment"># Define compiler flags (sh…
+<span class="lnr"> 5 </span><span class="Identifier">CXXFLAGS</span>=-Wall
+<span class="lnr"> 6 </span><span class="Comment">#CXXFLAGS=-std=c++0x</span>
+<span class="lnr"> 7 </span>
+<span class="lnr"> 8 </span><span class="Comment"># Define linker flags</span>
+<span class="lnr"> 9 </span><span class="Comment">#LDFLAGS=-fopenmp</span>
+<span class="lnr"> 10 </span>
+<span class="lnr"> 11 </span><span class="Comment"># Compile optimized code</s…
+<span class="lnr"> 12 </span><span class="Identifier">CXXFLAGS</span>+=-O2
+<span class="lnr"> 13 </span>
+<span class="lnr"> 14 </span><span class="Comment"># Compile debuggable code</…
+<span class="lnr"> 15 </span><span class="Comment">#CXXFLAGS+=-g</span>
+<span class="lnr"> 16 </span>
+<span class="lnr"> 17 </span><span class="Comment"># Compile profilable code</…
+<span class="lnr"> 18 </span><span class="Comment">#CXXFLAGS+=-pg</span>
+<span class="lnr"> 19 </span><span class="Comment">#LDFLAGS+=-pg</span>
+<span class="lnr"> 20 </span>
+<span class="lnr"> 21 </span><span class="Comment"># Define linker</span>
+<span class="lnr"> 22 </span><span class="Identifier">LD</span>=g++
+<span class="lnr"> 23 </span>
+<span class="lnr"> 24 </span><span class="Comment"># All source code files</sp…
+<span class="lnr"> 25 </span><span class="Identifier">SRC</span>=<span class="…
+<span class="lnr"> 26 </span>
+<span class="lnr"> 27 </span>
+<span class="lnr"> 28 </span><span class="Comment"># Filenames of source code<…
+<span class="lnr"> 29 </span><span class="Identifier">SHARED_SRC</span>=ode.cp…
+<span class="lnr"> 30 </span><span class="Identifier">SHARED_HEADERS</span>=ty…
+<span class="lnr"> 31 </span><span class="Identifier">SRC_A</span>=mainA.cpp <…
+<span class="lnr"> 32 </span><span class="Identifier">HEAD_A</span>=<span clas…
+<span class="lnr"> 33 </span><span class="Identifier">SRC_B</span>=mainB.cpp <…
+<span class="lnr"> 34 </span><span class="Identifier">HEAD_B</span>=<span clas…
+<span class="lnr"> 35 </span><span class="Identifier">SRC_C</span>=mainC.cpp <…
+<span class="lnr"> 36 </span><span class="Identifier">HEAD_C</span>=<span clas…
+<span class="lnr"> 37 </span><span class="Identifier">SRC_D</span>=mainD.cpp <…
+<span class="lnr"> 38 </span><span class="Identifier">HEAD_D</span>=<span clas…
+<span class="lnr"> 39 </span>
+<span class="lnr"> 40 </span><span class="Comment"># Filenames of object files…
+<span class="lnr"> 41 </span><span class="Identifier">OBJ_A</span>=<span class…
+<span class="lnr"> 42 </span><span class="Identifier">OBJ_B</span>=<span class…
+<span class="lnr"> 43 </span><span class="Identifier">OBJ_C</span>=<span class…
+<span class="lnr"> 44 </span><span class="Identifier">OBJ_D</span>=<span class…
+<span class="lnr"> 45 </span>
+<span class="lnr"> 46 </span><span class="Comment"># Remove file type extensio…
+<span class="lnr"> 47 </span><span class="Identifier">BIN_A</span>=odeA
+<span class="lnr"> 48 </span><span class="Identifier">BIN_B</span>=odeB
+<span class="lnr"> 49 </span><span class="Identifier">BIN_C</span>=odeC
+<span class="lnr"> 50 </span><span class="Identifier">BIN_D</span>=odeD
+<span class="lnr"> 51 </span>
+<span class="lnr"> 52 </span><span class="Comment"># Define editor and options…
+<span class="lnr"> 53 </span><span class="Identifier">EDITOR</span>=vim -p
+<span class="lnr"> 54 </span>
+<span class="lnr"> 55 </span>
+<span class="lnr"> 56 </span><span class="Comment"># The default &quot;all&quo…
+<span class="lnr"> 57 </span><span class="Identifier">all:</span> A B C D
+<span class="lnr"> 58 </span>
+<span class="lnr"> 59 </span><span class="Identifier">A:</span> plotA.png
+<span class="lnr"> 60 </span>
+<span class="lnr"> 61 </span><span class="Identifier">B:</span> plotB.png
+<span class="lnr"> 62 </span>
+<span class="lnr"> 63 </span><span class="Identifier">C:</span> plotC.png
+<span class="lnr"> 64 </span>
+<span class="lnr"> 65 </span><span class="Identifier">D:</span> plotD.png
+<span class="lnr"> 66 </span>
+<span class="lnr"> 67 </span><span class="Identifier">plotA.png:</span> funcA.…
+<span class="lnr"> 68 </span><span class="Constant"> </span><span class…
+<span class="lnr"> 69 </span><span class="Special"> @</span><span class…
+<span class="lnr"> 70 </span>
+<span class="lnr"> 71 </span><span class="Identifier">plotB.png:</span> funcB.…
+<span class="lnr"> 72 </span><span class="Constant"> </span><span class…
+<span class="lnr"> 73 </span><span class="Special"> @</span><span class…
+<span class="lnr"> 74 </span>
+<span class="lnr"> 75 </span><span class="Identifier">plotC.png:</span> funcC.…
+<span class="lnr"> 76 </span><span class="Constant"> </span><span class…
+<span class="lnr"> 77 </span><span class="Special"> @</span><span class…
+<span class="lnr"> 78 </span>
+<span class="lnr"> 79 </span><span class="Identifier">plotD.png:</span> funcD.…
+<span class="lnr"> 80 </span><span class="Constant"> </span><span class…
+<span class="lnr"> 81 </span><span class="Special"> @</span><span class…
+<span class="lnr"> 82 </span>
+<span class="lnr"> 83 </span><span class="Identifier">funcA.dat:</span> <span …
+<span class="lnr"> 84 </span><span class="Special"> @</span><span class…
+<span class="lnr"> 85 </span><span class="Constant"> </span>
+<span class="lnr"> 86 </span><span class="Identifier">funcB.dat:</span> <span …
+<span class="lnr"> 87 </span><span class="Special"> @</span><span class…
+<span class="lnr"> 88 </span>
+<span class="lnr"> 89 </span><span class="Identifier">funcC.dat:</span> <span …
+<span class="lnr"> 90 </span><span class="Special"> @</span><span class…
+<span class="lnr"> 91 </span><span class="Constant"> </span>
+<span class="lnr"> 92 </span><span class="Identifier">funcD.dat:</span> <span …
+<span class="lnr"> 93 </span><span class="Special"> @</span><span class…
+<span class="lnr"> 94 </span><span class="Constant"> </span>
+<span class="lnr"> 95 </span><span class="Identifier">$(BIN_A):</span> <span c…
+<span class="lnr"> 96 </span><span class="Special"> @</span><span class…
+<span class="lnr"> 97 </span><span class="Constant"> </span><span class…
+<span class="lnr"> 98 </span><span class="Constant"> </span>
+<span class="lnr"> 99 </span><span class="Identifier">$(BIN_B):</span> <span c…
+<span class="lnr">100 </span><span class="Special"> @</span><span class…
+<span class="lnr">101 </span><span class="Constant"> </span><span class…
+<span class="lnr">102 </span>
+<span class="lnr">103 </span><span class="Identifier">$(BIN_C):</span> <span c…
+<span class="lnr">104 </span><span class="Special"> @</span><span class…
+<span class="lnr">105 </span><span class="Constant"> </span><span class…
+<span class="lnr">106 </span>
+<span class="lnr">107 </span><span class="Identifier">$(BIN_D):</span> <span c…
+<span class="lnr">108 </span><span class="Special"> @</span><span class…
+<span class="lnr">109 </span><span class="Constant"> </span><span class…
+<span class="lnr">110 </span>
+<span class="lnr">111 </span><span class="Identifier">clean:</span> cleanA cl…
+<span class="lnr">112 </span>
+<span class="lnr">113 </span><span class="Identifier">cleanA: </span>
+<span class="lnr">114 </span><span class="Special"> @</span><span class…
+<span class="lnr">115 </span><span class="Constant"> rm -f </span><span…
+<span class="lnr">116 </span><span class="Special"> @</span><span class…
+<span class="lnr">117 </span><span class="Constant"> rm -f </span><span…
+<span class="lnr">118 </span><span class="Special"> @</span><span class…
+<span class="lnr">119 </span><span class="Constant"> rm -f funcA.dat pl…
+<span class="lnr">120 </span>
+<span class="lnr">121 </span><span class="Identifier">cleanB: </span>
+<span class="lnr">122 </span><span class="Special"> @</span><span class…
+<span class="lnr">123 </span><span class="Constant"> rm -f </span><span…
+<span class="lnr">124 </span><span class="Special"> @</span><span class…
+<span class="lnr">125 </span><span class="Constant"> rm -f </span><span…
+<span class="lnr">126 </span><span class="Special"> @</span><span class…
+<span class="lnr">127 </span><span class="Constant"> rm -f funcB.dat pl…
+<span class="lnr">128 </span>
+<span class="lnr">129 </span><span class="Identifier">cleanC: </span>
+<span class="lnr">130 </span><span class="Special"> @</span><span class…
+<span class="lnr">131 </span><span class="Constant"> rm -f </span><span…
+<span class="lnr">132 </span><span class="Special"> @</span><span class…
+<span class="lnr">133 </span><span class="Constant"> rm -f </span><span…
+<span class="lnr">134 </span><span class="Special"> @</span><span class…
+<span class="lnr">135 </span><span class="Constant"> rm -f funcC.dat pl…
+<span class="lnr">136 </span>
+<span class="lnr">137 </span><span class="Identifier">cleanD: </span>
+<span class="lnr">138 </span><span class="Special"> @</span><span class…
+<span class="lnr">139 </span><span class="Constant"> rm -f </span><span…
+<span class="lnr">140 </span><span class="Special"> @</span><span class…
+<span class="lnr">141 </span><span class="Constant"> rm -f </span><span…
+<span class="lnr">142 </span><span class="Constant"> </span><span class…
+<span class="lnr">143 </span><span class="Special"> @</span><span class…
+<span class="lnr">144 </span>
+<span class="lnr">145 </span><span class="Identifier">htmlfiles:</span> html/m…
+<span class="lnr">146 </span><span class="Constant"> </span><span class…
+<span class="lnr">147 </span><span class="Constant"> rst2html2 README.r…
+<span class="lnr">148 </span>
+<span class="lnr">149 </span><span class="Identifier">html/%.html:</span> <spa…
+<span class="lnr">150 </span><span class="Constant"> vim </span><span c…
+<span class="lnr">151 </span>
+<span class="lnr">152 </span>
+<span class="lnr">153 </span><span class="Identifier">edit:</span>
+<span class="lnr">154 </span><span class="Special"> @</span><span class…
+<span class="lnr">155 </span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/README.html b/exam/html/README.html
t@@ -0,0 +1,406 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.…
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.9.1: http://docutils.sourceforge.ne…
+<title>README: ODE integration with complex numbers</title>
+<style type="text/css">
+
+/*
+:Author: David Goodger ([email protected])
+:Id: $Id: html4css1.css 7434 2012-05-11 21:06:27Z milde $
+:Copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+*/
+
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+ border: 0 }
+
+table.borderless td, table.borderless th {
+ /* Override padding for "table.docutils td" with "! important".
+ The right padding separates the table cells. */
+ padding: 0 0.5em 0 0 ! important }
+
+.first {
+ /* Override more specific margin styles with "! important". */
+ margin-top: 0 ! important }
+
+.last, .with-subtitle {
+ margin-bottom: 0 ! important }
+
+.hidden {
+ display: none }
+
+a.toc-backref {
+ text-decoration: none ;
+ color: black }
+
+blockquote.epigraph {
+ margin: 2em 5em ; }
+
+dl.docutils dd {
+ margin-bottom: 0.5em }
+
+object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
+ overflow: hidden;
+}
+
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
+ font-weight: bold }
+*/
+
+div.abstract {
+ margin: 2em 5em }
+
+div.abstract p.topic-title {
+ font-weight: bold ;
+ text-align: center }
+
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
+ margin: 2em ;
+ border: medium outset ;
+ padding: 1em }
+
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+ font-weight: bold ;
+ font-family: sans-serif }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+ color: red ;
+ font-weight: bold ;
+ font-family: sans-serif }
+
+/* Uncomment (and remove this text!) to get reduced vertical space in
+ compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+ margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+ margin-top: 0.5em }
+*/
+
+div.dedication {
+ margin: 2em 5em ;
+ text-align: center ;
+ font-style: italic }
+
+div.dedication p.topic-title {
+ font-weight: bold ;
+ font-style: normal }
+
+div.figure {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+div.footer, div.header {
+ clear: both;
+ font-size: smaller }
+
+div.line-block {
+ display: block ;
+ margin-top: 1em ;
+ margin-bottom: 1em }
+
+div.line-block div.line-block {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ margin-left: 1.5em }
+
+div.sidebar {
+ margin: 0 0 0.5em 1em ;
+ border: medium outset ;
+ padding: 1em ;
+ background-color: #ffffee ;
+ width: 40% ;
+ float: right ;
+ clear: right }
+
+div.sidebar p.rubric {
+ font-family: sans-serif ;
+ font-size: medium }
+
+div.system-messages {
+ margin: 5em }
+
+div.system-messages h1 {
+ color: red }
+
+div.system-message {
+ border: medium outset ;
+ padding: 1em }
+
+div.system-message p.system-message-title {
+ color: red ;
+ font-weight: bold }
+
+div.topic {
+ margin: 2em }
+
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+ margin-top: 0.4em }
+
+h1.title {
+ text-align: center }
+
+h2.subtitle {
+ text-align: center }
+
+hr.docutils {
+ width: 75% }
+
+img.align-left, .figure.align-left, object.align-left {
+ clear: left ;
+ float: left ;
+ margin-right: 1em }
+
+img.align-right, .figure.align-right, object.align-right {
+ clear: right ;
+ float: right ;
+ margin-left: 1em }
+
+img.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left }
+
+.align-center {
+ clear: both ;
+ text-align: center }
+
+.align-right {
+ text-align: right }
+
+/* reset inner alignment in figures */
+div.align-right {
+ text-align: inherit }
+
+/* div.align-center * { */
+/* text-align: left } */
+
+ol.simple, ul.simple {
+ margin-bottom: 1em }
+
+ol.arabic {
+ list-style: decimal }
+
+ol.loweralpha {
+ list-style: lower-alpha }
+
+ol.upperalpha {
+ list-style: upper-alpha }
+
+ol.lowerroman {
+ list-style: lower-roman }
+
+ol.upperroman {
+ list-style: upper-roman }
+
+p.attribution {
+ text-align: right ;
+ margin-left: 50% }
+
+p.caption {
+ font-style: italic }
+
+p.credits {
+ font-style: italic ;
+ font-size: smaller }
+
+p.label {
+ white-space: nowrap }
+
+p.rubric {
+ font-weight: bold ;
+ font-size: larger ;
+ color: maroon ;
+ text-align: center }
+
+p.sidebar-title {
+ font-family: sans-serif ;
+ font-weight: bold ;
+ font-size: larger }
+
+p.sidebar-subtitle {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+p.topic-title {
+ font-weight: bold }
+
+pre.address {
+ margin-bottom: 0 ;
+ margin-top: 0 ;
+ font: inherit }
+
+pre.literal-block, pre.doctest-block, pre.math, pre.code {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+pre.code .ln { /* line numbers */
+ color: grey;
+}
+
+.code {
+ background-color: #eeeeee
+}
+
+span.classifier {
+ font-family: sans-serif ;
+ font-style: oblique }
+
+span.classifier-delimiter {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+span.interpreted {
+ font-family: sans-serif }
+
+span.option {
+ white-space: nowrap }
+
+span.pre {
+ white-space: pre }
+
+span.problematic {
+ color: red }
+
+span.section-subtitle {
+ /* font-size relative to parent (h1..h6 element) */
+ font-size: 80% }
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px }
+
+table.docinfo {
+ margin: 2em 4em }
+
+table.docutils {
+ margin-top: 0.5em ;
+ margin-bottom: 0.5em }
+
+table.footnote {
+ border-left: solid 1px black;
+ margin-left: 1px }
+
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
+ padding-left: 0.5em ;
+ padding-right: 0.5em ;
+ vertical-align: top }
+
+table.docutils th.field-name, table.docinfo th.docinfo-name {
+ font-weight: bold ;
+ text-align: left ;
+ white-space: nowrap ;
+ padding-left: 0 }
+
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+ font-size: 100% }
+
+ul.auto-toc {
+ list-style-type: none }
+
+</style>
+</head>
+<body>
+<div class="document" id="readme-ode-integration-with-complex-numbers">
+<h1 class="title">README: ODE integration with complex numbers</h1>
+
+<p>Exam exercise for <em>Numerical Methods</em> by Anders D. Christensen (<a c…
+<div class="section" id="file-description">
+<h1>File description</h1>
+<ul class="simple">
+<li><tt class="docutils literal">Makefile</tt>: Description for GNU Make, hand…
+<li><tt class="docutils literal">README.rst</tt> (this file): Description of n…
+Written with reStructuredText syntax.</li>
+<li><tt class="docutils literal">check.cpp</tt>: Function for displaying the s…
+<li><tt class="docutils literal">check.h</tt>: Prototype for the check-functio…
+<li><tt class="docutils literal">functions.h</tt>: Input functions to be evalu…
+<li><tt class="docutils literal">mainA.cpp</tt>: Main source code file for par…
+<li><tt class="docutils literal">ode.cpp</tt>: Constructor and functions for t…
+stepper and driver.</li>
+<li><tt class="docutils literal">ode.h</tt>: Header file with the ODE class. T…
+programs that want to utilize the ODE functionality.</li>
+<li><tt class="docutils literal">plot.gp</tt>: Script for plotting all graphs …
+<li><tt class="docutils literal">typedefs.h</tt>: Header file containing defin…
+<tt class="docutils literal">Inttype</tt>, a whole-number type, and <tt class=…
+type. The type definitions can be changed to different lengths and precisions.
+The program can be compiled for verbose output by changing the <tt class="docu…
+variable.</li>
+<li><tt class="docutils literal">vector_arithmetic.h</tt>: Operator overloadin…
+class.</li>
+</ul>
+</div>
+<div class="section" id="problem-descriptions">
+<h1>Problem descriptions</h1>
+<p>The four generated executables each demonstrate the ODE solvers functionali…
+performing the following tasks. The results consist of the console output and
+the corresponding plot with filename <tt class="docutils literal"><span class=…
+- <em>A</em>: Construct an ODE solver that can handle functions with complex v…
+Demonstrate that it solves the real component correctly, by stepping along
+a path in the real range.
+- <em>B</em>: Demonstrate that the ODE solver can solve the imaginary componen…
+stepping along a path in the imaginary range.
+- <em>C</em>: Demonstrate the solution of a set of complex equations by steppi…
+through the complex plane.
+- <em>D</em>: For an integration path in the complex plane, visualize how the
+requirements of absolute- and relative precision are related to the number of
+integration steps, for a given floating point precision.</p>
+</div>
+<div class="section" id="implementation">
+<h1>Implementation</h1>
+<p>This exercise was written in object-oriented C++ for easy reuse. For
+portability, all included classes are from the standard template library.</p>
+<p>The necessary <tt class="docutils literal"><span class="pre">std::vector</s…
+element-wise operations, such as vector-scalar multiplication, vector-vector
+addition, etc. This approach was preferred over using <tt class="docutils lite…
+is not dynamically expandable.</p>
+<p>When creating a new ODE object, the user specifies the end-points of the li…
+range, where the specified system of ordinary differential equations with
+complex values will be solved. The range end-points are complex numbers
+themselves, and the user can thus specify whether the integrator steps through…
+range of real values, imaginary values, or both components in the complex plan…
+<p>The solver steps through the specified range by an adaptive step size, whic…
+also a complex number. The user specifies the fraction of the range to be used
+as a start value for the step. The default value is 0.01.</p>
+<p>The ODE class contains functions for writing the ODE solution to stdout
+(<tt class="docutils literal"><span class="pre">ODE::print</span></tt>) or to …
+following; the first column is the real part of x, second column the imaginary
+part. The subsequent columns do in turn consist of real- and imaginary parts …
+the variables in the ODE.</p>
+<p>The program requires a modern C++ compiler, GNU Make and Gnuplot. It has be…
+tested with GCC, Clang and llvm.</p>
+</div>
+<div class="section" id="compiliation-and-execution">
+<h1>Compiliation and execution</h1>
+<p>To make and execute the program, go to the root folder and type <cite>make<…
+will compile and execute the programs for part A-D, and plot output graphs. If
+desired, individual parts can be compiled and executed using <cite>make &lt;Ch…
+<p>To view the source code in a browser with vim's syntax highlighting, type <…
+html</cite>, and view the files in the <cite>html</cite> folder. The generatio…
+requires a newer vim for the source code files, and Docutils for the readme.</…
+<p>All output and objects can be removed using <cite>make clean</cite>.</p>
+<p>#vim: set tw=80</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/exam/html/check.cpp.html b/exam/html/check.cpp.html
t@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/check.cpp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Special { color: #ff40ff; }
+.Statement { color: #ffff00; }
+.Type { color: #00ff00; }
+.Constant { color: #ffff00; }
+.PreProc { color: #ff40ff; }
+.Comment { color: #00ffff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="Comment">// Function used for reporti…
+<span class="lnr"> 2 </span><span class="Comment">// statement to stdout using…
+<span class="lnr"> 3 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 4 </span>
+<span class="lnr"> 5 </span><span class="Type">void</span> check(<span class="…
+<span class="lnr"> 6 </span>{
+<span class="lnr"> 7 </span> <span class="Statement">if</span> (statement == …
+<span class="lnr"> 8 </span> std::cout &lt;&lt; <span class="Constant">&quo…
+<span class="lnr"> 9 </span> <span class="Statement">else</span>
+<span class="lnr">10 </span> std::cout &lt;&lt; <span class="Constant">&quo…
+<span class="lnr">11 </span>}
+</pre>
+</body>
+</html>
diff --git a/exam/html/check.h.html b/exam/html/check.h.html
t@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/check.h.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Type { color: #00ff00; }
+.Comment { color: #00ffff; }
+.PreProc { color: #ff40ff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr">1 </span><span class="PreProc">#ifndef CHECK_H_</span>
+<span class="lnr">2 </span><span class="PreProc">#define CHECK_H_</span>
+<span class="lnr">3 </span>
+<span class="lnr">4 </span><span class="Comment">// Prototype for checking fun…
+<span class="lnr">5 </span><span class="Type">void</span> check(<span class="T…
+<span class="lnr">6 </span>
+<span class="lnr">7 </span><span class="PreProc">#endif</span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/functions.h.html b/exam/html/functions.h.html
t@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/functions.h.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Statement { color: #ffff00; }
+.Type { color: #00ff00; }
+.Constant { color: #ffff00; }
+.PreProc { color: #ff40ff; }
+.Comment { color: #00ffff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="Comment">// Make sure file is only in…
+<span class="lnr"> 2 </span><span class="PreProc">#ifndef FUNCTIONS_H_</span>
+<span class="lnr"> 3 </span><span class="PreProc">#define FUNCTIONS_H_</span>
+<span class="lnr"> 4 </span>
+<span class="lnr"> 5 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 6 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 7 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 8 </span>
+<span class="lnr"> 9 </span>
+<span class="lnr">10 </span><span class="Comment">//// ODEs with real+complex …
+<span class="lnr">11 </span><span class="Comment">//// Return the derivatives …
+<span class="lnr">12 </span>
+<span class="lnr">13 </span>std::vector&lt;std::complex&lt;Floattype&gt; &gt;
+<span class="lnr">14 </span> func1(<span class="Type">const</span> std:…
+<span class="lnr">15 </span> <span class="Type">const</span> std:…
+<span class="lnr">16 </span>{
+<span class="lnr">17 </span> std::vector&lt;std::complex&lt;Floattype&gt; &gt…
+<span class="lnr">18 </span> dydz[<span class="Constant">0</span>].real() = y…
+<span class="lnr">19 </span> dydz[<span class="Constant">0</span>].imag() = y…
+<span class="lnr">20 </span> dydz[<span class="Constant">1</span>].real() = -…
+<span class="lnr">21 </span> dydz[<span class="Constant">1</span>].imag() = <…
+<span class="lnr">22 </span> <span class="Statement">return</span> dydz;
+<span class="lnr">23 </span>}
+<span class="lnr">24 </span>
+<span class="lnr">25 </span><span class="PreProc">#endif</span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/mainA.cpp.html b/exam/html/mainA.cpp.html
t@@ -0,0 +1,87 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/mainA.cpp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Special { color: #ff40ff; }
+.Statement { color: #ffff00; }
+.Comment { color: #00ffff; }
+.Type { color: #00ff00; }
+.Constant { color: #ffff00; }
+.PreProc { color: #ff40ff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 2 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 3 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 4 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 5 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 6 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 7 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 8 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 9 </span>
+<span class="lnr">10 </span>
+<span class="lnr">11 </span><span class="Type">int</span> main()
+<span class="lnr">12 </span>{
+<span class="lnr">13 </span> <span class="Comment">// Namespace declarations<…
+<span class="lnr">14 </span> <span class="Statement">using</span> std::cout;
+<span class="lnr">15 </span> <span class="Statement">using</span> std::vector;
+<span class="lnr">16 </span> <span class="Statement">using</span> std::comple…
+<span class="lnr">17 </span>
+<span class="lnr">18 </span> <span class="Comment">// Calculate machine preci…
+<span class="lnr">19 </span> Floattype eps_machine = <span class="Constant">1…
+<span class="lnr">20 </span> <span class="Statement">while</span> (<span clas…
+<span class="lnr">21 </span> eps_machine /= <span class="Constant">2.0f</sp…
+<span class="lnr">22 </span>
+<span class="lnr">23 </span> <span class="Type">const</span> <span class="Typ…
+<span class="lnr">24 </span> <span class="Type">const</span> <span class="Typ…
+<span class="lnr">25 </span> cout &lt;&lt; <span class="Constant">&quot;</spa…
+<span class="lnr">26 </span> &lt;&lt; <span class="Constant">&quot;</spa…
+<span class="lnr">27 </span> &lt;&lt; id%n &lt;&lt; <span class="Constan…
+<span class="lnr">28 </span> cout &lt;&lt; <span class="Constant">&quot;Exami…
+<span class="lnr">29 </span> &lt;&lt; <span class="Constant">&quot;with …
+<span class="lnr">30 </span>
+<span class="lnr">31 </span> cout &lt;&lt; <span class="Constant">&quot;</spa…
+<span class="lnr">32 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">33 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">34 </span> cout &lt;&lt; <span class="Constant">&quot;Integ…
+<span class="lnr">35 </span> Inttype n_eqs = <span class="Constant">2</span>;…
+<span class="lnr">36 </span> vector&lt;<span class="Type">complex</span>&lt;F…
+<span class="lnr">37 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">38 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">39 </span> y_start[<span class="Constant">0</span>] = y0;
+<span class="lnr">40 </span> y_start[<span class="Constant">1</span>] = y1;
+<span class="lnr">41 </span> Floattype h_start = <span class="Constant">0.01f…
+<span class="lnr">42 </span> ODE realode(func1, <span class="Comment">// O…
+<span class="lnr">43 </span> y_start, <span class="Comment">// I…
+<span class="lnr">44 </span> a, <span class="Comment">// L…
+<span class="lnr">45 </span> b, <span class="Comment">// U…
+<span class="lnr">46 </span> h_start, <span class="Comment">// S…
+<span class="lnr">47 </span> <span class="Constant">10000</span>,…
+<span class="lnr">48 </span> eps_machine*<span class="Constant">1…
+<span class="lnr">49 </span> eps_machine*<span class="Constant">1…
+<span class="lnr">50 </span> realode.write(<span class="Constant">&quot;funcA…
+<span class="lnr">51 </span>
+<span class="lnr">52 </span> <span class="Comment">// Report to stdout</span>
+<span class="lnr">53 </span> cout &lt;&lt; <span class="Constant">&quot;ODE s…
+<span class="lnr">54 </span> &lt;&lt; realode.steps() &lt;&lt; <span cla…
+<span class="lnr">55 </span>
+<span class="lnr">56 </span> <span class="Comment">// Return successfully</sp…
+<span class="lnr">57 </span> <span class="Statement">return</span> <span clas…
+<span class="lnr">58 </span>}
+<span class="lnr">59 </span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/mainB.cpp.html b/exam/html/mainB.cpp.html
t@@ -0,0 +1,78 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/mainB.cpp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Special { color: #ff40ff; }
+.Statement { color: #ffff00; }
+.Comment { color: #00ffff; }
+.Type { color: #00ff00; }
+.Constant { color: #ffff00; }
+.PreProc { color: #ff40ff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 2 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 3 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 4 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 5 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 6 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 7 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 8 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 9 </span>
+<span class="lnr">10 </span><span class="Type">int</span> main()
+<span class="lnr">11 </span>{
+<span class="lnr">12 </span> <span class="Comment">// Namespace declarations<…
+<span class="lnr">13 </span> <span class="Statement">using</span> std::cout;
+<span class="lnr">14 </span> <span class="Statement">using</span> std::vector;
+<span class="lnr">15 </span> <span class="Statement">using</span> std::comple…
+<span class="lnr">16 </span>
+<span class="lnr">17 </span> <span class="Comment">// Calculate machine preci…
+<span class="lnr">18 </span> Floattype eps_machine = <span class="Constant">1…
+<span class="lnr">19 </span> <span class="Statement">while</span> (<span clas…
+<span class="lnr">20 </span> eps_machine /= <span class="Constant">2.0f</sp…
+<span class="lnr">21 </span>
+<span class="lnr">22 </span> cout &lt;&lt; <span class="Constant">&quot;</spa…
+<span class="lnr">23 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">24 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">25 </span> cout &lt;&lt; <span class="Constant">&quot;Integ…
+<span class="lnr">26 </span> Inttype n_eqs = <span class="Constant">2</span>;…
+<span class="lnr">27 </span> vector&lt;<span class="Type">complex</span>&lt;F…
+<span class="lnr">28 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">29 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">30 </span> y_start[<span class="Constant">0</span>] = y0;
+<span class="lnr">31 </span> y_start[<span class="Constant">1</span>] = y1;
+<span class="lnr">32 </span> Floattype h_start = <span class="Constant">0.01f…
+<span class="lnr">33 </span> ODE imagode(func1, <span class="Comment">// O…
+<span class="lnr">34 </span> y_start, <span class="Comment">// I…
+<span class="lnr">35 </span> a, <span class="Comment">// L…
+<span class="lnr">36 </span> b, <span class="Comment">// U…
+<span class="lnr">37 </span> h_start, <span class="Comment">// S…
+<span class="lnr">38 </span> <span class="Constant">10000</span>,…
+<span class="lnr">39 </span> eps_machine*<span class="Constant">1…
+<span class="lnr">40 </span> eps_machine*<span class="Constant">1…
+<span class="lnr">41 </span> imagode.write(<span class="Constant">&quot;funcB…
+<span class="lnr">42 </span>
+<span class="lnr">43 </span> <span class="Comment">// Report to stdout</span>
+<span class="lnr">44 </span> cout &lt;&lt; <span class="Constant">&quot;ODE s…
+<span class="lnr">45 </span> &lt;&lt; imagode.steps() &lt;&lt; <span cla…
+<span class="lnr">46 </span>
+<span class="lnr">47 </span> <span class="Comment">// Return successfully</sp…
+<span class="lnr">48 </span> <span class="Statement">return</span> <span clas…
+<span class="lnr">49 </span>}
+<span class="lnr">50 </span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/mainC.cpp.html b/exam/html/mainC.cpp.html
t@@ -0,0 +1,78 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/mainC.cpp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Special { color: #ff40ff; }
+.Statement { color: #ffff00; }
+.Comment { color: #00ffff; }
+.Type { color: #00ff00; }
+.Constant { color: #ffff00; }
+.PreProc { color: #ff40ff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 2 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 3 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 4 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 5 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 6 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 7 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 8 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 9 </span>
+<span class="lnr">10 </span><span class="Type">int</span> main()
+<span class="lnr">11 </span>{
+<span class="lnr">12 </span> <span class="Comment">// Namespace declarations<…
+<span class="lnr">13 </span> <span class="Statement">using</span> std::cout;
+<span class="lnr">14 </span> <span class="Statement">using</span> std::vector;
+<span class="lnr">15 </span> <span class="Statement">using</span> std::comple…
+<span class="lnr">16 </span>
+<span class="lnr">17 </span> <span class="Comment">// Calculate machine preci…
+<span class="lnr">18 </span> Floattype eps_machine = <span class="Constant">1…
+<span class="lnr">19 </span> <span class="Statement">while</span> (<span clas…
+<span class="lnr">20 </span> eps_machine /= <span class="Constant">2.0f</sp…
+<span class="lnr">21 </span>
+<span class="lnr">22 </span> cout &lt;&lt; <span class="Constant">&quot;</spa…
+<span class="lnr">23 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">24 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">25 </span> cout &lt;&lt; <span class="Constant">&quot;Integ…
+<span class="lnr">26 </span> Inttype n_eqs = <span class="Constant">2</span>;…
+<span class="lnr">27 </span> vector&lt;<span class="Type">complex</span>&lt;F…
+<span class="lnr">28 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">29 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">30 </span> y_start[<span class="Constant">0</span>] = y0;
+<span class="lnr">31 </span> y_start[<span class="Constant">1</span>] = y1;
+<span class="lnr">32 </span> Floattype h_start = <span class="Constant">0.01f…
+<span class="lnr">33 </span> ODE ode(func1, <span class="Comment">// O…
+<span class="lnr">34 </span> y_start, <span class="Comment">// I…
+<span class="lnr">35 </span> a, <span class="Comment">// Lower lim…
+<span class="lnr">36 </span> b, <span class="Comment">// Upper lim…
+<span class="lnr">37 </span> h_start, <span class="Comment">// S…
+<span class="lnr">38 </span> <span class="Constant">10000</span>, …
+<span class="lnr">39 </span> eps_machine*<span class="Constant">1e12f…
+<span class="lnr">40 </span> eps_machine*<span class="Constant">1e12f…
+<span class="lnr">41 </span> ode.write(<span class="Constant">&quot;funcC.dat…
+<span class="lnr">42 </span>
+<span class="lnr">43 </span> <span class="Comment">// Report to stdout</span>
+<span class="lnr">44 </span> cout &lt;&lt; <span class="Constant">&quot;ODE s…
+<span class="lnr">45 </span> &lt;&lt; ode.steps() &lt;&lt; <span class="…
+<span class="lnr">46 </span>
+<span class="lnr">47 </span> <span class="Comment">// Return successfully</sp…
+<span class="lnr">48 </span> <span class="Statement">return</span> <span clas…
+<span class="lnr">49 </span>}
+<span class="lnr">50 </span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/mainD.cpp.html b/exam/html/mainD.cpp.html
t@@ -0,0 +1,96 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/mainD.cpp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Special { color: #ff40ff; }
+.Statement { color: #ffff00; }
+.Comment { color: #00ffff; }
+.Type { color: #00ff00; }
+.Constant { color: #ffff00; }
+.PreProc { color: #ff40ff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 2 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 3 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 4 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 5 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 6 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 7 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 8 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 9 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr">10 </span>
+<span class="lnr">11 </span>
+<span class="lnr">12 </span><span class="Type">int</span> main()
+<span class="lnr">13 </span>{
+<span class="lnr">14 </span> <span class="Comment">// Namespace declarations<…
+<span class="lnr">15 </span> <span class="Statement">using</span> std::cout;
+<span class="lnr">16 </span> <span class="Statement">using</span> std::vector;
+<span class="lnr">17 </span> <span class="Statement">using</span> std::comple…
+<span class="lnr">18 </span>
+<span class="lnr">19 </span> <span class="Comment">// Calculate machine preci…
+<span class="lnr">20 </span> Floattype eps_machine = <span class="Constant">1…
+<span class="lnr">21 </span> <span class="Statement">while</span> (<span clas…
+<span class="lnr">22 </span> eps_machine /= <span class="Constant">2.0f</sp…
+<span class="lnr">23 </span>
+<span class="lnr">24 </span> cout &lt;&lt; <span class="Constant">&quot;</spa…
+<span class="lnr">25 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">26 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">27 </span> cout &lt;&lt; <span class="Constant">&quot;Integ…
+<span class="lnr">28 </span> Inttype n_eqs = <span class="Constant">2</span>;…
+<span class="lnr">29 </span> vector&lt;<span class="Type">complex</span>&lt;F…
+<span class="lnr">30 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">31 </span> <span class="Type">complex</span>&lt;Floattype&g…
+<span class="lnr">32 </span> y_start[<span class="Constant">0</span>] = y0;
+<span class="lnr">33 </span> y_start[<span class="Constant">1</span>] = y1;
+<span class="lnr">34 </span> Floattype h_start = <span class="Constant">0.01f…
+<span class="lnr">35 </span>
+<span class="lnr">36 </span> vector&lt;Floattype&gt; precs; <span class="Comm…
+<span class="lnr">37 </span> vector&lt;Inttype&gt; steps; <span class="Comm…
+<span class="lnr">38 </span>
+<span class="lnr">39 </span> <span class="Statement">for</span> (Floattype pr…
+<span class="lnr">40 </span> ODE ode(func1, <span class="Comment">// O…
+<span class="lnr">41 </span> y_start, <span class="Comment">// I…
+<span class="lnr">42 </span> a, <span class="Comment">// L…
+<span class="lnr">43 </span> b, <span class="Comment">// U…
+<span class="lnr">44 </span> h_start, <span class="Comment">// S…
+<span class="lnr">45 </span> <span class="Constant">100000</span>, …
+<span class="lnr">46 </span> prec, <span class="Comment">// A…
+<span class="lnr">47 </span> prec); <span class="Comment">// R…
+<span class="lnr">48 </span> precs.push_back(prec); <span class="Com…
+<span class="lnr">49 </span> steps.push_back(ode.steps()); <span class="Com…
+<span class="lnr">50 </span> }
+<span class="lnr">51 </span>
+<span class="lnr">52 </span> <span class="Comment">// Save results to text fi…
+<span class="lnr">53 </span> std::ofstream ost; <span class="Comment">// Out …
+<span class="lnr">54 </span> ost.open(<span class="Constant">&quot;funcD.dat&…
+<span class="lnr">55 </span> <span class="Statement">if</span> (!ost) {
+<span class="lnr">56 </span> std::cerr &lt;&lt; <span class="Constant">&quo…
+<span class="lnr">57 </span> <span class="Statement">return</span> <span cl…
+<span class="lnr">58 </span> }
+<span class="lnr">59 </span> <span class="Comment">// Write output values</sp…
+<span class="lnr">60 </span> <span class="Statement">for</span> (Inttype i=<s…
+<span class="lnr">61 </span> ost &lt;&lt; precs[i] &lt;&lt; <span class="Sp…
+<span class="lnr">62 </span>
+<span class="lnr">63 </span> <span class="Comment">// Close file</span>
+<span class="lnr">64 </span> ost.close();
+<span class="lnr">65 </span>
+<span class="lnr">66 </span> <span class="Comment">// Return successfully</sp…
+<span class="lnr">67 </span> <span class="Statement">return</span> <span clas…
+<span class="lnr">68 </span>}
+</pre>
+</body>
+</html>
diff --git a/exam/html/ode.cpp.html b/exam/html/ode.cpp.html
t@@ -0,0 +1,191 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/ode.cpp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Special { color: #ff40ff; }
+.Statement { color: #ffff00; }
+.Type { color: #00ff00; }
+.Comment { color: #00ffff; }
+.Constant { color: #ffff00; }
+.PreProc { color: #ff40ff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="PreProc">#include </span><span class…
+<span class="lnr"> 2 </span><span class="PreProc">#include </span><span class…
+<span class="lnr"> 3 </span><span class="PreProc">#include </span><span class…
+<span class="lnr"> 4 </span><span class="PreProc">#include </span><span class…
+<span class="lnr"> 5 </span><span class="PreProc">#include </span><span class…
+<span class="lnr"> 6 </span><span class="PreProc">#include </span><span class…
+<span class="lnr"> 7 </span><span class="PreProc">#include </span><span class…
+<span class="lnr"> 8 </span>
+<span class="lnr"> 9 </span><span class="Comment">// Constructor</span>
+<span class="lnr"> 10 </span>ODE::ODE(std::vector&lt;std::complex&lt;Floattype…
+<span class="lnr"> 11 </span> (*f_in)(<span class="Type">const<…
+<span class="lnr"> 12 </span> <span class="Type">const<…
+<span class="lnr"> 13 </span> <span class="Type">const</span> std::vec…
+<span class="lnr"> 14 </span> <span class="Type">const</span> std::com…
+<span class="lnr"> 15 </span> <span class="Type">const</span> std::com…
+<span class="lnr"> 16 </span> <span class="Type">const</span> Floattyp…
+<span class="lnr"> 17 </span> <span class="Type">const</span> Inttype …
+<span class="lnr"> 18 </span> <span class="Type">const</span> Floattyp…
+<span class="lnr"> 19 </span> <span class="Type">const</span> Floattyp…
+<span class="lnr"> 20 </span> <span class="Type">const</span> Floattyp…
+<span class="lnr"> 21 </span> <span class="Type">const</span> Floattyp…
+<span class="lnr"> 22 </span> : f(f_in),
+<span class="lnr"> 23 </span> a(a_in), b(b_in),
+<span class="lnr"> 24 </span> h((b_in-a_in)*h_start),
+<span class="lnr"> 25 </span> n_max(max_steps),
+<span class="lnr"> 26 </span> delta(delta_in), epsilon(epsilon_in),
+<span class="lnr"> 27 </span> power(power_in), safety(safety_in)
+<span class="lnr"> 28 </span>{
+<span class="lnr"> 29 </span> x_list.push_back(a);
+<span class="lnr"> 30 </span> y_list.push_back(y_start);
+<span class="lnr"> 31 </span>
+<span class="lnr"> 32 </span> <span class="Comment">// Perform integration</s…
+<span class="lnr"> 33 </span> rkdriver();
+<span class="lnr"> 34 </span>}
+<span class="lnr"> 35 </span>
+<span class="lnr"> 36 </span>
+<span class="lnr"> 37 </span><span class="Comment">// Estimate tolerance</span>
+<span class="lnr"> 38 </span>Floattype ODE::tau(<span class="Type">const</span…
+<span class="lnr"> 39 </span> <span class="Type">const</span…
+<span class="lnr"> 40 </span>{
+<span class="lnr"> 41 </span> <span class="Statement">return</span> abs((epsi…
+<span class="lnr"> 42 </span>}
+<span class="lnr"> 43 </span>
+<span class="lnr"> 44 </span><span class="Comment">// Runge-Kutta mid-point st…
+<span class="lnr"> 45 </span><span class="Type">void</span> ODE::rkstep12(<spa…
+<span class="lnr"> 46 </span> <span class="Type">const</span…
+<span class="lnr"> 47 </span> std::vector&lt;std::complex&lt…
+<span class="lnr"> 48 </span> std::vector&lt;std::complex&lt…
+<span class="lnr"> 49 </span>{
+<span class="lnr"> 50 </span> <span class="Comment">// Denominator 2 used in …
+<span class="lnr"> 51 </span> <span class="Type">const</span> std::complex&lt…
+<span class="lnr"> 52 </span>
+<span class="lnr"> 53 </span> <span class="Comment">// Evaluate function at t…
+<span class="lnr"> 54 </span> (<span class="Type">void</span>)f(x0,y0);
+<span class="lnr"> 55 </span> <span class="Type">const</span> std::vector&lt;…
+<span class="lnr"> 56 </span> <span class="Type">const</span> std::vector&lt;…
+<span class="lnr"> 57 </span>
+<span class="lnr"> 58 </span> <span class="Comment">// Write results to outpu…
+<span class="lnr"> 59 </span> y1 = y0 + k12*h;
+<span class="lnr"> 60 </span> dy = (k0 - k12) * h/den2;
+<span class="lnr"> 61 </span>}
+<span class="lnr"> 62 </span>
+<span class="lnr"> 63 </span>
+<span class="lnr"> 64 </span><span class="Comment">// ODE driver with adaptive…
+<span class="lnr"> 65 </span><span class="Type">void</span> ODE::rkdriver()
+<span class="lnr"> 66 </span>{
+<span class="lnr"> 67 </span> std::vector&lt;std::complex&lt;Floattype&gt; &g…
+<span class="lnr"> 68 </span> std::vector&lt;std::complex&lt;Floattype&gt; &g…
+<span class="lnr"> 69 </span>
+<span class="lnr"> 70 </span> std::complex&lt;Floattype&gt; x;
+<span class="lnr"> 71 </span> Floattype err, tol;
+<span class="lnr"> 72 </span> std::vector&lt;std::complex&lt;Floattype&gt; &g…
+<span class="lnr"> 73 </span>
+<span class="lnr"> 74 </span> <span class="Statement">while</span> (x_list.ba…
+<span class="lnr"> 75 </span> || x_list.back().imag() &lt; b.imag())
+<span class="lnr"> 76 </span> {
+<span class="lnr"> 77 </span> <span class="Comment">// Get values for this …
+<span class="lnr"> 78 </span> x = x_list.back();
+<span class="lnr"> 79 </span> y = y_list.back();
+<span class="lnr"> 80 </span>
+<span class="lnr"> 81 </span> <span class="Comment">// Make sure we don't s…
+<span class="lnr"> 82 </span> <span class="Statement">if</span> ((x + h).re…
+<span class="lnr"> 83 </span> || (x + h).imag() &gt; b.imag())
+<span class="lnr"> 84 </span> h = b - x;
+<span class="lnr"> 85 </span>
+<span class="lnr"> 86 </span> <span class="Comment">// Run Runge-Kutta mid-…
+<span class="lnr"> 87 </span> rkstep12(x, y, y1, dy);
+<span class="lnr"> 88 </span>
+<span class="lnr"> 89 </span> <span class="Comment">// Determine whether th…
+<span class="lnr"> 90 </span> err = cnorm(dy); <span class="Comment">// Err…
+<span class="lnr"> 91 </span> tol = tau(y, h); <span class="Comment">// Tol…
+<span class="lnr"> 92 </span> <span class="Statement">if</span> (err &lt; t…
+<span class="lnr"> 93 </span> x_list.push_back(x+h);
+<span class="lnr"> 94 </span> y_list.push_back(y1);
+<span class="lnr"> 95 </span> }
+<span class="lnr"> 96 </span>
+<span class="lnr"> 97 </span> <span class="Comment">// Check that we havn't…
+<span class="lnr"> 98 </span> <span class="Statement">if</span> (x_list.siz…
+<span class="lnr"> 99 </span> std::cerr &lt;&lt; <span class="Constant">&…
+<span class="lnr">100 </span> &lt;&lt; <span class="Constant">&…
+<span class="lnr">101 </span> &lt;&lt; <span class="Constant">&…
+<span class="lnr">102 </span> &lt;&lt; <span class="Constant">&…
+<span class="lnr">103 </span> &lt;&lt; <span class="Constant">&…
+<span class="lnr">104 </span> <span class="Statement">return</span>;
+<span class="lnr">105 </span> }
+<span class="lnr">106 </span>
+<span class="lnr">107 </span> <span class="Comment">// Determine new step s…
+<span class="lnr">108 </span> std::complex&lt;Floattype&gt; multiplicator (…
+<span class="lnr">109 </span> <span class="Statement">if</span> (err &gt; <…
+<span class="lnr">110 </span> h = h*pow(tol/err, power) * safety;
+<span class="lnr">111 </span> <span class="Statement">else</span>
+<span class="lnr">112 </span> h = multiplicator*h;
+<span class="lnr">113 </span> }
+<span class="lnr">114 </span>}
+<span class="lnr">115 </span>
+<span class="lnr">116 </span>
+<span class="lnr">117 </span><span class="Comment">// Return the number of ste…
+<span class="lnr">118 </span>Inttype ODE::steps()
+<span class="lnr">119 </span>{
+<span class="lnr">120 </span> <span class="Statement">return</span> x_list.si…
+<span class="lnr">121 </span>}
+<span class="lnr">122 </span>
+<span class="lnr">123 </span><span class="Type">void</span> ODE::print()
+<span class="lnr">124 </span>{
+<span class="lnr">125 </span> <span class="Statement">for</span> (Inttype i=<…
+<span class="lnr">126 </span> std::cout &lt;&lt; x_list[i] &lt;&lt; <span c…
+<span class="lnr">127 </span> <span class="Statement">for</span> (Inttype j…
+<span class="lnr">128 </span> std::cout &lt;&lt; y_list[i][j] &lt;&lt; <s…
+<span class="lnr">129 </span> std::cout &lt;&lt; <span class="Special">'\n'…
+<span class="lnr">130 </span> }
+<span class="lnr">131 </span>}
+<span class="lnr">132 </span>
+<span class="lnr">133 </span><span class="Comment">// Write the x- and y-value…
+<span class="lnr">134 </span><span class="Type">void</span> ODE::write(<span c…
+<span class="lnr">135 </span>{
+<span class="lnr">136 </span> std::ofstream outstream;
+<span class="lnr">137 </span>
+<span class="lnr">138 </span> <span class="Comment">// Open outfile for write…
+<span class="lnr">139 </span> outstream.open(filename);
+<span class="lnr">140 </span> <span class="Statement">if</span> (!outstream) {
+<span class="lnr">141 </span> std::cerr &lt;&lt; <span class="Constant">&qu…
+<span class="lnr">142 </span> &lt;&lt; filename &lt;&lt; <span cl…
+<span class="lnr">143 </span> <span class="Statement">return</span>;
+<span class="lnr">144 </span> }
+<span class="lnr">145 </span>
+<span class="lnr">146 </span> <span class="Comment">// Write output values</s…
+<span class="lnr">147 </span> <span class="Statement">for</span> (Inttype i=<…
+<span class="lnr">148 </span> outstream &lt;&lt; x_list[i].real() &lt;&lt; …
+<span class="lnr">149 </span> outstream &lt;&lt; x_list[i].imag() &lt;&lt; …
+<span class="lnr">150 </span> <span class="Statement">for</span> (Inttype j…
+<span class="lnr">151 </span> outstream &lt;&lt; y_list[i][j].real() &lt;…
+<span class="lnr">152 </span> outstream &lt;&lt; y_list[i][j].imag() &lt;…
+<span class="lnr">153 </span> }
+<span class="lnr">154 </span> outstream &lt;&lt; <span class="Special">'\n'…
+<span class="lnr">155 </span> }
+<span class="lnr">156 </span>
+<span class="lnr">157 </span> <span class="Comment">// Close file</span>
+<span class="lnr">158 </span> outstream.close();
+<span class="lnr">159 </span>
+<span class="lnr">160 </span> <span class="Statement">if</span> (verbose == <…
+<span class="lnr">161 </span> std::cout &lt;&lt; <span class="Constant">&qu…
+<span class="lnr">162 </span>}
+<span class="lnr">163 </span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/ode.h.html b/exam/html/ode.h.html
t@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/ode.h.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Statement { color: #ffff00; }
+.Type { color: #00ff00; }
+.Constant { color: #ffff00; }
+.PreProc { color: #ff40ff; }
+.Comment { color: #00ffff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="Comment">// Make sure header is only …
+<span class="lnr"> 2 </span><span class="PreProc">#ifndef ODE_H_</span>
+<span class="lnr"> 3 </span><span class="PreProc">#define ODE_H_</span>
+<span class="lnr"> 4 </span>
+<span class="lnr"> 5 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 6 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 7 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 8 </span>
+<span class="lnr"> 9 </span><span class="Comment">// ODE class</span>
+<span class="lnr">10 </span><span class="Type">class</span> ODE {
+<span class="lnr">11 </span>
+<span class="lnr">12 </span> <span class="Comment">// Values and functions on…
+<span class="lnr">13 </span> <span class="Statement">private</span>:
+<span class="lnr">14 </span>
+<span class="lnr">15 </span> <span class="Comment">// System of ordinary di…
+<span class="lnr">16 </span> std::vector&lt;std::complex&lt;Floattype&gt; &…
+<span class="lnr">17 </span> (*f)(<span class="Type">const</span> std::…
+<span class="lnr">18 </span> <span class="Type">const</span> std::…
+<span class="lnr">19 </span>
+<span class="lnr">20 </span> <span class="Comment">// Points to be evaluate…
+<span class="lnr">21 </span> std::vector&lt;std::complex&lt;Floattype&gt; &…
+<span class="lnr">22 </span>
+<span class="lnr">23 </span> <span class="Comment">// Limits of range to ev…
+<span class="lnr">24 </span> <span class="Type">const</span> std::complex&l…
+<span class="lnr">25 </span> <span class="Type">const</span> std::complex&l…
+<span class="lnr">26 </span>
+<span class="lnr">27 </span> <span class="Comment">// Step size</span>
+<span class="lnr">28 </span> std::complex&lt;Floattype&gt; h;
+<span class="lnr">29 </span>
+<span class="lnr">30 </span> <span class="Comment">// Results stored in 2D:…
+<span class="lnr">31 </span> std::vector&lt;std::vector&lt;std::complex&lt;…
+<span class="lnr">32 </span>
+<span class="lnr">33 </span> <span class="Comment">// Maximum number of ste…
+<span class="lnr">34 </span> <span class="Type">const</span> Inttype n_max;
+<span class="lnr">35 </span>
+<span class="lnr">36 </span> <span class="Comment">// Accuracy requirement …
+<span class="lnr">37 </span> <span class="Type">const</span> Floattype delt…
+<span class="lnr">38 </span> <span class="Type">const</span> Floattype epsi…
+<span class="lnr">39 </span>
+<span class="lnr">40 </span> <span class="Comment">// Tolerance estimator</…
+<span class="lnr">41 </span> Floattype tau(<span class="Type">const</span> …
+<span class="lnr">42 </span> <span class="Type">const</span> …
+<span class="lnr">43 </span>
+<span class="lnr">44 </span> <span class="Comment">// Runge-Kutta mid-point…
+<span class="lnr">45 </span> <span class="Type">void</span> rkstep12(<span …
+<span class="lnr">46 </span> <span class="Type">const</span> …
+<span class="lnr">47 </span> std::vector&lt;std::comple…
+<span class="lnr">48 </span> std::vector&lt;std::comple…
+<span class="lnr">49 </span>
+<span class="lnr">50 </span> <span class="Comment">// Runge-Kutta driver fu…
+<span class="lnr">51 </span> <span class="Type">const</span> Floattype powe…
+<span class="lnr">52 </span> <span class="Type">const</span> Floattype safe…
+<span class="lnr">53 </span>
+<span class="lnr">54 </span> <span class="Comment">// Runge-Kutta driver pr…
+<span class="lnr">55 </span> <span class="Type">void</span> rkdriver();
+<span class="lnr">56 </span>
+<span class="lnr">57 </span>
+<span class="lnr">58 </span> <span class="Comment">// Values and functions ac…
+<span class="lnr">59 </span> <span class="Statement">public</span>:
+<span class="lnr">60 </span>
+<span class="lnr">61 </span> <span class="Comment">// Constructor, some par…
+<span class="lnr">62 </span> ODE(std::vector&lt;std::complex&lt;Floattype&g…
+<span class="lnr">63 </span> (*f_in)(<span class="Type">const</…
+<span class="lnr">64 </span> <span class="Type">const</…
+<span class="lnr">65 </span> <span class="Type">const</span> std::vecto…
+<span class="lnr">66 </span> <span class="Type">const</span> std::compl…
+<span class="lnr">67 </span> <span class="Type">const</span> std::compl…
+<span class="lnr">68 </span> <span class="Type">const</span> Floattype …
+<span class="lnr">69 </span> <span class="Type">const</span> Inttype ma…
+<span class="lnr">70 </span> <span class="Type">const</span> Floattype …
+<span class="lnr">71 </span> <span class="Type">const</span> Floattype …
+<span class="lnr">72 </span> <span class="Type">const</span> Floattype …
+<span class="lnr">73 </span> <span class="Type">const</span> Floattype …
+<span class="lnr">74 </span> );
+<span class="lnr">75 </span>
+<span class="lnr">76 </span> <span class="Comment">// Return the number of …
+<span class="lnr">77 </span> Inttype steps();
+<span class="lnr">78 </span>
+<span class="lnr">79 </span> <span class="Comment">// Print the x- and y-va…
+<span class="lnr">80 </span> <span class="Type">void</span> print();
+<span class="lnr">81 </span>
+<span class="lnr">82 </span> <span class="Comment">// Write the x- and y-va…
+<span class="lnr">83 </span> <span class="Type">void</span> write(<span cla…
+<span class="lnr">84 </span>
+<span class="lnr">85 </span>};
+<span class="lnr">86 </span>
+<span class="lnr">87 </span><span class="PreProc">#endif</span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/plotA.gp.html b/exam/html/plotA.gp.html
t@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/plotA.gp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="gp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Constant { color: #ffff00; }
+.Statement { color: #ffff00; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr">1 </span>set terminal png
+<span class="lnr">2 </span>set <span class="Statement">output</span> <span cla…
+<span class="lnr">3 </span>set xlabel <span class="Constant">&quot;x.real&quot…
+<span class="lnr">4 </span>set ylabel <span class="Constant">&quot;y.real&quot…
+<span class="lnr">5 </span>set title <span class="Constant">&quot;Integration …
+<span class="lnr">6 </span>set grid
+<span class="lnr">7 </span>plot <span class="Constant">&quot;funcA.dat&quot;</…
+<span class="lnr">8 </span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/plotB.gp.html b/exam/html/plotB.gp.html
t@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/plotB.gp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="gp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Constant { color: #ffff00; }
+.Statement { color: #ffff00; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr">1 </span>set terminal png
+<span class="lnr">2 </span>set <span class="Statement">output</span> <span cla…
+<span class="lnr">3 </span>set xlabel <span class="Constant">&quot;x.imag&quot…
+<span class="lnr">4 </span>set ylabel <span class="Constant">&quot;y.imag&quot…
+<span class="lnr">5 </span>set title <span class="Constant">&quot;Integration …
+<span class="lnr">6 </span>set grid
+<span class="lnr">7 </span>plot <span class="Constant">&quot;funcB.dat&quot;</…
+<span class="lnr">8 </span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/plotC.gp.html b/exam/html/plotC.gp.html
t@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/plotC.gp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="gp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Constant { color: #ffff00; }
+.Statement { color: #ffff00; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr">1 </span>set terminal png
+<span class="lnr">2 </span>set <span class="Statement">output</span> <span cla…
+<span class="lnr">3 </span>set xlabel <span class="Constant">&quot;x.r&quot;</…
+<span class="lnr">4 </span>set ylabel <span class="Constant">&quot;x.i&quot;</…
+<span class="lnr">5 </span>set zlabel <span class="Constant">&quot;y&quot;</sp…
+<span class="lnr">6 </span>set title <span class="Constant">&quot;Integration …
+<span class="lnr">7 </span>set grid
+<span class="lnr">8 </span>splot <span class="Constant">&quot;funcC.dat&quot;<…
+<span class="lnr">9 </span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/plotD.gp.html b/exam/html/plotD.gp.html
t@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/plotD.gp.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="gp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Constant { color: #ffff00; }
+.Statement { color: #ffff00; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr">1 </span>set terminal png
+<span class="lnr">2 </span>set <span class="Statement">output</span> <span cla…
+<span class="lnr">3 </span>set xlabel <span class="Constant">&quot;Precision&q…
+<span class="lnr">4 </span>set ylabel <span class="Constant">&quot;No. of step…
+<span class="lnr">5 </span>set title <span class="Constant">&quot;Number of st…
+<span class="lnr">6 </span>set grid
+<span class="lnr">7 </span>set <span class="Statement">log</span> xy
+<span class="lnr">8 </span>plot <span class="Constant">&quot;funcD.dat&quot;</…
+<span class="lnr">9 </span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/typedefs.h.html b/exam/html/typedefs.h.html
t@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/typedefs.h.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Constant { color: #ffff00; }
+.Type { color: #00ff00; }
+.PreProc { color: #ff40ff; }
+.Comment { color: #00ffff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="Comment">// Make sure header is only …
+<span class="lnr"> 2 </span><span class="PreProc">#ifndef TYPEDEFS_H_</span>
+<span class="lnr"> 3 </span><span class="PreProc">#define TYPEDEFS_H_</span>
+<span class="lnr"> 4 </span>
+<span class="lnr"> 5 </span><span class="Comment">// Define whether the progra…
+<span class="lnr"> 6 </span><span class="Comment">//const bool verbose = false…
+<span class="lnr"> 7 </span><span class="Type">const</span> <span class="Type"…
+<span class="lnr"> 8 </span>
+<span class="lnr"> 9 </span><span class="Comment">// Choose length variable ty…
+<span class="lnr">10 </span><span class="Type">typedef</span> <span class="Typ…
+<span class="lnr">11 </span>
+<span class="lnr">12 </span><span class="Comment">// Choose floating-point pre…
+<span class="lnr">13 </span><span class="Type">typedef</span> <span class="Typ…
+<span class="lnr">14 </span>
+<span class="lnr">15 </span><span class="PreProc">#endif</span>
+</pre>
+</body>
+</html>
diff --git a/exam/html/vector_arithmetic.h.html b/exam/html/vector_arithmetic.h…
t@@ -0,0 +1,116 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/…
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>~/code/numeric/exam/vector_arithmetic.h.html</title>
+<meta name="Generator" content="Vim/7.3">
+<meta name="plugin-version" content="vim7.3_v10">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="number_lines,use_css,pre_wrap,expand_tabs">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; backgroun…
+body { font-family: monospace; color: #ffffff; background-color: #000000; }
+.lnr { color: #ffff00; }
+.Type { color: #00ff00; }
+.Statement { color: #ffff00; }
+.Constant { color: #ffff00; }
+.PreProc { color: #ff40ff; }
+.Comment { color: #00ffff; }
+-->
+</style>
+</head>
+<body>
+<pre>
+<span class="lnr"> 1 </span><span class="Comment">// Make sure header is only …
+<span class="lnr"> 2 </span><span class="PreProc">#ifndef VECTOR_ARITHMETIC_H_…
+<span class="lnr"> 3 </span><span class="PreProc">#define VECTOR_ARITHMETIC_H_…
+<span class="lnr"> 4 </span>
+<span class="lnr"> 5 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 6 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 7 </span><span class="PreProc">#include </span><span class=…
+<span class="lnr"> 8 </span>
+<span class="lnr"> 9 </span><span class="Comment">//// Overload vector methods…
+<span class="lnr">10 </span><span class="Comment">//// and element-wise arithm…
+<span class="lnr">11 </span>
+<span class="lnr">12 </span><span class="Comment">// Scalar multiplication (sa…
+<span class="lnr">13 </span>std::vector&lt;std::complex&lt;Floattype&gt; &gt;
+<span class="lnr">14 </span> <span class="Statement">operator</span>*(<…
+<span class="lnr">15 </span> <span class="Type">const</span> …
+<span class="lnr">16 </span>{
+<span class="lnr">17 </span> std::vector&lt;std::complex&lt;Floattype&gt; &gt…
+<span class="lnr">18 </span> <span class="Statement">for</span> (Inttype i=<s…
+<span class="lnr">19 </span> result[i].real() = real(vec[i])*scalar;
+<span class="lnr">20 </span> result[i].imag() = imag(vec[i])*scalar;
+<span class="lnr">21 </span> }
+<span class="lnr">22 </span> <span class="Statement">return</span> result;
+<span class="lnr">23 </span>}
+<span class="lnr">24 </span>
+<span class="lnr">25 </span><span class="Comment">// Scalar multiplication</sp…
+<span class="lnr">26 </span>std::vector&lt;std::complex&lt;Floattype&gt; &gt;
+<span class="lnr">27 </span> <span class="Statement">operator</span>*(<…
+<span class="lnr">28 </span> <span class="Type">const</span> …
+<span class="lnr">29 </span>{
+<span class="lnr">30 </span> std::vector&lt;std::complex&lt;Floattype&gt; &gt…
+<span class="lnr">31 </span> <span class="Statement">for</span> (Inttype i=<s…
+<span class="lnr">32 </span> result[i] = vec[i]*scalar;
+<span class="lnr">33 </span> <span class="Statement">return</span> result;
+<span class="lnr">34 </span>}
+<span class="lnr">35 </span>
+<span class="lnr">36 </span><span class="Comment">// Scalar division </span>
+<span class="lnr">37 </span>std::vector&lt;std::complex&lt;Floattype&gt; &gt;
+<span class="lnr">38 </span> <span class="Statement">operator</span>/(<…
+<span class="lnr">39 </span> <span class="Type">const</span> …
+<span class="lnr">40 </span>{
+<span class="lnr">41 </span> std::vector&lt;std::complex&lt;Floattype&gt; &gt…
+<span class="lnr">42 </span> <span class="Statement">for</span> (Inttype i=<s…
+<span class="lnr">43 </span> result[i] = vec[i]/scalar;
+<span class="lnr">44 </span> <span class="Statement">return</span> result;
+<span class="lnr">45 </span>}
+<span class="lnr">46 </span>
+<span class="lnr">47 </span><span class="Comment">// Element-wise addition</sp…
+<span class="lnr">48 </span>std::vector&lt;std::complex&lt;Floattype&gt; &gt;
+<span class="lnr">49 </span> <span class="Statement">operator</span>+(<…
+<span class="lnr">50 </span> <span class="Type">const</span> …
+<span class="lnr">51 </span>{
+<span class="lnr">52 </span> std::vector&lt;std::complex&lt;Floattype&gt; &gt…
+<span class="lnr">53 </span> <span class="Statement">for</span> (Inttype i=<s…
+<span class="lnr">54 </span> result[i] = vec1[i] + vec2[i];
+<span class="lnr">55 </span> <span class="Statement">return</span> result;
+<span class="lnr">56 </span>}
+<span class="lnr">57 </span>
+<span class="lnr">58 </span><span class="Comment">// Element-wise subtraction<…
+<span class="lnr">59 </span>std::vector&lt;std::complex&lt;Floattype&gt; &gt;
+<span class="lnr">60 </span> <span class="Statement">operator</span>-(<…
+<span class="lnr">61 </span> <span class="Type">const</span> …
+<span class="lnr">62 </span>{
+<span class="lnr">63 </span> std::vector&lt;std::complex&lt;Floattype&gt; &gt…
+<span class="lnr">64 </span> <span class="Statement">for</span> (Inttype i=<s…
+<span class="lnr">65 </span> result[i] = vec1[i] - vec2[i];
+<span class="lnr">66 </span> <span class="Statement">return</span> result;
+<span class="lnr">67 </span>}
+<span class="lnr">68 </span>
+<span class="lnr">69 </span><span class="Comment">// Element-wise multiplicati…
+<span class="lnr">70 </span>std::vector&lt;std::complex&lt;Floattype&gt; &gt;
+<span class="lnr">71 </span> <span class="Statement">operator</span>*(<…
+<span class="lnr">72 </span> <span class="Type">const</span> …
+<span class="lnr">73 </span>{
+<span class="lnr">74 </span> std::vector&lt;std::complex&lt;Floattype&gt; &gt…
+<span class="lnr">75 </span> <span class="Statement">for</span> (Inttype i=<s…
+<span class="lnr">76 </span> result[i] = vec1[i] * vec2[i];
+<span class="lnr">77 </span> <span class="Statement">return</span> result;
+<span class="lnr">78 </span>}
+<span class="lnr">79 </span>
+<span class="lnr">80 </span><span class="Comment">// Normalize vector</span>
+<span class="lnr">81 </span>Floattype cnorm(<span class="Type">const</span> st…
+<span class="lnr">82 </span>{
+<span class="lnr">83 </span> Floattype res = <span class="Constant">0.0f</spa…
+<span class="lnr">84 </span> <span class="Statement">for</span> (Inttype i=<s…
+<span class="lnr">85 </span> res += norm(vec[i])*norm(vec[i]);
+<span class="lnr">86 </span> <span class="Statement">return</span> sqrt(res);
+<span class="lnr">87 </span>}
+<span class="lnr">88 </span>
+<span class="lnr">89 </span><span class="PreProc">#endif</span>
+</pre>
+</body>
+</html>
diff --git a/exam/mainA.cpp b/exam/mainA.cpp
t@@ -0,0 +1,59 @@
+#include <iostream>
+#include <vector>
+#include <complex>
+#include <cmath>
+#include "typedefs.h"
+#include "check.h"
+#include "ode.h"
+#include "functions.h"
+
+
+int main()
+{
+ // Namespace declarations
+ using std::cout;
+ using std::vector;
+ using std::complex;
+
+ // Calculate machine precision
+ Floattype eps_machine = 1.0f;
+ while (1.0f + eps_machine != 1.0f)
+ eps_machine /= 2.0f;
+
+ const int id = 20062213;
+ const char n = 10;
+ cout << "\nMy student id is \033[1;37m" << id
+ << "\033[0m, resulting in exam exercise: \033[1;31m"
+ << id%n << "\033[0m\n";
+ cout << "Examination project:\033[1;37m ODE integration "
+ << "with complex numbers\033[0m\n\n";
+
+ cout << "\033[1;33m--- Part A: Solving along a real path ---\033[0m\n";
+ complex<Floattype> a(0.0f, 0.0f); // Lower limit
+ complex<Floattype> b(2.0f*M_PI, 0.0f); // Upper limit
+ cout << "Integration path: b-a = " << b-a << '\n';
+ Inttype n_eqs = 2; // Number of equations in ODE system
+ vector<complex<Floattype> > y_start(n_eqs);
+ complex<Floattype> y0(0.0f, 0.0f);
+ complex<Floattype> y1(1.0f, 1.0f);
+ y_start[0] = y0;
+ y_start[1] = y1;
+ Floattype h_start = 0.01f;
+ ODE realode(func1, // ODE system
+ y_start, // Initial values
+ a, // Lower limit
+ b, // Upper limit
+ h_start, // Start value of step size
+ 10000, // Max. number of steps
+ eps_machine*1e12f, // Absolute precision
+ eps_machine*1e12f); // Relative precision
+ realode.write("funcA.dat"); // Write solutions to data file
+
+ // Report to stdout
+ cout << "ODE system solved in "
+ << realode.steps() << " steps.\n\n";
+
+ // Return successfully
+ return 0;
+}
+
diff --git a/exam/mainB.cpp b/exam/mainB.cpp
t@@ -0,0 +1,50 @@
+#include <iostream>
+#include <vector>
+#include <complex>
+#include <cmath>
+#include "typedefs.h"
+#include "check.h"
+#include "ode.h"
+#include "functions.h"
+
+int main()
+{
+ // Namespace declarations
+ using std::cout;
+ using std::vector;
+ using std::complex;
+
+ // Calculate machine precision
+ Floattype eps_machine = 1.0f;
+ while (1.0f + eps_machine != 1.0f)
+ eps_machine /= 2.0f;
+
+ cout << "\n\033[1;33m--- Part B: Solving along an imaginary path ---\033[0m\…
+ complex<Floattype> a(0.0f, 0.0f); // Lower limit
+ complex<Floattype> b(0.0f, 2.0f*M_PI); // Upper limit
+ cout << "Integration path: b-a = " << b-a << '\n';
+ Inttype n_eqs = 2; // Number of equations in ODE system
+ vector<complex<Floattype> > y_start(n_eqs);
+ complex<Floattype> y0(0.0f, 0.0f);
+ complex<Floattype> y1(1.0f, 1.0f);
+ y_start[0] = y0;
+ y_start[1] = y1;
+ Floattype h_start = 0.01f;
+ ODE imagode(func1, // ODE system
+ y_start, // Initial values
+ a, // Lower limit
+ b, // Upper limit
+ h_start, // Start value of step size
+ 10000, // Max. number of steps
+ eps_machine*1e12f, // Absolute precision
+ eps_machine*1e12f); // Relative precision
+ imagode.write("funcB.dat"); // Write solutions to data file
+
+ // Report to stdout
+ cout << "ODE system solved in "
+ << imagode.steps() << " steps.\n\n";
+
+ // Return successfully
+ return 0;
+}
+
diff --git a/exam/mainC.cpp b/exam/mainC.cpp
t@@ -0,0 +1,50 @@
+#include <iostream>
+#include <vector>
+#include <complex>
+#include <cmath>
+#include "typedefs.h"
+#include "check.h"
+#include "ode.h"
+#include "functions.h"
+
+int main()
+{
+ // Namespace declarations
+ using std::cout;
+ using std::vector;
+ using std::complex;
+
+ // Calculate machine precision
+ Floattype eps_machine = 1.0f;
+ while (1.0f + eps_machine != 1.0f)
+ eps_machine /= 2.0f;
+
+ cout << "\n\033[1;33m--- Part C: Solving along a complex path ---\033[0m\n";
+ complex<Floattype> a(0.0f, 0.0f); // Lower limit
+ complex<Floattype> b(2.0f*M_PI, 2.0f*M_PI); // Upper limit
+ cout << "Integration path: b-a = " << b-a << '\n';
+ Inttype n_eqs = 2; // Number of equations in ODE system
+ vector<complex<Floattype> > y_start(n_eqs);
+ complex<Floattype> y0(0.0f, 0.0f);
+ complex<Floattype> y1(1.0f, 1.0f);
+ y_start[0] = y0;
+ y_start[1] = y1;
+ Floattype h_start = 0.01f;
+ ODE ode(func1, // ODE system
+ y_start, // Initial values
+ a, // Lower limit
+ b, // Upper limit
+ h_start, // Start value of step size
+ 10000, // Max. number of steps
+ eps_machine*1e12f, // Absolute precision
+ eps_machine*1e12f); // Relative precision
+ ode.write("funcC.dat"); // Write solutions to data file
+
+ // Report to stdout
+ cout << "ODE system solved in "
+ << ode.steps() << " steps.\n\n";
+
+ // Return successfully
+ return 0;
+}
+
diff --git a/exam/mainD.cpp b/exam/mainD.cpp
t@@ -0,0 +1,68 @@
+#include <iostream>
+#include <vector>
+#include <complex>
+#include <cmath>
+#include <fstream>
+#include "typedefs.h"
+#include "check.h"
+#include "ode.h"
+#include "functions.h"
+
+
+int main()
+{
+ // Namespace declarations
+ using std::cout;
+ using std::vector;
+ using std::complex;
+
+ // Calculate machine precision
+ Floattype eps_machine = 1.0f;
+ while (1.0f + eps_machine != 1.0f)
+ eps_machine /= 2.0f;
+
+ cout << "\n\033[1;33m--- Part D: Precision analysis ---\033[0m\n";
+ complex<Floattype> a(0.0f, 0.0f); // Lower limit
+ complex<Floattype> b(2.0f*M_PI, 2.0f*M_PI); // Upper limit
+ cout << "Integration path: b-a = " << b-a << '\n';
+ Inttype n_eqs = 2; // Number of equations in ODE system
+ vector<complex<Floattype> > y_start(n_eqs);
+ complex<Floattype> y0(0.0f, 0.0f);
+ complex<Floattype> y1(1.0f, 1.0f);
+ y_start[0] = y0;
+ y_start[1] = y1;
+ Floattype h_start = 0.01f;
+
+ vector<Floattype> precs; // Vector containing precision values
+ vector<Inttype> steps; // Vector containing number of steps required
+
+ for (Floattype prec=eps_machine*10.0f; prec<0.1f; prec *= 10.0f) {
+ ODE ode(func1, // ODE system
+ y_start, // Initial values
+ a, // Lower limit
+ b, // Upper limit
+ h_start, // Start value of step size
+ 100000, // Max. number of steps
+ prec, // Absolute precision
+ prec); // Relative precision
+ precs.push_back(prec); // Save precision
+ steps.push_back(ode.steps()); // Save number of steps taken
+ }
+
+ // Save results to text file
+ std::ofstream ost; // Out stream object
+ ost.open("funcD.dat"); // Open outfile for write
+ if (!ost) {
+ std::cerr << "Error, can't open output file!\n";
+ return 1;
+ }
+ // Write output values
+ for (Inttype i=0; i<precs.size(); ++i)
+ ost << precs[i] << '\t' << steps[i] << '\n';
+
+ // Close file
+ ost.close();
+
+ // Return successfully
+ return 0;
+}
diff --git a/exam/ode.cpp b/exam/ode.cpp
t@@ -0,0 +1,163 @@
+#include <iostream>
+#include <vector>
+#include <cmath> // for sqrt and pow
+#include <fstream>
+#include "typedefs.h"
+#include "ode.h"
+#include "vector_arithmetic.h"
+
+// Constructor
+ODE::ODE(std::vector<std::complex<Floattype> >
+ (*f_in)(const std::complex<Floattype> x,
+ const std::vector<std::complex<Floattype> > &y),
+ const std::vector<std::complex<Floattype> > y_start,
+ const std::complex<Floattype> a_in,
+ const std::complex<Floattype> b_in,
+ const Floattype h_start,
+ const Inttype max_steps,
+ const Floattype delta_in,
+ const Floattype epsilon_in,
+ const Floattype power_in,
+ const Floattype safety_in)
+ : f(f_in),
+ a(a_in), b(b_in),
+ h((b_in-a_in)*h_start),
+ n_max(max_steps),
+ delta(delta_in), epsilon(epsilon_in),
+ power(power_in), safety(safety_in)
+{
+ x_list.push_back(a);
+ y_list.push_back(y_start);
+
+ // Perform integration
+ rkdriver();
+}
+
+
+// Estimate tolerance
+Floattype ODE::tau(const std::vector<std::complex<Floattype> > &y,
+ const std::complex<Floattype> h_i)
+{
+ return abs((epsilon * cnorm(y) + delta) * sqrt(h_i/(b-a)));
+}
+
+// Runge-Kutta mid-point stepper
+void ODE::rkstep12(const std::complex<Floattype> x0,
+ const std::vector<std::complex<Floattype> > &y0,
+ std::vector<std::complex<Floattype> > &y1,
+ std::vector<std::complex<Floattype> > &dy)
+{
+ // Denominator 2 used in arithmetic operations
+ const std::complex<Floattype> den2 (2.0f,2.0f);
+
+ // Evaluate function at two points
+ (void)f(x0,y0);
+ const std::vector<std::complex<Floattype> > k0 = f(x0,y0);
+ const std::vector<std::complex<Floattype> > k12 = f(x0 + h/den2, y0 + k0*h/d…
+
+ // Write results to output vectors
+ y1 = y0 + k12*h;
+ dy = (k0 - k12) * h/den2;
+}
+
+
+// ODE driver with adaptive step size control
+void ODE::rkdriver()
+{
+ std::vector<std::complex<Floattype> > dy(n_max);
+ std::vector<std::complex<Floattype> > y1(n_max);
+
+ std::complex<Floattype> x;
+ Floattype err, tol;
+ std::vector<std::complex<Floattype> > y;
+
+ while (x_list.back().real() < b.real()
+ || x_list.back().imag() < b.imag())
+ {
+ // Get values for this step
+ x = x_list.back();
+ y = y_list.back();
+
+ // Make sure we don't step past the upper boundary
+ if ((x + h).real() > b.real()
+ || (x + h).imag() > b.imag())
+ h = b - x;
+
+ // Run Runge-Kutta mid-point stepper
+ rkstep12(x, y, y1, dy);
+
+ // Determine whether the step should be accepted
+ err = cnorm(dy); // Error estimate
+ tol = tau(y, h); // Tolerance
+ if (err < tol) { // Step accepted
+ x_list.push_back(x+h);
+ y_list.push_back(y1);
+ }
+
+ // Check that we havn't hit the max. number of steps
+ if (x_list.size() == n_max) {
+ std::cerr << "Error, the max. number of steps "
+ << "was insufficient\n"
+ << "Try either increasing the max. number "
+ << "of steps, or decreasing the precision "
+ << "requirements\n";
+ return;
+ }
+
+ // Determine new step size
+ std::complex<Floattype> multiplicator (2.0f, 2.0f);
+ if (err > 0.0f)
+ h = h*pow(tol/err, power) * safety;
+ else
+ h = multiplicator*h;
+ }
+}
+
+
+// Return the number of steps taken
+Inttype ODE::steps()
+{
+ return x_list.size();
+}
+
+void ODE::print()
+{
+ for (Inttype i=0; i<x_list.size(); ++i) {
+ std::cout << x_list[i] << '\t';
+ for (Inttype j=0; j<y_list[0].size(); ++j)
+ std::cout << y_list[i][j] << '\t';
+ std::cout << '\n';
+ }
+}
+
+// Write the x- and y-values to file
+void ODE::write(const char* filename)
+{
+ std::ofstream outstream;
+
+ // Open outfile for write
+ outstream.open(filename);
+ if (!outstream) {
+ std::cerr << "Error, can't open output file '"
+ << filename << "'.\n";
+ return;
+ }
+
+ // Write output values
+ for (Inttype i=0; i<x_list.size(); ++i) {
+ outstream << x_list[i].real() << '\t';
+ outstream << x_list[i].imag() << '\t';
+ for (Inttype j=0; j<y_list[0].size(); ++j) {
+ outstream << y_list[i][j].real() << '\t';
+ outstream << y_list[i][j].imag() << '\t';
+ }
+ outstream << '\n';
+ }
+
+ // Close file
+ outstream.close();
+
+ if (verbose == true)
+ std::cout << "Output written in '" << filename << "'.\n";
+}
+
diff --git a/exam/ode.h b/exam/ode.h
t@@ -0,0 +1,87 @@
+// Make sure header is only included once
+#ifndef ODE_H_
+#define ODE_H_
+
+#include <vector>
+#include <complex>
+#include "typedefs.h"
+
+// ODE class
+class ODE {
+
+ // Values and functions only accessible from the class internally
+ private:
+
+ // System of ordinary differential equations to solve
+ std::vector<std::complex<Floattype> >
+ (*f)(const std::complex<Floattype> x,
+ const std::vector<std::complex<Floattype> > &y);
+
+ // Points to be evaluated
+ std::vector<std::complex<Floattype> > x_list;
+
+ // Limits of range to evaluate
+ const std::complex<Floattype> a; // Lower
+ const std::complex<Floattype> b; // Upper
+
+ // Step size
+ std::complex<Floattype> h;
+
+ // Results stored in 2D: vector of vectors
+ std::vector<std::vector<std::complex<Floattype> > > y_list;
+
+ // Maximum number of steps to evaluate, defined by y size
+ const Inttype n_max;
+
+ // Accuracy requirement values
+ const Floattype delta; // Absolute
+ const Floattype epsilon; // Relative
+
+ // Tolerance estimator
+ Floattype tau(const std::vector<std::complex<Floattype> > &y,
+ const std::complex<Floattype> h);
+
+ // Runge-Kutta mid-point stepper prototype
+ void rkstep12(const std::complex<Floattype> x0,
+ const std::vector<std::complex<Floattype> > &y0,
+ std::vector<std::complex<Floattype> > &y1,
+ std::vector<std::complex<Floattype> > &dy);
+
+ // Runge-Kutta driver function parameters
+ const Floattype power;
+ const Floattype safety;
+
+ // Runge-Kutta driver prototype
+ void rkdriver();
+
+
+ // Values and functions accessible from the outside
+ public:
+
+ // Constructor, some parameters with default values
+ ODE(std::vector<std::complex<Floattype> >
+ (*f_in)(const std::complex<Floattype> x,
+ const std::vector<std::complex<Floattype> > &y),
+ const std::vector<std::complex<Floattype> > y_start,
+ const std::complex<Floattype> a_in,
+ const std::complex<Floattype> b_in,
+ const Floattype h_start = 0.01f,
+ const Inttype max_steps = 1e4,
+ const Floattype delta_in = 1e-3f,
+ const Floattype epsilon_in = 1e-3f,
+ const Floattype power_in = 0.25f,
+ const Floattype safety_in = 0.95f
+ );
+
+ // Return the number of steps taken
+ Inttype steps();
+
+ // Print the x- and y-values to stdout
+ void print();
+
+ // Write the x- and y-values to file
+ void write(const char* filename);
+
+};
+
+#endif
diff --git a/exam/plotA.gp b/exam/plotA.gp
t@@ -0,0 +1,8 @@
+set terminal png
+set output "plotA.png"
+set xlabel "x.real"
+set ylabel "y.real"
+set title "Integration along a real path"
+set grid
+plot "funcA.dat" u 1:3 t "rk12" w lp
+
diff --git a/exam/plotB.gp b/exam/plotB.gp
t@@ -0,0 +1,8 @@
+set terminal png
+set output "plotB.png"
+set xlabel "x.imag"
+set ylabel "y.imag"
+set title "Integration along an imaginary path"
+set grid
+plot "funcB.dat" u 2:4 t "rk12" w lp
+
diff --git a/exam/plotC.gp b/exam/plotC.gp
t@@ -0,0 +1,9 @@
+set terminal png
+set output "plotC.png"
+set xlabel "x.r"
+set ylabel "x.i"
+set zlabel "y"
+set title "Integration along a complex path"
+set grid
+splot "funcC.dat" u 1:2:3 t "y.real" w lp, "" u 1:2:4 t "y.imag" w lp
+
diff --git a/exam/plotD.gp b/exam/plotD.gp
t@@ -0,0 +1,9 @@
+set terminal png
+set output "plotD.png"
+set xlabel "Precision"
+set ylabel "No. of steps"
+set title "Number of steps required for a given absolute and relative precisio…
+set grid
+set log xy
+plot "funcD.dat" u 1:2 t "rk12" w lp
+
diff --git a/exam/typedefs.h b/exam/typedefs.h
t@@ -0,0 +1,15 @@
+// Make sure header is only included once
+#ifndef TYPEDEFS_H_
+#define TYPEDEFS_H_
+
+// Define whether the program should output values of matrices
+//const bool verbose = false;
+const bool verbose = true;
+
+// Choose length variable type
+typedef unsigned int Inttype;
+
+// Choose floating-point precision
+typedef double Floattype;
+
+#endif
diff --git a/exam/vector_arithmetic.h b/exam/vector_arithmetic.h
t@@ -0,0 +1,89 @@
+// Make sure header is only included once
+#ifndef VECTOR_ARITHMETIC_H_
+#define VECTOR_ARITHMETIC_H_
+
+#include <vector>
+#include <cmath> // for sqrt
+#include "typedefs.h"
+
+//// Overload vector methods to allow scalar-
+//// and element-wise arithmetic operations
+
+// Scalar multiplication (same scalar for real and imaginary parts)
+std::vector<std::complex<Floattype> >
+ operator*(const std::vector<std::complex<Floattype> > vec,
+ const Floattype scalar)
+{
+ std::vector<std::complex<Floattype> > result(vec.size());
+ for (Inttype i=0; i<vec.size(); ++i) {
+ result[i].real() = real(vec[i])*scalar;
+ result[i].imag() = imag(vec[i])*scalar;
+ }
+ return result;
+}
+
+// Scalar multiplication
+std::vector<std::complex<Floattype> >
+ operator*(const std::vector<std::complex<Floattype> > vec,
+ const std::complex<Floattype> scalar)
+{
+ std::vector<std::complex<Floattype> > result(vec.size());
+ for (Inttype i=0; i<(Inttype)vec.size(); ++i)
+ result[i] = vec[i]*scalar;
+ return result;
+}
+
+// Scalar division
+std::vector<std::complex<Floattype> >
+ operator/(const std::vector<std::complex<Floattype> > vec,
+ const std::complex<Floattype> scalar)
+{
+ std::vector<std::complex<Floattype> > result(vec.size());
+ for (Inttype i=0; i<(Inttype)vec.size(); ++i)
+ result[i] = vec[i]/scalar;
+ return result;
+}
+
+// Element-wise addition
+std::vector<std::complex<Floattype> >
+ operator+(const std::vector<std::complex<Floattype> > vec1,
+ const std::vector<std::complex<Floattype> > vec2)
+{
+ std::vector<std::complex<Floattype> > result(vec1.size());
+ for (Inttype i=0; i<(Inttype)vec1.size(); ++i)
+ result[i] = vec1[i] + vec2[i];
+ return result;
+}
+
+// Element-wise subtraction
+std::vector<std::complex<Floattype> >
+ operator-(const std::vector<std::complex<Floattype> > vec1,
+ const std::vector<std::complex<Floattype> > vec2)
+{
+ std::vector<std::complex<Floattype> > result(vec1.size());
+ for (Inttype i=0; i<(Inttype)vec1.size(); ++i)
+ result[i] = vec1[i] - vec2[i];
+ return result;
+}
+
+// Element-wise multiplication
+std::vector<std::complex<Floattype> >
+ operator*(const std::vector<std::complex<Floattype> > vec1,
+ const std::vector<std::complex<Floattype> > vec2)
+{
+ std::vector<std::complex<Floattype> > result(vec1.size());
+ for (Inttype i=0; i<(Inttype)vec1.size(); ++i)
+ result[i] = vec1[i] * vec2[i];
+ return result;
+}
+
+// Normalize vector
+Floattype cnorm(const std::vector<std::complex<Floattype> > vec)
+{
+ Floattype res = 0.0f;
+ for (Inttype i=0; i<(Inttype)vec.size(); ++i)
+ res += norm(vec[i])*norm(vec[i]);
+ return sqrt(res);
+}
+
+#endif
diff --git a/hello/Makefile b/hello/Makefile
t@@ -0,0 +1,71 @@
+# Define compiler
+CC=g++
+
+# Define compiler flags (show all warnings)
+CCFLAGS=-Wall
+
+# Define linker
+LD=g++
+
+# Define linker flags
+LDFLAGS=
+
+# Filenames of source code
+ASRC=$(shell ls *.A.cpp)
+BSRC=$(shell ls *.B.cpp)
+
+# Filenames of object files
+BOBJ=$(BSRC:.cpp=.o)
+
+# Remove file type extension for binary filename
+ABIN=$(ASRC:.cpp=)
+BBIN=hello_user.B
+
+# The default "all" depends on A and B
+
+all: A B
+
+correct:
+ # Cenerating correct answer
+ @echo "Hello, $(USER)" > correct.txt
+
+A:
+ # Compile source code
+ $(CC) $(CCFLAGS) $(ASRC) -o $(ABIN)
+ # Execute program and redirect stdout to file
+ ./$(ABIN) > out.A.txt
+
+B: $(BOBJ)
+ # Link object files together
+ $(LD) $(LDFLAGS) $(BOBJ) -o $(BBIN)
+ # Execute program and redirect stdout to file
+ ./$(BBIN) > out.B.txt
+
+# Object files for B require B source code files
+.B.o: $(BSRC)
+ $(CC) $(CCFLAGS) -c $< -o $@
+
+clean-A:
+ # Remove binary
+ rm -f $(ABIN)
+
+clean-B:
+ # Remove object files
+ rm -f $(BOBJ)
+ # Remove binary
+ rm -f $(BBIN)
+
+clean: clean-A clean-B
+ rm -f correct.txt
+
+test-A: correct A
+ @echo "Checking A... "
+ @diff --brief correct.txt out.A.txt
+ @echo "done"
+
+test-B: correct B
+ @echo "Checking B... "
+ @diff --brief correct.txt out.B.txt
+ @echo "done"
+
+test: test-A test-B
diff --git a/hello/hello.B.cpp b/hello/hello.B.cpp
t@@ -0,0 +1,6 @@
+#include <iostream>
+
+void hello()
+{
+ std::cout << "Hello, ";
+}
diff --git a/hello/hello_user.A.cpp b/hello/hello_user.A.cpp
t@@ -0,0 +1,19 @@
+#include <iostream>
+#include <string>
+#include <cstdlib> // For getenv()
+
+int main()
+{
+ // Namespace definitions
+ using std::cout;
+ using std::string;
+
+ // Get USER environment variable
+ string username = getenv("USER");
+
+ // Greet user
+ cout << "Hello, " << username << '\n';
+
+ // Successfull exit
+ return 0;
+}
diff --git a/hello/main.B.cpp b/hello/main.B.cpp
t@@ -0,0 +1,14 @@
+#include <iostream>
+
+// Prototype functions
+#include "main.B.h"
+
+int main()
+{
+ // Call functions from object files
+ hello();
+ your_username();
+
+ // Successfull exit
+ return 0;
+}
diff --git a/hello/main.B.h b/hello/main.B.h
t@@ -0,0 +1,8 @@
+// Header file containing prototype functions
+
+// hello.B.cpp
+void hello();
+
+// your_username.B.cpp
+void your_username();
+
diff --git a/hello/your_username.B.cpp b/hello/your_username.B.cpp
t@@ -0,0 +1,14 @@
+#include <iostream>
+#include <string>
+#include <cstdlib> // For getenv()
+
+void your_username()
+{
+
+ // Get USER environment variable
+ std::string username = getenv("USER");
+
+ // Print username to stdout
+ std::cout << username << '\n';
+
+}
diff --git a/integration/Makefile b/integration/Makefile
t@@ -0,0 +1,71 @@
+# Define compiler
+CC=g++
+
+# Define compiler flags (show all warnings)
+CPPFLAGS=-Wall
+#CPPFLAGS=-std=c++0x
+
+# Define linker flags
+LDFLAGS=
+
+# Define extra libraries to be dynamically linked
+#LDLIBS+=-larmadillo
+#LDLIBS+=-lstdc++
+
+# Compile optimized code
+#CPPFLAGS+=-O2
+
+# Compile debuggable code
+#CPPFLAGS+=-g
+
+# Compile profilable code
+#CPPFLAGS+=-pg
+#LDFLAGS+=-pg
+
+# Define linker
+LD=g++
+
+# Filenames of source code
+SRC=$(shell ls *.cpp)
+
+# Filenames of object files
+OBJ=$(SRC:.cpp=.o)
+#OBJ=downhill_simplex.o main.o
+#OBJB=downhill_simplex.o main.B.o
+
+# Remove file type extension for binary filename
+BIN=integ
+#BINB=optimB
+
+# The default "all" depends on A and B
+
+#all: A B
+
+
+A: $(BIN)
+ @# Run program and write amoeba positions to file
+ ./$(BIN)
+
+#B: $(BINB)
+# ./$(BINB) 2> amoebaB.dat
+
+$(BIN): $(OBJ)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ) -o $(BIN) $(LDLIBS)
+
+$(BINB): $(OBJB)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJB) -o $(BINB) $(LDLIBS)
+
+clean:
+ @# Remove object files
+ rm -f $(OBJ) $(OBJB)
+ @# Remove binaries
+ rm -f $(BIN) $(BINB)
+ @# Remove datafiles and plot
+ #rm -f *.dat *.png
+ @# Remove error logs
+ @#rm -f amoeba.dat amoebaB.dat
+edit:
+ vim -p Makefile *.cpp *.h
+
diff --git a/integration/functions.h b/integration/functions.h
t@@ -0,0 +1,27 @@
+#ifndef FUNCTIONS_H_
+#define FUNCTIONS_H_
+
+#include <cmath>
+#include "header.h"
+
+int ncalls = 0;
+
+Floattype func1(const Floattype x)
+{
+ ++ncalls;
+ return x*x;
+}
+
+Floattype func2(const Floattype x)
+{
+ ++ncalls;
+ return log(x)/sqrt(x);
+}
+
+Floattype func3(const Floattype x)
+{
+ ++ncalls;
+ return 4.0f*sqrt(1.0f-(1.0f-x)*(1.0f-x));
+}
+
+#endif
diff --git a/integration/header.h b/integration/header.h
t@@ -0,0 +1,18 @@
+// Make sure header is only included once
+#ifndef HEADER_H_
+#define HEADER_H_
+
+// Define whether the program should output values of matrices
+const bool verbose = false;
+//const bool verbose = true;
+
+// Prototype for checking function
+void check(const bool statement);
+
+// Choose length variable type
+typedef long int Lengthtype;
+
+// Choose floating-point precision
+typedef double Floattype;
+
+#endif
diff --git a/integration/integrator.cpp b/integration/integrator.cpp
t@@ -0,0 +1,120 @@
+#include <iostream>
+#include <cmath>
+#include <vector>
+#include <string>
+#include <typeinfo>
+#include "integrator.h"
+#include "header.h"
+
+// Constructor
+Integral::Integral(Floattype (*function)(const Floattype),
+ const Floattype lower_limit,
+ const Floattype upper_limit,
+ const Floattype absolute_accuracy,
+ const Floattype relative_accuracy)
+ : f_in(function), acc_pres(absolute_accuracy), eps(relative_accuracy)
+{
+ // Initialize number of recursions to 0
+ nrec = 0;
+
+ // Test whether input interval has infinite limits
+ if (std::isinf(lower_limit) == 1 && std::isinf(upper_limit) == 1) {
+ f = Integral::infinf;
+ low = 0.0f; high = 1.0f;
+ } else if (std::isinf(lower_limit) == 0 && std::isinf(upper_limit == 1)) {
+ f = Integral::fininf;
+ low = 0.0f; high = 1.0f;
+ } else if (std::isinf(lower_limit) == 1 && std::isinf(upper_limit == 0)) {
+ f = &Integral::inffin;
+ low = 0.0f; high = 1.0f;
+ } else {
+ f = Integral::f_in;
+ low = lower_limit;
+ high = upper_limit;
+ }
+
+ Floattype f2 = f(low + 2.0f * (high-low)/6.0f);
+ Floattype f3 = f(low + 4.0f * (high-low)/6.0f);
+
+ res = adapt(low, high, acc_pres, f2, f3);
+}
+
+// Adaptive integrator, to be called recursively
+Floattype Integral::adapt(const Floattype a,
+ const Floattype b,
+ const Floattype acc,
+ const Floattype f2,
+ const Floattype f3)
+{
+ if (nrec > 2147483647)
+ return NAN; // Return NaN if recursions seem infinite
+
+ // Function value at end points
+ Floattype f1 = f(a + 1.0f * (b-a)/6.0f);
+ Floattype f4 = f(b + 5.0f * (b-a)/6.0f);
+
+ // Quadrature rules
+ Floattype Q = (2.0f*f1 + f2 + f3 + 2.0f*f4) / 6.0f * (b-a);
+ Floattype q = (f1 + f2 + f3 + f4) / 4.0f * (b-a);
+
+ Floattype tolerance = acc + eps*fabs(Q);
+ err = fabs(Q-q);
+
+ // Evaluate whether result is precise
+ // enough to fulfill criteria
+ if (err < tolerance)
+ return Q;
+ else { // Perform recursions in lower and upper interval
+ ++nrec;
+ Floattype q1 = adapt(a, a+(b-a)/2.0f, acc/sqrt(2), f1, f2);
+ ++nrec;
+ Floattype q2 = adapt(a+(b-a)/2.0f, b, acc/sqrt(2), f3, f4);
+ return q1+q2;
+ }
+}
+
+// Return result
+Floattype Integral::result()
+{
+ return res;
+}
+
+// Return the number of recursions taken
+Lengthtype Integral::recursions()
+{
+ return nrec;
+}
+
+// Print results of function integration
+void Integral::show(const std::string function_description)
+{
+ std::cout << "Integral of function '"
+ << function_description
+ << "' in interval ["
+ << low << ";" << high << "] is "
+ << res << ",\n"
+ << "with an absolute accuracy of "
+ << acc_pres
+ << " and a relative accuracy of "
+ << eps << ".\n"
+ << "Integral calculated in "
+ << nrec << " recursions, error is "
+ << err << ".\n";
+}
+
+// Functions for variable transformations when limits are infinite
+Floattype Integral::infinf(const Floattype t)
+{
+ return (f_in((1.0f - t) / t) + f_in(-(1.0f - t) / t)) / (t*t);
+}
+
+Floattype Integral::fininf(const Floattype t)
+{
+ return f_in(low + (1.0f - t) / t) / (t*t);
+}
+
+Floattype Integral::inffin(const Floattype t)
+{
+ return f_in(high - (1.0f - t) / t) / (t*t);
+}
+
diff --git a/integration/integrator.h b/integration/integrator.h
t@@ -0,0 +1,68 @@
+#ifndef INTEGRATOR_H_
+#define INTEGRATOR_H_
+
+#include <string>
+#include "header.h"
+
+class Integral {
+
+ private:
+
+ // Input function (maybe to be transformed)
+ Floattype (*f_in)(const Floattype);
+
+ // Function to be evaluated (pointer to function)
+ Floattype (*f)(const Floattype);
+
+ // Integral limits
+ Floattype low; // Lower
+ Floattype high; // Upper
+
+ // Accuracy requirement values
+ const Floattype acc_pres; // Absolute
+ const Floattype eps; // Relative
+
+ // Number of recursions
+ Lengthtype nrec;
+
+ // Adaptive integrator function to be
+ // called recursively
+ Floattype adapt(const Floattype a,
+ const Floattype b,
+ const Floattype acc,
+ const Floattype f2,
+ const Floattype f3);
+
+ // Result of integral
+ Floattype res;
+
+ // Size of error
+ Floattype err;
+
+ // Functions for variable transformations
+ // when one or both limits are infinite
+ Floattype infinf(const Floattype t); // a=inf
+ Floattype fininf(const Floattype t); // b=inf
+ Floattype inffin(const Floattype t); // a=inf,b=inf
+
+
+ public:
+
+ // Constructor
+ Integral(Floattype (*function)(const Floattype),
+ const Floattype lower_limit,
+ const Floattype upper_limit,
+ const Floattype absolute_accuracy,
+ const Floattype relative_accuracy);
+
+ // Return value of result
+ Floattype result();
+
+ // Return number of recursions taken
+ Lengthtype recursions();
+
+ // Print results and statistics
+ void show(const std::string function_description);
+};
+
+#endif
diff --git a/integration/main.cpp b/integration/main.cpp
t@@ -0,0 +1,57 @@
+#include <iostream>
+#include "header.h"
+#include "functions.h"
+#include "integrator.h"
+
+int main(int argc, char* argv[])
+{
+ // Namespace declarations
+ using std::cout;
+
+ // Calculate machine precision
+ Floattype eps_machine = 1.0f;
+ while (1.0f + eps_machine != 1.0f)
+ eps_machine /= 2.0f;
+
+ Floattype a, b, acc, eps;
+
+ // Find the integral of function 1
+ a = 0.0f, b = 1.0f;
+ acc = 0.001f; eps = acc;
+ ncalls = 0;
+ Integral F1(func1, a, b, acc, eps);
+ F1.show("f(x) = x*x");
+ cout << '\n';
+
+ // Find the integral of function 2
+ a = 1e-8f, b = 1.0f;
+ acc = 0.001f; eps = acc;
+ ncalls = 0;
+ Integral F2(func2, a, b, acc, eps);
+ F2.show("f(x) = log(x)/sqrt(x)");
+ cout << "Check: Integral equal to -4:\t";
+ check(fabs(F2.result() + 4.0f) < 0.1f);
+ cout << '\n';
+
+ // Find the integral of function 3
+ a = 0.0f, b = 1.0f;
+ acc = 1e-8f; eps = acc;
+ ncalls = 0;
+ Integral F3(func3, a, b, acc, eps);
+ F3.show("f(x) = 4*sqrt(1-(1-x)^2)");
+ cout << "Check: Integral equal to pi:\t";
+ check(fabs(F3.result() - M_PI) < 0.01f);
+ cout << '\n';
+
+ // Return successfully
+ return 0;
+}
+
+void check(const bool statement)
+{
+ using std::cout;
+ if (statement == true)
+ cout << "\t\033[0;32mPassed\033[0m\n";
+ else
+ cout << "\t\033[1;31mFail!!\033[0m\n";
+}
diff --git a/leastsq/Makefile b/leastsq/Makefile
t@@ -0,0 +1,67 @@
+# Define compiler
+CC=g++
+
+# Define compiler flags (show all warnings)
+CPPFLAGS=-Wall
+
+# Define linker flags
+LDFLAGS=
+
+# Define extra libraries to be dynamically linked
+LDLIBS+=-larmadillo
+
+# Compile optimized code
+#CPPFLAGS+=-O2
+
+# Compile debuggable code
+#CPPFLAGS+=-g
+
+# Compile profilable code
+#CPPFLAGS+=-pg
+#LDFLAGS+=-pg
+
+# Define linker
+LD=g++
+
+# Filenames of source code
+SRC=$(shell ls *.cpp)
+
+# Filenames of object files
+OBJ=$(SRC:.cpp=.o)
+
+# Remove file type extension for binary filename
+BIN=leastsq
+
+# The default "all" depends on A and B
+
+all: A B
+
+A: plot.A.png
+
+B: plot.B.png
+
+plot.%.png: fit.A.dat fit.B.dat data.A.txt data.B.txt
+ gnuplot plotall.gp
+
+fit.A.dat: $(BIN)
+ ./$(BIN) data.A.txt fit.A.dat
+
+fit.B.dat: $(BIN)
+ ./$(BIN) data.B.txt fit.B.dat
+
+$(BIN): $(OBJ)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ) -o $(BIN) $(LDLIBS)
+ @# Execute program and redirect stdout to file
+ @#./$(BIN) > out.txt
+
+clean:
+ @# Remove object files
+ rm -f $(OBJ)
+ @# Remove binary
+ rm -f $(BIN)
+ @# Remove datafiles and plot
+ rm -f *.dat *.png
+edit:
+ vim -p Makefile *.cpp *.h *.gp
+
diff --git a/leastsq/data.A.txt b/leastsq/data.A.txt
t@@ -0,0 +1,7 @@
+20.0 10.26 2.2
+40.0 10.52 4.12
+60.0 9.22 5.2
+80.0 17.77 3.5
+100.0 38.14 5.21
+120.0 45.56 1.2
+140.0 54.29 6.2
diff --git a/leastsq/data.B.txt b/leastsq/data.B.txt
t@@ -0,0 +1,10 @@
+0 1 0.2
+1 2 0.2
+2 3 0.2
+3 2 0.2
+4 4 0.2
+5 3 0.2
+6 2.5 0.2
+7 3.5 0.2
+8 4 0.2
+9 5 0.2
diff --git a/leastsq/file_o.cpp b/leastsq/file_o.cpp
t@@ -0,0 +1,25 @@
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include "header.h"
+
+// Write arrays to text file, readable by plotting tools
+int write_output(const std::vector<Floattype> &a,
+ const std::vector<Floattype> &b,
+ const char *outfile)
+{
+ std::ofstream outstream;
+
+ // Open outfile for write
+ outstream.open(outfile);
+
+ // Write output arrays in two columns
+ for (Lengthtype i=0; i<(Lengthtype)a.size(); ++i)
+ outstream << a[i] << '\t' << b[i] << '\n';
+
+ // Close file
+ outstream.close();
+
+ // Return successfully
+ return 0;
+}
diff --git a/leastsq/header.h b/leastsq/header.h
t@@ -0,0 +1,21 @@
+// Make sure header is only included once
+#ifndef HEADER_H_
+#define HEADER_H_
+
+#include <vector>
+
+// Define whether the program should output values of matrices
+const bool verbose = false;
+
+// Choose vector length variable type
+typedef int Lengthtype;
+
+// Choose floating-point precision
+typedef double Floattype;
+
+// File output function prototype
+int write_output(const std::vector<Floattype> &a,
+ const std::vector<Floattype> &b,
+ const char *outfile);
+
+#endif
diff --git a/leastsq/lsfit.cpp b/leastsq/lsfit.cpp
t@@ -0,0 +1,61 @@
+#include <iostream>
+#include <cmath> // NaN is here
+#include <armadillo>
+#include "header.h"
+#include "lsfit.h"
+#include "qrfunc.h"
+
+// A number of i fitting functions, evaluated at x
+Floattype LSfit::fitfuncts(char i, Floattype x)
+{
+ // Choose function i
+ switch (i) {
+ case 0:
+ return 1.0f;
+ break;
+ case 1:
+ return x;
+ break;
+ case 2:
+ return x*x;
+ break;
+ default:
+ std::cout << "Wrong function (i = "
+ << i << ") specified in fitfuncts, x = "
+ << x << '\n';
+ return NAN;
+ }
+}
+
+// Constructor
+LSfit::LSfit(arma::Col<Floattype> &x,
+ arma::Col<Floattype> &y,
+ arma::Col<Floattype> &delta_y) : n(x.n_rows), m(3), A(n,m), b(n),…
+{
+
+ // Initialize b values
+ b = y/delta_y;
+
+ // Initialize A values
+ for (Lengthtype i=0; i<n; ++i) {
+ for (Lengthtype k=0; k<m; ++k) {
+ A(i,k) = fitfuncts(k,x(i)) / delta_y(i);
+ }
+ }
+
+ // Perform QR decomposition
+ QR qr(A);
+
+ // Calculate the least-squares solution
+ c = qr.backsub(b);
+}
+
+// Evaluate function at x
+Floattype LSfit::eval(Floattype x)
+{
+ // Find the linear combination of m functions to calculate F(x)
+ Floattype sum = 0.0f;
+ for (char k=0; k<m; ++k)
+ sum += c(k) * fitfuncts(k, x);
+ return sum;
+}
diff --git a/leastsq/lsfit.h b/leastsq/lsfit.h
t@@ -0,0 +1,41 @@
+// Make sure header is only included once per object
+#ifndef LSFIT_H_
+#define LSFIT_H_
+
+#include <armadillo>
+#include "header.h"
+
+// lsfit structure
+class LSfit {
+ private:
+ const Lengthtype n; // Input data count
+ const Lengthtype m; // Fitting function count
+
+ // Covariance matrix
+ arma::Mat<Floattype> A;
+
+ // Data points
+ arma::Col<Floattype> b;
+
+ // Fitting coefficients
+ arma::Col<Floattype> c;
+
+ // Evaluate fitting function i at x
+ Floattype fitfuncts(char i, Floattype x);
+
+ public:
+
+ // Constructor. Arguments: input data points
+ LSfit(arma::Col<Floattype> &x,
+ arma::Col<Floattype> &y,
+ arma::Col<Floattype> &delta_y);
+
+ // Destructor
+ //~LSfit();
+
+ // Return value fitted at x
+ Floattype eval(Floattype x);
+
+};
+
+#endif
diff --git a/leastsq/main.cpp b/leastsq/main.cpp
t@@ -0,0 +1,89 @@
+#include <iostream>
+#include <cstdio> // For fscanf
+#include <armadillo>
+#include <vector>
+#include "header.h"
+#include "lsfit.h"
+
+int main(int argc, char* argv[])
+{
+ // Namespace declarations
+ using std::cout;
+
+ // Check that a data file is given as an input argument
+ if (argc < 2 || argc > 3) {
+ cout << "Usage: " << argv[0] << " <input file> [output file]\n"
+ << "If 'output file' is not specified, output data "
+ << "will be written to stdout.\n"
+ << "Example: " << argv[0] << " data.A.txt\n";
+ return 1;
+ }
+
+ FILE *fin; // File pointer
+
+ // Check that the input file exists and can be read
+ if ((fin = fopen(argv[1], "r")) == NULL) {
+ cout << "Error while reading " << argv[1] << '\n';
+ return 1;
+ }
+
+ // First, count the number of newline characters
+ // for preallocation purposes
+ Lengthtype n = 0;
+ int c;
+ while ((c = getc(fin)) != EOF) {
+ if (c == '\n')
+ ++n;
+ }
+ fclose(fin);
+ cout << "Input file \"" << argv[1] << "\" consists of n="
+ << n << " data points.\n";
+
+ // Allocate input data structures
+ arma::Col<Floattype> x = arma::Col<Floattype> (n);
+ arma::Col<Floattype> y = arma::Col<Floattype> (n);
+ arma::Col<Floattype> delta_y = arma::Col<Floattype> (n);
+
+ // Read data into memory
+ if ((fin = fopen(argv[1], "r")) == NULL) {
+ cout << "Error while reading " << argv[1] << '\n';
+ return 1;
+ }
+ float x_tmp, y_tmp, delta_y_tmp;
+ for (Lengthtype i=0; i<n; ++i) {
+ fscanf(fin, "%f %f %f", &x_tmp, &y_tmp, &delta_y_tmp);
+ x(i) = x_tmp;
+ y(i) = y_tmp;
+ delta_y(i) = delta_y_tmp;
+ }
+ fclose(fin);
+
+ // Perform least-squares fit with LSfit class
+ LSfit lsfit(x, y, delta_y);
+
+ // Evaluate fit at a fine resolution
+ const unsigned int res = 100;
+ Floattype x_min = x.min();
+ cout << "x_min = " << x_min;
+ Floattype x_max = x.max();
+ cout << ", x_max = " << x_max << '\n';
+ std::vector<Floattype> xo (res);
+ std::vector<Floattype> yo (res);
+ for (unsigned int i=0; i<res; ++i) {
+ xo[i] = x_min + (x_max - x_min) * ((Floattype)i/res);
+ yo[i] = lsfit.eval(xo[i]);
+ }
+
+ // Write to file if specified in as command line arguments
+ if (argc == 3) {
+ write_output(xo, yo, argv[2]);
+ } else {
+ for (unsigned int i=0; i<res; ++i) {
+ cout << xo[i] << '\t' << yo[i] << '\n';
+ }
+ }
+
+
+ // Return successfully
+ return 0;
+}
diff --git a/leastsq/plotall.gp b/leastsq/plotall.gp
t@@ -0,0 +1,17 @@
+set terminal png # Set output file format
+set output "plot.A.png" # Set output filename
+set key top left
+set xlabel "x"
+set ylabel "y"
+set title "Least-squares fit A"
+set grid
+plot "fit.A.dat" u 1:2 w lp title "LSfit", "data.A.txt" w errorbars title "Dat…
+
+set terminal png # Set output file format
+set output "plot.B.png" # Set output filename
+set key top left
+set xlabel "x"
+set ylabel "y"
+set title "Least-squares fit B"
+set grid
+plot "fit.B.dat" u 1:2 w lp title "LSfit", "data.B.txt" w errorbars title "Dat…
diff --git a/leastsq/qrfunc.cpp b/leastsq/qrfunc.cpp
t@@ -0,0 +1,90 @@
+#include <iostream>
+#include <armadillo>
+#include "header.h"
+#include "qrfunc.h"
+
+// QR decomposition constructor
+QR::QR(arma::mat &A)
+ : n(A.n_cols),
+ A(A),
+ Q(A)
+{
+ // Initialize output structures
+ R = arma::zeros<arma::mat> (n,n);
+
+ // Perform QR decomposition straight away
+ decomp();
+}
+
+// Class deconstructor (equivalent to compiler destructor)
+QR::~QR() { };
+
+// Return system size
+Lengthtype QR::size()
+{
+ return n;
+}
+
+// QR decomposition function of Armadillo matrix.
+// Returns right matrix R, and modifies A into Q.
+// Uses Gram-Schmidt orthogonalization
+void QR::decomp()
+{
+ Floattype r, s;
+ Lengthtype j;
+ for (Lengthtype i=0; i<n; ++i) {
+ r = dot(Q.col(i), Q.col(i));
+ R(i,i) = sqrt(r);
+ Q.col(i) /= sqrt(r); // Normalization
+ for (j=i+1; j<n; ++j) {
+ s = dot(Q.col(i), Q.col(j));
+ Q.col(j) -= s*Q.col(i); // Orthogonalization
+ R(i,j) = s;
+ }
+ }
+}
+
+// Solve the square system of linear equations with back
+// substitution. T is an upper triangular matrix.
+arma::vec QR::backsub(arma::vec &b)
+{
+ Floattype tmpsum;
+ arma::vec x = Q.t() * b;
+ for (Lengthtype i=n-1; i>=0; --i) {
+ tmpsum = 0.0f;
+ for (Lengthtype k=i+1; k<n; ++k)
+ tmpsum += R(i,k) * x(k);
+
+ x(i) = 1.0f/R(i,i) * (x(i) - tmpsum);
+ }
+ return x;
+}
+
+// Calculate the (absolute value of the) determinant of
+// matrix A given the Q and R components.
+// det(A) = det(Q) * det(R), |det(Q) = 1|
+// => |det(A)| = |det(R)|
+Floattype QR::det()
+{
+ Floattype determinant = 1.0f;
+ for (Lengthtype i=0; i<n; ++i)
+ determinant *= R(i,i);
+ return fabs(determinant);
+}
+
+// Calculate the inverse of matrix A given the Q and R
+// components.
+arma::mat QR::inverse()
+{
+ arma::mat inv = arma::zeros<arma::mat> (n, n);
+ // In vector z, all elements are equal to 0, except z(i) = 1
+ arma::vec z = arma::zeros<arma::mat> (n);
+
+ for (Lengthtype i=0; i<n; ++i) {
+ z(i) = 1.0f; // Element i changed to 1
+ inv.col(i) = backsub(z);
+ z(i) = 0.0f; // Element i changed back to 0
+ }
+
+ return inv;
+}
diff --git a/leastsq/qrfunc.h b/leastsq/qrfunc.h
t@@ -0,0 +1,49 @@
+// Make sure header is only included once
+#ifndef QRFUNC_H_
+#define QRFUNC_H_
+
+#include <armadillo>
+#include "header.h"
+
+// QR structure
+class QR {
+ private:
+ // System size
+ const Lengthtype n;
+
+ public:
+ //// Data
+
+ // Input data
+ arma::mat A;
+
+ // QR decomposition matrices
+ arma::mat Q;
+ arma::mat R;
+
+ //// Prototype functions
+
+ // Constructor prototype
+ QR(arma::mat &A);
+
+ // Destructor
+ ~QR();
+
+ // Return system size
+ Lengthtype size();
+
+ // QR decomposition of Armadillo matrix A, returning R
+ // and modified A (=Q)
+ void decomp();
+
+ // Backsubstitution of triangular system
+ arma::vec backsub(arma::vec &b);
+
+ // Absolute value of the determinant of matrix R
+ Floattype det();
+
+ // Inverse of matrix A
+ arma::mat inverse();
+};
+
+#endif
diff --git a/matrixmul/Makefile b/matrixmul/Makefile
t@@ -0,0 +1,150 @@
+# Compare speed of different programming languages
+# in a matrix multiplication algorithm: AB=C.
+# A is uniform with the cell values '2', B should contain
+# pseudorandom numbers.
+# Initialization of A, B and C in the same loop is allowed,
+# but the multiplication should be done in a separate loop.
+# Matrix dimensions are specified as a command line argument.
+
+MATRIXDIMS_SLOW = 100 200 400 800 1600
+MATRIXDIMS = $(MATRIXDIMS_SLOW) 3200
+PREFIXCMD = nice \gtime -ao
+
+CC=gcc
+CXX=g++
+CFLAGS=-Wall -O3
+CXXFLAGS=-Wall -O3
+
+performance.png: plot.gp lua-arrofarrs.dat lua-linarr.dat luajit-arrofarrs.dat…
+ gnuplot plot.gp
+
+# Lua: Matrices as arrays of arrays
+lua-arrofarrs.dat: lua-arrofarrs.lua
+ # lua-arrofars.lua
+ @rm -f $@
+ @for dims in $(MATRIXDIMS_SLOW); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" lua $< $$dims; \
+ echo $$dims; \
+ done
+
+# Lua: Matrices as linear arrays
+lua-linarr.dat: lua-linarr.lua
+ # lua-linarr.lua
+ @rm -f $@
+ @for dims in $(MATRIXDIMS_SLOW); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" lua $< $$dims; \
+ echo $$dims; \
+ done
+
+# LuaJIT: Matrices as arrays of arrays
+luajit-arrofarrs.dat: lua-arrofarrs.lua
+ # luajit-arrofars.lua
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" luajit $< $$dims; \
+ echo $$dims; \
+ done
+
+# LuaJIT: Matrices as linear arrays
+luajit-linarr.dat: lua-linarr.lua
+ # LuaJIT lua-linarr.lua
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" luajit $< $$dims; \
+ echo $$dims; \
+ done
+
+# C: Array of arrays
+c-arrofarrs.dat: c-arrofarrs
+ # c-arrofarrs
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" ./$< $$dims; \
+ echo $$dims; \
+ done
+
+# C: Matrices as linear arrays
+c-linarr.dat: c-linarr
+ # c-linarr
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" ./$< $$dims; \
+ echo $$dims; \
+ done
+
+# C: Array of arrays, OpenMP
+c-omp-arrofarrs.dat: c-omp-arrofarrs
+ # c-omp-arrofarrs
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" ./$< $$dims; \
+ echo $$dims; \
+ done
+
+# C: Matrices as linear arrays, OpenMP
+c-omp-linarr.dat: c-omp-linarr
+ # c-omp-linarr
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" ./$< $$dims; \
+ echo $$dims; \
+ done
+
+c-omp-arrofarrs: c-arrofarrs.c
+ $(CC) $(CFLAGS) -fopenmp $< -o $@
+
+c-omp-linarr: c-linarr.c
+ $(CC) $(CFLAGS) -fopenmp $< -o $@
+
+# Julia, native arrays
+julia.dat: julia.jl
+ # julia.jl
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" julia $< $$dims; \
+ echo $$dims; \
+ done
+
+# C++: Vector of vectors
+cpp-vectorofvectors.dat: cpp-vectorofvectors
+ # cpp-vectorofvectors
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" ./$< $$dims; \
+ echo $$dims; \
+ done
+
+# C++: Linear vectors
+cpp-linvectors.dat: cpp-linvectors
+ # cpp-linvectors
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" ./$< $$dims; \
+ echo $$dims; \
+ done
+
+# Python: Numpy module
+python-numpy.dat: python-numpy.py
+ # python-numpy.py
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" python $< $$dims; \
+ echo $$dims; \
+ done
+
+# Octave
+octave.dat: octave.m
+ # octave.m
+ @rm -f $@
+ @for dims in $(MATRIXDIMS); do \
+ $(PREFIXCMD) $@ -f "$$dims %e" octave -qf $< $$dims; \
+ echo $$dims; \
+ done
+
+clean:
+ rm -f *.o
+ rm -f *.dat
+ rm -f *.png
+
+edit:
+ vim -p Makefile plot.gp
diff --git a/matrixmul/c-arrofarrs.c b/matrixmul/c-arrofarrs.c
t@@ -0,0 +1,72 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+void matrixMult(double** A, double** B, double** C, int N)
+{
+ int i, j, k;
+ double sum;
+#pragma omp parallel for private (j,k,sum)
+ for (i = 0; i<N; i++) {
+ for (j = 0; j<N; j++) {
+ sum = 0.0f;
+ for (k = 0; k<N; k++) {
+ sum += A[i][k] * B[k][j];
+ }
+ C[i][j] = sum;
+ }
+ }
+}
+
+
+int main(int argc, char* argv[])
+{
+ int i, j, N;
+ double** A;
+ double** B;
+ double** C;
+
+ /* Read input argument as matrix height */
+ if (argc == 2) {
+ N = atoi(argv[1]);
+ } else {
+ printf("Sorry, I need matrix width as command line argument\n");
+ return 1;
+ }
+
+ /* Allocate arrays */
+ A = (double**) malloc(N * sizeof(double*));
+ B = (double**) malloc(N * sizeof(double*));
+ C = (double**) malloc(N * sizeof(double*));
+
+ /* Allocate row arrays inside arrays */
+ for (i = 0; i < N; i++) {
+ A[i] = (double*) malloc(N * sizeof(double));
+ B[i] = (double*) malloc(N * sizeof(double));
+ C[i] = (double*) malloc(N * sizeof(double));
+ }
+
+ /* Fill matrices A and B with values */
+ for (i = 0; i < N; i++) {
+ for (j = 0; j < N; j++) {
+ A[i][j] = 2.0;
+ /* We want a random value between 0 and 1 */
+ B[i][j] = rand()/RAND_MAX;
+ }
+ }
+
+ /* Perform matrix multiplication */
+ matrixMult(A, B, C, N);
+
+ /* Free memory */
+ for (i = 0; i < N; i++) {
+ free(A[i]);
+ free(B[i]);
+ free(C[i]);
+ }
+ free(A);
+ free(B);
+ free(C);
+
+ /* Exit with success */
+ return 0;
+}
diff --git a/matrixmul/c-linarr.c b/matrixmul/c-linarr.c
t@@ -0,0 +1,58 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+void matrixMult(double* A, double* B, double* C, int N)
+{
+ int i, j, k;
+ double sum;
+#pragma omp parallel for private (j,k,sum)
+ for (i = 0; i<N; i++) {
+ for (j = 0; j<N; j++) {
+ sum = 0.0f;
+ for (k = 0; k<N; k++) {
+ sum += A[k*N+i] * B[j*N+k];
+ }
+ C[j*N+i] = sum;
+ }
+ }
+}
+
+
+int main(int argc, char* argv[])
+{
+ int i, N;
+ double* A;
+ double* B;
+ double* C;
+
+ /* Read input argument as matrix height */
+ if (argc == 2) {
+ N = atoi(argv[1]);
+ } else {
+ printf("Sorry, I need matrix width as command line argument\n");
+ return 1;
+ }
+
+ /* Allocate arrays */
+ A = (double*) malloc(N * N * sizeof(double*));
+ B = (double*) malloc(N * N * sizeof(double*));
+ C = (double*) malloc(N * N * sizeof(double*));
+
+ /* Fill matrices A and B with values */
+ for (i = 0; i < N*N; i++) {
+ A[i] = 2.0;
+ /* We want a random value between 0 and 1 */
+ B[i] = rand()/RAND_MAX;
+ }
+
+ /* Perform matrix multiplication */
+ matrixMult(A, B, C, N);
+
+ /* Free memory */
+ free(A);
+ free(B);
+ free(C);
+
+ /* Exit with success */
+ return 0;
+}
diff --git a/matrixmul/cpp-linvectors.cpp b/matrixmul/cpp-linvectors.cpp
t@@ -0,0 +1,49 @@
+#include <iostream>
+#include <vector>
+#include <cstdlib> // rand is here
+
+int main(int argc, char* argv[])
+{
+ using std::cout;
+ using std::vector;
+
+ int M, N, i, j, k;
+
+ // Read input argument as matrix height
+ if (argc == 2) {
+ N = atoi(argv[1]);
+ } else {
+ cout << "Sorry, I need matrix width as command line argument\n";
+ return 1;
+ }
+
+ // Width equal to height
+ M = N;
+
+ vector<double> A(M*N);
+ vector<double> B(M*N);
+ vector<double> C(M*N);
+
+ // Fill matrices A and B with values
+ for (i = 0; i<N; ++i) {
+ for (j = 0; j<M; ++j) {
+ A[j*M+i] = 2.0;
+ // We want a random value between 0 and 1
+ B[j*M+i] = rand()/RAND_MAX;
+ }
+ }
+
+ double sum;
+ // Perform matrix multiplication
+ for (i = 0; i < N; ++i) {
+ for (j = 0; j < M; ++j) {
+ sum = 0.0f;
+ for (k = 0; k < M; ++k)
+ sum += A[k*M+i] * B[j*M+k];
+ C[j*M+i] = sum;
+ }
+ }
+
+ // Exit with success
+ return 0;
+}
diff --git a/matrixmul/cpp-vectorofvectors.cpp b/matrixmul/cpp-vectorofvectors.…
t@@ -0,0 +1,49 @@
+#include <iostream>
+#include <vector>
+#include <cstdlib> // rand is here
+
+int main(int argc, char* argv[])
+{
+ using std::cout;
+ using std::vector;
+
+ int M, N, i, j, k;
+
+ // Read input argument as matrix height
+ if (argc == 2) {
+ N = atoi(argv[1]);
+ } else {
+ cout << "Sorry, I need matrix width as command line argument\n";
+ return 1;
+ }
+
+ // Width equal to height
+ M = N;
+
+ vector< vector<double> > A(M,vector<double>(M));
+ vector< vector<double> > B(M,vector<double>(M));
+ vector< vector<double> > C(M,vector<double>(M));
+
+ // Fill matrices A and B with values
+ for (i = 0; i<N; ++i) {
+ for (j = 0; j<M; ++j) {
+ A[i][j] = 2.0;
+ // We want a random value between 0 and 1
+ B[i][j] = rand()/RAND_MAX;
+ }
+ }
+
+ double sum;
+ // Perform matrix multiplication
+ for (i = 0; i < N; ++i) {
+ for (j = 0; j < M; ++j) {
+ sum = 0.0;
+ for (k = 0; k < M; ++k)
+ sum = A[k][j] * B[i][k];
+ C[i][j] = sum;
+ }
+ }
+
+ // Exit with success
+ return 0;
+}
diff --git a/matrixmul/julia.jl b/matrixmul/julia.jl
t@@ -0,0 +1,13 @@
+#!/usr/bin/julia
+
+if (length(ARGS) == 1)
+ N = int(ARGS[1])
+else
+ println("Sorry, I need the matrix width as a command line argument\n")
+end
+
+M = N
+
+A = ones(M,N)*2.0
+B = rand(M,N)
+C = A*B
diff --git a/matrixmul/lua-arrofarrs.lua b/matrixmul/lua-arrofarrs.lua
t@@ -0,0 +1,30 @@
+#!/usr/bin/lua
+
+N = arg[1]
+
+-- Initialize the matrix A with two's,
+-- matrix B with random numbers
+A = {}
+B = {}
+C = {}
+for i=1,N do
+ A[i] = {}
+ B[i] = {}
+ C[i] = {}
+ for j=1,N do
+ A[i][j] = 2
+ B[i][j] = math.random()
+ end
+end
+
+-- Multiply matrix A with matrix B,
+-- store result in matrix C
+for i=1,N do
+ for j=1,N do
+ sum = 0.0
+ for k=1,N do
+ sum = sum + A[i][k] * B[k][j]
+ end
+ C[i][j] = sum
+ end
+end
diff --git a/matrixmul/lua-linarr.lua b/matrixmul/lua-linarr.lua
t@@ -0,0 +1,25 @@
+#!/usr/bin/lua
+
+N = arg[1]
+
+-- Initialize the matrix A with two's,
+-- matrix B with random numbers
+A = {}
+B = {}
+for i=1,(N*N) do
+ A[i] = 2.0
+ B[i] = math.random()
+end
+
+-- Multiply matrix A with matrix B,
+-- store result in matrix C
+C = {}
+for i=1,N do
+ for j=1,N do
+ sum = 0.0
+ for k=1,N do
+ sum = sum + A[(k-1)*N+i] * B[(j-1)*N+k]
+ end
+ C[(i-1)*N + j] = sum
+ end
+end
diff --git a/matrixmul/octave.m b/matrixmul/octave.m
t@@ -0,0 +1,14 @@
+#/usr/bin/octave -q -f
+
+if (nargin == 1)
+ M = str2num(argv(){1});
+else
+ disp("Sorry, I need the matrix size as a command line argument");
+ exit(1);
+end
+
+N = M;
+
+A = ones(M,N) * 2.0;
+B = rand(M,N);
+C = A*B;
diff --git a/matrixmul/plot.gp b/matrixmul/plot.gp
t@@ -0,0 +1,9 @@
+set terminal png size 1200,600
+set output "performance.png"
+set xlabel "Matrix side length"
+set ylabel "Execution time [s]"
+set title "Random number generation and matrix multiplication"
+set log xy
+set grid
+set key outside
+plot "lua-arrofarrs.dat" title "Lua: Arrays of arrays" w lp, "lua-linarr.dat" …
diff --git a/matrixmul/python-numpy.py b/matrixmul/python-numpy.py
t@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+
+import sys
+import numpy
+
+if (len(sys.argv) == 2):
+ M = int(sys.argv[1])
+else:
+ print("Sorry, I need a matrix width as input argument!")
+ sys.exit(1)
+
+N = M
+
+A = numpy.ones((M,N))*2.0
+B = numpy.random.random_sample((M,N))
+C = numpy.dot(A,B) # A*B is element wise on numpy arrays
diff --git a/montecarlo/Makefile b/montecarlo/Makefile
t@@ -0,0 +1,89 @@
+# Define compiler
+CC=g++
+
+# Define compiler flags (show all warnings)
+CPPFLAGS=-Wall
+#CPPFLAGS=-std=c++0x
+
+# Define linker flags
+LDFLAGS=
+
+# Define extra libraries to be dynamically linked
+#LDLIBS+=-larmadillo
+#LDLIBS+=-lstdc++
+
+# Compile optimized code
+#CPPFLAGS+=-O2
+
+# Compile debuggable code
+#CPPFLAGS+=-g
+
+# Compile profilable code
+#CPPFLAGS+=-pg
+#LDFLAGS+=-pg
+
+# Define linker
+LD=g++
+
+# Filenames of source code
+SRC=$(shell ls *.cpp)
+
+# Filenames of object files
+OBJ=$(SRC:.cpp=.o)
+#OBJ=downhill_simplex.o main.o
+#OBJB=downhill_simplex.o main.B.o
+
+# Remove file type extension for binary filename
+BIN=mc
+#BINB=optimB
+
+# The default "all" depends on A and B
+
+#all: A B
+
+A: performance.png error.png
+
+%.png: performance.dat
+ gnuplot plot.gp
+
+
+
+performance.dat: $(BIN)
+ # Removing old performance data
+ rm -f performance.dat
+ # Running program and profiling runtime and error
+ nice ./$(BIN) 10000 > /dev/null
+ nice ./$(BIN) 20000 > /dev/null
+ nice ./$(BIN) 50000 > /dev/null
+ nice ./$(BIN) 100000 > /dev/null
+ nice ./$(BIN) 200000 > /dev/null
+ nice ./$(BIN) 500000 > /dev/null
+ nice ./$(BIN) 1000000 > /dev/null
+ nice ./$(BIN) 2000000 > /dev/null
+ nice ./$(BIN) 5000000 > /dev/null
+
+
+#B: $(BINB)
+# ./$(BINB) 2> amoebaB.dat
+
+test: $(BIN)
+ ./$(BIN)
+
+$(BIN): $(OBJ)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ) -o $(BIN) $(LDLIBS)
+
+$(BINB): $(OBJB)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJB) -o $(BINB) $(LDLIBS)
+
+clean:
+ @# Remove object files
+ rm -f $(OBJ)
+ @# Remove binaries
+ rm -f $(BIN)
+ @# Remove datafiles and plot
+ rm -f *.dat *.png
+edit:
+ vim -p Makefile *.cpp *.h *.gp
+
diff --git a/montecarlo/functions.h b/montecarlo/functions.h
t@@ -0,0 +1,20 @@
+#ifndef FUNCTIONS_H_
+#define FUNCTIONS_H_
+
+#include <iostream>
+#include <vector>
+#include <cmath>
+#include "header.h"
+
+int ncalls = 0;
+
+Floattype functionA(const std::vector<Floattype> x) {
+ if (x.size() != 3) {
+ std::cout << "Error! FunctionA must be given a 3D input point!\n";
+ return NAN;
+ }
+
+ return 1.0f / (1.0f-cos(x[0]) * cos(x[1]) * cos(x[2])) / M_PI / M_PI / M_PI;
+}
+
+#endif
diff --git a/montecarlo/header.h b/montecarlo/header.h
t@@ -0,0 +1,18 @@
+// Make sure header is only included once
+#ifndef HEADER_H_
+#define HEADER_H_
+
+// Define whether the program should output values of matrices
+const bool verbose = false;
+//const bool verbose = true;
+
+// Prototype for checking function
+void check(const bool statement);
+
+// Choose length variable type
+typedef long int Lengthtype;
+
+// Choose floating-point precision
+typedef double Floattype;
+
+#endif
diff --git a/montecarlo/main.cpp b/montecarlo/main.cpp
t@@ -0,0 +1,62 @@
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <cmath>
+#include <cstdlib>
+#include <ctime>
+#include "header.h"
+#include "functions.h"
+#include "montecarlo.h"
+
+int main(int argc, char* argv[])
+{
+ // Namespace declarations
+ using std::cout;
+
+ // Number of sample points as input argument
+ Lengthtype N;
+ if (argc == 1) // If no args are given..
+ N = 100; // 100 points are sampled
+ else
+ N = atol(argv[1]); // Else the specified number
+
+ cout << "Sampling function at " << N << " points.\n";
+
+ // Calculate machine precision
+ Floattype eps_machine = 1.0f;
+ while (1.0f + eps_machine != 1.0f)
+ eps_machine /= 2.0f;
+
+ // Evaluate 3D function A at 10 points in interval [a;b]
+ Lengthtype d = 3; // No of dimensions
+ std::vector<Floattype> a(d); // Lower limits
+ std::vector<Floattype> b(d); // Upper limits
+ for (Lengthtype i=0; i<d; ++i) { // Assign equidimensional limits
+ a[i] = 0.0f;
+ b[i] = M_PI;
+ }
+ Floattype tic = clock();
+ MC mc(functionA, a, b, N);
+ mc.plain(); // Plain Monte-Carlo integration
+ mc.show(); // Display results
+ Floattype t_elapsed = (clock() - tic)/(CLOCKS_PER_SEC);
+ cout << "Elapsed time: " << t_elapsed << " s.\n";
+
+ // Append results to performance.dat
+ std::ofstream file;
+ file.open("performance.dat", std::fstream::app); // Append to file
+ file << N << '\t' << t_elapsed << '\t' << mc.error() << '\n';
+ file.close();
+
+ // Return successfully
+ return 0;
+}
+
+void check(const bool statement)
+{
+ using std::cout;
+ if (statement == true)
+ cout << "\t\033[0;32mPassed\033[0m\n";
+ else
+ cout << "\t\033[1;31mFail!!\033[0m\n";
+}
diff --git a/montecarlo/montecarlo.cpp b/montecarlo/montecarlo.cpp
t@@ -0,0 +1,88 @@
+#include <iostream>
+#include <vector>
+#include <cstdlib> // for random functionality
+#include <cmath> // NaN
+#include "header.h"
+#include "montecarlo.h"
+
+// Constructor
+MC::MC(Floattype (*function)(const std::vector<Floattype>),
+ const std::vector<Floattype> a_in,
+ const std::vector<Floattype> b_in,
+ const Lengthtype N_in)
+ : d(a_in.size()), f(function), a(a_in), b(b_in), x(d), N(N_in)
+{
+ // Check that problem is at least 1D
+ if (d < 1)
+ std::cerr << "Error! Problem must be at least 1D\n";
+
+ // Check that the user has specified at least 1 random sample
+ if (N < 1)
+ std::cerr << "Error! The algorithm should evaluate at least 1 point!\n";
+
+ // Check input data
+ for (Lengthtype i=0; i<d; ++i)
+ if (a[i] >= b[i])
+ std::cerr << "Error! a >= b in dimension " << i << '\n';
+
+ // Initialize result and error to NaN
+ Q = NAN;
+ err = NAN;
+}
+
+// Plain Monte Carlo integrator
+void MC::plain()
+{
+
+ // Set volume of sample space
+ set_volume();
+
+ Floattype sum = 0.0f, sumsum = 0.0f, fx;
+
+ for (Lengthtype i=0; i<N; ++i) {
+ x = random_x(); // Random sample point inside intervals
+ fx = f(x);
+ sum += fx;
+ sumsum += fx*fx;
+ }
+
+ Floattype average = sum/N;
+ Floattype variance = sumsum/N - average*average;
+
+ // Write results
+ Q = average * V;
+ err = sqrt(variance/N)*V;
+}
+
+
+// Calculate volume by multiplying interval in each dimension
+void MC::set_volume()
+{
+ V = 1.0f;
+ for (Lengthtype i=0; i<d; ++i)
+ V *= b[i] - a[i];
+}
+
+// Draw pseudo-random position in sample space
+std::vector<Floattype> MC::random_x()
+{
+ std::vector<Floattype> pos(d);
+ for (Lengthtype i=0; i<d; ++i) {
+ // Random number in [a;b] interval in dimension
+ pos[i] = (b[i] - a[i]) * ((Floattype)rand()/RAND_MAX) + a[i];
+ }
+ return pos;
+}
+
+
+// Print results
+void MC::show()
+{
+ std::cout << "Integral Q = " << Q << ", error = " << err << '\n';
+}
+
+// Return the error
+Floattype MC::error()
+{
+ return err;
+}
diff --git a/montecarlo/montecarlo.h b/montecarlo/montecarlo.h
t@@ -0,0 +1,58 @@
+#ifndef MONTECARLO_H_
+#define MONTECARLO_H_
+
+#include <vector>
+#include "header.h"
+
+class MC {
+
+ private:
+
+ // Length of vectors
+ const Lengthtype d;
+
+ // Function to be evaluated (pointer to function)
+ Floattype (*f)(const std::vector<Floattype>);
+
+ // Integral limits in dimension d
+ const std::vector<Floattype> a;
+ const std::vector<Floattype> b;
+
+ // n-dimensional point
+ std::vector<Floattype> x;
+
+ // Number of samples
+ const Lengthtype N;
+
+ // Integration result
+ Floattype Q;
+
+ // Error
+ Floattype err;
+
+ // Volume
+ Floattype V;
+ void set_volume();
+
+ // Draw random position in sample space
+ std::vector<Floattype> random_x();
+
+ public:
+
+ // Constructor
+ MC(Floattype (*function)(const std::vector<Floattype>),
+ const std::vector<Floattype> a_in,
+ const std::vector<Floattype> b_in,
+ const Lengthtype N_in);
+
+ // Plain Monte Carlo integrator
+ void plain();
+
+ // Print result and error
+ void show();
+
+ // Return the error
+ Floattype error();
+};
+
+#endif
diff --git a/montecarlo/plot.gp b/montecarlo/plot.gp
t@@ -0,0 +1,17 @@
+set terminal png
+set output "performance.png"
+set xlabel "Sample points N"
+set ylabel "Execution time [s]"
+set title "Performane analysis"
+set log xy
+set grid
+plot "performance.dat" u 1:2 title "Plain Monte-Carlo" w lp
+
+set terminal png
+set output "error.png"
+set xlabel "Sample points N"
+set ylabel "Error"
+set title "Error analysis"
+set log xy
+set grid
+plot "performance.dat" u 1:3 title "Plain Monte-Carlo" w lp, 1/sqrt(x) w l tit…
diff --git a/notes.rst b/notes.rst
t@@ -0,0 +1,398 @@
+# vim: set tw=80:noautoindent
+
+For Jacobi exercise: Use atan2().
+
+11-4: Introduction
+#####
+Deadline for exercises: ~2 weeks after assignment
+
+All exercises must be done on Lifa:
+ lifa.phys.au.dk
+ Ethernet: vlifa01 or vlifa02
+You need RSA keys to login from outside net.
+Login from inside: NFIT credentials.
+
+Alternative server: molveno
+Dedicated for numerical course.
+
+Lifa will have approx. 5 year old software, molveno is updated.
+
+All phys.au.dk servers have NFS shared home folders.
+
+Dmitri answers:
+http://www.phys.au.dk/~fedorov/numeric/
+
+Bash: Last command starting with e.g. 'v': !v
+
+Exercises are weighted 75% and the exam 25%. You do need to complete at least
+51% of the exam.
+
+02: >51%
+4: >60%
+7: >80%
+10: >90%
+12: 100%
+
+16-4: Interpolation
+####
+Makefiles_:
+For all project, use makefiles, the project is evaluated by `make clean; make`.
+
+General structure of Makefile:
+ Definitions of variables
+ all: my_target
+ Target(s): Dependenc(y,ies)
+ <-tab-> Command(s)
+
+Strings are denoted without decoration, variables as $(VAR).
+To use the CC system linker to link C++ objects, add libraries:
+ LDLIBS += -lstdc++
+If you use e.g. g++ as the linker, the above command is not needed.
+
+If an object file is required as a dependency, the Makefile will issue a CC
+command, compiling the source code file with the same basename. `make -p | les…
+will show all build rules, even build in.
+
+Interpolation_:
+When you have a discrete set of datapoints, and you want a function that
+describes the points.
+
+If a function is analytical and continuous, and an infinitely large table of
+datapoints in an interval, the complete analytical function can be found from a
+taylor-series of _all_ derivatives in the interval.
+
+k-Polynomial: k+1 unknowns (variables). High polynomials tend to oscillate.
+
+Cubic interpolation: The interval between points can be described by a function
+of three polynomials.
+
+Spline interpolation: Also made of polynomials. First order spline (a0+x*a1),
+simply connects the data points linearly. The splines for each inter-datapoint
+interval must have the same values at the data points. The derivates are
+discontinuous.
+
+Solving linear splines:
+Datapoints: {x_i,y_i}, i = 1,...,n
+Splines (n-1): S_i(x) = a_i + b_i (x - x_i)
+ S_i(x_i) = y_i (n equations)
+ S_i(x_{i+1}) = S_{i+1}(x_i) (n-2 equations (inner points))
+Unkowns: a,b: 2n-2 variables. Solution:
+ => a_i = y_i
+ S_i(x) = y_i + b_i (x-x_i)
+ S_i(x_{i+1}) = y_i + b_i (x_{i+1} - x_i)
+ => b_i = (y_{i+1} - y_i) / (x_{i+1} - x_i)
+
+Start of by searching which interval x is located in. Optionally, remember the
+interval, as the next value will probably lie in the same interval.
+
+Binary search: Is x between x_1 and x_n? If not, error: Extrapolation.
+Continuously divide the interval into two, and find out if the x is in the
+larger or smaller part.
+DO A BINARY SEARCH.
+
+Second order spline:
+ S_i(x) = a_i + b_i(x-x_i) + c_i(x-x_i)^2
+ Unknowns: 3(n-1) = 3*n-3
+ Equations: 3*n-4
+ The derivatives are also continuous.
+
+Solution:
+ a_i = y_i
+ \delta x = (x-x_i)
+ y_i + b_i \delta x_i + c_i \delta x_i^2 = y_{i+1}
+ b_i + 2 c_i \delta x_i = b_{i+1}
+Suppose you know b_i, you can find c_i. From that you can find b_{i+1}, and in
+turn, c_{i+1}. Through recursion you find all unknowns by stepping forward.
+The backwards solution can be found from the last data-point (y_n) by solving
+the two equations with c_{n-1} and b_{n-1} as the two unkowns.
+
+Symmetry can be used as an extra condition.
+
+
+18-4:
+##############
+Interpolation exercise, plotting optionally in gnuplot, or graph (from
+plotutils):
+ graph -T png points.dat > plot.png
+In makefile, example:
+ plot.png: points.dat
+ graph --display-type png $^ > $@
+Each dataset in points.dat needs a header, e.g. # m=1, S=0
+
+lspline.cc: Linear spline
+qspline.cc: Quadratic spline
+cspline.cc: Cubic spline
+
+Linear spline:
+ S(x) = S_i(x) it x in [x_i,x_(i+1)]
+ S_i(x) = a_i + b_i (x-x_i)
+ S_i(x) = y_i + (\delta y_i)/(\delta x_i) (x-x_i)
+ S_i(x_i) = y_i
+ \delta y_i = y_(i+1) - y_i
+ S_i (x_(i+1)) = y_(i+1)
+
+In C++:
+ std::vector<double> x,y,p;
+Maybe typecasting? Could be fun.
+
+Procedural programming:
+--
+ struct lspline {
+ int n;
+ vector<double> x,y,p;
+ };
+
+Make a function:
+ struct lspline* construct_lspline(vector<double>&x, vector<double>&y)
+ double evaluate_lspline(struct lspline * asdf, double z)
+ free_lspline();
+
+Object-oriented programming:
+--
+If you want to take the structural approach, you keep the functions and
+structures seperate. If you take a OO approach, put the functions inside the
+structure (or class):
+ struct lspline {
+ int n;
+ vector<double> x,y,p;
+ lspline(...,..); // Constructor, same name as struct
+ double eval(double z);
+ };
+ struct lspline ms(x,y);
+ ms.eval(z);
+
+See Dmitri's cubic spline example which uses OO.
+
+Functional programming (in C++11), compile with -std=c++0x:
+--
+The functions can return functions:
+
+ #include <functional>
+ using namespace std;
+
+ function<double(double)> flspline (vector<double>&x, vector<double>&y);
+
+ auto my_spline = flspline(x,y);
+ my_spline(5,0);
+
+
+System of linear equations:
+-------
+A*x = b
+
+A_i,j x_j = b_i
+
+Solve by finding A^(-1): x = A^(-1) * b
+Numerically, you calculate the inverse by solving Ax=b.
+We will assume that the matrixes are not singular.
+
+ Turn the system into a triangular form.
+ The main diagonal is non-zero, all lower values are 0, and upper values are
+ denoted T_nn.
+ T_nn * x_n = b_n => x_n = 1/T_nn * b_nn
+ T_(n-1,n-1) x_(n-1) + T_(n-1,n) x_n = b_(n-1)
+ T_ii x_i + sum^n_(j=i+1) T_(i,j) x_j = b_i
+ x_i = 1/T_ii (b_i - sum^n_(j=i+1) T_ij, x_j)
+
+The simplest triangulation is by Gauss elimination. Numerically, the simplest
+method is LU decomposition (Lower Upper).
+ A = LU, where L=lower triangle, U=upper triangle.
+ n^2 equations.
+ L and U contain "(n^2 - n)/2 + n" elements.
+ L+U = n^2/2 + n/2 = (n(n+1))/2
+
+ The diagonals in L are all equal to 1: L_ii = 1.
+ See Dolittle algorithm in the lecture notes, which with the LU system is the
+ most used, and fastest method for solving a linear equation.
+
+ Ax = b
+ LUx = b, Ux=y
+
+Another method: QR decomposition: R=Right triangle (equal to U).
+ A = QR
+ Q^T Q = 1 (orthogonal)
+
+ Ax = b
+ QRx = b
+ Rx = Q^T b
+
+ Gram-Schmidt (spelling?) orthogonalization:
+ Consider the columns of your matrix A. Normalize them. Orthogonalize all oth…
+ columns to the first column.
+
+ Normalizing the column: ||a_1|| = sqrt(a_1 dot a_i)
+ Orthoginalize columns: a_2/||a_1|| -> q_1
+
+ Numerically:
+ for j=2 to m:
+ a_j - dot(dot(q_1,a_j),q_1) -> a_j
+ a_2 -> a_2/||a_2|| = q_2
+
+Find inverse matrix:
+ A A^-1 = diag(1)
+
+
+
+30-4: Diagonalization
+#########################
+
+Runtime comparison: Do a number of comparisons with different matrix sizes
+etc.numeric-2012
+
+Easiest way to diagonalize a matrix: Orthogonal transformation
+ A -> Q^T A Q = D
+Q matrix can be built with e.g. QR decomposition. Rotation: Computers to cyclic
+sweep, which is faster than the classic rotation.
+Cyclic: Zero all elements above the diagonal, and do your rotations until the
+matrix is diagonal. The matrix is converged if none of the eigenvalues have
+changed more than machine precision. You will destroy the upper half plus the
+diagonal. If you store the diagonal in another vector, you can preserve the
+matrix values.
+In the beginning, you look for the largest element in each row, and create an
+index which is a column that keeps the numbers of the largest elements.
+With an index, you can perform the operation fast. You have to update the index
+after each operation.
+
+For very large matrixes, > system memory:
+Krylov subspace methods: You use only a subspace of the whole space, and
+diagonalize the matrix in the subspace.
+
+
+02-5: Ordinary Differential Equations (ODEs)
+############################################
+
+ dy/dx = f(x,y)
+
+Usually coupled equations:
+ dy_1/dx = f_1(x,y_1,y_2)
+ dy_2/dx = f_1(x,y_1,y_2)
+ [y_1, ..., y_n] = y
+ [f_1(x,y), ..., f_n(x,y) = f(x,y)
+ y' = f(x,y)
+x is usually time. If f has the above form, it is a ODE.
+Sine function:
+ y'' = -y
+In this form, it is not a ODE, because it has a second derivative.
+You can redifine it to be an ODE:
+ => y = u_1 -> u'_1 = u_2
+ y' = u_2 -> u'_2 = -u_1
+
+Solving ODEs with a starting condition:
+ y' = f(x,y)
+ y(x_0) = y_0
+ a->b (Shape of the function in the interval)
+You can calculate the derivative at (x_0,y_0). You then make a step towards
+x_0+h, and apply Euler's method:
+ y' \approx (\delta y)/(\delta x) = (y(x_0+h) - y_0)/h
+ y(x_0+h) \approx y(x_0) + h*f(x_0,y_0)
+ y(x) = y_0 + y'_0(x-x0) + 1/(2!) y''_0(x_0)(x-x_0)^2 + ... (Taylor exp.)
+You can find the higher-order terms by sampling points around (x_0,y_0).
+Estimate the new derivative half a step towards h, which is used for the first
+point. You sample your function, and fit a polynomial. Higher order polynomiums
+tend to oscillate.
+When solving ODE's the many sampled points create a tabulated function. If you
+want to do something further with the function, you interpolate the points by
+e.g. splines.
+Only three steps are needed if the equation is a parabola. Other functions are
+called multi-step methods. You do not want to go to high in the
+Taylor-expansion, as there lies a danger with the higher order terms
+oscillating.
+If the function is changing fast inside an interval, the step size h needs to …
+small. This is done by a driver.
+The Runge-kutta is single step, and the most widely used.
+
+Absolute accuracy (delta) vs. relative accuracy (epsilon) can behave
+significantly differently when the machine precision is reached.
+The user usually specifies both, and the accuracy is satisfied, when one of the
+conditions are met (the tolerance, tau).
+ tau = delta + epsilon*||y||
+
+Stepper: Must return y(x+h), e (error estimate).
+Driver: x->x+h. If e is smaller than tau, it accepts the step.
+The driver finds the size of the next h:
+ h_next = h(tau/e)^power * safety
+ power = 0.25
+ safety = 0.95
+ The driver thus increases the step size if the error was low relative to the
+ tolerance, and vice-versa.
+
+ Runge principle for determining the error:
+ e = C*h^(p+1)
+ You first do a full h step, then two h/2 steps.
+ 2*c*(h/2)^(p+1) = c * (h^(p+1))/(2^p)
+ For the error, you calculate y_1 from full step, and then y_1 from two half …
+ e = ||y_1(full step) - y_1(2 half steps)||
+ You can also instead use RK1 and RK2, and evaluate the difference between the
+ two for the same step.
+
+The effectiveness of the driver and stepper is determined by how many times you
+call the right-hand side of the ODEs.
+
+Save the x and y values in a C++ vector, and add dynamically using the
+push_back() function.
+
+
+07-5: Nonlinear equations and optimization
+#####
+Pipe stdin to program:
+ cat input.txt | ./my_prog
+Redirect stdout to file:
+ ./my_prog > out.txt
+Redirect stderr to file:
+ ./my_prog 2> err.txt
+
+Jacobian matrix: Filled with partial derivatives. Used for linearizing the
+problem. f(x+\delta x) \approx f + J \delta x
+
+Machine precision: double: 2e-16. It is the largest number where 1 + eps = 1.
+
+Quasi-Newton methods: Might be exam exercise.
+
+
+14-5: Numerical integration
+#####
+Examination problem: FFT or Multiprocessing
+
+Functions for calculating:
+ \int_a^b f(x) dx
+
+Often not possible analytically, thus numerical aproach. Most differential
+operations are possible analytically.
+
+Riemann integral: Numerical approximation.
+You divide the interval into subintervals (t_1, ..., t_n).
+Riemann sum:
+ S_n = \sum_{i=1}^n f(x_i) \Delta x_i
+Approaching the integral as the interval approaches 0.0. The geometric
+interpretation corresponds to rectangles with height f(x_i) and width \Delta
+x_i. The function passes trough the middle of the top side of the rectangles.
+The integral exists also for discontinuous functions.
+
+Rectangle method: Stable, does no assumptions
+ \int_a^b f(x) dx \approx \sum_{i=1}^n f(x_i) \Delta x_i
+Trapezum method:
+ Instead of one point inside the interval, two points are calculated, and the
+ average is used.
+ \int_a^b f(x) dx \approx \sum_{i=1}^n (f(x_{i+1} )+ f(x_i))/2 * \Delta x_i
+Adaptive methods:
+ The \Delta x_i is adjusted to how flat the function is in an interval.
+ As few points as possible are used.
+Polynomial functions:
+ Analytical solutions exist. Taylor series expansion. w_i: Weight.
+ \sum_{i=1}^n w_i f(x_i) => \int_a^b f(x) dx
+ `---- quadrature -----`
+ n functions: {\phi_1(x),...,\phi_n(x)}
+ Often the polynomials are chosen: {1,x,x^2,...,x^{n-1}}
+ \sum_{i=1}^n w_i \phi_k(x_i) = I_k
+ I_k = \int_a^b \phi_k (x) dx
+Gauss methods:
+ Also use the quadratures as tuning parameters, as the polynomial method.
+ w_i,x_i as tuning parameters: 2*n tuning parameters.
+ \int_a^b f(x) w(x) dx
+ Functions like 1/sqrt(x) or sqrt(x) are handled through the weight function.
+ See the lecture notes for details. Both nodes and weights are adjusted.
+
+The method to use is dependent on the problem at hand.
+
+
+
diff --git a/notes/book.pdf b/notes/book.pdf
Binary files differ.
diff --git a/notes/eigen.pdf b/notes/eigen.pdf
Binary files differ.
diff --git a/notes/fft.pdf b/notes/fft.pdf
Binary files differ.
diff --git a/notes/integration.pdf b/notes/integration.pdf
Binary files differ.
diff --git a/notes/interp.pdf b/notes/interp.pdf
Binary files differ.
diff --git a/notes/krylov.pdf b/notes/krylov.pdf
Binary files differ.
diff --git a/notes/leastsq.pdf b/notes/leastsq.pdf
Binary files differ.
diff --git a/notes/lineq.pdf b/notes/lineq.pdf
Binary files differ.
diff --git a/notes/montecarlo.pdf b/notes/montecarlo.pdf
Binary files differ.
diff --git a/notes/odes.pdf b/notes/odes.pdf
Binary files differ.
diff --git a/notes/roots.pdf b/notes/roots.pdf
Binary files differ.
diff --git a/notes/sfun.pdf b/notes/sfun.pdf
diff --git a/optimization/Makefile b/optimization/Makefile
t@@ -0,0 +1,69 @@
+# Define compiler
+CC=g++
+
+# Define compiler flags (show all warnings)
+CPPFLAGS=-Wall -std=c++0x
+
+# Define linker flags
+LDFLAGS=
+
+# Define extra libraries to be dynamically linked
+LDLIBS+=-larmadillo -lstdc++
+
+# Compile optimized code
+#CPPFLAGS+=-O2
+
+# Compile debuggable code
+#CPPFLAGS+=-g
+
+# Compile profilable code
+#CPPFLAGS+=-pg
+#LDFLAGS+=-pg
+
+# Define linker
+LD=g++
+
+# Filenames of source code
+SRC=$(shell ls *.cpp)
+
+# Filenames of object files
+#OBJ=$(SRC:.cpp=.o)
+OBJ=downhill_simplex.o main.o
+OBJB=downhill_simplex.o main.B.o
+
+# Remove file type extension for binary filename
+BIN=optim
+BINB=optimB
+
+# The default "all" depends on A and B
+
+all: A B
+
+
+A: $(BIN)
+ @# Run program and write amoeba positions to file
+ ./$(BIN) 2> amoeba.dat
+
+B: $(BINB)
+ ./$(BINB) 2> amoebaB.dat
+
+$(BIN): $(OBJ)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ) -o $(BIN) $(LDLIBS)
+
+$(BINB): $(OBJB)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJB) -o $(BINB) $(LDLIBS)
+
+clean:
+ @# Remove object files
+ rm -f $(OBJ) $(OBJB)
+ @# Remove binaries
+ rm -f $(BIN) $(BINB)
+ @# Remove datafiles and plot
+ #rm -f *.dat *.png
+ @# Remove error log
+ rm -f amoeba.dat amoebaB.dat
+edit:
+ vim -p Makefile *.cpp *.h
+
diff --git a/optimization/downhill_simplex.cpp b/optimization/downhill_simplex.…
t@@ -0,0 +1,173 @@
+#include <iostream>
+#include <armadillo>
+#include <vector>
+#include <functional>
+#include "downhill_simplex.h"
+
+using namespace std;
+using namespace arma;
+
+// Amoeba constructor
+amoeba::amoeba(function<double(vec)> fun, vector<vec> simplex)
+ : d(simplex.size()-1), f(fun), value(zeros<vec>(d)), p_ce(zeros<vec>(d))
+{
+ p_ce_o = p_ce;
+
+ for (int i=0; i<d+1; ++i)
+ p.push_back(simplex[i]);
+ for (int i=0; i<d+1; ++i)
+ value[i] = f(p[i]);
+
+ update();
+
+}
+
+// Update amoeba parameters
+void amoeba::update()
+{
+
+ p_ce_o = p_ce;
+
+ // Find highest point
+ hi = 0;
+ for (int i=1; i<d+1; ++i)
+ if (value[i] > value[hi])
+ hi = i;
+
+ // Find lowest point
+ lo = 0;
+ for (int i=1; i<d+1; ++i)
+ if (value[i] < value[lo])
+ lo = i;
+
+ // Find centroid
+ p_ce = zeros<vec>(d);
+ for (int i=0; i<d+1; ++i)
+ if (i != hi)
+ p_ce += p[i];
+ p_ce /= d;
+
+ // Write amoeba position to stderr
+ pos();
+}
+
+// Find size of simplex
+double amoeba::size()
+{
+ double s = 0;
+ for (int i=0; i<d+1; ++i)
+ if (i != lo) {
+ double n = norm(p[i] - p[lo], 2.0f);
+ if (n>s)
+ s=n;
+ }
+ return s;
+}
+
+void amoeba::downhill(double simplex_size_goal)
+{
+ // Find operation to update position
+ while (size() > simplex_size_goal) {
+
+ vec p_re = p_ce + (p_ce - p[hi]); // Try reflection
+ double f_re = f(p_re);
+ if (f_re < value[lo]) {
+ vec p_ex = p_ce + 1.0f * (p_ce - p[hi]); // Try expansion
+ double f_ex = f(p_ex);
+ if (f_ex < f_re) {
+ value[hi] = f_ex;
+ p[hi] = p_ex; // Accept expansion
+ update(); continue; // Start loop over
+ }
+ }
+
+ if (f_re < value[hi]) {
+ value[hi] = f_re;
+ p[hi] = p_re; // Accept reflection
+ update(); continue; // Start loop over
+ }
+
+ vec p_co = p_ce + 0.5f * (p[hi] - p_ce); // Try contraction
+ double f_co = f(p_co);
+ if (f_co < value[hi]) {
+ value[hi] = f_co;
+ p[hi] = p_co; // Accept contraction
+ update(); continue; // Start loop over
+ }
+
+ for (int i=0; i<d+1; ++i)
+ if (i != lo) {
+ p[i] = 0.5f * (p[i] + p[lo]); // Do reduction
+ value[i] = f(p[i]);
+ }
+ update(); continue;
+ }
+}
+
+void amoeba::downhill_mod(double simplex_size_goal)
+{
+ // Find operation to update position
+ while (size() > simplex_size_goal) {
+
+ vec p_re = p_ce + (p_ce - p[hi]); // Try reflection
+
+ double f_re = f(p_re);
+ if (f_re < value[lo]) {
+ vec p_ex_n = p_ce + 1.0f * (p_ce - p[hi]); // Try expansion
+ double f_ex_n = f(p_ex_n);
+ vec p_ex_o = p_ce_o + 1.0f * (p_ce_o - p[hi]); // Try expansion, old val
+ double f_ex_o = f(p_ex_o);
+
+ // Find out which expansion gave the lowest value
+ vec p_ex; double f_ex;
+ if (f_ex_n < f_ex_o) { // New val
+ p_ex = p_ex_n;
+ f_ex = f_ex_n;
+ } else { // Old val
+ p_ex = p_ex_o;
+ f_ex = f_ex_o;
+ }
+
+ if (f_ex < f_re) {
+ value[hi] = f_ex;
+ p[hi] = p_ex; // Accept expansion
+ update(); continue; // Start loop over
+ }
+ }
+
+ if (f_re < value[hi]) {
+ value[hi] = f_re;
+ p[hi] = p_re; // Accept reflection
+ update(); continue; // Start loop over
+ }
+
+ vec p_co = p_ce + 0.5f * (p[hi] - p_ce); // Try contraction
+ double f_co = f(p_co);
+ if (f_co < value[hi]) {
+ value[hi] = f_co;
+ p[hi] = p_co; // Accept contraction
+ update(); continue; // Start loop over
+ }
+
+ for (int i=0; i<d+1; ++i)
+ if (i != lo) {
+ p[i] = 0.5f * (p[i] + p[lo]); // Do reduction
+ value[i] = f(p[i]);
+ }
+ update(); continue;
+ }
+}
+
+// Write simplex points to stderr
+void amoeba::pos()
+{
+ for (int i=0; i<d+1; ++i)
+ std::cerr << p[i][0] << '\t'
+ << p[i][1] << '\n';
+}
+
+// Return lowest point of simplex
+vec amoeba::low()
+{
+ return p[lo];
+}
diff --git a/optimization/downhill_simplex.h b/optimization/downhill_simplex.h
t@@ -0,0 +1,61 @@
+#ifndef DOWNHILL_SIMPLEX_H_
+#define DOWNHILL_SIMPLEX_H_
+
+#include <functional>
+#include <vector>
+#include <armadillo>
+using namespace std;
+using namespace arma;
+
+class amoeba {
+
+ public:
+
+ // Constructor
+ amoeba(function<double(vec)> fun, vector<vec> simplex);
+
+ // Return lowest simplex position
+ vec low();
+
+ // Move amoeba downhill with relevant method
+ void downhill(double simplex_size_goal);
+
+ // Move amoeba downhill with relevant method, modified method
+ void downhill_mod(double simplex_size_goal);
+
+ private:
+
+ // Number of vertexes
+ int d;
+
+ // Maxima points of function
+ int hi, lo;
+
+ // Vertex points
+ vector<vec> p;
+
+ // Functions to be evaluated
+ std::function<double(vec)> f;
+
+ // Function values at points
+ vec value;
+
+ // Centroid
+ vec p_ce;
+
+ // Centroid from previous step
+ vec p_ce_o;
+
+ // Filename of output file
+
+ // Private class functions
+ void update();
+
+ // Returns size of the amoeba
+ double size();
+
+ // Write amoeba position vertexes to stderr
+ void pos();
+};
+
+#endif
diff --git a/optimization/functions.h b/optimization/functions.h
t@@ -0,0 +1,24 @@
+#include <functional>
+#include <armadillo>
+using namespace arma;
+using namespace std;
+
+int ncalls = 0;
+
+
+// Rosenbrock's function
+function<double(vec)> rosenbrock = [&ncalls] (vec p) {
+ ++ncalls;
+ double x = p[0], y = p[1];
+ return (1.0f - x) * (1.0f - x)
+ + 100.f * (y - x*x) * (y - x*x);
+};
+
+// Himmelblau's function
+function<double(vec)> himmelblau = [&ncalls] (vec p) {
+ ++ncalls;
+ double x = p[0], y = p[1];
+ return (x*x + y - 11.0f) * (x*x + y - 11.0f)
+ + (x + y*y - 7.0f) * (x + y*y - 7.0f);
+};
+
diff --git a/optimization/header.h b/optimization/header.h
t@@ -0,0 +1,12 @@
+// Make sure header is only included once
+#ifndef HEADER_H_
+#define HEADER_H_
+
+// Define whether the program should output values of matrices
+const bool verbose = false;
+//const bool verbose = true;
+
+// Prototype for checking function
+void check(const bool statement);
+
+#endif
diff --git a/optimization/main.B.cpp b/optimization/main.B.cpp
t@@ -0,0 +1,93 @@
+#include <iostream>
+#include <armadillo>
+#include <functional>
+#include "header.h"
+#include "functions.h"
+#include "downhill_simplex.h"
+using namespace arma;
+using namespace std;
+
+int main(int argc, char* argv[])
+{
+ // Namespace declarations
+ using std::cout;
+
+ // Calculate machine precision
+ double eps = 1.0f;
+ while (1.0f + eps != 1.0f)
+ eps /= 2.0f;
+
+ cout << "\n\033[1;36m## Minimization with downhill-simplex, part B ##\033[0m…
+
+ // Try amoeba on Rosenbrock's valley function
+ cout << "\n\033[1;33m--- Rosenbrock's valley function ---\033[0m\n";
+ int d = 2;
+ vec p(2); p[0]=5; p[1]=6;
+ if (verbose == true)
+ p.print("Initial simplex is chosen around the point:");
+ vector<vec> simplex;
+ vector<vec> simplex_mod;
+ for(int i=0; i<d+1; ++i) {
+ simplex.push_back(p);
+ simplex_mod.push_back(p);
+ }
+ double dx = 1;
+ for(int i=0; i<d; ++i) {
+ simplex[i][i] += dx;
+ simplex_mod[i][i] += dx;
+ }
+ amoeba A(rosenbrock, simplex);
+ ncalls = 0;
+ A.downhill(10.0f*eps);
+ if (verbose == true)
+ A.low().print("Lowest point:");
+ cout << "Amoeba converged after " << ncalls << " calls\n";
+ amoeba A_mod(rosenbrock, simplex_mod);
+ ncalls = 0;
+ A_mod.downhill_mod(10.0f*eps);
+ if (verbose == true)
+ A_mod.low().print("Lowest point (modified downhill)");
+ cout << "Amoeba converged after " << ncalls << " calls with modified method\…
+
+
+ // Try amoeba on Himmelblau's function
+ cout << "\n\033[1;33m--- Himmelblau's function ---\033[0m\n";
+ vec p2(2); p2[0]=5; p2[1]=6;
+ if (verbose == true)
+ p2.print("Initial simplex is chosen around the point:");
+ vector<vec> simplex2;
+ vector<vec> simplex2_mod;
+ for(int i=0; i<d+1; ++i) {
+ simplex2.push_back(p2);
+ simplex2_mod.push_back(p2);
+ }
+ double dx2 = 1;
+ for(int i=0; i<d; ++i) {
+ simplex2[i][i] += dx2;
+ simplex2_mod[i][i] += dx2;
+ }
+ amoeba A2(himmelblau, simplex2);
+ ncalls = 0;
+ A2.downhill(10.0f*eps);
+ if (verbose == true)
+ A2.low().print("Lowest point:");
+ cout << "Amoeba converged after " << ncalls << " calls\n";
+ amoeba A2_mod(himmelblau, simplex2_mod);
+ ncalls = 0;
+ A2_mod.downhill_mod(10.0f*eps);
+ if (verbose == true)
+ A2_mod.low().print("Lowest point (modified downhill)");
+ cout << "Amoeba converged after " << ncalls << " calls with modified method\…
+
+ // Return successfully
+ return 0;
+}
+
+void check(const bool statement)
+{
+ using std::cout;
+ if (statement == true)
+ cout << "\t\033[0;32mPassed\033[0m\n";
+ else
+ cout << "\t\033[1;31mFail!!\033[0m\n";
+}
diff --git a/optimization/main.cpp b/optimization/main.cpp
t@@ -0,0 +1,68 @@
+#include <iostream>
+#include <armadillo>
+#include <functional>
+#include "header.h"
+#include "functions.h"
+#include "downhill_simplex.h"
+using namespace arma;
+using namespace std;
+
+int main(int argc, char* argv[])
+{
+ // Namespace declarations
+ using std::cout;
+
+ // Calculate machine precision
+ double eps = 1.0f;
+ while (1.0f + eps != 1.0f)
+ eps /= 2.0f;
+
+ cout << "\n\033[1;36m## Minimization with downhill-simplex, part A ##\033[0m…
+
+ // Try amoeba on Rosenbrock's valley function
+ cout << "\n\033[1;33m--- Rosenbrock's valley function ---\033[0m\n";
+ int d = 2;
+ vec p(2); p[0]=5; p[1]=6;
+ p.print("Initial simplex is chosen around the point:");
+ vector<vec> simplex;
+ for(int i=0; i<d+1; ++i)
+ simplex.push_back(p);
+ double dx = 1;
+ for(int i=0; i<d; ++i)
+ simplex[i][i] += dx;
+ amoeba A(rosenbrock, simplex);
+ ncalls = 0;
+ A.downhill(10.0f*eps);
+ A.low().print("Lowest point:");
+ cout << "Amoeba converged after " << ncalls << " calls\n"
+ << "(Newton's root-finding method did this in 4181 calls)\n";
+
+ // Try amoeba on Himmelblau's function
+ cout << "\n\033[1;33m--- Himmelblau's function ---\033[0m\n";
+ vec p2(2); p2[0]=5; p2[1]=6;
+ p2.print("Initial simplex is chosen around the point:");
+ vector<vec> simplex2;
+ for(int i=0; i<d+1; ++i)
+ simplex2.push_back(p2);
+ double dx2 = 1;
+ for(int i=0; i<d; ++i)
+ simplex2[i][i] += dx2;
+ amoeba A2(himmelblau, simplex2);
+ ncalls = 0;
+ A2.downhill(10.0f*eps);
+ A2.low().print("Lowest point:");
+ cout << "Amoeba converged after " << ncalls << " calls\n"
+ << "(Newton's root-finding method did this in 33 calls)\n";
+
+ // Return successfully
+ return 0;
+}
+
+void check(const bool statement)
+{
+ using std::cout;
+ if (statement == true)
+ cout << "\t\033[0;32mPassed\033[0m\n";
+ else
+ cout << "\t\033[1;31mFail!!\033[0m\n";
+}
diff --git a/roots/Makefile b/roots/Makefile
t@@ -0,0 +1,74 @@
+# Define compiler
+CC=g++
+
+# Define compiler flags (show all warnings)
+CPPFLAGS=-Wall -std=c++0x
+CXXFLAGS=-Wall -std=c++0x
+
+# Define linker flags
+LDFLAGS=
+
+# Define extra libraries to be dynamically linked
+LDLIBS+=-larmadillo -lstdc++
+
+# Compile optimized code
+#CPPFLAGS+=-O2
+
+# Compile debuggable code
+#CPPFLAGS+=-g
+
+# Compile profilable code
+#CPPFLAGS+=-pg
+#LDFLAGS+=-pg
+
+# Define linker
+LD=g++
+
+# Filenames of source code
+SRC=$(shell ls *.cpp)
+
+# Filenames of object files
+OBJ=$(SRC:.cpp=.o)
+
+# Remove file type extension for binary filename
+BIN=roots
+
+# The default "all" depends on A and B
+
+#all: A B
+
+#A: plot.A.png
+
+#B: plot.B.png
+
+#plot.%.png: fit.A.dat fit.B.dat data.A.txt data.B.txt
+# gnuplot plotall.gp
+
+#fit.A.dat: $(BIN)
+# ./$(BIN) data.A.txt fit.A.dat
+
+#fit.B.dat: $(BIN)
+# ./$(BIN) data.B.txt fit.B.dat
+#
+
+run: $(BIN)
+ ./$(BIN) 2> error.log
+
+$(BIN): $(OBJ)
+ @# Link object files together
+ $(LD) $(LDFLAGS) $(OBJ) -o $(BIN) $(LDLIBS)
+ @# Execute program and redirect stdout to file
+ @#./$(BIN) > out.txt
+
+clean:
+ @# Remove object files
+ rm -f $(OBJ)
+ @# Remove binary
+ rm -f $(BIN)
+ @# Remove datafiles and plot
+ #rm -f *.dat *.png
+ @# Remove error log
+ rm -f error.log
+edit:
+ vim -p Makefile *.cpp *.h
+
diff --git a/roots/functions.h b/roots/functions.h
t@@ -0,0 +1,84 @@
+#include <functional>
+#include <armadillo>
+using namespace arma;
+using namespace std;
+
+int ncalls = 0;
+
+// System of equations (first task)
+function<vec(vec)> sys_2_eqs = [&ncalls] (vec p) {
+ ++ncalls;
+ double A = 10000.0f;
+ vec f(2);
+ double x = p[0], y = p[1];
+ f[0] = A * x * y - 1.0f;
+ f[1] = exp(-x) + exp(-y) - 1.0f - 1.0f/A;
+ return f;
+};
+
+// Rosenbrock's function
+function<vec(vec)> rosenbrock = [&ncalls] (vec p) {
+ ++ncalls;
+ vec f(1);
+ double x = p[0], y = p[1];
+ f[0] = (1.0f - x) * (1.0f - x)
+ + 100.f * (y - x*x) * (y - x*x);
+ return f;
+};
+
+// Gradient of Rosenbrock's function
+function<vec(vec)> rosenbrockGrad = [&ncalls] (vec p) {
+ ++ncalls;
+ vec f(2);
+ double x = p[0], y = p[1];
+ f[0] = 2.0f * (1.0f - x) * (-1.0f)
+ + 100.0f * 2.0f * (y - x*x) * (-1.0f) * 2.0f * x;
+ f[1] = 100.0f * 2.0f * (y - x*x);
+ return f;
+};
+
+// Return derivatives of Rosenbrock's function (Jacobian matrix)
+mat rosenbrockJacobian(vec p) {
+ mat J(2,2);
+ double x = p[0], y = p[1];
+ J(0,0) = 2.0f + 1200.0f*x*x - 400.0f*y;
+ J(0,1) = -400.0f*x;
+ J(1,0) = -400.0f*x;
+ J(1,1) = 200.0f;
+ return J;
+};
+
+
+// Himmelblau's function
+function<vec(vec)> himmelblau = [&ncalls] (vec p) {
+ ++ncalls;
+ vec f(1);
+ double x = p[0], y = p[1];
+ f[0] = (x*x + y - 11.0f) * (x*x + y - 11.0f)
+ + (x + y*y - 7.0f) * (x + y*y - 7.0f);
+ return f;
+};
+
+// Gradient of Himmelblau's function
+function<vec(vec)> himmelblauGrad = [&ncalls] (vec p) {
+ ++ncalls;
+ vec f(2);
+ double x = p[0], y = p[1];
+ f[0] = 2.0f * (x*x + y - 11.0f) * 2.0f * x + 2.0f*(x + y*y - 7.0f);
+ f[1] = 2.0f * (x*x + y - 11.0f) + 2.0f * (x + y*y - 7.0f) * 2.0f * y;
+ return f;
+};
+
+// Return derivatives of Himmelblau's function (Jacobian matrix)
+mat himmelblauJacobian(vec p) {
+ mat J(2,2);
+ double x = p[0], y = p[1];
+ J(0,0) = 4.0f * x*2.0f * x
+ + 4.0f * (x*x + y - 11.0f) + 2.0f;
+ J(0,1) = 4.0f * x+4.0f * y;
+ J(1,0) = 4.0f * x+4.0f * y;
+ J(1,1) = 4.0f * y * 2.0f * y
+ + 4.0f * (y*y + x - 7.0f) + 2.0f;
+
+ return J;
+}
diff --git a/roots/header.h b/roots/header.h
t@@ -0,0 +1,20 @@
+// Make sure header is only included once
+#ifndef HEADER_H_
+#define HEADER_H_
+
+// Define whether the program should output values of matrices
+const bool verbose = false;
+//const bool verbose = true;
+
+// Choose vector length variable type
+typedef int Lengthtype;
+
+// Choose floating-point precision
+//typedef float Floattype;
+typedef double Floattype;
+//typedef long double Floattype;
+
+// Prototype for checking function
+void check(const bool statement);
+
+#endif
diff --git a/roots/main.cpp b/roots/main.cpp
t@@ -0,0 +1,79 @@
+#include <iostream>
+#include <armadillo>
+#include <functional>
+#include "header.h"
+#include "functions.h"
+using namespace arma;
+using namespace std;
+
+vec newton(function<vec(vec)> f, vec x_0, vec dx, Floattype eps);
+vec newtonJac(function<vec(vec)> f, vec x_0, vec dx, Floattype eps,
+ mat (*J)(vec));
+
+int main(int argc, char* argv[])
+{
+ // Namespace declarations
+ using std::cout;
+
+ // Calculate machine precision
+ Floattype eps = 1.0f;
+ while (1.0f + eps != 1.0f)
+ eps /= 2.0f;
+
+ cout << "\nFinding the solution to the two-equation linear system:\n";
+ vec x1(2); x1[0] = 2.0f; x1[1] = 2.1f;
+ vec dx1(2); dx1[0] = 1e-6f; dx1[1] = 1e-6f;
+ ncalls = 0;
+ vec root1 = newton(sys_2_eqs, x1, dx1, eps*10.f);
+ root1.print("Solution x:");
+ sys_2_eqs(root1).print("f(x):");
+ cout << "It took " << ncalls << " function calls\n";
+
+ cout << "\nFinding the minumum of the Rosenbrock's valley function:\n";
+ vec x2(2); x2[0] = 5.0f; x2[1] = 6.0f;
+ vec dx2(2); dx2[0] = 1e-6f; dx2[1] = 1e-6f;
+ ncalls = 0;
+ vec root2 = newton(rosenbrockGrad, x2, dx2, eps*10.f);
+ root2.print("Solution x:");
+ rosenbrock(root2).print("Rosenbrock at x:");
+ cout << "It took " << ncalls << " function calls\n";
+
+ cout << "\nFinding the minumum of the Rosenbrock's valley function, Jacobian…
+ vec x2J(2); x2J[0] = 5.0f; x2J[1] = 6.0f;
+ vec dx2J(2); dx2J[0] = 1e-6f; dx2J[1] = 1e-6f;
+ ncalls = 0;
+ vec root2J = newtonJac(rosenbrockGrad, x2J, dx2J, eps*10.f, rosenbrockJacobi…
+ root2J.print("Solution x, Jacobian:");
+ rosenbrock(root2J).print("Rosenbrock at x, Jacobian:");
+ cout << "It took " << ncalls << " function calls\n";
+
+ cout << "\nFinding the minumum of the Himmelblau's function:\n";
+ vec x3(2); x3[0] = 5.0f; x3[1] = 6.0f;
+ vec dx3(2); dx3[0] = 1e-6f; dx3[1] = 1e-6f;
+ ncalls = 0;
+ vec root3 = newton(himmelblauGrad, x3, dx3, eps*10.f);
+ root3.print("Solution x:");
+ himmelblau(root3).print("Himmelblau at x:");
+ cout << "It took " << ncalls << " function calls\n";
+
+ cout << "\nFinding the minumum of the Himmelblau's function, Jacobian matrix…
+ vec x3J(2); x3J[0] = 5.0f; x3J[1] = 6.0f;
+ vec dx3J(2); dx3J[0] = 1e-6f; dx3J[1] = 1e-6f;
+ ncalls = 0;
+ vec root3J = newtonJac(himmelblauGrad, x3, dx3, eps*10.f, himmelblauJacobian…
+ root3J.print("Solution x:");
+ himmelblau(root3J).print("Himmelblau at x, Jacobian:");
+ cout << "It took " << ncalls << " function calls\n";
+
+ // Return successfully
+ return 0;
+}
+
+void check(const bool statement)
+{
+ using std::cout;
+ if (statement == true)
+ cout << "\t\033[0;32mPassed\033[0m\n";
+ else
+ cout << "\t\033[1;31mFail!!\033[0m\n";
+}
diff --git a/roots/newton.cpp b/roots/newton.cpp
t@@ -0,0 +1,89 @@
+#include <functional>
+#include <armadillo>
+#include "qrfunc.h"
+
+using namespace arma;
+
+// Newton's method
+vec newton(std::function<vec(vec)> f, vec x_0, vec dx, double eps)
+{
+ vec x = x_0;
+ int n = x.size();
+ mat A(n,n);
+ vec y(n);
+ vec fx(n);
+ vec fy(n);
+ vec df(n);
+ vec Dx(n);
+
+ do {
+ fx = f(x);
+ for (int j=0; j<n; ++j) {
+ x[j] += dx[j];
+ df = f(x) - fx;
+
+ for (int i=0; i<n; ++i)
+ A(i,j) = df[i]/dx[j];
+
+ x[j] -= dx[j];
+ }
+
+ // Perform QR decomposition
+ QR qr(A);
+ vec fx_neg = -1.0f*fx;
+ Dx = qr.backsub(fx_neg);
+
+ double lambda = 2.0f;
+ do {
+ lambda /= 2.0f;
+ y = x + Dx * lambda;
+ fy = f(y);
+ } while (norm(fy,2.0f) > (1.0f-lambda/2.0f)*norm(fx,2.0f) && lambda > 0.02…
+
+ x = y;
+ fx = fy;
+ std::cerr << "Newton: f(x).norm() = " << norm(fx, 2.0f) << '\n';
+ } while (norm(Dx,2.0f) > norm(dx,2.0f) && norm(fx,2.0f) > eps);
+
+ // Return solution
+ return x;
+}
+
+// Newton's method - the user supplies his own derivatives
+vec newtonJac(std::function<vec(vec)> f, vec x_0, vec dx, double eps,
+ mat (*J)(vec))
+{
+ vec x = x_0;
+ int n = x.size();
+ vec y(n);
+ vec fx(n);
+ vec fy(n);
+ vec Dx(n);
+
+ fx = f(x);
+
+ do {
+
+ // Get Jacobian matrix
+ mat Jx = J(x_0);
+
+ // Perform QR decomposition
+ QR qr(Jx);
+ vec fx_neg = -1.0f*fx;
+ Dx = qr.backsub(fx_neg);
+
+ double lambda = 2.0f;
+ do {
+ lambda /= 2.0f;
+ y = x + Dx * lambda;
+ fy = f(y);
+ } while (norm(fy,2.0f) > (1.0f-lambda/2.0f)*norm(fx,2.0f) && lambda > 0.02…
+
+ x = y;
+ fx = fy;
+ std::cerr << "Newton: f(x).norm() = " << norm(fx, 2.0f) << '\n';
+ } while (norm(Dx,2.0f) > norm(dx,2.0f) && norm(fx,2.0f) > eps);
+
+ // Return solution
+ return x;
+}
diff --git a/roots/qrfunc.cpp b/roots/qrfunc.cpp
t@@ -0,0 +1,90 @@
+#include <iostream>
+#include <armadillo>
+#include "header.h"
+#include "qrfunc.h"
+
+// QR decomposition constructor
+QR::QR(arma::mat &A)
+ : n(A.n_cols),
+ A(A),
+ Q(A)
+{
+ // Initialize output structures
+ R = arma::zeros<arma::mat> (n,n);
+
+ // Perform QR decomposition straight away
+ decomp();
+}
+
+// Class deconstructor (equivalent to compiler destructor)
+QR::~QR() { };
+
+// Return system size
+Lengthtype QR::size()
+{
+ return n;
+}
+
+// QR decomposition function of Armadillo matrix.
+// Returns right matrix R, and modifies A into Q.
+// Uses Gram-Schmidt orthogonalization
+void QR::decomp()
+{
+ Floattype r, s;
+ Lengthtype j;
+ for (Lengthtype i=0; i<n; ++i) {
+ r = dot(Q.col(i), Q.col(i));
+ R(i,i) = sqrt(r);
+ Q.col(i) /= sqrt(r); // Normalization
+ for (j=i+1; j<n; ++j) {
+ s = dot(Q.col(i), Q.col(j));
+ Q.col(j) -= s*Q.col(i); // Orthogonalization
+ R(i,j) = s;
+ }
+ }
+}
+
+// Solve the square system of linear equations with back
+// substitution. T is an upper triangular matrix.
+arma::vec QR::backsub(arma::vec &b)
+{
+ Floattype tmpsum;
+ arma::vec x = Q.t() * b;
+ for (Lengthtype i=n-1; i>=0; --i) {
+ tmpsum = 0.0f;
+ for (Lengthtype k=i+1; k<n; ++k)
+ tmpsum += R(i,k) * x(k);
+
+ x(i) = 1.0f/R(i,i) * (x(i) - tmpsum);
+ }
+ return x;
+}
+
+// Calculate the (absolute value of the) determinant of
+// matrix A given the Q and R components.
+// det(A) = det(Q) * det(R), |det(Q) = 1|
+// => |det(A)| = |det(R)|
+Floattype QR::det()
+{
+ Floattype determinant = 1.0f;
+ for (Lengthtype i=0; i<n; ++i)
+ determinant *= R(i,i);
+ return fabs(determinant);
+}
+
+// Calculate the inverse of matrix A given the Q and R
+// components.
+arma::mat QR::inverse()
+{
+ arma::mat inv = arma::zeros<arma::mat> (n, n);
+ // In vector z, all elements are equal to 0, except z(i) = 1
+ arma::vec z = arma::zeros<arma::mat> (n);
+
+ for (Lengthtype i=0; i<n; ++i) {
+ z(i) = 1.0f; // Element i changed to 1
+ inv.col(i) = backsub(z);
+ z(i) = 0.0f; // Element i changed back to 0
+ }
+
+ return inv;
+}
diff --git a/roots/qrfunc.h b/roots/qrfunc.h
t@@ -0,0 +1,49 @@
+// Make sure header is only included once
+#ifndef qrfunc_h_
+#define qrfunc_h_
+
+#include <armadillo>
+#include "header.h"
+
+// QR structure
+class QR {
+ private:
+ // System size
+ const Lengthtype n;
+
+ public:
+ //// Data
+
+ // Input data
+ arma::mat A;
+
+ // QR decomposition matrices
+ arma::mat Q;
+ arma::mat R;
+
+ //// Prototype functions
+
+ // Constructor prototype
+ QR(arma::mat &A);
+
+ // Destructor
+ ~QR();
+
+ // Return system size
+ Lengthtype size();
+
+ // QR decomposition of Armadillo matrix A, returning R
+ // and modified A (=Q)
+ void decomp();
+
+ // Backsubstitution of triangular system
+ arma::vec backsub(arma::vec &b);
+
+ // Absolute value of the determinant of matrix R
+ Floattype det();
+
+ // Inverse of matrix A
+ arma::mat inverse();
+};
+
+#endif
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.