0001"""
0002**geometric objects of the complex plane** as transformed by a given Moebius
0003tranformation
0004"""
0005
0006__Defs__ = ['mobTransform']
0007
0008__Classes__ = ['mobPointSets','mobMultiply','mobTranslate'
0009,'mobReciprocate','mobUnitCircle','mobFromFixed','mobMapCircles','mobRotate',
0010 'mobInverse']
0011
0012__all__= __Classes__ + __Defs__
0013
0014__doc_hints__={'m_type':'factory'}
0015
0016import pygeo.base.abstracts._complex as Complex
0017from pygeo.base.analytics.pygeomath import Mobius, Hermitian,matrixmultiply, sqrt, math_E,sin, inverse
0018
0019
0020class mobPointSets(Complex._zTransformation):
0021 """
0022*Mobius transformation* applied to the given **list of objects** of the complex plane
0023mapping the **3 (ordered) complex points** of the first point set
0024to the **3 (ordered) complex points** of the second point set.
0025
0026 inherits
0027
0028 `_zTransformation`__
0029
0030__ class-base.abstracts._complex._zTransformation
0031
0032 """
0033
0034 __doc_hints__= {'factory':'mobTransform',
0035 'args':['[list of 3 points], [list of 3 points], [list of objects]']}
0036
0037 def __init__(self,v,w,elements,**kws):
0038 self.v=v
0039 self.w=w
0040 self.elements=[]
0041 for e in elements:
0042 for t in e:
0043 self.elements.append(t)
0044 args=self.v+self.w+self.elements
0045 for element in elements:
0046 if not element in args:
0047 args.append(element)
0048 Complex._zTransformation.__init__(self,*args,**kws)
0049 self.normal_form = kws.get('normal_form',False)
0050 self.init()
0051
0052 def _getMobius(self):
0053 p=self.v[0]
0054 q=self.v[1]
0055 r=self.v[2]
0056 p1=self.w[0]
0057 q1=self.w[1]
0058 r1=self.w[2]
0059 s=(p-r)/(q-r)
0060 s1=(p1-r1)/(q1-r1)
0061 a=s*p1-s1*q1
0062 b=p*q1*s1-p1*q*s
0063 c=s-s1
0064 d=p*s1-q*s
0065 try:
0066 self._mobius= Mobius([[a,b],[c,d]]).normalize()
0067 if self.normal_form:
0068 self._mobius.normal_form()
0069 except ValueError:
0070 self._mobius = Mobius([[0,0],[0,0]])
0071 print "degenerate Mobius matrix"
0072 return False
0073 return True
0074
0075class mobUnitCircle(Complex._zTransformation):
0076 """
0077*Mobius transformation* applied to the given **list of objects** of the complex plane
0078mapping the given **complex circle** to the unit circle.
0079
0080 inherits
0081
0082 `_zTransformation`__
0083
0084__ class-base.abstracts._complex._zTransformation
0085
0086 """
0087
0088 __doc_hints__= {'factory':'mobTransform',
0089 'args':['zcircle, [list of objects]']}
0090
0091 def __init__(self,zcircle,elements,**kws):
0092 self.zcircle=zcircle
0093 self.elements=[]
0094 for e in elements:
0095 for t in e:
0096 self.elements.append(t)
0097 args=[zcircle]+[elements]+self.elements
0098 for element in elements:
0099 if not element in args:
0100 args.append(element)
0101 Complex._zTransformation.__init__(self,*args,**kws)
0102 self.init()
0103
0104 def _getMobius(self):
0105 t_mat=Hermitian([[1,-self.zcircle._center],[0,1]])
0106 d_mat=Hermitian([[1.0/self.zcircle._radius,0],[0,1]])
0107 self._mobius= Mobius(matrixmultiply(d_mat,t_mat)).normalize()
0108 return True
0109
0110class mobMultiply(Complex._zTransformation):
0111 """
0112*Mobius transformation* multiplying the given **list of objects** of the complex plane
0113by the given **complex point**
0114
0115 inherits
0116
0117 `_zTransformation`__
0118
0119__ class-base.abstracts._complex._zTransformation
0120
0121 """
0122
0123 __doc_hints__= {'factory':'mobTransform',
0124 'args':['zpoint, [list of objects]'],
0125 'qualifier':'MULTIPLY'}
0126
0127 __opts__= Complex._zTransformation.__opts__[:] +['alt']
0128
0129 def __init__(self,z,elements,**kws):
0130 self.z=z
0131 self.elements=[]
0132 for e in elements:
0133 for t in e:
0134 self.elements.append(t)
0135 args=[z]+[elements]+self.elements
0136 for element in elements:
0137 if not element in args:
0138 args.append(element)
0139 Complex._zTransformation.__init__(self,*args,**kws)
0140 self.init()
0141
0142 def _getMobius(self):
0143 k=sqrt(self.z.toComplex())
0144
0145 self._mobius= Mobius([[k,0.],[0,1./k]]).normalize()
0146
0147
0148
0149 return True
0150
0151
0152
0153class mobTranslate(Complex._zTransformation):
0154 """
0155*Mobius transformation* translating the given **list of objects** of the complex plane
0156in the direction of the given **complex point**
0157
0158 inherits
0159
0160 `_zTransformation`__
0161
0162__ class-base.abstracts._complex._zTransformation
0163
0164 """
0165
0166 __doc_hints__= {'factory':'mobTransform',
0167 'args':['zpoint, [list of objects]'],
0168 'qualifier':'TRANSLATE'}
0169
0170 __opts__= Complex._zTransformation.__opts__[:] +['alt']
0171
0172 def __init__(self,z,elements,**kws):
0173 self.z=z
0174 self.elements=[]
0175 for e in elements:
0176 for t in e:
0177 self.elements.append(t)
0178
0179 args=[z]+[elements]+self.elements
0180 for element in elements:
0181 if not element in args:
0182 args.append(element)
0183 Complex._zTransformation.__init__(self,*args,**kws)
0184 self.init()
0185
0186 def _getMobius(self):
0187 self._mobius= Mobius([[1,self.z.toComplex()],[0,1]]).normalize()
0188 return True
0189
0190class mobReciprocate(Complex._zTransformation):
0191 """
0192*Mobius transformation* reciprocating the given **list of objects**
0193of the complex plane
0194
0195 inherits
0196
0197 `_zTransformation`__
0198
0199__ class-base.abstracts._complex._zTransformation
0200
0201 """
0202
0203 __doc_hints__= {'factory':'mobTransform',
0204 'args':['[list of objects]']}
0205
0206 def __init__(self,elements,**kws):
0207 self.elements=[]
0208 for e in elements:
0209 for t in e:
0210 self.elements.append(t)
0211 args=self.elements+[elements]
0212 for element in elements:
0213 if not element in args:
0214 args.append(element)
0215 Complex._zTransformation.__init__(self,*args,**kws)
0216 self.init()
0217
0218 def _getMobius(self):
0219 self._mobius= Mobius([[0.,1j],[1j,0.]])
0220 return True
0221
0222class mobFromFixed(Complex._zTransformation):
0223 """
0224*Mobius transformation* applied to the given **list of objects** of the complex plane
0225with the given **2 complex points** as fixed points, and the given **numerical
0226value** as the transformation mulitplier
0227
0228 inherits
0229
0230 `_zTransformation`__
0231
0232__ class-base.abstracts._complex._zTransformation
0233
0234 """
0235
0236 __doc_hints__= {'factory':'mobTransform',
0237 'args':['zpoint1,zpoint2,float,[list of objects]']}
0238
0239 def __init__(self,f1,f2,k,elements,**kws):
0240 self.f1=f1
0241 self.f2=f2
0242 self.k=k
0243 self.elements=[]
0244 for e in elements:
0245 for t in e:
0246 self.elements.append(t)
0247
0248 args=[f1]+ [f2]+[k]+[elements]+self.elements
0249 for element in elements:
0250 if not element in args:
0251 args.append(element)
0252 Complex._zTransformation.__init__(self,*args,**kws)
0253 self.init()
0254
0255 def _getMobius(self):
0256 f1=self.f1
0257 f2=self.f2
0258 k=self.k
0259 A=f1-k*f2
0260 B=f1*f2*(k-1)
0261 C=1-k
0262 D=k*f1-f2
0263 self._mobius= Mobius([[A,B],[C,D]]).normalize()
0264 return True
0265
0266class mobMapCircles(Complex._zTransformation):
0267 """
0268*Mobius transformation* applied to the given **list of objects** of the complex plane mapping
0269the interior of the first given **complex circle** to the exterior of the second
0270given **complex circle**,
0271
0272 inherits
0273
0274 `_zTransformation`__
0275
0276__ class-base.abstracts._complex._zTransformation
0277
0278 """
0279
0280 __doc_hints__= {'factory':'mobTransform',
0281 'args':['zcircle1, zcircle2, [list of objects]']}
0282
0283 def __init__(self,circle1,circle2,elements,**kws):
0284 self.circle1=circle1
0285 self.circle2=circle2
0286 self.elements=[]
0287 for e in elements:
0288 for t in e:
0289 self.elements.append(t)
0290 args=[circle1]+[circle2]+self.elements
0291 for element in elements:
0292 if not element in args:
0293 args.append(element)
0294 Complex._zTransformation.__init__(self,*args,**kws)
0295 self.normal_form = kws.get('normal_form',False)
0296 self.init()
0297
0298 def _getMobius(self):
0299 c1=self.circle1._center.toComplex()
0300 c2=self.circle2._center.toComplex()
0301 r1=self.circle1._radius
0302 r2=self.circle2._radius
0303 mat1=Mobius([[1,-c1],[0,1.]])
0304 mat2=Mobius([[0.,r1*r2],[1j,0]]).normalize()
0305 mat3=Mobius([[1,c2],[0,1.]])
0306 m=matrixmultiply(mat3,matrixmultiply(mat2,mat1))
0307 try:
0308 self._mobius=Mobius(m).normalize()
0309 if self.normal_form:
0310 self._mobius.normal_form()
0311 except ValueError:
0312 self._mobius = Mobius([[0,0],[0,0]])
0313 print "degenerate Mobius matrix"
0314 return False
0315 return True
0316
0317class mobRotate(Complex._zTransformation):
0318 """
0319*Mobius transformation* applied to the given **list of objects** of the complex plane
0320induced by the rotation of the Riemann sphere, with the stereographic projection of the
0321given **complex point** as axis, by the given **numeric angle (in radians)**
0322
0323 inherits
0324
0325 `_zTransformation`__
0326
0327__ class-base.abstracts._complex._zTransformation
0328
0329 """
0330
0331 __doc_hints__= {'factory':'mobTransform',
0332 'args':['zpoint, float , [list of objects]']}
0333
0334 def __init__(self,zcenter,angle,elements,**kws):
0335 self.zcenter=zcenter
0336 self.angle=angle
0337 self.elements=[]
0338 for e in elements:
0339 for t in e:
0340 self.elements.append(t)
0341 args=[zcenter]+self.elements
0342 for element in elements:
0343 if not element in args:
0344 args.append(element)
0345 Complex._zTransformation.__init__(self,*args,**kws)
0346 self.normal_form = kws.get('normal_form',False)
0347 self.init()
0348
0349 def _getMobius(self):
0350 center=self.zcenter
0351 h_angle=self.angle/2.
0352 a=math_E**complex(0,h_angle)*center.mod2()+math_E**-(complex(0,h_angle))
0353 b=(0+2j)*sin(h_angle)*center
0354 c=-b.conjugate()
0355 d=a.conjugate()
0356 try:
0357 self._mobius=Mobius([[a,b],[c,d]]).normalize()
0358 if self.normal_form:
0359 self._mobius.normal_form()
0360 except ValueError:
0361 self._mobius = Mobius([[0,0],[0,0]])
0362 print "degenerate Mobius matrix"
0363 return False
0364 return True
0365
0366class mobInverse(Complex._zTransformation):
0367 """
0368*Mobius transformation* applied to the given **list of objects** of the complex plane
0369defined by the matrix inverse of matrix representing the **given Mobius transformation**
0370
0371 inherits
0372
0373 `_zTransformation`__
0374
0375__ class-base.abstracts._complex._zTransformation
0376
0377 """
0378
0379 __doc_hints__= {'factory':'mobTransform',
0380 'args':['mobTransform, [list of objects]']}
0381
0382 def __init__(self,transform,elements,**kws):
0383 self.mobius=transform
0384 self.elements=[]
0385 for e in elements:
0386 for t in e:
0387 self.elements.append(t)
0388 args=[transform]+self.elements
0389 for element in elements:
0390 if not element in args:
0391 args.append(element)
0392 Complex._zTransformation.__init__(self,*args,**kws)
0393 self.normal_form = kws.get('normal_form',False)
0394 self.init()
0395
0396 def _getMobius(self):
0397 self._mobius=self.mobius._mobius.inverse()
0398 return True
0399
0400def mobTransform(*args,**kws):
0401 """
0402'class factory' function returns instance of object derived from the
0403_zTransformation abstract class representing the Moebius tranformation defined
0404by its arguments, applied to a given list of objects of the complex plane
0405 """
0406 from pygeo.base.abstracts._element import method_get
0407 from pygeo.base.support.pygeoexceptions import Argument_Type_Error
0408 from pygeo.base.support.pygeoconstants import TRANSLATE, MULTIPLY
0409
0410 __sigs__= [[list,list,list],
0411 [Complex._zCircle,list], [Complex._zPoint,list],
0412 [Complex._zPoint,list,float],
0413 [Complex._zCircle,Complex._zCircle,list],[list],
0414 [Complex._zPoint,float,list],
0415 [Complex._zPoint,Complex._zPoint,float,list]]
0416
0417 t,i = method_get(__sigs__,args)
0418
0419 if t is None:
0420 raise Argument_Type_Error(__sigs__,args)
0421 else:
0422 if i==0:
0423 if (len(t[0])==3 and len(t[1])==3):
0424 return mobPointSets(t[0],t[1],t[2],**kws)
0425 elif i==1:
0426 return mobUnitCircle(t[0],t[1],**kws)
0427 elif i==2:
0428 return mobMultiply(t[0],t[1],**kws)
0429 elif i==3:
0430 if t[2]==TRANSLATE:
0431 return mobTranslate(t[0],t[1],**kws)
0432 elif t[2]==MULTIPLY:
0433 return mobMultiply(t[0],t[1],**kws)
0434 else:
0435 raise Argument_Type_Error(__sigs__,args)
0436 elif i==4:
0437 return mobMapCircles(t[0],t[1],t[2],**kws)
0438 elif i==5:
0439 return mobReciprocate(t[0],**kws)
0440 elif i==6:
0441 return mobRotate(t[0],t[1],t[2],**kws)
0442 elif i==7:
0443 return mobFromFixed(t[0],t[1],t[2],t[3],**kws)
0444 else:
0445 raise Argument_Type_Error(__sigs__,args)