(* Copyright (c) 1992, 1993 Peter Schr\"oder Department of Computer Science 35 Olden St. Princeton University Princeton, NJ 08544-2087 ps@cs.princeton.edu Peter Schr\"oder hereby grants anyone permission to use, copy and modify this program, so long as this notice in its entirety is attached. This permission does not include the right to redistribute or sublicense for consideration, or commercially exploit in any way, any modification of this program, any derivative work made from this program, or any incorporation of this program in another program, without the express written consent of Peter Schr\"oder. PETER SCHR\"ODER PROVIDES ABSOLUTELY NO WARRANTY OF ANY KIND WITH RESPECT TO THIS PROGRAM, INCLUDING WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THIS PROGRAM IS WITH THE USER. IN NO EVENT WILL PETER SCHR\"ODER BE LIABLE TO ANYONE FOR DAMAGES ARISING OUT OF THE USE OF THIS PROGRAM, INCLUDING, WITHOUT LIMITATION, DAMAGES RESULTING FROM LOST DATA OR LOST PROFITS, OR FOR ANY SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES. *) Remove[pair,bilcoeff,fourc,integralplanar,G,H, l1,l2,l3,l4,logs,lcis,logselect,kpart,dilog,logpart, logint,integral,mag,area,cross,FormFactor] pair[l_List]:= Block[{pi,pj,ei,ej,di,dj}, (* given two lines compute c_{0,1,2,3,4,5} Mathematica arrays are offset 1 so they are actually called c[[1,2,3,4,5,6]]... *) pj=l[[1,1]]; pi=l[[2,1]]; ej=l[[1,2]]-l[[1,1]]; ei=l[[2,2]]-l[[2,1]]; dj=ej/mag[ej]; di=ei/mag[ei]; Simplify[{mag[ej],-2 di.dj,mag[ei],-2 dj.(pi-pj), 2 di.(pi-pj),(pi-pj).(pi-pj)}] ] bilcoeff[c_List]:= Block[{const,theta,phi,argdiff,eps=10^-6}, (* determine whether the biquadratic form factors into the product of two bilinear forms. This corresponds to the case that the two edges lie in the same plane Since we always assume the coefficients of s^2 and t^2 to be 1 we may write the product of the bilinear forms as (s Exp[I theta]+t Exp[I phi]+const) (s Exp[-I theta]+t Exp[-I phi]+const) From this follows that Sqrt[c[[6]]] must be const *) const=Sqrt[c[[6]]]; (* Furthermore, if c==0 then c[[4]] and c[[5]] must also be zero! In this case we are underconstrained. What's more Abs[c[[2]]]<=2 since ArcCos[c[[2]]/2]=theta-phi since both c[[4]] and c[[5]] are zero we arbitrarily pick theta==0 *) argdiff=ArcCos[c[[2]]/2]; If[N[Abs[const]]=0,Log[x]-2I Pi,Log[x]] l4[x_]:=If[Im[x]>=0&&Re[x]<=0,Log[x]-2I Pi,Log[x]] logs={l1,l2,l3,l4} lcis[a_,b_]:= Block[{xdisc=Re[b]^2-Abs[b]^2+Abs[a]^2, ydisc=Im[b]^2-Abs[b]^2+Abs[a]^2, x1,x2,y1,y2}, (* intersect the real and the imaginary axis with a circle of radius a, centered at b *) x1=Re[b]+Sqrt[xdisc]; x2=Re[b]-Sqrt[xdisc]; y1=Im[b]+Sqrt[ydisc]; y2=Im[b]-Sqrt[ydisc]; (* return the solutions, if any, in the order real axis, imaginary axis *) {If[xdisc>=0,{x1,x2},{}],If[ydisc>=0,{y1,y2},{}]} ] logselect[a_,b_,l_,u_]:= Block[{maxpath,minpath,posreal,negreal,posimg,negimg, seghit,sols}, (* a is the radius b is the center l is lower u is upper any argument has the form z=b+a*Exp[I(Arg[l]+t(Arg[u]-Arg[l]))] resolve the multivaluedness accordingly This is your basic graphics problem. We have a unit circle centered at b and scaled by a and ask whether the real axis or the imaginary axis intersects it, and if so, in the segment of the circle that we will traverse during the integration. *) maxpath=Max[Arg[l],Arg[u]]; minpath=Min[Arg[l],Arg[u]]; seghit[z_]:=minpath<=Arg[(z-b)/a]<=maxpath; sols=lcis[a,b]; (* check for negative real axis *) negreal=(Length[sols[[1]]]==2)&& ((Re[sols[[1,1]]]<=0 && seghit[sols[[1,1]]])|| (Re[sols[[1,2]]]<=0 && seghit[sols[[1,2]]])); (* check for positive real axis *) posreal=(Length[sols[[1]]]==2)&& ((Re[sols[[1,1]]]>=0 && seghit[sols[[1,1]]])|| (Re[sols[[1,2]]]>=0 && seghit[sols[[1,2]]])); (* check for negative imaginary axis *) negimg=(Length[sols[[2]]]==2)&& ((Re[sols[[2,1]]]<=0 && seghit[I sols[[2,1]]])|| (Re[sols[[2,2]]]<=0 && seghit[I sols[[2,2]]])); (* check for positive imaginary axis *) posimg=(Length[sols[[2]]]==2)&& ((Re[sols[[2,1]]]>=0 && seghit[I sols[[2,1]]])|| (Re[sols[[2,2]]]>=0 && seghit[I sols[[2,2]]])); If[!negreal, 1, If[!negimg, 2, If[!posimg, 4, If[!posreal, 3, ] ] ] ] ] kpart[k_,l_,u_]:= Block[{int}, (* int[t]=Integrate[t^2/(1-t^2)^3,t] *) int[t_]:=t/(4(t^2-1)^2)+t/(8(t^2-1))+Log[(t-1)/(t+1)]/16; I(2k+1)Pi(int[u]-int[l]) ] dilog[c_,r_,l_,u_]:= Block[{sols,maxpath,minpath,seghit,cross,p,parg,towardsu,towardsl, pu,pl,start,end}, (* return the points where the argument of the log is on the real axis *) sols=lcis[r,c][[1]]; (* since we don't know the ordering *) maxpath=Max[Arg[l],Arg[u]]; minpath=Min[Arg[l],Arg[u]]; (* given such a point on the real axis where does it lie on the unit cirle (of which we are interested in the segment between l and u) *) seghit[z_]:=minpath<=Arg[(z-c)/r]<=maxpath; (* only if there are any solutions, the solutions are on the negative real axis, they are within the segment of interest, there is only one intersection (we actually cross) *) cross=(Length[sols]==2)&& Xor[Re[sols[[1]]]<=0 && seghit[sols[[1]]], Re[sols[[2]]]<=0 && seghit[sols[[2]]]]; (* for the dilog we have an argument of the form 1-z, compute it *) p=If[Re[sols[[1]]]<=0 && seghit[sols[[1]]], 1-sols[[1]], 1-sols[[2]] ]; (* put this argument on the unit circle remembering that we already know that it is within the contour over which we are integrating *) parg=Arg[((1-p)-c)/r]; (* we want to cut the path at that point *) towardsu=If[Arg[u]0, -2Pi I(2 Log[p]-Log[start]), -2Pi I Log[end] ], If[k==4, If[Im[pu]<0, -2Pi I(2 Log[p]-Log[end]), -2Pi I Log[start] ], 0 ] ], 0 ] ] logpart[b_,l_,u_]:= Block[{p1,p2,p3,int}, (* this integrates `t^2/(1-t^2)^3 Log[t+b]' between l and u *) p1=logs[[logselect[1,b,l,u]]]; p2=logs[[logselect[-1/(1+b),1/(1+b),l,u]]]; p3=logs[[logselect[1/(1-b),1/(1-b),l,u]]]; int[t_]:=-p1[t-1]b/(1+b)^2-p1[1+t]b/(b-1)^2+ p1[b+t]2(b+t)(1+b t)((b-t)^2+(b t-1)^2)/ ((b^2-1)^2(t^2-1)^2)+2(b-t)/((b^2-1)(t^2-1))+ p2[(1-t)/(1+b)]p1[b+t]-p3[(1+t)/(1-b)]p1[b+t]; 1/16(int[u]-int[l]+ dilog[1/(1+b),-1/(1+b),l,u]- dilog[1/(1-b),1/(1-b),l,u]) ] logint[s_,c15_,c16_,c17_,c18_,l_,u_]:= Block[{k,lan,p1,p2,p3,p4,tan,check,eps=10^-6}, (* we need to determine the value of k when going from the arctan to the log representation. We simply guess and stick in two points to see what we get *) p1=logs[[logselect[1,-c17[s],l,u]]]; p2=logs[[logselect[1,-c18[s],l,u]]]; p3=logs[[logselect[1,c17[s],l,u]]]; p4=logs[[logselect[1,c18[s],l,u]]]; (* the integrand when written with logs *) lan[t_,k_]:=t^2/(1-t^2)^3/(2I)*(I(2k+1)Pi+ p1[t-c17[s]]+p2[t-c18[s]]- p3[t+c17[s]]-p4[t+c18[s]]); (* the original integrand *) tan[t_]=t^2/(1-t^2)^3* ArcTan[(Conjugate[c16[s]] t^2-c16[s])/(c15 t)]; check[k_]:=N[Abs[tan[u]-lan[u,k]]+Abs[tan[l]-lan[l,k]]]; k=If[check[0]eps, ff-=c[[2]] integral[c], ] ] ]; ff/(8 Pi area[p1]) ]