Quantenmechanik/ Bell-Ungleichungen/ BKS-Skript

Aus Wikibooks

Das folgende Skript schreibt eine Datei namens 'bks_18.svg'.

# Graph of Kochen-Specker system, Nodes=orthobases, Lines=vectors=observables
# set of 18 Kochen-Specker vectors
# vector notation ++++ +..+ -+-+  as labels

from math import pi,cos,sin, sqrt,exp,log
def div(p,q) : return int(p/q)

###### plot

class svgdump :
  def plotbegin(sd, w,h,f) : # args: width height zoomfactor
    W=str(w); H=str(h); u=''; fw=str(f*w); fh=str(f*h)
    s=( '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'+
     '<!DOCTYPE svg>\n'+
     '<svg xmlns="http://www.w3.org/2000/svg"\n'+
     '  xmlns:xlink="http://www.w3.org/1999/xlink"\n'+
     '  width="'+W+'" height="'+H+'" viewBox="0 0 '+fw+' '+fh+'">\n')
    return s

  def plotend(sd) : return '</svg>\n'
  def move(sd,x,y) : return 'M'+str(x)+','+str(y)
  def line(sd,x,y) : return 'L'+str(x)+','+str(y)
      
  def ball(sd, x,y,r,col) :
    return ('<circle fill="'+col+'" cx="'+str(x)+'" cy="'+str(y)+
      '" r="'+str(r)+'" />\n')

  def labl(sd,s,x,y, size=14,fill='#000') :
    f=' font-family="Arial"'
    t='<tspan x="'+str(x)+'" y="'+str(y)+'">'+s+'</tspan>'; fsz= str(size)
    return ('<text fill="'+fill+'"'+f+' font-size="'+fsz+'px">'+t+'</text>\n')

  def path(sd,w,s,lc='#000',fc='none') : # path w=with lc=linecolor fc=fillcol
    t='<path fill="'+fc+'" stroke="'+lc+'" stroke-width="'+str(w)+'" '
    t+= ' stroke-linecap="round" ' 
    return t + 'd="\n'+s+'" />\n'

# end class svgdump

def aprx(x) : # 3-digit approximation
  y= (-x) if(x<0) else x; z= int(1e3*y+1e-3); z= (-z) if (x<0) else z
  return z/1000.0

def curve(sd,scale,xy, fill='#000', width=1, spray='none', raw=0) :
  (xs,fx,xmin, ys,fy,ymin) = scale; s=''; n= div(len(xy),2) 
  for i in range(n) : 
    if raw==1 : x=xy[2*i]; y=xy[2*i+1]
    else : x= aprx(xmin+fx*(xy[2*i]-xs)); y= aprx(ymin+fy*(xy[2*i+1]-ys))
    s+= sd.move(x,y) if(i==0) else sd.line(x,y)
  return sd.path(width,s,lc=fill,fc=spray)

def label(sd,scale,txt,tx,ty) : # tx,ty plot coordinates not pixels
  (xs,fx,xmin, ys,fy,ymin) = scale; d=len(txt); s=''; dx=0
  x= aprx(xmin+fx*(tx-xs)); y= aprx(ymin+fy*(ty-ys)); r=15
  if d==1 : s+= sd.ball(x,y,r,'#990'); dx=d
  elif (d>1)and(d<10) : 
    xa=x-6*d;xb=x+6*d;ya=y-7;yb=y+7; xy=[xa,ya,xb,ya,xb,yb,xa,yb,xa,ya]
    s+= curve(sd,scale,xy,spray='#ff7',raw=1); dx=d
  return s+sd.labl(txt,x-6*dx,y+5)

def plot2(fn,xy,txt,w=800,h=600) :
  xmin=0; xmax=1.0; ymin=0; ymax=1.0; d=20 if((w+h)>1000) else 15
  xyf=[ xmin,ymin, xmax,ymin, xmax,ymax, xmin,ymax, xmin,ymin ] # frame
  xs,fx,xpix= xmin, (w-2*d)/(xmax-xmin),d # scale user units, min in pixels
  ys,fy,ypix= ymin,-(h-2*d)/(ymax-ymin),h-d ; scale=(xs,fx,xpix, ys,fy,ypix)
  sd=svgdump(); buf=sd.plotbegin(w,h,1)
  buf += curve(sd,scale, xyf, fill='#777'); 
  for j in range(len(xy)) : buf+= curve(sd,scale, xy[j])
  for j in range(len(txt)) :
    buf += label(sd,scale, txt[j][0], txt[j][1], txt[j][2])
  g=open(fn+'.svg','w'); g.write(buf+sd.plotend()); g.close()

