| 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 "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 <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 << <span class="Constant">&quo… | |
| +<span class="lnr"> 9 </span> <span class="Statement">else</span> | |
| +<span class="lnr">10 </span> std::cout << <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<std::complex<Floattype> > | |
| +<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<std::complex<Floattype> >… | |
| +<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 << <span class="Constant">"</spa… | |
| +<span class="lnr">26 </span> << <span class="Constant">"</spa… | |
| +<span class="lnr">27 </span> << id%n << <span class="Constan… | |
| +<span class="lnr">28 </span> cout << <span class="Constant">"Exami… | |
| +<span class="lnr">29 </span> << <span class="Constant">"with … | |
| +<span class="lnr">30 </span> | |
| +<span class="lnr">31 </span> cout << <span class="Constant">"</spa… | |
| +<span class="lnr">32 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">33 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">34 </span> cout << <span class="Constant">"Integ… | |
| +<span class="lnr">35 </span> Inttype n_eqs = <span class="Constant">2</span>;… | |
| +<span class="lnr">36 </span> vector<<span class="Type">complex</span><F… | |
| +<span class="lnr">37 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">38 </span> <span class="Type">complex</span><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">"funcA… | |
| +<span class="lnr">51 </span> | |
| +<span class="lnr">52 </span> <span class="Comment">// Report to stdout</span> | |
| +<span class="lnr">53 </span> cout << <span class="Constant">"ODE s… | |
| +<span class="lnr">54 </span> << realode.steps() << <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 << <span class="Constant">"</spa… | |
| +<span class="lnr">23 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">24 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">25 </span> cout << <span class="Constant">"Integ… | |
| +<span class="lnr">26 </span> Inttype n_eqs = <span class="Constant">2</span>;… | |
| +<span class="lnr">27 </span> vector<<span class="Type">complex</span><F… | |
| +<span class="lnr">28 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">29 </span> <span class="Type">complex</span><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">"funcB… | |
| +<span class="lnr">42 </span> | |
| +<span class="lnr">43 </span> <span class="Comment">// Report to stdout</span> | |
| +<span class="lnr">44 </span> cout << <span class="Constant">"ODE s… | |
| +<span class="lnr">45 </span> << imagode.steps() << <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 << <span class="Constant">"</spa… | |
| +<span class="lnr">23 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">24 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">25 </span> cout << <span class="Constant">"Integ… | |
| +<span class="lnr">26 </span> Inttype n_eqs = <span class="Constant">2</span>;… | |
| +<span class="lnr">27 </span> vector<<span class="Type">complex</span><F… | |
| +<span class="lnr">28 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">29 </span> <span class="Type">complex</span><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">"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 << <span class="Constant">"ODE s… | |
| +<span class="lnr">45 </span> << ode.steps() << <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 << <span class="Constant">"</spa… | |
| +<span class="lnr">25 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">26 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">27 </span> cout << <span class="Constant">"Integ… | |
| +<span class="lnr">28 </span> Inttype n_eqs = <span class="Constant">2</span>;… | |
| +<span class="lnr">29 </span> vector<<span class="Type">complex</span><F… | |
| +<span class="lnr">30 </span> <span class="Type">complex</span><Floattype&g… | |
| +<span class="lnr">31 </span> <span class="Type">complex</span><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<Floattype> precs; <span class="Comm… | |
| +<span class="lnr">37 </span> vector<Inttype> 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">"funcD.dat&… | |
| +<span class="lnr">55 </span> <span class="Statement">if</span> (!ost) { | |
| +<span class="lnr">56 </span> std::cerr << <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 << precs[i] << <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<std::complex<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<std::complex<… | |
| +<span class="lnr"> 48 </span> std::vector<std::complex<… | |
| +<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<… | |
| +<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<… | |
| +<span class="lnr"> 56 </span> <span class="Type">const</span> std::vector<… | |
| +<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<std::complex<Floattype> &g… | |
| +<span class="lnr"> 68 </span> std::vector<std::complex<Floattype> &g… | |
| +<span class="lnr"> 69 </span> | |
| +<span class="lnr"> 70 </span> std::complex<Floattype> x; | |
| +<span class="lnr"> 71 </span> Floattype err, tol; | |
| +<span class="lnr"> 72 </span> std::vector<std::complex<Floattype> &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() < 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() > 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 < 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 << <span class="Constant">&… | |
| +<span class="lnr">100 </span> << <span class="Constant">&… | |
| +<span class="lnr">101 </span> << <span class="Constant">&… | |
| +<span class="lnr">102 </span> << <span class="Constant">&… | |
| +<span class="lnr">103 </span> << <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<Floattype> multiplicator (… | |
| +<span class="lnr">109 </span> <span class="Statement">if</span> (err > <… | |
| +<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 << x_list[i] << <span c… | |
| +<span class="lnr">127 </span> <span class="Statement">for</span> (Inttype j… | |
| +<span class="lnr">128 </span> std::cout << y_list[i][j] << <s… | |
| +<span class="lnr">129 </span> std::cout << <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 << <span class="Constant">&qu… | |
| +<span class="lnr">142 </span> << filename << <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 << x_list[i].real() << … | |
| +<span class="lnr">149 </span> outstream << x_list[i].imag() << … | |
| +<span class="lnr">150 </span> <span class="Statement">for</span> (Inttype j… | |
| +<span class="lnr">151 </span> outstream << y_list[i][j].real() <… | |
| +<span class="lnr">152 </span> outstream << y_list[i][j].imag() <… | |
| +<span class="lnr">153 </span> } | |
| +<span class="lnr">154 </span> outstream << <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 << <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<std::complex<Floattype> &… | |
| +<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<std::complex<Floattype> &… | |
| +<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<Floattype> 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<std::vector<std::complex<… | |
| +<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<std::comple… | |
| +<span class="lnr">48 </span> std::vector<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<std::complex<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">"x.real"… | |
| +<span class="lnr">4 </span>set ylabel <span class="Constant">"y.real"… | |
| +<span class="lnr">5 </span>set title <span class="Constant">"Integration … | |
| +<span class="lnr">6 </span>set grid | |
| +<span class="lnr">7 </span>plot <span class="Constant">"funcA.dat"</… | |
| +<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">"x.imag"… | |
| +<span class="lnr">4 </span>set ylabel <span class="Constant">"y.imag"… | |
| +<span class="lnr">5 </span>set title <span class="Constant">"Integration … | |
| +<span class="lnr">6 </span>set grid | |
| +<span class="lnr">7 </span>plot <span class="Constant">"funcB.dat"</… | |
| +<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">"x.r"</… | |
| +<span class="lnr">4 </span>set ylabel <span class="Constant">"x.i"</… | |
| +<span class="lnr">5 </span>set zlabel <span class="Constant">"y"</sp… | |
| +<span class="lnr">6 </span>set title <span class="Constant">"Integration … | |
| +<span class="lnr">7 </span>set grid | |
| +<span class="lnr">8 </span>splot <span class="Constant">"funcC.dat"<… | |
| +<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">"Precision&q… | |
| +<span class="lnr">4 </span>set ylabel <span class="Constant">"No. of step… | |
| +<span class="lnr">5 </span>set title <span class="Constant">"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">"funcD.dat"</… | |
| +<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<std::complex<Floattype> > | |
| +<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<std::complex<Floattype> >… | |
| +<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<std::complex<Floattype> > | |
| +<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<std::complex<Floattype> >… | |
| +<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<std::complex<Floattype> > | |
| +<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<std::complex<Floattype> >… | |
| +<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<std::complex<Floattype> > | |
| +<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<std::complex<Floattype> >… | |
| +<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<std::complex<Floattype> > | |
| +<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<std::complex<Floattype> >… | |
| +<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<std::complex<Floattype> > | |
| +<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<std::complex<Floattype> >… | |
| +<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 |