#include "libscl.h"
using namespace scl;
using namespace std;

int main()
{
  ofstream fout;
  string filename;

  REAL radius = 1.0;
  cout << '\n';
  cout << "volume of a ball of radius " << radius << '\n';
  for (INTEGER d=0; d<=10; ++d) {
    cout << d << " " << ball_volume(d, radius) << '\n';
  }
  cout << '\n';
 
  radius = 2.0;
  cout << "volume of a ball of radius " << radius << '\n';
  for (INTEGER d=0; d<=10; ++d) {
    cout << d << " " << ball_volume(d, radius) << '\n';
  }
  cout << '\n';

  INTEGER n = 50;

  INTEGER d = 2;
  radius = 1.0;

  INT_32BIT ix = 88383;
  realmat draws(d,n,0.0);
  for (INTEGER j=1; j<=n; ++j) {
    realmat draw = ball_rand(&ix,d,radius);
    for (INTEGER i=1; i<=d; ++i) draws(i,j) = draw[i];
  }

  cout << draws;

  ix = 88383;
  draws.resize(d,n,0.0);
  for (INTEGER j=1; j<=n; ++j) {
    realmat draw = ball_rand(ix,d,radius);
    for (INTEGER i=1; i<=d; ++i) draws(i,j) = draw[i];
  }

  cout << draws;

  radius = 2.0;

  ix = 88383;
  draws.resize(d,n,0.0);
  realmat radii(n,1);
  for (INTEGER j=1; j<=n; ++j) {
    realmat draw = ball_rand(ix,d,radius);
    REAL sum = 0.0;
    for (INTEGER i=1; i<=d; ++i) {
      draws(i,j) = draw[i];
      sum += pow(draw[i],2);
    }
    radii[j] = sqrt(sum);
  }

  cout << draws << radii;

  filename = "tstball.dat";
  fout.open(filename.c_str());
  if (!fout) error("Error, cannot open " + filename);

  n = 5000;

  ix = 88383;
  realmat sum(d,1,0.0);
  for (INTEGER j=1; j<=n; ++j) {
    realmat draw = ball_rand(ix,d,radius);
    for (INTEGER i=1; i<=d; ++i) sum[i] += draw[i];
    if (d == 2) fout << draw[1] << "  " << draw[2] << '\n';
  }
  realmat mean = sum/n;

  cout << mean;

  radius = 7.7928233774862563e-02;
  d = 15;

  cout << '\n';
  cout << fmt('e',26,16,log_ball_volume(d,radius)) << '\n';
  cout << fmt('e',26,16,log(ball_volume(d,radius))) << '\n';
  cout << fmt('e',26,16,exp(log_ball_volume(d,radius))) << '\n';
  cout << fmt('e',26,16,ball_volume(d,radius)) << '\n';

  radius = 1.0;
  d = 0;

  cout << '\n';
  cout << fmt('e',26,16,log_ball_volume(d,radius)) << '\n';
  cout << fmt('e',26,16,log(ball_volume(d,radius))) << '\n';
  cout << fmt('e',26,16,exp(log_ball_volume(d,radius))) << '\n';
  cout << fmt('e',26,16,ball_volume(d,radius)) << '\n';

  radius = 1.0;
  d = 1;

  cout << '\n';
  cout << fmt('e',26,16,log_ball_volume(d,radius)) << '\n';
  cout << fmt('e',26,16,log(ball_volume(d,radius))) << '\n';
  cout << fmt('e',26,16,exp(log_ball_volume(d,radius))) << '\n';
  cout << fmt('e',26,16,ball_volume(d,radius)) << '\n';

  radius = 1.0;
  d = 2;

  cout << '\n';
  cout << fmt('e',26,16,log_ball_volume(d,radius)) << '\n';
  cout << fmt('e',26,16,log(ball_volume(d,radius))) << '\n';
  cout << fmt('e',26,16,exp(log_ball_volume(d,radius))) << '\n';
  cout << fmt('e',26,16,ball_volume(d,radius)) << '\n';


  fout.clear(); fout.close();

  return 0;
}
