To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

Commit 54f25445 authored by Donjan Rodic's avatar Donjan Rodic

added examples for week 02

parent 5ff6677c
#include <iostream>
#include <functional>
int f(int x) { return x+1;}
int main()
{
// function pointer
int (*p1)(int) = f;
// easier function pointer with auto
auto p2 =f;
// or here we could just have used std::function
std::function<int(int)> p3=f;
std::cout << (*p1)(42) << std::endl;
std::cout << (*p2)(42) << std::endl;
std::cout << p3(42) << std::endl;
}
#include "simpson.hpp"
#include <iostream>
#include <cmath>
// a function with two variables
double expax(double a, double x)
{
return std::exp(a*x);
}
int main()
{
// where do we set a?
std::cout << simpson(expax,0.,1.,100) << std::endl;
return 0;
}
#include "simpson.hpp"
#include <iostream>
#include <cmath>
#include <functional>
// a function with two variables
double expax(double a, double x)
{
return std::exp(a*x);
}
int main()
{
using namespace std::placeholders;
double a=3.4;
// bind one argument
// _1, _2, .... are used for unbound arguments of the resulting function
auto f = std::bind(expax,3.4,_1);
std::cout << simpson(f,0.,1.,100) << std::endl;
return 0;
}
#include "simpson.hpp"
#include <iostream>
#include <cmath>
// a function object for exp(a*x)
class expax
{
public:
// set the parameter a in the constructor
expax(double a) : a_(a) {}
// the function call operator calculates the function
double operator()(double x) { return std::exp(a_*x);}
private:
double a_; // the fixed parameter a
};
int main()
{
double a=3.4;
std::cout << simpson(expax(a),0.,1.,100) << std::endl;
return 0;
}
#include "simpson.hpp"
#include <iostream>
#include <cmath>
// an ugly global variable
double a;
// the function to be integrated
double expax(double x)
{
return std::exp(a*x);
}
int main()
{
a=3.4;
std::cout << simpson(expax,0.,1.,100) << std::endl;
return 0;
}
#include "simpson.hpp"
#include <iostream>
#include <cmath>
int main()
{
double a=3.4;
// create a lambda function
// [=] indicates that the variable a should be used inside the lambda
auto f = [=] (double x) { return std::exp(a*x); };
std::cout << simpson(f,0.,1.,100) << std::endl;
return 0;
}
#include "simpson.hpp"
#include <iostream>
#include <cmath>
int main()
{
double a=3.4;
std::cout << simpson([=] (double x) { return std::exp(a*x); },0.,1.,100)
<< std::endl;
return 0;
}
#include <iostream>
int main()
{
// create a function and store a pointer to it in f
auto f = []() {std::cout << "Hello world!\n";};
// call the function
f();
}
\ No newline at end of file
#include <iostream>
#include <thread>
int main()
{
// create a function and store a pointer to it in f
auto f = []() {std::cout << "Hello world!\n";};
// call the function in a thread
std::thread t(f);
t.join();
}
\ No newline at end of file
#include <random>
#include <iostream>
template <class Engine, class Distribution>
void print_random_numnbers(Engine& eng, Distribution& dist, std::string doc)
{
std::cout << "\n" << doc << "\n";
for (int i=0; i<10; ++i)
std::cout << dist(eng) << "\n";
}
int main()
{
// create two engines
std::minstd_rand lcg;
std::mt19937 mt;
// seed the Mersenne twister using the lcg.
// This can be used for stochastic seeding of multiple generators in parallel
mt.seed(lcg());
std::cout << lcg() << " " << mt() << std::endl;
// create various distributions
std::uniform_int_distribution<int> uint_d(0,10);
std::uniform_real_distribution<double> ureal_d(0.,10.);
std::normal_distribution<double> normal_d(0.,4.);
std::exponential_distribution<double> exp_d(1.);
print_random_numnbers(mt,uint_d,"uniform int");
print_random_numnbers(mt,ureal_d,"uniform real");
print_random_numnbers(mt,normal_d,"normal");
print_random_numnbers(mt,exp_d,"exponential");
return 0;
}
\ No newline at end of file
#include <random>
#include <iostream>
int main()
{
// create an engine
std::mt19937 mt;
// seed the generator
mt.seed(42);
// create four distributions
std::uniform_int_distribution<int> uint_d(0,10);
std::uniform_real_distribution<double> ureal_d(0.,10.);
std::normal_distribution<double> normal_d(0.,4.);
std::exponential_distribution<double> exp_d(1.);
// create random numbers with each of these distributions:
std::cout << uint_d(mt) << "\n";
std::cout << ureal_d(mt) << "\n";
std::cout << normal_d(mt) << "\n";
std::cout << exp_d(mt) << "\n";
return 0;
}
\ No newline at end of file
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include <cassert>
#include <functional>
inline double simpson(std::function<double(double)> f, double a, double b, unsigned int N)
{
assert (b>=a);
assert (N!=0u);
double h=(b-a)/N;
// boundary values
double result = ( f(a) + 4*f(a+h/2) + f(b) ) / 2.0;
// values between boundaries
for ( unsigned int i = 1; i <= N-1; ++i )
result += f(a+i*h) + 2*f(a+(i+0.5)*h);
return result * h / 3.0;
}
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include <iostream>
#include <chrono>
#include <ctime>
int fibonacci(int n)
{
if (n < 3) return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
int main()
{
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();
int result = fibonacci(42);
end = std::chrono::system_clock::now();
int elapsed_seconds = std::chrono::duration_cast<std::chrono::milliseconds>
(end-start).count();
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
std::cout << "finished computation at " << std::ctime(&end_time)
<< "elapsed time: " << elapsed_seconds << "ms\n";
}
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include <iostream>
#include <chrono>
int fibonacci(int n)
{
if (n < 3) return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
int main()
{
std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
start = std::chrono::high_resolution_clock::now();
int result = fibonacci(42);
end = std::chrono::high_resolution_clock::now();
int elapsed_microseconds = std::chrono::duration_cast<std::chrono::microseconds>
(end-start).count();
std::cout << "elapsed time: " << elapsed_microseconds << "ms\n";
}
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include <iostream>
#include <thread>
#include <vector>
std::once_flag printonce_flag;
void printonce()
{
std::cout << "This should be printed only once\n";
}
int main()
{
std::vector<std::thread> threads;
for (int n = 0; n < 10; ++n)
threads.push_back(
std::thread([&](){std::call_once(printonce_flag,printonce);}));
for (std::thread& t : threads)
t.join();
// and again
for (int n = 0; n < 10; ++n)
threads[n] =
std::thread([&](){std::call_once(printonce_flag,printonce);});
for (std::thread& t : threads)
t.join();
// and again
std::call_once(printonce_flag,printonce);
}
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include <iostream>
#include <thread>
#include <vector>
void printer( int n )
{
for ( int i = 0; i < 100; ++i)
std::cout << "do not garble thread " << n << ": " << i << std::endl;
}
int main()
{
std::vector<std::thread> threads;
for (int n = 1; n < 10; ++n)
threads.push_back(std::thread(printer, n));
for (std::thread& t : threads)
t.join();
}
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include <vector>
#include <iostream>
#include <thread>
#include <numeric>
#include <iomanip>
// sum terms [i-j) of the power series for pi/4
void sumterms(long double& sum, std::size_t i, std::size_t j)
{
sum = 0.0;
for (std::size_t t = i; t < j; ++t)
sum += (1.0 - 2* (t % 2)) / (2*t + 1);
}
int main()
{
// decide how many threads to use
std::size_t const nthreads = std::max(1u, std::thread::hardware_concurrency());
std::vector<std::thread> threads(nthreads);
std::vector<long double> results(nthreads);
unsigned long const nterms = 100000000;
long double const step = (nterms+0.5l) / nthreads;
for (unsigned i = 0; i < nthreads; ++i)
threads[i] = std::thread(sumterms,std::ref(results[i]), i * step, (i+1) * step);
for (std::thread& t : threads)
t.join();
long double pi = 4 * std::accumulate(results.begin(), results.end(), 0. );
std::cout << "pi=" << std::setprecision(18) << pi << std::endl;
return 0;
}
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include <vector>
#include <iostream>
#include <thread>
#include <iomanip>
// sum terms [i-j) of the power series for pi/4
void sumterms(long double& sum, std::size_t i, std::size_t j)
{
for (std::size_t t = i; t < j; ++t)
sum += (1.0 - 2* (t % 2)) / (2*t + 1);
}
int main()
{
// decide how many threads to use
std::size_t const nthreads = std::max(1u, std::thread::hardware_concurrency());
std::vector<std::thread> threads(nthreads);
// let us just use a single result
long double result=0.;
unsigned long const nterms = 100000000;
long double const step = (nterms+0.5l) / nthreads;
for (unsigned i = 0; i < nthreads; ++i)
threads[i] = std::thread(sumterms,std::ref(result), i * step, (i+1) * step);
for (std::thread& t : threads)
t.join();
std::cout << "pi=" << std::setprecision(18) << 4.*result << std::endl;
return 0;
}
\ No newline at end of file
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include <vector>
#include <iostream>
#include <thread>
#include <iomanip>
#include <mutex>
// sum terms [i-j) of the power series for pi/4
void sumterms(std::pair<long double, std::mutex>& result, std::size_t i, std::size_t j)
{
long double sum=0.;
for (std::size_t t = i; t < j; ++t)
sum += (1.0 - 2* (t % 2)) / (2*t + 1);
std::lock_guard<std::mutex> l (result.second);
result.first += sum;
}
int main()
{
// decide how many threads to use
std::size_t const nthreads = std::max(1u, std::thread::hardware_concurrency());
std::vector<std::thread> threads(nthreads);
// let us just use a single result
std::pair<long double, std::mutex> result;
result.first = 0.;
unsigned long const nterms = 100000000;
long double const step = (nterms+0.5l) / nthreads;
for (unsigned i = 0; i < nthreads; ++i)
threads[i] = std::thread(sumterms,std::ref(result), i * step, (i+1) * step);
for (std::thread& t : threads)
t.join();
// no need to lock here
std::cout << "pi=" << std::setprecision(18) << 4.*result.first << std::endl;
return 0;
}
\ No newline at end of file
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include <cassert>
#include <functional>
inline double simpson(std::function<double(double)> f, double a, double b, unsigned int N)
{
assert (b>=a);
assert (N!=0u);
double h=(b-a)/N;
// boundary values
double result = ( f(a) + 4*f(a+h/2) + f(b) ) / 2.0;
// values between boundaries
for ( unsigned int i = 1; i <= N-1; ++i )
result += f(a+i*h) + 2*f(a+(i+0.5)*h);
return result * h / 3.0;
}
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include "simpson.hpp"
#include <cmath>
#include <iostream>
// The function to integrate
double func(double x)
{
return x * std::sin(x);
}
int main()
{
double a; // lower bound of integration
double b; // upper bound of integration
unsigned int nsteps; // number of subintervals for integration
// read the parameters
std::cin >> a >> b >> nsteps;
// print the result
std::cout << simpson(func,a,b,nsteps) << std::endl;
return 0;
}
\ No newline at end of file
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include "simpson.hpp"
#include <cmath>
#include <iostream>
#include <thread>
// The function to integrate
double func(double x)
{
return x * std::sin(x);
}
int main()
{
double a; // lower bound of integration
double b; // upper bound of integration
unsigned int nsteps; // number of subintervals for integration
// read the parameters
std::cin >> a >> b >> nsteps;
double result1; // the integral of the first half
// spawn a thread for the first half of the interval
std::thread t( [&] () { result1 = simpson(func,a,a+(b-a)/2.,nsteps/2);} );
// locally integrate the second half
double result2 = simpson(func,a+(b-a)/2.,b,nsteps/2);
t.join(); // wait for the thread to join
std::cout << result1 + result2 << std::endl;
return 0;
}
\ No newline at end of file
// Example codes for HPC course
// (c) 2012 Matthias Troyer, ETH Zurich
#include "simpson.hpp"
#include <cmath>
#include <iostream>
#include <thread>
#include <future>
// The function to integrate
double func(double x)
{
return x * std::sin(x);
}
int main()
{
double a; // lower bound of integration
double b; // upper bound of integration
unsigned int nsteps; // number of subintervals for integration
// read the parameters
std::cin >> a >> b >> nsteps;
// create a packaged task
std::packaged_task<double()> pt(std::bind(simpson,func,a,a+(b-a)/2.,nsteps/2));
std::future<double> fi = pt.get_future(); // get the future return value
std::thread t (std::move(pt)); // launch the thread
// locally integrate the second half
double result = simpson(func,a+(b-a)/2.,b,nsteps/2);