<commit_before>#include <vector>
#include <iterator>
#include <algorithm>
#include <values.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <utility>
#include <cmath>
using namespace std;

ostream & operator <<(ostream &os, const vector<double> &d)
{
  os << "V(";
  for (int i = 0; i < d.size(); i++) {
    if (i > 0) os << ",";
    os << d[i];
  }
  return os << ")";
}

#include "dataset.h"
#include "tuple.h"
#include "random.h"
#include "extra.h"
#include "regressor.h"
#include "policy.h"
#include "domain.h"
#include "fqi.h"

/** Calculate the mean squared error of the output for a data set,
 * given a tree.
 */
double mse(const dataset &ts, const ExtraTree &rf)
{
  double mse;
  for (int i = 0; i < ts.size(); i++) {
    double tmp = rf.output(ts.data[i].attributes) - ts.data[i].output;
    mse += tmp * tmp;
  }
  return mse / ts.size();
}

/* Read the Parkinson's disease data (classification)
 */
void readparkinsons(dataset &ts) {
  ifstream src("parkinsons.data");
  string line;

  while (getline(src, line)) {
    double tmp[24];
    int i = 0;
    int p1 = 0;
    int p2 = 0;
    while ((p2 = line.find(',', p1)) != string::npos) {
      tmp[i++] = strtod(line.substr(p1, p2).c_str(), NULL);
      p1 = p2 + 1;
    }
    tmp[i++] = strtod(line.substr(p1).c_str(), NULL);
    datum d;
    d.output = tmp[17] > 0.0 ? 1.0 : -1.0;
    for (int j = 1; j < 17; j++) {
      d.attributes.push_back(tmp[j]);
    }
    for (int j = 18; j < 24; j++) {
      d.attributes.push_back(tmp[j]);
    }
    ts.data.push_back(d);
  }
}

/* Read the yacht hydrodynamics data (regression)
 */
void readhydro(dataset &ts) {
  ifstream src("yacht_hydrodynamics.data");
  string line;

  while (getline(src, line)) {
    double tmp[7];
    int i = 0;
    int p1 = 0;
    int p2 = 0;
    while ((p2 = line.find(' ', p1)) != string::npos) {
      tmp[i++] = strtod(line.substr(p1, p2).c_str(), NULL);
      p1 = p2 + 1;
    }
    tmp[i++] = strtod(line.substr(p1).c_str(), NULL);
    datum d;
    d.output = tmp[6];
    for (int j = 0; j < 6; j++) {
      d.attributes.push_back(tmp[j]);
    }
    ts.data.push_back(d);
  }
}

double checkRegression(const dataset &ts, int ntrain, ExtraTree &rf) {
  dataset trainset, testset;
  ts.randomFold(ntrain, trainset, testset);

  rf.train(trainset, false);

  return mse(testset, rf);     // Calculate mean squared error
}

void testRegression(int nfolds, const dataset &ts) {
  int ntrain = ts.size() * (nfolds - 1) / nfolds;

  for (int i = 1; i <= nfolds; i++) {
    cout << "Fold " << i;
    ExtraTree rf(ts.nd(), 30, 2);
    double mse = checkRegression(ts, ntrain, rf);
    cout << " mse " << mse << endl;
    assert(mse < 3.5);
  }
}

class ConfusionMatrix {
private:
  int tp, tn, fp, fn;

public:
  ConfusionMatrix(int i_tp = 0, int i_tn = 0, int i_fp = 0, int i_fn = 0) {
    tp = i_tp;
    tn = i_tn;
    fp = i_fp;
    fn = i_fn;
  }

  ConfusionMatrix operator +(const ConfusionMatrix &cm) {
    ConfusionMatrix r(tp + cm.tp,
                      tn + cm.tn,
                      fp + cm.fp,
                      fn + cm.fn);
    return r;
  }

  int total() const { return (tp + tn + fp + fn); }
  double accuracy() const { return (tp + tn) / (double) total(); }
  double precision() const { return (double) tp / (tp + fp); }
  double recall() { return (double) tp / (tp + fn); }
  double specificity() { return (double) tn / (tn + fp); }

  void record(double nPred, double nTrue) {
    if (nPred == nTrue) {
      if (nPred > 0) {
        tp += 1;
      }
      else {
        tn += 1;
      }
    }
    else {
      if (nPred > 0) {
        fp += 1;
      }
      else {
        fn += 1;
      }
    }
  }
  friend ostream & operator <<(ostream &os, const ConfusionMatrix &d);
};

ostream & operator <<(ostream &os, const ConfusionMatrix &d) {
  return os << "tp " << d.tp << " tn " << d.tn << " fp " << d.fp << " fn " << d.fn;
}

ConfusionMatrix checkClassification(const dataset &ts, int ntrain, ExtraTree &rf) {
  dataset trainset, testset;
  ts.randomFold(ntrain, trainset, testset);
  ConfusionMatrix cm;

  rf.train(trainset, false);

  for (int i = 0; i < testset.size(); i++) {
    datum item = testset.data[i];
    double pred = rf.output(item.attributes);
    cm.record(pred, item.output);
  }
  return cm;
}

void testClassification(int nfolds, const dataset &ts) {
  int ntrain = ts.size() * (nfolds - 1) / nfolds;
  ConfusionMatrix cmTotal;

  for (int i = 1; i <= nfolds; i++) {
    cout << "Fold " << i << " ";
    ExtraTreeClassification rf(ts.nd(), 100, 2);
    ConfusionMatrix cm = checkClassification(ts, ntrain, rf);
    cout << cm << endl;
    cmTotal = cmTotal + cm;
  }

  cout << "Totals: " << cmTotal << endl;
  cout << "Overall precision: " << cmTotal.precision() << endl;
  cout << "Overall recall: " << cmTotal.recall() << endl;
  cout << "Accuracy: " << cmTotal.accuracy() << endl;
}

#include "getopt.h"

int main(int argc, char **argv) {
  const char *domain = "mc";

  Domain *pd;
  Regressor *pr;
  FQI *fqi;
  dataset ts1;
  dataset ts2;
  int c;
  int tflag = 0;
  int sflag = 0;
  while ((c = getopt(argc, argv, "tsd:")) != -1) {
    switch (c) {
    case 't':
      tflag++;
      break;
    case 's':
      sflag++;
      break;
    case 'd':
      domain = optarg;
      break;
    case '?':
      return 1;
    default:
      break;
    }
  }

  if (tflag) {
    cout << "Testing classification with parkinsons.data." << endl;
    readparkinsons(ts1);
    testClassification(10, ts1);

    cout << "Testing regression with yacht_hydrodynamics.data." << endl;
    readhydro(ts2);
    testRegression(10, ts2);
    return 0;
  }
  else {
    pd = CreateDomain(domain);
    if (sflag) {
      pr = new SingleETRegressor(pd->numActions, pd->numDimensions);
    }
    else {
      pr = new ExtraTreeRegressor(pd->numActions, pd->numDimensions);
    }
    fqi = new FQI(pd, pr, 0.98, 400, 10, 30);
    fqi->run();
  }
  cout << "done!" << endl;
}
<commit_msg>Expand and fix tests.<commit_after>#include <vector>
#include <iterator>
#include <algorithm>
#include <values.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <utility>
#include <cmath>
using namespace std;

ostream & operator <<(ostream &os, const vector<double> &d)
{
  os << "V(";
  for (int i = 0; i < d.size(); i++) {
    if (i > 0) os << ",";
    os << d[i];
  }
  return os << ")";
}

#include "dataset.h"
#include "tuple.h"
#include "random.h"
#include "extra.h"
#include "regressor.h"
#include "policy.h"
#include "domain.h"
#include "fqi.h"

/** Calculate the mean squared error of the output for a data set,
 * given a tree.
 */
double mse(const dataset &ts, const ExtraTree &rf)
{
  double mse;
  for (int i = 0; i < ts.size(); i++) {
    double tmp = rf.output(ts.data[i].attributes) - ts.data[i].output;
    mse += tmp * tmp;
  }
  return mse / ts.size();
}

/* Read the Parkinson's disease data (classification)
 */
void readparkinsons(dataset &ts) {
  ifstream src("testing/parkinsons.data");
  string line;

  while (getline(src, line)) {
    double tmp[24];
    int i = 0;
    int p1 = 0;
    int p2 = 0;
    while ((p2 = line.find(',', p1)) != string::npos) {
      tmp[i++] = strtod(line.substr(p1, p2 - p1).c_str(), NULL);
      p1 = p2 + 1;
    }
    tmp[i++] = strtod(line.substr(p1).c_str(), NULL);
    datum d;
    d.output = tmp[17] > 0.0 ? 1.0 : -1.0;
    for (int j = 1; j < 17; j++) {
      d.attributes.push_back(tmp[j]);
    }
    for (int j = 18; j < 24; j++) {
      d.attributes.push_back(tmp[j]);
    }
    ts.data.push_back(d);
  }
}

void readwdbc(dataset &ts) {
  ifstream src("testing/wdbc.data");
  string line;

  while (getline(src, line)) {
    double tmp[100];
    int i = 0;
    int n = 0;
    int p1 = 0;
    int p2 = 0;
    while ((p2 = line.find(',', p1)) != string::npos) {
      string subs = line.substr(p1, p2 - p1);

      /* index 0 is ignored, index 1 is either 'M' or 'B', the rest are
       * features.
       */
      if (n == 1) {
        tmp[i++] = (subs.compare("M") == 0) ? 1.0 : -1.0;
      }
      else if (n >= 2) {
        tmp[i++] = strtod(subs.c_str(), NULL);
      }
      n++;
      p1 = p2 + 1;
    }
    tmp[i++] = strtod(line.substr(p1).c_str(), NULL);
    datum d;
    d.output =  tmp[0];
    for (int j = 1; j < i; j++) {
      d.attributes.push_back(tmp[j]);
    }
    ts.data.push_back(d);
  }
}

/* Read the yacht hydrodynamics data (regression)
 */
void readhydro(dataset &ts) {
  ifstream src("testing/yacht_hydrodynamics.data");
  string line;

  while (getline(src, line)) {
    double tmp[7];
    int i = 0;
    int p1 = 0;
    int p2 = 0;
    while ((p2 = line.find(' ', p1)) != string::npos) {
      tmp[i++] = strtod(line.substr(p1, p2 - p1).c_str(), NULL);
      p1 = p2 + 1;
    }
    tmp[i++] = strtod(line.substr(p1).c_str(), NULL);
    datum d;
    d.output = tmp[6];
    for (int j = 0; j < 6; j++) {
      d.attributes.push_back(tmp[j]);
    }
    ts.data.push_back(d);
  }
}

double checkRegression(const dataset &ts, int ntrain, ExtraTree &rf) {
  dataset trainset, testset;
  ts.randomFold(ntrain, trainset, testset);

  rf.train(trainset, false);

  return mse(testset, rf);     // Calculate mean squared error
}

void testRegression(int nfolds, const dataset &ts) {
  int ntrain = ts.size() * (nfolds - 1) / nfolds;

  for (int i = 1; i <= nfolds; i++) {
    cout << "Fold " << i;
    ExtraTree rf(ts.nd(), 30, 2);
    double mse = checkRegression(ts, ntrain, rf);
    cout << " mse " << mse << endl;
    assert(mse < 3.5);
  }
}

class ConfusionMatrix {
private:
  int tp, tn, fp, fn;

public:
  ConfusionMatrix(int i_tp = 0, int i_tn = 0, int i_fp = 0, int i_fn = 0) {
    tp = i_tp;
    tn = i_tn;
    fp = i_fp;
    fn = i_fn;
  }

  ConfusionMatrix operator +(const ConfusionMatrix &cm) {
    ConfusionMatrix r(tp + cm.tp,
                      tn + cm.tn,
                      fp + cm.fp,
                      fn + cm.fn);
    return r;
  }

  int total() const { return (tp + tn + fp + fn); }
  double accuracy() const { return (tp + tn) / (double) total(); }
  double precision() const { return (double) tp / (tp + fp); }
  double recall() { return (double) tp / (tp + fn); }
  double specificity() { return (double) tn / (tn + fp); }

  void record(double nPred, double nTrue) {
    if (nPred == nTrue) {
      if (nPred > 0) {
        tp += 1;
      }
      else {
        tn += 1;
      }
    }
    else {
      if (nPred > 0) {
        fp += 1;
      }
      else {
        fn += 1;
      }
    }
  }
  friend ostream & operator <<(ostream &os, const ConfusionMatrix &d);
};

