<commit_before>// show default grid setup of 2D point contact detectors
{
   GeFiCa::PointContactDZ pcdz;
   pcdz.Dump(); // call TObject::Dump() to print data members
   pcdz.HoleR=5*GeFiCa::mm; pcdz.HoleH=3*GeFiCa::cm; // add bore hole
   pcdz.HoleTaperW=2*GeFiCa::mm; pcdz.HoleTaperH=2*GeFiCa::mm; // add taper
   pcdz.WrapAroundR=2*GeFiCa::cm; // add wrap arround
   pcdz.GrooveW=2*GeFiCa::mm; pcdz.GrooveH=2*GeFiCa::mm; // add groove
   TTree *t = pcdz.GetTree(); // create a ROOT tree for quick check
   gStyle->SetPadRightMargin(0.12); // give enough space for color palette
   t->Draw("c2:c1:v","","colz"); // visualize initial setup
}
<commit_msg>started to use GetBoundaryConditionFrom<commit_after>// show default grid setup of 2D point contact detectors
{
   GeFiCa::PointContact detector;
   detector.Dump(); // call TObject::Dump() to print data members
   detector.BoreR=5*GeFiCa::mm; detector.BoreH=3*GeFiCa::cm; // add bore hole
   detector.BoreTaperW=2*GeFiCa::mm; detector.BoreTaperH=2*GeFiCa::mm; // add taper
   detector.WrapAroundR=2*GeFiCa::cm; // add wrap arround
   detector.GrooveW=2*GeFiCa::mm; detector.GrooveH=2*GeFiCa::mm; // add groove

   GeFiCa::RhoZ grid;
   grid.GetBoundaryConditionFrom(detector);
   TTree *t = grid.GetTree(); // create a ROOT tree for quick check
   gStyle->SetPadRightMargin(0.12); // give enough space for color palette
   t->Draw("c2:c1:v","","colz"); // visualize initial setup
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <fstream>

struct Field {
  std::string name;
  std::string value;
};

using Fields = std::vector<Field>;

struct Entry {
  std::string type;
  std::string key;
  Fields fields;
  std::string comment;
};

using Entries = std::vector<Entry>;

enum ParserState {
  LIMBO,
  ENTRY_TYPE,
  ENTRY_KEY,
  FIELD_LIMBO,
  FIELD_NAME,
  FIELD_POST_EQUAL,
  FIELD_VALUE_TEXT,
  FIELD_VALUE_SPACE,
  COMMENT
};

enum FieldValueLimit {
  FVL_NONE,
  FVL_CURLY,
  FVL_QUOTE
};

static void make_lowercase(std::string& s) {
  std::transform(s.begin(), s.end(), s.begin(), ::tolower);
}

static std::string as_lowercase(std::string const& s) {
  std::string s2 = s;
  make_lowercase(s2);
  return s2;
}

static void print_entries(std::ostream& stream, Entries const& entries);

static bool isident(char c) {
  return std::isalnum(c) || c == '-' || c == '_' ||
    c == '.' || c == ':';
}

class Parser {
  ParserState state;
  int line;
  int column;
  int curly_depth;
  FieldValueLimit value_limit;
  Entries entries;

  bool is_curly(char c) {
    return c == '{' || c == '}';
  }

  void handle_curly(char c) {
    if (c == '{') ++curly_depth;
    if (c == '}') --curly_depth;
    if (curly_depth < 0) fail();
  }

  void fail() __attribute__((noreturn));

  bool field_value_ended(char c) {
    if (curly_depth != 0) return false;
    switch (value_limit) {
      case FVL_NONE: return c == ',';
      case FVL_CURLY: return c == '}';
      case FVL_QUOTE: return c == '"';
    }
  }

public:

  void run(std::istream& stream) {
    entries.clear();
    state = LIMBO;
    line = 1;
    column = 0;
    curly_depth = 0;
    char c;
    while (stream.get(c)) {
      if (c == '\n') {
        ++line;
        column = 0;
      } else {
        ++column;
      }
      switch (state) {
        case LIMBO:
          if (std::isspace(c)) break;
          else if (c == '@') {
            state = ENTRY_TYPE;
            entries.push_back(Entry());
          } else {
            entries.push_back(Entry());
            entries.back().type = "comment";
            entries.back().comment.push_back(c);
            state = COMMENT;
          }
        break;
        case ENTRY_TYPE:
          if (std::isspace(c)) {
            if (as_lowercase(entries.back().type) == "comment") {
              make_lowercase(entries.back().type);
              state = COMMENT;
            } else break;
          }
          else if (c == '{') {
            make_lowercase(entries.back().type);
            if (entries.back().type == "string") state = FIELD_LIMBO;
            else state = ENTRY_KEY;
          }
          else if (std::isalpha(c)) {
            entries.back().type.push_back(c);
          }
          else fail();
        break;
        case ENTRY_KEY:
          if (std::isspace(c)) break;
          else if (c == ',') {
            make_lowercase(entries.back().key);
            state = FIELD_LIMBO;
          }
          else if (isident(c)) {
            entries.back().key.push_back(c);
          }
          else fail();
        break;
        case FIELD_LIMBO:
          if (std::isspace(c)) break;
          else if (std::isalpha(c)) {
            entries.back().fields.push_back(Field());
            entries.back().fields.back().name.push_back(c);
            state = FIELD_NAME;
          } else if (c == '}') state = LIMBO;
          else if (c == ',') break;
          else fail();
        break;
        case FIELD_NAME:
          if (std::isspace(c)) break;
          else if (isident(c)) {
            entries.back().fields.back().name.push_back(c);
          } else if (c == '=') {
            make_lowercase(entries.back().fields.back().name);
            state = FIELD_POST_EQUAL;
          } else fail();
        break;
        case FIELD_POST_EQUAL:
          if (std::isspace(c)) break;
          else if (c == '{') {
            state = FIELD_VALUE_TEXT;
            value_limit = FVL_CURLY;
          } else if (c == '"') {
            state = FIELD_VALUE_TEXT;
            value_limit = FVL_QUOTE;
          } else if (std::isprint(c)) {
            value_limit = FVL_NONE;
            if (is_curly(c)) handle_curly(c);
            entries.back().fields.back().value.push_back(c);
            state = FIELD_VALUE_TEXT;
          } else fail();
        break;
        case FIELD_VALUE_TEXT:
          if (std::isspace(c)) state = FIELD_VALUE_SPACE;
          else if (field_value_ended(c)) {
            state = FIELD_LIMBO;
          } else if (std::isprint(c)) {
            if (is_curly(c)) handle_curly(c);
            entries.back().fields.back().value.push_back(c);
          } else fail();
        break;
        case FIELD_VALUE_SPACE:
          if (std::isspace(c)) break;
          else if (field_value_ended(c)) {
            state = FIELD_LIMBO;
          } else if (std::isprint(c)) {
            if (is_curly(c)) handle_curly(c);
            entries.back().fields.back().value.push_back(' ');
            entries.back().fields.back().value.push_back(c);
            state = FIELD_VALUE_TEXT;
          } else fail();
        break;
        case COMMENT:
          if (c == '\n') state = LIMBO;
          else entries.back().comment.push_back(c);
        break;
      }
    }
    if (state != LIMBO) {
      std::cout << "File ended early\n";
      exit(-1);
    }
  }

};

void Parser::fail() {
  std::cout << "Parse error at line " << line << " column " << column;
  std::cout << " state \"";
  switch (state) {
    case LIMBO: std::cout << "limbo"; break;
    case ENTRY_TYPE: std::cout << "entry type"; break;
    case ENTRY_KEY: std::cout << "entry key"; break;
    case FIELD_LIMBO: std::cout << "field limbo"; break;
    case FIELD_NAME: std::cout << "field name"; break;
    case FIELD_POST_EQUAL: std::cout << "field post equal"; break;
    case FIELD_VALUE_TEXT: std::cout << "field value text"; break;
    case FIELD_VALUE_SPACE: std::cout << "field value space"; break;
    case COMMENT: std::cout << "comment"; break;
  }
  std::cout << "\"\n";
  print_entries(std::cout, entries);
  exit(-1);
}

static void print_field(std::ostream& stream, Field const& field, bool last) {
  stream << "  " << field.name << "={" << field.value << "}";
  if (!last) stream << ",";
  stream << '\n';
}

static void print_fields(std::ostream& stream, Fields const& fields) {
  if (fields.empty()) return;
  for (size_t i = 0; i < fields.size() - 1; ++i)
    print_field(stream, fields[i], false);
  print_field(stream, fields.back(), true);
}

static void print_entry(std::ostream& stream, Entry const& entry) {
  if (entry.type == "comment") {
    stream << entry.comment << '\n';
    return;
  }
  stream << "@" << entry.type << "{";
  if (entry.type != "string") stream << entry.key << ",";
  stream << "\n";
  print_fields(stream, entry.fields);
  stream << "}\n\n";
}

static void print_entries(std::ostream& stream, Entries const& entries) {
  for (auto entry : entries) print_entry(stream, entry);
}

int main(int argc, char** argv) {
  if (argc != 2) {
    std::cout << "usage: " << argv[0] << " input.bib\n";
    return -1;
  }
  std::ifstream file(argv[1]);
  Parser parser;
  parser.run(file);
}
<commit_msg>debug some more issues with exposed field values<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <fstream>

struct Field {
  std::string name;
  std::string value;
};

using Fields = std::vector<Field>;

struct Entry {
  std::string type;
  std::string key;
  Fields fields;
  std::string comment;
};

using Entries = std::vector<Entry>;

enum ParserState {
  LIMBO,
  ENTRY_TYPE,
  ENTRY_KEY,
  FIELD_LIMBO,
  FIELD_NAME,
  FIELD_POST_EQUAL,
  FIELD_VALUE_TEXT,
  FIELD_VALUE_SPACE,
  COMMENT
};

enum FieldValueLimit {
  FVL_NONE,
  FVL_CURLY,
  FVL_QUOTE
};

static void make_lowercase(std::string& s) {
  std::transform(s.begin(), s.end(), s.begin(), ::tolower);
}

static std::string as_lowercase(std::string const& s) {
  std::string s2 = s;
  make_lowercase(s2);
  return s2;
}

static void print_entries(std::ostream& stream, Entries const& entries);

static bool isident(char c) {
  return std::isalnum(c) || c == '-' || c == '_' ||
    c == '.' || c == ':';
}

class Parser {
  ParserState state;
  int line;
  int column;
  int curly_depth;
  FieldValueLimit value_limit;
  Entries entries;
  char c;

  bool is_curly() {
    return c == '{' || c == '}';
  }

  void handle_curly() {
    if (!is_curly()) return;
    if (c == '{') ++curly_depth;
    if (c == '}') --curly_depth;
    if (curly_depth < 0) fail();
  }

  void fail() __attribute__((noreturn));

  bool field_value_ended() {
    if (curly_depth != 0) return false;
    switch (value_limit) {
      case FVL_NONE: return c == ',' || c == '\n';
      case FVL_CURLY: return c == '}';
      case FVL_QUOTE: return c == '"';
    }
  }

public:

  void run(std::istream& stream) {
    entries.clear();
    state = LIMBO;
    line = 1;
    column = 0;
    curly_depth = 0;
    while (stream.get(c)) {
      if (c == '\n') {
        ++line;
        column = 0;
      } else {
        ++column;
      }
      switch (state) {
        case LIMBO:
          if (std::isspace(c)) break;
          else if (c == '@') {
            state = ENTRY_TYPE;
            entries.push_back(Entry());
          } else {
            entries.push_back(Entry());
            entries.back().type = "comment";
            entries.back().comment.push_back(c);
            state = COMMENT;
          }
        break;
        case ENTRY_TYPE:
          if (std::isspace(c)) {
            if (as_lowercase(entries.back().type) == "comment") {
              make_lowercase(entries.back().type);
              state = COMMENT;
            } else break;
          }
          else if (c == '{') {
            make_lowercase(entries.back().type);
            if (entries.back().type == "string") state = FIELD_LIMBO;
            else state = ENTRY_KEY;
          }
          else if (std::isalpha(c)) {
            entries.back().type.push_back(c);
          }
          else fail();
        break;
        case ENTRY_KEY:
          if (std::isspace(c)) break;
          else if (c == ',') {
            make_lowercase(entries.back().key);
            state = FIELD_LIMBO;
          }
          else if (isident(c)) {
            entries.back().key.push_back(c);
          }
          else fail();
        break;
        case FIELD_LIMBO:
          if (std::isspace(c)) break;
          else if (std::isalpha(c)) {
            entries.back().fields.push_back(Field());
            entries.back().fields.back().name.push_back(c);
            state = FIELD_NAME;
          } else if (c == '}') state = LIMBO;
          else if (c == ',') break;
          else fail();
        break;
        case FIELD_NAME:
          if (std::isspace(c)) break;
          else if (isident(c)) {
            entries.back().fields.back().name.push_back(c);
          } else if (c == '=') {
            make_lowercase(entries.back().fields.back().name);
            state = FIELD_POST_EQUAL;
          } else fail();
        break;
        case FIELD_POST_EQUAL:
          if (std::isspace(c)) break;
          else if (c == '{') {
            state = FIELD_VALUE_TEXT;
            value_limit = FVL_CURLY;
          } else if (c == '"') {
            state = FIELD_VALUE_TEXT;
            value_limit = FVL_QUOTE;
          } else if (std::isprint(c)) {
            value_limit = FVL_NONE;
            handle_curly();
            entries.back().fields.back().value.push_back(c);
            state = FIELD_VALUE_TEXT;
          } else fail();
        break;
        case FIELD_VALUE_TEXT:
          if (field_value_ended()) {
            state = FIELD_LIMBO;
          } else if (std::isspace(c)) {
            state = FIELD_VALUE_SPACE;
          } else if (std::isprint(c)) {
            handle_curly();
            entries.back().fields.back().value.push_back(c);
          } else fail();
        break;
        case FIELD_VALUE_SPACE:
          if (field_value_ended()) {
            state = FIELD_LIMBO;
          } else if (std::isspace(c)) {
            break;
          } else if (std::isprint(c)) {
            handle_curly();
            entries.back().fields.back().value.push_back(' ');
            entries.back().fields.back().value.push_back(c);
            state = FIELD_VALUE_TEXT;
          } else fail();
        break;
        case COMMENT:
          if (c == '\n') state = LIMBO;
          else entries.back().comment.push_back(c);
        break;
      }
    }
    if (state != LIMBO) {
      std::cout << "File ended early\n";
      exit(-1);
    }
  }

};

void Parser::fail() {
  std::cout << "Parse error at line " << line << " column " << column;
  std::cout << " char " << c;
  std::cout << " state \"";
  switch (state) {
    case LIMBO: std::cout << "limbo"; break;
    case ENTRY_TYPE: std::cout << "entry type"; break;
    case ENTRY_KEY: std::cout << "entry key"; break;
    case FIELD_LIMBO: std::cout << "field limbo"; break;
    case FIELD_NAME: std::cout << "field name"; break;
    case FIELD_POST_EQUAL: std::cout << "field post equal"; break;
    case FIELD_VALUE_TEXT: std::cout << "field value text"; break;
    case FIELD_VALUE_SPACE: std::cout << "field value space"; break;
    case COMMENT: std::cout << "comment"; break;
  }
  std::cout << "\"\n";
  std::cout << "curly depth " << curly_depth;
  std::cout << " value delimiter ";
  switch (value_limit) {
    case FVL_NONE: std::cout << "none"; break;
    case FVL_CURLY: std::cout << "}"; break;
    case FVL_QUOTE: std::cout << "\""; break;
  }
  std::cout << '\n';
  print_entries(std::cout, entries);
  exit(-1);
}

static void print_field(std::ostream& stream, Field const& field, bool last) {
  stream << "  " << field.name << "={" << field.value << "}";
  if (!last) stream << ",";
  stream << '\n';
}

static void print_fields(std::ostream& stream, Fields const& fields) {
  if (fields.empty()) return;
  for (size_t i = 0; i < fields.size() - 1; ++i)
    print_field(stream, fields[i], false);
  print_field(stream, fields.back(), true);
}

static void print_entry(std::ostream& stream, Entry const& entry) {
  if (entry.type == "comment") {
    stream << entry.comment << '\n';
    return;
  }
  stream << "@" << entry.type << "{";
  if (entry.type != "string") stream << entry.key << ",";
  stream << "\n";
  print_fields(stream, entry.fields);
  stream << "}\n\n";
}

static void print_entries(std::ostream& stream, Entries const& entries) {
  for (auto entry : entries) print_entry(stream, entry);
}

int main(int argc, char** argv) {
  if (argc != 2) {
    std::cout << "usage: " << argv[0] << " input.bib\n";
    return -1;
  }
  std::ifstream file(argv[1]);
  Parser parser;
  parser.run(file);
}
<|endoftext|>


<commit_before><commit_msg>forgot one to delete<commit_after><|endoftext|>


<commit_before>// Copyright 2014 Ryuichi Ueda
// Released under the MIT License.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include "Exe.h"
#include "DefFile.h"
#include "DefStr.h"
#include "Pipeline.h"
#include "Arg.h"
#include "Feeder.h"
#include "Environment.h"
#include "DataJob.h"
#include "DataFile.h"
#include "Job.h"
#include "Where.h"
using namespace std;

Job::Job(Feeder *f, Environment *env) : Element(f,env)
{
	m_outfile = NULL;
	m_outstr = NULL;
	m_where = NULL;
	m_is_background = false;

	m_local_env = NULL;
}

Job::~Job()
{
	if(m_where != NULL)
		delete m_where;
}

void Job::print(int indent_level)
{
}

/* parse of a job, which is a set of pipelines combined by >> or !>.

	file f = command ... >>= command ... >> ...
	command ... !> command ... >>= ...

* to do:
	to implement file redirection for standard error, like
	file f1 f2 = command ...

	The way of writting for redirection of standard error
	toward one command line will be an issue.
*/
bool Job::parse(void)
{
	m_feeder->getPos(&m_start_line, &m_start_char);

	// scanning of file name
	// If `file <filename> =` is found,
	// the DefFile object is pushed as the first element of m_nodes.
	// This node is also given to the last command line.
	if(add(new DefFile(m_feeder,m_env))){
		m_outfile = (DefFile *)m_nodes[0];
		m_nodes.pop_back();
	}else if(add(new DefStr(m_feeder,m_env))){
		m_outstr = (DefStr *)m_nodes[0];
		m_nodes.pop_back();
	}

	int comnum = 0;
	while(1){
		if(add(new Pipeline(m_feeder,m_env)))
			comnum++;
		else
			break;

		m_feeder->getPos(&m_end_line, &m_end_char);
		m_feeder->blank();

		size_t num = m_nodes.size();
		Pipeline *back1 = (Pipeline *)m_nodes.back();
		Pipeline *back2 = num >= 2 ? (Pipeline *)m_nodes[num-2] : NULL;

		if(m_feeder->str(">>")){
			back1->m_has_and = true;
		}else if(m_feeder->str("?>")){
			back1->m_has_then = true;
		}else if(m_feeder->str("!>")){
			if(back2 != NULL and ( back2->m_has_and or back2->m_has_then) )
				back2->m_has_or = true;
			else
				back1->m_has_or = true;
		}else{
			m_feeder->setPos(m_end_line, m_end_char);
			break;
		}
	}

	if(comnum < 1){
		m_feeder->setPos(m_start_line,m_start_char);
		return false;
	}

	// whether background proc or not
	if(m_feeder->str("&")){
		m_is_background = true;
		if(! m_feeder->variable(&m_job_name)){
			m_error_msg = "no job name";
			m_exit_status = 2;
			throw this;
		}

		DataJob *d = new DataJob();
		d->setData(&m_job_name);

		try{
			m_env->setData(&m_job_name,d);
		}catch(Environment *e){
			m_error_msg = e->m_error_msg;
			m_exit_status = 2;
			throw this;
		}
	}

	setJobId(m_env->publishJobId());
	if(add(new Where(m_feeder,m_env))){
		m_where = (Where *)m_nodes.back();
		m_nodes.pop_back();
		// give conditions to strings
		if(m_outstr != NULL){
			m_outstr->m_condition = m_where->findCond(&m_outstr->m_var_name);
		}

	}
	if(m_outstr != NULL)	m_outstr->setJobId(m_job_id);
	if(m_outfile != NULL)	m_outfile->setJobId(m_job_id);
	if(m_where != NULL)	m_where->setJobId(m_job_id);

	m_feeder->getPos(&m_end_line, &m_end_char);
	return true;
}

int Job::exec(DefFile *f, DefFile *ef, DefStr *s, DefStr *es)
{
	if(m_outfile != NULL)
		f = m_outfile;
	if(m_outstr != NULL)
		s = m_outstr;
	// stdout of all commands are appended into a file
	/*
	for(auto *n : m_nodes){
		((Pipeline *)n)->m_outfile = m_outfile;
		((Pipeline *)n)->m_outstr = m_outstr;
	}*/

	cout << flush;

	eval();

	if(m_where != NULL){
		m_where->exec(f,ef,s,es);
		m_local_env = m_where->m_local_env;
	}

	if(m_is_background)
		return execBackGround(f,ef,s,es);

	return execNormal(f,ef,s,es);
}

int Job::execNormal(DefFile *f, DefFile *ef, DefStr *s, DefStr *es)
{
	bool skip = false; // flag to skip the next command
	bool stop_next = false; // stop after then
	for(int i=0;i<(int)m_nodes.size();i++){
		if(skip){
			skip = false;
			continue;
		}

		auto *p = (Pipeline *)m_nodes[i];
		if(f != NULL && i!=0)
			f->m_data->setAppend();

		int exs = p->exec(f,ef,s,es);
		if(stop_next)
			return exs;

		if(p->m_has_and and exs != 0){
			skip = true;
		}else if(p->m_has_or and exs == 0){
			skip = true;
		}

		if(p->m_has_then and exs == 0){
			stop_next = true;
		}else if(p->m_has_then and exs != 0){
			skip = true;
		}
	}
	return 0;
}

int Job::execBackGround(DefFile *f, DefFile *ef, DefStr *s, DefStr *es)
{
	int pid = fork();
	if(pid < 0)
		exit(4);

	if (pid == 0){//child
		if(m_env->m_v_opt)
			cerr << "+ pid " << m_env->m_pid << " fork " << m_job_name << endl;

		for(int i=0;i<(int)m_nodes.size();i++){
			auto *p = (Pipeline *)m_nodes[i];
			if(m_outfile != NULL && i!=0)
				m_outfile->m_data->setAppend();

			p->exec(f,ef,s,es);
		}
		exit(0);
	}

	try{
		DataJob *p = (DataJob *)m_env->getData(&m_job_name);
		p->m_pid = pid;
	}catch(...){
		m_error_msg = "Bug of backgound process";
		m_exit_status = 2;
		throw this;
	}

	return 0;
}
<commit_msg>Clean Job.cc<commit_after>// Copyright 2014 Ryuichi Ueda
// Released under the MIT License.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include "Exe.h"
#include "DefFile.h"
#include "DefStr.h"
#include "Pipeline.h"
#include "Arg.h"
#include "Feeder.h"
#include "Environment.h"
#include "DataJob.h"
#include "DataFile.h"
#include "Job.h"
#include "Where.h"
using namespace std;

Job::Job(Feeder *f, Environment *env) : Element(f,env)
{
	m_outfile = NULL;
	m_outstr = NULL;
	m_where = NULL;
	m_is_background = false;

	m_local_env = NULL;
}

Job::~Job()
{
	if(m_where != NULL)
		delete m_where;
}

void Job::print(int indent_level)
{
}

/* parse of a job, which is a set of pipelines combined by >> or !>.

	file f = command ... >>= command ... >> ...
	command ... !> command ... >>= ...

* to do:
	to implement file redirection for standard error, like
	file f1 f2 = command ...

	The way of writting for redirection of standard error
	toward one command line will be an issue.
*/
bool Job::parse(void)
{
	m_feeder->getPos(&m_start_line, &m_start_char);

	// scanning of file name
	// If `file <filename> =` is found,
	// the DefFile object is pushed as the first element of m_nodes.
	// This node is also given to the last command line.
	if(add(new DefFile(m_feeder,m_env))){
		m_outfile = (DefFile *)m_nodes[0];
		m_nodes.pop_back();
	}else if(add(new DefStr(m_feeder,m_env))){
		m_outstr = (DefStr *)m_nodes[0];
		m_nodes.pop_back();
	}

	int comnum = 0;
	while(1){
		if(add(new Pipeline(m_feeder,m_env)))
			comnum++;
		else
			break;

		m_feeder->getPos(&m_end_line, &m_end_char);
		m_feeder->blank();

		size_t num = m_nodes.size();
		Pipeline *back1 = (Pipeline *)m_nodes.back();
		Pipeline *back2 = num >= 2 ? (Pipeline *)m_nodes[num-2] : NULL;

		if(m_feeder->str(">>")){
			back1->m_has_and = true;
		}else if(m_feeder->str("?>")){
			back1->m_has_then = true;
		}else if(m_feeder->str("!>")){
			if(back2 != NULL and ( back2->m_has_and or back2->m_has_then) )
				back2->m_has_or = true;
			else
				back1->m_has_or = true;
		}else{
			m_feeder->setPos(m_end_line, m_end_char);
			break;
		}
	}

	if(comnum < 1){
		m_feeder->setPos(m_start_line,m_start_char);
		return false;
	}

	// whether background proc or not
	if(m_feeder->str("&")){
		m_is_background = true;
		if(! m_feeder->variable(&m_job_name)){
			m_error_msg = "no job name";
			m_exit_status = 2;
			throw this;
		}

		DataJob *d = new DataJob();
		d->setData(&m_job_name);

		try{
			m_env->setData(&m_job_name,d);
		}catch(Environment *e){
			m_error_msg = e->m_error_msg;
			m_exit_status = 2;
			throw this;
		}
	}

	setJobId(m_env->publishJobId());
	if(add(new Where(m_feeder,m_env))){
		m_where = (Where *)m_nodes.back();
		m_nodes.pop_back();
		// give conditions to strings
		if(m_outstr != NULL){
			m_outstr->m_condition = m_where->findCond(&m_outstr->m_var_name);
		}

	}
	if(m_outstr != NULL)	m_outstr->setJobId(m_job_id);
	if(m_outfile != NULL)	m_outfile->setJobId(m_job_id);
	if(m_where != NULL)	m_where->setJobId(m_job_id);

	m_feeder->getPos(&m_end_line, &m_end_char);
	return true;
}

int Job::exec(DefFile *f, DefFile *ef, DefStr *s, DefStr *es)
{
	if(m_outfile != NULL)
		f = m_outfile;
	if(m_outstr != NULL)
		s = m_outstr;

	cout << flush;

	eval();

	if(m_where != NULL){
		m_where->exec(f,ef,s,es);
		m_local_env = m_where->m_local_env;
	}

	if(m_is_background)
		return execBackGround(f,ef,s,es);

	return execNormal(f,ef,s,es);
}

int Job::execNormal(DefFile *f, DefFile *ef, DefStr *s, DefStr *es)
{
	bool skip = false; // flag to skip the next command
	bool stop_next = false; // stop after then
	for(int i=0;i<(int)m_nodes.size();i++){
		if(skip){
			skip = false;
			continue;
		}

		auto *p = (Pipeline *)m_nodes[i];
		if(f != NULL && i!=0)
			f->m_data->setAppend();

		int exs = p->exec(f,ef,s,es);
		if(stop_next)
			return exs;

		if(p->m_has_and and exs != 0){
			skip = true;
		}else if(p->m_has_or and exs == 0){
			skip = true;
		}

		if(p->m_has_then and exs == 0){
			stop_next = true;
		}else if(p->m_has_then and exs != 0){
			skip = true;
		}
	}
	return 0;
}

int Job::execBackGround(DefFile *f, DefFile *ef, DefStr *s, DefStr *es)
{
	int pid = fork();
	if(pid < 0)
		exit(4);

	if (pid == 0){//child
		if(m_env->m_v_opt)
			cerr << "+ pid " << m_env->m_pid << " fork " << m_job_name << endl;

		for(int i=0;i<(int)m_nodes.size();i++){
			auto *p = (Pipeline *)m_nodes[i];
			if(f != NULL && i!=0)
				f->m_data->setAppend();

			p->exec(f,ef,s,es);
		}
		exit(0);
	}

	try{
		DataJob *p = (DataJob *)m_env->getData(&m_job_name);
		p->m_pid = pid;
	}catch(...){
		m_error_msg = "Bug of backgound process";
		m_exit_status = 2;
		throw this;
	}

	return 0;
}
<|endoftext|>


<commit_before>// dui-demo.cpp : main source file
//

#include "stdafx.h"
#include <helper/MenuWndHook.h>
#include <helper/mybuffer.h>
#include "httpsvr/HTTPServer.h"
#include "MemFlash.h"
#include "../controls.extend/propgrid/SPropertyGrid.h"
#include "../controls.extend/SFlyWnd.h"
#include "../controls.extend/SFadeFrame.h"
#include "../controls.extend/sradiobox2.h"
#include "uianimation/UiAnimationWnd.h"

#if defined(_DEBUG) && !defined(_WIN64)
// #include <vld.h>//ʹVitural Leaker Detectorڴй©Դhttp://vld.codeplex.com/
#endif

#include "MainDlg.h"

#define RES_TYPE 0   //ļмԴ
// #define RES_TYPE 1   //PEԴмUIԴ
// #define RES_TYPE 2   //zipмԴ

#include "../components/resprovider-zip/zipresprovider-param.h"

#ifdef _DEBUG
#define SYS_NAMED_RESOURCE _T("soui-sys-resourced.dll")
#else
#define SYS_NAMED_RESOURCE _T("soui-sys-resource.dll")
#endif

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpstrCmdLine*/, int /*nCmdShow*/)
{
    //ҪOleInitializeʼл
    HRESULT hRes = OleInitialize(NULL);
    SASSERT(SUCCEEDED(hRes));
    LoadLibrary(L"E:\\soui.taobao\\richedit\\Debug\\riched20.dll");

    int nRet = 0;

    SComMgr *pComMgr = new SComMgr;

    //·޸ĵdemoڵĿ¼
    TCHAR szCurrentDir[MAX_PATH]={0};
    GetModuleFileName( NULL, szCurrentDir, sizeof(szCurrentDir) );
    LPTSTR lpInsertPos = _tcsrchr( szCurrentDir, _T('\\') );
    _tcscpy(lpInsertPos,_T("\\..\\demo"));
    SetCurrentDirectory(szCurrentDir);

    {
        //һSOUIϵͳʹõCOM
        //CAutoRefPtrһSOUIϵͳʹõָ
        CAutoRefPtr<IImgDecoderFactory> pImgDecoderFactory; //ͼƬimagedecoder-wid.dllģṩ
        CAutoRefPtr<IRenderFactory> pRenderFactory;         //UIȾģ飬render-gdi.dllrender-skia.dllṩ
        CAutoRefPtr<ITranslatorMgr> trans;                  //Էģ飬translator.dllṩ
        CAutoRefPtr<IScriptModule> pScriptLua;              //luaűģ飬scriptmodule-lua.dllṩ

        BOOL bLoaded=FALSE;
        int nType=MessageBox(GetActiveWindow(),_T("ѡȾͣ\n[yes]: Skia\n[no]:GDI\n[cancel]:Quit"),_T("select a render"),MB_ICONQUESTION|MB_YESNOCANCEL);
        if(nType == IDCANCEL) return -1;
        //Ӹʾ

        if(nType == IDYES)
            bLoaded = pComMgr->CreateRender_Skia((IObjRef**)&pRenderFactory);
        else
            bLoaded = pComMgr->CreateRender_GDI((IObjRef**)&pRenderFactory);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),nType==IDYES?_T("render_skia"):_T("render_gdi"));
        bLoaded=pComMgr->CreateImgDecoder((IObjRef**)&pImgDecoderFactory);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("imgdecoder"));
        bLoaded=pComMgr->CreateTranslator((IObjRef**)&trans);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("translator"));

        //ΪȾģҪõͼƬģ
        pRenderFactory->SetImgDecoderFactory(pImgDecoderFactory);
        //һΨһSApplicationSApplicationӦóԴ
        SApplication *theApp=new SApplication(pRenderFactory,hInstance);

        //һ˸Դṩ,SOUIϵͳʵ3ԴطʽֱǴļأEXEԴؼZIPѹ
        CAutoRefPtr<IResProvider>   pResProvider;
