SOSpin is hosted by Hepforge, IPPP Durham
SOSpin  1.0.0
form.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // SOSpin Library
3 // Copyright (C) 2015 SOSpin Project
4 //
5 // Authors:
6 //
7 // Nuno Cardoso (nuno.cardoso@tecnico.ulisboa.pt)
8 // David Emmanuel-Costa (david.costa@tecnico.ulisboa.pt)
9 // Nuno Gonçalves (nunogon@deec.uc.pt)
10 // Catarina Simoes (csimoes@ulg.ac.be)
11 //
12 // ----------------------------------------------------------------------------
13 // This file is part of SOSpin Library.
14 //
15 // SOSpin Library is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or any
18 // later version.
19 //
20 // SOSpin Library is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with SOSpin Library. If not, see <http://www.gnu.org/licenses/>.
27 // ----------------------------------------------------------------------------
28 
29 // form.cpp created on 27/02/2015
30 //
31 // This file contains the functions necessary to do things
32 // in the SOSpin Library.
33 //
34 // Revision 1.1 28/02/2015 23:19:29 david
35 // License updated
36 //
37 
44 #include <sys/stat.h> // for stat()
45 
46 #include "form.h"
47 #include "son.h"
48 #include "dlist.h"
49 
50 using namespace std;
51 
52 
53 
54 namespace sospin {
55 
57 
58 
59 
60 
61 ToForm::ToForm(void){
62  filename = "form";
63  formRenumber = false;
64  resource_path = "";
65  indexSum = true;
66  }
67  ToForm::~ToForm(){
68  clear();
69  }
70 
71 
72 void ToForm::clear(){
73  Functions.clear();
74  FormContraction.clear();
75  resource_path.clear();
76  formRenumber = false;
77  indexSum = true;
78  filename = "form";
79 }
80 
81 
82 
83 
84  bool ToForm::getRenumberOption(){
85  return formRenumber;
86  }
87  bool ToForm::getIndexSum(){
88  return indexSum;
89  }
90  void ToForm::setIndexSum(bool flag){
91  indexSum = flag;
92  }
93 
94  void ToForm::setRenumber(bool flag){
95  formRenumber = flag;
96  if(formRenumber) cout << "Setting \"renumber 1;\" in FORM" << endl;
97  else cout << "UnSetting \"renumber 1;\" in FORM" << endl;
98  }
99  void ToForm::setFilename(string name){
100  filename = name;
101  }
102 
103 
104 
114  form.setRenumber(true);
115 }
121  form.setRenumber(false);
122 }
123 
130  form.setIndexSum(true);
131 }
135  form.setIndexSum(false);
136 }
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
156 string FormField(const string fieldname, \
157  const unsigned int numUpperIds, const unsigned int numLowerIds, \
158  const FuncProp funcp){
159 
160  bool flavorid = false;
161  if(funcp == ASYM_WITH_FLAVOR || funcp == SYM_WITH_FLAVOR ) flavorid = true;
162  //construct function name to form
163  string fname;
164  if(funcp == SYM || funcp == SYM_WITH_FLAVOR) fname = fieldname + "s";
165  else fname = fieldname;
166  if(numLowerIds > 0 || numUpperIds > 0){
167  fname += ToString<unsigned int>(numUpperIds) + ToString<unsigned int>(numLowerIds);
168  }
169  string functionheader = fname;
170  //when flavor id is present we cannot aggregate symmetric/antisymmetric to the field...
171  //if no lower and upper indices, still adds (anti)symmetric...
172  if(!flavorid && (numLowerIds == 0 || numUpperIds == 0) ){
173  if(funcp == SYM || funcp == SYM_WITH_FLAVOR) functionheader += "(symmetric)";
174  else functionheader += "(antisymmetric)";
175  }
176  //Store function name to include in form input file header Functions
177  //and check if the function/field is already defined...
178  bool newfunc = form.function(functionheader);
179  //if this function is a new function...
180  if(newfunc){
182  //field contractions
183  bool fieldctr = false;
184  //Deal with or without flavor id...
185  if(!flavorid && (numLowerIds > 0 && numUpperIds > 0) ) fieldctr = true;
186  if(flavorid && (numLowerIds > 0 || numUpperIds > 0) ) fieldctr = true;
187  if(fieldctr){
188  string tmp, idnum;
189  int idinc = 0;
190  if(flavorid) idinc = 1;
191  if(funcp == SYM || funcp == SYM_WITH_FLAVOR) tmp = "symmetrize " + fname + " ";
192  else tmp = "antisymmetrize " + fname + " ";
193  idnum = "";
194  if(numUpperIds > 1){
195  for(int i = 0; i < numUpperIds; i++){
196  idinc++;
197  idnum += ToString<int>(idinc);
198  if(i < numUpperIds-1) idnum += ",";
199  }
200  idnum += ";";
201  idnum = tmp + idnum;
202  //add it to form defs
203  form + idnum;
204  //cout << "defL: " << idnum << endl;
205  }
206  if(numLowerIds > 1){
207  idnum = "";
208  idinc = 0;
209  if(flavorid) idinc = 1;
210  for(int i = 0; i < numLowerIds; i++){
211  idinc++;
212  idnum += ToString<int>(idinc+numUpperIds);
213  if(i < numLowerIds-1) idnum += ",";
214  }
215  idnum += ";";
216  idnum = tmp + idnum;
217  //add it to form defs
218  form + idnum;
219  }
220  }
221  //form def for upper indice repeated with a lower indice...
222  if(numUpperIds > 0 && numLowerIds > 0){
223  string tmp = "id " + fname + "(";
224  if(flavorid){
225  tmp += "i0?,";
226  newId("i0");
227  }
228  newId("x");
229  for(int i = 1; i <= numUpperIds; i++){
230  for(int j=1; j<=numLowerIds; j++){
231  string tmp1 = tmp;
232  for(int k=1; k<=(numUpperIds+numLowerIds); k++){
233  if(k==i || k==(j+numUpperIds)) tmp1 += "?x";
234  else{
235  tmp1 += "i" + ToString<int>(k) + "?";
236  newId("i" + ToString<int>(k));
237  }
238  if(k < (numUpperIds+numLowerIds) ) tmp1 += ",";
239  else tmp1 += ")=0;";
240  }
241  form + tmp1;
242  }
243  }
244  }
245  //lower indices repeated...
246  if(numUpperIds > 1 && numLowerIds > 0){
247  string tmp = "id " + fname + "(";
248  if(flavorid){
249  tmp += "i0?,";
250  newId("i0");
251  }
252  newId("x");
253  for(int i = 1; i <= numUpperIds; i++){
254  for(int j=i+1; j<=numUpperIds; j++){
255  string tmp1 = tmp;
256  for(int k=1; k<=(numUpperIds+numLowerIds); k++){
257  if(k==i || k==j) tmp1 += "?x";
258  else{
259  tmp1 += "i" + ToString<int>(k) + "?";
260  newId("i" + ToString<int>(k));
261  }
262  if(k < (numUpperIds+numLowerIds) ) tmp1 += ",";
263  else tmp1 += ")=0;";
264  }
265  form + tmp1;
266  //cout << tmp1 << endl;
267  }
268  }
269  }
270  //upper indices repeated...
271  if(numUpperIds > 0 && numLowerIds > 1){
272  string tmp = "id " + fname + "(";
273  if(flavorid){
274  tmp += "i0?,";
275  newId("i0");
276  }
277  newId("x");
278  for(int i = 1; i <= numLowerIds; i++){
279  for(int j=i+1; j<=numLowerIds; j++){
280  string tmp1 = tmp;
281  for(int k=1; k<=(numUpperIds+numLowerIds); k++){
282  if(k==(i+numUpperIds) || k==(j+numUpperIds)) tmp1 += "?x";
283  else{
284  tmp1 += "i" + ToString<int>(k) + "?";
285  newId("i" + ToString<int>(k));
286  }
287  if(k < (numUpperIds+numLowerIds) ) tmp1 += ",";
288  else tmp1 += ")=0;";
289  }
290  form + tmp1;
291  //cout << tmp1 << endl;
292  }
293  }
294  }
295  }
296  return fname;
297 }
298 
299 
300 
301 
302 
303 
304 
305 
320 bool ToForm::function(string func){
321  std::vector<string>::iterator it;
322  it = find (Functions.begin(), Functions.end(), func);
323  if(it == Functions.end()) {
324  Functions.push_back(func);
325  return true;
326  }
327  return false;
328 }
329 
343 void ToForm::contractions(string func){
344  std::vector<string>::iterator it;
345  it = find (FormContraction.begin(), FormContraction.end(), func);
346  if(it != FormContraction.end()) FormContraction.push_back(func);
347 }
348 
352 string ToForm::getFC(){
353  string func = "";
354  for(int i = 0; i < FormContraction.size(); i++){
355  func += FormContraction.at(i);
356  func += "\n";
357  }
358  return func;
359 }
360 
364 string ToForm::getFunction(){
365  string func = "";
366  if(Functions.empty()==false){
367  func = "Functions ";
368  for(int i = 0; i < Functions.size(); i++){
369  func += Functions.at(i);
370  if( i == Functions.size()-1)
371  func +=";\n";
372  else
373  func += ", ";
374  }
375  }
376  return func;
377 }
378 
393 ToForm& ToForm::operator<<(const string &func){
394  std::vector<string>::iterator it;
395  it = find (Functions.begin(), Functions.end(), func);
396  if(it == Functions.end()) Functions.push_back(func);
397  return *this;
398 }
399 
412 ToForm& ToForm::operator+(const string &func){
413  std::vector<string>::iterator it;
414  it = find (FormContraction.begin(), FormContraction.end(), func);
415  if(it == FormContraction.end()) FormContraction.push_back(func);
416  return *this;
417 }
418 
419 
420 
421 
422 #define stringify( x ) stringify_literal( x )
423 #define stringify_literal( x ) # x
424 
431 void Formrun(Braket &exp, ToForm &formin, bool print, bool all, string newidlabel){
432 // static bool setformpath = true;
433  if(formin.rpath().empty()){
434  const char *path;
435  struct stat pstat;
436 #ifdef FORMDIR
437  string pathtmp = stringify(FORMDIR);
438  path = pathtmp.c_str();
439 #else
440  struct stat buffer;
441  if(stat ("form", &buffer) == 0) path=(char*)".";
442  else path = getenv("PATH_TO_FORM");
443 
444 #endif
445  //check path
446  if (!path) {
447  printf("warning: Environment variable PATH_TO_FORM is not set.\n");
448  exit(1);
449  } else if (stat(path, &pstat) || !S_ISDIR(pstat.st_mode)) {
450 #ifdef FORMDIR
451  printf("warning: The path \"%s\" does not exist or is not a directory\n.", path);
452 #else
453  printf("warning: The path \"%s\" specified by PATH_TO_FORM does not exist or is not a directory\n.", path);
454 #endif
455  exit(1);
456  } else {
457  formin.rpath() = path;
458  }
459  formin.rpath() += "/form";
460  //check form program
461  if (stat(formin.rpath().c_str(), &pstat) || !S_ISREG(pstat.st_mode)) {
462 #ifdef FORMDIR
463  printf("warning: The FORM program (\"form\") was not found in \"%s\"\n.", path);
464 #else
465  printf("warning: The FORM program (\"form\") was not found in \"%s\" specified by PATH_TO_FORM.\n.", path);
466 #endif
467  exit(1);
468  }
469  if(getVerbosity()>SUMMARIZE) cout << "Found form in: " << formin.rpath() << endl;
470 // setformpath = false;
471  }
472  if(getVerbosity()>SUMMARIZE) cout << "Creating input form file..." << endl;
473  string filenamein = formin.file() + "_in.frm";
474  ofstream fileout(filenamein.c_str());
475  if (fileout.is_open()){
476  fileout << "#-" << endl;
477  fileout << "**********************************************************************" << endl;
478  fileout << "* *" << endl;
479  fileout << "* Yukawa coupling *" << endl;
480  fileout << "* FORM PROGRAM *" << endl;
481  fileout << "* " << currentDateTime() << " *" << endl;
482  fileout << "**********************************************************************" << endl;
483  fileout << "*" << endl;
484  fileout << "*" << endl;
485  fileout << "Dimension " + ToString<int>(getDim()/2)+ ";" << endl;
486  fileout << "format 255;" << endl;
487  fileout << "CFunction sqrt;" << endl;
488  fileout << "Symbols y,z;" << endl;
489  fileout << formin.getFunction() << "Indices " << IndexList() << endl;
490  fileout << "Off statistics;" << endl;
491  fileout << "*" << endl;
492  exp.setON();
493  fileout << exp;
494  exp.setOFF();
495  fileout << "*" << endl;
496  fileout << "Local R =" << endl;
497  fileout << " #do ii = 1, " + ToString<int>(exp.size()) << endl;
498  fileout << " + R`ii'" << endl;
499  fileout << " #enddo" << endl;
500  fileout << ";" << endl;
501  fileout << "*" << endl;
502  fileout << "contract;" << endl;
503  fileout << "contract;" << endl;
504  fileout << "contract;" << endl;
505  fileout << "contract;" << endl;
506  fileout << "contract;" << endl;
507  fileout << "contract;" << endl;
508  fileout << "contract;" << endl;
509  fileout << "*\n" << formin.getFC() << endl;
510  if(form.getIndexSum()){
511  fileout << "sum " << IndexList() << endl;
512  fileout << "id e_(";
513  for(int i=1; i<= getDim() /2; i++){
514  fileout << i;
515  if(i < getDim() /2) fileout << ",";
516  }
517  fileout << ")=1;" << endl;
518  }
519  if(formin.getRenumberOption()) fileout << "renumber 1;" << endl;
520  //?????????????????????????????????????????????????????
521  //way to deal with 1/sqrt() in middle of expressions
522  fileout << "repeat;" << endl;
523  fileout << " id 1/(sqrt(y?)) = sqrt(1/y);" << endl;
524  fileout << " id sqrt(y?)*sqrt(z?) = sqrt(y*z);" << endl;
525  fileout << "endrepeat;" << endl;
526  //?????????????????????????????????????????????????????
527  if(all) fileout << "print +s;" << endl;
528  else fileout << "print R;" << endl;
529  fileout << ".end" << endl;
530  }
531  else{
532  cout << "Cannot create output file: " << filenamein << endl;
533  cout << "Exiting..." << endl;
534  exit(1);
535  }
536  fileout.close();
537  if(getVerbosity()>SUMMARIZE) cout << "################################################################" << endl;
538  string filenameout = formin.file() + "_out.frm";
539  if(getVerbosity()>SUMMARIZE) cout << "CALLING FORM..." << endl;
540  Timer t1;
541  t1.start();
542  stringstream torun;
543  torun << formin.rpath() << " " << filenamein << " > " << filenameout;
544 
545  if(getVerbosity()==DEBUG_VERBOSE) cout << "Running form: " << torun.str().c_str() << endl;
546  int out_system = system(torun.str().c_str());
547  if(getVerbosity()==DEBUG_VERBOSE) cout << "Read results form output form file..." << endl;
548  //Read results form output file
549  string line;
550  ifstream myfile(filenameout.c_str());
551  stringstream file;
552  if (myfile.is_open()){
553  while ( myfile.good() ){
554  getline(myfile,line);
555  file << line << endl;
556  }
557  myfile.close();
558  }
559  else{
560  cout << "Error reading output form file: " << filenameout << endl;
561  exit(1);
562  }
563  if(getVerbosity()==DEBUG_VERBOSE) cout << "Replacing form indices by j?..." << endl;
564  string filecontent = file.str();
565  //replace form indices by j_?
566  int i=1;
567  while(true){
568  string ind = "N" + ToString<int>(i) + "_?";
569  string idsub = newidlabel + ToString<int>(i);
570  if(filecontent.find(ind)==string::npos) break;
571  while(filecontent.find(ind)!=string::npos){
572  filecontent.replace(filecontent.find(ind),ind.size(),idsub);
573  newId(idsub); //add this id...
574  }
575  i++;
576  }
577  if(getVerbosity()==DEBUG_VERBOSE) cout << "Write back to output form file..." << endl;
578  ofstream fileout0(filenameout.c_str());
579  //write back to form output file with replaced indices
580  fileout0 << filecontent;
581  fileout0.close();
582  if(print){
583  cout << "################################################################" << endl;
584  cout << "RESULTS FROM FORM: " << endl;
585  }
586  if(filecontent.find("R =")==string::npos) {
587  cout << "Error, see FORM file for more details, " << filenameout << endl;
588  exit(1);
589  }
590  filecontent.replace(0, filecontent.find("R ="),"");
591  filecontent.replace(filecontent.find(";")+1, filecontent.length(),"");
592  //filecontent = "\tR = " +filecontent;
593  if(print) cout << filecontent << endl;
594  if(getVerbosity()==DEBUG_VERBOSE) cout << "Write the results in current expression..." << endl;
595  // NEED TO IMPLEMENT A BETTER WAY TO READ TO FORM AND CONVERT THE RESULT TO BRAKET.....
596  filecontent.erase(std::remove(filecontent.begin(), filecontent.end(), ' '), filecontent.end());
597  filecontent.erase(std::remove(filecontent.begin(), filecontent.end(), '\n'), filecontent.end());
598  filecontent = filecontent.substr(filecontent.find("R=")+2, filecontent.find(';')-filecontent.find("R=")-2);
599  vector<string> sta;
600  std::size_t found = filecontent.find_first_of("-+");
601  std::size_t found0 = 0;
602  while (found!=std::string::npos){
603  found=filecontent.find_first_of("+-",found0+1);
604  string tmp = filecontent.substr(found0, found-found0);
605  found0 = found;
606  if(!tmp.empty()) sta.push_back(tmp);
607  }
608  Braket newexp;
609  newexp.expfromForm(sta);
610  exp = newexp;
611  if(print) cout << "################################################################" << endl;
612  if(getVerbosity()>SUMMARIZE) cout << "Time FORM: " << t1.getElapsedTimeInMicroSec() << " us\t" << t1.getElapsedTimeInSec() << " s" << endl;
613 }
614 
615 
616 
617 void CallForm(Braket &exp, bool print, bool all, string newidlabel){
618  Formrun(exp, form, print, all, newidlabel);
619 }
620 
621 
622 }
double getElapsedTimeInSec()
Get elapsed time in second (same as getElapsedTime)
Definition: timer.cpp:116
void setON()
Activate expression term numbering for output writing for each term "Local R?=".
Definition: braket.cpp:225
string file()
Returns the beginning of a input/output FORM file.
Definition: form.h:176
int getDim()
Get the group dimension.
Definition: son.cpp:64
enum FuncProp_s FuncProp
Verbosity getVerbosity()
Return current verbosity level.
Definition: son.cpp:84
void setOFF()
Deactivate expression term numbering for output writing for each term "Local R?=".
Definition: braket.cpp:229
template string ToString< int >(int number)
string FormField(const string fieldname, const unsigned int numUpperIds, const unsigned int numLowerIds, const FuncProp funcp)
Function to add field name and create field proprieties to FORM input file.
Definition: form.cpp:156
Store expression...
Definition: braket.h:198
void expfromForm(vector< string > a)
To pass a expression from form.
Definition: braket.cpp:200
#define stringify(x)
Definition: form.cpp:422
void Formrun(Braket &exp, ToForm &formin, bool print, bool all, string newidlabel)
Create file input for FORM and run the FORM program and return the result to file and/or screen...
Definition: form.cpp:431
void CallForm(Braket &exp, bool print, bool all, string newidlabel)
Creat the file input for FORM and run the FORM program and return the result to file and/or screen...
Definition: form.cpp:617
Definition: enum.h:65
Defintions for all general (initialisation etc.) routines of class DList.
ToForm form
Definition: form.cpp:56
void setFormIndexSum()
Set the index sum in input FORM file, ie, adds "sum i,j,...;" and "id e_(1,...,N) = 1"...
Definition: form.cpp:129
Definition: enum.h:77
OPMode operator+(const OPMode a, const OPMode b)
calculate the mode for the sum
Definition: braket.cpp:304
bool getIndexSum()
Definition: form.cpp:87
void unsetFormIndexSum()
Unset the index sum in input FORM file.
Definition: form.cpp:134
Functions and tables to use with FORM program.
string getFunction()
Returns all the field names.
Definition: form.cpp:364
Main Sospin header file. Includes C++ macros, to simplify expression writing, B operator, Verbosity level and memory usage.
void setFormRenumber()
Set "renumber 1;" in FORM input file. This option is used to renumber indices in order to allow furth...
Definition: form.cpp:113
void start()
Start timer.
Definition: timer.cpp:62
ostream & operator<<(ostream &out, const OPMode &a)
Get the mode of the expression.
Definition: braket.cpp:266
bool getRenumberOption()
Definition: form.cpp:84
bool function(string f)
Store a field, one at each time .
Definition: form.cpp:320
void setRenumber(bool flag=true)
Set "renumber 1;" in FORM input file. This option is used to renumber indices in order to allow furth...
Definition: form.cpp:94
double getElapsedTimeInMicroSec()
Get elapsed time in micro-second.
Definition: timer.cpp:88
void newId(string i)
Store new index of type "string".
Definition: index.cpp:125
const std::string currentDateTime()
Get current date/time, format is YYYY-MM-DD.HH:mm:ss.
Definition: timer.cpp:27
Measure elapsed time.
Definition: timer.h:48
void unsetFormRenumber()
Unset "renumber 1;" in FORM input file.
Definition: form.cpp:120
Container for form specifications.
Definition: form.h:123
string IndexList()
Index list.
Definition: index.cpp:150
string getFC()
Return all type of contractions for the fields.
Definition: form.cpp:352
void setIndexSum(bool flag)
Definition: form.cpp:90
string & rpath()
Returns the full path name and form binary file.
Definition: form.h:180
template string ToString< unsigned int >(unsigned int number)