def train_dc(self, max_iter=50):
		N = self.sobj.get_num_samples()
		DIMS = self.sobj.get_num_dims()
		
		# intermediate solutions
		# latent variables
		latent = [0.0]*N

		sol = normal(DIMS,1)
		psi = matrix(0.0, (DIMS,N)) # (dim x exm)
		old_psi = matrix(0.0, (DIMS,N)) # (dim x exm)
		threshold = matrix(0.0)

		obj = -1
		iter = 0 

		# terminate if objective function value doesn't change much
		while iter<max_iter and (iter<2 or sum(sum(abs(np.array(psi-old_psi))))>=0.001):
			print('Starting iteration {0}.'.format(iter))
			print(sum(sum(abs(np.array(psi-old_psi)))))
			iter += 1
			old_psi = matrix(psi)

			# 1. linearize
			# for the current solution compute the 
			# most likely latent variable configuration
			mean = matrix(0.0, (DIMS, 1))
			for i in range(N):
				(foo, latent[i], psi[:,i]) = self.sobj.argmax(sol, i, add_prior=True)
				mean += psi[:,i]

			mpsi = matrix(psi)
			mean /= float(N)
			#for i in range(N):
				#mphi[:,i] -= mean

			# 2. solve the intermediate convex optimization problem 
			A = mpsi*mpsi.trans()
			print A.size
			W = matrix(0.0, (DIMS,DIMS))
			syev(A,W,jobz='V')
			print W
			print A
			print A*A.trans()
			#sol = (W[3:,0].trans() * A[:,3:].trans()).trans()
			#sol = (W[3:,0].trans() * A[:,3:].trans()).trans()
			sol = A[:,DIMS-1]
			print sol

		print(sum(sum(abs(np.array(psi-old_psi)))))
		self.sol = sol
		self.latent = latent
		return (sol, latent, threshold)
Make sure that serializing to JSON works for structs with choices.
dataset/ETHPy150Open nicococo/tilitools/structured_pca.py/StructuredPCA.train_dc--crossover with--dataset/ETHPy150Open wickman/pystachio/tests/test_choice.py/test_json_choice