main.cpp 5.82 KB
Newer Older
1
#include <algorithm>
Lars Kuehne's avatar
Lars Kuehne committed
2 3
#include <cassert>
#include <chrono>
plgruener's avatar
plgruener committed
4
#include <cmath>
Lars Kuehne's avatar
Lars Kuehne committed
5
#include <fstream>
6
#include <iostream>
Lars Kuehne's avatar
Lars Kuehne committed
7
#include <random>
plgruener's avatar
plgruener committed
8
#include <sstream>
Christoph Saffer's avatar
Christoph Saffer committed
9 10
#include <vector>

11
#include <boost/program_options.hpp>
Christoph Saffer's avatar
Christoph Saffer committed
12

13 14
#include <png.h>

plgruener's avatar
plgruener committed
15
#include "colormaps.hpp"
16
#include "compute.hpp"
17
#include "picture.hpp"
plgruener's avatar
plgruener committed
18

19
int main(int argc, char* argv[]) {
plgruener's avatar
plgruener committed
20
  // get arguments from CLI
21 22
  // these can be input by user
  int num_iterations;
plgruener's avatar
plgruener committed
23
  float threshold;
24 25 26 27 28 29
  float alphamin;
  float alphamax;
  int alpha_num_intervals;
  float betamin;
  float betamax;
  int beta_num_intervals;
30
  int num_seedpoints;
31
  bool output;
32
  std::vector<float> seedpoints;
33 34 35 36

  namespace po = boost::program_options;
  try {
    po::options_description desc("Options");
plgruener's avatar
plgruener committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
    desc.add_options()
      ("help", "Help message")
      ("iterations,n", po::value<int>(&num_iterations)->default_value(100),
      " Number of iterations")
      ("width,w", po::value<int>(&alpha_num_intervals)->default_value(100),
      " 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 above that computation is stopped")
      ("amin,a", po::value<float>(&alphamin)->default_value(0),
      " alpha lower bound")
      ("amax,A", po::value<float>(&alphamax)->default_value(1),
      " alpha upper bound")
      ("bmin,b", po::value<float>(&betamin)->default_value(0),
      " 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),
      " Number of seedpoints (uniformly distributed in (0,1) )")
      ("seedpoints,S", po::value<std::vector<float>>(&seedpoints)->multitoken(),
      " Values for explicit seedpoints")
      ("output,O", po::value<bool>(&output)->default_value(true),
      " Boolean flag for output")
      ;
62
      
63 64 65 66 67 68 69 70

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);

    if (vm.count("help")) {
      std::cout << desc << std::endl;
      return 0;
    }
71

72 73 74
    po::notify(vm);

    // check if our integers are >0, else throw invalid-argument-error
75 76
    if ((num_iterations < 1) || (alpha_num_intervals < 1) ||
        (beta_num_intervals < 1)) {
77 78 79
      throw po::validation_error(po::validation_error::invalid_option_value);
    }

80
  } catch (po::error& e) {
81
    std::cerr << e.what() << std::endl;
plgruener's avatar
plgruener committed
82 83
    return -1;
  }
84

85

86
  // these are computed
87
  int alpha_num_params = alpha_num_intervals + 1;
Lars Kuehne's avatar
Lars Kuehne committed
88
  float alpha_interval_size = (alphamax - alphamin) / (alpha_num_intervals);
89
  int beta_num_params = beta_num_intervals + 1;
Lars Kuehne's avatar
Lars Kuehne committed
90
  float beta_interval_size = (betamax - betamin) / (beta_num_intervals);
plgruener's avatar
plgruener committed
91

92
  // fill prametervectors alpha and beta
Christoph Saffer's avatar
Christoph Saffer committed
93
  aligned_vector<float> alphas(alpha_num_params);
Lars Kuehne's avatar
Lars Kuehne committed
94 95 96 97
  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;
98
  }
Christoph Saffer's avatar
Christoph Saffer committed
99
  aligned_vector<float> betas(beta_num_params);
Lars Kuehne's avatar
Lars Kuehne committed
100 101 102 103
  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;
104 105
  }

106 107
  // Initialization and output of seedpoints 
  std::cout << "Following seedpoints are used for computation:" << std::endl;
108 109
  aligned_vector<float> x_start(num_seedpoints);
  aligned_vector<float> y_start(num_seedpoints);
110 111
  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);
112
    y_start[i - 1] = 0;
113 114 115 116 117 118
    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] << ", ";
119
  }
120
  std::cout << '\n';
121

122
  // Initialization pixel values and color vectors
123
  aligned_vector<float> result(alpha_num_params * beta_num_params);
124 125
  aligned_vector<unsigned char> colors(alpha_num_params * beta_num_params);
  aligned_vector<unsigned char> colors_rgb(3 * alpha_num_params * beta_num_params);
Lars Kuehne's avatar
Lars Kuehne committed
126

plgruener's avatar
plgruener committed
127 128
  auto time_start = std::chrono::system_clock::now();

129
  // Computation 
130
#pragma omp parallel for schedule(dynamic)
Lars Kuehne's avatar
Lars Kuehne committed
131 132
  for (int a = 0; a < alpha_num_params; a++) {
    for (int b = beta_num_params - 1; b >= 0; b--) {
133 134
      result[(beta_num_params - b - 1) * alpha_num_params + a] = compute(
          alphas[a], betas[b], x_start, y_start, num_iterations, threshold);
135
    }
136
  }
plgruener's avatar
plgruener committed
137
  auto time_end = std::chrono::system_clock::now();
plgruener's avatar
plgruener committed
138
  float elapsed_seconds =
Lars Kuehne's avatar
Lars Kuehne committed
139
      std::chrono::duration<float>(time_end - time_start).count();
plgruener's avatar
plgruener committed
140
  std::cout << "TIME for computation: " << elapsed_seconds << std::endl;
plgruener's avatar
plgruener committed
141

142
  // Generate output
143
  if (output) {
plgruener's avatar
plgruener committed
144 145
    time_start = std::chrono::system_clock::now();
   // Output result into .csv
146 147 148 149 150
    std::string file_result = "result.csv";
    std::ofstream ostrm_csv(file_result);
    ostrm_csv << "alpha beta value\n";
    for (int a = 0; a < alpha_num_params; a++) {
      for (int b = beta_num_params - 1; b >= 0; b--) {
151 152 153
        ostrm_csv << alphas[a] << ' ' << betas[b] << ' '
                  << result[(beta_num_params - b - 1) * alpha_num_params + a]
                  << std::endl;
154
      }
155
    }
plgruener's avatar
plgruener committed
156 157 158
  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;
159

plgruener's avatar
plgruener committed
160 161 162 163 164 165

  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;
166
  }
plgruener's avatar
plgruener committed
167
}