diff --git a/check/fixes.frm b/check/fixes.frm index d5f4d599..fcb6ea75 100644 --- a/check/fixes.frm +++ b/check/fixes.frm @@ -4379,6 +4379,64 @@ assert stdout =~ exact_pattern(<<'EOF') ~~~Factor 1 is a EOF *--#] Issue747_2 : +*--#[ Issue750 : +#- +Off Statistics; + +NTensor A,B,C; +CTensor D,E,F; +NFunction a,b,c; +CFunction d,e,f; + +AutoDeclare Vector p; +AutoDeclare Index mu; + +Local testNT1 = A(mu1) *B(mu1) *C(mu1); +Local testNT2 = A(mu1,mu2) *B(mu1,mu2) *C(mu1,mu2); +Local testNT3 = A(mu1,mu2,mu3)*B(mu1,mu2,mu3)*C(mu1,mu2,mu3); +Local testCT1 = D(mu1) *E(mu1) *F(mu1); +Local testCT2 = D(mu1,mu2) *E(mu1,mu2) *F(mu1,mu2); +Local testCT3 = D(mu1,mu2,mu3)*E(mu1,mu2,mu3)*F(mu1,mu2,mu3); +Local testNF1 = a(mu1) *b(mu1) *c(mu1); +Local testNF2 = a(mu1,mu2) *b(mu1,mu2) *c(mu1,mu2); +Local testNF3 = a(mu1,mu2,mu3)*b(mu1,mu2,mu3)*c(mu1,mu2,mu3); +Local testCF1 = d(mu1) *e(mu1) *f(mu1); +Local testCF2 = d(mu1,mu2) *e(mu1,mu2) *f(mu1,mu2); +Local testCF3 = d(mu1,mu2,mu3)*e(mu1,mu2,mu3)*f(mu1,mu2,mu3); + +* Replace the last first, to make sure the non-commuting +* versions stay in-order in the single-index case. +Identify C(?a) = putfirst_(C,2,?a); +Identify F(?a) = putfirst_(F,2,?a); +Identify c(?a) = putfirst_(c,2,?a); +Identify f(?a) = putfirst_(f,2,?a); + +Identify B(?a) = putfirst_(B,2,?a); +Identify E(?a) = putfirst_(E,2,?a); +Identify b(?a) = putfirst_(b,2,?a); +Identify e(?a) = putfirst_(e,2,?a); + +Identify A(?a) = putfirst_(A,2,?a); +Identify D(?a) = putfirst_(D,2,?a); +Identify a(?a) = putfirst_(a,2,?a); +Identify d(?a) = putfirst_(d,2,?a); + +Print; +.end +assert succeeded? +assert result("testNT1") =~ expr("putfirst_(A,2,mu1)*putfirst_(B,2,mu1)*putfirst_(C,2,mu1)") +assert result("testNT2") =~ expr("A(mu2,mu1)*B(mu2,mu1)*C(mu2,mu1)") +assert result("testNT3") =~ expr("A(mu2,mu1,mu3)*B(mu2,mu1,mu3)*C(mu2,mu1,mu3)") +assert result("testCT1") =~ expr("putfirst_(F,2,mu1)*putfirst_(E,2,mu1)*putfirst_(D,2,mu1)") +assert result("testCT2") =~ expr("D(mu2,mu1)*E(mu2,mu1)*F(mu2,mu1)") +assert result("testCT3") =~ expr("D(mu2,mu1,mu3)*E(mu2,mu1,mu3)*F(mu2,mu1,mu3)") +assert result("testNF1") =~ expr("putfirst_(a,2,mu1)*putfirst_(b,2,mu1)*putfirst_(c,2,mu1)") +assert result("testNF2") =~ expr("a(mu2,mu1)*b(mu2,mu1)*c(mu2,mu1)") +assert result("testNF3") =~ expr("a(mu2,mu1,mu3)*b(mu2,mu1,mu3)*c(mu2,mu1,mu3)") +assert result("testCF1") =~ expr("putfirst_(f,2,mu1)*putfirst_(e,2,mu1)*putfirst_(d,2,mu1)") +assert result("testCF2") =~ expr("d(mu2,mu1)*e(mu2,mu1)*f(mu2,mu1)") +assert result("testCF3") =~ expr("d(mu2,mu1,mu3)*e(mu2,mu1,mu3)*f(mu2,mu1,mu3)") +*--#] Issue750 : *--#[ PullReq535 : * This test requires more than the specified 50K workspace. #:maxtermsize 200 diff --git a/doc/manual/functions.tex b/doc/manual/functions.tex index a7040bb5..19230141 100644 --- a/doc/manual/functions.tex +++ b/doc/manual/functions.tex @@ -986,10 +986,11 @@ \section{putfirst\_}\index{putfirst\_}\index{function!putfirst\_} This function allows one to select a given argument by its number. The syntax is: \begin{verbatim} - putfirst_(functionname,numberofargument,arguments.....); + putfirst_(name,argument_number,arguments...); \end{verbatim} -It will select the indicated argument in the argument field indicated by -arguments and output this as the first argument in the indicated function. +It will select the argument indicated by ``argument\_number'' in the argument +field ``arguments'' and output this as the first argument in the function or +tensor specified by ``name''. This argument will then be followed by the remaining arguments. Example: % THIS EXAMPLE IS PART OF THE TESTSUITE. CHANGES HERE SHOULD BE APPLIED THERE AS diff --git a/sources/normal.c b/sources/normal.c index 09321b26..582d6d27 100644 --- a/sources/normal.c +++ b/sources/normal.c @@ -2356,6 +2356,25 @@ ScanCont: while ( t < r ) { rr = term + *term; while ( argTail < rr ) *tt2++ = *argTail++; *term = tt2-term; + if ( functions[*t-FUNCTION].spec == TENSORFUNCTION ) { + // If the output function is a tensor, we have one more job to do. + // The args are formatted as single words, representing indices or vectors. + // There is no ARGHEAD. + WORD *dst = t + FUNHEAD; + WORD *src = dst + 1; + // Strip the type information from the args: + while ( src < t + t[1] ) { + *dst = *src; + dst++; src++; src++; + } + t[1] = dst - t; + // Now copy the rest of the term. We've advanced src one too many above. + src--; + while ( src < term + *term ) { + *dst++ = *src++; + } + *term = dst - term; + } goto Restart; } else pnco[nnco++] = t;