#if (RES_TYPE == 0)//ļ
        CreateResProvider(RES_FILE,(IObjRef**)&pResProvider);
        if(!pResProvider->Init((LPARAM)_T("uires"),0))
        {
            SASSERT(0);
            return 1;
        }
#elif (RES_TYPE==1)//EXEԴ
        CreateResProvider(RES_PE,(IObjRef**)&pResProvider);
        pResProvider->Init((WPARAM)hInstance,0);
#elif (RES_TYPE==2)//ZIP
        bLoaded=pComMgr->CreateResProvider_ZIP((IObjRef**)&pResProvider);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("resprovider_zip"));

        ZIPRES_PARAM param;
        param.ZipFile(pRenderFactory, _T("uires.zip"),"souizip");
        bLoaded = pResProvider->Init((WPARAM)&param,0);
        SASSERT(bLoaded);
#endif
        //IResProviderSApplication
        theApp->AddResProvider(pResProvider);

        //һhttpԴмflash
        CMemFlash   memFlash;

        CHTTPServer flashSvr(&memFlash);
        flashSvr.Start(CMemFlash::HomeDir(),"",82,0);

        if(trans)
        {//Է
            theApp->SetTranslator(trans);
            pugi::xml_document xmlLang;
            if(theApp->LoadXmlDocment(xmlLang,_T("lang_cn"),_T("translator")))
            {
                CAutoRefPtr<ITranslator> langCN;
                trans->CreateTranslator(&langCN);
                langCN->Load(&xmlLang.child(L"language"),1);//1=LD_XML
                trans->InstallTranslator(langCN);
            }
        }
