1 //==============================================================================================
2 //
3 //	This file is part of LiDIA --- a library for computational number theory
4 //
5 //	Copyright (c) 1994--2001 the LiDIA Group.  All rights reserved.
6 //
7 //	See http://www.informatik.tu-darmstadt.de/TI/LiDIA/
8 //
9 //----------------------------------------------------------------------------------------------
10 //
11 //	$Id$
12 //
13 //	Author	:Frank Lehmann(FL), Volker Mueller (VM), Markus Maurer (MM)
14 //	Changes	: See CVS log
15 //
16 //==============================================================================================
17 
18 
19 
20 #ifdef HAVE_CONFIG_H
21 # include	"config.h"
22 #endif
23 #include	"LiDIA/eco_prime.h"
24 
25 
26 
27 #ifdef LIDIA_NAMESPACE
28 namespace LiDIA {
29 #endif
30 
31 
32 
tildeEA(ff_element & tildeEa,ff_element & tildeEb,ff_element & P1,const ff_element & A_tau,const ff_element & j_ltau,const ff_element & Ea,const ff_element & Eb)33 int eco_prime::tildeEA (ff_element & tildeEa, ff_element & tildeEb,
34                         ff_element & P1, const ff_element & A_tau,
35                         const ff_element & j_ltau, const ff_element & Ea,
36                         const ff_element & Eb)
37 {
38 	// powers of A(tau), j(tau), j(ltau)
39 
40 	// base_vector< ff_element > Avec(l+2, 0), jvec(v+1, 0), jlvec(v+1, 0);
41 	// base_vector< ff_element > &A  = Avec;
42 	// base_vector< ff_element > &j  = jvec;
43 	// base_vector< ff_element > &jl = jlvec;
44 
45 	ff_element * j, *jl, *A;
46 
47 	j = new ff_element[v+1];
48 	jl = new ff_element[v+1];
49 	A = new ff_element[l+2];
50 
51 	ff_element DF1, DF2;
52 	ff_element DJ1, DJ2;
53 	ff_element DFF1, DFF2;
54 	ff_element DJJ1, DJJ2;
55 	ff_element DFJ1, DFJ2;
56 
57 	ff_element E4_tau, E6_tau;
58 	ff_element E4_ltau, E6_ltau;
59 	ff_element A_tau_1;
60 	ff_element j_tau, j_tau_1;
61 	ff_element j_ltau_1;
62 	ff_element E2_star;
63 	ff_element delta_tau, delta_ltau;
64 	ff_element W1, W2;
65 
66 	ff_element tmp1, tmp2, tmp3;
67 	ff_element l_r, tmp;
68 
69 	udigit r, k;
70 	int  rc;
71 
72 	// determine E4(tau) und E6(tau)
73 
74 	divide (E4_tau, Ea, ff_element(-3));
75 	divide (E6_tau, Eb, ff_element(-2));
76 
77 
78 	// determine j-invariant
79 
80 	compute_jinv (j_tau, Ea, Eb);
81 
82 
83 	// j'(tau) = - j * E6 / E4
84 
85 	divide   (j_tau_1, E6_tau, E4_tau);
86 	multiply (j_tau_1, j_tau_1, j_tau);
87 	negate   (j_tau_1, j_tau_1);
88 
89 
90 	// computation of DF1, DJ1, DFFi, DJJi, DFJi (i=1, 2)
91 
92 	// compute powers of A(tau), j(tau), j(ltau)
93 
94 	A[0]  = 1; A[1]  = A_tau;
95 	j[0]  = 1; j[1]  = j_tau;
96 	jl[0] = 1; jl[1] = j_ltau;
97 
98 	for (r = 2; r <= l+1; r++) {
99 		multiply (A[r], A[r-1], A[1]);
100 	}
101 	for (k = 2; k <= v; k++) {
102 		multiply (j[k], j[k-1], j[1]);
103 	}
104 	for (k = 2; k <= v; k++) {
105 		multiply (jl[k], jl[k-1], jl[1]);
106 	}
107 
108 
109 	// initialize file for reading the cofficients
110 
111 	rc = meq_prime::reset ();
112 	if (rc) {
113 		lidia_error_handler("eco_prime", "tildeEA()::Unable to reset file");
114 		delete [] j; delete[] jl; delete[] A;
115 		return 0;
116 	}
117 
118 	DF1  = DJ1  =        0;
119 	DFF1 = DJJ1 = DFJ1 = 0;
120 	DFF2 = DJJ2 = DFJ2 = 0;
121 
122 
123 	for (r = 0; r <= l+1; r++) {
124 		rc = read_row (p);
125 
126 		if (rc) {
127 			lidia_error_handler("eco_prime", "tildeEA()::Unable to reset file");
128 			delete [] j; delete[] jl; delete[] A;
129 			return 0;
130 		}
131 
132 		if (r > 0) {
133 			tmp1 = 0;
134 
135 			for (k = 0; k <= v; k++) {
136 				multiply (tmp2, row[k], j[k]);
137 				add      (tmp1, tmp1, tmp2);
138 			}
139 			multiply (tmp2, A[r-1], r);
140 			multiply (tmp1, tmp1, tmp2);
141 			add      (DF1, DF1, tmp1);
142 		}
143 
144 		if (r > 0) {
145 			tmp1 = 0;
146 
147 			for (k = 0; k <= v; k++) {
148 				multiply (tmp2, row[k], jl[k]);
149 				add      (tmp1, tmp1, tmp2);
150 			}
151 			multiply (tmp2, A[r-1], r);
152 			multiply (tmp1, tmp1, tmp2);
153 			add      (DF2, DF2, tmp1);
154 		}
155 
156 		tmp1 = 0;
157 
158 		for (k = 1; k <= v; k++) {
159 			multiply (tmp2, row[k], ff_element(k));
160 			multiply (tmp2, tmp2, j[k-1]);
161 			add      (tmp1, tmp1, tmp2);
162 		}
163 		multiply (tmp1, tmp1, A[r]);
164 		add      (DJ1, DJ1, tmp1);
165 
166 
167 		tmp1 = 0;
168 
169 		for (k = 1; k <= v; k++) {
170 			multiply (tmp2, row[k], ff_element(k));
171 			multiply (tmp2, tmp2, jl[k-1]);
172 			add      (tmp1, tmp1, tmp2);
173 		}
174 		multiply (tmp1, tmp1, A[r]);
175 		add      (DJ2, DJ2, tmp1);
176 
177 
178 		if (r > 1) {
179 			tmp1 = 0;
180 
181 			for (k = 0; k <= v; k++) {
182 				multiply (tmp2, row[k], j[k]);
183 				add      (tmp1, tmp1, tmp2);
184 			}
185 			multiply (tmp2, A[r-2], r*(r-1));
186 			multiply (tmp1, tmp1, tmp2);
187 			add      (DFF1, DFF1, tmp1);
188 		}
189 
190 		if (r > 1) {
191 			tmp1 = 0;
192 
193 			for (k = 0; k <= v; k++) {
194 				multiply (tmp2, row[k], jl[k]);
195 				add      (tmp1, tmp1, tmp2);
196 			}
197 			multiply (tmp2, A[r-2], r*(r-1));
198 			multiply (tmp1, tmp1, tmp2);
199 			add      (DFF2, DFF2, tmp1);
200 		}
201 
202 		tmp1 = 0;
203 
204 		for (k = 2; k <= v; k++) {
205 			multiply (tmp2, row[k], ff_element(k * (k-1)));
206 			multiply (tmp2, tmp2, j[k-2]);
207 			add      (tmp1, tmp1, tmp2);
208 		}
209 		multiply (tmp1, tmp1, A[r]);
210 		add      (DJJ1, DJJ1, tmp1);
211 
212 
213 		tmp1 = 0;
214 
215 		for (k = 2; k <= v; k++) {
216 			multiply (tmp2, row[k], ff_element(k * (k-1)));
217 			multiply (tmp2, tmp2, jl[k-2]);
218 			add      (tmp1, tmp1, tmp2);
219 		}
220 		multiply (tmp1, tmp1, A[r]);
221 		add      (DJJ2, DJJ2, tmp1);
222 
223 
224 		if (r > 0) {
225 			tmp1 = 0;
226 
227 			for (k = 1; k <= v; k++) {
228 				multiply (tmp2, row[k], ff_element(k));
229 				multiply (tmp2, tmp2, j[k-1]);
230 				add      (tmp1, tmp1, tmp2);
231 			}
232 			multiply (tmp2, A[r-1], r);
233 			multiply (tmp1, tmp1, tmp2);
234 			add      (DFJ1, DFJ1, tmp1);
235 		}
236 
237 		if (r > 0) {
238 			tmp1 = 0;
239 
240 			for (k = 1; k <= v; k++) {
241 				multiply (tmp2, row[k], ff_element(k));
242 				multiply (tmp2, tmp2, jl[k-1]);
243 				add      (tmp1, tmp1, tmp2);
244 			}
245 			multiply (tmp2, A[r-1], r);
246 			multiply (tmp1, tmp1, tmp2);
247 			add      (DFJ2, DFJ2, tmp1);
248 		}
249 
250 	} // end for r
251 
252 	// test whether a denominator is zero
253 
254 	if (DF1.is_zero() || DF2.is_zero() || DJ1.is_zero() || DJ2.is_zero()) {
255 		lidia_error_handler("eco_prime", "tildeEA::division by zero");
256 		delete[] j; delete[] jl; delete[] A;
257 		return 1;
258 	}
259 
260 
261 	// A'(tau) = - j'(tau) * DJ1 / DF1
262 
263 	multiply (A_tau_1, j_tau_1, DJ1);
264 	divide   (A_tau_1, A_tau_1, DF1);
265 	negate   (A_tau_1, A_tau_1);
266 
267 
268 	// j'(ltau) = - A'(tau) * DF2 / (l * DJ2)
269 
270 	multiply (j_ltau_1, A_tau_1, DF2);
271 	multiply (tmp1, DJ2, l);
272 	divide   (j_ltau_1, j_ltau_1, tmp1);
273 	negate   (j_ltau_1, j_ltau_1);
274 
275 
276 	// W1 = -1/DF1 * [ A' DFF1 + 2 j' DFJ1 - j' DJJ1 DF1 / DJ1 ]
277 
278 	divide   (tmp1, DF1, DJ1);
279 	multiply (tmp2, j_tau_1, DJJ1);
280 	multiply (W1, tmp1, tmp2);
281 
282 	multiply (tmp1, j_tau_1, DFJ1);
283 	add      (tmp1, tmp1, tmp1);
284 	subtract (W1, tmp1, W1);
285 
286 	multiply (tmp1, A_tau_1, DFF1);
287 	add      (W1, W1, tmp1);
288 
289 	divide (W1, W1, DF1);
290 	negate (W1, W1);
291 
292 
293 	// W2 = -1/DF2 * [ A' DFF2 + 2 l j'(l) DFJ2 - l j'(l) DJJ2 DF2 / DJ2 ]
294 
295 	divide   (tmp1, DF2, DJ2);
296 	multiply (tmp2, j_ltau_1, l);
297 	multiply (tmp2, tmp2, DJJ2);
298 	multiply (W2, tmp1, tmp2);
299 
300 	multiply (tmp1, j_ltau_1, 2*l);
301 	multiply (tmp2, tmp1, DFJ2);
302 	subtract (W2, tmp2, W2);
303 
304 	multiply (tmp1, A_tau_1, DFF2);
305 	add      (W2, W2, tmp1);
306 
307 	divide  (W2, W2, DF2);
308 	negate  (W2, W2);
309 
310 
311 	// E4(ltau) = j_ltau_1 ^2 / (j_ltau * (j_ltau - 1728))
312 
313 	if (j_ltau.is_zero()) {
314 		lidia_error_handler("eco_prime", "tildeEA::division by zero");
315 		delete[] j; delete[]jl; delete[] A;
316 		return 1;
317 	}
318 
319 	multiply   (tmp, j_ltau_1, j_ltau_1);
320 
321 	tmp2 = ff_element(1728);
322 	subtract (tmp3, j_ltau, tmp2);
323 	multiply (tmp3, tmp3, j_ltau);
324 
325 	divide   (E4_ltau, tmp, tmp3);
326 
327 
328 	// E6(ltau) = - E4(ltau) * j_ltau_1 / j_ltau
329 
330 	multiply (tmp, E4_ltau, j_ltau_1);
331 	divide   (tmp2, tmp, j_ltau);
332 	negate   (E6_ltau, tmp2);
333 
334 
335 	// delta(tau) = E4^3/j_tau
336 
337 	multiply (tmp, E4_tau, E4_tau);
338 	multiply (tmp, tmp, E4_tau);
339 	divide   (delta_tau, tmp, j_tau);
340 
341 
342 	// delta(l*tau) = E4(l*tau)^3/j(l*tau)
343 
344 	multiply (tmp, E4_ltau, E4_ltau);
345 	multiply (tmp, tmp, E4_ltau);
346 	divide   (delta_ltau, tmp, j_ltau);
347 
348 
349 	// test whether a denominator is equal to zero
350 
351 	if (j_ltau_1.is_zero() || j_tau_1.is_zero() || delta_tau.is_zero() || delta_ltau.is_zero()) {
352 		lidia_error_handler("eco_prime", "tildeEA::division by zero");
353 		delete[] j; delete [] jl; delete[] A;
354 		return 1;
355 	}
356 
357 	// E2_star = 6*(W2-W1)
358         //         + 3*(l*j(lt)*E4(lt) / j'(lt) - j(t)*E4(t) / j'(t))
359         //         + 4*(l*E4(lt)*E6(lt)^2 / (delta(lt) * j'(lt)) - E4(t)*E6(t)^2 / (delta(t) * j'(t)))
360 
361 	multiply (tmp, j_ltau, l);
362 	divide   (tmp2, E4_ltau, j_ltau_1);
363 	multiply (tmp, tmp, tmp2);
364 
365 	multiply (tmp2, j_tau, E4_tau);
366 	divide   (tmp3, tmp2, j_tau_1);
367 
368 	subtract (tmp2, tmp, tmp3);
369 	multiply (tmp2, tmp2, 3);
370 
371 	subtract (tmp, W2, W1);
372 	multiply (tmp, tmp, 6);
373 
374 	add       (tmp, tmp, tmp2);
375 
376 	multiply (tmp2, E4_ltau, 4 * l);
377 	multiply (tmp2, tmp2, E6_ltau);
378 	multiply (tmp2, tmp2, E6_ltau);
379 
380 	multiply (tmp3, delta_ltau, j_ltau_1);
381 
382 	divide   (tmp2, tmp2, tmp3);
383 
384 	add      (tmp, tmp, tmp2);
385 
386 	multiply (tmp2, E4_tau, 4);
387 	multiply (tmp2, tmp2, E6_tau);
388 	multiply (tmp2, tmp2, E6_tau);
389 
390 	multiply (tmp3, delta_tau, j_tau_1);
391 
392 	divide   (tmp2, tmp2, tmp3);
393 
394 	subtract (E2_star, tmp, tmp2);
395 
396 
397 	// P1 = - l/2 * E2_star
398 
399 	tmp  =  l;
400 	tmp2 =  2;
401 
402 	divide   (tmp3, tmp, tmp2);
403 	multiply (tmp2, tmp3, E2_star);
404 	negate   (P1, tmp2);
405 
406 
407 	// E~ = (A~, B~),
408 	// A~ == -3 * l^4 * E4(l*tau),
409 	// B~ == -2 * l^6 * E6(l*tau)
410 
411 	tmp = l;
412 
413 	power  (l_r, tmp, 4);
414 	multiply (tildeEa, ff_element(-3), E4_ltau);
415 	multiply (tildeEa, tildeEa, l_r);
416 
417 	power    (l_r, tmp, 6);
418 	multiply (tildeEb, ff_element(-2), E6_ltau);
419 	multiply (tildeEb, tildeEb, l_r);
420 
421 	delete[] j; delete[] jl; delete[] A;
422 
423 	return rc;
424 }
425 
426 
427 
tildeEf(ff_element & tildeEa,ff_element & tildeEb,ff_element & P1,const ff_element & g_tau,const ff_element & Ea,const ff_element & Eb)428 int eco_prime::tildeEf (ff_element & tildeEa, ff_element & tildeEb,
429                         ff_element & P1, const ff_element & g_tau,
430 	                const ff_element & Ea, const ff_element & Eb)
431 {
432   int rc;
433   udigit r, k;
434   ff_element * g, *j;
435 
436   g = new ff_element[l+2];
437   j = new ff_element[v+1];
438 
439   ff_element E4_tau, E6_tau;
440   ff_element E4_ltau, E6_ltau;
441   ff_element f_tau;
442   ff_element g_tau_1, f_tau_1;
443   ff_element g_tau_1num, g_tau_1den;
444   ff_element j_ltau_1num, j_ltau_1den;
445   ff_element j_tau, j_ltau;
446   ff_element j_tau_1, j_ltau_1;
447   ff_element E2_star;
448   ff_element E0_tau, E0_tau_1;
449   ff_element delta_tau, delta_ltau;
450 
451   ff_element DF, DJ, DFF, DJJ;
452   ff_element DFJ;
453   ff_element tmp, tmp2, tmp3;
454 
455   ff_element sum, sum_k, sum_k2;
456 
457   // compute values for  E4(tau) and E6(tau)
458 
459   divide(E4_tau, Ea, ff_element(-3));
460   divide(E6_tau, Eb, ff_element(-2));
461 
462   if (E4_tau.is_zero())
463     lidia_error_handler ("eco_prime", "tildeEf()::E4_tau == 0,"
464 			 " division by zero");
465 
466   // compute value for j-invariant
467 
468   compute_jinv (j_tau, Ea, Eb);
469 
470   // first derivation of j at tau
471   // j'(tau) = - j(tau) * E6(tau) / E4(tau)
472 
473   divide   (j_tau_1, E6_tau, E4_tau);
474   multiply (j_tau_1, j_tau_1, j_tau);
475   negate   (j_tau_1, j_tau_1);
476 
477 
478   // initialize vectors g and j
479   // g[r] = g(tau)^r  j[k] = j(tau)^k
480 
481   g[0] = ff_element(1); g[1] = g_tau;
482   j[0] = ff_element(1); j[1] = j_tau;
483 
484   for (r = 2; r <= l+1; r++)
485     multiply (g[r], g[r-1], g_tau);
486 
487   for (k = 2; k <= v; k++)
488     multiply (j[k], j[k-1], j_tau);
489 
490   // reset file to read coeff. of modular equation
491 
492   rc = meq_prime::reset ();
493 
494   if (rc)
495     lidia_error_handler ("eco_prime", "tildeEf()::Unable to reset file");
496 
497   // computation of several derivations
498   // for notation see [Ma94]
499 
500 
501   DFF = DJJ = DFJ = ff_element(0);
502   DF  = DJ  = ff_element(0);
503   g_tau_1num = g_tau_1den = ff_element(0);
504 
505   for (r = 0; r <= l+1; r++) {
506     rc = read_row (p);
507 
508     if (rc)
509       lidia_error_handler ("eco_prime", "tildeEA()::Unable to read row");
510 
511 	// compute value for g'(tau)
512 
513 	for (k = 1; k <= v; k++) {
514 	  multiply (tmp2, row[k], ff_element(k));
515 	  multiply (tmp2, tmp2, g[r]);
516 	  multiply (tmp2, tmp2, j[k-1]);
517 
518 	  add      (g_tau_1num, g_tau_1num, tmp2);
519 	}
520 
521     if (r > 0)
522       for (k = 0; k <= v; k++) {
523 	multiply (tmp2, row[k], ff_element(r));
524 	multiply (tmp2, tmp2, g[r-1]);
525 	multiply (tmp2, tmp2, j[k]);
526 
527 	add      (g_tau_1den, g_tau_1den, tmp2);
528       }
529 
530 
531     // sum      = \sum_{k=0}^{v}     a_{r, k} g(tau)^{r} j(tau)^{k}
532     // sum_k    = \sum_{k=1}^{v} k   a_{r, k} g(tau)^{r} j(tau)^{k}
533     // sum_k2   = \sum_{k=1}^{v} k^2 a_{r, k} g(tau)^{r} j(tau)^{k}
534 
535     sum    = ff_element(0);
536     sum_k  = ff_element(0);
537     sum_k2 = ff_element(0);
538 
539     for (k = 0; k <= v; k++) {
540       multiply (tmp, row[k], j[k]);
541 
542       add      (sum, sum, tmp);
543 
544       multiply (tmp2, k, tmp);
545       add      (sum_k, sum_k, tmp2);
546 
547       multiply (tmp2, k, tmp2);
548       add      (sum_k2, sum_k2, tmp2);
549     }
550 
551     multiply (sum, sum, g[r]);
552     multiply (sum_k, sum_k, g[r]);
553     multiply (sum_k2, sum_k2, g[r]);
554 
555 
556     // compute value for DFF
557 
558     if (r > 0) {
559       multiply (tmp, r*r, sum);
560       add      (DFF, DFF, tmp);
561     }
562 
563 
564     // compute value for DJJ
565 
566     add  (DJJ, DJJ, sum_k2);
567 
568 
569     // compute value for DF
570 
571     if (r > 0) {
572       multiply (tmp, r, sum);
573       add      (DF, DF, tmp);
574     }
575 
576     // compute value for DJ
577 
578     add  (DJ, DJ, sum_k);
579 
580     // compute value for DFJ
581 
582     multiply (tmp, r, sum_k);
583     add      (DFJ, DFJ, tmp);
584   }
585 
586 
587   // compute value for f'(tau)
588   // f'(tau) = - j'(tau) * \frac{g_tau_1num}{g_tau_1den}
589 
590   negate   (g_tau_1, j_tau_1);
591   multiply (g_tau_1, g_tau_1, g_tau_1num);
592   divide   (g_tau_1, g_tau_1, g_tau_1den);
593 
594 
595   // compute value for E2_star = (E6*DJ)/(E4*DF)
596   //                          = -(s/12) E2*(tau) in [Ma94]
597 
598   multiply (E2_star, E6_tau, DJ);
599   multiply (tmp, E4_tau, DF);
600 
601   if (tmp.is_zero())
602     lidia_error_handler ("eco_prime", "tildeEf()::DF or E4(tau) is zero");
603 
604   divide (E2_star, E2_star, tmp);
605 
606 
607   // compute value for E0_tau = DF/DJ
608   //                         = -(s/12) E0(tau) in [Ma94]
609 
610   if (DJ.is_zero())
611     lidia_error_handler ("eco_prime", "tildeEf()::DF is zero");
612 
613   divide (E0_tau, DF, DJ);
614 
615 
616   // compute value for E0_tau_1
617   //  = [ DFF*E2_star - 2*DFJ*E6/E4 + DJJ*E0*E6/E4 ] / DJ
618 
619   divide   (tmp, E6_tau, E4_tau);
620   multiply (tmp2, E0_tau, tmp);
621   multiply (E0_tau_1, DJJ, tmp2);
622 
623   multiply (tmp2, 2, DFJ);
624   multiply (tmp2, tmp2, tmp);
625   subtract (E0_tau_1, E0_tau_1, tmp2);
626 
627   multiply (tmp2, DFF, E2_star);
628   add      (E0_tau_1, E0_tau_1, tmp2);
629 
630   if (DJ.is_zero())
631     lidia_error_handler ("eco_prime", "tildeEf()::DJ is zero");
632 
633   divide (E0_tau_1, E0_tau_1, DJ);
634 
635 
636   // compute value of E4_ltau
637   // = [ E4 + 12/s*E2_star* {12*E0'/E0 + 6*E4^2/E6 - 4*E6/E4 + 12/s*E2_star} ] / l^2
638 
639   multiply (tmp2, ff_element(4), tmp); // tmp = E6/E4
640   negate   (E4_ltau, tmp2); // then: E4_ltau  =  -4*E6/E4
641 
642   if (tmp.is_zero())
643     lidia_error_handler ("eco_prime", "tildeEf()::E6 is zero");
644 
645   invert   (tmp2, tmp);
646   multiply (tmp2, tmp2, E4_tau);
647   multiply (tmp2, tmp2, ff_element(6));
648 
649   add      (E4_ltau, E4_ltau, tmp2); // E4_ltau +=  6*E4^2/E6
650 
651 
652   if (E0_tau.is_zero())
653     lidia_error_handler ("eco_prime", "tildeEf()::E0_tau is zero");
654 
655   divide   (tmp2, E0_tau_1, E0_tau);
656   multiply (tmp, ff_element(12), tmp2);
657 
658   add      (E4_ltau, E4_ltau, tmp); // E4_ltau +=  12*E0'/E0
659 
660   multiply (tmp, ff_element(12/s), E2_star);
661 
662   add      (E4_ltau, E4_ltau, tmp); // E4_ltau +=  12/s*E2_star
663   multiply (E4_ltau, E4_ltau, tmp); // E4_ltau *=  12/s*E2_star
664   add      (E4_ltau, E4_ltau, E4_tau); // E4_ltau +=  E4_tau
665 
666   tmp = ff_element(l*l);
667 
668   if (tmp.is_zero())
669     lidia_error_handler ("eco_prime", "tildeEf()::l^2 is zero");
670 
671   divide (E4_ltau, E4_ltau, tmp); // E4_ltau /= l^2
672 
673 
674   // compute value for delta_tau = E4^3/j_tau
675 
676   multiply (tmp, E4_tau, E4_tau);
677   multiply (tmp, tmp, E4_tau);
678 
679   if (j_tau.is_zero())
680     lidia_error_handler ("eco_prime", "tildeEf()::j_tau is zero");
681 
682   divide (delta_tau, tmp, j_tau);
683 
684 
685   // compute value for delta_ltau = delta_tau/ f_tau^{12/s}
686   // with f_tau = l^s / g_tau
687   //            => delta_ltau = delta_tau * g_tau^{12/s} / l^12
688 
689   power     (tmp, g_tau, static_cast<long>(12/s));
690   power     (tmp2, ff_element(l), static_cast<long>(12));
691 
692   multiply   (delta_ltau, delta_tau, tmp);
693 
694   if (tmp2.is_zero())
695     lidia_error_handler ("eco_prime", "tildeEf()::l^12 is zero");
696 
697   divide   (delta_ltau, delta_ltau, tmp2);
698 
699 
700   // compute value for j_ltau = E4_ltau^3 / delta_ltau
701 
702   multiply (tmp, E4_ltau, E4_ltau);
703   multiply (tmp, tmp, E4_ltau);
704 
705   if (delta_ltau.is_zero())
706     lidia_error_handler ("eco_prime", "tildeEf()::delta_ltau is zero");
707 
708   divide (j_ltau, tmp, delta_ltau);
709 
710 
711   // perform the transformation tau -> -1/ltau
712   // thus, we see: g(tau) -> l^s/g(tau) = f(tau)
713   //              j(tau) -> j(l tau)
714   // then, f'(tau) = - f(tau) g'(tau) / g(tau)
715 
716   power  (tmp, ff_element(l), static_cast<long>(s));
717   divide (f_tau, tmp, g_tau);
718 
719   multiply (tmp, f_tau, g_tau_1);
720   divide   (tmp, tmp, g_tau);
721   negate   (f_tau_1, tmp);
722 
723 
724   // initialize vectors g and j
725   // g[r] = f(tau)^r  j[k] = j(l tau)^k
726 
727 
728   g[0] = ff_element(1); g[1] = f_tau;
729   j[0] = ff_element(1); j[1] = j_ltau;
730 
731   for (r = 2; r <= l+1; r++)
732     multiply (g[r], g[r-1], f_tau);
733 
734   for (k = 2; k <= v; k++)
735     multiply (j[k], j[k-1], j_ltau);
736 
737 
738   // reset file to read coeff. of modular equation
739 
740   rc = meq_prime::reset ();
741 
742 
743   // compute value for j_ltau_1
744 
745   j_ltau_1num = j_ltau_1den = ff_element(0);
746 
747   for (r = 0; r <= l+1; r++) {
748     rc = read_row (p);
749 
750     if (rc)
751       lidia_error_handler ("eco_prime", "tildeEA()::Unable to read row");
752 
753     // compute value for j'(l tau)
754 
755     if (r > 0)
756       for (k = 0; k <= v; k++) {
757 	multiply (tmp2, ff_element(row[k]), ff_element(r));
758 	multiply (tmp2, tmp2, g[r-1]);
759 	multiply (tmp2, tmp2, j[k]);
760 
761 	add      (j_ltau_1num, j_ltau_1num, tmp2);
762       }
763 
764     for (k = 1; k <= v; k++) {
765       multiply (tmp2, ff_element(row[k]), ff_element(k));
766       multiply (tmp2, tmp2, g[r]);
767       multiply (tmp2, tmp2, j[k-1]);
768 
769       add      (j_ltau_1den, j_ltau_1den, tmp2);
770     }
771   }
772 
773   multiply (j_ltau_1num, j_ltau_1num, f_tau_1);
774   multiply (j_ltau_1den, j_ltau_1den, ff_element(- static_cast<long>(l)));
775 
776   if (j_ltau_1den.is_zero())
777     lidia_error_handler ("eco_prime", "tildeEf::denominator of j'(l tau) is zero");
778 
779   divide (j_ltau_1, j_ltau_1num, j_ltau_1den);
780 
781 
782   // compute value for E6(l tau)
783   // E6(l tau) = - E4(ltau) * j'(l tau) / j(l tau)
784 
785   multiply   (tmp, E4_ltau, j_ltau_1);
786 
787   if (j_ltau.is_zero())
788     lidia_error_handler ("eco_prime", "tildeEf::j(l tau) is zero");
789 
790   divide (tmp2, tmp, j_ltau);
791   negate (E6_ltau, tmp2);
792 
793 
794   // compute parameters P1, tildeEa, and tildeEb
795   // P1 = -l/2 E2*(tau) = l/2 12/s E2_star
796   // tildeEa == -3 * l^4 * E4(l tau)
797   // tildeEb == -2 * l^6 * E6(l tau)
798 
799   tmp = tmp2 = ff_element(l);
800 
801   square(tmp, tmp); square(tmp, tmp);
802   power (tmp2, tmp2, static_cast<long>(6));
803 
804   multiply (P1, ff_element(l * 6 / s), E2_star);
805   multiply (tildeEa, ff_element(-3) * tmp, E4_ltau);
806   multiply (tildeEb, ff_element(-2) * tmp2, E6_ltau);
807 
808   delete[] g; delete[] j;
809 
810   return 0;
811 }
812 
813 
814 #ifdef LIDIA_NAMESPACE
815 }	// end of namespace LiDIA
816 #endif
817