Merge lp:~maddevelopers/mg5amcnlo/aloha_new_C_routine into lp:~maddevelopers/mg5amcnlo/1.4.3

Proposed by Olivier Mattelaer
Status: Rejected
Rejected by: Olivier Mattelaer
Proposed branch: lp:~maddevelopers/mg5amcnlo/aloha_new_C_routine
Merge into: lp:~maddevelopers/mg5amcnlo/1.4.3
Diff against target: 669 lines (+344/-112)
3 files modified
aloha/aloha_writers.py (+55/-45)
aloha/create_aloha.py (+15/-14)
tests/unit_tests/various/test_aloha.py (+274/-53)
To merge this branch: bzr merge lp:~maddevelopers/mg5amcnlo/aloha_new_C_routine
Reviewer Review Type Date Requested Status
Olivier Mattelaer Disapprove
Johan Alwall (community) Approve
Review via email: mp+94406@code.launchpad.net

Description of the change

I propose a specific review on those changes (independently of those in 1.4.3)
since they are potentially quite dangerous (at least for MSSM).

They are three changes with these branches.
First one 'aesthetical' modification (which simplifies one of the bug fixing and is require for spoin3/2)
- a flip of the argument for the C routine. (this is in fact a "technical"
flip which has no impact at MG5 level, but which will be helpfull for the
implementation of spoin3/2)
so before
def FFVC1_0(F1 , F2, V, Coup):
    return F1[4]*F2[3]*V[1] *Coup
pass to
def FFVC1_0(F2 , F1, V, Coup):
    return F2[4]*F1[3]*V[1] *Coup
therefore this doesn't require any change in the way to call the ALOHA function.

Then two bug corrections (both discover due to spin3/2):
- the definition of Epsilon (mu, nu ,rho,sigma) which now is coherent with the FR definition
- The momentum (inside the Lorentz definition) were wrongly define in previous case in case of C routine. Partially due to flipping of the argument that were not present, and due to the fact that momentum convention are different for incoming and outcoming fermion.

Note that FFVC1_1, FFVC1_2 are not modified.
The case of 4 fermion should be dealt correctly (thanks to unittest)

To post a comment you must log in.
Revision history for this message
Johan Alwall (johan-alwall) wrote :

Hi Olivier,

These are bugs and fixes that I can't really assess. Clearly, the first one is harmless, but for the bug fixes, I can't say. How did you find the bugs? And how do you plan to verify them?

I would suggest to create a couple of models which differ only in the order of Majorana particles to make sure we get the same result. This might be a bit too extensive to include in 1.4.3 though if you want to release that within a day or two.

Cheers,
Johan

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :

Hi Johan,

Both are bugs discover due to problem with either goldstino/spin 3/2
(in a new model made by benjamin for spin3/2).
and discover those thanks to the "check" command.

The first one, is not that worrying the Epsilon(1,2,3,4) was never
use, and the definition in the UFO/ALOHA paper didn't specify the
convention for the sign.
The only problem linked to that bug fixing might be if someone
implemented a model by hand (not very probable).

The second one is the most tricky one.
In fact the first modification is not that harmless since this flip
the definition of the momenta. (which is part of the bug)

For the Epsilon, I have just edit the unit-test by flipping the
expecting sign. This is by far enough.
For the flip +sign: I've add a couple of unit-test associated to those
situations.
I think that this is enough for the moment, when the spin3/2
implementation will be part of the official release, then we can add
some
acceptance test using the "check" command associated to this model.

But at current stage, in addition to all the tests, I've checked that
all the "check" were passing for the two model associated with the
goldstino.

Cheers,

Olivier

On 23-févr.-12, at 20:25, Johan Alwall wrote:

> Hi Olivier,
>
> These are bugs and fixes that I can't really assess. Clearly, the
> first one is harmless, but for the bug fixes, I can't say. How did
> you find the bugs? And how do you plan to verify them?
>
> I would suggest to create a couple of models which differ only in
> the order of Majorana particles to make sure we get the same result.
> This might be a bit too extensive to include in 1.4.3 though if you
> want to release that within a day or two.
>
> Cheers,
> Johan
> --
> https://code.launchpad.net/~maddevelopers/madgraph5/
> aloha_new_C_routine/+merge/94406
> Your team MadDevelopers is subscribed to branch lp:~maddevelopers/
> madgraph5/1.4.3.

211. By Johan Alwall

Add 7545 command for forbidden s-channels, and keep $ for forbidden onshell s-channels

212. By Johan Alwall

Ensure that ptj and mmjj < xqcut for xqcut > 0. If set larger, they are set to 0 unless auto_ptj_and_mjj is T.

213. By mattelaer-olivier

fix interface issue, allow cluster to be 5 time usresponsive for the submit/control function
add seed to the banner

214. By mattelaer-olivier

fix plot issue

Revision history for this message
Johan Alwall (johan-alwall) wrote :

Hello Olivier,

Great work. As I said, I can't really assess this, but if all parallel tests pass and the new version passes all checks (and gives the right result compared to analytical calculations for the models in question), then I'm happy to approve.

Cheers,
Johan

review: Approve
215. By Johan Alwall

Fixed acceptance tests (once and for all), fixed symfact.dat writing independent of number of diagrams (works also for > 10000)

216. By Olivier Mattelaer

new implementation of sqve command

217. By Olivier Mattelaer

merge with the new cmd format.

218. By Olivier Mattelaer

merge with the aloha fixes

219. By Olivier Mattelaer

more secure way for the html double link trick.
fix parralel test for cross-section

220. By mattelaer-olivier

Change html output for the details of the cross-sections. (Merge all results on a single page)
Take care correctly of chrome restricting local call to ajax.

221. By Olivier Mattelaer

fix bug #942376

222. By Olivier Mattelaer

fix a multiple try problem (cluster only)
fix the ./bin/madevent script to close it properly

223. By mattelaer-olivier

fix the delphes problem on the web, simple optimisation, adding a new acceptance test

224. By mattelaer-olivier

New C routine for wavefunctions (not working for Cpp + not tested for combine routine)

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :

Hi,

I' re-using this branch for the last (?) aloha problem pointed by the spin 3/2.

so now for FF
_1 returns a wavefunction associates to the incoming fermion
_2 returns a wavefunction associates to the outcoming fermion

This has off course no effect on SM. (since this is in IO anyway)
For the MSSM, this is probably just equivalent to a renaming of the argumments in ALOHA.
For some NP, this might be important if momentum are present in the lorentz structure.
And off course this is crucial for spin3/2.

This might also explains the failure of Johan to solve the problem associated with the pid.

Note that this is not yet ready for review. Since
1) the Cpp output is not yet fixed
2) I didn't test the combine aloha output with this additional flipping
3) I didn't run any acceptance/parralel test. (but unit test passes, but one linked to Cpp output)

review: Needs Fixing
225. By Olivier Mattelaer

fix Cpp writter

226. By Olivier Mattelaer

added test to ensure combine routines in presence of C routines

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :

Hi,

The two first point are fixed.
and the acceptance test and the short test are all working.

So I'm updating the spin 3/2 branch to see if this fix the associated problem.
And will run tomorrow parallel tests

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :

Hi Johan,

The spoin3/2 requires some additional fixes compare to that versions,
but nothing that claim that the fix is conceptually wrong.
anyway it might be better to merge this branch in spin 3/2 directly.
(and merge 1.4.3 independently of this.)