ostream & operator <<(ostream &os, const ConfusionMatrix &d) {
  return os << "tp " << d.tp << " tn " << d.tn << " fp " << d.fp << " fn " << d.fn;
}

ConfusionMatrix checkClassification(const dataset &ts, int ntrain, ExtraTree &rf) {
  dataset trainset, testset;
  ts.randomFold(ntrain, trainset, testset);
  ConfusionMatrix cm;

  rf.train(trainset, false);

  for (int i = 0; i < testset.size(); i++) {
    datum item = testset.data[i];
    double pred = rf.output(item.attributes);
    cm.record(pred, item.output);
  }
  return cm;
}

void testClassification(int nfolds, const dataset &ts) {
  int ntrain = ts.size() * (nfolds - 1) / nfolds;
  ConfusionMatrix cmTotal;

  for (int i = 1; i <= nfolds; i++) {
    cout << "Fold " << i << " ";
    ExtraTreeClassification rf(ts.nd(), 100, 2);
    ConfusionMatrix cm = checkClassification(ts, ntrain, rf);
    cout << cm << endl;
    cmTotal = cmTotal + cm;
  }

  cout << "Totals: " << cmTotal << endl;
  cout << "Overall precision: " << cmTotal.precision() << endl;
  cout << "Overall recall: " << cmTotal.recall() << endl;
  cout << "Accuracy: " << cmTotal.accuracy() << endl;
}

#include "getopt.h"

int main(int argc, char **argv) {
  const char *domain = "mc";

  Domain *pd;
  Regressor *pr;
  FQI *fqi;
  int c;
  int tflag = 0;
  int sflag = 0;
  while ((c = getopt(argc, argv, "tsd:")) != -1) {
    switch (c) {
    case 't':
      tflag++;
      break;
    case 's':
      sflag++;
      break;
    case 'd':
      domain = optarg;
      break;
    case '?':
      return 1;
    default:
      break;
    }
  }

  if (tflag) {
    dataset ts1, ts2, ts3;

    cout << "Testing classification with parkinsons.data." << endl;
    readparkinsons(ts1);
    testClassification(10, ts1);

    cout << "Testing classification with wdbc.data." << endl;
    readwdbc(ts2);
    testClassification(10, ts2);

    cout << "Testing regression with yacht_hydrodynamics.data." << endl;
    readhydro(ts3);
    testRegression(10, ts3);
    return 0;
  }
  else {
    pd = CreateDomain(domain);
    if (sflag) {
      pr = new SingleETRegressor(pd->numActions, pd->numDimensions);
    }
    else {
      pr = new ExtraTreeRegressor(pd->numActions, pd->numDimensions);
    }
    fqi = new FQI(pd, pr, 0.98, 400, 10, 30);
    fqi->run();
  }
  cout << "done!" << endl;
}
<|endoftext|>


<commit_before>52e97f87-2748-11e6-bbde-e0f84713e7b8<commit_msg>this is my first commit?<commit_after>55810a2b-2748-11e6-90fa-e0f84713e7b8<|endoftext|>


<commit_before>#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
    int arr[2][3][5][7] = {0};
    for(int l = 0;l < 2;l++)
    {
        for(int i = 0;i < 3;i++)
        {
            for(int j = 0;j < 5;j++)
            {
                for(int k = 0;k < 7;k++)
                {
                    if(j == 0 && k == 0)
                        arr[l][i][j][k] = 4;//開幕
                    if(j == 0 && k == 1)
                        arr[l][i][j][k] = 4;
                    if(j == 0 && k == 5)
                        arr[l][i][j][k] = 5;//混合
                    if(j == 0 && k == 6)
                        arr[l][i][j][k] = 5;
                    if(j == 1 && k == 5)
                        arr[l][i][j][k] = 5;
                    if(j == 1 && k == 6)
                        arr[l][i][j][k] = 5;
                    if(j == 2 && k == 4)
                        arr[l][i][j][k] = 6;//活動
                    if(j == 2 && k == 5)
                        arr[l][i][j][k] = 6;
                    if(j == 2 && k == 6)
                        arr[l][i][j][k] = 6;
                    if(j == 3 && k == 4)
                        arr[l][i][j][k] = 7;//亂教
                    if(j == 3 && k == 5)
                        arr[l][i][j][k] = 8;//桌遊
                    if(j == 3 && k == 6)
                        arr[l][i][j][k] = 8;
                    if(j == 4 && k == 1)
                        arr[l][i][j][k] = 6;
                    if(j == 4 && k == 2)
                        arr[l][i][j][k] = 6;
                    if(j == 4 && k == 3)
                        arr[l][i][j][k] = 6;
                    if(j == 4 && k == 4)
                        arr[l][i][j][k] = 7;
                    if(j == 4 && k == 5)
                        arr[l][i][j][k] = 9;//結業
                    if(j == 4 && k == 6)
                        arr[l][i][j][k] = 9;

                    while(!arr[l][i][j][k])
                    {
                        srand( clock() );
                        arr[l][i][j][k] = rand() % 2 + 1;
                    }
                }
            }
        }
    }
    for(int l = 0;l < 2;l++)
    {
        for(int i = 0;i < 3;i++)
        {
            for(int j = 0;j < 5;j++)
            {
                for(int k = 0;k < 7;k++)
                {

                    if(arr[l][i][j][k] == 1)
                        cout << "社會";
                    if(arr[l][i][j][k] == 2)
                        cout << "自然";
                    if(arr[l][i][j][k] == 4)
                        cout << "開幕";
                    if(arr[l][i][j][k] == 5)
                        cout << "混合";
                    if(arr[l][i][j][k] == 6)
                        cout << "活動";
                    if(arr[l][i][j][k] == 7)
                        cout << "亂教";
                    if(arr[l][i][j][k] == 8)
                        cout << "桌遊";
                    if(arr[l][i][j][k] == 9)
                        cout << "結業";
                    cout << " ";
                }
                cout << endl;
            }
            cout << endl;
        }
    }
    return 0;
}
<commit_msg>version 0.9<commit_after>#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>

using namespace std;

void print_soc(int l,int ptr)
{
    if(l == 0)
    {
        if(ptr == 0)
            cout << "戰爭策略-烽火連天的清末";
        if(ptr == 1)
            cout << "人物誌-慈禧太后傳奇";
        if(ptr == 2)
            cout << "人物誌-慈禧太后傳的秘密";
        if(ptr == 3)
            cout << "宗教團體-揭密刀槍不入的義和團";
        if(ptr == 4)
            cout << "治台方法-清朝與台灣";
        if(ptr == 5)
            cout << "司法及變法-清末的政治改革";
        if(ptr == 6)
            cout << "盜墓-盜墓筆記";
        if(ptr == 7)
            cout << "皇帝的感情生活-深宮秘辛";
        if(ptr == 8)
            cout << "清代文學-聊齋";
        if(ptr == 9)
            cout << "奇案-清末四大奇案";
    }
    else
    {
        if(ptr == 0)
            cout << "人物-你是誰?";
        if(ptr == 1)
            cout << "地理-風吹草低見牛羊";
        if(ptr == 2)
            cout << "食-吃飯我最大";
        if(ptr == 3)
            cout << "政治、軍事制度-咦?怎麼開打?";
        if(ptr == 4)
            cout << "成語-假文青";
        if(ptr == 5)
            cout << "傳說-攏是假";
        if(ptr == 6)
            cout << "搞笑故事-都給你說";
        if(ptr == 7)
            cout << "行-幾號公車";
        if(ptr == 8)
            cout << "住-大樓不要倒";
        if(ptr == 9)
            cout << "衣-黑白配";
    }
}

void print_sci(int l,int ptr)
{
    if(l == 0)
    {
        if(ptr == 0)
            cout << "磁力-羅盤的秘密";
        if(ptr == 1)
            cout << "早熟稻-撫養人口大角色";
        if(ptr == 2)
            cout << "鏡像是什麼-活字版印刷";
        if(ptr == 3)
            cout << "致命的火藥-隨時引爆";
        if(ptr == 4)
            cout << "璀璨煙花-五顏六色的奧義";
        if(ptr == 5)
            cout << "算盤-數學好好玩";
        if(ptr == 6)
            cout << "夢溪筆談選讀-大星由天降";
    }
    else
    {
        if(ptr == 0)
            cout << "錯視-受困八陣圖的秘密";
        if(ptr == 1)
            cout << "摩擦力-孔明的運輸好夥伴「木牛流馬」";
        if(ptr == 2)
            cout << "浮力-曹沖秤象的智慧";
        if(ptr == 3)
            cout << "浮力、重力-水上決戰赤壁";
        if(ptr == 4)
            cout << "重心-董卓強大的利器「馬蹬」";
        if(ptr == 5)
            cout << "醋膽素-武神關羽";
        if(ptr == 6)
            cout << "基因-三國英雄的傳承";
    }
}