#ifdef DLL_CORE
        //LUAűģ飬ע⣬űģֻSOUIںDLLʽʱʹá
        bLoaded=pComMgr->CreateScrpit_Lua((IObjRef**)&pScriptLua);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("scirpt_lua"));

        if(pScriptLua)
        {
            theApp->SetScriptModule(pScriptLua);
            size_t sz=pResProvider->GetRawBufferSize(_T("script"),_T("lua_test"));
            if(sz)
            {
                CMyBuffer<char> lua;
                lua.Allocate(sz);
                pResProvider->GetRawBuffer(_T("script"),_T("lua_test"),lua,sz);
                pScriptLua->executeScriptBuffer(lua,sz);
            }
        }
#endif//DLL_CORE

        //SApplicationϵͳעⲿչĿؼSkinObj
        SWkeLoader wkeLoader;
        if(wkeLoader.Init(_T("wke.dll")))
        {
            theApp->RegisterWndFactory(TplSWindowFactory<SWkeWebkit>());//עWKE
        }
        theApp->RegisterWndFactory(TplSWindowFactory<SGifPlayer>());//עGIFPlayer
        theApp->RegisterSkinFactory(TplSkinFactory<SSkinGif>());//עSkinGif
        theApp->RegisterSkinFactory(TplSkinFactory<SSkinAPNG>());//עSkinGif

        theApp->RegisterWndFactory(TplSWindowFactory<SIPAddressCtrl>());//עIPؼ
        theApp->RegisterWndFactory(TplSWindowFactory<SPropertyGrid>());//עԱؼ

        if(SUCCEEDED(CUiAnimation::Init()))
        {
            theApp->RegisterWndFactory(TplSWindowFactory<SUiAnimationWnd>());//עᶯؼ
        }
        theApp->RegisterWndFactory(TplSWindowFactory<SFlyWnd>());//עжؼ
        theApp->RegisterWndFactory(TplSWindowFactory<SFadeFrame>());//עὥؼ
        theApp->RegisterWndFactory(TplSWindowFactory<SRadioBox2>());//עὥؼ
        SSkinGif::Gdiplus_Startup();

        //ϵͳԴ
        HMODULE hSysResource=LoadLibrary(SYS_NAMED_RESOURCE);
        if(hSysResource)
        {
            CAutoRefPtr<IResProvider> sysSesProvider;
            CreateResProvider(RES_PE,(IObjRef**)&sysSesProvider);
            sysSesProvider->Init((WPARAM)hSysResource,0);
            theApp->LoadSystemNamedResource(sysSesProvider);
        }
        //hookƲ˵ı߿
        CMenuWndHook::InstallHook(hInstance,L"_skin.sys.menu.border");

        //ȫԴXML
        theApp->Init(_T("xml_init"));

        {
            //ʾʹSOUIӦó򴰿,Ϊ˱洰ڶ󣬰һ㡣
            CMainDlg dlgMain;
            dlgMain.Create(GetActiveWindow(),0,0,800,600);
            dlgMain.GetNative()->SendMessage(WM_INITDIALOG);
            dlgMain.CenterWindow();
            dlgMain.ShowWindow(SW_SHOWNORMAL);
            nRet=theApp->Run(dlgMain.m_hWnd);
        }

        //Ӧó˳
        delete theApp;

        flashSvr.Shutdown();

        //жز˵߿hook
        CMenuWndHook::UnInstallHook();
        CUiAnimation::Free();

        SSkinGif::Gdiplus_Shutdown();
    }
    delete pComMgr;
    OleUninitialize();

    return nRet;
}

