added files for performance measurement and plotting
This commit is contained in:
parent
0ad5239581
commit
17acf32b06
|
|
@ -13,6 +13,7 @@
|
||||||
*.auxlock
|
*.auxlock
|
||||||
*.dpth
|
*.dpth
|
||||||
*.md5
|
*.md5
|
||||||
|
*.csv
|
||||||
|
|
||||||
build/*
|
build/*
|
||||||
TexCode/*
|
TexCode/*
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
namespace fsi {
|
namespace fsi {
|
||||||
|
|
||||||
size_t binom(size_t n, size_t k) {
|
inline size_t binom(size_t n, size_t k) {
|
||||||
if (2 * k > n) {
|
if (2 * k > n) {
|
||||||
k = n - k;
|
k = n - k;
|
||||||
}
|
}
|
||||||
|
|
@ -26,6 +26,47 @@ size_t binom(size_t n, size_t k) {
|
||||||
return prod;
|
return prod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename JumpIt>
|
||||||
|
class StepIterator {
|
||||||
|
JumpIt jump_it;
|
||||||
|
size_t first_dim_value;
|
||||||
|
size_t last_dim_value;
|
||||||
|
size_t last_dim_count;
|
||||||
|
size_t tail_dims_counter;
|
||||||
|
|
||||||
|
public:
|
||||||
|
StepIterator(JumpIt jump_it)
|
||||||
|
: jump_it(jump_it),
|
||||||
|
first_dim_value(0),
|
||||||
|
last_dim_value(0),
|
||||||
|
last_dim_count(jump_it.lastDimensionCount()),
|
||||||
|
tail_dims_counter(0){};
|
||||||
|
|
||||||
|
void next() {
|
||||||
|
tail_dims_counter += 1;
|
||||||
|
last_dim_value += 1;
|
||||||
|
if (last_dim_value >= last_dim_count) {
|
||||||
|
last_dim_value = 0;
|
||||||
|
jump_it.next();
|
||||||
|
if (jump_it.firstIndex() != first_dim_value) {
|
||||||
|
first_dim_value = jump_it.firstIndex();
|
||||||
|
tail_dims_counter = 0;
|
||||||
|
}
|
||||||
|
last_dim_count = jump_it.lastDimensionCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool done() { return jump_it.done(); }
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
jump_it.reset();
|
||||||
|
first_dim_value = 0;
|
||||||
|
last_dim_value = 0;
|
||||||
|
last_dim_count = jump_it.lastDimensionCount();
|
||||||
|
tail_dims_counter = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <size_t d>
|
template <size_t d>
|
||||||
class TemplateBoundedSumIterator {
|
class TemplateBoundedSumIterator {
|
||||||
size_t bound;
|
size_t bound;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
// Copyright (C) 2008-today The SG++ project
|
||||||
|
// This file is part of the SG++ project. For conditions of distribution and
|
||||||
|
// use, please see the copyright notice provided with SG++ or at
|
||||||
|
// sgpp.sparsegrids.org
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Interpolation.hpp>
|
||||||
|
#include <Iterators.hpp>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
inline double f(std::vector<double> point) {
|
||||||
|
double prod = 1.0;
|
||||||
|
for (size_t dim = 0; dim < point.size(); ++dim) {
|
||||||
|
prod *= point[dim];
|
||||||
|
}
|
||||||
|
return prod;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GoldenPointDistribution {
|
||||||
|
static constexpr double golden_ratio = 0.5 * (1.0 + sqrt(5));
|
||||||
|
|
||||||
|
public:
|
||||||
|
double operator()(size_t idx) {
|
||||||
|
double value = (idx + 1) * golden_ratio;
|
||||||
|
return value - int(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SimplePointDistribution {
|
||||||
|
public:
|
||||||
|
double operator()(size_t idx) {
|
||||||
|
if (idx == 0) {
|
||||||
|
return 0.0;
|
||||||
|
} else if (idx == 1) {
|
||||||
|
return 1.0;
|
||||||
|
} else {
|
||||||
|
return 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MonomialFunctions {
|
||||||
|
public:
|
||||||
|
std::function<double(double)> operator()(size_t idx) {
|
||||||
|
return [=](double x) { return pow(x, idx); };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
|
||||||
|
os << "[";
|
||||||
|
for (auto ii = v.begin(); ii != v.end(); ++ii) {
|
||||||
|
os << " " << *ii;
|
||||||
|
}
|
||||||
|
os << " ]";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &os, fsi::MultiDimVector const &v) {
|
||||||
|
for (size_t i = 0; i < v.data.size(); ++i) {
|
||||||
|
std::cout << v.data[i] << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: refactoring:
|
||||||
|
/**
|
||||||
|
* - Interface for MultiDimVector
|
||||||
|
* - Separate Functions for L- and U-Multiplication, Creation of LU decomposition, computation of
|
||||||
|
* function values
|
||||||
|
* - Pass a callback function to iterator instead of calling it.next() - this might improve the
|
||||||
|
* vector functions (could be made recursive or even loops for fixed dimension implementation)
|
||||||
|
* - Typed interface?
|
||||||
|
* - Tests?
|
||||||
|
* - More point distributions / Basis functions?
|
||||||
|
* - Forward evaluation?
|
||||||
|
* - Computation of derivatives?
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline double measure_execution_time(std::function<void()> f) {
|
||||||
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
f();
|
||||||
|
auto finish = std::chrono::high_resolution_clock::now();
|
||||||
|
std::chrono::duration<double> elapsed = finish - start;
|
||||||
|
return elapsed.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Timer {
|
||||||
|
std::chrono::system_clock::time_point start;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Timer() : start(std::chrono::high_resolution_clock::now()){};
|
||||||
|
void reset() { start = std::chrono::high_resolution_clock::now(); }
|
||||||
|
double elapsed() {
|
||||||
|
auto finish = std::chrono::high_resolution_clock::now();
|
||||||
|
std::chrono::duration<double> elapsed = finish - start;
|
||||||
|
return elapsed.count();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void measurePerformance();
|
||||||
106
test/main.cpp
106
test/main.cpp
|
|
@ -13,105 +13,9 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
==============================================================================*/
|
==============================================================================*/
|
||||||
|
|
||||||
#include <Interpolation.hpp>
|
#include "common.hpp"
|
||||||
#include <Iterators.hpp>
|
|
||||||
#include <chrono>
|
|
||||||
#include <cmath>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
double f(std::vector<double> point) {
|
void runFunctions() {
|
||||||
double prod = 1.0;
|
|
||||||
for (size_t dim = 0; dim < point.size(); ++dim) {
|
|
||||||
prod *= point[dim];
|
|
||||||
}
|
|
||||||
return prod;
|
|
||||||
}
|
|
||||||
|
|
||||||
class GoldenPointDistribution {
|
|
||||||
static constexpr double golden_ratio = 0.5 * (1.0 + sqrt(5));
|
|
||||||
|
|
||||||
public:
|
|
||||||
double operator()(size_t idx) {
|
|
||||||
double value = (idx + 1) * golden_ratio;
|
|
||||||
return value - int(value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SimplePointDistribution {
|
|
||||||
public:
|
|
||||||
double operator()(size_t idx) {
|
|
||||||
if (idx == 0) {
|
|
||||||
return 0.0;
|
|
||||||
} else if (idx == 1) {
|
|
||||||
return 1.0;
|
|
||||||
} else {
|
|
||||||
return 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MonomialFunctions {
|
|
||||||
public:
|
|
||||||
std::function<double(double)> operator()(size_t idx) {
|
|
||||||
return [=](double x) { return pow(x, idx); };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
|
|
||||||
os << "[";
|
|
||||||
for (auto ii = v.begin(); ii != v.end(); ++ii) {
|
|
||||||
os << " " << *ii;
|
|
||||||
}
|
|
||||||
os << " ]";
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, fsi::MultiDimVector const &v) {
|
|
||||||
for (size_t i = 0; i < v.data.size(); ++i) {
|
|
||||||
std::cout << v.data[i] << "\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: refactoring:
|
|
||||||
/**
|
|
||||||
* - Interface for MultiDimVector
|
|
||||||
* - Separate Functions for L- and U-Multiplication, Creation of LU decomposition, computation of
|
|
||||||
* function values
|
|
||||||
* - Pass a callback function to iterator instead of calling it.next() - this might improve the
|
|
||||||
* vector functions (could be made recursive or even loops for fixed dimension implementation)
|
|
||||||
* - Typed interface?
|
|
||||||
* - Tests?
|
|
||||||
* - More point distributions / Basis functions?
|
|
||||||
* - Forward evaluation?
|
|
||||||
* - Computation of derivatives?
|
|
||||||
*/
|
|
||||||
|
|
||||||
double measure_execution_time(std::function<void()> f) {
|
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
|
||||||
f();
|
|
||||||
auto finish = std::chrono::high_resolution_clock::now();
|
|
||||||
std::chrono::duration<double> elapsed = finish - start;
|
|
||||||
return elapsed.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Timer {
|
|
||||||
std::chrono::system_clock::time_point start;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Timer() : start(std::chrono::high_resolution_clock::now()){};
|
|
||||||
void reset() { start = std::chrono::high_resolution_clock::now(); }
|
|
||||||
double elapsed() {
|
|
||||||
auto finish = std::chrono::high_resolution_clock::now();
|
|
||||||
std::chrono::duration<double> elapsed = finish - start;
|
|
||||||
return elapsed.count();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// using namespace fsi;
|
|
||||||
int main() {
|
|
||||||
constexpr size_t d = 8;
|
constexpr size_t d = 8;
|
||||||
size_t bound = 24;
|
size_t bound = 24;
|
||||||
fsi::TemplateBoundedSumIterator<d> it(bound);
|
fsi::TemplateBoundedSumIterator<d> it(bound);
|
||||||
|
|
@ -146,3 +50,9 @@ int main() {
|
||||||
// std::cout << result.data[i] << "\n\n";
|
// std::cout << result.data[i] << "\n\n";
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// using namespace fsi;
|
||||||
|
int main() {
|
||||||
|
// runFunctions();
|
||||||
|
measurePerformance();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* Copyright 2019 The fast_sparse_interpolation Authors. All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==============================================================================*/
|
||||||
|
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
double measureRuntime(std::function<double()> f, size_t k = 3) {
|
||||||
|
size_t n = 2 * k + 1;
|
||||||
|
|
||||||
|
std::vector<double> singleResults(n);
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
singleResults[i] = f();
|
||||||
|
}
|
||||||
|
std::sort(singleResults.begin(), singleResults.end());
|
||||||
|
// return (singleResults[k-1] + singleResults[k] +
|
||||||
|
// singleResults[k+1]) / 3.0;
|
||||||
|
return singleResults[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
void measurePerformance() {
|
||||||
|
// std::vector < size_t > dimensions = {2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64 };
|
||||||
|
// std::vector<size_t> dimensions = {5, 10};
|
||||||
|
|
||||||
|
std::vector<size_t> dimensions = {2, 4, 8, 16, 32};
|
||||||
|
// size_t maxNumPoints = 20000000;
|
||||||
|
size_t maxNumPoints = 500000;
|
||||||
|
|
||||||
|
std::ostringstream stream;
|
||||||
|
|
||||||
|
size_t approxNumSteps = 8;
|
||||||
|
size_t k = 1;
|
||||||
|
|
||||||
|
for (size_t d : dimensions) {
|
||||||
|
std::cout << "Dimension: " << d << "\n";
|
||||||
|
size_t maxBound = 0;
|
||||||
|
|
||||||
|
while (fsi::binom(maxBound + d, d) <= maxNumPoints) {
|
||||||
|
maxBound += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t stepsize = maxBound / approxNumSteps + 1;
|
||||||
|
|
||||||
|
for (size_t bound = 2; bound < maxBound; bound += stepsize) {
|
||||||
|
std::cout << "Bound: " << bound << "\n";
|
||||||
|
double runtime = measureRuntime(
|
||||||
|
[&]() {
|
||||||
|
fsi::BoundedSumIterator it(d, bound);
|
||||||
|
std::vector<MonomialFunctions> phi(d);
|
||||||
|
std::vector<GoldenPointDistribution> x(d);
|
||||||
|
|
||||||
|
auto rhs = evaluateFunction(it, f, x);
|
||||||
|
auto op = createInterpolationOperator(it, phi, x);
|
||||||
|
|
||||||
|
Timer timer;
|
||||||
|
op.solve(rhs);
|
||||||
|
double time = timer.elapsed();
|
||||||
|
std::cout << "Time for solve(): " << time << " s\n";
|
||||||
|
return time;
|
||||||
|
},
|
||||||
|
k);
|
||||||
|
|
||||||
|
stream << d << ", " << bound << ", " << fsi::binom(bound + d, d) << ", " << runtime << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream file("performance_data.csv");
|
||||||
|
file << stream.str();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from mpl_toolkits.mplot3d import Axes3D
|
||||||
|
import numpy as np
|
||||||
|
import os.path
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
def readFromFile(filename):
|
||||||
|
if not os.path.isfile(filename):
|
||||||
|
return ''
|
||||||
|
|
||||||
|
file = open(filename, 'r')
|
||||||
|
result = file.read()
|
||||||
|
file.close()
|
||||||
|
return result
|
||||||
|
|
||||||
|
datastr = readFromFile("../performance_data.csv")
|
||||||
|
rows = datastr.split("\n")[:-1]
|
||||||
|
values = np.array([[float(s) for s in r.split(', ')] for r in rows])
|
||||||
|
# print(values)
|
||||||
|
|
||||||
|
dimensions = values[:, 0]
|
||||||
|
bounds = values[:, 1]
|
||||||
|
points = values[:, 2]
|
||||||
|
times = values[:, 3]
|
||||||
|
|
||||||
|
fig = plt.figure()
|
||||||
|
ax = fig.add_subplot(1,1,1, projection='3d')
|
||||||
|
surf = ax.plot_trisurf(np.log2(dimensions), np.log2(points), np.log10(times), cmap='viridis', edgecolor='none')
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue