<commit_before>from generate_chain_system import *

class BezierConstraintSolverEven( BezierConstraintSolver ):
	'''
	Fixed direction, magnitude free (for G1 or A).
	'''
	
	def update_system_with_result_of_previous_iteration( self, solution ):
		### Iterate only over the parts of the matrix that will change,
		### such as the system matrix involving fixed directions,
		### lagrange multipliers across G1 or A edges, and the right-hand-side.	
		solution = asarray(solution)
		num = len(self.bundles)
		assert solution.shape == (num, 4, 2)
		directions = [[dir_allow_zero( solution[i][1]-solution[i][0] ), dir_allow_zero( solution[i][2]-solution[i][3] )] for i in range(num) ]
	
		for i in range(num):
			self.bundles[i].directions = directions[i]
		
		self._update_bundles()
		self.system_factored = None
		## UPDATE: Actually, if constrained directions align with coordinate axes
		##         or have zero magnitude, then the systems may gain
		##		   or lose zeros. So, reset the symbolic factorization.
		## UPDATE 2: If we could update_bundles once with all directions zero-free,
		##           and then compute the symbolic factorization, we could keep it.
		## UPDATE 3: Let's try it assuming that the first time through there are no zeros.
		## UPDATE 4: I tried it and it makes no difference to performance at all
		##           up to alec's alligator. So, we'll reset the symbolic factorization
		##           in case the initial configuration has zeros.
		self.system_symbolic_factored = None
		
	
	def solve( self ):
		### Return a nicely formatted chain of bezier curves, un-substituting the fixed
		### directions.
		dofs_per_bundle = self.dofs_per_bundle
		dirs_per_bundle = [bundle.directions for bundle in self.bundles]
		# num = len( dofs_per_bundle )
		
		if self.system_symbolic_factored is None:
			#print 'even symbolic factoring'
			system = to_system_solve_t( self.system )
			self.system_symbolic_factored = compute_symbolic_factorization( system )
			self.system_factored = self.system_symbolic_factored( system )
		
		elif self.system_factored is None:
			#print 'even numeric factoring'
			system = to_system_solve_t( self.system )
			self.system_factored = self.system_symbolic_factored( system )
		
		#print 'even solve'
		x = self.system_factored( self.rhs )
		# x = linalg.solve( self.system, self.rhs )
		# x = scipy.sparse.linalg.spsolve( self.system, self.rhs )
	
		### Return a nicely formatted chain of bezier curves.
		result = []
# 		debugger()
		dofs_offset = 0
		for dofs, dirs in zip(dofs_per_bundle, dirs_per_bundle):
			solution = zeros( (4, 2) )
			if dofs[0] == 4:
				solution[ :2 ] = x[dofs_offset : dofs_offset + 4].reshape(2,2)
				
			elif dofs[0] == 3:
				solution[0] = x[dofs_offset : dofs_offset + 2]
				solution[1] = solution[0] + asarray(dirs[0]) * x[dofs_offset + 2]
			
			dofs_offset += dofs[0]
			
			if dofs[1] == 4:
				solution[ 2:4 ] = x[dofs_offset : dofs_offset + 4].reshape(2,2)
				
			elif dofs[1] == 3:
				solution[3] = x[dofs_offset : dofs_offset + 2]
				solution[2] = solution[3] + asarray(dirs[1]) * x[dofs_offset + 2]
				

			dofs_offset += dofs[1]
				
			result.append(solution)
		
		return result	
	
	def lagrange_equations_for_curve_constraints( self, bundle0, bundle1 ):
		mag0, mag1 = bundle0.magnitudes[1], bundle1.magnitudes[0]
		dim = 2
		dofs0 = self.compute_dofs_per_curve(bundle0)
		dofs1 = self.compute_dofs_per_curve(bundle1)
		dofs = sum(dofs0) + sum(dofs1)
		dirs0 = asarray(bundle0.directions)
		dirs1 = asarray(bundle1.directions)
		
		assert bundle0.constraints[1][0] == bundle1.constraints[0][0]
		smoothness = bundle0.constraints[1][0]
		if smoothness == 'C0':         ## C0
			'''
			Boundary Conditions are as follows:
			lambda1 * ( P4x' - Q1x' ) = 0
			lambda2 * ( P4y' - Q1y' ) = 0
			'''
			R = zeros( ( dofs, dim ) )
			if dofs0[1] == 3:
				R[dofs0[0] : dofs0[0]+dim, :] = identity(dim)
			else:
				R[sum(dofs0)-dim : sum(dofs0), :] = identity(dim)
			R[sum(dofs0) : sum(dofs0)+dim, :] = identity(dim) * -1

		elif smoothness == 'A':        ## fixed angle
			R = zeros( ( dofs, dim ) )
			if dofs0[1] == 3:
				R[dofs0[0] : dofs0[0]+dim, :] = identity(dim)
			else:
				R[sum(dofs0)-dim : sum(dofs0), :] = identity(dim)
			R[sum(dofs0) : sum(dofs0)+dim, :] = identity(dim) * -1
			
		elif smoothness == 'C1':        ## C1
			'''
			Boundary Conditions are as follows:
			lambda1 * ( P4x' - Q1x' ) = 0
			lambda2 * ( P4y' - Q1y' ) = 0
			lambda3 * ( w_q(P4x' - P3x') + w_p(Q1x' - Q2x')) = 0
			lambda4 * ( w_q(P4y' - P3y') + w_p(Q1y' - Q2y')) = 0
			'''
			R = zeros( ( dofs, 2*dim ) )
			if dofs0[1] == 3:
				R[dofs0[0] : dofs0[0]+dim, :dim] = identity(dim)
				R[dofs0[0] : dofs0[0]+dim, -dim:] = identity(dim)
			else:
				R[sum(dofs0)-dim : sum(dofs0), :dim] = identity(dim)
				R[sum(dofs0)-dim : sum(dofs0), -dim:] = identity(dim)
				
			R[sum(dofs0) : sum(dofs0)+dim, :dim] = identity(dim) * -1
			R[sum(dofs0) : sum(dofs0)+dim, -dim:] = identity(dim)
			
			if dofs0[0] == 4:
				R[sum(dofs0)-2*dim : sum(dofs0)-dim, -dim:] = identity(dim) * -1
			elif dofs0[0] == 3:
				R[dofs0[0], -dim:] = -dirs0[1]
				
			if dofs1[1] == 4:
				R[sum(dofs0)+dim : sum(dofs0)+2*dim, -dim:] = identity(dim) * -1
			elif dofs1[1] == 3:
				R[sum(dofs0)+dofs1[0], -dim:] = -dirs1[0]
				
			## multiply by w_q and w_p
			R[ :sum(dofs0), dim: ] *= mag1
			R[ sum(dofs0):, dim: ] *= mag0
				
		elif smoothness == 'G1':        ## G1
			R = zeros( ( dofs, dim ) )
			if dofs0[1] == 3:
				R[dofs0[0] : dofs0[0]+dim, :] = identity(dim)
			else:
				R[sum(dofs0)-dim : sum(dofs0), :] = identity(dim)
			R[sum(dofs0) : sum(dofs0)+dim, :] = identity(dim) * -1
		else:
			R = zeros( ( dofs, 0 ) )
		
		rhs = zeros(R.shape[1])
		
		fixed = bundle0.control_points[-1][:dim]
		is_fixed = bundle0.constraints[1][1]
		assert type( is_fixed ) == bool
		if is_fixed:

			fixed = asarray(fixed)
			'''
			Boundary Conditions are as follows:
			lambda1 * ( P4x' - constraint_X' ) = 0
			lambda2 * ( P4y' - constraint_Y' ) = 0
			'''
			R2 = zeros( ( dofs, dim ) )
# 			for i in range( dim ):
			R2[sum(dofs0)-dim : sum(dofs0), :] = identity(dim)
		
			R = concatenate((R, R2), axis=1)
			rhs = concatenate((rhs, fixed))
	
		return R.T, rhs
		
		
	def system_for_curve( self, bundle ):
	
		dofs = self.compute_dofs_per_curve(bundle)
		dirs = asarray(bundle.directions)

		## p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y
		if array_equal(dofs, (4,4)):
			Left = [[1./7, 0., 1./14, 0., 1./35, 0., 1./140, 0.],
					[0., 1./7, 0., 1./14, 0., 1./35, 0., 1./140],
					[1./14, 0., 3./35, 0., 9./140, 0., 1./35, 0.],
					[0., 1./14, 0., 3./35, 0., 9./140, 0., 1./35],<commit_msg>remove repeating assignment in even solver.<commit_after>from generate_chain_system import *

class BezierConstraintSolverEven( BezierConstraintSolver ):
	'''
	Fixed direction, magnitude free (for G1 or A).
	'''
	
	def update_system_with_result_of_previous_iteration( self, solution ):
		### Iterate only over the parts of the matrix that will change,
		### such as the system matrix involving fixed directions,
		### lagrange multipliers across G1 or A edges, and the right-hand-side.	
		solution = asarray(solution)
		num = len(self.bundles)
		assert solution.shape == (num, 4, 2)
		directions = [[dir_allow_zero( solution[i][1]-solution[i][0] ), dir_allow_zero( solution[i][2]-solution[i][3] )] for i in range(num) ]
	
		for i in range(num):
			self.bundles[i].directions = directions[i]
		
		self._update_bundles()
		self.system_factored = None
		## UPDATE: Actually, if constrained directions align with coordinate axes
		##         or have zero magnitude, then the systems may gain
		##		   or lose zeros. So, reset the symbolic factorization.
		## UPDATE 2: If we could update_bundles once with all directions zero-free,
		##           and then compute the symbolic factorization, we could keep it.
		## UPDATE 3: Let's try it assuming that the first time through there are no zeros.
		## UPDATE 4: I tried it and it makes no difference to performance at all
		##           up to alec's alligator. So, we'll reset the symbolic factorization
		##           in case the initial configuration has zeros.
		self.system_symbolic_factored = None
		
	
	def solve( self ):
		### Return a nicely formatted chain of bezier curves, un-substituting the fixed
		### directions.
		dofs_per_bundle = self.dofs_per_bundle
		dirs_per_bundle = [bundle.directions for bundle in self.bundles]
		# num = len( dofs_per_bundle )
		
		if self.system_symbolic_factored is None:
			#print 'even symbolic factoring'
			system = to_system_solve_t( self.system )
			self.system_symbolic_factored = compute_symbolic_factorization( system )
			self.system_factored = self.system_symbolic_factored( system )
		
		elif self.system_factored is None:
			#print 'even numeric factoring'
			system = to_system_solve_t( self.system )
			self.system_factored = self.system_symbolic_factored( system )
		
		#print 'even solve'
		x = self.system_factored( self.rhs )
		# x = linalg.solve( self.system, self.rhs )
		# x = scipy.sparse.linalg.spsolve( self.system, self.rhs )
	
		### Return a nicely formatted chain of bezier curves.
		result = []
# 		debugger()
		dofs_offset = 0
		for dofs, dirs in zip(dofs_per_bundle, dirs_per_bundle):
			solution = zeros( (4, 2) )
			if dofs[0] == 4:
				solution[ :2 ] = x[dofs_offset : dofs_offset + 4].reshape(2,2)
				
			elif dofs[0] == 3:
				solution[0] = x[dofs_offset : dofs_offset + 2]
				solution[1] = solution[0] + asarray(dirs[0]) * x[dofs_offset + 2]
			
			dofs_offset += dofs[0]
			
			if dofs[1] == 4:
				solution[ 2:4 ] = x[dofs_offset : dofs_offset + 4].reshape(2,2)
				
			elif dofs[1] == 3:
				solution[3] = x[dofs_offset : dofs_offset + 2]
				solution[2] = solution[3] + asarray(dirs[1]) * x[dofs_offset + 2]
				

			dofs_offset += dofs[1]
				
			result.append(solution)
		
		return result	
	
	def lagrange_equations_for_curve_constraints( self, bundle0, bundle1 ):
		mag0, mag1 = bundle0.magnitudes[1], bundle1.magnitudes[0]
		dim = 2
		dofs0 = self.compute_dofs_per_curve(bundle0)
		dofs1 = self.compute_dofs_per_curve(bundle1)
		dofs = sum(dofs0) + sum(dofs1)
		dirs0 = asarray(bundle0.directions)
		dirs1 = asarray(bundle1.directions)
		
		assert bundle0.constraints[1][0] == bundle1.constraints[0][0]
		smoothness = bundle0.constraints[1][0]
		if smoothness == 'C0':         ## C0
			'''
			Boundary Conditions are as follows:
			lambda1 * ( P4x' - Q1x' ) = 0
			lambda2 * ( P4y' - Q1y' ) = 0
			'''
			R = zeros( ( dofs, dim ) )
			if dofs0[1] == 3:
				R[dofs0[0] : dofs0[0]+dim, :] = identity(dim)
			else:
				R[sum(dofs0)-dim : sum(dofs0), :] = identity(dim)
			R[sum(dofs0) : sum(dofs0)+dim, :] = identity(dim) * -1

		elif smoothness == 'A':        ## fixed angle
			R = zeros( ( dofs, dim ) )
			if dofs0[1] == 3:
				R[dofs0[0] : dofs0[0]+dim, :] = identity(dim)
			else:
				R[sum(dofs0)-dim : sum(dofs0), :] = identity(dim)
			R[sum(dofs0) : sum(dofs0)+dim, :] = identity(dim) * -1
			
		elif smoothness == 'C1':        ## C1
			'''
			Boundary Conditions are as follows:
			lambda1 * ( P4x' - Q1x' ) = 0
			lambda2 * ( P4y' - Q1y' ) = 0
			lambda3 * ( w_q(P4x' - P3x') + w_p(Q1x' - Q2x')) = 0
			lambda4 * ( w_q(P4y' - P3y') + w_p(Q1y' - Q2y')) = 0
			'''
			R = zeros( ( dofs, 2*dim ) )
			if dofs0[1] == 3:
				R[dofs0[0] : dofs0[0]+dim, :dim] = identity(dim)
				R[dofs0[0] : dofs0[0]+dim, -dim:] = identity(dim)
			else:
				R[sum(dofs0)-dim : sum(dofs0), :dim] = identity(dim)
				R[sum(dofs0)-dim : sum(dofs0), -dim:] = identity(dim)
				
			R[sum(dofs0) : sum(dofs0)+dim, :dim] = identity(dim) * -1
			R[sum(dofs0) : sum(dofs0)+dim, -dim:] = identity(dim)
			
			if dofs0[0] == 4:
				R[sum(dofs0)-2*dim : sum(dofs0)-dim, -dim:] = identity(dim) * -1
			elif dofs0[0] == 3:
				R[dofs0[0], -dim:] = -dirs0[1]
				
			if dofs1[1] == 4:
				R[sum(dofs0)+dim : sum(dofs0)+2*dim, -dim:] = identity(dim) * -1
			elif dofs1[1] == 3:
				R[sum(dofs0)+dofs1[0], -dim:] = -dirs1[0]
				
			## multiply by w_q and w_p
			R[ :sum(dofs0), dim: ] *= mag1
			R[ sum(dofs0):, dim: ] *= mag0
				
		elif smoothness == 'G1':        ## G1
			R = zeros( ( dofs, dim ) )
			if dofs0[1] == 3:
				R[dofs0[0] : dofs0[0]+dim, :] = identity(dim)
			else:
				R[sum(dofs0)-dim : sum(dofs0), :] = identity(dim)
			R[sum(dofs0) : sum(dofs0)+dim, :] = identity(dim) * -1
		else:
			R = zeros( ( dofs, 0 ) )
		
		rhs = zeros(R.shape[1])
		
		fixed = bundle0.control_points[-1][:dim]
		is_fixed = bundle0.constraints[1][1]
		assert type( is_fixed ) == bool
		if is_fixed:

			fixed = asarray(fixed)
			'''
			Boundary Conditions are as follows:
			lambda1 * ( P4x' - constraint_X' ) = 0
			lambda2 * ( P4y' - constraint_Y' ) = 0
			'''
			R2 = zeros( ( dofs, dim ) )
			R2[sum(dofs0)-dim : sum(dofs0), :] = identity(dim)
		
			R = concatenate((R, R2), axis=1)
			rhs = concatenate((rhs, fixed))
	
		return R.T, rhs
		
		
	def system_for_curve( self, bundle ):
	
		dofs = self.compute_dofs_per_curve(bundle)
		dirs = asarray(bundle.directions)

		## p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y
		if array_equal(dofs, (4,4)):
			Left = [[1./7, 0., 1./14, 0., 1./35, 0., 1./140, 0.],
					[0., 1./7, 0., 1./14, 0., 1./35, 0., 1./140],
					[1./14, 0., 3./35, 0., 9./140, 0., 1./35, 0.],
					[0., 1./14, 0., 3./35, 0., 9./140, 0., 1./35],
{'fraction_non_alphanumeric': 0.15892696122633002, 'fraction_numerical': 0.043883378418996095, 'mean_word_length': 3.0787618755746244, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '949635', 'n_tokens_mistral': 6249, 'n_tokens_neox': 5257, 'n_words': 1249}