<commit_msg><commit_after>// dui-demo.cpp : main source file
//

#include "stdafx.h"
#include <helper/MenuWndHook.h>
#include <helper/mybuffer.h>
#include "httpsvr/HTTPServer.h"
#include "MemFlash.h"
#include "../controls.extend/propgrid/SPropertyGrid.h"
#include "../controls.extend/SFlyWnd.h"
#include "../controls.extend/SFadeFrame.h"
#include "../controls.extend/sradiobox2.h"
#include "uianimation/UiAnimationWnd.h"

#if defined(_DEBUG) && !defined(_WIN64)
// #include <vld.h>//ʹVitural Leaker Detectorڴй©Դhttp://vld.codeplex.com/
#endif

#include "MainDlg.h"

#define RES_TYPE 0   //ļмԴ
// #define RES_TYPE 1   //PEԴмUIԴ
// #define RES_TYPE 2   //zipмԴ

#include "../components/resprovider-zip/zipresprovider-param.h"

#ifdef _DEBUG
#define SYS_NAMED_RESOURCE _T("soui-sys-resourced.dll")
#else
#define SYS_NAMED_RESOURCE _T("soui-sys-resource.dll")
#endif

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpstrCmdLine*/, int /*nCmdShow*/)
{
    //ҪOleInitializeʼл
    HRESULT hRes = OleInitialize(NULL);
    SASSERT(SUCCEEDED(hRes));

    int nRet = 0;

    SComMgr *pComMgr = new SComMgr;

    //·޸ĵdemoڵĿ¼
    TCHAR szCurrentDir[MAX_PATH]={0};
    GetModuleFileName( NULL, szCurrentDir, sizeof(szCurrentDir) );
    LPTSTR lpInsertPos = _tcsrchr( szCurrentDir, _T('\\') );
    _tcscpy(lpInsertPos,_T("\\..\\demo"));
    SetCurrentDirectory(szCurrentDir);

    {
        //һSOUIϵͳʹõCOM
        //CAutoRefPtrһSOUIϵͳʹõָ
        CAutoRefPtr<IImgDecoderFactory> pImgDecoderFactory; //ͼƬimagedecoder-wid.dllģṩ
        CAutoRefPtr<IRenderFactory> pRenderFactory;         //UIȾģ飬render-gdi.dllrender-skia.dllṩ
        CAutoRefPtr<ITranslatorMgr> trans;                  //Էģ飬translator.dllṩ
        CAutoRefPtr<IScriptModule> pScriptLua;              //luaűģ飬scriptmodule-lua.dllṩ

        BOOL bLoaded=FALSE;
        int nType=MessageBox(GetActiveWindow(),_T("ѡȾͣ\n[yes]: Skia\n[no]:GDI\n[cancel]:Quit"),_T("select a render"),MB_ICONQUESTION|MB_YESNOCANCEL);
        if(nType == IDCANCEL) return -1;
        //Ӹʾ

        if(nType == IDYES)
            bLoaded = pComMgr->CreateRender_Skia((IObjRef**)&pRenderFactory);
        else
            bLoaded = pComMgr->CreateRender_GDI((IObjRef**)&pRenderFactory);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),nType==IDYES?_T("render_skia"):_T("render_gdi"));
        bLoaded=pComMgr->CreateImgDecoder((IObjRef**)&pImgDecoderFactory);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("imgdecoder"));
        bLoaded=pComMgr->CreateTranslator((IObjRef**)&trans);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("translator"));

        //ΪȾģҪõͼƬģ
        pRenderFactory->SetImgDecoderFactory(pImgDecoderFactory);
        //һΨһSApplicationSApplicationӦóԴ
        SApplication *theApp=new SApplication(pRenderFactory,hInstance);

        //һ˸Դṩ,SOUIϵͳʵ3ԴطʽֱǴļأEXEԴؼZIPѹ
        CAutoRefPtr<IResProvider>   pResProvider;
#if (RES_TYPE == 0)//ļ
        CreateResProvider(RES_FILE,(IObjRef**)&pResProvider);
        if(!pResProvider->Init((LPARAM)_T("uires"),0))
        {
            SASSERT(0);
            return 1;
        }
#elif (RES_TYPE==1)//EXEԴ
        CreateResProvider(RES_PE,(IObjRef**)&pResProvider);
        pResProvider->Init((WPARAM)hInstance,0);
#elif (RES_TYPE==2)//ZIP
        bLoaded=pComMgr->CreateResProvider_ZIP((IObjRef**)&pResProvider);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("resprovider_zip"));

        ZIPRES_PARAM param;
        param.ZipFile(pRenderFactory, _T("uires.zip"),"souizip");
        bLoaded = pResProvider->Init((WPARAM)&param,0);
        SASSERT(bLoaded);
#endif
        //IResProviderSApplication
        theApp->AddResProvider(pResProvider);

        //һhttpԴмflash
        CMemFlash   memFlash;

        CHTTPServer flashSvr(&memFlash);
        flashSvr.Start(CMemFlash::HomeDir(),"",82,0);

        if(trans)
        {//Է
            theApp->SetTranslator(trans);
            pugi::xml_document xmlLang;
            if(theApp->LoadXmlDocment(xmlLang,_T("lang_cn"),_T("translator")))
            {
                CAutoRefPtr<ITranslator> langCN;
                trans->CreateTranslator(&langCN);
                langCN->Load(&xmlLang.child(L"language"),1);//1=LD_XML
                trans->InstallTranslator(langCN);
            }
        }
#ifdef DLL_CORE
        //LUAűģ飬ע⣬űģֻSOUIںDLLʽʱʹá
        bLoaded=pComMgr->CreateScrpit_Lua((IObjRef**)&pScriptLua);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("scirpt_lua"));

        if(pScriptLua)
        {
            theApp->SetScriptModule(pScriptLua);
            size_t sz=pResProvider->GetRawBufferSize(_T("script"),_T("lua_test"));
            if(sz)
            {
                CMyBuffer<char> lua;
                lua.Allocate(sz);
                pResProvider->GetRawBuffer(_T("script"),_T("lua_test"),lua,sz);
                pScriptLua->executeScriptBuffer(lua,sz);
            }
        }
#endif//DLL_CORE

        //SApplicationϵͳעⲿչĿؼSkinObj
        SWkeLoader wkeLoader;
        if(wkeLoader.Init(_T("wke.dll")))
        {
            theApp->RegisterWndFactory(TplSWindowFactory<SWkeWebkit>());//עWKE
        }
        theApp->RegisterWndFactory(TplSWindowFactory<SGifPlayer>());//עGIFPlayer
        theApp->RegisterSkinFactory(TplSkinFactory<SSkinGif>());//עSkinGif
        theApp->RegisterSkinFactory(TplSkinFactory<SSkinAPNG>());//עSkinGif

        theApp->RegisterWndFactory(TplSWindowFactory<SIPAddressCtrl>());//עIPؼ
        theApp->RegisterWndFactory(TplSWindowFactory<SPropertyGrid>());//עԱؼ

        if(SUCCEEDED(CUiAnimation::Init()))
        {
            theApp->RegisterWndFactory(TplSWindowFactory<SUiAnimationWnd>());//עᶯؼ
        }
        theApp->RegisterWndFactory(TplSWindowFactory<SFlyWnd>());//עжؼ
        theApp->RegisterWndFactory(TplSWindowFactory<SFadeFrame>());//עὥؼ
        theApp->RegisterWndFactory(TplSWindowFactory<SRadioBox2>());//עὥؼ
        SSkinGif::Gdiplus_Startup();

        //ϵͳԴ
        HMODULE hSysResource=LoadLibrary(SYS_NAMED_RESOURCE);
        if(hSysResource)
        {
            CAutoRefPtr<IResProvider> sysSesProvider;
            CreateResProvider(RES_PE,(IObjRef**)&sysSesProvider);
            sysSesProvider->Init((WPARAM)hSysResource,0);
            theApp->LoadSystemNamedResource(sysSesProvider);
        }
        //hookƲ˵ı߿
        CMenuWndHook::InstallHook(hInstance,L"_skin.sys.menu.border");

        //ȫԴXML
        theApp->Init(_T("xml_init"));

        {
            //ʾʹSOUIӦó򴰿,Ϊ˱洰ڶ󣬰һ㡣
            CMainDlg dlgMain;
            dlgMain.Create(GetActiveWindow(),0,0,800,600);
            dlgMain.GetNative()->SendMessage(WM_INITDIALOG);
            dlgMain.CenterWindow();
            dlgMain.ShowWindow(SW_SHOWNORMAL);
            nRet=theApp->Run(dlgMain.m_hWnd);
        }

        //Ӧó˳
        delete theApp;

        flashSvr.Shutdown();

        //жز˵߿hook
        CMenuWndHook::UnInstallHook();
        CUiAnimation::Free();

        SSkinGif::Gdiplus_Shutdown();
    }
    delete pComMgr;
    OleUninitialize();

    return nRet;
}

<|endoftext|>


<commit_before>#include <stdlib.h>
#include "check_entry_exit.h"

bool checkEntry(Bitcoin *btcLong, Bitcoin *btcShort, Result &res, Parameters params) {

  double priceLong;
  double priceShort;

  // compute limit (fees + spreadEntry)
  double limit = 2 * btcLong->getFees() + 2 * btcShort->getFees() + params.spreadEntry;

  // check if btcLong is below btcShort
  if (btcShort->getHasShort()) {

    // btcLong:  buy looking to match ask
    // btcShort: sell looking to match bid
    priceLong = btcLong->getLastAsk();
    priceShort = btcShort->getLastBid();
    res.spreadIn = (priceShort - priceLong) / priceLong;

    // maxCurrSpread and minCurrSpread
    if (res.spreadIn > res.maxCurrSpread) {
      res.maxCurrSpread = res.spreadIn;
    }
    if (res.spreadIn < res.minCurrSpread) {
      res.minCurrSpread = res.spreadIn;
    }
    if (params.verbose) {
      std::cout << "   Spread " << btcLong->getExchName() << "/" << btcShort->getExchName() << ": " << res.spreadIn * 100.0 << "%";
      std::cout << " (target " << limit * 100.0 << "%, min " << res.minCurrSpread * 100.0 << "%, max " << res.maxCurrSpread * 100.0 << "%)" << std::endl;
    }
    if (res.spreadIn >= limit && priceLong > 0.0 && priceShort > 0.0) {
      // opportunity found
      res.idExchLong = btcLong->getId();
      res.idExchShort = btcShort->getId();
      res.feesLong = btcLong->getFees();
      res.feesShort = btcShort->getFees();
      res.exchNameLong = btcLong->getExchName();
      res.exchNameShort = btcShort->getExchName();
      res.priceLongIn = priceLong;
      res.priceShortIn = priceShort;
      return true;
    }
  }
  // no opportunity
  return false;
}

