forked from jan/fdfd_tools
		
	Use L-BFGS instead of CG, and remove rayleigh iteration refinement
scipy CG doesn't seem to converge as well as L-BFGS... worth looking into later
This commit is contained in:
		
							parent
							
								
									16f97d7f6b
								
							
						
					
					
						commit
						85030448c3
					
				@ -359,6 +359,8 @@ def eigsolve(num_modes: int,
 | 
				
			|||||||
    """
 | 
					    """
 | 
				
			||||||
    h_size = 2 * epsilon[0].size
 | 
					    h_size = 2 * epsilon[0].size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    kmag = norm(G_matrix @ k0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    Generate the operators
 | 
					    Generate the operators
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
@ -409,16 +411,26 @@ def eigsolve(num_modes: int,
 | 
				
			|||||||
    result = scipy.optimize.minimize(rayleigh_quotient,
 | 
					    result = scipy.optimize.minimize(rayleigh_quotient,
 | 
				
			||||||
                                     numpy.random.rand(*y_shape),
 | 
					                                     numpy.random.rand(*y_shape),
 | 
				
			||||||
                                     jac=True,
 | 
					                                     jac=True,
 | 
				
			||||||
                                     method='CG',
 | 
					                                     method='L-BFGS-B',
 | 
				
			||||||
                                     tol=1e-5,
 | 
					                                     tol=1e-20,
 | 
				
			||||||
                                     options={'maxiter': 30, 'disp':True})
 | 
					                                     options={'maxiter': 2000, 'gtol':0, 'ftol':1e-20 , 'disp':True})#, 'maxls':80, 'm':30})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    result = scipy.optimize.minimize(lambda y: rayleigh_quotient(y, False),
 | 
					    result = scipy.optimize.minimize(lambda y: rayleigh_quotient(y, False),
 | 
				
			||||||
                                     result.x,
 | 
					                                     result.x,
 | 
				
			||||||
                                     jac=True,
 | 
					                                     jac=True,
 | 
				
			||||||
                                     method='CG',
 | 
					                                     method='L-BFGS-B',
 | 
				
			||||||
                                     tol=1e-13,
 | 
					                                     tol=1e-20,
 | 
				
			||||||
                                     options={'maxiter': 100, 'disp':True})
 | 
					                                     options={'maxiter': 2000, 'ptol':1e-18, 'disp':True})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for i in range(20):
 | 
				
			||||||
 | 
					        result = scipy.optimize.minimize(lambda y: rayleigh_quotient(y, False),
 | 
				
			||||||
 | 
					                                     result.x,
 | 
				
			||||||
 | 
					                                     jac=True,
 | 
				
			||||||
 | 
					                                     method='L-BFGS-B',
 | 
				
			||||||
 | 
					                                     tol=1e-20,
 | 
				
			||||||
 | 
					                                     options={'maxiter': 70, 'gtol':1e-18, 'disp':True})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    z = result.x.reshape(y_shape)
 | 
					    z = result.x.reshape(y_shape)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -436,25 +448,13 @@ def eigsolve(num_modes: int,
 | 
				
			|||||||
        v = eigvecs[:, i]
 | 
					        v = eigvecs[:, i]
 | 
				
			||||||
        n = eigvals[i]
 | 
					        n = eigvals[i]
 | 
				
			||||||
        v /= norm(v)
 | 
					        v /= norm(v)
 | 
				
			||||||
        logger.info('eigness {}: {}'.format(i, norm(scipy_op @ v - (v.conj() @ (scipy_op @ v)) * v )))
 | 
					        eigness = norm(scipy_op @ v - (v.conj() @ (scipy_op @ v)) * v )
 | 
				
			||||||
 | 
					        f = numpy.sqrt(-numpy.real(n))
 | 
				
			||||||
 | 
					        df = numpy.sqrt(-numpy.real(n + eigness))
 | 
				
			||||||
 | 
					        neff_err = kmag * (1/df - 1/f)
 | 
				
			||||||
 | 
					        logger.info('eigness {}: {}\n neff_err: {}'.format(i, eigness, neff_err))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ev2 = eigvecs.copy()
 | 
					 | 
				
			||||||
    for i in range(len(eigvals)):
 | 
					 | 
				
			||||||
        logger.info('Refining eigenvector {}'.format(i))
 | 
					 | 
				
			||||||
        eigvals[i], ev2[:, i] = rayleigh_quotient_iteration(scipy_op,
 | 
					 | 
				
			||||||
                                                            guess_vector=eigvecs[:, i],
 | 
					 | 
				
			||||||
                                                            iterations=40,
 | 
					 | 
				
			||||||
                                                            tolerance=tolerance * numpy.real(numpy.sqrt(eigvals[i])) * 2,
 | 
					 | 
				
			||||||
                                                            solver = lambda A, b: spalg.bicgstab(A, b, maxiter=200)[0])
 | 
					 | 
				
			||||||
    eigvecs = ev2
 | 
					 | 
				
			||||||
    order = numpy.argsort(numpy.abs(eigvals))
 | 
					    order = numpy.argsort(numpy.abs(eigvals))
 | 
				
			||||||
 | 
					 | 
				
			||||||
    for i in range(len(eigvals)):
 | 
					 | 
				
			||||||
        v = eigvecs[:, i]
 | 
					 | 
				
			||||||
        n = eigvals[i]
 | 
					 | 
				
			||||||
        v /= norm(v)
 | 
					 | 
				
			||||||
        logger.info('eigness {}: {}'.format(i, norm(scipy_op @ v - (v.conj() @ (scipy_op @ v)) * v )))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return eigvals[order], eigvecs.T[order]
 | 
					    return eigvals[order], eigvecs.T[order]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user