...
 
Commits (8)
......@@ -5,16 +5,24 @@ set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
find_package(OpenMP)
add_executable(dynamicsystems main.cpp compute.cpp picture.cpp)
add_executable(dynamicsystems-cli cli.cpp compute.cpp picture.cpp)
find_package(FLTK)
find_package(OpenGL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${-lfltk_images} ${-lfltk_png}")
find_package(PNG REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
add_executable(dynamicsystems-gui gui.cpp compute.cpp picture.cpp)
target_link_libraries(dynamicsystems-gui ${FLTK_LIBRARIES} ${OPENGL_LIBRARIES} ${PNG_LIBRARY})
if(OPENMP_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
find_package(PNG REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
find_package(Boost REQUIRED COMPONENTS program_options)
target_include_directories(dynamicsystems PRIVATE ${Boost_INCLUDE_DIR})
target_link_libraries(dynamicsystems PRIVATE ${PNG_LIBRARY} ${Boost_LIBRARIES})
target_include_directories(dynamicsystems-cli PRIVATE ${Boost_INCLUDE_DIR})
target_link_libraries(dynamicsystems-cli PRIVATE ${PNG_LIBRARY} ${Boost_LIBRARIES})
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
......
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cmath>
#include <fstream>
#include <iostream>
#include <random>
#include <sstream>
#include <vector>
#include <boost/program_options.hpp>
#include <png.h>
#include "colormaps.hpp"
#include "compute.hpp"
#include "picture.hpp"
int main(int argc, char* argv[]) {
// get arguments from CLI
......@@ -28,7 +17,7 @@ int main(int argc, char* argv[]) {
float betamax;
int beta_num_intervals;
int num_seedpoints;
bool output;
bool output_csv;
std::vector<float> seedpoints;
namespace po = boost::program_options;
......@@ -42,7 +31,7 @@ int main(int argc, char* argv[]) {
" width of image (alpha resolution)")
("height,h", po::value<int>(&beta_num_intervals)->default_value(100),
" height of image (beta resolution)")
("threshold,s", po::value<float>(&threshold)->default_value(1),
("threshold,t", po::value<float>(&threshold)->default_value(1),
" Threshold above that computation is stopped")
("amin,a", po::value<float>(&alphamin)->default_value(0),
" alpha lower bound")
......@@ -52,11 +41,11 @@ int main(int argc, char* argv[]) {
" beta lower bound")
("bmax,B", po::value<float>(&betamax)->default_value(1),
" beta upper bound")
("num_seedpoints,N", po::value<int>(&num_seedpoints)->default_value(8),
("num_seedpoints,m", po::value<int>(&num_seedpoints)->default_value(8),
" Number of seedpoints (uniformly distributed in (0,1) )")
("seedpoints,S", po::value<std::vector<float>>(&seedpoints)->multitoken(),
" Values for explicit seedpoints")
("outputcsv,O", po::value<bool>(&output)->default_value(false),
("csv,O", po::value<bool>(&output_csv)->default_value(false),
" Boolean flag for output a csv file")
;
......@@ -82,84 +71,18 @@ int main(int argc, char* argv[]) {
return -1;
}
compute_all(
num_iterations,
threshold,
alphamin,
alphamax,
alpha_num_intervals,
betamin,
betamax,
beta_num_intervals,
num_seedpoints,
output_csv,
seedpoints
);
// these are computed
int alpha_num_params = alpha_num_intervals + 1;
float alpha_interval_size = (alphamax - alphamin) / (alpha_num_intervals);
int beta_num_params = beta_num_intervals + 1;
float beta_interval_size = (betamax - betamin) / (beta_num_intervals);
// fill prametervectors alpha and beta
aligned_vector<float> alphas(alpha_num_params);
float* alphasp = alphas.data();
#pragma omp simd aligned(alphasp : 64)
for (int i = 0; i < alpha_num_params; i++) {
alphasp[i] = alphamin + i * alpha_interval_size;
}
aligned_vector<float> betas(beta_num_params);
float* betasp = betas.data();
#pragma omp simd aligned(betasp : 64)
for (int i = 0; i < beta_num_params; i++) {
betasp[i] = betamin + i * beta_interval_size;
}
// Initialization and output of seedpoints
std::cout << "Following seedpoints are used for computation:" << std::endl;
aligned_vector<float> x_start(num_seedpoints);
aligned_vector<float> y_start(num_seedpoints);
for (int i = 1; i < num_seedpoints - seedpoints.size() + 1; ++i) {
x_start[i - 1] = 0.5f * static_cast<float>(i) / (num_seedpoints - seedpoints.size() + 1);
y_start[i - 1] = 0;
std::cout << x_start[i - 1] << ", ";
}
for (int i = 0; i < seedpoints.size(); ++i) {
x_start[num_seedpoints - seedpoints.size() + i] = seedpoints[i];
y_start[num_seedpoints - seedpoints.size() + i] = 0;
std::cout << x_start[num_seedpoints - seedpoints.size() + i] << ", ";
}
std::cout << '\n';
// Initialization pixel values and color vectors
aligned_vector<float> result(alpha_num_params * beta_num_params);
auto time_start = std::chrono::system_clock::now();
// Computation
#pragma omp parallel for schedule(dynamic)
for (int b = beta_num_params - 1; b >= 0; b--) {
for (int a = 0; a < alpha_num_params; a++) {
result[(beta_num_params - b - 1) * alpha_num_params + a] = compute(
alphas[a], betas[b], x_start, y_start, num_iterations, threshold);
}
}
auto time_end = std::chrono::system_clock::now();
float elapsed_seconds =
std::chrono::duration<float>(time_end - time_start).count();
std::cout << "TIME for computation: " << elapsed_seconds << std::endl;
time_start = std::chrono::system_clock::now();
write_png("picture.png", result.data(), threshold, alpha_num_params, beta_num_params);
time_end = std::chrono::system_clock::now();
elapsed_seconds = std::chrono::duration<float>(time_end - time_start).count();
std::cout << "TIME for picture: " << elapsed_seconds << std::endl;
// Generate output
if (output) {
time_start = std::chrono::system_clock::now();
// Output result into .csv
std::string file_result = "result.csv";
std::ofstream ostrm_csv(file_result);
ostrm_csv << "alpha beta value\n";
for (int b = beta_num_params - 1; b >= 0; b--) {
for (int a = 0; a < alpha_num_params; a++) {
ostrm_csv << alphas[a] << ' ' << betas[b] << ' '
<< result[(beta_num_params - b - 1) * alpha_num_params + a]
<< '\n';
}
}
time_end = std::chrono::system_clock::now();
elapsed_seconds = std::chrono::duration<float>(time_end - time_start).count();
std::cout << "TIME for csv: " << elapsed_seconds << std::endl;
}
}
......@@ -33,3 +33,100 @@ float compute(float alpha, float beta, aligned_vector<float> seed_x,
return d;
}
void compute_all(
int num_iterations,
float threshold,
float alphamin,
float alphamax,
int alpha_num_intervals,
float betamin,
float betamax,
int beta_num_intervals,
int num_seedpoints,
bool output_csv,
std::vector<float> seedpoints
) {
// these are computed
int alpha_num_params = alpha_num_intervals + 1;
float alpha_interval_size = (alphamax - alphamin) / (alpha_num_intervals);
int beta_num_params = beta_num_intervals + 1;
float beta_interval_size = (betamax - betamin) / (beta_num_intervals);
// fill prametervectors alpha and beta
aligned_vector<float> alphas(alpha_num_params);
float* alphasp = alphas.data();
#pragma omp simd aligned(alphasp : 64)
for (int i = 0; i < alpha_num_params; i++) {
alphasp[i] = alphamin + i * alpha_interval_size;
}
aligned_vector<float> betas(beta_num_params);
float* betasp = betas.data();
#pragma omp simd aligned(betasp : 64)
for (int i = 0; i < beta_num_params; i++) {
betasp[i] = betamin + i * beta_interval_size;
}
// Initialization and output of seedpoints
std::cout << "Following seedpoints are used for computation:" << std::endl;
aligned_vector<float> x_start(num_seedpoints);
aligned_vector<float> y_start(num_seedpoints);
for (int i = 1; i < num_seedpoints - seedpoints.size() + 1; ++i) {
x_start[i - 1] = 0.5f * static_cast<float>(i) / (num_seedpoints - seedpoints.size() + 1);
y_start[i - 1] = 0;
std::cout << x_start[i - 1] << ", ";
}
for (int i = 0; i < seedpoints.size(); ++i) {
x_start[num_seedpoints - seedpoints.size() + i] = seedpoints[i];
y_start[num_seedpoints - seedpoints.size() + i] = 0;
std::cout << x_start[num_seedpoints - seedpoints.size() + i] << ", ";
}
std::cout << '\n';
// Initialization pixel values and color vectors
aligned_vector<float> result(alpha_num_params * beta_num_params);
auto time_start = std::chrono::system_clock::now();
// Computation
#pragma omp parallel for schedule(dynamic)
for (int b = beta_num_params - 1; b >= 0; b--) {
for (int a = 0; a < alpha_num_params; a++) {
result[(beta_num_params - b - 1) * alpha_num_params + a] = compute(
alphas[a], betas[b], x_start, y_start, num_iterations, threshold);
}
}
auto time_end = std::chrono::system_clock::now();
float elapsed_seconds =
std::chrono::duration<float>(time_end - time_start).count();
std::cout << "TIME for computation: " << elapsed_seconds << std::endl;
time_start = std::chrono::system_clock::now();
write_png("picture.png", result.data(), threshold, alpha_num_params, beta_num_params);
time_end = std::chrono::system_clock::now();
elapsed_seconds = std::chrono::duration<float>(time_end - time_start).count();
std::cout << "TIME for picture: " << elapsed_seconds << std::endl;
// Generate output
if (output_csv) {
time_start = std::chrono::system_clock::now();
// Output result into .csv
std::string file_result = "result.csv";
std::ofstream ostrm_csv(file_result);
ostrm_csv << "alpha beta value\n";
for (int b = beta_num_params - 1; b >= 0; b--) {
for (int a = 0; a < alpha_num_params; a++) {
ostrm_csv << alphas[a] << ' ' << betas[b] << ' '
<< result[(beta_num_params - b - 1) * alpha_num_params + a]
<< '\n';
}
}
time_end = std::chrono::system_clock::now();
elapsed_seconds = std::chrono::duration<float>(time_end - time_start).count();
std::cout << "TIME for csv: " << elapsed_seconds << std::endl;
}
}
......@@ -2,9 +2,18 @@
#define COMPUTE_H
#include <boost/align/aligned_allocator.hpp>
#include <chrono>
#include <cmath>
#include <fstream>
#include <iostream>
#include <random>
#include <sstream>
#include <vector>
#include <png.h>
#include "colormaps.hpp"
#include "picture.hpp"
template <typename T>
using aligned_allocator = boost::alignment::aligned_allocator<T, 64>;
template <typename T>
......@@ -16,4 +25,19 @@ constexpr float TWO_PI = 2 * PI;
float compute(float alpha, float beta, aligned_vector<float> seed_x,
aligned_vector<float> seed_y, int num_iterations,
float threshold);
void compute_all(
int num_iterations,
float threshold,
float alphamin,
float alphamax,
int alpha_num_intervals,
float betamin,
float betamax,
int beta_num_intervals,
int num_seedpoints,
bool output_csv,
std::vector<float> seedpoints
);
#endif
#include <iostream>
#include <vector>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_PNG_Image.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Value_Input.H>
#include "compute.hpp"
class ScrollBox : public Fl_Box {
Fl_Scroll *scroll;
public:
void SetScroll(Fl_Scroll *val) {
scroll = val;
}
ScrollBox(int x,int y,int w,int h,const char*l=0) : Fl_Box(x,y,w,h,l) {
color(FL_BLUE);
box(FL_FLAT_BOX);
}
};
class SimpleWindow : public Fl_Window {
public:
SimpleWindow(int w, int h, const char* title);
~SimpleWindow();
Fl_Scroll* scroll;
ScrollBox* scrollbox;
Fl_PNG_Image* image;
Fl_Button* button_compute;
Fl_Value_Input* in_num_iterations;
Fl_Value_Input* in_threshold;
Fl_Value_Input* in_alphamin;
Fl_Value_Input* in_alphamax;
Fl_Value_Input* in_alpha_num_intervals;
Fl_Value_Input* in_betamin;
Fl_Value_Input* in_betamax;
Fl_Value_Input* in_beta_num_intervals;
Fl_Value_Input* in_num_seedpoints;
Fl_Check_Button* in_output_csv;
private:
static void callback_compute(Fl_Widget*, void*);
inline void callback_compute_il();
};
int main() {
SimpleWindow win(800,600,"Dynamic Systems");
return Fl::run();
}
// Constructor
SimpleWindow::SimpleWindow(int w, int h, const char* title):Fl_Window(w,h,title) {
// between begin...end comes what to show in window
this->begin(); // this-> is implicit
// Top: ScrollBox containing the picture
image = new Fl_PNG_Image("picture.png");
scroll = new Fl_Scroll(0,0,800,400);
scroll->begin();
scrollbox = new ScrollBox(0,0,800,400);
scrollbox->SetScroll(scroll);
scrollbox->image(image);
scroll->end();
// Bottom: inputboxes and button
int boxwidth = 80; // width input boxes
int boxheight = 20; // height input boxes
int firstrow = 450;
int secondrow = 550;
int padding = 100;
in_alphamin = new Fl_Value_Input(0*padding,firstrow,boxwidth,boxheight,"alpha_min");
in_alphamin->align(FL_ALIGN_TOP);
in_alphamin->value(0.0);
in_alphamax = new Fl_Value_Input(1*padding,firstrow,boxwidth,boxheight,"alpha_max");
in_alphamax->align(FL_ALIGN_TOP);
in_alphamax->value(1.0);
in_alpha_num_intervals = new Fl_Value_Input(2*padding,firstrow,boxwidth,boxheight,"width");
in_alpha_num_intervals->align(FL_ALIGN_TOP);
in_alpha_num_intervals->value(400);
in_betamin = new Fl_Value_Input(0*padding,secondrow,boxwidth,boxheight,"beta_min");
in_betamin->align(FL_ALIGN_TOP);
in_betamin->value(0.0);
in_betamax = new Fl_Value_Input(1*padding,secondrow,boxwidth,boxheight,"beta_max");
in_betamax->align(FL_ALIGN_TOP);
in_betamax->value(1.0);
in_beta_num_intervals = new Fl_Value_Input(2*padding,secondrow,boxwidth,boxheight,"height");
in_beta_num_intervals->align(FL_ALIGN_TOP);
in_beta_num_intervals->value(400);
in_num_iterations = new Fl_Value_Input(3*padding,firstrow,boxwidth,boxheight,"iterations");
in_num_iterations->align(FL_ALIGN_TOP);
in_num_iterations->value(100);
in_threshold = new Fl_Value_Input(4*padding,firstrow,boxwidth,boxheight,"threshold");
in_threshold->align(FL_ALIGN_TOP);
in_threshold->value(1);
in_num_seedpoints = new Fl_Value_Input(3*padding,secondrow,boxwidth,boxheight,"#seedpoints");
in_num_seedpoints->align(FL_ALIGN_TOP);
in_num_seedpoints->value(8);
button_compute = new Fl_Button(5*padding,firstrow,boxwidth,boxheight,"compute");
button_compute->type(FL_NORMAL_BUTTON);
button_compute->color(FL_RED);
button_compute->callback(callback_compute,this);
in_output_csv = new Fl_Check_Button(5*padding,secondrow,boxwidth,boxheight,"csv output");
this->end();
resizable(this);
this->show();
}
// Destructor
SimpleWindow::~SimpleWindow() {}
// Button callback, just cast object and call real function
void SimpleWindow::callback_compute(Fl_Widget* o, void* v) {
( (SimpleWindow*)v )->callback_compute_il();
}
// no arguments needed, because has access to all class members
void SimpleWindow::callback_compute_il() {
std::cout << "start computation..." << std::endl;
std::vector<float> seedpoints = {};
compute_all(
in_num_iterations->value(),
in_threshold->value(),
in_alphamin->value(),
in_alphamax->value(),
in_alpha_num_intervals->value(),
in_betamin->value(),
in_betamax->value(),
in_beta_num_intervals->value(),
in_num_seedpoints->value(),
in_output_csv->value(),
seedpoints
);
image = new Fl_PNG_Image("picture.png");
scrollbox->image(image);
scrollbox->resize(0,0,image->w(),image->h());
redraw();
std::cout << "done." << std::endl;
}