int main()
{
    restart:
    cout << endl << "==================================================================================" << endl;
    int arr[2][3][5][7] = {0};
    for(int l = 0;l < 2;l++)
    {
        int social = 0, science = 0;
        for(int i = 0;i < 3;i++)
        {
            for(int j = 0;j < 5;j++)
            {
                for(int k = 0;k < 7;k++)
                {
                    if(j == 0 && k == 0)
                        arr[l][i][j][k] = 4;//開幕
                    if(j == 0 && k == 1)
                        arr[l][i][j][k] = 4;
                    if(j == 0 && k == 5)
                        arr[l][i][j][k] = 5;//混合
                    if(j == 0 && k == 6)
                        arr[l][i][j][k] = 5;
                    if(j == 1 && k == 5)
                        arr[l][i][j][k] = 5;
                    if(j == 1 && k == 6)
                        arr[l][i][j][k] = 5;
                    if(j == 2 && k == 4)
                        arr[l][i][j][k] = 6;//活動
                    if(j == 2 && k == 5)
                        arr[l][i][j][k] = 6;
                    if(j == 2 && k == 6)
                        arr[l][i][j][k] = 6;
                    if(j == 3 && k == 4)
                        arr[l][i][j][k] = 7;//亂教
                    if(j == 3 && k == 5)
                        arr[l][i][j][k] = 8;//桌遊
                    if(j == 3 && k == 6)
                        arr[l][i][j][k] = 8;
                    if(j == 4 && k == 1)
                        arr[l][i][j][k] = 6;
                    if(j == 4 && k == 2)
                        arr[l][i][j][k] = 6;
                    if(j == 4 && k == 3)
                        arr[l][i][j][k] = 6;
                    if(j == 4 && k == 4)
                        arr[l][i][j][k] = 7;
                    if(j == 4 && k == 5)
                        arr[l][i][j][k] = 9;//結業
                    if(j == 4 && k == 6)
                        arr[l][i][j][k] = 9;

                    while(!arr[l][i][j][k])
                    {
                        srand( clock() );
                        arr[l][i][j][k] = rand() % 2 + 1;
                        if(arr[l][i][j][k] == 2)
                        {
                            science ++;
                            if(science > 7)
                                arr[l][i][j][k] = 0;
                        }
                        if(arr[l][i][j][k] == 1)
                        {
                            social ++;
                            if(social > 10)
                                arr[l][i][j][k] = 0;
                        }
                        if(i != 0)
                            arr[l][i][j][k] = arr[l][0][j][k];
                    }
                }
            }
        }
    }
    for(int l = 0;l < 2;l++)
    {
        int social[3][5][7] = {0}, science[3][5][7] = {0};
        for(int i = 0;i < 3;i++)
        {
            bool used_soc[10] = {0},used_sci[7] = {0};
            for(int j = 0;j < 5;j++)
            {
                for(int k = 0;k < 7;k++)
                {

                    if(arr[l][i][j][k] == 1)
                    {
                        int time = 0;
                        cout << "社會";
                        while(1)
                        {
                            bool flag = 0;
                            srand( clock() );
                            int ptr = rand() % 10;
                            if(!used_soc[ptr])
                            {
                                if(i == 0)
                                    flag = 1;
                                else if(i == 1 && social[0][j][k] != ptr)
                                    flag = 1;
                                else if(social[0][j][k] != ptr && social[1][j][k] != ptr)
                                    flag = 1;
                            }
                            if(flag)
                            {
                                used_soc[ptr] = 1;
                                social[i][j][k] = ptr;
                                print_soc(l, ptr);
                                break;
                            }
                            time++;
                            if(time > 100)
                                goto restart;
                        }
                    }
                    if(arr[l][i][j][k] == 2)
                    {
                        int time = 0;
                        cout << "自然";
                        while(1)
                        {
                            bool flag = 0;
                            srand( clock() );
                            int ptr = rand() % 7;
                            if(!used_sci[ptr])
                            {
                                if(i == 0)
                                    flag = 1;
                                else if(i == 1 && science[0][j][k] != ptr)
                                    flag = 1;
                                else if(science[0][j][k] != ptr && science[1][j][k] != ptr)
                                    flag = 1;
                            }
                            if(flag)
                            {
                                used_sci[ptr] = 1;
                                science[i][j][k] = ptr;
                                print_sci(l, ptr);
                                break;
                            }
                            time++;
                            if(time > 100)
                                goto restart;
                        }

                    }
                    if(arr[l][i][j][k] == 4)
                        cout << "開幕";
                    if(arr[l][i][j][k] == 5)
                        cout << "混合";
                    if(arr[l][i][j][k] == 6)
                        cout << "活動";
                    if(arr[l][i][j][k] == 7)
                        cout << "亂教";
                    if(arr[l][i][j][k] == 8)
                        cout << "桌遊";
                    if(arr[l][i][j][k] == 9)
                        cout << "結業";
                    cout << " ";
                }
                cout << endl;
            }
            cout << endl;
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>b70370eb-2747-11e6-a4e8-e0f84713e7b8<commit_msg>For roselyn to integrate at some point<commit_after>b71411d7-2747-11e6-a93c-e0f84713e7b8<|endoftext|>


<commit_before>#include <math.h>
#include <stdio.h>

struct Vec3
{
    typedef const Vec3& InParam;

    Vec3() noexcept {}

    Vec3(const float x, const float y, const float z) noexcept
        : x(x)
        , y(y)
        , z(z)
    {
    }

    float x, y, z;
};

Vec3& operator+=(Vec3& left, Vec3::InParam right) noexcept {
    left.x += right.x;
    left.y += right.y;
    left.z += right.z;
    return left;
}

Vec3 operator+(Vec3::InParam left, Vec3::InParam right) noexcept {
    return Vec3{
        left.x + right.x,
        left.y + right.y,
        left.z + right.z
    };
}

Vec3 operator-(Vec3::InParam left, Vec3::InParam right) noexcept {
    return Vec3{
        left.x - right.x,
        left.y - right.y,
        left.z - right.z
    };
}

Vec3 operator*(Vec3::InParam v, const float scale) noexcept {
    return Vec3{
        v.x * scale,
        v.y * scale,
        v.z * scale
    };
}

Vec3& operator*=(Vec3& v, const float scale) noexcept {
    v.x *= scale;
    v.y *= scale;
    v.z *= scale;
    return v;
}

float dot(Vec3::InParam left, Vec3::InParam right) noexcept {
    return left.x*right.x + left.y*right.y + left.z*right.z;
}

float length_squared(const float x, const float y, const float z) noexcept {
    return x*x + y*y + z*z;
}

float length_squared(Vec3::InParam in) noexcept {
    return length_squared(in.x, in.y, in.z);
}

float length(const float x, const float y) noexcept {
    // sqrt may raise std::domain_error if the input is negative but that's not
    // possible here as we're summing two squares
    return sqrt(x*x + y*y);
}

float length(const float x, const float y, const float z) noexcept {
    // sqrt may raise std::domain_error if the input is negative but that's not
    // possible here as we're summing three squares
    return sqrt(x*x + y*y + z*z);
}

float length(Vec3::InParam in) noexcept {
    return length(in.x, in.y, in.z);
}

Vec3 normalised(Vec3::InParam in) noexcept {
    const float scale = 1.0f / length(in);
    return in * scale;
}

Vec3 lerp(Vec3::InParam from, Vec3::InParam to, const float t) noexcept {
    return (from * (1.0f - t)) + (to * t);
}

Vec3 reflected(Vec3::InParam vector, Vec3::InParam normal) noexcept {
    // To reflect the supplied vector along the axis of the normal, add as much
    // of the normal to the vector as would make it perpendicular to the
    // normal, then add the same amount again.
    //
    // This will reverse the vector's magnitude with respect to the normal,
    // whilst keeping the magnitude of the vector the same.
    //
    const float magnitude_of_normal_shared_with_vector = dot(vector, normal);
    const float normal_scale = -2.0f * magnitude_of_normal_shared_with_vector;
    return vector + normal * normal_scale;
}

Vec3 sample_sky(const Vec3::InParam direction) noexcept {
    const Vec3 up{0.0f, 1.0f, 0.0f};

    const float red = 32.0f;
    const float green = 128.0f;
    const float blue = 180.0f + 64.0f * dot(direction, up);

    return Vec3{red, green, blue};
}

Vec3 sample_ground(
        const Vec3::InParam position,
        const Vec3::InParam direction,
        const Vec3::InParam sphere_point_on_ground,
        const float sphere_magnitude_squared) noexcept
{
    const float inverse_square_scale = 0.1f;
    const int x = fabs(position.x * inverse_square_scale);
    const int y = fabs(position.z * inverse_square_scale);

    const Vec3 world_down {0.0f, -1.0f, 0.0f};
    const float dot_down {dot(direction, world_down)};

    Vec3 colour;

    if ((x%2) ^ (y%2)) {
        const Vec3 green {32.0f, 128.0f, 32.0f};
        const Vec3 light_green {green * 2.0f};
        colour = lerp(green, light_green, dot_down);
    } else {
        const Vec3 green {64.0f, 128.0f, 64.0f};
        const Vec3 light_green {green * 2.0f};
        colour = lerp(green, light_green, dot_down);
    }

    const Vec3 to_sphere_on_ground = sphere_point_on_ground - position;
    if (length_squared(to_sphere_on_ground) < sphere_magnitude_squared) {
        colour *= 0.5f;
    }

    return colour;
}

Vec3 sample_sphere(
        const Vec3::InParam position,
        const Vec3::InParam normal,
        const Vec3::InParam direction) noexcept
{
    const Vec3 world_up {0.0f, 1.0f, 0.0f};
    const float dot_up {dot(normal, world_up)};

    const Vec3 half {0.5f, 0.5f, 0.5f};
    const Vec3 color {(normal * 0.5f + half) * 255.0f};
    const Vec3 half_color {color * 0.5f};
    return lerp(half_color, color, dot_up);
}

Vec3 sample(Vec3 position, Vec3 direction) noexcept {

    Vec3 colour {0.0f, 0.0f, 0.0f};
    float colour_blend = 1.0f;

    // check for collision against sphere
    const Vec3 sphere_point {0.0f, 15.0f, 40.0f};
    const Vec3 sphere_point_on_ground {0.0f, 0.0f, 40.0f};
    const float sphere_magnitude = 11.0f;
    const float sphere_magnitude_squared = sphere_magnitude * sphere_magnitude;
    const Vec3 to_sphere {sphere_point - position};
    const float closest_to_sphere {dot(direction, to_sphere)};
    const Vec3 point_nearest_sphere {position + direction * closest_to_sphere};
    const float length_to_sphere {length(sphere_point - point_nearest_sphere)};
    // TODO: use squared magnitude
    if (length_to_sphere < sphere_magnitude) {
        // calc intersection point
        const float adjacent_length = sqrt(
            sphere_magnitude * sphere_magnitude
            - length_to_sphere * length_to_sphere);
        const Vec3 intersection {
            point_nearest_sphere - (direction * adjacent_length)};

        // sample the sphere
        const Vec3 normal {normalised(intersection - sphere_point)};
        position = intersection;
        direction = reflected(direction, normal);
        colour = lerp(
            colour,
            sample_sphere(intersection, normal, direction),
            colour_blend);
        colour_blend = 0.5f;
    }

    // check for collision against ground
    const Vec3 ground_inverse_normal(0.0f, -1.0f, 0.0f);
    if (dot(ground_inverse_normal, direction) > 0.0f) {
        // hit the ground, figure out where
        const Vec3 ground_point(0.0f, 0.0f, 0.0f);
        const Vec3 to_ground {ground_point - position};
        const float distance_to_ground {dot(to_ground, ground_inverse_normal)};
        const float dot_to_ground {dot(direction, ground_inverse_normal)};
        const float distance {distance_to_ground / dot_to_ground};
        const Vec3 ground_intersection {position + direction * distance};
        colour = lerp(
            colour,
            sample_ground(
                ground_intersection,
                direction,
                sphere_point_on_ground,
                sphere_magnitude_squared),
            colour_blend);
    } else {
        colour = lerp(
            colour,
            // TODO: remove position parameter
            sample_sky(direction),
            colour_blend);
    }

    return colour;
}

void draw_scene(const int image_width, const int image_height) noexcept {
    const Vec3 camera_forward{0.0f, 0.0f, 1.0f};
    const Vec3 camera_right{1.0f, 0.0f, 0.0f};
    const Vec3 camera_up{0.0f, 1.0f, 0.0f};
    const Vec3 camera_pos{0.0f, 10.0f, 0.0f};

    const int half_image_width = image_width / 2;
    const int half_image_height = image_height / 2;

    for (int y=image_height-1; y>=0; --y) {
        for (int x=0; x<image_width; ++x) {
            const Vec3 pixel_offset = Vec3{
                float(x-half_image_width),
                float(y-half_image_height),
                0.0f};

            const Vec3 pixel_direction = normalised(
                camera_forward*image_height + pixel_offset);

            const Vec3 colour = sample(camera_pos, pixel_direction);

            printf("%c%c%c", int(colour.x), int(colour.y), int(colour.z));
        }
    }
}

int main() {
    printf("P6 512 512 255 ");
    draw_scene(512, 512);
}

// Copyright 2014-2019 Angelos Evripiotis
//
// 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.
<commit_msg>Remove redundant consts on InParams<commit_after>#include <math.h>
#include <stdio.h>

struct Vec3
{
    typedef const Vec3& InParam;

    Vec3() noexcept {}

    Vec3(const float x, const float y, const float z) noexcept
        : x(x)
        , y(y)
        , z(z)
    {
    }

    float x, y, z;
};

Vec3& operator+=(Vec3& left, Vec3::InParam right) noexcept {
    left.x += right.x;
    left.y += right.y;
    left.z += right.z;
    return left;
}

Vec3 operator+(Vec3::InParam left, Vec3::InParam right) noexcept {
    return Vec3{
        left.x + right.x,
        left.y + right.y,
        left.z + right.z
    };
}

Vec3 operator-(Vec3::InParam left, Vec3::InParam right) noexcept {
    return Vec3{
        left.x - right.x,
        left.y - right.y,
        left.z - right.z
    };
}

Vec3 operator*(Vec3::InParam v, const float scale) noexcept {
    return Vec3{
        v.x * scale,
        v.y * scale,
        v.z * scale
    };
}

Vec3& operator*=(Vec3& v, const float scale) noexcept {
    v.x *= scale;
    v.y *= scale;
    v.z *= scale;
    return v;
}

float dot(Vec3::InParam left, Vec3::InParam right) noexcept {
    return left.x*right.x + left.y*right.y + left.z*right.z;
}

float length_squared(const float x, const float y, const float z) noexcept {
    return x*x + y*y + z*z;
}

float length_squared(Vec3::InParam in) noexcept {
    return length_squared(in.x, in.y, in.z);
}

float length(const float x, const float y) noexcept {
    // sqrt may raise std::domain_error if the input is negative but that's not
    // possible here as we're summing two squares
    return sqrt(x*x + y*y);
}

float length(const float x, const float y, const float z) noexcept {
    // sqrt may raise std::domain_error if the input is negative but that's not
    // possible here as we're summing three squares
    return sqrt(x*x + y*y + z*z);
}

float length(Vec3::InParam in) noexcept {
    return length(in.x, in.y, in.z);
}

Vec3 normalised(Vec3::InParam in) noexcept {
    const float scale = 1.0f / length(in);
    return in * scale;
}

Vec3 lerp(Vec3::InParam from, Vec3::InParam to, const float t) noexcept {
    return (from * (1.0f - t)) + (to * t);
}

Vec3 reflected(Vec3::InParam vector, Vec3::InParam normal) noexcept {
    // To reflect the supplied vector along the axis of the normal, add as much
    // of the normal to the vector as would make it perpendicular to the
    // normal, then add the same amount again.
    //
    // This will reverse the vector's magnitude with respect to the normal,
    // whilst keeping the magnitude of the vector the same.
    //
    const float magnitude_of_normal_shared_with_vector = dot(vector, normal);
    const float normal_scale = -2.0f * magnitude_of_normal_shared_with_vector;
    return vector + normal * normal_scale;
}

Vec3 sample_sky(Vec3::InParam direction) noexcept {
    const Vec3 up{0.0f, 1.0f, 0.0f};

    const float red = 32.0f;
    const float green = 128.0f;
    const float blue = 180.0f + 64.0f * dot(direction, up);

    return Vec3{red, green, blue};
}

Vec3 sample_ground(
        Vec3::InParam position,
        Vec3::InParam direction,
        Vec3::InParam sphere_point_on_ground,
        const float sphere_magnitude_squared) noexcept
{
    const float inverse_square_scale = 0.1f;
    const int x = fabs(position.x * inverse_square_scale);
    const int y = fabs(position.z * inverse_square_scale);

    const Vec3 world_down {0.0f, -1.0f, 0.0f};
    const float dot_down {dot(direction, world_down)};

    Vec3 colour;

    if ((x%2) ^ (y%2)) {
        const Vec3 green {32.0f, 128.0f, 32.0f};
        const Vec3 light_green {green * 2.0f};
        colour = lerp(green, light_green, dot_down);
    } else {
        const Vec3 green {64.0f, 128.0f, 64.0f};
        const Vec3 light_green {green * 2.0f};
        colour = lerp(green, light_green, dot_down);
    }

    const Vec3 to_sphere_on_ground = sphere_point_on_ground - position;
    if (length_squared(to_sphere_on_ground) < sphere_magnitude_squared) {
        colour *= 0.5f;
    }

    return colour;
}

Vec3 sample_sphere(
        Vec3::InParam position,
        Vec3::InParam normal,
        Vec3::InParam direction) noexcept
{
    const Vec3 world_up {0.0f, 1.0f, 0.0f};
    const float dot_up {dot(normal, world_up)};

    const Vec3 half {0.5f, 0.5f, 0.5f};
    const Vec3 color {(normal * 0.5f + half) * 255.0f};
    const Vec3 half_color {color * 0.5f};
    return lerp(half_color, color, dot_up);
}

Vec3 sample(Vec3 position, Vec3 direction) noexcept {

    Vec3 colour {0.0f, 0.0f, 0.0f};
    float colour_blend = 1.0f;

    // check for collision against sphere
    const Vec3 sphere_point {0.0f, 15.0f, 40.0f};
    const Vec3 sphere_point_on_ground {0.0f, 0.0f, 40.0f};
    const float sphere_magnitude = 11.0f;
    const float sphere_magnitude_squared = sphere_magnitude * sphere_magnitude;
    const Vec3 to_sphere {sphere_point - position};
    const float closest_to_sphere {dot(direction, to_sphere)};
    const Vec3 point_nearest_sphere {position + direction * closest_to_sphere};
    const float length_to_sphere {length(sphere_point - point_nearest_sphere)};
    // TODO: use squared magnitude
    if (length_to_sphere < sphere_magnitude) {
        // calc intersection point
        const float adjacent_length = sqrt(
            sphere_magnitude * sphere_magnitude
            - length_to_sphere * length_to_sphere);
        const Vec3 intersection {
            point_nearest_sphere - (direction * adjacent_length)};

        // sample the sphere
        const Vec3 normal {normalised(intersection - sphere_point)};
        position = intersection;
        direction = reflected(direction, normal);
        colour = lerp(
            colour,
            sample_sphere(intersection, normal, direction),
            colour_blend);
        colour_blend = 0.5f;
    }

    // check for collision against ground
    const Vec3 ground_inverse_normal(0.0f, -1.0f, 0.0f);
    if (dot(ground_inverse_normal, direction) > 0.0f) {
        // hit the ground, figure out where
        const Vec3 ground_point(0.0f, 0.0f, 0.0f);
        const Vec3 to_ground {ground_point - position};
        const float distance_to_ground {dot(to_ground, ground_inverse_normal)};
        const float dot_to_ground {dot(direction, ground_inverse_normal)};
        const float distance {distance_to_ground / dot_to_ground};
        const Vec3 ground_intersection {position + direction * distance};
        colour = lerp(
            colour,
            sample_ground(
                ground_intersection,
                direction,
                sphere_point_on_ground,
                sphere_magnitude_squared),
            colour_blend);
    } else {
        colour = lerp(
            colour,
            // TODO: remove position parameter
            sample_sky(direction),
            colour_blend);
    }

    return colour;
}

void draw_scene(const int image_width, const int image_height) noexcept {
    const Vec3 camera_forward{0.0f, 0.0f, 1.0f};
    const Vec3 camera_right{1.0f, 0.0f, 0.0f};
    const Vec3 camera_up{0.0f, 1.0f, 0.0f};
    const Vec3 camera_pos{0.0f, 10.0f, 0.0f};

    const int half_image_width = image_width / 2;
    const int half_image_height = image_height / 2;

    for (int y=image_height-1; y>=0; --y) {
        for (int x=0; x<image_width; ++x) {
            const Vec3 pixel_offset = Vec3{
                float(x-half_image_width),
                float(y-half_image_height),
                0.0f};

            const Vec3 pixel_direction = normalised(
                camera_forward*image_height + pixel_offset);

            const Vec3 colour = sample(camera_pos, pixel_direction);

            printf("%c%c%c", int(colour.x), int(colour.y), int(colour.z));
        }
    }
}

int main() {
    printf("P6 512 512 255 ");
    draw_scene(512, 512);
}

// Copyright 2014-2019 Angelos Evripiotis
//
// 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.
<|endoftext|>


<commit_before>8ec32100-4b02-11e5-a3e3-28cfe9171a43<commit_msg>Too poor for Dropbox<commit_after>8ecd1723-4b02-11e5-ac29-28cfe9171a43<|endoftext|>


<commit_before>c14c0282-4b02-11e5-a4e7-28cfe9171a43<commit_msg>Bug fixes and performance improvements<commit_after>c159fbbd-4b02-11e5-b226-28cfe9171a43<|endoftext|>


<commit_before>/*
 * main.cpp
 *
 *  Created on: Apr 9, 2014
 *      Author: Pimenta
 */

#include <cmath>
#include <cstdint>
#include <cstdio>
#include <fstream>
#include <list>
#include <map>
#include <set>
#include <string>

using namespace std;

typedef int64_t  word_t;
typedef uint64_t uword_t;
typedef uint32_t address_t;

enum field_t {
  A, B, J
};

#ifndef MEM_WORDS
#define MEM_WORDS 0x2000
#endif

const uword_t ADDRESS_WIDTH = uword_t(log2(double(MEM_WORDS)));

fstream f;
string buf;
address_t text_offset;
set<string> exported;
map<string, address_t> symbols;
map<string, list<pair<address_t, field_t>>> references;
list<pair<address_t, field_t>> absolute;
address_t mem_size = 0;
uword_t* mem = new uword_t[MEM_WORDS];

inline void readField(uword_t& instr, field_t field) {
  int mult = field == A ? 2 : (field == B ? 1 : 0);
  if (buf[0] == '0' && buf[1] == 'x') {
    address_t tmp;
    sscanf(buf.c_str(), "%i", &tmp);
    instr |= (tmp << mult*ADDRESS_WIDTH);
    absolute.emplace_back(mem_size, field);
  }
  else {
    auto sym = symbols.find(buf);
    if (sym == symbols.end())
      references[buf].emplace_back(mem_size, field);
    else
      instr |= (uword_t(sym->second) << mult*ADDRESS_WIDTH);
  }
}

int main(int argc, char* argv[]) {
  if (argc != 3) {
    fprintf(stderr, "Usage mode: subleq-asm <assembly_file> <object_file>\n");
    return 0;
  }

  f.open(argv[1]);

  f >> buf; // reading ".export"

  for (f >> buf; buf != ".data"; f >> buf) { // reading export section
    exported.insert(buf);
  }

  for (f >> buf; buf != ".text"; f >> buf) { // reading data section
    symbols[buf.substr(0, buf.size() - 1)] = mem_size;
    f >> mem[mem_size++];
  }

  text_offset = mem_size;
  for (f >> buf; !f.eof(); f >> buf) { // reading text section
    if (buf[buf.size() - 1] == ':') { // label found
      symbols[buf.substr(0, buf.size() - 1)] = mem_size;

      if (buf == "start:") // exporting start label
        exported.insert(string("start"));

      continue;
    }

    uword_t instr = 0;
    readField(instr, A);
    f >> buf;
    readField(instr, B);
    f >> buf;
    readField(instr, J);
    mem[mem_size++] = instr;
  }

  f.close();

  // solve references
  for (auto map_it = references.begin(); map_it != references.end();) {
    // external symbols
    auto sym = symbols.find(map_it->first);
    if (sym == symbols.end()) {
      ++map_it;
      continue;
    }

    // solve
    for (auto it = map_it->second.begin(); it != map_it->second.end(); ++it) {
      uword_t& instr = mem[it->first];
      switch (it->second) {
        case A:
          instr |= (uword_t(sym->second) << 2*ADDRESS_WIDTH);
          break;
        case B:
          instr |= (uword_t(sym->second) << 1*ADDRESS_WIDTH);
          break;
        case J:
          instr |= (uword_t(sym->second) << 0*ADDRESS_WIDTH);
          break;
      }
    }

    references.erase(map_it++);
  }

  f.open(argv[2], fstream::out | fstream::binary);

  {
    uint32_t tmp;

    // write text section offset
    tmp = text_offset;
    f.write((const char*)&tmp, sizeof(address_t));

    // write number of exported symbols
    tmp = exported.size();
    f.write((const char*)&tmp, sizeof(uint32_t));

    // write exported symbols
    for (auto& exp : exported) {
      // string
      f.write(exp.c_str(), exp.size() + 1);

      // address
      tmp = symbols[exp];
      f.write((const char*)&tmp, sizeof(uint32_t));
    }

    // write number of symbols of pending references
    tmp = references.size();
    f.write((const char*)&tmp, sizeof(uint32_t));

    // write symbols of pending references
    for (auto& sym : references) {
      // string
      f.write(sym.first.c_str(), sym.first.size() + 1);

      // write number of references to current symbol
      tmp = sym.second.size();
      f.write((const char*)&tmp, sizeof(uint32_t));

      // write references to current symbol
      for (auto& ref : sym.second) {
        // address
        tmp = ref.first;
        f.write((const char*)&tmp, sizeof(uint32_t));

        // field
        tmp = ref.second;
        f.write((const char*)&tmp, sizeof(uint32_t));
      }
    }

    // write number of absolute addresses
    tmp = absolute.size();
    f.write((const char*)&tmp, sizeof(uint32_t));

    // write absolute addresses
    for (auto& addr : absolute) {
      // address
      tmp = addr.first;
      f.write((const char*)&tmp, sizeof(uint32_t));

      // field
      tmp = addr.second;
      f.write((const char*)&tmp, sizeof(uint32_t));
    }

    // write assembled code size
    f.write((const char*)&mem_size, sizeof(address_t));

    // write assembled code
    f.write((const char*)mem, sizeof(uword_t)*mem_size);
  }

  f.close();

  delete[] mem;

  return 0;
}
<commit_msg>Adding text_offset variable<commit_after>/*
 * main.cpp
 *
 *  Created on: Apr 9, 2014
 *      Author: Pimenta
 */

#include <cmath>
#include <cstdint>
#include <cstdio>
#include <fstream>
#include <list>
#include <map>
#include <set>
#include <string>

using namespace std;

typedef int64_t  word_t;
typedef uint64_t uword_t;
typedef uint32_t address_t;

enum field_t {
  A, B, J
};

#ifndef MEM_WORDS
#define MEM_WORDS 0x2000
#endif

const uword_t ADDRESS_WIDTH = uword_t(log2(double(MEM_WORDS)));

fstream f;
string buf;
address_t text_offset;
set<string> exported;
map<string, address_t> symbols;
map<string, list<pair<address_t, field_t>>> references;
list<pair<address_t, field_t>> absolute;
address_t mem_size = 0;
uword_t* mem = new uword_t[MEM_WORDS];

inline void readField(uword_t& instr, field_t field) {
  int mult = field == A ? 2 : (field == B ? 1 : 0);
  if (buf[0] == '0' && buf[1] == 'x') {
    address_t tmp;
    sscanf(buf.c_str(), "%i", &tmp);
    instr |= (tmp << mult*ADDRESS_WIDTH);
    absolute.emplace_back(mem_size, field);
  }
  else {
    auto sym = symbols.find(buf);
    if (sym == symbols.end())
      references[buf].emplace_back(mem_size, field);
    else
      instr |= (uword_t(sym->second) << mult*ADDRESS_WIDTH);
  }
}

int main(int argc, char* argv[]) {
  if (argc != 3) {
    fprintf(stderr, "Usage mode: subleq-asm <assembly_file> <object_file>\n");
    return 0;
  }

  f.open(argv[1]);

  f >> buf; // reading ".export"

  for (f >> buf; buf != ".data"; f >> buf) { // reading export section
    exported.insert(buf);
  }

  for (f >> buf; buf != ".text"; f >> buf) { // reading data section
    symbols[buf.substr(0, buf.size() - 1)] = mem_size;
    f >> mem[mem_size++];
  }

  text_offset = mem_size;
  for (f >> buf; !f.eof(); f >> buf) { // reading text section
    if (buf[buf.size() - 1] == ':') { // label found
      symbols[buf.substr(0, buf.size() - 1)] = mem_size;

      if (buf == "start:") // exporting start label
        exported.insert(string("start"));

      continue;
    }

    uword_t instr = 0;
    readField(instr, A);
    f >> buf;
    readField(instr, B);
    f >> buf;
    readField(instr, J);
    mem[mem_size++] = instr;
  }

  f.close();

  // solve references
  for (auto map_it = references.begin(); map_it != references.end();) {
    // external symbols
    auto sym = symbols.find(map_it->first);
    if (sym == symbols.end()) {
      ++map_it;
      continue;
    }

    // solve
    for (auto it = map_it->second.begin(); it != map_it->second.end(); ++it) {
      uword_t& instr = mem[it->first];
      switch (it->second) {
        case A:
          instr |= (uword_t(sym->second) << 2*ADDRESS_WIDTH);
          break;
        case B:
          instr |= (uword_t(sym->second) << 1*ADDRESS_WIDTH);
          break;
        case J:
          instr |= (uword_t(sym->second) << 0*ADDRESS_WIDTH);
          break;
      }
    }

    references.erase(map_it++);
  }

  f.open(argv[2], fstream::out | fstream::binary);

  {
    uint32_t tmp;

    // write text section offset
    f.write((const char*)&text_offset, sizeof(address_t));

    // write number of exported symbols
    tmp = exported.size();
    f.write((const char*)&tmp, sizeof(uint32_t));

    // write exported symbols
    for (auto& exp : exported) {
      // string
      f.write(exp.c_str(), exp.size() + 1);

      // address
      tmp = symbols[exp];
      f.write((const char*)&tmp, sizeof(uint32_t));
    }

    // write number of symbols of pending references
    tmp = references.size();
    f.write((const char*)&tmp, sizeof(uint32_t));

    // write symbols of pending references
    for (auto& sym : references) {
      // string
      f.write(sym.first.c_str(), sym.first.size() + 1);

      // write number of references to current symbol
      tmp = sym.second.size();
      f.write((const char*)&tmp, sizeof(uint32_t));

      // write references to current symbol
      for (auto& ref : sym.second) {
        // address
        tmp = ref.first;
        f.write((const char*)&tmp, sizeof(uint32_t));

        // field
        tmp = ref.second;
        f.write((const char*)&tmp, sizeof(uint32_t));
      }
    }

    // write number of absolute addresses
    tmp = absolute.size();
    f.write((const char*)&tmp, sizeof(uint32_t));

    // write absolute addresses
    for (auto& addr : absolute) {
      // address
      tmp = addr.first;
      f.write((const char*)&tmp, sizeof(uint32_t));

      // field
      tmp = addr.second;
      f.write((const char*)&tmp, sizeof(uint32_t));
    }

    // write assembled code size
    f.write((const char*)&mem_size, sizeof(address_t));

    // write assembled code
    f.write((const char*)mem, sizeof(uword_t)*mem_size);
  }

  f.close();

  delete[] mem;

  return 0;
}
<|endoftext|>


<commit_before>#include <string.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include "trim.hxx"
#include "contains.hxx"
#include "system.hxx"
#include "ldd.hxx"

using namespace std;

// Entry point for lddgraph
int main (int argc, char* argv[])
{
    /* Prints output when no arguments where specified */
    if (argc < 2)
    {
        cout << "Usage:" << endl
            << "  lddgraph [OPTION...] file" << endl
            << "Options:" << endl
            << "  -f <format>\tOutput graph format 'dot -T?'"
            << " for a complete list." << endl
            << "  -o <file>\tOutput file." << endl
            << "  -i <library>\tIgnore a specific library."
            << endl
            << "  -v Verbose mode" << endl;
        return 0;
    }

    /* lddgraph options */
    string input = argv[argc - 1];
    string basename = input.substr(input.find_last_of('/') + 1);
    string output = basename + ".deps.gv";
    string format = "jpg";
    vector<string> ignoreList;
    bool verbose = false;

    /*
     * Arguments parsing
     * Assuming that argv[0] is the executable path
     */
    for (int i = 1; i < argc - 1; i++)
    {
        int arglen = strlen(argv[i]);
        if (arglen < 2)
            arglen = 2;
        if (strncmp(argv[i], "-f", arglen) == 0)
        {
            i++;
            if (i > argc)
                format = argv[i];
        }
        else if (strncmp(argv[i], "-o", arglen) == 0)
        {
            i++;
            if (i > argc)
                output = argv[i];
        }
        else if (strncmp(argv[i], "-i", arglen) == 0)
        {
            i++;
            if (i > argc)
                ignoreList.push_back(argv[i]);
        }
        else if(strncmp(argv[i], "-v", arglen) == 0)
        {
            verbose = true;
        }
        else
        {
            cout << "Error: Invalid parameter" << endl;
        }
    }

    ofstream graphStream;
    graphStream.open(output.c_str());
    if (!graphStream.is_open())
    {
        cout << "Error: Can't open file " << output << endl;
        return 0;
    }

    graphStream << "digraph Dependencies {" << endl;

    vector<string> alreadyScanned;

    lddRecurse(input, alreadyScanned, ignoreList, graphStream, verbose);

    graphStream << "}" << endl;
    graphStream.flush();
    graphStream.close();

    string dotCMD = "dot -T" + format + " -o" + basename + ".deps.jpg " + output;
    system(dotCMD);

    return 0;
}

<commit_msg>Added graph displaying by invoking the display command<commit_after>#include <string.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
#include "trim.hxx"
#include "contains.hxx"
#include "system.hxx"
#include "ldd.hxx"

using namespace std;

// Entry point for lddgraph
int main (int argc, char* argv[])
{
    /* Prints output when no arguments where specified */
    if (argc < 2)
    {
        cout << "Usage:" << endl
            << "  lddgraph [OPTION...] file" << endl
            << "Options:" << endl
            << "  -f <format>\tOutput graph format 'dot -T?'"
            << " for a complete list." << endl
            << "  -o <file>\tOutput file." << endl
            << "  -i <library>\tIgnore a specific library."
            << endl
            << "  -v Verbose mode" << endl;
        return 0;
    }

    /* lddgraph options */
    string input = argv[argc - 1];
    string basename = input.substr(input.find_last_of('/') + 1);
    string gvoutput = basename + ".deps.gv";
    string imgoutput = basename + ".deps.jpg";
    string format = "jpg";
    vector<string> ignoreList;
    bool verbose = false;

    /*
     * Arguments parsing
     * Assuming that argv[0] is the executable path
     */
    for (int i = 1; i < argc - 1; i++)
    {
        int arglen = strlen(argv[i]);
        if (arglen < 2)
            arglen = 2;
        if (strncmp(argv[i], "-f", arglen) == 0)
        {
            i++;
            if (i > argc)
                format = argv[i];
        }
        else if (strncmp(argv[i], "-o", arglen) == 0)
        {
            i++;
            if (i > argc)
                imgoutput = argv[i];
        }
        else if (strncmp(argv[i], "-i", arglen) == 0)
        {
            i++;
            if (i > argc)
                ignoreList.push_back(argv[i]);
        }
        else if(strncmp(argv[i], "-v", arglen) == 0)
        {
            verbose = true;
        }
        else
        {
            cout << "Error: Invalid parameter" << endl;
        }
    }

    ofstream graphStream;
    graphStream.open(gvoutput.c_str());
    if (!graphStream.is_open())
    {
        cout << "Error: Can't open file " << gvoutput << endl;
        return 0;
    }

    graphStream << "digraph Dependencies {" << endl;

    vector<string> alreadyScanned;

    lddRecurse(input, alreadyScanned, ignoreList, graphStream, verbose);

    graphStream << "}" << endl;
    graphStream.flush();
    graphStream.close();

    string dotCMD = "dot -T" + format + " -o" + imgoutput + " " + gvoutput;
    string displayCMD = "display " + imgoutput;
    system(dotCMD.c_str());
    system(displayCMD.c_str());
    return 0;
}

<|endoftext|>


<commit_before>#include <cstddef>

#include <tuple>

#include <type_traits>

#include <utility>

namespace generic
{

namespace detail
{

namespace many
{

enum TupleValue { Scalar, Reference, Class };

template<std::size_t I,
  class T,
  TupleValue = ::std::is_class<T>{} ?
    TupleValue::Class :
    ::std::is_reference<T>{} ?
      TupleValue::Reference :
      TupleValue::Scalar
>
struct tuple_base
{
  T value;

  tuple_base() = default;

  template <typename A>
  constexpr tuple_base(A&& value) : value{::std::forward<A>(value)}
  {
  }
};

template<std::size_t I, class T>
struct tuple_base<I, T, TupleValue::Reference>
{
  ::std::add_pointer_t<::std::remove_reference_t<T>> value;

  tuple_base() = delete;

  constexpr tuple_base(T value) : value{&value}
  {
  }

  tuple_base(tuple_base&&) = default;
  tuple_base(tuple_base const&) = default;
  tuple_base& operator=(tuple_base&&) = default;
  tuple_base& operator=(tuple_base const&) = default;
};

template<std::size_t I, class T>
struct tuple_base<I, T, TupleValue::Class> : T
{
  tuple_base() = default;

  template <typename A>
  constexpr tuple_base(A&& value) : T{::std::forward<A>(value)}
  {
  }
};

template <::std::size_t I, class T>
auto& get(tuple_base<I, T, TupleValue::Scalar>& obj)
{
  return obj.value;
}

template <::std::size_t I, class T>
auto& get(tuple_base<I, T, TupleValue::Scalar> const& obj)
{
  return obj.value;
}

template <::std::size_t I, class T>
auto& get(tuple_base<I, T, TupleValue::Reference> const& obj)
{
  return *obj.value;
}

template <::std::size_t I, class T>
auto get(tuple_base<I, T, TupleValue::Class>& obj) -> T&
{
  return obj;
}

template <::std::size_t I, class T>
auto get(tuple_base<I, T, TupleValue::Class> const& obj) -> T const&
{
  return obj;
}

template <typename ...>
struct many_impl;

template <::std::size_t... Is, typename ...Types>
struct many_impl<::std::index_sequence<Is...>, Types...> :
  tuple_base<Is, Types>...
{
  many_impl() = default;
  ~many_impl() = default;
  many_impl(many_impl&&) = default;
  many_impl(many_impl const&) = default;
  many_impl& operator=(many_impl&&) = default;
  many_impl& operator=(many_impl const&) = default;

#if !__cpp_aggregate_bases
  template<typename ...U>
  constexpr many_impl(U&& ...u) :
    tuple_base<Is, Types>{::std::forward<U>(u)}...
  {
  }
#endif
};

}

}

template <typename ...Types>
struct many : detail::many::many_impl<
  ::std::make_index_sequence<sizeof...(Types)>,
  Types...
>
{
  many() = default;
  ~many() = default;
  many(many&&) = default;
  many(many const&) = default;
  many& operator=(many&&) = default;
  many& operator=(many const&) = default;

#if !__cpp_aggregate_bases
  template<class... U>
  constexpr many(U&& ...u) : many::many_impl{::std::forward<U>(u)...}
  {
  }
#endif
};

}

namespace std
{

template <typename ...Types>
struct tuple_size<::generic::many<Types...>> :
  ::std::integral_constant<size_t, sizeof...(Types)>
{
};

template <size_t I, class ...Types>
struct tuple_element<I, ::generic::many<Types...>>
{
  using type = tuple_element_t<I, tuple<Types...>>;
};

template <size_t I, typename ...Types>
auto& get(::generic::many<Types...>& m) noexcept
{
  return ::generic::detail::many::get(m);
}

template <size_t I, typename ...Types>
auto& get(::generic::many<Types...> const& m) noexcept
{
  return ::generic::detail::many::get<I>(m);
}

template<size_t I, typename ...Types>
auto&& get(::generic::many<Types...>&& m) noexcept
{
  // m is now a lvalue
  return ::generic::detail::many::get<I>(m);
}

}
<commit_msg>some fixes<commit_after>#include <cstddef>

#include <tuple>

#include <type_traits>

#include <utility>

namespace generic
{

namespace detail
{

namespace many
{

enum TupleValue { Scalar, Reference, Class };

template<std::size_t I,
  class T,
  TupleValue = ::std::is_class<T>{} ?
    TupleValue::Class :
    ::std::is_reference<T>{} ?
      TupleValue::Reference :
      TupleValue::Scalar
>
struct tuple_base
{
  T value;

  tuple_base() = default;

  template <typename A>
  constexpr tuple_base(A&& value) : value{::std::forward<A>(value)}
  {
  }
};

template<std::size_t I, class T>
struct tuple_base<I, T, TupleValue::Reference>
{
  ::std::add_pointer_t<::std::remove_reference_t<T>> value;

  tuple_base() = delete;

  constexpr tuple_base(T value) : value{&value}
  {
  }

  tuple_base(tuple_base&&) = default;
  tuple_base(tuple_base const&) = default;
  tuple_base& operator=(tuple_base&&) = default;
  tuple_base& operator=(tuple_base const&) = default;
};

template<std::size_t I, class T>
struct tuple_base<I, T, TupleValue::Class> : T
{
  tuple_base() = default;

  template <typename A>
  constexpr tuple_base(A&& value) : T{::std::forward<A>(value)}
  {
  }
};

template <::std::size_t I, class T>
auto& get(tuple_base<I, T, TupleValue::Scalar>& obj)
{
  return obj.value;
}

template <::std::size_t I, class T>
auto& get(tuple_base<I, T, TupleValue::Scalar> const& obj)
{
  return obj.value;
}

template <::std::size_t I, class T>
auto& get(tuple_base<I, T, TupleValue::Reference> const& obj)
{
  return *obj.value;
}

template <::std::size_t I, class T>
auto get(tuple_base<I, T, TupleValue::Class>& obj) -> T&
{
  return obj;
}

template <::std::size_t I, class T>
auto get(tuple_base<I, T, TupleValue::Class> const& obj) -> T const&
{
  return obj;
}

template <typename ...>
struct many_impl;

template <::std::size_t... Is, typename ...Types>
struct many_impl<::std::index_sequence<Is...>, Types...> :
  tuple_base<Is, Types>...
{
  many_impl() = default;
  ~many_impl() = default;
  many_impl(many_impl&&) = default;
  many_impl(many_impl const&) = default;
  many_impl& operator=(many_impl&&) = default;
  many_impl& operator=(many_impl const&) = default;

#if !__cpp_aggregate_bases
  template<typename ...U>
  constexpr many_impl(U&& ...u) :
    tuple_base<Is, Types>{::std::forward<U>(u)}...
  {
  }
#endif
};

}

}

template <typename ...Types>
struct many : detail::many::many_impl<
  ::std::make_index_sequence<sizeof...(Types)>,
  Types...
>
{
  many() = default;
  ~many() = default;
  many(many&&) = default;
  many(many const&) = default;
  many& operator=(many&&) = default;
  many& operator=(many const&) = default;

#if !__cpp_aggregate_bases
  template<class... U>
  constexpr many(U&& ...u) : many::many_impl{::std::forward<U>(u)...}
  {
  }
#endif
};

}

namespace std
{

template <typename ...Types>
class tuple_size<::generic::many<Types...>> :
  public ::std::integral_constant<size_t, sizeof...(Types)>
{
};

template <size_t I, class ...Types>
class tuple_element<I, ::generic::many<Types...>>
{
public:
  using type = tuple_element_t<I, tuple<Types...>>;
};

template <size_t I, typename ...Types>
auto& get(::generic::many<Types...>& m) noexcept
{
  return ::generic::detail::many::get<I>(m);
}

template <size_t I, typename ...Types>
auto& get(::generic::many<Types...> const& m) noexcept
{
  return ::generic::detail::many::get<I>(m);
}

template<size_t I, typename ...Types>
auto& get(::generic::many<Types...>&& m) noexcept
{
  // m is now a lvalue
  return ::generic::detail::many::get<I>(m);
}

}
<|endoftext|>


<commit_before>/**
 * A remake of the R2KS code, optimised for the apocrita cluster
 */

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <list>
#include <cstdlib>
#include <getopt.h>
#include <mpi.h>

using namespace std;

// Options Struct
struct Options {
  std::string filename;

  // Internal
  unsigned int num_genes;
  unsigned int num_lists;
  unsigned int pivot;

  // MPI
  int num_procs, mpi_id;

};

// MPI Datatype
typedef struct {
  int i,j;
  double result;
}MPIResult;

MPI_Datatype resultType;

/**
 * Calculate the weight for this term
 * For now, we are ignoring weight
 */

float calculateWeight(unsigned int idx, unsigned int pivot) {
  return 1.0;
  int h = (pivot - idx);
  float w = h * (h + 1.0) / 2.0;
  w = w < 0 ? 1 : w;
  return w;
}

/**
 * Perform the r2ks score for two lists
 * Take the two lists, the corresponding weights and the total weight, then perform
 * the scoring.
 */

double scoreLists(Options & options, std::vector<unsigned int> & gene_list0, std::vector<unsigned int> & gene_list1) {

  // First, calculate total weeight
  // TODO - we can so cache this

  // TODO - Given how weights are calculated this formula might work
  // totalweight = (pivot * ( pivot + 1) * (pivot + 2)) / 6.0 + (list length - pivot);

  float total_weight = 0.0;
  for (unsigned int i = 0; i < gene_list0.size(); ++i ){
    total_weight += calculateWeight(i, options.pivot);
  }

  std::vector<unsigned int> buff (gene_list0.size());

  for (unsigned int i = 0; i < gene_list0.size(); ++i ){
    buff[ gene_list1[i] ] = i;
  }

  // The algorithm follows the paper:
  // http://online.liebertpub.com/doi/pdf/10.1089/cmb.2012.0026
  // We optimise the algorithm by storing a history of previous values in the second loop
  // We take advantage of the fact that a gene is unique and always occurs in both lists and only once
  // thus rather than filling in the complete matrix, we only fill in the values we need by keeping
  // a record of where and what the previous values were.

  typedef struct {
    unsigned int pos_y;
    double value;
  }History;

  // Used to calculate the actual score
  double rvalue = 0.0;
  double one_over = 1.0 /  (options.num_genes * options.num_genes);

  std::vector<History> history;

  // First line has no history, so we do this one separately.
  {

    unsigned int ivalue = gene_list0[0];
    float pivot = buff[ivalue];

    double iw = calculateWeight(0, options.pivot);
    double jw = calculateWeight(pivot, options.pivot);
    double w = iw < jw ? iw : jw;
    double front = w;

    double prev = 0.0;

    History nh;
    nh.value = front;
    nh.pos_y = pivot;

    history.push_back(nh);

  }

  // Now we have a history so we perform the operation normally

  for (unsigned int i = 1; i < options.num_genes; ++i ){

    unsigned int ivalue = gene_list0[i];
    float pivot = buff[ivalue];

    double iw = calculateWeight(i, options.pivot);
    double jw = calculateWeight(pivot, options.pivot);
    double w = iw < jw ? iw : jw;

    double front = 0.0;

    History lh = history[history.size()-1];

    // we check to see if the pivot is still greater than all the histories
    // This is the best case scenario

    if (pivot > lh.pos_y){
      History nh;
      nh.value = lh.value + w;
      nh.pos_y = pivot;
      history.push_back(nh);

      double second_term = static_cast<double>((nh.pos_y+1) * (i+1)) * one_over;
      double nvalue = (nh.value / total_weight) - second_term;
      rvalue = nvalue > rvalue ? nvalue : rvalue;

    } else {

      std::vector<History>::iterator it = history.end();

      if (pivot < lh.pos_y){

        // we need to trawl back through the histories, updating as we go

        for (it--; it != history.begin() && it->pos_y > pivot; it--){
        //for (int j = history.size()-1; j >= 0; --j){

          History ph = *it;
          if (ph.pos_y > pivot){
            it->value += w;

            double second_term = static_cast<double>((it->pos_y+1) * (i+1)) * one_over;
            double nvalue = (it->value / total_weight) - second_term;
            rvalue = nvalue > rvalue ? nvalue : rvalue;

          }
        }
      }

      // Insert new pivot
      History nh;
      nh.value = it->value + w;
      nh.pos_y = pivot;

      history.insert(it+1, nh);

      double second_term = static_cast<double>((nh.pos_y+1) * (i+1)) * one_over;
      double nvalue = (nh.value / total_weight) - second_term;
      rvalue = nvalue > rvalue ? nvalue : rvalue;

    }

  }

  return rvalue * sqrt(options.num_genes);
}

/**
 * Read the header block from our file
 */

void readHeaderBlock(Options & options) {
  std::ifstream is (options.filename.c_str());
  is >> options.num_genes >> options.num_lists;
  is.close();
}

/**
 * Read a line from a file.
 * Assume gene_list is pre-populated with zeros
 */

void readLineIndex(Options & options, int idx, std::vector<unsigned int> & gene_list ) {

  std::ifstream fin;
  fin.open(options.filename.c_str());
  fin.seekg(std::ios::beg);

  for(int i=0; i < idx; ++i){
    fin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
  }

  // The list we are reading in is a set of gene expressions.
  // The position/index of this number is the gene itself.
  // We want a list that ranks these indices

  unsigned int gene_expression;
  unsigned int gidx = 0;
  while (fin >> gene_expression && gidx < options.num_genes) {
    gene_list[gene_expression] = gidx;
    gidx++;
  }

  fin.close();
}

/**
 * parse our command line options
 */

void parseCommandOptions (int argc, const char * argv[], Options &options) {
  int c;
  int digit_optind = 0;
  static struct option long_options[] = {
  };

  int option_index = 0;

  while ((c = getopt_long(argc, (char **)argv, "f:?", long_options, &option_index)) != -1) {
    int this_option_optind = optind ? optind : 1;
    switch (c) {
      case 0 :
        break;

      case 'f' :
        options.filename = std::string(optarg);
        break;

      default:
        std::cout << "?? getopt returned character code" << c << std::endl;
      }
  }

  if (optind < argc) {
      std::cout << "non-option ARGV-elements: " << std::endl;
      while (optind < argc)
          std::cout << argv[optind++];
      std::cout << std::endl;
  }

}

/**
 * Master MPI Process
 */

void masterProcess(Options &options){
  int total_tests =  options.num_lists * ( options.num_lists - 1) / 2;
  int processes_per_node = total_tests / (options.num_procs - 1);
  int extra_processes = total_tests % (options.num_procs - 1);

  vector < int > test_numbers;

  // Create our list of pairs
  for (int i=1; i < options.num_lists + 1; ++i){
    for (int j = i + 1; j < options.num_lists + 1; ++j){
      test_numbers.push_back( i );
      test_numbers.push_back( j );
    }
  }

  // Send the initial values to each client process, its total number of tests
  // and the test numbers themselves

  for (int i = 1; i < options.num_procs; ++i){

    int send_count = processes_per_node;
    if (i == options.num_procs - 1)
      send_count += extra_processes;

    int offset = processes_per_node * 2 * (i-1);

    send_count *= 2;
    MPI_Send(&send_count, 1, MPI_INT, i, 999, MPI_COMM_WORLD);
    MPI_Send(&test_numbers[offset], send_count, MPI_INT, i, 999, MPI_COMM_WORLD);

  }

  // Now wait to receive the results

  vector <MPIResult> results;

  while(results.size() < total_tests){
    MPIResult mp;
    MPI_Status status;
    MPI_Recv(&mp, 1, resultType, MPI_ANY_SOURCE,  MPI_ANY_TAG,MPI_COMM_WORLD, &status );
    results.push_back(mp);
  }

  // Finish with the results
  for (MPIResult mp : results){
    std::cout << mp.i << "_" << mp.j << " " << mp.result << std::endl;
  }

}

/**
 * Client MPI Process
 */

void clientProcess(Options &options){

  MPI_Status status;
  int bsize;

  MPI_Recv(&bsize, 1, MPI_INT, 0, MPI_ANY_TAG,MPI_COMM_WORLD, &status);

  int buffer[bsize];
  MPI_Recv(&buffer, bsize, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

  // Now the proper loop begins

  for (int i = 0; i < bsize; i+=2){
    int l0 = buffer[i];
    int l1 = buffer[i+1];

    std::vector<unsigned int> gene_list0(options.num_genes);
    std::vector<unsigned int> gene_list1(options.num_genes);

    readLineIndex(options, l0, gene_list0);
    readLineIndex(options, l1, gene_list1);

    float rvalue = scoreLists(options, gene_list0, gene_list1 );

    MPIResult mp;
    mp.i = l0;
    mp.j = l1;
    mp.result = rvalue;

    MPI_Send(&mp, 1, resultType, 0, 999, MPI_COMM_WORLD);

  }

}

/**
 * Main entry point
 */

int main (int argc, const char * argv[]) {
  Options ops;

  // Defaults for Options
  ops.pivot = 0;
  parseCommandOptions(argc,argv,ops);

  // MPI Init

  MPI_Init(&argc, const_cast<char***>(&argv));
  int length_name;
  char name[200];

  MPI_Comm_size(MPI_COMM_WORLD, &ops.num_procs);
  MPI_Comm_rank(MPI_COMM_WORLD, &ops.mpi_id);
  MPI_Get_processor_name(name, &length_name);

  if (ops.mpi_id == 0){
    cout << "MPI NumProcs: " << ops.num_procs << endl;
  }

  cout << "MPI ID: " << ops.mpi_id << " Name: " << name << endl;

  /// MPI Datatype for results
  MPI_Aint offsets[2], extent;
  MPI_Datatype oldtypes[2];
  int blockcounts[2];

  offsets[0] = 0;
  oldtypes[0] = MPI_INT;
  blockcounts[0] = 2;

  MPI_Type_extent(MPI_INT, &extent);
  offsets[1] = 2 * extent;
  oldtypes[1] = MPI_DOUBLE;
  blockcounts[1] = 1;

  MPI_Type_struct(2, blockcounts, offsets, oldtypes, &resultType);
  MPI_Type_commit(&resultType);

  // Read only, so mpi processes shouldnt clash with that
  readHeaderBlock(ops);

  if (ops.num_procs > 1){

    // The master MPI Process will farm out to the required processes
    if (ops.mpi_id == 0){
      masterProcess(ops);

    } else {
      clientProcess(ops);
    }

  } else {

    for (int i = 0; i < ops.num_lists; ++i ){
      for (int j = i + 1; j < ops.num_lists; ++j ){

        int l0 = i + 1;
        int l1 = j + 1;

        std::vector<unsigned int> gene_list0(ops.num_genes);
        std::vector<unsigned int> gene_list1(ops.num_genes);

        readLineIndex(ops, l0, gene_list0);
        readLineIndex(ops, l1, gene_list1);

        float rvalue = scoreLists(ops, gene_list0, gene_list1 );

        cout << l0 << "_" << l1 << " " << rvalue << endl;
      }
    }
  }

  MPI_Finalize();
}<commit_msg>Simplest and fastest thus far<commit_after>/**
 * A remake of the R2KS code, optimised for the apocrita cluster
 */

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <list>
#include <cstdlib>
#include <getopt.h>
#include <mpi.h>

using namespace std;

// Options Struct
struct Options {
  std::string filename;

  // Internal
  unsigned int num_genes;
  unsigned int num_lists;
  unsigned int pivot;

  // MPI
  int num_procs, mpi_id;

};

// MPI Datatype
typedef struct {
  int i,j;
  double result;
}MPIResult;

MPI_Datatype resultType;

/**
 * Calculate the weight for this term
 * For now, we are ignoring weight
 */

float calculateWeight(unsigned int idx, unsigned int pivot) {
  return 1.0;
  int h = (pivot - idx);
  float w = h * (h + 1.0) / 2.0;
  w = w < 0 ? 1 : w;
  return w;
}

/**
 * Perform the r2ks score for two lists
 * Take the two lists, the corresponding weights and the total weight, then perform
 * the scoring.
 */

double scoreLists(Options & options, std::vector<unsigned int> & gene_list0, std::vector<unsigned int> & gene_list1) {

  // First, calculate total weeight
  // TODO - we can so cache this

  // TODO - Given how weights are calculated this formula might work
  // totalweight = (pivot * ( pivot + 1) * (pivot + 2)) / 6.0 + (list length - pivot);

  float total_weight = 0.0;
  for (unsigned int i = 0; i < gene_list0.size(); ++i ){
    total_weight += calculateWeight(i, options.pivot);
  }

  std::vector<unsigned int> buff (gene_list0.size());

  for (unsigned int i = 0; i < gene_list0.size(); ++i ){
    buff[ gene_list1[i] ] = i;
  }

  // The algorithm follows the paper:
  // http://online.liebertpub.com/doi/pdf/10.1089/cmb.2012.0026
  // We optimise the algorithm by storing a history of previous values in the second loop
  // We take advantage of the fact that a gene is unique and always occurs in both lists and only once
  // thus rather than filling in the complete matrix, we only fill in the values we need by keeping
  // a record of where and what the previous values were.

  typedef struct {
    unsigned int pos_y;
    double value;
  }History;

  // Used to calculate the actual score
  double rvalue = 0.0;
  double one_over = 1.0 /  (options.num_genes * options.num_genes);

  std::vector<History> history;

  // First line has no history, so we do this one separately.
  {

    unsigned int ivalue = gene_list0[0];
    float pivot = buff[ivalue];

    double iw = calculateWeight(0, options.pivot);
    double jw = calculateWeight(pivot, options.pivot);
    double w = iw < jw ? iw : jw;
    double front = w;

    double prev = 0.0;

    History nh;
    nh.value = front;
    nh.pos_y = pivot;

    history.push_back(nh);

  }

  // Now we have a history so we perform the operation normally

  for (unsigned int i = 1; i < options.num_genes; ++i ){

    unsigned int ivalue = gene_list0[i];
    float pivot = buff[ivalue];

    double iw = calculateWeight(i, options.pivot);
    double jw = calculateWeight(pivot, options.pivot);
    double w = iw < jw ? iw : jw;

    double front = 0.0;

    History lh = history[history.size()-1];

    // we check to see if the pivot is still greater than all the histories
    // This is the best case scenario

    if (pivot > lh.pos_y){
      History nh;
      nh.value = lh.value + w;
      nh.pos_y = pivot;
      history.push_back(nh);

      double second_term = static_cast<double>((nh.pos_y+1) * (i+1)) * one_over;
      double nvalue = (nh.value / total_weight) - second_term;
      rvalue = nvalue > rvalue ? nvalue : rvalue;

    } else {

      std::vector<History>::iterator it = history.end();

      // we need to trawl back through the histories, updating as we go

      for (it--; it != history.begin() && it->pos_y > pivot; it--){
      //for (int j = history.size()-1; j >= 0; --j){

        History ph = *it;
        if (ph.pos_y > pivot){
          it->value += w;

          double second_term = static_cast<double>((it->pos_y+1) * (i+1)) * one_over;
          double nvalue = (it->value / total_weight) - second_term;
          rvalue = nvalue > rvalue ? nvalue : rvalue;

        }
      }

      // Insert new pivot
      History nh;
      nh.value = it->value + w;
      nh.pos_y = pivot;

      history.insert(it+1, nh);

      double second_term = static_cast<double>((nh.pos_y+1) * (i+1)) * one_over;
      double nvalue = (nh.value / total_weight) - second_term;
      rvalue = nvalue > rvalue ? nvalue : rvalue;

    }

  }

  return rvalue * sqrt(options.num_genes);
}

/**
 * Read the header block from our file
 */

void readHeaderBlock(Options & options) {
  std::ifstream is (options.filename.c_str());
  is >> options.num_genes >> options.num_lists;
  is.close();
}

/**
 * Read a line from a file.
 * Assume gene_list is pre-populated with zeros
 */

void readLineIndex(Options & options, int idx, std::vector<unsigned int> & gene_list ) {

  std::ifstream fin;
  fin.open(options.filename.c_str());
  fin.seekg(std::ios::beg);

  for(int i=0; i < idx; ++i){
    fin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
  }

  // The list we are reading in is a set of gene expressions.
  // The position/index of this number is the gene itself.
  // We want a list that ranks these indices

  unsigned int gene_expression;
  unsigned int gidx = 0;
  while (fin >> gene_expression && gidx < options.num_genes) {
    gene_list[gene_expression] = gidx;
    gidx++;
  }

  fin.close();
}

/**
 * parse our command line options
 */

void parseCommandOptions (int argc, const char * argv[], Options &options) {
  int c;
  int digit_optind = 0;
  static struct option long_options[] = {
  };

  int option_index = 0;

  while ((c = getopt_long(argc, (char **)argv, "f:?", long_options, &option_index)) != -1) {
    int this_option_optind = optind ? optind : 1;
    switch (c) {
      case 0 :
        break;

      case 'f' :
        options.filename = std::string(optarg);
        break;

      default:
        std::cout << "?? getopt returned character code" << c << std::endl;
      }
  }

  if (optind < argc) {
      std::cout << "non-option ARGV-elements: " << std::endl;
      while (optind < argc)
          std::cout << argv[optind++];
      std::cout << std::endl;
  }

}

/**
 * Master MPI Process
 */

void masterProcess(Options &options){
  int total_tests =  options.num_lists * ( options.num_lists - 1) / 2;
  int processes_per_node = total_tests / (options.num_procs - 1);
  int extra_processes = total_tests % (options.num_procs - 1);

  vector < int > test_numbers;

  // Create our list of pairs
  for (int i=1; i < options.num_lists + 1; ++i){
    for (int j = i + 1; j < options.num_lists + 1; ++j){
      test_numbers.push_back( i );
      test_numbers.push_back( j );
    }
  }

  // Send the initial values to each client process, its total number of tests
  // and the test numbers themselves

  for (int i = 1; i < options.num_procs; ++i){

    int send_count = processes_per_node;
    if (i == options.num_procs - 1)
      send_count += extra_processes;

    int offset = processes_per_node * 2 * (i-1);

    send_count *= 2;
    MPI_Send(&send_count, 1, MPI_INT, i, 999, MPI_COMM_WORLD);
    MPI_Send(&test_numbers[offset], send_count, MPI_INT, i, 999, MPI_COMM_WORLD);

  }

  // Now wait to receive the results

  vector <MPIResult> results;

  while(results.size() < total_tests){
    MPIResult mp;
    MPI_Status status;
    MPI_Recv(&mp, 1, resultType, MPI_ANY_SOURCE,  MPI_ANY_TAG,MPI_COMM_WORLD, &status );
    results.push_back(mp);
  }

  // Finish with the results
  for (MPIResult mp : results){
    std::cout << mp.i << "_" << mp.j << " " << mp.result << std::endl;
  }

}

/**
 * Client MPI Process
 */

void clientProcess(Options &options){

  MPI_Status status;
  int bsize;

  MPI_Recv(&bsize, 1, MPI_INT, 0, MPI_ANY_TAG,MPI_COMM_WORLD, &status);

  int buffer[bsize];
  MPI_Recv(&buffer, bsize, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

  // Now the proper loop begins

  for (int i = 0; i < bsize; i+=2){
    int l0 = buffer[i];
    int l1 = buffer[i+1];

    std::vector<unsigned int> gene_list0(options.num_genes);
    std::vector<unsigned int> gene_list1(options.num_genes);

    readLineIndex(options, l0, gene_list0);
    readLineIndex(options, l1, gene_list1);

    float rvalue = scoreLists(options, gene_list0, gene_list1 );

    MPIResult mp;
    mp.i = l0;
    mp.j = l1;
    mp.result = rvalue;

    MPI_Send(&mp, 1, resultType, 0, 999, MPI_COMM_WORLD);

  }

}

/**
 * Main entry point
 */

int main (int argc, const char * argv[]) {
  Options ops;

  // Defaults for Options
  ops.pivot = 0;
  parseCommandOptions(argc,argv,ops);

  // MPI Init

  MPI_Init(&argc, const_cast<char***>(&argv));
  int length_name;
  char name[200];

  MPI_Comm_size(MPI_COMM_WORLD, &ops.num_procs);
  MPI_Comm_rank(MPI_COMM_WORLD, &ops.mpi_id);
  MPI_Get_processor_name(name, &length_name);

  if (ops.mpi_id == 0){
    cout << "MPI NumProcs: " << ops.num_procs << endl;
  }

  cout << "MPI ID: " << ops.mpi_id << " Name: " << name << endl;

  /// MPI Datatype for results
  MPI_Aint offsets[2], extent;
  MPI_Datatype oldtypes[2];
  int blockcounts[2];

  offsets[0] = 0;
  oldtypes[0] = MPI_INT;
  blockcounts[0] = 2;

  MPI_Type_extent(MPI_INT, &extent);
  offsets[1] = 2 * extent;
  oldtypes[1] = MPI_DOUBLE;
  blockcounts[1] = 1;

  MPI_Type_struct(2, blockcounts, offsets, oldtypes, &resultType);
  MPI_Type_commit(&resultType);

  // Read only, so mpi processes shouldnt clash with that
  readHeaderBlock(ops);

  if (ops.num_procs > 1){

    // The master MPI Process will farm out to the required processes
    if (ops.mpi_id == 0){
      masterProcess(ops);

    } else {
      clientProcess(ops);
    }

  } else {

    for (int i = 0; i < ops.num_lists; ++i ){
      for (int j = i + 1; j < ops.num_lists; ++j ){

        int l0 = i + 1;
        int l1 = j + 1;

        std::vector<unsigned int> gene_list0(ops.num_genes);
        std::vector<unsigned int> gene_list1(ops.num_genes);

        readLineIndex(ops, l0, gene_list0);
        readLineIndex(ops, l1, gene_list1);

        float rvalue = scoreLists(ops, gene_list0, gene_list1 );

        cout << l0 << "_" << l1 << " " << rvalue << endl;
      }
    }
  }

  MPI_Finalize();
}<|endoftext|>


<commit_before>#include "allvars.h"
#include "proto.h"
#include "part_data.hpp"
#include "thermalvel.hpp"
#include <gadgetwriter.hpp>

using namespace GadgetWriter;
using namespace std;

#define BUFFER 48

int64_t write_particle_data(GWriteSnap & snap, int type, lpt_data& outdata, part_grid& Pgrid, FermiDiracVel *therm_vels, const double vel_prefac, const double vel_prefac2, int64_t FirstId, const bool twolpt)
{
  const int64_t NumPart = outdata.GetNumPart();
  float *block;
  id_type *blockid;
  int64_t written=0, pc;
  std::string posstr("POS ");
  std::string velstr("VEL ");
  std::string idstr("ID  ");
  std::string ustr("U   ");
  //HDF5 has different strings
  if(ICFormat == 3){
      posstr = "Coordinates";
      velstr = "Velocities";
      idstr = "ParticleIDs";
      ustr = "InternalEnergy";
  }
  printf("\nWriting IC-file\n");
  const int64_t blockmaxlen = BUFFER * 1024 * 1024;
  if(!(block = (float *) malloc(blockmaxlen*3*sizeof(float))))
    {
      printf("failed to allocate memory for `block' (%ld MB).\n", 3*sizeof(float)*blockmaxlen/1024/1024);
      exit(24);
    }

  /*We are about to write the POS block*/
  /* Add displacement to Lagrangian coordinates, and multiply velocities by correct factor when writing VEL*/
  pc = 0;
  for(int64_t i = 0; i < NumPart; i++){
      for(int k = 0; k < 3; k++){
          block[3 * pc + k] = Pgrid.Pos(i,k, type) + outdata.Vel(i,k);
          if(twolpt)
                block[3 * pc + k] -= 3./7. * outdata.Vel2(i,k);
          block[3 * pc + k] = periodic_wrap(block[3*pc+k], Pgrid.GetBox());
      }
      pc++;

#ifdef NEUTRINO_PAIRS
      /*Add an extra copy of the position vector for the double neutrino*/
      if(type == NEUTRINO_TYPE) {
	  for(int k = 0; k < 3; k++)
	    block[3 * pc + k] = periodic_wrap(Pgrid.Pos(i,k,type) + outdata.Vel(i,k), Pgrid.GetBox());
	  pc++;
      }
#endif //NEUTRINO_PAIRS

      if(pc > blockmaxlen){
	  if(snap.WriteBlocks(posstr,type, block, pc,written) != pc)
                  FatalError(2);
          written+=pc;
	  pc = 0;
	}
  }
  if(pc > 0)
	  if(snap.WriteBlocks(posstr,type, block, pc,written) != pc)
                  FatalError(2);
  /*Done writing POS block*/
  written=0;
  pc = 0;

  /* write velocities: sizes are the same as for positions */
  for(int64_t i = 0; i < NumPart; i++) {
      for(int k = 0; k < 3; k++){
          block[3 * pc + k] = vel_prefac*outdata.Vel(i,k);
          if(twolpt)
                block[3 * pc + k] += vel_prefac2* outdata.Vel2(i,k);
      }

      //Add thermal velocities
      if(therm_vels) {
#ifdef NEUTRINO_PAIRS
          float vtherm[3];
          for(int k = 0; k < 3; k++)
              vtherm[k] = 0;
          therm_vels->add_thermal_speeds(vtherm);
          for(int k = 0; k < 3; k++)
              block[3 * pc + k] = vel_prefac*outdata.Vel(i,k) + vtherm[k];
          pc++;
          for(int k = 0; k < 3; k++)
              block[3 * pc + k] = vel_prefac*outdata.Vel(i,k) - vtherm[k];
#else
          therm_vels->add_thermal_speeds(&block[3 * pc]);
#endif //NEUTRINO_PAIRS
      }
      pc++;

      if(pc > blockmaxlen){
          if(snap.WriteBlocks(velstr,type, block, pc,written) != pc)
                  FatalError(2);
          written+=pc;
          pc = 0;
      }
  }
  if(pc > 0)
	  if(snap.WriteBlocks(velstr,type, block, pc,written) != pc)
                  FatalError(2);

  /* write particle ID */
  written=0;
  pc = 0;
  blockid = (id_type *) block;
  for(int64_t i = 0; i < NumPart; i++) {
      blockid[pc] = i+FirstId;
      pc++;

#ifdef NEUTRINO_PAIRS
      if(type == 2) {
	  blockid[pc] = i+FirstId+NumPart;
	  pc++;
	}
#endif //NEUTRINO_PAIRS

      if(pc > blockmaxlen){
	  if(snap.WriteBlocks(idstr,type, block, pc,written) != pc)
                  FatalError(2);
          written+=pc;
	  pc = 0;
      }
  }
  if(pc > 0)
	  if(snap.WriteBlocks(idstr,type, block, pc,written) != pc)
                  FatalError(2);

  /*Done writing IDs*/

  /* write zero temperatures if needed */
  if(type== 0) {
      written=0;
      pc = 0;
      for(int64_t i = 0; i < NumPart; i++) {
          block[pc] = 0;
          pc++;
          if(pc > blockmaxlen){
              if(snap.WriteBlocks(ustr,type, block, pc,written) != pc)
                  FatalError(2);
              written+=pc;
              pc = 0;
          }
      }
      if(pc > 0)
         if(snap.WriteBlocks(ustr,type, block, pc,written) != pc)
                  FatalError(2);
  }
  /*Done writing temperatures*/

  free(block);
  printf("Finished writing IC file.\n");
  FirstId+=NumPart;
#ifdef NEUTRINO_PAIRS
  if(type==2)
          FirstId+=NumPart;
#endif
  return FirstId;
}

double periodic_wrap(double x, double box)
{
  x = fmod(x, box);

  if (x < 0)
    x += box;

  return x;
}

<commit_msg>Use the newly added format detection function instead of ICFormat in save.cpp, and remove allvars.h header<commit_after>#include "proto.h"
#include "part_data.hpp"
#include "thermalvel.hpp"
#include <gadgetwriter.hpp>

using namespace GadgetWriter;
using namespace std;

#define BUFFER 48

int64_t write_particle_data(GWriteSnap & snap, int type, lpt_data& outdata, part_grid& Pgrid, FermiDiracVel *therm_vels, const double vel_prefac, const double vel_prefac2, int64_t FirstId, const bool twolpt)
{
  const int64_t NumPart = outdata.GetNumPart();
  float *block;
  id_type *blockid;
  int64_t written=0, pc;
  std::string posstr("POS ");
  std::string velstr("VEL ");
  std::string idstr("ID  ");
  std::string ustr("U   ");
  //HDF5 has different strings
  if(snap.GetFormat() == 3){
      posstr = "Coordinates";
      velstr = "Velocities";
      idstr = "ParticleIDs";
      ustr = "InternalEnergy";
  }
  printf("\nWriting IC-file\n");
  const int64_t blockmaxlen = BUFFER * 1024 * 1024;
  if(!(block = (float *) malloc(blockmaxlen*3*sizeof(float))))
    {
      printf("failed to allocate memory for `block' (%ld MB).\n", 3*sizeof(float)*blockmaxlen/1024/1024);
      exit(24);
    }

  /*We are about to write the POS block*/
  /* Add displacement to Lagrangian coordinates, and multiply velocities by correct factor when writing VEL*/
  pc = 0;
  for(int64_t i = 0; i < NumPart; i++){
      for(int k = 0; k < 3; k++){
          block[3 * pc + k] = Pgrid.Pos(i,k, type) + outdata.Vel(i,k);
          if(twolpt)
                block[3 * pc + k] -= 3./7. * outdata.Vel2(i,k);
          block[3 * pc + k] = periodic_wrap(block[3*pc+k], Pgrid.GetBox());
      }
      pc++;

#ifdef NEUTRINO_PAIRS
      /*Add an extra copy of the position vector for the double neutrino*/
      if(type == NEUTRINO_TYPE) {
	  for(int k = 0; k < 3; k++)
	    block[3 * pc + k] = periodic_wrap(Pgrid.Pos(i,k,type) + outdata.Vel(i,k), Pgrid.GetBox());
	  pc++;
      }
#endif //NEUTRINO_PAIRS

      if(pc > blockmaxlen){
	  if(snap.WriteBlocks(posstr,type, block, pc,written) != pc)
                  FatalError(2);
          written+=pc;
	  pc = 0;
	}
  }
  if(pc > 0)
	  if(snap.WriteBlocks(posstr,type, block, pc,written) != pc)
                  FatalError(2);
  /*Done writing POS block*/
  written=0;
  pc = 0;

  /* write velocities: sizes are the same as for positions */
  for(int64_t i = 0; i < NumPart; i++) {
      for(int k = 0; k < 3; k++){
          block[3 * pc + k] = vel_prefac*outdata.Vel(i,k);
          if(twolpt)
                block[3 * pc + k] += vel_prefac2* outdata.Vel2(i,k);
      }

      //Add thermal velocities
      if(therm_vels) {
#ifdef NEUTRINO_PAIRS
          float vtherm[3];
          for(int k = 0; k < 3; k++)
              vtherm[k] = 0;
          therm_vels->add_thermal_speeds(vtherm);
          for(int k = 0; k < 3; k++)
              block[3 * pc + k] = vel_prefac*outdata.Vel(i,k) + vtherm[k];
          pc++;
          for(int k = 0; k < 3; k++)
              block[3 * pc + k] = vel_prefac*outdata.Vel(i,k) - vtherm[k];
#else
          therm_vels->add_thermal_speeds(&block[3 * pc]);
#endif //NEUTRINO_PAIRS
      }
      pc++;

      if(pc > blockmaxlen){
          if(snap.WriteBlocks(velstr,type, block, pc,written) != pc)
                  FatalError(2);
          written+=pc;
          pc = 0;
      }
  }
  if(pc > 0)
	  if(snap.WriteBlocks(velstr,type, block, pc,written) != pc)
                  FatalError(2);

  /* write particle ID */
  written=0;
  pc = 0;
  blockid = (id_type *) block;
  for(int64_t i = 0; i < NumPart; i++) {
      blockid[pc] = i+FirstId;
      pc++;

#ifdef NEUTRINO_PAIRS
      if(type == 2) {
	  blockid[pc] = i+FirstId+NumPart;
	  pc++;
	}
#endif //NEUTRINO_PAIRS

      if(pc > blockmaxlen){
	  if(snap.WriteBlocks(idstr,type, block, pc,written) != pc)
                  FatalError(2);
          written+=pc;
	  pc = 0;
      }
  }
  if(pc > 0)
	  if(snap.WriteBlocks(idstr,type, block, pc,written) != pc)
                  FatalError(2);

  /*Done writing IDs*/

  /* write zero temperatures if needed */
  if(type== 0) {
      written=0;
      pc = 0;
      for(int64_t i = 0; i < NumPart; i++) {
          block[pc] = 0;
          pc++;
          if(pc > blockmaxlen){
              if(snap.WriteBlocks(ustr,type, block, pc,written) != pc)
                  FatalError(2);
              written+=pc;
              pc = 0;
          }
      }
      if(pc > 0)
         if(snap.WriteBlocks(ustr,type, block, pc,written) != pc)
                  FatalError(2);
  }
  /*Done writing temperatures*/

  free(block);
  printf("Finished writing IC file.\n");
  FirstId+=NumPart;
#ifdef NEUTRINO_PAIRS
  if(type==2)
          FirstId+=NumPart;
#endif
  return FirstId;
}

double periodic_wrap(double x, double box)
{
  x = fmod(x, box);

  if (x < 0)
    x += box;

  return x;
}

<|endoftext|>