bool checkExit(Bitcoin *btcLong, Bitcoin *btcShort, Result &res, Parameters params, time_t period) {

  double priceLong;
  double priceShort;

  // close btcLong:  sell looking to match bid
  // close btcShort: buy looking to match ask
  priceLong  = btcLong->getLastBid();
  priceShort = btcShort->getLastAsk();
  res.spreadOut = (priceShort - priceLong) / priceLong;

  // maxCurrSpread and minCurrSpread
  if (res.spreadOut > res.maxCurrSpread) {
    res.maxCurrSpread = res.spreadOut;
  }
  if (res.spreadOut < res.minCurrSpread) {
    res.minCurrSpread = res.spreadOut;
  }

  if (params.verbose) {
    std::cout << "   Spread " << btcLong->getExchName() << "/" << btcShort->getExchName() << ": " << res.spreadOut * 100.0 << "%";
    std::cout << " (target " << params.spreadExit * 100.0 << "%, min " << res.minCurrSpread * 100.0 << "%, max " << res.maxCurrSpread * 100.0 << "%)" << std::endl;
  }

  // check length
  if (period - res.entryTime >= params.maxLenght) {
    res.priceLongOut  = priceLong;
    res.priceShortOut = priceShort;
    return true;
  }

  if (res.spreadOut <= params.spreadExit && priceLong > 0.0 && priceShort > 0.0) {
    // exit opportunity found
    res.priceLongOut  = priceLong;
    res.priceShortOut = priceShort;
    return true;
  }
  // no exit opportunity
  return false;
}
<commit_msg>Typo Length<commit_after>#include <stdlib.h>
#include "check_entry_exit.h"

bool checkEntry(Bitcoin *btcLong, Bitcoin *btcShort, Result &res, Parameters params) {

  double priceLong;
  double priceShort;

  // compute limit (fees + spreadEntry)
  double limit = 2 * btcLong->getFees() + 2 * btcShort->getFees() + params.spreadEntry;

  // check if btcLong is below btcShort
  if (btcShort->getHasShort()) {

    // btcLong:  buy looking to match ask
    // btcShort: sell looking to match bid
    priceLong = btcLong->getLastAsk();
    priceShort = btcShort->getLastBid();
    res.spreadIn = (priceShort - priceLong) / priceLong;

    // maxCurrSpread and minCurrSpread
    if (res.spreadIn > res.maxCurrSpread) {
      res.maxCurrSpread = res.spreadIn;
    }
    if (res.spreadIn < res.minCurrSpread) {
      res.minCurrSpread = res.spreadIn;
    }
    if (params.verbose) {
      std::cout << "   Spread " << btcLong->getExchName() << "/" << btcShort->getExchName() << ": " << res.spreadIn * 100.0 << "%";
      std::cout << " (target " << limit * 100.0 << "%, min " << res.minCurrSpread * 100.0 << "%, max " << res.maxCurrSpread * 100.0 << "%)" << std::endl;
    }
    if (res.spreadIn >= limit && priceLong > 0.0 && priceShort > 0.0) {
      // opportunity found
      res.idExchLong = btcLong->getId();
      res.idExchShort = btcShort->getId();
      res.feesLong = btcLong->getFees();
      res.feesShort = btcShort->getFees();
      res.exchNameLong = btcLong->getExchName();
      res.exchNameShort = btcShort->getExchName();
      res.priceLongIn = priceLong;
      res.priceShortIn = priceShort;
      return true;
    }
  }
  // no opportunity
  return false;
}

bool checkExit(Bitcoin *btcLong, Bitcoin *btcShort, Result &res, Parameters params, time_t period) {

  double priceLong;
  double priceShort;

  // close btcLong:  sell looking to match bid
  // close btcShort: buy looking to match ask
  priceLong  = btcLong->getLastBid();
  priceShort = btcShort->getLastAsk();
  res.spreadOut = (priceShort - priceLong) / priceLong;

  // maxCurrSpread and minCurrSpread
  if (res.spreadOut > res.maxCurrSpread) {
    res.maxCurrSpread = res.spreadOut;
  }
  if (res.spreadOut < res.minCurrSpread) {
    res.minCurrSpread = res.spreadOut;
  }

  if (params.verbose) {
    std::cout << "   Spread " << btcLong->getExchName() << "/" << btcShort->getExchName() << ": " << res.spreadOut * 100.0 << "%";
    std::cout << " (target " << params.spreadExit * 100.0 << "%, min " << res.minCurrSpread * 100.0 << "%, max " << res.maxCurrSpread * 100.0 << "%)" << std::endl;
  }

  // check length
  if (period - res.entryTime >= params.maxLength) {
    res.priceLongOut  = priceLong;
    res.priceShortOut = priceShort;
    return true;
  }

  if (res.spreadOut <= params.spreadExit && priceLong > 0.0 && priceShort > 0.0) {
    // exit opportunity found
    res.priceLongOut  = priceLong;
    res.priceShortOut = priceShort;
    return true;
  }
  // no exit opportunity
  return false;
}
<|endoftext|>


<commit_before>#include <FImage.h>
#include "../png.h"

using namespace FImage;

// We don't have exp in the language yet, a rough approximation to a Gaussian-like function
Expr gaussian(Expr x) {
    return 1.0f/(x*x+1.0f);
}

// Remap x using y as the central point, an amplitude of alpha, and a std.dev of sigma
Expr remap(Expr x, Expr y, Expr alpha, Expr beta, Expr sigma) {
    return y + (x - y) * (beta + alpha * gaussian((x - y)/sigma));
}

Func downsample(Func f) {
    Var x, y;
    Func downx, downy;

    downx(x, y) = (f(2*x-1, y) + 3.0f * (f(2*x, y) + f(2*x+1, y)) + f(2*x+2, y)) / 8.0f;
    downy(x, y) = (downx(x, 2*y-1) + 3.0f * (downx(x, 2*y) + downx(x, 2*y+1)) + downx(x, 2*y+2)) / 8.0f;

    return downy;
}

Func upsample(Func f) {
    Var x, y;
    Func upx, upy;

    upx(x, y) = 0.25f * f((x/2) - 1 + 2*(x % 2), y) + 0.75f * f(x/2, y);
    upy(x, y) = 0.25f * upx(x, (y/2) - 1 + 2*(y % 2)) + 0.75f * upx(x, y/2);

    return upy;
}

int main(int argc, char **argv) {

    // Number of pyramid levels
    int J = 8;

    // number of intensity levels
    Uniform<int> levels("levels");
    // Parameters controlling the filter
    Uniform<float> alpha("alpha"), beta("beta");
    // Takes a 16-bit input
    UniformImage input(UInt(16), 3);

    assert(J <= 12);

    // loop variables
    Var x, y, c, k;

    // Convert to floating point
    Func floating("floating");
    floating(x, y, c) = Cast<float>(input(x, y, c)) / 65535.0f;

    // Set a boundary condition
    Func clamped("clamped");
    clamped(x, y, c) = floating(Clamp(x, 0, input.width()-1), Clamp(y, 0, input.height()-1), c);

    // Get the luminance channel
    Func gray("gray");
    gray(x, y) = 0.299f * clamped(x, y, 0) + 0.587f * clamped(x, y, 1) + 0.114f * clamped(x, y, 2);

    // Make the processed Gaussian pyramid
    Func gPyramid[] = {"gp0", "gp1", "gp2", "gp3", "gp4", "gp5", "gp6", "gp7", "gp8", "gp9", "gp10", "gp11"};
    gPyramid[0](x, y, k) = remap(gray(x, y), Cast<float>(k) / (levels-1), alpha, beta, 1.0f / (levels-1));
    for (int j = 1; j < J; j++)
        gPyramid[j](x, y, k) = downsample(gPyramid[j-1])(x, y, k);

    // Get its laplacian pyramid
    Func lPyramid[] = {"lp0", "lp1", "lp2", "lp3", "lp4", "lp5", "lp6", "lp7", "lp8", "lp9", "lp10", "lp11"};
    lPyramid[J-1] = gPyramid[J-1];
    for (int j = J-2; j >= 0; j--)
        lPyramid[j](x, y, k) = gPyramid[j](x, y, k) - upsample(gPyramid[j+1])(x, y, k);

    // Make the Gaussian pyramid of the input
    Func inGPyramid[] = {"igp0", "igp1", "igp2", "igp3", "igp4", "igp5", "igp6", "igp7", "igp8", "igp9", "igp10", "igp11"};
    inGPyramid[0] = gray;
    for (int j = 1; j < J; j++)
        inGPyramid[j](x, y) = downsample(inGPyramid[j-1])(x, y);

    // Make the laplacian pyramid of the output
    Func outLPyramid[] = {"olp0", "olp1", "olp2", "olp3", "olp4", "olp5", "olp6", "olp7", "olp8", "olp9", "olp10", "olp11"};
    for (int j = 0; j < J; j++) {
        // Split input pyramid value into integer and floating parts
        Expr level = inGPyramid[j](x, y) * Cast<float>(levels-1);
        Expr li = Clamp(Cast<int>(level), 0, levels-2);
        Expr lf = level - Cast<float>(li);
        // Linearly interpolate between the nearest processed pyramid levels
        outLPyramid[j](x, y) = (1.0f - lf) * lPyramid[j](x, y, li) + lf * lPyramid[j](x, y, li+1);
    }

    // Make the Gaussian pyramid of the output
    Func outGPyramid[] = {"ogp0", "ogp1", "ogp2", "ogp3", "ogp4", "ogp5", "ogp6", "ogp7", "ogp8", "ogp9", "ogp10", "ogp11"};
    outGPyramid[J-1] = outLPyramid[J-1];
    for (int j = J-2; j >= 0; j--)
        outGPyramid[j](x, y) = upsample(outGPyramid[j+1])(x, y) + outLPyramid[j](x, y);

    // Reintroduce color
    Func color;
    color(x, y, c) = outGPyramid[0](x, y) * clamped(x, y, c) / gray(x, y);

    Func output;
    // Convert back to 16-bit
    Var xo, yo;
    output(xo, yo, c) = Cast<uint16_t>(Clamp(color(xo, yo, c), 0.0f, 1.0f) * 65535.0f);

    // Breadth-first, with some unrolling to clean up upsampling and downsampling a little

    Var xi, yi;

    switch (atoi(argv[1])) {
    case 0:
        // breadth-first scalar: 2159 ms
        output.root();
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root();
            gPyramid[j].root();
            outGPyramid[j].root();
            if (j == J-1) break;
            lPyramid[j].root();
            outLPyramid[j].root();
        }
        break;
    case 1:
        // parallelize each stage across outermost dimension: 944 ms
        output.split(yo, yo, yi, 128).parallel(yo);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y);
            gPyramid[j].root().parallel(k);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y);
            if (j == J-1) break;
            lPyramid[j].root().parallel(k);
            outLPyramid[j].root().split(y, y, yi, 4).parallel(y);
        }
        break;
    case 2:
        // Same as above, but also vectorize heavily across x: 952 ms
        output.split(yo, yo, yi, 128).parallel(yo).vectorize(xo, 4);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            gPyramid[j].root().parallel(k).vectorize(x, 4);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            if (j == J-1) break;
            lPyramid[j].root().parallel(k).vectorize(x, 4);
            outLPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
        }
        break;
    case 3:
        // parallelize across yi instead of yo: Bad idea - 1747 ms
        output.split(yo, yo, yi, 8).parallel(yi);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 8).parallel(yi);
            gPyramid[j].root().parallel(k);
            outGPyramid[j].root().split(y, y, yi, 8).parallel(yi);
            if (j == J-1) break;
            lPyramid[j].root().parallel(k);
            outLPyramid[j].root().split(y, y, yi, 8).parallel(yi);
        }
        break;
    case 4:
        // Parallelize, inlining all the laplacian pyramid levels
        // (they can be computed from the gaussian pyramids on the
        // fly): 750 ms
        output.split(yo, yo, yi, 128).parallel(yo);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 1).parallel(y);
            gPyramid[j].root().parallel(k);
            outGPyramid[j].root().split(y, y, yi, 1).parallel(y);
        }
        break;
    case 5:
        // Same as above with vectorization (now that we're doing more
        // math and less memory, maybe it will matter): 646 ms
        output.split(yo, yo, yi, 128).parallel(yo).vectorize(xo, 4);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            gPyramid[j].root().parallel(k).vectorize(x, 4);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
        }
        break;
    case 6:
        // Also inline every other pyramid level: Bad idea - 2109 ms
        output.split(yo, yo, yi, 128).parallel(yo).vectorize(xo, 4);
        for (int j = 0; j < J; j+=2) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            gPyramid[j].root().parallel(k).vectorize(x, 4);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
        }
        break;
    case 7:
        // Take care of the boundary condition earlier to avoid costly branching: 808 ms
        output.split(yo, yo, yi, 128).parallel(yo).vectorize(xo, 4);
        clamped.root().split(y, y, yi, 128).parallel(y).vectorize(x, 4);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            gPyramid[j].root().parallel(k).vectorize(x, 4);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
        }
        break;
    case 8:
        // Unroll by a factor of two to try and simplify the upsampling math: not worth it - 836 ms
        output.split(yo, yo, yi, 128).parallel(yo).unroll(xo, 2).unroll(yi, 2);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).unroll(x, 2).unroll(y, 2);
            gPyramid[j].root().parallel(k).unroll(x, 2).unroll(y, 2);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).unroll(x, 2).unroll(y, 2);
        }
        break;
    case 9:
        //
    default:
        break;
    }

    output.compileToFile("local_laplacian");

    return 0;
}

