def weights_for_target(cov, target_var, rank=2, w3=0):
    '''
	return the weight for risky asset in the vol target problem
	'''
    # check cov is valid?
    if rank == 2:
        a = cov[0, 0] + cov[1, 1] - 2 * cov[0, 1]
        b = 2 * cov[0, 1] - 2 * cov[1, 1]
        c = cov[1, 1] - target_var
        try:
            weights = solve_quadratic_equation(a, b, c)
        except Exception, e:
            weights = None, None

        return weights
def weights_for_target(cov, target_var, rank=2, w3=0):
	'''
	return the weight for risky asset in the vol target problem
	'''
	# check cov is valid?
	if rank == 2:
		a = cov[0, 0] + cov[1, 1] - 2 * cov[0, 1]
		b = 2 * cov[0, 1] - 2 * cov[1, 1]
		c = cov[1, 1] - target_var
		try:
			weights = solve_quadratic_equation(a, b, c)
		except Exception, e:
			weights = None, None
		
		return weights
        a = cov[0, 0] + cov[1, 1] - 2 * cov[0, 1]
        b = 2 * cov[0, 1] - 2 * cov[1, 1]
        c = cov[1, 1] - target_var
        try:
            weights = solve_quadratic_equation(a, b, c)
        except Exception, e:
            weights = None, None

        return weights
    elif rank == 3:
        a = cov[0, 0] + cov[1, 1] - 2 * cov[0, 1]
        b = cov[1, 1] * (2 * w3 - 2) - cov[1, 2] * 2 * w3 + cov[
            0, 2] * 2 * w3 + cov[0, 1] * 2 * (1 - w3)
        c = cov[2, 2] * w3 * w3 + cov[1, 1] * (
            1 - 2 * w3 + w3 * w3) + 2 * cov[1, 2] * (1 - w3) * w3 - target_var
        return solve_quadratic_equation(a, b, c)


def simple_weight(vol, target_vol):
    # assuming no correlation
    mat = np.array([vol * vol, 0, 0, 0]).reshape(2, 2)
    return weights_for_target(mat, target_vol * target_vol)[0]


def make_simple_weight(target_vol):
    def weight(vol):
        return simple_weight(vol, target_vol)

    return weight

	# check cov is valid?
	if rank == 2:
		a = cov[0, 0] + cov[1, 1] - 2 * cov[0, 1]
		b = 2 * cov[0, 1] - 2 * cov[1, 1]
		c = cov[1, 1] - target_var
		try:
			weights = solve_quadratic_equation(a, b, c)
		except Exception, e:
			weights = None, None
		
		return weights
	elif rank == 3:
		a = cov[0, 0] + cov[1, 1] - 2 * cov[0, 1]
		b = cov[1, 1] * (2 * w3 - 2) - cov[1, 2] * 2 * w3 + cov[0, 2] * 2 * w3 + cov[0, 1] * 2 * (1 - w3)
		c = cov[2, 2] * w3 * w3 + cov[1, 1] * (1 - 2 * w3 + w3 * w3) + 2 * cov[1, 2] * (1 - w3) * w3 - target_var
		return solve_quadratic_equation(a, b, c)


def simple_weight(vol, target_vol):
	# assuming no correlation
	mat = np.array([vol * vol, 0, 0, 0]).reshape(2, 2)
	return weights_for_target(mat, target_vol * target_vol)[0]


def make_simple_weight(target_vol):
	def weight(vol):
		return simple_weight(vol, target_vol)

	return weight