def prepplot(tbl,wp=800,hp=600) :
  def drawline(xy, xa,ya,xb,yb) : xy+=[[xa,ya,xb,yb]]
  def drawbutton(txt, x,y,b) : txt+=[[b,x,y]]
  def drawlabel(txt, x,y,s) : txt+=[[s,x,y]]
  def condense(s) :
    t=''; n=len(s); u= s if(s[0]=='-') else ('+'+s); r=0 if(len(u)<8) else 4
    for i in range(r) : c=u[2*i]; d=u[2*i+1]; t+= ('.' if(d=='0') else c)
    return t
  def commonitem(t,i,j) : # find in columns i,j
    m=len(t);n=len(t[0]); s='?'
    for h in range(m) : 
      for k in range(m) : u=t[h][i]; v=t[k][j]; s= u if(u==v) else s
    return s
  txt=[]; xy=[] # plot items
  w=1.0; h=1.0; m=18; n=9 
  x0=w/2; y0=h/2; r=0.8*y0; s=0.5*y0
  n=6; np=9; a=2*pi/(n+0.0); a2=a/2; px=[0]*np; py=[0]*np # nodes for basis
  for i in range(n) : px[i]=x0+r*cos(i*a); py[i]=y0+r*sin(i*a)
  for i in range(3) : px[i+n]=x0+s*cos(2*i*a-a2); py[i+n]=y0+s*sin(2*i*a-a2)
  lbn='541762308'; lk=[[]]*m  # node labels in graph order
  for i in range(6) : lk[i]=[i,(i+1)% 6] # outer ring of links
  for i in range(3) : # 4 links to each of 3 inner points
    j=6+4*i; k=6+i; lk[j]=[k,(2*i+5)% 6];lk[j+1]=[k,2*i]
    lk[j+2]=[k,(2*i+2)% 6]; lk[j+3]=[k,(2*i+3)% 6]
  for i in range(m) : j,k=tuple(lk[i]); drawline(xy,px[j],py[j],px[k],py[k])
  for i in range(np) : drawbutton(txt,px[i],py[i], lbn[i])
  # vector label refpoints are halfway, except for the 6 long lines
  for i in range(m) :
    j,k=tuple(lk[i]); xa,ya,xb,yb=(px[j],py[j],px[k],py[k]); f=0.5
    l2=(xb-xa)*(xb-xa)+(yb-ya)*(yb-ya); r2=r*r*1.3; f=0.25 if(l2>r2) else 0.5
    xc=f*xa+(1-f)*xb; yc=f*ya+(1-f)*yb # s is entry common to 2 columns
    ca=int(lbn[j]); cb=int(lbn[k]); s=commonitem(tbl,ca,cb); t=condense(s)
    drawlabel(txt,xc,yc,t); print(s+' '+t)
  print('len(xy)='+str(len(xy))+' len(txt)='+str(len(txt)))
  s='Bell-Kochen-Specker-Menge mit 18 Elementen. Dimension=4.'
  drawlabel(txt,0.01*w,0.95*h,s)
  s='9 Knoten=Orthogonalbasen, 18 Linien=Vektoren.  Notation:'
  drawlabel(txt,0.01*w,0.08*h,s)
  s='(-+++)==(-a+b+c+d); (.+.-)==(0+b+0-d); Einheitsvektoren a,b,c,d.'
  drawlabel(txt,0.01*w,0.04*h,s)
  plot2('bks_18',xy,txt,w=wp,h=hp)

def plotonly() :
  tbl=[
'0+0+0+d 0+0+0+d a-b+c-d a-b+c-d 0+0+c+0 a-b-c+d a+b-c+d  a+b-c+d  a+b+c-d',
'0+0+c+0 0+b+0+0 a-b-c+d a+b+c+d 0+b+0+0 a+b+c+d a+b+c-d -a+b+c+d -a+b+c+d',
'a+b+0+0 a+0+c+0 a+b+0+0 a+0-c+0 a+0+0+d a+0+0-d a-b+0+0  a+0+c+0  a+0+0+d',
'a-b+0+0 a+0-c+0 0+0+c+d 0+b+0-d a+0+0-d 0+b-c+0 0+0+c+d  0+b+0-d  0+b-c+0 ',
  ]
  m=len(tbl); n=len(tbl[0]); t2=[[]]*m; m2=0
  for i in range(m) : t2[i]= tbl[i].split(); m2+=len(t2[i])
  prepplot(t2,wp=550,hp=450)

plotonly()