<commit_msg>More aggressively parallel<commit_after>#include <FImage.h>
#include "../png.h"

using namespace FImage;

// We don't have exp in the language yet, a rough approximation to a Gaussian-like function
Expr gaussian(Expr x) {
    return 1.0f/(x*x+1.0f);
}

// Remap x using y as the central point, an amplitude of alpha, and a std.dev of sigma
Expr remap(Expr x, Expr y, Expr alpha, Expr beta, Expr sigma) {
    return y + (x - y) * (beta + alpha * gaussian((x - y)/sigma));
}

Func downsample(Func f) {
    Var x, y;
    Func downx, downy;

    downx(x, y) = (f(2*x-1, y) + 3.0f * (f(2*x, y) + f(2*x+1, y)) + f(2*x+2, y)) / 8.0f;
    downy(x, y) = (downx(x, 2*y-1) + 3.0f * (downx(x, 2*y) + downx(x, 2*y+1)) + downx(x, 2*y+2)) / 8.0f;

    return downy;
}

Func upsample(Func f) {
    Var x, y;
    Func upx, upy;

    upx(x, y) = 0.25f * f((x/2) - 1 + 2*(x % 2), y) + 0.75f * f(x/2, y);
    upy(x, y) = 0.25f * upx(x, (y/2) - 1 + 2*(y % 2)) + 0.75f * upx(x, y/2);

    return upy;
}

int main(int argc, char **argv) {

    // Number of pyramid levels
    int J = 8;

    // number of intensity levels
    Uniform<int> levels("levels");
    // Parameters controlling the filter
    Uniform<float> alpha("alpha"), beta("beta");
    // Takes a 16-bit input
    UniformImage input(UInt(16), 3);

    assert(J <= 12);

    // loop variables
    Var x, y, c, k;

    // Convert to floating point
    Func floating("floating");
    floating(x, y, c) = Cast<float>(input(x, y, c)) / 65535.0f;

    // Set a boundary condition
    Func clamped("clamped");
    clamped(x, y, c) = floating(Clamp(x, 0, input.width()-1), Clamp(y, 0, input.height()-1), c);

    // Get the luminance channel
    Func gray("gray");
    gray(x, y) = 0.299f * clamped(x, y, 0) + 0.587f * clamped(x, y, 1) + 0.114f * clamped(x, y, 2);

    // Make the processed Gaussian pyramid
    Func gPyramid[] = {"gp0", "gp1", "gp2", "gp3", "gp4", "gp5", "gp6", "gp7", "gp8", "gp9", "gp10", "gp11"};
    gPyramid[0](x, y, k) = remap(gray(x, y), Cast<float>(k) / (levels-1), alpha, beta, 1.0f / (levels-1));
    for (int j = 1; j < J; j++)
        gPyramid[j](x, y, k) = downsample(gPyramid[j-1])(x, y, k);

    // Get its laplacian pyramid
    Func lPyramid[] = {"lp0", "lp1", "lp2", "lp3", "lp4", "lp5", "lp6", "lp7", "lp8", "lp9", "lp10", "lp11"};
    lPyramid[J-1] = gPyramid[J-1];
    for (int j = J-2; j >= 0; j--)
        lPyramid[j](x, y, k) = gPyramid[j](x, y, k) - upsample(gPyramid[j+1])(x, y, k);

    // Make the Gaussian pyramid of the input
    Func inGPyramid[] = {"igp0", "igp1", "igp2", "igp3", "igp4", "igp5", "igp6", "igp7", "igp8", "igp9", "igp10", "igp11"};
    inGPyramid[0] = gray;
    for (int j = 1; j < J; j++)
        inGPyramid[j](x, y) = downsample(inGPyramid[j-1])(x, y);

    // Make the laplacian pyramid of the output
    Func outLPyramid[] = {"olp0", "olp1", "olp2", "olp3", "olp4", "olp5", "olp6", "olp7", "olp8", "olp9", "olp10", "olp11"};
    for (int j = 0; j < J; j++) {
        // Split input pyramid value into integer and floating parts
        Expr level = inGPyramid[j](x, y) * Cast<float>(levels-1);
        Expr li = Clamp(Cast<int>(level), 0, levels-2);
        Expr lf = level - Cast<float>(li);
        // Linearly interpolate between the nearest processed pyramid levels
        outLPyramid[j](x, y) = (1.0f - lf) * lPyramid[j](x, y, li) + lf * lPyramid[j](x, y, li+1);
    }

    // Make the Gaussian pyramid of the output
    Func outGPyramid[] = {"ogp0", "ogp1", "ogp2", "ogp3", "ogp4", "ogp5", "ogp6", "ogp7", "ogp8", "ogp9", "ogp10", "ogp11"};
    outGPyramid[J-1] = outLPyramid[J-1];
    for (int j = J-2; j >= 0; j--)
        outGPyramid[j](x, y) = upsample(outGPyramid[j+1])(x, y) + outLPyramid[j](x, y);

    // Reintroduce color
    Func color;
    color(x, y, c) = outGPyramid[0](x, y) * clamped(x, y, c) / gray(x, y);

    Func output;
    // Convert back to 16-bit
    Var xo, yo;
    output(xo, yo, c) = Cast<uint16_t>(Clamp(color(xo, yo, c), 0.0f, 1.0f) * 65535.0f);

    // Breadth-first, with some unrolling to clean up upsampling and downsampling a little

    Var xi, yi;

    // Times are for a quad-core core2, and a 64-core nehalem at a lower clock
    switch (atoi(argv[1])) {
    case 0:
        // breadth-first scalar: 2159 ms, 2667 ms
        output.root();
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root();
            gPyramid[j].root();
            outGPyramid[j].root();
            if (j == J-1) break;
            lPyramid[j].root();
            outLPyramid[j].root();
        }
        break;
    case 1:
        // parallelize each stage across outermost dimension: 944 ms, 617 ms
        output.split(yo, yo, yi, 32).parallel(yo);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y);
            gPyramid[j].root().parallel(k);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y);
            if (j == J-1) break;
            lPyramid[j].root().parallel(k);
            outLPyramid[j].root().split(y, y, yi, 4).parallel(y);
        }
        break;
    case 2:
        // Same as above, but also vectorize heavily across x: 952 ms, 446 ms
        output.split(yo, yo, yi, 32).parallel(yo).vectorize(xo, 4);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            gPyramid[j].root().parallel(k).vectorize(x, 4);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            if (j == J-1) break;
            lPyramid[j].root().parallel(k).vectorize(x, 4);
            outLPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
        }
        break;
    case 3:
        // parallelize across yi instead of yo: Bad idea - 1747 ms, 1625 ms
        output.split(yo, yo, yi, 8).parallel(yi);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 8).parallel(yi);
            gPyramid[j].root().parallel(k);
            outGPyramid[j].root().split(y, y, yi, 8).parallel(yi);
            if (j == J-1) break;
            lPyramid[j].root().parallel(k);
            outLPyramid[j].root().split(y, y, yi, 8).parallel(yi);
        }
        break;
    case 4:
        // Parallelize, inlining all the laplacian pyramid levels
        // (they can be computed from the gaussian pyramids on the
        // fly): 750 ms, 461 ms
        output.split(yo, yo, yi, 32).parallel(yo);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 1).parallel(y);
            gPyramid[j].root().parallel(k);
            outGPyramid[j].root().split(y, y, yi, 1).parallel(y);
        }
        break;
    case 5:
        // Same as above with vectorization (now that we're doing more
        // math and less memory, maybe it will matter): 646 ms, 304 ms
        output.split(yo, yo, yi, 32).parallel(yo).vectorize(xo, 4);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            gPyramid[j].root().parallel(k).vectorize(x, 4);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
        }
        break;
    case 6:
        // Also inline every other pyramid level: Bad idea - 2109 ms, 656 ms
        output.split(yo, yo, yi, 32).parallel(yo).vectorize(xo, 4);
        for (int j = 0; j < J; j+=2) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            gPyramid[j].root().parallel(k).vectorize(x, 4);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
        }
        break;
    case 7:
        // Take care of the boundary condition earlier to avoid costly branching: 808 ms, 340 ms
        output.split(yo, yo, yi, 32).parallel(yo).vectorize(xo, 4);
        clamped.root().split(y, y, yi, 32).parallel(y).vectorize(x, 4);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
            gPyramid[j].root().parallel(k).vectorize(x, 4);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).vectorize(x, 4);
        }
        break;
    case 8:
        // Unroll by a factor of two to try and simplify the upsampling math: not worth it - 836 ms, 607 ms
        output.split(yo, yo, yi, 32).parallel(yo).unroll(xo, 2).unroll(yi, 2);
        for (int j = 0; j < J; j++) {
            inGPyramid[j].root().split(y, y, yi, 4).parallel(y).unroll(x, 2).unroll(y, 2);
            gPyramid[j].root().parallel(k).unroll(x, 2).unroll(y, 2);
            outGPyramid[j].root().split(y, y, yi, 4).parallel(y).unroll(x, 2).unroll(y, 2);
        }
        break;
    case 9:
        //
    default:
        break;
    }

    output.compileToFile("local_laplacian");

    return 0;
}

<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/openni_camera/openni_driver.h>
#include <pcl/features/integral_image_normal.h>
#include <pcl/console/parse.h>
#include <pcl/common/time.h>

#define FPS_CALC(_WHAT_) \
do \
{ \
    static unsigned count = 0;\
    static double last = pcl::getTime ();\
    if (++count == 100) \
    { \
      double now = pcl::getTime (); \
      std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
      count = 0; \
      last = now; \
    } \
}while(false)

template <typename PointType>
class OpenNIIntegralImageNormalEstimation
{
  public:
    typedef pcl::PointCloud<PointType> Cloud;
    typedef typename Cloud::Ptr CloudPtr;
    typedef typename Cloud::ConstPtr CloudConstPtr;

    OpenNIIntegralImageNormalEstimation (const std::string& device_id = "",
                     float leaf_size_x = 0.01, float leaf_size_y = 0.01, float leaf_size_z = 0.01)
    : viewer ("PCL OpenNI NormalEstimation Viewer")
    , device_id_(device_id)
    {
      ne_.setNormalEstimationMethod (pcl::IntegralImageNormalEstimation<PointType, pcl::Normal>::AVERAGE_3D_GRADIENT);
      new_cloud_ = false;
    }

    void
    cloud_cb (const CloudConstPtr& cloud)
    {
      boost::mutex::scoped_lock lock (mtx_);
      new_cloud_ = false;
      //lock while we set our cloud;

      FPS_CALC ("computation");

      normals_.reset (new pcl::PointCloud<pcl::Normal>);

      cloud_ = cloud;
      // Estimate surface normals
      ne_.setInputCloud (cloud);
      ne_.compute (*normals_);

      new_cloud_ = true;
      std::cerr <<"done computing" << std::endl;
    }

    void
    viz_cb (pcl::visualization::PCLVisualizer& viz)
    {
      boost::mutex::scoped_lock lock (mtx_);
      if (new_cloud_)
      {
        FPS_CALC ("visualization");

        if (cloud_)
        {
          //viz.addPointCloudNormals<PointType, pcl::Normal> (cloud_, normals_, 200, 0.1, "normalcloud");
          viewer.showCloud (cloud_);
        }
      }

    }

