def test_weighted_sum_operator(self, num_state_qubits, weights, input_x, result): """ weighted sum operator test """ # initialize weighted sum operator factory warnings.filterwarnings('ignore', category=DeprecationWarning) sum_op = WeightedSumOperator(num_state_qubits, weights) warnings.filterwarnings('always', category=DeprecationWarning) # initialize circuit q = QuantumRegister(num_state_qubits + sum_op.get_required_sum_qubits(weights)) if sum_op.required_ancillas() > 0: q_a = QuantumRegister(sum_op.required_ancillas()) qc = QuantumCircuit(q, q_a) else: q_a = None qc = QuantumCircuit(q) # set initial state for i, x in enumerate(input_x): if x == 1: qc.x(q[i]) # build circuit sum_op.build(qc, q, q_a) # run simulation job = execute(qc, BasicAer.get_backend('statevector_simulator'), shots=1) num_results = 0 value = None for i, s_a in enumerate(job.result().get_statevector()): if np.abs(s_a)**2 >= 1e-6: num_results += 1 b_value = '{0:b}'.format(i).rjust(qc.width(), '0') b_sum = b_value[(-len(q)):(-num_state_qubits)] value = int(b_sum, 2) # make sure there is only one result with non-zero amplitude self.assertEqual(num_results, 1) # compare to precomputed solution self.assertEqual(value, result)
def test_conditional_value_at_risk(self, simulator): # define backend to be used backend = BasicAer.get_backend(simulator) # set problem parameters n_z = 2 z_max = 2 z_values = np.linspace(-z_max, z_max, 2 ** n_z) p_zeros = [0.15, 0.25] rhos = [0.1, 0.05] lgd = [1, 2] K = len(p_zeros) alpha = 0.05 # set var value var = 2 var_prob = 0.961940 # determine number of qubits required to represent total loss n_s = WeightedSumOperator.get_required_sum_qubits(lgd) # create circuit factory (add Z qubits with weight/loss 0) agg = WeightedSumOperator(n_z + K, [0] * n_z + lgd) # define linear objective breakpoints = [0, var] slopes = [0, 1] offsets = [0, 0] # subtract VaR and add it later to the estimate f_min = 0 f_max = 3 - var c_approx = 0.25 # construct circuit factory for uncertainty model (Gaussian Conditional Independence model) u = GCI(n_z, z_max, p_zeros, rhos) cvar_objective = PwlObjective( agg.num_sum_qubits, 0, 2 ** agg.num_sum_qubits - 1, # max value that can be reached by the qubit register (will not always be reached) breakpoints, slopes, offsets, f_min, f_max, c_approx ) multivariate_cvar = MultivariateProblem(u, agg, cvar_objective) num_qubits = multivariate_cvar.num_target_qubits num_ancillas = multivariate_cvar.required_ancillas() q = QuantumRegister(num_qubits, name='q') q_a = QuantumRegister(num_ancillas, name='q_a') qc = QuantumCircuit(q, q_a) multivariate_cvar.build(qc, q, q_a) job = execute(qc, backend=backend) # evaluate resulting statevector value = 0 for i, a in enumerate(job.result().get_statevector()): b = ('{0:0%sb}' % multivariate_cvar.num_target_qubits).format(i)[-multivariate_cvar.num_target_qubits:] am = np.round(np.real(a), decimals=4) if np.abs(am) > 1e-6 and b[0] == '1': value += am ** 2 # normalize and add VaR to estimate value = multivariate_cvar.value_to_estimation(value) normalized_value = value / (1.0 - var_prob) + var # compare to precomputed solution self.assertEqual(0.0, np.round(normalized_value - 3.3796, decimals=4))
def test_asian_barrier_spread(self): """Test the asian barrier spread model.""" try: from qiskit.aqua.circuits import WeightedSumOperator, FixedValueComparator as Comparator from qiskit.aqua.components.uncertainty_problems import ( UnivariatePiecewiseLinearObjective as PwlObjective, MultivariateProblem) from qiskit.aqua.components.uncertainty_models import MultivariateLogNormalDistribution except ImportError: import warnings warnings.warn( 'Qiskit Aqua is not installed, skipping the application test.') return # number of qubits per dimension to represent the uncertainty num_uncertainty_qubits = 2 # parameters for considered random distribution spot_price = 2.0 # initial spot price volatility = 0.4 # volatility of 40% interest_rate = 0.05 # annual interest rate of 5% time_to_maturity = 40 / 365 # 40 days to maturity # resulting parameters for log-normal distribution # pylint: disable=invalid-name mu = ((interest_rate - 0.5 * volatility**2) * time_to_maturity + np.log(spot_price)) sigma = volatility * np.sqrt(time_to_maturity) mean = np.exp(mu + sigma**2 / 2) variance = (np.exp(sigma**2) - 1) * np.exp(2 * mu + sigma**2) stddev = np.sqrt(variance) # lowest and highest value considered for the spot price; in between, # an equidistant discretization is considered. low = np.maximum(0, mean - 3 * stddev) high = mean + 3 * stddev # map to higher dimensional distribution # for simplicity assuming dimensions are independent and identically distributed) dimension = 2 num_qubits = [num_uncertainty_qubits] * dimension low = low * np.ones(dimension) high = high * np.ones(dimension) mu = mu * np.ones(dimension) cov = sigma**2 * np.eye(dimension) # construct circuit factory distribution = MultivariateLogNormalDistribution(num_qubits=num_qubits, low=low, high=high, mu=mu, cov=cov) # determine number of qubits required to represent total loss weights = [] for n in num_qubits: for i in range(n): weights += [2**i] num_sum_qubits = WeightedSumOperator.get_required_sum_qubits(weights) # create circuit factoy agg = WeightedSumOperator(sum(num_qubits), weights) # set the strike price (should be within the low and the high value of the uncertainty) strike_price_1 = 3 strike_price_2 = 4 # set the barrier threshold barrier = 2.5 # map strike prices and barrier threshold from [low, high] to {0, ..., 2^n-1} max_value = 2**num_sum_qubits - 1 low_ = low[0] high_ = high[0] mapped_strike_price_1 = (strike_price_1 - dimension*low_) / \ (high_ - low_) * (2**num_uncertainty_qubits - 1) mapped_strike_price_2 = (strike_price_2 - dimension*low_) / \ (high_ - low_) * (2**num_uncertainty_qubits - 1) mapped_barrier = (barrier - low) / (high - low) * (2**num_uncertainty_qubits - 1) conditions = [] for i in range(dimension): # target dimension of random distribution and corresponding condition conditions += [(i, Comparator(num_qubits[i], mapped_barrier[i] + 1, geq=False))] # set the approximation scaling for the payoff function c_approx = 0.25 # setup piecewise linear objective fcuntion breakpoints = [0, mapped_strike_price_1, mapped_strike_price_2] slopes = [0, 1, 0] offsets = [0, 0, mapped_strike_price_2 - mapped_strike_price_1] f_min = 0 f_max = mapped_strike_price_2 - mapped_strike_price_1 bull_spread_objective = PwlObjective(num_sum_qubits, 0, max_value, breakpoints, slopes, offsets, f_min, f_max, c_approx) # define overall multivariate problem asian_barrier_spread = MultivariateProblem(distribution, agg, bull_spread_objective, conditions=conditions) num_req_qubits = asian_barrier_spread.num_target_qubits num_req_ancillas = asian_barrier_spread.required_ancillas() qr = QuantumRegister(num_req_qubits, name='q') qr_ancilla = QuantumRegister(num_req_ancillas, name='q_a') qc = QuantumCircuit(qr, qr_ancilla) asian_barrier_spread.build(qc, qr, qr_ancilla) job = execute(qc, backend=BasicAer.get_backend('statevector_simulator')) # evaluate resulting statevector value = 0 for i, amplitude in enumerate(job.result().get_statevector()): b = ('{0:0%sb}' % asian_barrier_spread.num_target_qubits ).format(i)[-asian_barrier_spread.num_target_qubits:] prob = np.abs(amplitude)**2 if prob > 1e-4 and b[0] == '1': value += prob # all other states should have zero probability due to ancilla qubits if i > 2**num_req_qubits: break # map value to original range mapped_value = asian_barrier_spread.value_to_estimation(value) / ( 2**num_uncertainty_qubits - 1) * (high_ - low_) expected = 0.83188 self.assertAlmostEqual(mapped_value, expected, places=5)
# # tracer les results pour la probabilité par default # plt.bar(range(K), p_default) # plt.xlabel('Asset', size=15) # plt.ylabel('probability (%)', size=15) # plt.title('Individual Default Probabilities', size=20) # plt.xticks(range(K), size=15) # plt.yticks(size=15) # plt.grid() # plt.show() #partie 2 estimation de la perte en utilisant QAE print("calcul de VaR, Loss et CVar avec le QAE") print("----------estimation de Expected Loss ------------") # déterminer le nombre de qubits requis pour représenter la perte totale n_s = WeightedSumOperator.get_required_sum_qubits(lgd) # construire le circuit pour realiser la somme pondérée agg = WeightedSumOperator(n_z + K, [0] * n_z + lgd) # définition de la fonction Objective breakpoints = [0] slopes = [1] offsets = [0] f_min = 0 f_max = sum(lgd) c_approx = 0.25 objective = UnivariatePiecewiseLinearObjective( agg.num_sum_qubits, 0,