def aposteriori_spawning(fin, fout, pin, pout, save_canonical=False): """ :param f: An ``IOManager`` instance providing the simulation data. :param datablock: The data block where the results are. """ # Number of time steps we saved timesteps = fin.load_wavepacket_timegrid() nrtimesteps = timesteps.shape[0] params = fin.load_wavepacket_parameters() coeffs = fin.load_wavepacket_coefficients() # A data transformation needed by API specification coeffs = [ [ coeffs[i,j,:] for j in xrange(pin["ncomponents"]) ] for i in xrange(nrtimesteps) ] # The potential Potential = PotentialFactory().create_potential(pin) # Initialize a mother Hagedorn wavepacket with the data from another simulation HAWP = HagedornWavepacket(pin) HAWP.set_quadrature(None) # Initialize an empty wavepacket for spawning SWP = HagedornWavepacket(pout) SWP.set_quadrature(None) # Initialize a Spawner NAS = NonAdiabaticSpawnerKF(pout) # Try spawning for these components, if none is given, try it for all. if not "spawn_components" in parametersout: components = range(pin["ncomponents"]) else: components = parametersout["spawn_components"] # Iterate over all timesteps and spawn for i, step in enumerate(timesteps): print(" Try spawning at timestep "+str(step)) # Configure the wave packet and project to the eigenbasis. HAWP.set_parameters(params[i]) HAWP.set_coefficients(coeffs[i]) # Project to the eigenbasis as the parameter estimation # has to happen there because of coupling. T = HAWP.clone() T.project_to_eigen(Potential) # Try spawning a new packet for each component estps = [ NAS.estimate_parameters(T, component=acomp) for acomp in components ] # The quadrature quadrature = InhomogeneousQuadrature() # Quadrature, assume same quadrature order for both packets # Assure the "right" quadrature is choosen if mother and child have # different basis sizes if max(HAWP.get_basis_size()) > max(SWP.get_basis_size()): quadrature.set_qr(HAWP.get_quadrature().get_qr()) else: quadrature.set_qr(SWP.get_quadrature().get_qr()) for index, ps in enumerate(estps): if ps is not None: # One choice of the sign U = SWP.clone() U.set_parameters(ps) # Project the coefficients to the spawned packet tmp = T.clone() NAS.project_coefficients(tmp, U, component=components[index]) # Other choice of the sign V = SWP.clone() # Transform parameters psm = list(ps) B = ps[0] Bm = -np.real(B)+1.0j*np.imag(B) psm[0] = Bm V.set_parameters(psm) # Project the coefficients to the spawned packet tmp = T.clone() NAS.project_coefficients(tmp, V, component=components[index]) # Compute some inner products to finally determine which parameter set we use ou = abs(quadrature.quadrature(T,U, component=components[index])) ov = abs(quadrature.quadrature(T,V, component=components[index])) # Choose the packet which maximizes the inner product. This is the main point! if ou >= ov: U = U else: U = V # Finally do the spawning, this is essentially to get the remainder T right # The packet U is already ok by now. NAS.project_coefficients(T, U, component=components[index]) # Transform back if save_canonical is True: T.project_to_canonical(Potential) U.project_to_canonical(Potential) # Save the mother packet rest fout.save_wavepacket_parameters(T.get_parameters(), timestep=step, blockid=2*index) fout.save_wavepacket_coefficients(T.get_coefficients(), timestep=step, blockid=2*index) # Save the spawned packet fout.save_wavepacket_parameters(U.get_parameters(), timestep=step, blockid=2*index+1) fout.save_wavepacket_coefficients(U.get_coefficients(), timestep=step, blockid=2*index+1)
params["eps"] = 0.2 params["basis_size"] = 6 params["ncomponents"] = 3 WP2 = HagedornWavepacket(params) WP2.set_parameters((1.0j, 1.0, 0.0, 0.0, 0.125)) WP2.set_quadrature(None) HQ1 = HomogeneousQuadrature() HQ1.build_qr(max(WP1.get_basis_size())) HQ2 = HomogeneousQuadrature() HQ2.build_qr(max(WP2.get_basis_size())) IHQ = InhomogeneousQuadrature() IHQ.build_qr(10) M1 = HQ1.build_matrix(WP1) M2 = HQ2.build_matrix(WP2) figure() matshow(real(M1)) savefig("M1r.png") figure() matshow(imag(M1)) savefig("M1i.png")
WP1.set_coefficient(0, 0, 1) WP1.set_quadrature(None) params["basis_size"] = 6 WP2 = HagedornWavepacket(params) WP2.set_coefficient(0, 0, 1) WP2.set_quadrature(None) HQ1 = HomogeneousQuadrature() HQ1.build_qr(max(WP1.get_basis_size())) HQ2 = HomogeneousQuadrature() HQ2.build_qr(max(WP2.get_basis_size())) IHQ = InhomogeneousQuadrature() IHQ.build_qr(nmax) Pibra = WP1.get_parameters() x = linspace(-4, 4, 4000) positions = linspace(-0.5, 2.5, 61) quads1 = [] quads2 = [] quads12 = [] for index, pos in enumerate(positions): print(pos) # Moving Gaussian
def spawn_basis_projection(self, mother, child, component, order=None): """Update the superposition coefficients of mother and spawned wavepacket. We do a full basis projection to the basis of the spawned wavepacket here. """ c_old = mother.get_coefficients(component=component) # Mother packet c_new_m = np.zeros(c_old.shape, dtype=np.complexfloating) # Spawned packet c_new_s = np.zeros((child.get_basis_size(component=component),1), dtype=np.complexfloating) # The quadrature quadrature = InhomogeneousQuadrature() # Quadrature rule. Assure the "right" quadrature is choosen if # mother and child have different basis sizes if mother.get_basis_size(component=component) > child.get_basis_size(component=component): quadrature.set_qr( mother.get_quadrature().get_qr() ) else: quadrature.set_qr( child.get_quadrature().get_qr() ) # The quadrature nodes and weights q0, QS = quadrature.mix_parameters(mother.get_parameters(), child.get_parameters()) nodes = quadrature.transform_nodes(mother.get_parameters(), child.get_parameters(), mother.eps) weights = quadrature.get_qr().get_weights() # Basis sets for both packets basis_m = mother.evaluate_basis_at(nodes, prefactor=True) basis_s = child.evaluate_basis_at(nodes, prefactor=True) max_order = min(child.get_basis_size(component=component), self.max_order) # Project to the basis of the spawned wavepacket # Original, inefficient code for projection # R = QR.get_order() # for i in xrange(max_order): # # Loop over all quadrature points # tmp = 0.0j # for r in xrange(R): # tmp += np.conj(np.dot( c_old[:,0], basis_m[:,r] )) * basis_s[i,r] * weights[0,r] # c_new_s[i,0] = self.eps * QS * tmp # Optimised and vectorised code (in ugly formatting) c_new_s[:max_order,:] = self.eps * QS * ( np.reshape( np.sum( np.transpose( np.reshape( np.conj( np.sum(c_old[:,:] * basis_m[:,:],axis=0) ) ,(-1,1) ) ) * (basis_s[:max_order,:] * weights[:,:]), axis=1 ) ,(-1,1) )) # Reassign the new coefficients mother.set_coefficients(c_new_m, component=component) child.set_coefficients(c_new_s, component=component) return (mother, child)