def test_lognormal(self, num_qubits, mu, sigma, bounds, upto_diag):
        """Test the statevector produced by ``LogNormalDistribution`` and the default arguments."""

        # construct default values and kwargs dictionary to call the constructor of
        # NormalDistribution. The kwargs dictionary is used to not pass any arguments which are
        # None to test the default values of the class.
        kwargs = {'num_qubits': num_qubits, 'upto_diag': upto_diag}

        if mu is None:
            mu = np.zeros(len(num_qubits)) if isinstance(num_qubits,
                                                         list) else 0
        else:
            kwargs['mu'] = mu

        if sigma is None:
            sigma = np.eye(len(num_qubits)).tolist() if isinstance(
                num_qubits, list) else 1
        else:
            kwargs['sigma'] = sigma

        if bounds is None:
            bounds = [
                (0, 1)
            ] * (len(num_qubits) if isinstance(num_qubits, list) else 1)
        else:
            kwargs['bounds'] = bounds

        normal = LogNormalDistribution(**kwargs)
        self.assertDistributionIsCorrect(normal, num_qubits, mu, sigma, bounds,
                                         upto_diag)
Exemple #2
0
    def test_application(self):
        """Test an end-to-end application."""
        try:
            from qiskit import Aer  # pylint: disable=unused-import,import-outside-toplevel
        except ImportError as ex:  # pylint: disable=broad-except
            self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(ex)))
            return

        num_qubits = 3

        # parameters for considered random distribution
        s_p = 2.0  # initial spot price
        vol = 0.4  # volatility of 40%
        r = 0.05  # annual interest rate of 4%
        t_m = 40 / 365  # 40 days to maturity

        # resulting parameters for log-normal distribution
        mu = ((r - 0.5 * vol ** 2) * t_m + np.log(s_p))
        sigma = vol * np.sqrt(t_m)
        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
        bounds = (low, high)

        # construct circuit factory for uncertainty model
        uncertainty_model = LogNormalDistribution(num_qubits,
                                                  mu=mu, sigma=sigma ** 2, bounds=bounds)

        # set the strike price (should be within the low and the high value of the uncertainty)
        strike_price = 1.896

        # create amplitude function
        european_call_delta = EuropeanCallDeltaObjective(num_state_qubits=num_qubits,
                                                         strike_price=strike_price,
                                                         bounds=bounds)

        # create state preparation
        state_preparation = european_call_delta.compose(uncertainty_model, front=True)

        problem = EstimationProblem(state_preparation=state_preparation,
                                    objective_qubits=[num_qubits],
                                    post_processing=european_call_delta.post_processing)

        # run amplitude estimation
        q_i = QuantumInstance(Aer.get_backend('qasm_simulator'),
                              seed_simulator=125, seed_transpiler=80)
        iae = IterativeAmplitudeEstimation(epsilon_target=0.01,
                                           alpha=0.05,
                                           quantum_instance=q_i)
        result = iae.estimate(problem)
        self.assertAlmostEqual(result.estimation_processed, 0.8079816552117238)
    def test_application(self):
        """Test an end-to-end application."""
        num_qubits = 3

        # parameters for considered random distribution
        s_p = 2.0  # initial spot price
        vol = 0.4  # volatility of 40%
        r = 0.05  # annual interest rate of 4%
        t_m = 40 / 365  # 40 days to maturity

        # resulting parameters for log-normal distribution
        mu = ((r - 0.5 * vol ** 2) * t_m + np.log(s_p))
        sigma = vol * np.sqrt(t_m)
        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
        bounds = (low, high)

        # construct circuit factory for uncertainty model
        uncertainty_model = LogNormalDistribution(num_qubits,
                                                  mu=mu, sigma=sigma ** 2, bounds=bounds)

        # set the strike price (should be within the low and the high value of the uncertainty)
        strike_price = 1.896

        # create amplitude function
        european_call_delta = EuropeanCallDelta(num_qubits, strike_price, bounds)

        # create state preparation
        state_preparation = european_call_delta.compose(uncertainty_model, front=True)

        # run amplitude estimation
        iae = IterativeAmplitudeEstimation(0.01, 0.05, state_preparation=state_preparation,
                                           objective_qubits=[num_qubits])

        backend = QuantumInstance(Aer.get_backend('qasm_simulator'),
                                  seed_simulator=125, seed_transpiler=80)
        result = iae.run(backend)
        self.assertAlmostEqual(result.estimation, 0.8088790606143996)