    void
    run ()
    {
      pcl::Grabber* interface = new pcl::OpenNIGrabber (device_id_);

      boost::function<void (const CloudConstPtr&)> f = boost::bind (&OpenNIIntegralImageNormalEstimation::cloud_cb, this, _1);
      boost::signals2::connection c = interface->registerCallback (f);

      viewer.runOnVisualizationThread (boost::bind(&OpenNIIntegralImageNormalEstimation::viz_cb, this, _1), "viz_cb");

      interface->start ();

      while (!viewer.wasStopped ())
      {
        sleep (1);
      }

      interface->stop ();
    }

    pcl::IntegralImageNormalEstimation<PointType, pcl::Normal> ne_;
    pcl::visualization::CloudViewer viewer;
    std::string device_id_;
    boost::mutex mtx_;
    // Data
    pcl::PointCloud<pcl::Normal>::Ptr normals_;
    CloudConstPtr cloud_;
    bool new_cloud_;
};

void
usage (char ** argv)
{
  std::cout << "usage: " << argv[0] << " <device_id> <options>\n\n";

  openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance ();
  if (driver.getNumberDevices () > 0)
  {
    for (unsigned deviceIdx = 0; deviceIdx < driver.getNumberDevices (); ++deviceIdx)
    {
      cout << "Device: " << deviceIdx + 1 << ", vendor: " << driver.getVendorName (deviceIdx) << ", product: " << driver.getProductName (deviceIdx)
              << ", connected: " << (int)driver.getBus (deviceIdx) << " @ " << (int)driver.getAddress (deviceIdx) << ", serial number: \'" << driver.getSerialNumber (deviceIdx) << "\'" << endl;
      cout << "device_id may be #1, #2, ... for the first second etc device in the list or" << endl
           << "                 bus@address for the device connected to a specific usb-bus / address combination (wotks only in Linux) or" << endl
           << "                 <serial-number> (only in Linux and for devices which provide serial numbers)"  << endl;
    }
  }
  else
    cout << "No devices connected." << endl;
}

int
main (int argc, char ** argv)
{
  if (argc < 2)
  {
    usage (argv);
    return 1;
  }

  std::string arg (argv[1]);

  if (arg == "--help" || arg == "-h")
  {
    usage (argv);
    return 1;
  }

  double leaf_x = 0.01, leaf_y = 0.01, leaf_z = 0.01;

  pcl::OpenNIGrabber grabber (arg);
  if (grabber.providesCallback<pcl::OpenNIGrabber::sig_cb_openni_point_cloud_rgb> ())
  {
    OpenNIIntegralImageNormalEstimation<pcl::PointXYZRGB> v (arg, leaf_x, leaf_y, leaf_z);
    v.run ();
  }
  else
  {
    OpenNIIntegralImageNormalEstimation<pcl::PointXYZ> v (arg, leaf_x, leaf_y, leaf_z);
    v.run ();
  }

  return (0);
}
<commit_msg>works<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/openni_grabber.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/openni_camera/openni_driver.h>
#include <pcl/features/integral_image_normal.h>
#include <pcl/console/parse.h>
#include <pcl/common/time.h>

#define FPS_CALC(_WHAT_) \
do \
{ \
    static unsigned count = 0;\
    static double last = pcl::getTime ();\
    if (++count == 100) \
    { \
      double now = pcl::getTime (); \
      std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
      count = 0; \
      last = now; \
    } \
}while(false)

template <typename PointType>
class OpenNIIntegralImageNormalEstimation
{
  public:
    typedef pcl::PointCloud<PointType> Cloud;
    typedef typename Cloud::Ptr CloudPtr;
    typedef typename Cloud::ConstPtr CloudConstPtr;

    OpenNIIntegralImageNormalEstimation (const std::string& device_id = "")
      : viewer ("PCL OpenNI NormalEstimation Viewer")
    , device_id_(device_id)
    {
      ne_.setNormalEstimationMethod (pcl::IntegralImageNormalEstimation<PointType, pcl::Normal>::AVERAGE_3D_GRADIENT);
//      ne_.setNormalEstimationMethod (pcl::IntegralImageNormalEstimation<PointType, pcl::Normal>::COVARIANCE_MATRIX);
      ne_.setRectSize (2, 2);
      new_cloud_ = false;
    }

    void
    cloud_cb (const CloudConstPtr& cloud)
    {
      boost::mutex::scoped_lock lock (mtx_);
      //lock while we set our cloud;
      FPS_CALC ("computation");
      // Estimate surface normals
      ne_.setInputCloud (cloud);

      normals_.reset (new pcl::PointCloud<pcl::Normal>);
      ne_.compute (*normals_);
      cloud_ = cloud;

      new_cloud_ = true;
    }

    void
    viz_cb (pcl::visualization::PCLVisualizer& viz)
    {
      boost::mutex::scoped_lock lock (mtx_);
      if (!cloud_)
      {
        usleep (10);
        return;
      }

      CloudConstPtr temp_cloud;
      temp_cloud.swap (cloud_); //here we set cloud_ to null, so that

      if (!viz.updatePointCloud (temp_cloud, "OpenNICloud"))
      {
        viz.addPointCloud (temp_cloud, "OpenNICloud");
        viz.resetCameraViewpoint ("OpenNICloud");
      }
      // Render the data
      if (new_cloud_ && normals_)
      {
        viz.removePointCloud ("normalcloud");
        viz.addPointCloudNormals<PointType, pcl::Normal> (temp_cloud, normals_, 200, 0.1, "normalcloud");
        new_cloud_ = false;
      }
    }

    void
    run ()
    {
      pcl::Grabber* interface = new pcl::OpenNIGrabber (device_id_);

      boost::function<void (const CloudConstPtr&)> f = boost::bind (&OpenNIIntegralImageNormalEstimation::cloud_cb, this, _1);
      boost::signals2::connection c = interface->registerCallback (f);

      viewer.runOnVisualizationThread (boost::bind(&OpenNIIntegralImageNormalEstimation::viz_cb, this, _1), "viz_cb");

      interface->start ();

      while (!viewer.wasStopped ())
      {
        usleep (10);
      }

      interface->stop ();
    }

    pcl::IntegralImageNormalEstimation<PointType, pcl::Normal> ne_;
    pcl::visualization::CloudViewer viewer;
    std::string device_id_;
    boost::mutex mtx_;
    // Data
    pcl::PointCloud<pcl::Normal>::Ptr normals_;
    CloudConstPtr cloud_;
    bool new_cloud_;
};

void
usage (char ** argv)
{
  std::cout << "usage: " << argv[0] << " <device_id> <options>\n\n";

  openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance ();
  if (driver.getNumberDevices () > 0)
  {
    for (unsigned deviceIdx = 0; deviceIdx < driver.getNumberDevices (); ++deviceIdx)
    {
      cout << "Device: " << deviceIdx + 1 << ", vendor: " << driver.getVendorName (deviceIdx) << ", product: " << driver.getProductName (deviceIdx)
              << ", connected: " << (int)driver.getBus (deviceIdx) << " @ " << (int)driver.getAddress (deviceIdx) << ", serial number: \'" << driver.getSerialNumber (deviceIdx) << "\'" << endl;
      cout << "device_id may be #1, #2, ... for the first second etc device in the list or" << endl
           << "                 bus@address for the device connected to a specific usb-bus / address combination (wotks only in Linux) or" << endl
           << "                 <serial-number> (only in Linux and for devices which provide serial numbers)"  << endl;
    }
  }
  else
    cout << "No devices connected." << endl;
}

int
main (int argc, char ** argv)
{
  if (argc < 2)
  {
    usage (argv);
    return 1;
  }

  std::string arg (argv[1]);

  if (arg == "--help" || arg == "-h")
  {
    usage (argv);
    return 1;
  }

  pcl::OpenNIGrabber grabber (arg);
  if (grabber.providesCallback<pcl::OpenNIGrabber::sig_cb_openni_point_cloud_rgb> ())
  {
    OpenNIIntegralImageNormalEstimation<pcl::PointXYZRGB> v (arg);
    v.run ();
  }
  else
  {
    OpenNIIntegralImageNormalEstimation<pcl::PointXYZ> v (arg);
    v.run ();
  }

  return (0);
}
<|endoftext|>


<commit_before>// $Id: fe.C,v 1.25 2004-01-03 15:37:42 benkirk Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2004  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "fe.h"
#include "libmesh.h"
#include "quadrature.h"
#include "elem.h"
#include "libmesh_logging.h"
#include "fe_macro.h"

// ------------------------------------------------------------
// FE class members
template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_quadrature_points () const
{
  assert (qrule != NULL);
  return qrule->n_points();
}

template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::reinit(const Elem* elem,
		       const std::vector<Point>* const pts)
{
  assert (elem != NULL);

  // Only need the quadrature rule if the user did not supply
  // the evaluation points
  if (pts == NULL)
    {
      assert (qrule   != NULL);
      qrule->init(elem->type());
    }

  // Initialize the shape functions at the user-specified
  // points
  if (pts != NULL)
    {
      // Set the element type
      elem_type = elem->type();

      // Initialize the shape functions
      this->init_shape_functions (*pts, elem);
    }

  // update the type in accordance to the current cell
  // and reinit if the cell type has changed or (as in
  // the case of the hierarchics) the shape functions need
  // reinit, since they depend on the particular element
  else if ((this->get_type() != elem->type()) ||
	   this->shapes_need_reinit())
    {
      // Set the element type
      elem_type = elem->type();

      // Initialize the shape functions
      this->init_shape_functions (qrule->get_points(), elem);
    }

  // Compute the map for this element.  In the future we can specify
  // different types of maps
  if (pts != NULL)
    {
      std::vector<Real> dummy_weights (pts->size(), 1.);

      this->compute_map (dummy_weights, elem);
    }
  else
    {
      this->compute_map (qrule->get_weights(), elem);
    }

  // Compute the shape functions and the derivatives at all of the
  // quadrature points.
  this->compute_shape_functions ();
}

template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::init_shape_functions(const std::vector<Point>& qp,
				     const Elem* elem)
{
  assert (elem  != NULL);

  /**
   * Start logging the shape function initialization
   */
  START_LOG("init_shape_functions()", "FE");

  // The number of quadrature points.
  const unsigned int n_qp = qp.size();

  // The element type and order to use in
  // the map
  const Order    mapping_order     (elem->default_order());
  const ElemType mapping_elem_type (elem->type());

  // Number of shape functions in the finite element approximation
  // space.
  const unsigned int n_approx_shape_functions =
    this->n_shape_functions(this->get_type(),
			    this->get_order());

  // Number of shape functions used to construt the map
  // (Lagrange shape functions are used for mapping)
  const unsigned int n_mapping_shape_functions =
    FE<Dim,LAGRANGE>::n_shape_functions (mapping_elem_type,
					 mapping_order);

  // resize the vectors to hold current data
  // Phi are the shape functions used for the FE approximation
  // Phi_map are the shape functions used for the FE mapping
  {
    phi.resize     (n_approx_shape_functions);
    dphi.resize    (n_approx_shape_functions);
    dphidx.resize  (n_approx_shape_functions);
    dphidy.resize  (n_approx_shape_functions);
    dphidz.resize  (n_approx_shape_functions);
    dphidxi.resize (n_approx_shape_functions);

    if (Dim > 1)
      dphideta.resize      (n_approx_shape_functions);

    if (Dim == 3)
      dphidzeta.resize     (n_approx_shape_functions);

    phi_map.resize         (n_mapping_shape_functions);
    dphidxi_map.resize     (n_mapping_shape_functions);

    if (Dim > 1)
      dphideta_map.resize  (n_mapping_shape_functions);

    if (Dim == 3)
      dphidzeta_map.resize (n_mapping_shape_functions);

    for (unsigned int i=0; i<n_approx_shape_functions; i++)
      {
	phi[i].resize         (n_qp);
	dphi[i].resize        (n_qp);
	dphidx[i].resize      (n_qp);
	dphidy[i].resize      (n_qp);
	dphidz[i].resize      (n_qp);
	dphidxi[i].resize     (n_qp);

	if (Dim > 1)
	  dphideta[i].resize  (n_qp);

	if (Dim == 3)
	  dphidzeta[i].resize (n_qp);

      }

    for (unsigned int i=0; i<n_mapping_shape_functions; i++)
      {
	phi_map[i].resize         (n_qp);
	dphidxi_map[i].resize     (n_qp);

	if (Dim > 1)
	  dphideta_map[i].resize  (n_qp);

	if (Dim == 3)
	  dphidzeta_map[i].resize (n_qp);
      }
  }

#ifdef ENABLE_INFINITE_ELEMENTS
  //------------------------------------------------------------
  // Initialize the data fields, which should only be used for infinite
  // elements, to some sensible values, so that using a FE with the
  // variational formulation of an InfFE, correct element matrices are
  // returned

 {
    weight.resize  (n_qp);
    dweight.resize (n_qp);
    dphase.resize  (n_qp);

    for (unsigned int p=0; p<n_qp; p++)
      {
        weight[p] = 1.;
	dweight[p].zero();
	dphase[p].zero();
      }

 }
#endif // ifdef ENABLE_INFINITE_ELEMENTS

  switch (Dim)
    {

      //------------------------------------------------------------
      // 1D
    case 1:
      {
	// Compute the value of the approximation shape function i at quadrature point p
	for (unsigned int i=0; i<n_approx_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi[i][p]      = FE<Dim,T>::shape       (elem, this->get_order(), i,    qp[p]);
	      dphidxi[i][p]  = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 0, qp[p]);
	    }

	// Compute the value of the mapping shape function i at quadrature point p
	// (Lagrange shape functions are used for mapping)
	for (unsigned int i=0; i<n_mapping_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi_map[i][p]      = FE<Dim,LAGRANGE>::shape       (mapping_elem_type, mapping_order, i,    qp[p]);
	      dphidxi_map[i][p]  = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
	    }

	break;
      }

      //------------------------------------------------------------
      // 2D
    case 2:
      {
	// Compute the value of the approximation shape function i at quadrature point p
	for (unsigned int i=0; i<n_approx_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi[i][p]      = FE<Dim,T>::shape       (elem, this->get_order(), i,    qp[p]);
	      dphidxi[i][p]  = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 0, qp[p]);
	      dphideta[i][p] = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 1, qp[p]);
	    }

	// Compute the value of the mapping shape function i at quadrature point p
	// (Lagrange shape functions are used for mapping)
	for (unsigned int i=0; i<n_mapping_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi_map[i][p]      = FE<Dim,LAGRANGE>::shape       (mapping_elem_type, mapping_order, i,    qp[p]);
	      dphidxi_map[i][p]  = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
	      dphideta_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 1, qp[p]);
	    }

       	break;
      }

      //------------------------------------------------------------
      // 3D
    case 3:
      {
	// Compute the value of the approximation shape function i at quadrature point p
	for (unsigned int i=0; i<n_approx_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi[i][p]       = FE<Dim,T>::shape       (elem, this->get_order(), i,    qp[p]);
	      dphidxi[i][p]   = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 0, qp[p]);
	      dphideta[i][p]  = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 1, qp[p]);
	      dphidzeta[i][p] = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 2, qp[p]);
	    }

	// Compute the value of the mapping shape function i at quadrature point p
	// (Lagrange shape functions are used for mapping)
	for (unsigned int i=0; i<n_mapping_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi_map[i][p]       = FE<Dim,LAGRANGE>::shape       (mapping_elem_type, mapping_order, i,    qp[p]);
	      dphidxi_map[i][p]   = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
	      dphideta_map[i][p]  = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 1, qp[p]);
	      dphidzeta_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 2, qp[p]);
	    }

	break;
      }

    default:
      error();
    }

  /**
   * Stop logging the shape function initialization
   */
  STOP_LOG("init_shape_functions()", "FE");
}

#ifdef ENABLE_INFINITE_ELEMENTS

template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::init_base_shape_functions(const std::vector<Point>& qp,
					  const Elem* e)
{
  elem_type = e->type();
  init_shape_functions(qp, e);
}

#endif

//--------------------------------------------------------------
// Explicit instantiations using macro from fe_macro.h

INSTANTIATE_FE(1);

INSTANTIATE_FE(2);

INSTANTIATE_FE(3);

<commit_msg>changed comment style so that it makes it into the documented source<commit_after>// $Id: fe.C,v 1.26 2004-02-10 22:48:53 benkirk Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2004  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "fe.h"
#include "libmesh.h"
#include "quadrature.h"
#include "elem.h"
#include "libmesh_logging.h"
#include "fe_macro.h"

// ------------------------------------------------------------
// FE class members
template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_quadrature_points () const
{
  assert (qrule != NULL);
  return qrule->n_points();
}

template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::reinit(const Elem* elem,
		       const std::vector<Point>* const pts)
{
  assert (elem != NULL);

  // Only need the quadrature rule if the user did not supply
  // the evaluation points
  if (pts == NULL)
    {
      assert (qrule   != NULL);
      qrule->init(elem->type());
    }

  // Initialize the shape functions at the user-specified
  // points
  if (pts != NULL)
    {
      // Set the element type
      elem_type = elem->type();

      // Initialize the shape functions
      this->init_shape_functions (*pts, elem);
    }

  // update the type in accordance to the current cell
  // and reinit if the cell type has changed or (as in
  // the case of the hierarchics) the shape functions need
  // reinit, since they depend on the particular element
  else if ((this->get_type() != elem->type()) ||
	   this->shapes_need_reinit())
    {
      // Set the element type
      elem_type = elem->type();

      // Initialize the shape functions
      this->init_shape_functions (qrule->get_points(), elem);
    }

  // Compute the map for this element.  In the future we can specify
  // different types of maps
  if (pts != NULL)
    {
      std::vector<Real> dummy_weights (pts->size(), 1.);

      this->compute_map (dummy_weights, elem);
    }
  else
    {
      this->compute_map (qrule->get_weights(), elem);
    }

  // Compute the shape functions and the derivatives at all of the
  // quadrature points.
  this->compute_shape_functions ();
}

template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::init_shape_functions(const std::vector<Point>& qp,
				     const Elem* elem)
{
  assert (elem  != NULL);

  // Start logging the shape function initialization
  START_LOG("init_shape_functions()", "FE");

  // The number of quadrature points.
  const unsigned int n_qp = qp.size();

  // The element type and order to use in
  // the map
  const Order    mapping_order     (elem->default_order());
  const ElemType mapping_elem_type (elem->type());

  // Number of shape functions in the finite element approximation
  // space.
  const unsigned int n_approx_shape_functions =
    this->n_shape_functions(this->get_type(),
			    this->get_order());

  // Number of shape functions used to construt the map
  // (Lagrange shape functions are used for mapping)
  const unsigned int n_mapping_shape_functions =
    FE<Dim,LAGRANGE>::n_shape_functions (mapping_elem_type,
					 mapping_order);

  // resize the vectors to hold current data
  // Phi are the shape functions used for the FE approximation
  // Phi_map are the shape functions used for the FE mapping
  {
    phi.resize     (n_approx_shape_functions);
    dphi.resize    (n_approx_shape_functions);
    dphidx.resize  (n_approx_shape_functions);
    dphidy.resize  (n_approx_shape_functions);
    dphidz.resize  (n_approx_shape_functions);
    dphidxi.resize (n_approx_shape_functions);

    if (Dim > 1)
      dphideta.resize      (n_approx_shape_functions);

    if (Dim == 3)
      dphidzeta.resize     (n_approx_shape_functions);

    phi_map.resize         (n_mapping_shape_functions);
    dphidxi_map.resize     (n_mapping_shape_functions);

    if (Dim > 1)
      dphideta_map.resize  (n_mapping_shape_functions);

    if (Dim == 3)
      dphidzeta_map.resize (n_mapping_shape_functions);

    for (unsigned int i=0; i<n_approx_shape_functions; i++)
      {
	phi[i].resize         (n_qp);
	dphi[i].resize        (n_qp);
	dphidx[i].resize      (n_qp);
	dphidy[i].resize      (n_qp);
	dphidz[i].resize      (n_qp);
	dphidxi[i].resize     (n_qp);

	if (Dim > 1)
	  dphideta[i].resize  (n_qp);

	if (Dim == 3)
	  dphidzeta[i].resize (n_qp);

      }

    for (unsigned int i=0; i<n_mapping_shape_functions; i++)
      {
	phi_map[i].resize         (n_qp);
	dphidxi_map[i].resize     (n_qp);

	if (Dim > 1)
	  dphideta_map[i].resize  (n_qp);

	if (Dim == 3)
	  dphidzeta_map[i].resize (n_qp);
      }
  }

#ifdef ENABLE_INFINITE_ELEMENTS
  //------------------------------------------------------------
  // Initialize the data fields, which should only be used for infinite
  // elements, to some sensible values, so that using a FE with the
  // variational formulation of an InfFE, correct element matrices are
  // returned

 {
    weight.resize  (n_qp);
    dweight.resize (n_qp);
    dphase.resize  (n_qp);

    for (unsigned int p=0; p<n_qp; p++)
      {
        weight[p] = 1.;
	dweight[p].zero();
	dphase[p].zero();
      }

 }
#endif // ifdef ENABLE_INFINITE_ELEMENTS

  switch (Dim)
    {

      //------------------------------------------------------------
      // 1D
    case 1:
      {
	// Compute the value of the approximation shape function i at quadrature point p
	for (unsigned int i=0; i<n_approx_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi[i][p]      = FE<Dim,T>::shape       (elem, this->get_order(), i,    qp[p]);
	      dphidxi[i][p]  = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 0, qp[p]);
	    }

	// Compute the value of the mapping shape function i at quadrature point p
	// (Lagrange shape functions are used for mapping)
	for (unsigned int i=0; i<n_mapping_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi_map[i][p]      = FE<Dim,LAGRANGE>::shape       (mapping_elem_type, mapping_order, i,    qp[p]);
	      dphidxi_map[i][p]  = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
	    }

	break;
      }

      //------------------------------------------------------------
      // 2D
    case 2:
      {
	// Compute the value of the approximation shape function i at quadrature point p
	for (unsigned int i=0; i<n_approx_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi[i][p]      = FE<Dim,T>::shape       (elem, this->get_order(), i,    qp[p]);
	      dphidxi[i][p]  = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 0, qp[p]);
	      dphideta[i][p] = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 1, qp[p]);
	    }

	// Compute the value of the mapping shape function i at quadrature point p
	// (Lagrange shape functions are used for mapping)
	for (unsigned int i=0; i<n_mapping_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi_map[i][p]      = FE<Dim,LAGRANGE>::shape       (mapping_elem_type, mapping_order, i,    qp[p]);
	      dphidxi_map[i][p]  = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
	      dphideta_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 1, qp[p]);
	    }

       	break;
      }

      //------------------------------------------------------------
      // 3D
    case 3:
      {
	// Compute the value of the approximation shape function i at quadrature point p
	for (unsigned int i=0; i<n_approx_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi[i][p]       = FE<Dim,T>::shape       (elem, this->get_order(), i,    qp[p]);
	      dphidxi[i][p]   = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 0, qp[p]);
	      dphideta[i][p]  = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 1, qp[p]);
	      dphidzeta[i][p] = FE<Dim,T>::shape_deriv (elem, this->get_order(), i, 2, qp[p]);
	    }

	// Compute the value of the mapping shape function i at quadrature point p
	// (Lagrange shape functions are used for mapping)
	for (unsigned int i=0; i<n_mapping_shape_functions; i++)
	  for (unsigned int p=0; p<n_qp; p++)
	    {
	      phi_map[i][p]       = FE<Dim,LAGRANGE>::shape       (mapping_elem_type, mapping_order, i,    qp[p]);
	      dphidxi_map[i][p]   = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
	      dphideta_map[i][p]  = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 1, qp[p]);
	      dphidzeta_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 2, qp[p]);
	    }

	break;
      }

    default:
      error();
    }

  // Stop logging the shape function initialization
  STOP_LOG("init_shape_functions()", "FE");
}

#ifdef ENABLE_INFINITE_ELEMENTS

template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::init_base_shape_functions(const std::vector<Point>& qp,
					  const Elem* e)
{
  elem_type = e->type();
  init_shape_functions(qp, e);
}

#endif

//--------------------------------------------------------------
// Explicit instantiations using macro from fe_macro.h

INSTANTIATE_FE(1);

INSTANTIATE_FE(2);

INSTANTIATE_FE(3);

<|endoftext|>