Spin 3/2 is not yet ready for the merge since they are still some problem for some processes,
like a n1 > grv. But this rather points as a external routines problem (that's my current best guess).

Cheers,

Olivier

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :

I don't know why it passed to merged here.
let put in rejected (since this is now include in spin 3/2 branch)

review: Disapprove

Unmerged revisions

226. By Olivier Mattelaer

added test to ensure combine routines in presence of C routines

225. By Olivier Mattelaer

fix Cpp writter

224. By mattelaer-olivier

New C routine for wavefunctions (not working for Cpp + not tested for combine routine)

223. By mattelaer-olivier

fix the delphes problem on the web, simple optimisation, adding a new acceptance test

222. By Olivier Mattelaer

fix a multiple try problem (cluster only)
fix the ./bin/madevent script to close it properly

221. By Olivier Mattelaer

fix bug #942376

220. By mattelaer-olivier

Change html output for the details of the cross-sections. (Merge all results on a single page)
Take care correctly of chrome restricting local call to ajax.

219. By Olivier Mattelaer

more secure way for the html double link trick.
fix parralel test for cross-section

218. By Olivier Mattelaer

merge with the aloha fixes

217. By Olivier Mattelaer

merge with the new cmd format.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'aloha/aloha_writers.py'
2--- aloha/aloha_writers.py 2012-02-23 16:07:14 +0000
3+++ aloha/aloha_writers.py 2012-03-02 06:37:23 +0000
4@@ -34,10 +34,20 @@
5 self.namestring = name
6 self.abstractname = abstract_routine.name
7 self.comment = abstract_routine.infostr
8- self.offshell = abstract_routine.outgoing
9+ self.offshell = abstract_routine.outgoing
10+
11 self.symmetries = abstract_routine.symmetries
12 self.tag = abstract_routine.tag
13
14+ self.outgoing = self.offshell
15+ if 'C%s' %((self.outgoing + 1) // 2) in self.tag:
16+ #flip the outgoing tag if in conjugate
17+ self.outgoing = self.outgoing + self.outgoing % 2 - (self.outgoing +1) % 2
18+
19+
20+
21+
22+
23 #prepare the necessary object
24 self.collect_variables() # Look for the different variables
25 self.make_all_lists() # Compute the expression for the call ordering
26@@ -182,12 +192,11 @@
27
28 if index in conjugate:
29 index2, spin2 = index+1, self.particles[index+1]
30- if index2 + 1 != outgoing:
31- call_arg.append('%s%d' % (spin2, index2 +1))
32- call_arg.append('%s%d' % (spin, index +1))
33+ call_arg.append('%s%d' % (spin2, index2 +1))
34+ #call_arg.append('%s%d' % (spin, index +1))
35 elif index-1 in conjugate:
36- if index == outgoing:
37- call_arg.append('%s%d' % (spin, index +1))
38+ index2, spin2 = index-1, self.particles[index]
39+ call_arg.append('%s%d' % (spin2, index2 +1))
40 else:
41 call_arg.append('%s%d' % (spin, index +1))
42
43@@ -226,14 +235,14 @@
44 global_sign = -1
45
46 flipped = [2*(int(c[1:])-1) for c in self.tag if c.startswith('C')]
47- if self.offshell % 2:
48- not_flip = self.offshell - 1
49- if not_flip in flipped:
50- flipped.remove(not_flip)
51- else:
52- not_flip = self.offshell - 2
53- if not_flip in flipped:
54- flipped.remove(not_flip)
55+# if self.offshell % 2:
56+# not_flip = self.offshell - 1
57+# if not_flip in flipped:
58+# flipped.remove(not_flip)
59+# else:
60+# not_flip = self.offshell - 2
61+# if not_flip in flipped:
62+# flipped.remove(not_flip)
63
64 for index, spin in enumerate(self.particles):
65 assert(spin in ['S','F','V','T'])
66@@ -252,7 +261,7 @@
67 if index-1 in flipped:
68 sign *= -1
69 # No need to include the outgoing particles in the definitions
70- if index == self.offshell -1:
71+ if index == self.outgoing -1:
72 continue
73
74 # write the
75@@ -320,11 +329,11 @@
76 if not alredy_update:
77 declare_list.append('double complex denom')
78 declare_list.append('double precision M%(id)d, W%(id)d' %
79- {'id': self.offshell})
80+ {'id': self.outgoing})
81 call_arg = '%(args)s, COUP, M%(id)d, W%(id)d, %(spin)s%(id)d' % \
82 {'args': ', '.join(CallList),
83 'spin': self.particles[self.offshell -1],
84- 'id': self.offshell}
85+ 'id': self.outgoing}
86 str_out = ' subroutine %s(%s)\n' % (name, call_arg)
87
88 # Forcing implicit None
89@@ -371,7 +380,7 @@
90 offshell_size = self.type_to_size[offshelltype]
91 #Implement the conservation of Energy Impulsion
92 for i in range(-1,1):
93- str_out += '%s%d(%d)= ' % (offshelltype, self.offshell, \
94+ str_out += '%s%d(%d)= ' % (offshelltype, self.outgoing, \
95 offshell_size + i)
96
97 pat=re.compile(r'^[-+]?(?P<spin>\w)')
98@@ -390,11 +399,11 @@
99 if self.offshell == index and type in ['V','S']:
100 sign = -1
101 if 'C%s' % ((index +1) // 2) in self.tag:
102- if index == self.offshell:
103- pass
104- elif index % 2 and index -1 != self.offshell:
105- pass
106- elif index %2 == 1 and index + 1 != self.offshell:
107+ if index == self.outgoing:
108+ pass
109+ elif index % 2 and index -1 != self.outgoing:
110+ pass
111+ elif index % 2 == 1 and index + 1 != self.outgoing:
112 pass
113 else:
114 sign *= -1
115@@ -464,7 +473,7 @@
116 OutString = OutString + string + '\n'
117 else:
118 OffShellParticle = '%s%d' % (self.particles[self.offshell-1],\
119- self.offshell)
120+ self.outgoing)
121 numerator = self.obj.numerator
122 denominator = self.obj.denominator
123 for ind in denominator.listindices():
124@@ -577,11 +586,11 @@
125 else:
126 main = '%(spin)s%(id)d' % \
127 {'spin': self.particles[offshell -1],
128- 'id': self.offshell}
129+ 'id': self.outgoing}
130 call_arg = '%(args)s, %(COUP)s, M%(id)d, W%(id)d, %(LAST)s' % \
131 {'args': ', '.join(self.calllist['CallList']),
132 'COUP':'COUP%d',
133- 'id': self.offshell,
134+ 'id': self.outgoing,
135 'LAST': '%s'}
136
137 # make the first call
138@@ -723,8 +732,8 @@
139 str_out = 'void %(name)s(%(args)s, double M%(number)d, double W%(number)d, complex<double>%(out)s%(number)d[])' % \
140 {'name': name,
141 'args': ','.join(CallList+ ['complex<double> COUP']),
142- 'out': self.particles[OffShellParticle],
143- 'number': OffShellParticle + 1
144+ 'out': self.particles[self.outgoing - 1],
145+ 'number': self.outgoing
146 }
147
148 h_string = str_out + ";\n\n"
149@@ -755,7 +764,7 @@
150 offshell_size = self.type_to_size[offshelltype]
151 #Implement the conservation of Energy Impulsion
152 for i in range(-2,0):
153- str_out += '%s%d[%d]= ' % (offshelltype, self.offshell,
154+ str_out += '%s%d[%d]= ' % (offshelltype, self.outgoing,
155 offshell_size + i)
156
157 pat=re.compile(r'^[-+]?(?P<spin>\w)')
158@@ -775,11 +784,11 @@
159 if self.offshell == index and type in ['V', 'S']:
160 sign = -1
161 if 'C%s' % ((index +1) // 2) in self.tag:
162- if index == self.offshell:
163- pass
164- elif index % 2 and index -1 != self.offshell:
165- pass
166- elif index %2 == 1 and index + 1 != self.offshell:
167+ if index == self.outgoing:
168+ pass
169+ elif index % 2 and index -1 != self.outgoing:
170+ pass
171+ elif index %2 == 1 and index + 1 != self.outgoing:
172 pass
173 else:
174 sign *= -1
175@@ -845,7 +854,7 @@
176 string = string.replace('+-', '-')
177 OutString = OutString + string + ';\n'
178 else:
179- OffShellParticle = self.particles[self.offshell-1]+'%s'%(self.offshell)
180+ OffShellParticle = self.particles[self.offshell-1]+'%s'%(self.outgoing)
181 numerator = self.obj.numerator
182 denominator = self.obj.denominator
183 for ind in denominator.listindices():
184@@ -1115,7 +1124,7 @@
185
186 WriteALOHA.__init__(self, abstract_routine, dirpath)
187 self.outname = '%s%s' % (self.particles[self.offshell -1], \
188- self.offshell)
189+ self.outgoing)
190
191
192 def change_var_format(self, name):
193@@ -1192,7 +1201,7 @@
194 str_out += 'def %(name)s(%(args)s, COUP, M%(id)d, W%(id)d):\n' % \
195 {'name': name,
196 'args': ', '.join(CallList),
197- 'id': self.offshell}
198+ 'id': self.outgoing}
199 return str_out
200
201 def make_declaration_list(self):
202@@ -1238,16 +1247,17 @@
203 sign = 1
204 if self.offshell == index and type in ['V','S']:
205 sign = -1
206+
207 if 'C%s' % ((index +1) // 2) in self.tag:
208- if index == self.offshell:
209- pass
210- elif index % 2 and index -1 != self.offshell:
211- pass
212- elif index %2 == 1 and index + 1 != self.offshell:
213+ if index == self.outgoing:
214+ pass
215+ elif index % 2 and index -1 != self.outgoing:
216+ pass
217+ elif index %2 == 1 and index + 1 != self.outgoing:
218 pass
219 else:
220 sign *= -1
221-
222+
223 if sign == -1 :
224 sign = '- '
225 else:
226@@ -1340,11 +1350,11 @@
227 else:
228 main = '%(spin)s%(id)d' % \
229 {'spin': self.particles[self.offshell -1],
230- 'id': self.offshell}
231+ 'id': self.outgoing}
232 call_arg = '%(args)s, %(COUP)s, M%(id)d, W%(id)d' % \
233 {'args': ', '.join(self.calllist['CallList']),
234 'COUP':'COUP%d',
235- 'id': self.offshell}
236+ 'id': self.outgoing}
237
238 # make the first call
239 line = " %s = %s%s("+call_arg+")\n"
240
241=== modified file 'aloha/create_aloha.py'
242--- aloha/create_aloha.py 2012-02-21 18:10:48 +0000
243+++ aloha/create_aloha.py 2012-03-02 06:37:23 +0000
244@@ -199,6 +199,9 @@
245 #multiply by the wave functions
246 nb_spinor = 0
247 outgoing = self.outgoing
248+ if (outgoing + 1) // 2 in self.conjg:
249+ #flip the outgoing tag if in conjugate
250+ outgoing = outgoing + outgoing % 2 - (outgoing +1) % 2
251
252 if not self.routine_kernel:
253 AbstractRoutineBuilder.counter += 1
254@@ -215,21 +218,25 @@
255 else:
256 lorentz = self.routine_kernel
257 aloha_lib.USE_TAG = set(self.kernel_tag)
258- for (i, spin ) in enumerate(self.spins):
259+
260+
261+ for (i, spin ) in enumerate(self.spins):
262 id = i + 1
263+
264 #Check if this is the outgoing particle
265 if id == outgoing:
266 if spin == 1:
267 lorentz *= complex(0,1)
268 elif spin == 2:
269 # shift and flip the tag if we multiply by C matrices
270- if (id+1) // 2 in self.conjg:
271- id += _conjugate_gap
272- nb_spinor += 1
273- if nb_spinor %2:
274- lorentz *= SpinorPropagator(id, 'I2', self.outgoing)
275+ if (id + 1) // 2 in self.conjg:
276+ id += _conjugate_gap + id % 2 - (id +1) % 2
277+ if id % 2:
278+ #propagator outcoming
279+ lorentz *= SpinorPropagator(id, 'I2', outgoing)
280 else:
281- lorentz *= SpinorPropagator('I2', id, self.outgoing)
282+ #propagator incoming
283+ lorentz *= SpinorPropagator('I2', id, outgoing)
284 elif spin == 3 :
285 lorentz *= VectorPropagator(id, 'I2', id)
286 elif spin == 5 :
287@@ -250,15 +257,9 @@
288 elif spin == 2:
289 # shift the tag if we multiply by C matrices
290 if (id+1) // 2 in self.conjg:
291- spin_id = id + _conjugate_gap
292- if id % 2:
293- if outgoing not in [id, id+1]:
294- spin_id += 1
295- elif outgoing not in [id, id-1]:
296- spin_id -= 1
297+ spin_id = id + _conjugate_gap + id % 2 - (id +1) % 2
298 else:
299 spin_id = id
300- nb_spinor += 1
301 lorentz *= Spinor(spin_id, id)
302 elif spin == 3:
303 lorentz *= Vector(id, id)
304
305=== modified file 'tests/unit_tests/various/test_aloha.py'
306--- tests/unit_tests/various/test_aloha.py 2012-02-26 02:56:25 +0000
307+++ tests/unit_tests/various/test_aloha.py 2012-03-02 06:37:23 +0000
308@@ -3742,55 +3742,55 @@
309 """ test that python writer works """
310
311 solution ="""import wavefunctions
312-def FFV1C1_1(F2, V3, COUP, M1, W1):
313+def FFV1C1_1(F1, V3, COUP, M2, W2):
314+ F2 = wavefunctions.WaveFunction(size=6)
315+ F2[4] = F1[4]+V3[4]
316+ F2[5] = F1[5]+V3[5]
317+ P2 = [complex(F2[4]).real, \\
318+ complex(F2[5]).real, \\
319+ complex(F2[5]).imag, \\
320+ complex(F2[4]).imag]
321+ denom =1.0/(( (M2*( -M2+1j*W2))+( (P2[0]**2)-(P2[1]**2)-(P2[2]**2)-(P2[3]**2))))
322+ F2[0]= COUP*denom*( (F1[1]*( (P2[0]*( 1j*V3[1]-V3[2]))+( (P2[1]*( -1j*V3[0]-1j*V3[3]))+( (P2[2]*( V3[0]+V3[3]))+(P2[3]*( 1j*V3[1]-V3[2]))))))+( (F1[0]*( (P2[0]*( -1j*V3[0]+1j*V3[3]))+( (P2[1]*( 1j*V3[1]+V3[2]))+( (P2[2]*( -V3[1]+1j*V3[2]))+(P2[3]*( -1j*V3[0]+1j*V3[3]))))))+(M2*( (F1[3]*( -1j*V3[1]+V3[2]))+(F1[2]*( -1j*V3[0]-1j*V3[3]))))))
323+ F2[1]= COUP*denom*( (F1[1]*( (P2[0]*( -1j*V3[0]-1j*V3[3]))+( (P2[1]*( 1j*V3[1]-V3[2]))+( (P2[2]*( V3[1]+1j*V3[2]))+(P2[3]*( 1j*V3[0]+1j*V3[3]))))))+( (F1[0]*( (P2[0]*( 1j*V3[1]+V3[2]))+( (P2[1]*( -1j*V3[0]+1j*V3[3]))+( (P2[2]*( -V3[0]+V3[3]))+(P2[3]*( -1j*V3[1]-V3[2]))))))+(M2*( (F1[3]*( -1j*V3[0]+1j*V3[3]))+(F1[2]*( -1j*V3[1]-V3[2]))))))
324+ F2[2]= COUP*denom*( (F1[3]*( (P2[0]*( -1j*V3[1]+V3[2]))+( (P2[1]*( 1j*V3[0]-1j*V3[3]))+( (P2[2]*( -V3[0]+V3[3]))+(P2[3]*( 1j*V3[1]-V3[2]))))))+( (F1[2]*( (P2[0]*( -1j*V3[0]-1j*V3[3]))+( (P2[1]*( 1j*V3[1]+V3[2]))+( (P2[2]*( -V3[1]+1j*V3[2]))+(P2[3]*( 1j*V3[0]+1j*V3[3]))))))+(M2*( (F1[1]*( 1j*V3[1]-V3[2]))+(F1[0]*( -1j*V3[0]+1j*V3[3]))))))
325+ F2[3]= COUP*denom*( (F1[3]*( (P2[0]*( -1j*V3[0]+1j*V3[3]))+( (P2[1]*( 1j*V3[1]-V3[2]))+( (P2[2]*( V3[1]+1j*V3[2]))+(P2[3]*( -1j*V3[0]+1j*V3[3]))))))+( (F1[2]*( (P2[0]*( -1j*V3[1]-V3[2]))+( (P2[1]*( 1j*V3[0]+1j*V3[3]))+( (P2[2]*( V3[0]+V3[3]))+(P2[3]*( -1j*V3[1]-V3[2]))))))+(M2*( (F1[1]*( -1j*V3[0]-1j*V3[3]))+(F1[0]*( 1j*V3[1]+V3[2]))))))
326+ return F2
327+
328+
329+"""
330+
331+ FFV = UFOLorentz(name = 'FFV1',
332+ spins = [ 2, 2, 3 ],
333+ structure = 'Gamma(3,2,1)')
334+ builder = create_aloha.AbstractRoutineBuilder(FFV)
335+ builder.apply_conjugation()
336+ amp = builder.compute_routine(1)
337+ routine = amp.write(output_dir=None, language='Python')
338+
339+ split_solution = solution.split('\n')
340+ split_routine = routine.split('\n')
341+ self.assertEqual(split_solution, split_routine)
342+ self.assertEqual(len(split_routine), len(split_solution))
343+
344+ solution ="""import wavefunctions
345+def FFV1C1_2(F2, V3, COUP, M1, W1):
346 F1 = wavefunctions.WaveFunction(size=6)
347- F1[4] = F2[4]+V3[4]
348- F1[5] = F2[5]+V3[5]
349+ F1[4] = F2[4]-V3[4]
350+ F1[5] = F2[5]-V3[5]
351 P1 = [complex(F1[4]).real, \\
352 complex(F1[5]).real, \\
353 complex(F1[5]).imag, \\
354 complex(F1[4]).imag]
355 denom =1.0/(( (M1*( -M1+1j*W1))+( (P1[0]**2)-(P1[1]**2)-(P1[2]**2)-(P1[3]**2))))
356- F1[0]= COUP*denom*( (F2[1]*( (P1[0]*( 1j*V3[1]-V3[2]))+( (P1[1]*( -1j*V3[0]-1j*V3[3]))+( (P1[2]*( V3[0]+V3[3]))+(P1[3]*( 1j*V3[1]-V3[2]))))))+( (F2[0]*( (P1[0]*( -1j*V3[0]+1j*V3[3]))+( (P1[1]*( 1j*V3[1]+V3[2]))+( (P1[2]*( -V3[1]+1j*V3[2]))+(P1[3]*( -1j*V3[0]+1j*V3[3]))))))+(M1*( (F2[3]*( -1j*V3[1]+V3[2]))+(F2[2]*( -1j*V3[0]-1j*V3[3]))))))
357- F1[1]= COUP*denom*( (F2[1]*( (P1[0]*( -1j*V3[0]-1j*V3[3]))+( (P1[1]*( 1j*V3[1]-V3[2]))+( (P1[2]*( V3[1]+1j*V3[2]))+(P1[3]*( 1j*V3[0]+1j*V3[3]))))))+( (F2[0]*( (P1[0]*( 1j*V3[1]+V3[2]))+( (P1[1]*( -1j*V3[0]+1j*V3[3]))+( (P1[2]*( -V3[0]+V3[3]))+(P1[3]*( -1j*V3[1]-V3[2]))))))+(M1*( (F2[3]*( -1j*V3[0]+1j*V3[3]))+(F2[2]*( -1j*V3[1]-V3[2]))))))
358- F1[2]= COUP*denom*( (F2[3]*( (P1[0]*( -1j*V3[1]+V3[2]))+( (P1[1]*( 1j*V3[0]-1j*V3[3]))+( (P1[2]*( -V3[0]+V3[3]))+(P1[3]*( 1j*V3[1]-V3[2]))))))+( (F2[2]*( (P1[0]*( -1j*V3[0]-1j*V3[3]))+( (P1[1]*( 1j*V3[1]+V3[2]))+( (P1[2]*( -V3[1]+1j*V3[2]))+(P1[3]*( 1j*V3[0]+1j*V3[3]))))))+(M1*( (F2[1]*( 1j*V3[1]-V3[2]))+(F2[0]*( -1j*V3[0]+1j*V3[3]))))))
359- F1[3]= COUP*denom*( (F2[3]*( (P1[0]*( -1j*V3[0]+1j*V3[3]))+( (P1[1]*( 1j*V3[1]-V3[2]))+( (P1[2]*( V3[1]+1j*V3[2]))+(P1[3]*( -1j*V3[0]+1j*V3[3]))))))+( (F2[2]*( (P1[0]*( -1j*V3[1]-V3[2]))+( (P1[1]*( 1j*V3[0]+1j*V3[3]))+( (P1[2]*( V3[0]+V3[3]))+(P1[3]*( -1j*V3[1]-V3[2]))))))+(M1*( (F2[1]*( -1j*V3[0]-1j*V3[3]))+(F2[0]*( 1j*V3[1]+V3[2]))))))
360+ F1[0]= COUP*denom*( (F2[0]*( (V3[1]*( 1j*P1[1]+P1[2]))+( (V3[2]*( -P1[1]+1j*P1[2]))+( (V3[0]*( -1j*P1[0]+1j*P1[3]))+(V3[3]*( -1j*P1[0]+1j*P1[3]))))))+( (F2[1]*( (V3[0]*( 1j*P1[1]+P1[2]))+( (V3[3]*( -1j*P1[1]-P1[2]))+( (V3[1]*( -1j*P1[0]+1j*P1[3]))+(V3[2]*( -P1[0]+P1[3]))))))+(M1*( (F2[2]*( -1j*V3[0]+1j*V3[3]))+(F2[3]*( 1j*V3[1]+V3[2]))))))
361+ F1[1]= COUP*denom*( (F2[0]*( (V3[1]*( -1j*P1[0]-1j*P1[3]))+( (V3[2]*( P1[0]+P1[3]))+( (V3[0]*( 1j*P1[1]-P1[2]))+(V3[3]*( 1j*P1[1]-P1[2]))))))+( (F2[1]*( (V3[0]*( -1j*P1[0]-1j*P1[3]))+( (V3[3]*( 1j*P1[0]+1j*P1[3]))+( (V3[1]*( 1j*P1[1]-P1[2]))+(V3[2]*( P1[1]+1j*P1[2]))))))+(M1*( (F2[2]*( 1j*V3[1]-V3[2]))+(F2[3]*( -1j*V3[0]-1j*V3[3]))))))
362+ F1[2]= COUP*denom*( (F2[2]*( (V3[1]*( 1j*P1[1]+P1[2]))+( (V3[2]*( -P1[1]+1j*P1[2]))+( (V3[0]*( -1j*P1[0]-1j*P1[3]))+(V3[3]*( 1j*P1[0]+1j*P1[3]))))))+( (F2[3]*( (V3[0]*( -1j*P1[1]-P1[2]))+( (V3[3]*( -1j*P1[1]-P1[2]))+( (V3[1]*( 1j*P1[0]+1j*P1[3]))+(V3[2]*( P1[0]+P1[3]))))))+(M1*( (F2[0]*( -1j*V3[0]-1j*V3[3]))+(F2[1]*( -1j*V3[1]-V3[2]))))))
363+ F1[3]= COUP*denom*( (F2[2]*( (V3[1]*( 1j*P1[0]-1j*P1[3]))+( (V3[2]*( -P1[0]+P1[3]))+( (V3[0]*( -1j*P1[1]+P1[2]))+(V3[3]*( 1j*P1[1]-P1[2]))))))+( (F2[3]*( (V3[0]*( -1j*P1[0]+1j*P1[3]))+( (V3[3]*( -1j*P1[0]+1j*P1[3]))+( (V3[1]*( 1j*P1[1]-P1[2]))+(V3[2]*( P1[1]+1j*P1[2]))))))+(M1*( (F2[0]*( -1j*V3[1]+V3[2]))+(F2[1]*( -1j*V3[0]+1j*V3[3]))))))
364 return F1
365
366
367 """
368-
369- FFV = UFOLorentz(name = 'FFV1',
370- spins = [ 2, 2, 3 ],
371- structure = 'Gamma(3,2,1)')
372- builder = create_aloha.AbstractRoutineBuilder(FFV)
373- builder.apply_conjugation()
374- amp = builder.compute_routine(1)
375- routine = amp.write(output_dir=None, language='Python')
376-
377- split_solution = solution.split('\n')
378- split_routine = routine.split('\n')
379- self.assertEqual(split_solution, split_routine)
380- self.assertEqual(len(split_routine), len(split_solution))
381-
382- solution ="""import wavefunctions
383-def FFV1C1_2(F1, V3, COUP, M2, W2):
384- F2 = wavefunctions.WaveFunction(size=6)
385- F2[4] = F1[4]-V3[4]
386- F2[5] = F1[5]-V3[5]
387- P2 = [complex(F2[4]).real, \\
388- complex(F2[5]).real, \\
389- complex(F2[5]).imag, \\
390- complex(F2[4]).imag]
391- denom =1.0/(( (M2*( -M2+1j*W2))+( (P2[0]**2)-(P2[1]**2)-(P2[2]**2)-(P2[3]**2))))
392- F2[0]= COUP*denom*( (F1[0]*( (V3[1]*( 1j*P2[1]+P2[2]))+( (V3[2]*( -P2[1]+1j*P2[2]))+( (V3[0]*( -1j*P2[0]+1j*P2[3]))+(V3[3]*( -1j*P2[0]+1j*P2[3]))))))+( (F1[1]*( (V3[0]*( 1j*P2[1]+P2[2]))+( (V3[3]*( -1j*P2[1]-P2[2]))+( (V3[1]*( -1j*P2[0]+1j*P2[3]))+(V3[2]*( -P2[0]+P2[3]))))))+(M2*( (F1[2]*( -1j*V3[0]+1j*V3[3]))+(F1[3]*( 1j*V3[1]+V3[2]))))))
393- F2[1]= COUP*denom*( (F1[0]*( (V3[1]*( -1j*P2[0]-1j*P2[3]))+( (V3[2]*( P2[0]+P2[3]))+( (V3[0]*( 1j*P2[1]-P2[2]))+(V3[3]*( 1j*P2[1]-P2[2]))))))+( (F1[1]*( (V3[0]*( -1j*P2[0]-1j*P2[3]))+( (V3[3]*( 1j*P2[0]+1j*P2[3]))+( (V3[1]*( 1j*P2[1]-P2[2]))+(V3[2]*( P2[1]+1j*P2[2]))))))+(M2*( (F1[2]*( 1j*V3[1]-V3[2]))+(F1[3]*( -1j*V3[0]-1j*V3[3]))))))
394- F2[2]= COUP*denom*( (F1[2]*( (V3[1]*( 1j*P2[1]+P2[2]))+( (V3[2]*( -P2[1]+1j*P2[2]))+( (V3[0]*( -1j*P2[0]-1j*P2[3]))+(V3[3]*( 1j*P2[0]+1j*P2[3]))))))+( (F1[3]*( (V3[0]*( -1j*P2[1]-P2[2]))+( (V3[3]*( -1j*P2[1]-P2[2]))+( (V3[1]*( 1j*P2[0]+1j*P2[3]))+(V3[2]*( P2[0]+P2[3]))))))+(M2*( (F1[0]*( -1j*V3[0]-1j*V3[3]))+(F1[1]*( -1j*V3[1]-V3[2]))))))
395- F2[3]= COUP*denom*( (F1[2]*( (V3[1]*( 1j*P2[0]-1j*P2[3]))+( (V3[2]*( -P2[0]+P2[3]))+( (V3[0]*( -1j*P2[1]+P2[2]))+(V3[3]*( 1j*P2[1]-P2[2]))))))+( (F1[3]*( (V3[0]*( -1j*P2[0]+1j*P2[3]))+( (V3[3]*( -1j*P2[0]+1j*P2[3]))+( (V3[1]*( 1j*P2[1]-P2[2]))+(V3[2]*( P2[1]+1j*P2[2]))))))+(M2*( (F1[0]*( -1j*V3[1]+V3[2]))+(F1[1]*( -1j*V3[0]+1j*V3[3]))))))
396- return F2
397-
398-
399-"""
400
401 amp = builder.compute_routine(2)
402
403@@ -3800,6 +3800,52 @@
404 split_routine = routine.split('\n')
405 self.assertEqual(split_solution, split_routine)
406 self.assertEqual(len(split_routine), len(split_solution))
407+
408+ solution = """import wavefunctions
409+def FFV1C1_1(F1, V3, COUP, M2, W2):
410+ F2 = wavefunctions.WaveFunction(size=6)
411+ F2[4] = F1[4]+V3[4]
412+ F2[5] = F1[5]+V3[5]
413+ P2 = [complex(F2[4]).real, \\
414+ complex(F2[5]).real, \\
415+ complex(F2[5]).imag, \\
416+ complex(F2[4]).imag]
417+ denom =1.0/(( (M2*( -M2+1j*W2))+( (P2[0]**2)-(P2[1]**2)-(P2[2]**2)-(P2[3]**2))))
418+ F2[0]= COUP*denom*( (F1[1]*( (P2[0]*( 1j*V3[1]-V3[2]))+( (P2[1]*( -1j*V3[0]-1j*V3[3]))+( (P2[2]*( V3[0]+V3[3]))+(P2[3]*( 1j*V3[1]-V3[2]))))))+( (F1[0]*( (P2[0]*( -1j*V3[0]+1j*V3[3]))+( (P2[1]*( 1j*V3[1]+V3[2]))+( (P2[2]*( -V3[1]+1j*V3[2]))+(P2[3]*( -1j*V3[0]+1j*V3[3]))))))+(M2*( (F1[3]*( -1j*V3[1]+V3[2]))+(F1[2]*( -1j*V3[0]-1j*V3[3]))))))
419+ F2[1]= COUP*denom*( (F1[1]*( (P2[0]*( -1j*V3[0]-1j*V3[3]))+( (P2[1]*( 1j*V3[1]-V3[2]))+( (P2[2]*( V3[1]+1j*V3[2]))+(P2[3]*( 1j*V3[0]+1j*V3[3]))))))+( (F1[0]*( (P2[0]*( 1j*V3[1]+V3[2]))+( (P2[1]*( -1j*V3[0]+1j*V3[3]))+( (P2[2]*( -V3[0]+V3[3]))+(P2[3]*( -1j*V3[1]-V3[2]))))))+(M2*( (F1[3]*( -1j*V3[0]+1j*V3[3]))+(F1[2]*( -1j*V3[1]-V3[2]))))))
420+ F2[2]= COUP*denom*( (F1[3]*( (P2[0]*( -1j*V3[1]+V3[2]))+( (P2[1]*( 1j*V3[0]-1j*V3[3]))+( (P2[2]*( -V3[0]+V3[3]))+(P2[3]*( 1j*V3[1]-V3[2]))))))+( (F1[2]*( (P2[0]*( -1j*V3[0]-1j*V3[3]))+( (P2[1]*( 1j*V3[1]+V3[2]))+( (P2[2]*( -V3[1]+1j*V3[2]))+(P2[3]*( 1j*V3[0]+1j*V3[3]))))))+(M2*( (F1[1]*( 1j*V3[1]-V3[2]))+(F1[0]*( -1j*V3[0]+1j*V3[3]))))))
421+ F2[3]= COUP*denom*( (F1[3]*( (P2[0]*( -1j*V3[0]+1j*V3[3]))+( (P2[1]*( 1j*V3[1]-V3[2]))+( (P2[2]*( V3[1]+1j*V3[2]))+(P2[3]*( -1j*V3[0]+1j*V3[3]))))))+( (F1[2]*( (P2[0]*( -1j*V3[1]-V3[2]))+( (P2[1]*( 1j*V3[0]+1j*V3[3]))+( (P2[2]*( V3[0]+V3[3]))+(P2[3]*( -1j*V3[1]-V3[2]))))))+(M2*( (F1[1]*( -1j*V3[0]-1j*V3[3]))+(F1[0]*( 1j*V3[1]+V3[2]))))))
422+ return F2
423+
424+
425+def FFV1C1_2_1(F1, V3, COUP1,COUP2, M2, W2):
426+
427+
428+ F2 = FFV1C1_1(F1, V3, COUP1, M2, W2)
429+ tmp = FFV2C1_1(F1, V3, COUP2, M2, W2)
430+ for i in range(4):
431+ F2[i] += tmp[i]
432+ return F2
433+
434+"""
435+
436+
437+
438+ FFV = UFOLorentz(name = 'FFV1',
439+ spins = [ 2, 2, 3 ],
440+ structure = 'Gamma(3,2,1)')
441+ builder = create_aloha.AbstractRoutineBuilder(FFV)
442+ builder.apply_conjugation()
443+ amp = builder.compute_routine(1)
444+ amp.add_combine(['FFV2'])
445+ routine = amp.write(output_dir=None, language='Python')
446+
447+
448+ split_solution = solution.split('\n')
449+ split_routine = routine.split('\n')
450+ self.assertEqual(split_solution, split_routine)
451+ self.assertEqual(len(split_routine), len(split_solution))
452+
453
454 def test_pythonwriter_4_fermion(self):
455 """ test that python writer works """
456@@ -3838,20 +3884,20 @@
457
458
459 solution ="""import wavefunctions
460-def FFFF1C1_1(F2, F3, F4, COUP, M1, W1):
461- F1 = wavefunctions.WaveFunction(size=6)
462- F1[4] = F2[4]-F3[4]+F4[4]
463- F1[5] = F2[5]-F3[5]+F4[5]
464- P1 = [complex(F1[4]).real, \\
465- complex(F1[5]).real, \\
466- complex(F1[5]).imag, \\
467- complex(F1[4]).imag]
468- denom =1.0/(( (M1*( -M1+1j*W1))+( (P1[0]**2)-(P1[1]**2)-(P1[2]**2)-(P1[3]**2))))
469- F1[0]= COUP*denom*( (F2[3]*( (P1[1]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P1[2]*( -(F4[0]*F3[0])-(F4[1]*F3[1])-(F4[2]*F3[2])-(F4[3]*F3[3])))))+( (F2[2]*( (P1[0]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P1[3]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))))+(M1*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3]))*F2[0])))
470- F1[1]= COUP*denom*( (F2[2]*( (P1[1]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P1[2]*( (F4[0]*F3[0])+(F4[1]*F3[1])+(F4[2]*F3[2])+(F4[3]*F3[3])))))+( (F2[3]*( (P1[0]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P1[3]*( -1j*(F4[0]*F3[0])-1j*(F4[1]*F3[1])-1j*(F4[2]*F3[2])-1j*(F4[3]*F3[3])))))+(M1*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3]))*F2[1])))
471- F1[2]= COUP*denom*( (F2[1]*( (P1[1]*( -1j*(F4[0]*F3[0])-1j*(F4[1]*F3[1])-1j*(F4[2]*F3[2])-1j*(F4[3]*F3[3])))+(P1[2]*( (F4[0]*F3[0])+(F4[1]*F3[1])+(F4[2]*F3[2])+(F4[3]*F3[3])))))+( (F2[0]*( (P1[0]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P1[3]*( -1j*(F4[0]*F3[0])-1j*(F4[1]*F3[1])-1j*(F4[2]*F3[2])-1j*(F4[3]*F3[3])))))+(M1*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3]))*F2[2])))
472- F1[3]= COUP*denom*( (F2[0]*( (P1[1]*( -1j*(F4[0]*F3[0])-1j*(F4[1]*F3[1])-1j*(F4[2]*F3[2])-1j*(F4[3]*F3[3])))+(P1[2]*( -(F4[0]*F3[0])-(F4[1]*F3[1])-(F4[2]*F3[2])-(F4[3]*F3[3])))))+( (F2[1]*( (P1[0]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P1[3]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))))+(M1*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3]))*F2[3])))
473- return F1
474+def FFFF1C1_1(F1, F3, F4, COUP, M2, W2):
475+ F2 = wavefunctions.WaveFunction(size=6)
476+ F2[4] = F1[4]-F3[4]+F4[4]
477+ F2[5] = F1[5]-F3[5]+F4[5]
478+ P2 = [complex(F2[4]).real, \\
479+ complex(F2[5]).real, \\
480+ complex(F2[5]).imag, \\
481+ complex(F2[4]).imag]
482+ denom =1.0/(( (M2*( -M2+1j*W2))+( (P2[0]**2)-(P2[1]**2)-(P2[2]**2)-(P2[3]**2))))
483+ F2[0]= COUP*denom*( (F1[3]*( (P2[1]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P2[2]*( -(F4[0]*F3[0])-(F4[1]*F3[1])-(F4[2]*F3[2])-(F4[3]*F3[3])))))+( (F1[2]*( (P2[0]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P2[3]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))))+(M2*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3]))*F1[0])))
484+ F2[1]= COUP*denom*( (F1[2]*( (P2[1]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P2[2]*( (F4[0]*F3[0])+(F4[1]*F3[1])+(F4[2]*F3[2])+(F4[3]*F3[3])))))+( (F1[3]*( (P2[0]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P2[3]*( -1j*(F4[0]*F3[0])-1j*(F4[1]*F3[1])-1j*(F4[2]*F3[2])-1j*(F4[3]*F3[3])))))+(M2*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3]))*F1[1])))
485+ F2[2]= COUP*denom*( (F1[1]*( (P2[1]*( -1j*(F4[0]*F3[0])-1j*(F4[1]*F3[1])-1j*(F4[2]*F3[2])-1j*(F4[3]*F3[3])))+(P2[2]*( (F4[0]*F3[0])+(F4[1]*F3[1])+(F4[2]*F3[2])+(F4[3]*F3[3])))))+( (F1[0]*( (P2[0]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P2[3]*( -1j*(F4[0]*F3[0])-1j*(F4[1]*F3[1])-1j*(F4[2]*F3[2])-1j*(F4[3]*F3[3])))))+(M2*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3]))*F1[2])))
486+ F2[3]= COUP*denom*( (F1[0]*( (P2[1]*( -1j*(F4[0]*F3[0])-1j*(F4[1]*F3[1])-1j*(F4[2]*F3[2])-1j*(F4[3]*F3[3])))+(P2[2]*( -(F4[0]*F3[0])-(F4[1]*F3[1])-(F4[2]*F3[2])-(F4[3]*F3[3])))))+( (F1[1]*( (P2[0]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))+(P2[3]*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3])))))+(M2*( 1j*(F4[0]*F3[0])+1j*(F4[1]*F3[1])+1j*(F4[2]*F3[2])+1j*(F4[3]*F3[3]))*F1[3])))
487+ return F2
488
489
490 """
491@@ -3941,6 +3987,181 @@
492
493
494
495+ def test_fortranwriter_C(self):
496+ """ test that python writer works """
497+
498+ solution = """ subroutine FFV1C1_1(F1, V3, COUP, M2, W2, F2)
499+implicit none
500+double complex F1(*)
501+double complex F2(*)
502+double complex V3(*)
503+double complex COUP
504+double complex denom
505+double precision M2, W2
506+double precision P2(0:3)
507+
508+F2(5)= F1(5)+V3(5)
509+F2(6)= F1(6)+V3(6)
510+P2(0) = dble(F2(5))
511+P2(1) = dble(F2(6))
512+P2(2) = dimag(F2(6))
513+P2(3) = dimag(F2(5))
514+
515+denom =1d0/(( (M2*( -M2+(0, 1)*W2))+( (P2(0)**2)-(P2(1)**2)-(P2(2)**2)-(P2(3)**2))))
516+F2(1)= COUP*denom*( (F1(2)*( (P2(0)*( (0, 1)*V3(2)-V3(3)))+( (P2(1)*( (0, -1)*V3(1)+(0, -1)*V3(4)))+( (P2(2)*( V3(1)+V3(4)))+(P2(3)*( (0, 1)*V3(2)-V3(3)))))))+( (F1(1)*( (P2(0)*( (0, -1)*V3(1)+(0, 1)*V3(4)))+( (P2(1)*( (0, 1)*V3(2)+V3(3)))+( (P2(2)*( -V3(2)+(0, 1)*V3(3)))+(P2(3)*( (0, -1)*V3(1)+(0, 1)*V3(4)))))))+(M2*( (F1(4)*( (0, -1)*V3(2)+V3(3)))+(F1(3)*( (0, -1)*V3(1)+(0, -1)*V3(4)))))))
517+F2(2)= COUP*denom*( (F1(2)*( (P2(0)*( (0, -1)*V3(1)+(0, -1)*V3(4)))+( (P2(1)*( (0, 1)*V3(2)-V3(3)))+( (P2(2)*( V3(2)+(0, 1)*V3(3)))+(P2(3)*( (0, 1)*V3(1)+(0, 1)*V3(4)))))))+( (F1(1)*( (P2(0)*( (0, 1)*V3(2)+V3(3)))+( (P2(1)*( (0, -1)*V3(1)+(0, 1)*V3(4)))+( (P2(2)*( -V3(1)+V3(4)))+(P2(3)*( (0, -1)*V3(2)-V3(3)))))))+(M2*( (F1(4)*( (0, -1)*V3(1)+(0, 1)*V3(4)))+(F1(3)*( (0, -1)*V3(2)-V3(3)))))))
518+F2(3)= COUP*denom*( (F1(4)*( (P2(0)*( (0, -1)*V3(2)+V3(3)))+( (P2(1)*( (0, 1)*V3(1)+(0, -1)*V3(4)))+( (P2(2)*( -V3(1)+V3(4)))+(P2(3)*( (0, 1)*V3(2)-V3(3)))))))+( (F1(3)*( (P2(0)*( (0, -1)*V3(1)+(0, -1)*V3(4)))+( (P2(1)*( (0, 1)*V3(2)+V3(3)))+( (P2(2)*( -V3(2)+(0, 1)*V3(3)))+(P2(3)*( (0, 1)*V3(1)+(0, 1)*V3(4)))))))+(M2*( (F1(2)*( (0, 1)*V3(2)-V3(3)))+(F1(1)*( (0, -1)*V3(1)+(0, 1)*V3(4)))))))
519+F2(4)= COUP*denom*( (F1(4)*( (P2(0)*( (0, -1)*V3(1)+(0, 1)*V3(4)))+( (P2(1)*( (0, 1)*V3(2)-V3(3)))+( (P2(2)*( V3(2)+(0, 1)*V3(3)))+(P2(3)*( (0, -1)*V3(1)+(0, 1)*V3(4)))))))+( (F1(3)*( (P2(0)*( (0, -1)*V3(2)-V3(3)))+( (P2(1)*( (0, 1)*V3(1)+(0, 1)*V3(4)))+( (P2(2)*( V3(1)+V3(4)))+(P2(3)*( (0, -1)*V3(2)-V3(3)))))))+(M2*( (F1(2)*( (0, -1)*V3(1)+(0, -1)*V3(4)))+(F1(1)*( (0, 1)*V3(2)+V3(3)))))))
520+end
521+
522+
523+"""
524+ FFV = UFOLorentz(name = 'FFV1',
525+ spins = [ 2, 2, 3 ],
526+ structure = 'Gamma(3,2,1)')
527+ builder = create_aloha.AbstractRoutineBuilder(FFV)
528+ builder.apply_conjugation()
529+ amp = builder.compute_routine(1)
530+ routine = amp.write(output_dir=None, language='Fortran')
531+
532+ split_solution = solution.split('\n')
533+ split_routine = routine.split('\n')
534+ self.assertEqual(split_solution, split_routine)
535+ self.assertEqual(len(split_routine), len(split_solution))
536+
537+ solution=""" subroutine FFV1C1_2(F2, V3, COUP, M1, W1, F1)
538+implicit none
539+double complex F1(*)
540+double complex F2(*)
541+double complex V3(*)
542+double complex COUP
543+double complex denom
544+double precision M1, W1
545+double precision P1(0:3)
546+
547+F1(5)= F2(5)-V3(5)
548+F1(6)= F2(6)-V3(6)
549+P1(0) = dble(F1(5))
550+P1(1) = dble(F1(6))
551+P1(2) = dimag(F1(6))
552+P1(3) = dimag(F1(5))
553+
554+denom =1d0/(( (M1*( -M1+(0, 1)*W1))+( (P1(0)**2)-(P1(1)**2)-(P1(2)**2)-(P1(3)**2))))
555+F1(1)= COUP*denom*( (F2(1)*( (V3(2)*( (0, 1)*P1(1)+P1(2)))+( (V3(3)*( -P1(1)+(0, 1)*P1(2)))+( (V3(1)*( (0, -1)*P1(0)+(0, 1)*P1(3)))+(V3(4)*( (0, -1)*P1(0)+(0, 1)*P1(3)))))))+( (F2(2)*( (V3(1)*( (0, 1)*P1(1)+P1(2)))+( (V3(4)*( (0, -1)*P1(1)-P1(2)))+( (V3(2)*( (0, -1)*P1(0)+(0, 1)*P1(3)))+(V3(3)*( -P1(0)+P1(3)))))))+(M1*( (F2(3)*( (0, -1)*V3(1)+(0, 1)*V3(4)))+(F2(4)*( (0, 1)*V3(2)+V3(3)))))))
556+F1(2)= COUP*denom*( (F2(1)*( (V3(2)*( (0, -1)*P1(0)+(0, -1)*P1(3)))+( (V3(3)*( P1(0)+P1(3)))+( (V3(1)*( (0, 1)*P1(1)-P1(2)))+(V3(4)*( (0, 1)*P1(1)-P1(2)))))))+( (F2(2)*( (V3(1)*( (0, -1)*P1(0)+(0, -1)*P1(3)))+( (V3(4)*( (0, 1)*P1(0)+(0, 1)*P1(3)))+( (V3(2)*( (0, 1)*P1(1)-P1(2)))+(V3(3)*( P1(1)+(0, 1)*P1(2)))))))+(M1*( (F2(3)*( (0, 1)*V3(2)-V3(3)))+(F2(4)*( (0, -1)*V3(1)+(0, -1)*V3(4)))))))
557+F1(3)= COUP*denom*( (F2(3)*( (V3(2)*( (0, 1)*P1(1)+P1(2)))+( (V3(3)*( -P1(1)+(0, 1)*P1(2)))+( (V3(1)*( (0, -1)*P1(0)+(0, -1)*P1(3)))+(V3(4)*( (0, 1)*P1(0)+(0, 1)*P1(3)))))))+( (F2(4)*( (V3(1)*( (0, -1)*P1(1)-P1(2)))+( (V3(4)*( (0, -1)*P1(1)-P1(2)))+( (V3(2)*( (0, 1)*P1(0)+(0, 1)*P1(3)))+(V3(3)*( P1(0)+P1(3)))))))+(M1*( (F2(1)*( (0, -1)*V3(1)+(0, -1)*V3(4)))+(F2(2)*( (0, -1)*V3(2)-V3(3)))))))
558+F1(4)= COUP*denom*( (F2(3)*( (V3(2)*( (0, 1)*P1(0)+(0, -1)*P1(3)))+( (V3(3)*( -P1(0)+P1(3)))+( (V3(1)*( (0, -1)*P1(1)+P1(2)))+(V3(4)*( (0, 1)*P1(1)-P1(2)))))))+( (F2(4)*( (V3(1)*( (0, -1)*P1(0)+(0, 1)*P1(3)))+( (V3(4)*( (0, -1)*P1(0)+(0, 1)*P1(3)))+( (V3(2)*( (0, 1)*P1(1)-P1(2)))+(V3(3)*( P1(1)+(0, 1)*P1(2)))))))+(M1*( (F2(1)*( (0, -1)*V3(2)+V3(3)))+(F2(2)*( (0, -1)*V3(1)+(0, 1)*V3(4)))))))
559+end
560+
561+
562+"""
563+ amp = builder.compute_routine(2)
564+
565+ routine = amp.write(output_dir=None, language='Fortran')
566+
567+ split_solution = solution.split('\n')
568+ split_routine = routine.split('\n')
569+ self.assertEqual(split_solution, split_routine)
570+ self.assertEqual(len(split_routine), len(split_solution))
571+
572+ def test_Cppwriter_C(self):
573+ """ test that python writer works """
574+
575+
576+ solution_h = """#ifndef FFV1C1_1_guard
577+#define FFV1C1_1_guard
578+#include <complex>
579+using namespace std;
580+
581+void FFV1C1_1(complex<double> F1[],complex<double> V3[],complex<double> COUP, double M2, double W2, complex<double>F2[]);
582+
583+#endif
584+
585+"""
586+ solution_c = """#include "FFV1C1_1.h"
587+
588+void FFV1C1_1(complex<double> F1[],complex<double> V3[],complex<double> COUP, double M2, double W2, complex<double>F2[]){
589+complex<double> denom;
590+double P2[4];
591+F2[4]= F1[4]+V3[4];
592+F2[5]= F1[5]+V3[5];
593+P2[0] = F2[4].real();
594+P2[1] = F2[5].real();
595+P2[2] = F2[5].imag();
596+P2[3] = F2[4].imag();
597+denom =1./(( (M2*( -M2+complex<double>(0., 1.)*W2))+( (pow(P2[0],2))-(pow(P2[1],2))-(pow(P2[2],2))-(pow(P2[3],2)))));
598+F2[0]= COUP*denom*( (F1[1]*( (P2[0]*( complex<double>(0., 1.)*V3[1]-V3[2]))+( (P2[1]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., -1.)*V3[3]))+( (P2[2]*( V3[0]+V3[3]))+(P2[3]*( complex<double>(0., 1.)*V3[1]-V3[2]))))))+( (F1[0]*( (P2[0]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., 1.)*V3[3]))+( (P2[1]*( complex<double>(0., 1.)*V3[1]+V3[2]))+( (P2[2]*( -V3[1]+complex<double>(0., 1.)*V3[2]))+(P2[3]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., 1.)*V3[3]))))))+(M2*( (F1[3]*( complex<double>(0., -1.)*V3[1]+V3[2]))+(F1[2]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., -1.)*V3[3]))))));
599+F2[1]= COUP*denom*( (F1[1]*( (P2[0]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., -1.)*V3[3]))+( (P2[1]*( complex<double>(0., 1.)*V3[1]-V3[2]))+( (P2[2]*( V3[1]+complex<double>(0., 1.)*V3[2]))+(P2[3]*( complex<double>(0., 1.)*V3[0]+complex<double>(0., 1.)*V3[3]))))))+( (F1[0]*( (P2[0]*( complex<double>(0., 1.)*V3[1]+V3[2]))+( (P2[1]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., 1.)*V3[3]))+( (P2[2]*( -V3[0]+V3[3]))+(P2[3]*( complex<double>(0., -1.)*V3[1]-V3[2]))))))+(M2*( (F1[3]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., 1.)*V3[3]))+(F1[2]*( complex<double>(0., -1.)*V3[1]-V3[2]))))));
600+F2[2]= COUP*denom*( (F1[3]*( (P2[0]*( complex<double>(0., -1.)*V3[1]+V3[2]))+( (P2[1]*( complex<double>(0., 1.)*V3[0]+complex<double>(0., -1.)*V3[3]))+( (P2[2]*( -V3[0]+V3[3]))+(P2[3]*( complex<double>(0., 1.)*V3[1]-V3[2]))))))+( (F1[2]*( (P2[0]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., -1.)*V3[3]))+( (P2[1]*( complex<double>(0., 1.)*V3[1]+V3[2]))+( (P2[2]*( -V3[1]+complex<double>(0., 1.)*V3[2]))+(P2[3]*( complex<double>(0., 1.)*V3[0]+complex<double>(0., 1.)*V3[3]))))))+(M2*( (F1[1]*( complex<double>(0., 1.)*V3[1]-V3[2]))+(F1[0]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., 1.)*V3[3]))))));
601+F2[3]= COUP*denom*( (F1[3]*( (P2[0]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., 1.)*V3[3]))+( (P2[1]*( complex<double>(0., 1.)*V3[1]-V3[2]))+( (P2[2]*( V3[1]+complex<double>(0., 1.)*V3[2]))+(P2[3]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., 1.)*V3[3]))))))+( (F1[2]*( (P2[0]*( complex<double>(0., -1.)*V3[1]-V3[2]))+( (P2[1]*( complex<double>(0., 1.)*V3[0]+complex<double>(0., 1.)*V3[3]))+( (P2[2]*( V3[0]+V3[3]))+(P2[3]*( complex<double>(0., -1.)*V3[1]-V3[2]))))))+(M2*( (F1[1]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., -1.)*V3[3]))+(F1[0]*( complex<double>(0., 1.)*V3[1]+V3[2]))))));
602+}
603+
604+"""
605+
606+ FFV = UFOLorentz(name = 'FFV1',
607+ spins = [ 2, 2, 3 ],
608+ structure = 'Gamma(3,2,1)')
609+ builder = create_aloha.AbstractRoutineBuilder(FFV)
610+ builder.apply_conjugation()
611+ amp = builder.compute_routine(1)
612+ routine = amp.write(output_dir=None, language='CPP')
613+
614+ split_solution = solution_h.split('\n')
615+ split_routine = routine[0].split('\n')
616+ self.assertEqual(split_solution, split_routine)
617+ self.assertEqual(len(split_routine), len(split_solution))
618+
619+ split_solution = solution_c.split('\n')
620+ split_routine = routine[1].split('\n')
621+ self.assertEqual(split_solution, split_routine)
622+ self.assertEqual(len(split_routine), len(split_solution))
623+
624+ solution_h = """#ifndef FFV1C1_2_guard
625+#define FFV1C1_2_guard
626+#include <complex>
627+using namespace std;
628+
629+void FFV1C1_2(complex<double> F2[],complex<double> V3[],complex<double> COUP, double M1, double W1, complex<double>F1[]);
630+
631+#endif
632+
633+"""
634+
635+ solution_c = """#include "FFV1C1_2.h"
636+
637+void FFV1C1_2(complex<double> F2[],complex<double> V3[],complex<double> COUP, double M1, double W1, complex<double>F1[]){
638+complex<double> denom;
639+double P1[4];
640+F1[4]= F2[4]-V3[4];
641+F1[5]= F2[5]-V3[5];
642+P1[0] = F1[4].real();
643+P1[1] = F1[5].real();
644+P1[2] = F1[5].imag();
645+P1[3] = F1[4].imag();
646+denom =1./(( (M1*( -M1+complex<double>(0., 1.)*W1))+( (pow(P1[0],2))-(pow(P1[1],2))-(pow(P1[2],2))-(pow(P1[3],2)))));
647+F1[0]= COUP*denom*( (F2[0]*( (V3[1]*( complex<double>(0., 1.)*P1[1]+P1[2]))+( (V3[2]*( -P1[1]+complex<double>(0., 1.)*P1[2]))+( (V3[0]*( complex<double>(0., -1.)*P1[0]+complex<double>(0., 1.)*P1[3]))+(V3[3]*( complex<double>(0., -1.)*P1[0]+complex<double>(0., 1.)*P1[3]))))))+( (F2[1]*( (V3[0]*( complex<double>(0., 1.)*P1[1]+P1[2]))+( (V3[3]*( complex<double>(0., -1.)*P1[1]-P1[2]))+( (V3[1]*( complex<double>(0., -1.)*P1[0]+complex<double>(0., 1.)*P1[3]))+(V3[2]*( -P1[0]+P1[3]))))))+(M1*( (F2[2]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., 1.)*V3[3]))+(F2[3]*( complex<double>(0., 1.)*V3[1]+V3[2]))))));
648+F1[1]= COUP*denom*( (F2[0]*( (V3[1]*( complex<double>(0., -1.)*P1[0]+complex<double>(0., -1.)*P1[3]))+( (V3[2]*( P1[0]+P1[3]))+( (V3[0]*( complex<double>(0., 1.)*P1[1]-P1[2]))+(V3[3]*( complex<double>(0., 1.)*P1[1]-P1[2]))))))+( (F2[1]*( (V3[0]*( complex<double>(0., -1.)*P1[0]+complex<double>(0., -1.)*P1[3]))+( (V3[3]*( complex<double>(0., 1.)*P1[0]+complex<double>(0., 1.)*P1[3]))+( (V3[1]*( complex<double>(0., 1.)*P1[1]-P1[2]))+(V3[2]*( P1[1]+complex<double>(0., 1.)*P1[2]))))))+(M1*( (F2[2]*( complex<double>(0., 1.)*V3[1]-V3[2]))+(F2[3]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., -1.)*V3[3]))))));
649+F1[2]= COUP*denom*( (F2[2]*( (V3[1]*( complex<double>(0., 1.)*P1[1]+P1[2]))+( (V3[2]*( -P1[1]+complex<double>(0., 1.)*P1[2]))+( (V3[0]*( complex<double>(0., -1.)*P1[0]+complex<double>(0., -1.)*P1[3]))+(V3[3]*( complex<double>(0., 1.)*P1[0]+complex<double>(0., 1.)*P1[3]))))))+( (F2[3]*( (V3[0]*( complex<double>(0., -1.)*P1[1]-P1[2]))+( (V3[3]*( complex<double>(0., -1.)*P1[1]-P1[2]))+( (V3[1]*( complex<double>(0., 1.)*P1[0]+complex<double>(0., 1.)*P1[3]))+(V3[2]*( P1[0]+P1[3]))))))+(M1*( (F2[0]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., -1.)*V3[3]))+(F2[1]*( complex<double>(0., -1.)*V3[1]-V3[2]))))));
650+F1[3]= COUP*denom*( (F2[2]*( (V3[1]*( complex<double>(0., 1.)*P1[0]+complex<double>(0., -1.)*P1[3]))+( (V3[2]*( -P1[0]+P1[3]))+( (V3[0]*( complex<double>(0., -1.)*P1[1]+P1[2]))+(V3[3]*( complex<double>(0., 1.)*P1[1]-P1[2]))))))+( (F2[3]*( (V3[0]*( complex<double>(0., -1.)*P1[0]+complex<double>(0., 1.)*P1[3]))+( (V3[3]*( complex<double>(0., -1.)*P1[0]+complex<double>(0., 1.)*P1[3]))+( (V3[1]*( complex<double>(0., 1.)*P1[1]-P1[2]))+(V3[2]*( P1[1]+complex<double>(0., 1.)*P1[2]))))))+(M1*( (F2[0]*( complex<double>(0., -1.)*V3[1]+V3[2]))+(F2[1]*( complex<double>(0., -1.)*V3[0]+complex<double>(0., 1.)*V3[3]))))));
651+}
652+
653+"""
654+
655+ amp = builder.compute_routine(2)
656+
657+ routine = amp.write(output_dir=None, language='CPP')
658+
659+ split_solution = solution_h.split('\n')
660+ split_routine = routine[0].split('\n')
661+ self.assertEqual(split_solution, split_routine)
662+ self.assertEqual(len(split_routine), len(split_solution))
663+
664+ split_solution = solution_c.split('\n')
665+ split_routine = routine[1].split('\n')
666+ self.assertEqual(split_solution, split_routine)
667+ self.assertEqual(len(split_routine), len(split_solution))
668+
669+
670
671
672

Subscribers

People subscribed via source and target branches

to all changes: