├── .github └── workflows │ ├── python-app.yml │ ├── release.yml │ └── sphinx_doc.yml ├── .gitignore ├── LICENSE ├── QQuantLib ├── AA │ ├── __init__.py │ └── amplitude_amplification.py ├── AE │ ├── __init__.py │ ├── ae_class.py │ ├── ae_classical_qpe.py │ ├── ae_iterative_quantum_pe.py │ ├── bayesian_ae.py │ ├── extended_real_quantum_ae.py │ ├── iterative_quantum_ae.py │ ├── maximum_likelihood_ae.py │ ├── mlae_utils.py │ ├── modified_iterative_quantum_ae.py │ ├── modified_real_quantum_ae.py │ ├── montecarlo_ae.py │ ├── real_quantum_ae.py │ └── shots_real_quantum_ae.py ├── DL │ ├── __init__.py │ ├── data_loading.py │ └── encoding_protocols.py ├── PE │ ├── __init__.py │ ├── classical_qpe.py │ ├── iterative_quantum_pe.py │ └── windows_pe.py ├── __init__.py ├── _test_my_lib.py ├── finance │ ├── __init__.py │ ├── ae_price_estimation.py │ ├── ae_price_estimation_step_payoff.py │ ├── classical_finance.py │ ├── cliquet_return_estimation.py │ ├── cliquet_return_estimation_step_payoff.py │ ├── payoff_class.py │ ├── probability_class.py │ └── quantum_integration.py ├── qml4var │ ├── __init__.py │ ├── adam.py │ ├── architectures.py │ ├── data_utils.py │ ├── losses.py │ ├── myqlm_workflows.py │ └── plugins.py ├── qpu │ ├── NoisyModels.ipynb │ ├── REAME.md │ ├── __init__.py │ ├── get_qpu.py │ ├── model_noise.py │ ├── noise_test_bank_functions.py │ ├── qpu_ideal.json │ ├── qpu_noisy.json │ └── select_qpu.py └── utils │ ├── __init__.py │ ├── benchmark_utils.py │ ├── data_extracting.py │ └── utils.py ├── README.md ├── benchmark ├── README.md ├── compare_ae_probability │ ├── CompareAEalgorithmsOnPureProbability.ipynb │ ├── jsons │ │ ├── ae_base_configuration.json │ │ ├── ae_configuration_bayesqae.json │ │ ├── ae_configuration_cqpeae.json │ │ ├── ae_configuration_erqae.json │ │ ├── ae_configuration_iqae.json │ │ ├── ae_configuration_miqae.json │ │ ├── ae_configuration_mlae.json │ │ ├── ae_configuration_mrqae.json │ │ ├── ae_configuration_rqae.json │ │ ├── ae_configuration_srqae.json │ │ ├── density_probability.json │ │ ├── domain_configuration.json │ │ ├── qpu_ideal.json │ │ └── qpu_noisy.json │ └── probability_estimation.py ├── q_ae_cliquet │ ├── QAE_CliquetOptions.ipynb │ ├── asset_configuration.json │ ├── bayesqae_configuration.json │ ├── benchmark_cliquet.py │ ├── benchmark_cliquet_step_po.py │ ├── cliquet_configuration.json │ ├── iqae_configuration.json │ ├── miqae_configuration.json │ ├── mrqae_configuration.json │ └── qpu_ideal.json ├── q_ae_price │ ├── Compare_AE_algorithms_On_PriceEstimation.ipynb │ ├── benchmark_ae_option_price.py │ ├── benchmark_ae_option_price_step_po.py │ └── jsons │ │ ├── ae_base_configuration.json │ │ ├── bayes_configuration.json │ │ ├── cqpeae_configuration.json │ │ ├── density_probability.json │ │ ├── domain_configuration.json │ │ ├── erqae_configuration.json │ │ ├── iqae_configuration.json │ │ ├── miqae_configuration.json │ │ ├── payoffs.json │ │ ├── qpu_ideal.json │ │ ├── qpu_noisy.json │ │ └── rqae_configuration.json ├── qml4var │ ├── JSONs │ │ ├── base_optimizer.json │ │ ├── base_pqc.json │ │ ├── bs.json │ │ ├── new_optimizer.json │ │ ├── new_pqc.json │ │ ├── qpu_ideal.json │ │ └── random.json │ ├── __init__.py │ ├── continue_training.py │ ├── data_sets.py │ ├── new_training.py │ ├── new_training_mse.py │ └── random │ │ └── data.json └── sine_integral │ ├── QAE_SineIntegration_WindowQPE.ipynb │ ├── jsons │ ├── qae_sine_bayes.json │ ├── qae_sine_cqpeae.json │ ├── qae_sine_iqae.json │ ├── qae_sine_mlae.json │ ├── qae_sine_pattern.json │ ├── qae_sine_rqae.json │ └── qpu_ideal.json │ └── qae_sine_integral.py ├── binder ├── apt.txt ├── environment.yml └── postBuild ├── doc ├── aa.amplitude_amplification.rst ├── aa.rst ├── ae.ae_class.rst ├── ae.ae_classical_qpe.rst ├── ae.ae_iterative_quantum_pe.rst ├── ae.bayesian_ae.rst ├── ae.ereal_quantum_ae.rst ├── ae.iterative_quantum_ae.rst ├── ae.maximum_likelihood_ae.rst ├── ae.miterative_quantum_ae.rst ├── ae.mlae_utils.rst ├── ae.montecarlo_ae.rst ├── ae.mreal_quantum_ae.rst ├── ae.real_quantum_ae.rst ├── ae.rst ├── ae.sreal_quantum_ae.rst ├── conf.py ├── dl.data_loading.rst ├── dl.encoding_protocols.rst ├── dl.rst ├── favicon.ico ├── finance.ae_price_estimation.rst ├── finance.ae_price_estimation_step_payoff.rst ├── finance.classical_finance.rst ├── finance.cliquet_return_estimation.rst ├── finance.cliquet_return_estimation_step_payoff.rst ├── finance.payoff_class.rst ├── finance.probability_class.rst ├── finance.quantum_integration.rst ├── finance.rst ├── index.rst ├── logo-neasqc.svg ├── pe.classical_qpe.rst ├── pe.iterative_quantum_pe.rst ├── pe.rst ├── qml4var.adam.rst ├── qml4var.architectures.rst ├── qml4var.data_utils.rst ├── qml4var.losses.rst ├── qml4var.myqlm_workflows.rst ├── qml4var.plugins.rst ├── qml4var.rst ├── qpu.get_qpu.rst ├── qpu.model_noise.rst ├── qpu.noise_test_bank_functions.rst ├── qpu.rst ├── qpu.select_qpu.rst ├── utils.benchmark_utils.rst ├── utils.data_extracting.rst ├── utils.rst └── utils.utils_utils.rst ├── environment.yml ├── misc ├── notebooks │ ├── 00_AboutTheNotebooksAndQPUs.ipynb │ ├── 01_Data_Loading_Module_Use.ipynb │ ├── 02_Amplitude_Amplification_Operators.ipynb │ ├── 03_Maximum_Likelihood_Amplitude_Estimation_Class.ipynb │ ├── 04-02_Classical_Phase_Estimation_Windows.ipynb │ ├── 04_Classical_Phase_Estimation_Class.ipynb │ ├── 05_Iterative_Quantum_Phase_Estimation_Class.ipynb │ ├── 06_Iterative_Quantum_Amplitude_Estimation_class.ipynb │ ├── 07-02_Improvements_on_Real_Quantum_Amplitude_Estimation.ipynb │ ├── 07_Real_Quantum_Amplitude_Estimation_class.ipynb │ ├── 08_AmplitudeEstimation_Class.ipynb │ ├── 09_DataEncodingClass.ipynb │ ├── 10_ApplicationTo_Finance_01_IntegralComputing.ipynb │ ├── 11_ApplicationTo_Finance_02_ClassicalFinance.ipynb │ ├── 12_ApplicationTo_Finance_03_AEPriceEstimation.ipynb │ ├── 13_Benchmark_utils.ipynb │ ├── 14_qml4var_Intro.ipynb │ ├── 15_qml4var_DataSets.ipynb │ ├── 16_qml4var_BuildPQC.ipynb │ ├── 17_qml4var_pqc_evaluation.ipynb │ ├── 18_qml4var_loss_computation.ipynb │ ├── 19_qml4var_training.ipynb │ ├── 20_PerformanceComparisons.ipynb │ ├── 21_VaR_computation.ipynb │ ├── 22_BayesianQuantumAmplitudeEstimation.ipynb │ ├── CliquetOptions.ipynb │ ├── README.md │ ├── images │ │ ├── Grover.svg │ │ ├── GroverGeometrico.png │ │ ├── OraculeReflection.png │ │ ├── Qiskit_IQPE.png │ │ ├── StateReflection.png │ │ ├── StateReflection.svg │ │ └── rqae.svg │ ├── other_staff │ │ ├── 01_Multi_Controlled_Gate_Decomposition.ipynb │ │ ├── 02_Multi_Controlled_Gate_Decomposition.ipynb │ │ ├── 03_ClasicalFinance.ipynb │ │ ├── 04_Encoding02_Demo.ipynb │ │ ├── CZ_multiplexor.png │ │ ├── Multiplexor_base.png │ │ └── Recursive_Multiplexor.png │ └── qml4var_data │ │ ├── 2024_10_04_BS_testing.csv │ │ ├── 2024_10_04_BS_training.csv │ │ ├── data.json │ │ ├── mse_loss_function.csv │ │ ├── optimizer_info.json │ │ ├── pqc.json │ │ └── qdml_loss_function.csv └── pylint.rc ├── setup.py └── tests ├── __test_my_lib.py ├── test_IQAE.py ├── test_RQAE.py ├── test_amplitude_amplification.py ├── test_classical_qpe.py ├── test_data_loading.py ├── test_iqpe.py └── test_maximum_likelihood.py /.github/workflows/python-app.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a single version of Python 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Python application 5 | 6 | on: 7 | push: 8 | paths-ignore: 9 | - 'doc/**' 10 | - '.github/**' 11 | workflow_call: 12 | 13 | jobs: 14 | build: 15 | 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: conda-incubator/setup-miniconda@v3 21 | with: 22 | mamba-version: "*" 23 | miniconda-version: "latest" 24 | environment-file: environment.yml 25 | auto-update-conda: true 26 | auto-activate-base: false 27 | activate-environment: myqlmdask 28 | #- name: Set up Python 3.12 29 | # uses: actions/setup-python@v4 30 | # with: 31 | # python-version: 3.12 32 | - shell: bash -el {0} 33 | run: | 34 | conda info 35 | #conda list 36 | # python -m pip install --upgrade pip 37 | # pip install flake8 pytest 38 | # #if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 39 | - name: Lint with flake8 40 | shell: bash -el {0} 41 | run: | 42 | # stop the build if there are Python syntax errors or undefined names 43 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 44 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 45 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 46 | - name: Test with pytest 47 | shell: bash -el {0} 48 | run: | 49 | python -m pytest 50 | #pytest 51 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # This pipeline is designed to create a wheel and publich the wheel on 2 | # GitHub 3 | 4 | # Execute pipeline only on a new tag, if the tag 5 | # if named "v*" (e.g. v1.0) 6 | on: 7 | push: 8 | tags: 9 | - 'v*' 10 | 11 | 12 | # Pipeline name 13 | name: Create new release 14 | 15 | 16 | # Run pipeline 17 | jobs: 18 | build: 19 | name: Build package 20 | uses: ./.github/workflows/python-app.yml 21 | deploy: 22 | name: Deploy package 23 | runs-on: ubuntu-latest 24 | needs: [build] 25 | steps: 26 | - name: Checkout repository 27 | uses: actions/checkout@v2 28 | - name: Set up Python 3.9 29 | uses: actions/setup-python@v2 30 | with: 31 | python-version: 3.9 32 | - name: Install dependencies 33 | run: | 34 | python -m pip install --upgrade pip 35 | python3 -m pip install build 36 | - name: Compute release version 37 | run: | 38 | TAG=${{ github.ref }} 39 | echo "VERSION=${TAG#refs/tags/v}" >> $GITHUB_ENV 40 | echo "The release version if ${TAG#refs/tags/v}" 41 | - name: Create wheel 42 | env: 43 | TAG_NAME: ${{ env.VERSION }} 44 | run: python -m build 45 | - name: Create release 46 | id: create_release 47 | uses: actions/create-release@v1 48 | env: 49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 50 | with: 51 | tag_name: ${{ env.VERSION }} 52 | draft: false 53 | prerelease: false 54 | - name: Upload release assets 55 | uses: actions/upload-release-asset@v1 56 | env: 57 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 58 | with: 59 | upload_url: ${{ steps.create_release.outputs.upload_url }} 60 | asset_path: ./dist/FinancialApplications-${{ env.VERSION }}-py3-none-any.whl 61 | asset_name: FinancialApplications-${{ env.VERSION }}-py3-none-any.whl 62 | asset_content_type: application/x-wheel+zip 63 | -------------------------------------------------------------------------------- /.github/workflows/sphinx_doc.yml: -------------------------------------------------------------------------------- 1 | name: Sphinx Build 2 | 3 | # Controls when the workflow will run 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the main branch 6 | push: 7 | paths: 'doc/**' 8 | 9 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 10 | jobs: 11 | # This workflow contains a single job called "build" 12 | build: 13 | # The type of runner that the job will run on 14 | runs-on: ubuntu-latest 15 | 16 | # Steps represent a sequence of tasks that will be executed as part of the job 17 | steps: 18 | #Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 19 | - uses: actions/checkout@v4 20 | 21 | # - name: Sphinx Build 22 | # #You may pin to the exact commit or the version. 23 | # uses: ammaraskar/sphinx-action@master 24 | # with: 25 | # # The folder containing your sphinx docs. 26 | # docs-folder: 'doc/' # default is docs/ 27 | # # The command used to build your documentation. 28 | # build-command: 'sphinx-build -b html . _build ' # optional, default is make html 29 | # # Run before the build command, you can use this to install system level dependencies, for example with "apt-get update -y && apt-get install -y perl" 30 | # pre-build-command: 'python -m pip install sphinx_rtd_theme nbsphinx sphinxcontrib.bibtex sphinxcontrib.programoutput sphinxcontrib.contentui autodoc MarkupSafe==2.0.1' 31 | 32 | - name: Build Python 33 | uses: actions/setup-python@v3 34 | with: 35 | python-version: '3.10' 36 | 37 | - name: Install 38 | run: pip install sphinx_rtd_theme nbsphinx sphinxcontrib.bibtex sphinxcontrib.programoutput sphinxcontrib.contentui autodoc MarkupSafe==2.0.1 39 | 40 | - name: Build 41 | run: | 42 | cd doc 43 | sphinx-build -b html . _build 44 | 45 | - name: Upload a Build Artifact 46 | uses: actions/upload-artifact@v4 47 | with: 48 | name: 'html.zip' 49 | path: 'doc/_build/' 50 | 51 | - name: Checkout neasqc.github.io 52 | uses: actions/checkout@v4 53 | with: 54 | ref: main 55 | persist-credentials: true 56 | fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. 57 | repository: NEASQC/neasqc.github.io 58 | path: "neasqc" 59 | token: ${{ secrets.ACTION_TOKEN }} 60 | 61 | - name: Create local changes 62 | run: | 63 | mkdir -p neasqc/FinancialApplications #Replace test with repo name 64 | rm -rf neasqc/FinancialApplications/* #Replace test with repo name 65 | cp -r doc/_build/* neasqc/FinancialApplications #Replace test with repo name 66 | cd neasqc 67 | git config --local user.email "action@github.com" 68 | git config --local user.name "GitHub Action" 69 | git add . 70 | git commit -m "Update documentation from github actions" || true 71 | - name: Push changes 72 | uses: ad-m/github-push-action@master 73 | with: 74 | branch: main 75 | directory: neasqc 76 | repository: NEASQC/neasqc.github.io 77 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.out 3 | .ipynb_checkpoints/ 4 | *.swp 5 | *.csv 6 | *_untracked* 7 | __pycache__/ 8 | __*__/ 9 | .eggs/ 10 | *.egg-info/ 11 | Results/ 12 | -------------------------------------------------------------------------------- /QQuantLib/AA/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/QQuantLib/AA/__init__.py -------------------------------------------------------------------------------- /QQuantLib/AE/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/QQuantLib/AE/__init__.py -------------------------------------------------------------------------------- /QQuantLib/AE/ae_iterative_quantum_pe.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains necessary functions and classes to implement amplitude 3 | estimation algorithm using Iterative Quantum Phase Estimation (IQPE). 4 | The implementation is based on following paper: 5 | 6 | *Dobšíček, Miroslav and Johansson, Göran and Shumeiko, Vitaly and 7 | Wendin, Göran*. 8 | Arbitrary accuracy iterative quantum phase estimation algorithm 9 | using a single ancillary qubit: A two-qubit benchmark. 10 | Physical Review A 3(76), 2007. 11 | https://arxiv.org/abs/quant-ph/0610214* 12 | 13 | Author: Gonzalo Ferro Costas & Alberto Manzano Herrero 14 | 15 | """ 16 | 17 | import time 18 | #from copy import deepcopy 19 | import numpy as np 20 | import qat.lang.AQASM as qlm 21 | from QQuantLib.qpu.get_qpu import get_qpu 22 | from QQuantLib.PE.iterative_quantum_pe import IQPE 23 | from QQuantLib.AA.amplitude_amplification import grover 24 | from QQuantLib.utils.utils import check_list_type 25 | 26 | 27 | class IQPEAE: 28 | """ 29 | Class for using Iterative Quantum Phase Estimation (IQPE) class for 30 | doing Amplitude Estimation (AE) 31 | 32 | Parameters 33 | ---------- 34 | oracle: QLM gate 35 | QLM gate with the Oracle for implementing the 36 | Grover operator 37 | target : list of ints 38 | python list with the target for the amplitude estimation 39 | index : list of ints 40 | qubits which mark the register to do the amplitude 41 | estimation 42 | 43 | kwars : dictionary 44 | dictionary that allows the configuration of the IQPEAE algorithm: \\ 45 | Implemented keys: 46 | 47 | qpu : kwargs, QLM solver 48 | solver for simulating the resulting circutis 49 | shots : kwargs, int 50 | number of measurements 51 | mcz_qlm : kwargs, bool 52 | for using or not QLM implementation of the multi controlled Z 53 | gate 54 | """ 55 | 56 | def __init__(self, oracle: qlm.QRoutine, target: list, index: list, **kwargs): 57 | """ 58 | 59 | Method for initializing the class 60 | 61 | """ 62 | # Setting attributes 63 | self._oracle = oracle 64 | self._target = check_list_type(target, int) 65 | self._index = check_list_type(index, int) 66 | 67 | # Set the QPU to use 68 | self.linalg_qpu = kwargs.get("qpu", None) 69 | if self.linalg_qpu is None: 70 | print("Not QPU was provide. PyLinalg will be used") 71 | self.linalg_qpu = get_qpu("python") 72 | 73 | self.cbits_number = kwargs.get("cbits_number", 8) 74 | self.shots = int(kwargs.get("shots", 100)) 75 | self.mcz_qlm = kwargs.get("mcz_qlm", True) 76 | # First thing is create the grover operator from the oracle 77 | self._grover_oracle = grover( 78 | self.oracle, self.target, self.index, mcz_qlm=self.mcz_qlm 79 | ) 80 | 81 | # For storing results 82 | self.ae_l = None 83 | self.ae_u = None 84 | self.theta = None 85 | self.ae = None 86 | self.iqpe_object = None 87 | self.final_results = None 88 | self.circuit_statistics = None 89 | self.run_time = None 90 | self.oracle_calls = None 91 | self.max_oracle_depth = None 92 | self.schedule_pdf = None 93 | self.quantum_times = [] 94 | self.quantum_time = None 95 | 96 | ##################################################################### 97 | @property 98 | def oracle(self): 99 | """ 100 | creating oracle property 101 | """ 102 | return self._oracle 103 | 104 | @oracle.setter 105 | def oracle(self, value): 106 | """ 107 | setter of the oracle property 108 | """ 109 | self._oracle = value 110 | self._grover_oracle = grover( 111 | self.oracle, self.target, self.index, mcz_qlm=self.mcz_qlm 112 | ) 113 | 114 | @property 115 | def target(self): 116 | """ 117 | creating target property 118 | """ 119 | return self._target 120 | 121 | @target.setter 122 | def target(self, value): 123 | """ 124 | setter of the target property 125 | """ 126 | self._target = check_list_type(value, int) 127 | self._grover_oracle = grover( 128 | self.oracle, self.target, self.index, mcz_qlm=self.mcz_qlm 129 | ) 130 | 131 | @property 132 | def index(self): 133 | """ 134 | creating index property 135 | """ 136 | return self._index 137 | 138 | @index.setter 139 | def index(self, value): 140 | """ 141 | setter of the index property 142 | """ 143 | self._index = check_list_type(value, int) 144 | self._grover_oracle = grover( 145 | self.oracle, self.target, self.index, mcz_qlm=self.mcz_qlm 146 | ) 147 | 148 | ##################################################################### 149 | 150 | def run(self): 151 | r""" 152 | run method for the class. 153 | 154 | Parameters 155 | ---------- 156 | 157 | Returns 158 | ---------- 159 | 160 | result : 161 | the estimation of a 162 | 163 | Notes 164 | ----- 165 | .. math:: 166 | a = \cos^2(\theta) 167 | 168 | Where :math:`\theta` is: 169 | 170 | .. math:: 171 | \mathcal{Q}|\Psi\rangle = e^{2i\theta}|\Psi\rangle 172 | 173 | And :math:`\mathcal{Q}` the Grover Operator 174 | """ 175 | 176 | start = time.time() 177 | self.circuit_statistics = {} 178 | dict_ae_iqpe = { 179 | "initial_state": self.oracle, 180 | "unitary_operator": self._grover_oracle, 181 | "cbits_number": self.cbits_number, 182 | "shots": self.shots, 183 | "qpu": self.linalg_qpu, 184 | } 185 | 186 | # Create object IQPE class from Amplitude Estimation inputs 187 | self.iqpe_object = IQPE(**dict_ae_iqpe) 188 | # Execute IQPE algorithm 189 | self.iqpe_object.iqpe() 190 | step_circuit_stats = self.iqpe_object.circuit.statistics() 191 | step_circuit_stats.update({"n_shots": self.shots}) 192 | self.circuit_statistics = {"IQPEAE": step_circuit_stats} 193 | self.final_results = self.iqpe_object.final_results 194 | self.theta = self.final_results["theta_90"].iloc[0] 195 | self.ae = np.cos(self.theta) ** 2 196 | end = time.time() 197 | self.run_time = end - start 198 | #Total number of oracle calls 199 | self.oracle_calls = self.shots * np.sum( 200 | [2 * (2 ** i ) + 1 for i in range(self.cbits_number)] 201 | ) 202 | #Maximum number of oracle applications 203 | self.max_oracle_depth = 2 ** (int(self.cbits_number)-1) + 1 204 | self.quantum_times = self.iqpe_object.quantum_times 205 | self.quantum_time = sum(self.iqpe_object.quantum_times) 206 | return self.ae 207 | -------------------------------------------------------------------------------- /QQuantLib/AE/mlae_utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains mandatory functions used by the MLAE class 3 | 4 | Author: Gonzalo Ferro Costas & Alberto Manzano Herrero 5 | 6 | """ 7 | 8 | import numpy as np 9 | 10 | 11 | def likelihood(theta: float, m_k: int, n_k: int, h_k: int) -> float: 12 | r""" 13 | Calculates Likelihood from Suzuki paper. For h_k positive events 14 | of n_k total events, this function calculates the probability of 15 | this taking into account that the probability of a positive 16 | event is given by theta and by m_k 17 | The idea is use this function to minimize it for this reason it gives 18 | minus Likelihood 19 | 20 | Notes 21 | ----- 22 | .. math:: 23 | l_k(\theta|h_k) = \sin^2\left((2m_k+1)\theta\right)^{h_k} \ 24 | \cos^2 \left((2m_k+1)\theta\right)^{n_k-h_k} 25 | 26 | Parameters 27 | ---------- 28 | 29 | theta : float 30 | Angle (radians) for calculating the probability of measure a 31 | positive event. 32 | m_k : int 33 | number of times the grover operator was applied. 34 | n_k : int 35 | number of total events measured for the specific m_k 36 | h_k : int 37 | number of positive events measured for each m_k 38 | 39 | Returns 40 | ---------- 41 | 42 | float 43 | Gives the Likelihood p(h_k with m_k amplifications|theta) 44 | 45 | """ 46 | theta_ = (2 * m_k + 1) * theta 47 | p_0 = np.sin(theta_) ** 2 48 | p_1 = np.cos(theta_) ** 2 49 | l_k = (p_0**h_k) * (p_1 ** (n_k - h_k)) 50 | return l_k 51 | 52 | def log_likelihood(theta: float, m_k: int, n_k: int, h_k: int) -> float: 53 | r""" 54 | Calculates log of the likelihood from Suzuki paper. 55 | 56 | Notes 57 | ----- 58 | .. math:: 59 | \log{l_k(\theta|h_k)} = 2h_k\log\big[\sin\left((2m_k+1) \ 60 | \theta\right)\big] +2(n_k-h_k)\log\big[\cos\left((2m_k+1) \ 61 | \theta\right)\big] 62 | 63 | Parameters 64 | ---------- 65 | 66 | theta : float 67 | Angle (radians) for calculating the probability of measure a 68 | positive event. 69 | m_k : int 70 | number of times the grover operator was applied. 71 | n_k : int 72 | number of total events measured for the specific m_k 73 | h_k : int 74 | number of positive events measured for each m_k 75 | 76 | Returns 77 | ---------- 78 | 79 | float 80 | Gives the log Likelihood p(h_k with m_k amplifications|theta) 81 | 82 | """ 83 | theta_ = (2 * m_k + 1) * theta 84 | p_0 = np.sin(theta_) ** 2 85 | p_1 = np.cos(theta_) ** 2 86 | l_k = h_k * np.log(p_0) + (n_k - h_k) * np.log(p_1) 87 | return l_k 88 | 89 | 90 | def cost_function(angle: float, m_k: list, n_k: list, h_k: list) -> float: 91 | r""" 92 | This method calculates the -Likelihood of angle theta 93 | for a given schedule m_k,n_k 94 | 95 | Notes 96 | ----- 97 | .. math:: 98 | L(\theta,\mathbf{h}) = -\sum_{k = 0}^M\log{l_k(\theta|h_k)} 99 | 100 | Parameters 101 | ---------- 102 | 103 | angle: float 104 | Angle (radians) for calculating the probability of measure a 105 | positive event. 106 | m_k : list of ints 107 | number of times the grover operator was applied. 108 | n_k : list of ints 109 | number of total events measured for the specific m_k 110 | h_k : list of ints 111 | number of positive events measured for each m_k 112 | 113 | Returns 114 | ---------- 115 | 116 | cost : float 117 | the aggregation of the individual likelihoods 118 | """ 119 | log_cost = 0 120 | # for i in range(len(m_k)): 121 | for i, _ in enumerate(m_k): 122 | log_l_k = log_likelihood(angle, m_k[i], n_k[i], h_k[i]) 123 | log_cost = log_cost + log_l_k 124 | return -log_cost 125 | -------------------------------------------------------------------------------- /QQuantLib/AE/montecarlo_ae.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains the necessary functions and classes to implement a 3 | Monte-Carlo Amplitude Estimation routine. Given a quantum oracle operator, 4 | the amplitude of a given target state is estimated by evaluating it. 5 | Grover-like operators are not used in this routine. 6 | 7 | 8 | Author: Gonzalo Ferro Costas & Alberto Manzano Herrero 9 | 10 | """ 11 | 12 | import time 13 | #from copy import deepcopy 14 | import numpy as np 15 | import pandas as pd 16 | import qat.lang.AQASM as qlm 17 | from QQuantLib.qpu.get_qpu import get_qpu 18 | from QQuantLib.utils.data_extracting import get_results 19 | from QQuantLib.utils.utils import check_list_type, measure_state_probability 20 | 21 | 22 | class MCAE: 23 | """ 24 | Class for MonteCarlo Amplitude Estimation (MCAE). 25 | 26 | Parameters 27 | ---------- 28 | oracle: QLM gate 29 | QLM gate with the Oracle for implementing the 30 | Grover operator 31 | target : list of ints 32 | python list with the target for the amplitude estimation 33 | index : list of ints 34 | qubits which mark the register to do the amplitude 35 | estimation 36 | 37 | kwargs : dictionary 38 | dictionary that allows the configuration of the IQAE algorithm: \\ 39 | Implemented keys: 40 | 41 | qpu : kwargs, QLM solver 42 | solver for simulating the resulting circuits 43 | shots : kwargs, int 44 | number of measurements 45 | mcz_qlm : kwargs, bool 46 | for using or not QLM implementation of the multi controlled Z 47 | gate 48 | """ 49 | 50 | def __init__(self, oracle: qlm.QRoutine, target: list, index: list, **kwargs): 51 | """ 52 | 53 | Method for initializing the class 54 | """ 55 | # Setting attributes 56 | self._oracle = oracle 57 | self._target = check_list_type(target, int) 58 | self._index = check_list_type(index, int) 59 | 60 | # Set the QPU to use 61 | self.linalg_qpu = kwargs.get("qpu", None) 62 | if self.linalg_qpu is None: 63 | print("Not QPU was provide. PyLinalg will be used") 64 | self.linalg_qpu = get_qpu("python") 65 | 66 | self.shots = int(kwargs.get("shots", 100)) 67 | self.mcz_qlm = kwargs.get("mcz_qlm", True) 68 | 69 | self.ae_l = None 70 | self.ae_u = None 71 | self.theta_l = None 72 | self.theta_u = None 73 | self.theta = None 74 | self.ae = None 75 | self.circuit_statistics = None 76 | self.time_pdf = None 77 | self.run_time = None 78 | self.schedule = {} 79 | self.oracle_calls = None 80 | self.max_oracle_depth = None 81 | self.schedule_pdf = None 82 | self.quantum_times = [] 83 | self.quantum_time = None 84 | 85 | ##################################################################### 86 | @property 87 | def oracle(self): 88 | """ 89 | creating oracle property 90 | """ 91 | return self._oracle 92 | 93 | @oracle.setter 94 | def oracle(self, value): 95 | """ 96 | setter of the oracle property 97 | """ 98 | self._oracle = value 99 | 100 | @property 101 | def target(self): 102 | """ 103 | creating target property 104 | """ 105 | return self._target 106 | 107 | @target.setter 108 | def target(self, value): 109 | """ 110 | setter of the target property 111 | """ 112 | self._target = check_list_type(value, int) 113 | 114 | @property 115 | def index(self): 116 | """ 117 | creating index property 118 | """ 119 | return self._index 120 | 121 | @index.setter 122 | def index(self, value): 123 | """ 124 | setter of the index property 125 | """ 126 | self._index = check_list_type(value, int) 127 | 128 | ##################################################################### 129 | 130 | def run(self): 131 | r""" 132 | run method for the class. 133 | 134 | Returns 135 | ---------- 136 | 137 | self.ae : 138 | amplitude estimation parameter 139 | 140 | """ 141 | 142 | #Done Measurements on the oracle 143 | start = time.time() 144 | results, circuit, _, _ = get_results( 145 | self.oracle, 146 | linalg_qpu=self.linalg_qpu, 147 | shots=self.shots, 148 | qubits=self.index 149 | ) 150 | end = time.time() 151 | self.quantum_times.append(end-start) 152 | self.ae = measure_state_probability(results, self.target) 153 | self.ae_l = max(0.0, self.ae - 2.0 / np.sqrt(float(self.shots))) 154 | self.ae_u = min(1.0, self.ae + 2.0 / np.sqrt(float(self.shots))) 155 | self.run_time = end - start 156 | self.schedule_pdf = pd.DataFrame( 157 | [[0, self.shots]], 158 | columns=['m_k', 'shots'] 159 | ) 160 | self.oracle_calls = np.sum( 161 | self.schedule_pdf['shots'] * (2 * self.schedule_pdf['m_k'] + 1)) 162 | self.max_oracle_depth = np.max(2 * self.schedule_pdf['m_k']+ 1) 163 | self.quantum_time = sum(self.quantum_times) 164 | return self.ae 165 | -------------------------------------------------------------------------------- /QQuantLib/DL/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/QQuantLib/DL/__init__.py -------------------------------------------------------------------------------- /QQuantLib/PE/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/QQuantLib/PE/__init__.py -------------------------------------------------------------------------------- /QQuantLib/PE/windows_pe.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains different window functions. Based on: 3 | Effects of cosine tapering window on quantum phase estimation. 4 | Rendon, Gumaro and Izubuchi, Taku and Kikuchi, Yuta 5 | Phys. Rev. D, 106. 2022 6 | Author: Gonzalo Ferro Costas 7 | """ 8 | 9 | import numpy as np 10 | import pandas as pd 11 | from scipy.special import i0 12 | import qat.lang.AQASM as qlm 13 | from QQuantLib.DL.data_loading import load_probability 14 | 15 | @qlm.build_gate("cosinewindow", [int], arity=lambda x: x) 16 | def cosine_window(number_qubits: int): 17 | """ 18 | Creates a QLM AbstractGate for loading a Cosine Window Function 19 | into a quantum state. 20 | 21 | Parameters 22 | ---------- 23 | number_qubits : int 24 | Number of qubits for the quantum AbstractGate 25 | 26 | Return 27 | ---------- 28 | 29 | window_state: AbstractGate 30 | AbstractGate for loading a cosine 31 | """ 32 | 33 | window_state = qlm.QRoutine() 34 | q_bits = window_state.new_wires(number_qubits) 35 | window_state.apply(qlm.H, q_bits[-1]) 36 | window_state.apply( 37 | qlm.qftarith.QFT(number_qubits), 38 | q_bits 39 | ) 40 | for i, qb in enumerate(q_bits[:-1]): 41 | window_state.apply(qlm.PH(-np.pi * 2 ** i / 2**number_qubits), qb) 42 | window_state.apply( 43 | qlm.PH(np.pi * (2 ** (number_qubits -1)) / 2 ** number_qubits), 44 | q_bits[-1] 45 | ) 46 | #window_state.apply(qlm.X, q_bits[0]) 47 | return window_state 48 | 49 | @qlm.build_gate("sinewindow", [int], arity=lambda x: x) 50 | def sine_window(number_qubits: int): 51 | """ 52 | Creates a QLM AbstractGate for loading a Sine Window Function 53 | into a quantum state. 54 | 55 | Parameters 56 | ---------- 57 | number_qubits : int 58 | Number of qubits for the quantum AbstractGate 59 | 60 | Return 61 | ---------- 62 | 63 | window_state: AbstractGate 64 | AbstractGate for loading a sine 65 | """ 66 | window_state = qlm.QRoutine() 67 | q_bits = window_state.new_wires(number_qubits) 68 | window_state.apply(qlm.H, q_bits[-1]) 69 | window_state.apply( 70 | qlm.qftarith.QFT(number_qubits), 71 | q_bits 72 | ) 73 | for i, qb in enumerate(q_bits[:-1]): 74 | window_state.apply(qlm.PH(-np.pi * 2 ** i / 2**number_qubits), qb) 75 | window_state.apply( 76 | qlm.PH(np.pi * (2 ** (number_qubits -1)) / 2 ** number_qubits), 77 | q_bits[-1] 78 | ) 79 | window_state.apply(qlm.X, q_bits[-1]) 80 | return window_state 81 | 82 | def kaiser_array(number_qubits, alpha=1.0e-5): 83 | """ 84 | Creates the probability discretization of a Kaiser window function 85 | for a given input of number of qubits and a alpha 86 | Parameters 87 | ---------- 88 | number_qubits : int 89 | Number of qubits for building the Kaiser window function 90 | alpha : float 91 | Parameter for modified Bessel function or order 0. 92 | 93 | Return 94 | ---------- 95 | 96 | pdf: pandas DataFrame 97 | pandas DF with the probability discretization of the Kaiser 98 | window function 99 | """ 100 | # Integer domain: 101 | domain_int = np.array(range(-2**(number_qubits-1), 2**(number_qubits-1))) 102 | x_ = domain_int / 2 ** (number_qubits-1) 103 | x_ = np.sqrt(1 - x_ ** 2) 104 | y_ = i0(np.pi * alpha * x_) / i0(np.pi * alpha) 105 | y_ = y_ / 2 ** number_qubits 106 | y_ = y_ ** 2 107 | # Final Probability to load 108 | y_final = y_ / np.sum(y_) 109 | pdf = pd.DataFrame([domain_int, y_final]).T 110 | pdf.rename(columns={0: "Int_neg", 1: "Prob"}, inplace=True) 111 | # Change to positive integers 112 | pdf["Int"] = np.where( 113 | pdf["Int_neg"] < 0, 114 | 2 ** number_qubits + pdf["Int_neg"], 115 | pdf["Int_neg"] 116 | ) 117 | # Sort by positive integers 118 | pdf.sort_values(["Int"], inplace=True) 119 | pdf.reset_index(drop=True, inplace=True) 120 | return pdf 121 | 122 | def kaiser_window(number_qubits, alpha=1.0e-5): 123 | """ 124 | Creates a QLM AbstractGate for loading a Kaiser Window Function 125 | into a quantum state. Uses load_probability function for loading 126 | the discretization of the probability of the Kaiser window function. 127 | 128 | Parameters 129 | ---------- 130 | number_qubits : int 131 | Number of qubits for the quantum AbstractGate 132 | alpha : float 133 | Parameter for modified Bessel function or order 0. 134 | 135 | Return 136 | ---------- 137 | 138 | kaiser_state: AbstractGate 139 | AbstractGate for loading a Kaiser Window 140 | """ 141 | pdf = kaiser_array(number_qubits, alpha=alpha) 142 | kaiser_state = load_probability(pdf["Prob"], id_name="KaiserWindow") 143 | return kaiser_state 144 | 145 | def window_selector(window_type, **kwargs): 146 | """ 147 | Selector funcion for window functions 148 | 149 | Parameters 150 | ---------- 151 | window_type : str 152 | String with the desired Window function 153 | kwargs : keyword arguments 154 | Keyword arguments for configuring window functions. Mandatory: 155 | auxiliar_qbits_number : kwargs, int 156 | Number of auxilary qubits for QFT 157 | kaiser_alpha : kwargs, float 158 | alpha for the Kaiser window 159 | 160 | Return 161 | ---------- 162 | 163 | window gate: AbstractGate 164 | AbstractGate with the desired window function 165 | last_control_change : Bool 166 | last_control_change value 167 | """ 168 | number_qubits = kwargs.get("auxiliar_qbits_number", None) 169 | if number_qubits is None: 170 | raise ValueError("auxiliar_qbits_number is None") 171 | 172 | if window_type in ["Cosine", "cosine", "cos"]: 173 | return cosine_window(number_qubits), True 174 | elif window_type in ["Sine", "sine", "sin"]: 175 | return sine_window(number_qubits), False 176 | elif window_type in ["Kaiser", "kaiser", "kais"]: 177 | kaiser_alpha = kwargs.get("kaiser_alpha", None) 178 | if kaiser_alpha is None: 179 | raise ValueError("kaiser_alpha not provided") 180 | return kaiser_window(number_qubits, kaiser_alpha), True 181 | else: 182 | raise ValueError( 183 | "Incorrect window_type provided. Only valid \ 184 | [Cosine, cosine, cos] for cosine window, \ 185 | [Sine,sine, sin] for sine window \ 186 | [Kaiser, kaiser, kais] for Kaiser window" 187 | ) 188 | -------------------------------------------------------------------------------- /QQuantLib/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding : utf-8 -*- 2 | 3 | """ 4 | Modules have doctrings! 5 | """ 6 | 7 | 8 | def some_function(some_integer): 9 | """ 10 | Functions have docstrings. 11 | 12 | Variable and functions are named in snake case 13 | """ 14 | return 2 * some_integer 15 | 16 | 17 | class MyClass: 18 | """ 19 | Classes have docstrings. 20 | Classes are named in camel case. 21 | """ 22 | 23 | def __init__(self, *args): 24 | pass 25 | -------------------------------------------------------------------------------- /QQuantLib/_test_my_lib.py: -------------------------------------------------------------------------------- 1 | # -*- coding : utf-8 -*- 2 | 3 | """ 4 | Test for this module 5 | """ 6 | 7 | 8 | from . import some_function, MyClass 9 | 10 | 11 | class TestMyClass: 12 | """ 13 | Testing MyClass 14 | """ 15 | 16 | def test_instantiation(self): 17 | # pylint: disable=no-self-use 18 | """ 19 | Testing the constructor 20 | """ 21 | MyClass(1, 1, 2) 22 | MyClass() 23 | 24 | 25 | def test_some_fucntion(): 26 | """ 27 | Testing some_function 28 | """ 29 | assert 4 == some_function(2) 30 | -------------------------------------------------------------------------------- /QQuantLib/finance/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/QQuantLib/finance/__init__.py -------------------------------------------------------------------------------- /QQuantLib/finance/ae_price_estimation.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module implements the *ae_price_estimation* function that allows to 3 | the user configure a price estimation problem using financial parameters, 4 | encode the expected value integral to compute in a quantum state and 5 | estimate it using the different **AE** algorithms implemented in the 6 | **QQuantLib.AE** package. 7 | 8 | This function uses the DensityProbability and the PayOff classes (from 9 | *finance.probability_class* and *finance.payoff_class* modules 10 | respectively) for defining the option price estimation problem. 11 | Then the q_solve_integral function (from *finance.quantum_integration* 12 | module) is used for computing the expected value integral. 13 | 14 | The function deals with all the mandatory normalisations for returning 15 | the desired price estimation. 16 | 17 | Authors: Alberto Pedro Manzano Herrero & Gonzalo Ferro Costas 18 | """ 19 | 20 | import sys 21 | import numpy as np 22 | import pandas as pd 23 | from QQuantLib.finance.probability_class import DensityProbability 24 | from QQuantLib.finance.payoff_class import PayOff 25 | from QQuantLib.finance.quantum_integration import q_solve_integral 26 | 27 | 28 | def ae_price_estimation(**kwargs): 29 | """ 30 | Configures an option price estimation problem and solving it using 31 | AE integration techniques 32 | 33 | Parameters 34 | ---------- 35 | 36 | kwargs : dictionary. 37 | Dictionary for configuring the price estimation problem, the 38 | encoding of the price estimation data into the quantum circuit 39 | and the AE integration technique for solving it. 40 | 41 | Note 42 | ____ 43 | 44 | The keys for the input kwargs dictionary will be the necessary keys 45 | for configuring the DensityProbability class \\ 46 | (see QQuantLib.finance.probability_class), the PayOff class \\ 47 | (see QQuantLib.finance.payoff_class) and the q_solve_integral \\ 48 | function (see QQuantLib.finance.quantum_integration). 49 | 50 | Returns 51 | _______ 52 | 53 | pdf : Pandas DataFrame 54 | DataFrame with the configuration of the AE problem and the solution 55 | """ 56 | 57 | ae_problem = kwargs 58 | #Building the domain 59 | n_qbits = ae_problem.get("n_qbits", None) 60 | x0 = ae_problem.get("x0", 1.0) 61 | xf = ae_problem.get("xf", 3.0) 62 | domain = np.linspace(x0, xf, 2**n_qbits) 63 | 64 | #Building the Probability distribution 65 | pc = DensityProbability(**ae_problem) 66 | p_x = pc.probability(domain) 67 | #Normalisation of the probability distribution 68 | p_x_normalisation = np.sum(p_x) + 1e-8 69 | norm_p_x = p_x / p_x_normalisation 70 | 71 | #Building the option payoff 72 | po = PayOff(**ae_problem) 73 | pay_off = po.pay_off(domain) 74 | #Normalisation of the pay off 75 | pay_off_normalisation = np.max(np.abs(pay_off)) + 1e-8 76 | norm_pay_off = pay_off / pay_off_normalisation 77 | 78 | #Getting the exact price of the option under BS 79 | exact_solution = None 80 | if po.pay_off_bs is not None: 81 | exact_solution = po.pay_off_bs(**ae_problem) 82 | 83 | #Now we update the input dictionary with the probability and the 84 | #function arrays 85 | ae_problem.update({ 86 | "array_function" : norm_pay_off, 87 | "array_probability" : norm_p_x, 88 | }) 89 | 90 | #EXECUTE COMPUTATION 91 | solution, solver_object = q_solve_integral(**ae_problem) 92 | 93 | #For generating the output DataFrame we delete the arrays 94 | del ae_problem["array_function"] 95 | del ae_problem["array_probability"] 96 | 97 | #Undoing the normalisations 98 | ae_expectation = solution * pay_off_normalisation * p_x_normalisation 99 | 100 | #Creating the output DataFrame with the complete information 101 | 102 | #The basis will be the input python dictionary for traceability 103 | pdf = pd.DataFrame([ae_problem]) 104 | #Added normalisation constants 105 | pdf["payoff_normalisation"] = pay_off_normalisation 106 | pdf["p_x_normalisation"] = p_x_normalisation 107 | 108 | #Expectation calculation using Riemann sum 109 | pdf["riemann_expectation"] = np.sum(p_x * pay_off) 110 | #Expectation calculation using AE integration techniques 111 | pdf[ 112 | [col + "_expectation" for col in ae_expectation.columns] 113 | ] = ae_expectation 114 | # Pure integration Absolute Error 115 | pdf["absolute_error"] = np.abs( 116 | pdf["ae_expectation"] - pdf["riemann_expectation"]) 117 | pdf["measured_epsilon"] = np.abs( 118 | pdf["ae_u_expectation"] - pdf["ae_l_expectation"]) / 2.0 119 | # Finance Info 120 | #Exact option price under the Black-Scholes model 121 | pdf["finance_exact_price"] = exact_solution 122 | #Option price estimation using expectation computed as Riemann sum 123 | pdf["finance_riemann_price"] = pdf["riemann_expectation"] * np.exp( 124 | -pdf["risk_free_rate"] * pdf["maturity"] 125 | ) 126 | #Option price estimation using expectation computed by AE integration 127 | pdf["finance_price_estimation"] = pdf["ae_expectation"] * \ 128 | np.exp(-pdf["risk_free_rate"] * pdf["maturity"]).iloc[0] 129 | #Computing Absolute with discount: Rieman vs AE techniques 130 | pdf["finance_error_riemann"] = np.abs( 131 | pdf["finance_price_estimation"] - pdf["finance_riemann_price"] 132 | ) 133 | #Computing Absolute error: Exact BS price vs AE techniques 134 | pdf["finance_error_exact"] = np.abs( 135 | pdf["finance_price_estimation"] - pdf["finance_exact_price"]) 136 | #Other interesting staff 137 | if solver_object is None: 138 | #Computation Fails Encoding 0 and RQAE 139 | pdf["schedule_pdf"] = [None] 140 | pdf["oracle_calls"] = [None] 141 | pdf["max_oracle_depth"] = [None] 142 | pdf["run_time"] = [None] 143 | else: 144 | if solver_object.schedule_pdf is None: 145 | pdf["schedule_pdf"] = [None] 146 | else: 147 | pdf["schedule_pdf"] = [solver_object.schedule_pdf.to_dict()] 148 | pdf["oracle_calls"] = solver_object.oracle_calls 149 | pdf["max_oracle_depth"] = solver_object.max_oracle_depth 150 | pdf["run_time"] = solver_object.solver_ae.run_time 151 | 152 | return pdf 153 | -------------------------------------------------------------------------------- /QQuantLib/finance/ae_price_estimation_step_payoff.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module implements the *ae_price_estimation_step_po* function that 3 | allows to the user configure a price estimation problem using financial 4 | parameters, encode the expected value integral to compute in a quantum 5 | state and estimate it using the different **AE** algorithms implemented 6 | in the **QQuantLib.AE** package. 7 | 8 | This function uses the DensityProbability and the PayOff classes (from 9 | *finance.probability_class* and *finance.payoff_class* modules 10 | respectively) for defining the option price estimation problem. 11 | Then the q_solve_integral function (from *finance.quantum_integration* 12 | module) is used for computing the expected value integral. 13 | 14 | The *ae_price_estimation_step_po* functions load and estimate the 15 | amplitude for the positive and negative parts of the payoff separately 16 | and process the results to get the desired price estimation. 17 | 18 | 19 | Authors: Alberto Pedro Manzano Herrero & Gonzalo Ferro Costas 20 | """ 21 | 22 | import sys 23 | import numpy as np 24 | import pandas as pd 25 | from QQuantLib.finance.probability_class import DensityProbability 26 | from QQuantLib.finance.payoff_class import PayOff 27 | from QQuantLib.finance.quantum_integration import q_solve_integral 28 | 29 | def ae_price_estimation_step_po(**kwargs): 30 | """ 31 | Configures an option price estimation problem and solving it using 32 | AE integration techniques 33 | 34 | Parameters 35 | ---------- 36 | 37 | kwargs : dictionary. 38 | Dictionary for configuring the price estimation problem, the 39 | encoding of the price estimation data into the quantum circuit 40 | and the AE integration technique for solving it. 41 | 42 | Note 43 | ____ 44 | 45 | The keys for the input kwargs dictionary will be the necessary keys 46 | for configuring the DensityProbability class \\ 47 | (see QQuantLib.finance.probability_class), the PayOff class \\ 48 | (see QQuantLib.finance.payoff_class) and the q_solve_integral \\ 49 | function (see QQuantLib.finance.quantum_integration). 50 | 51 | Returns 52 | _______ 53 | 54 | pdf : Pandas DataFrame 55 | DataFrame with the configuration of the AE problem and the solution 56 | """ 57 | 58 | ae_problem = kwargs 59 | #Building the domain 60 | n_qbits = ae_problem.get("n_qbits", None) 61 | x0 = ae_problem.get("x0", 1.0) 62 | xf = ae_problem.get("xf", 3.0) 63 | domain = np.linspace(x0, xf, 2**n_qbits) 64 | 65 | #Building the Probability distribution 66 | pc = DensityProbability(**ae_problem) 67 | p_x = pc.probability(domain) 68 | #Normalisation of the probability distribution 69 | p_x_normalisation = np.sum(p_x) + 1e-8 70 | norm_p_x = p_x / p_x_normalisation 71 | 72 | #Building the option payoff 73 | po = PayOff(**ae_problem) 74 | pay_off = po.pay_off(domain) 75 | #Normalisation of the pay off 76 | pay_off_normalisation = np.max(np.abs(pay_off)) + 1e-8 77 | norm_pay_off = pay_off / pay_off_normalisation 78 | 79 | #Getting the exact price of the option under BS 80 | exact_solution = None 81 | if po.pay_off_bs is not None: 82 | exact_solution = po.pay_off_bs(**ae_problem) 83 | 84 | #### Positive Pay Off part execution #### 85 | npo_positive = np.where(norm_pay_off < 0, 0.0, norm_pay_off) 86 | ae_problem.update({ 87 | "array_function" : npo_positive, 88 | "array_probability" : norm_p_x, 89 | }) 90 | solution_p, solver_object_p = q_solve_integral(**ae_problem) 91 | 92 | #### Negative Pay Off part execution #### 93 | npo_neagtive = np.abs(np.where(norm_pay_off >= 0, 0.0, norm_pay_off)) 94 | ae_problem.update({ 95 | "array_function" : npo_neagtive, 96 | "array_probability" : norm_p_x, 97 | }) 98 | solution_n, solver_object_n = q_solve_integral(**ae_problem) 99 | 100 | ###### Combine Solutions ########## 101 | 102 | # First compute errors of both contributions 103 | epsilon_p = (solution_p["ae_u"] - solution_p["ae_l"]) / 2.0 104 | epsilon_n = (solution_n["ae_u"] - solution_n["ae_l"]) / 2.0 105 | #epsilon_final = np.sqrt(epsilon_p ** 2 + epsilon_n ** 2) 106 | epsilon_final = epsilon_p + epsilon_n 107 | # Second compute the expected value 108 | solution = solution_p["ae"] - solution_n["ae"] 109 | # Compute the expected value to compute 110 | ae_expectation = solution * pay_off_normalisation * p_x_normalisation 111 | # Compute the associated error 112 | measured_epsilon = epsilon_final * pay_off_normalisation * p_x_normalisation 113 | ###### Creation of the output ########## 114 | #The basis will be the input python dictionary for traceability 115 | pdf = pd.DataFrame([ae_problem]) 116 | pdf.drop(["array_function", "array_probability"], axis=1, inplace=True) 117 | #Added normalisation constants 118 | pdf["payoff_normalisation"] = pay_off_normalisation 119 | pdf["p_x_normalisation"] = p_x_normalisation 120 | #Expectation calculation using Riemann sum 121 | pdf["riemann_expectation"] = np.sum(p_x * pay_off) 122 | # Positive Part estimation 123 | pdf[[col + "_positive_part" for col in solution_p.columns]] = solution_p 124 | # Negative part estimation 125 | pdf[[col + "_negative_part" for col in solution_p.columns]] = solution_n 126 | #Expectation calculation using AE integration techniques 127 | pdf["ae_expectation"] = ae_expectation 128 | # Pure integration Absolute Error 129 | pdf["absolute_error"] = np.abs( 130 | pdf["ae_expectation"] - pdf["riemann_expectation"]) 131 | pdf["measured_epsilon"] = measured_epsilon 132 | # Finance Info 133 | #Exact option price under the Black-Scholes model 134 | pdf["finance_exact_price"] = exact_solution 135 | #Option price estimation using expectation computed as Riemann sum 136 | pdf["finance_riemann_price"] = pdf["riemann_expectation"] * np.exp( 137 | -pdf["risk_free_rate"] * pdf["maturity"] 138 | ) 139 | #Option price estimation using expectation computed by AE integration 140 | pdf["finance_price_estimation"] = pdf["ae_expectation"] * \ 141 | np.exp(-pdf["risk_free_rate"] * pdf["maturity"]).iloc[0] 142 | # Associated error of the price estimation 143 | pdf["finance_price_epsilon"] = pdf["measured_epsilon"] * \ 144 | np.exp(-pdf["risk_free_rate"] * pdf["maturity"]).iloc[0] 145 | #Computing Absolute with discount: Rieman vs AE techniques 146 | pdf["finance_error_riemann"] = np.abs( 147 | pdf["finance_price_estimation"] - pdf["finance_riemann_price"] 148 | ) 149 | #Computing Absolute error: Exact BS price vs AE techniques 150 | pdf["finance_error_exact"] = np.abs( 151 | pdf["finance_price_estimation"] - pdf["finance_exact_price"]) 152 | 153 | # We have two objects. It is not interesting have the schedules 154 | pdf["schedule_pdf"] = [None] 155 | pdf["oracle_calls"] = solver_object_p.oracle_calls + solver_object_n.oracle_calls 156 | pdf["max_oracle_depth"] = max( 157 | solver_object_p.max_oracle_depth, solver_object_n.max_oracle_depth) 158 | pdf["circuit_stasts"] = [None] 159 | pdf["run_time"] = solver_object_p.solver_ae.run_time + solver_object_n.solver_ae.run_time 160 | return pdf 161 | -------------------------------------------------------------------------------- /QQuantLib/finance/payoff_class.py: -------------------------------------------------------------------------------- 1 | """ 2 | In this module, the Python PayOff class is defined. This class allows 3 | to the user configure payoffs for different financial derivatives 4 | (like options or futures) by providing typical financial parameters 5 | The PayOff class uses functions from finance.classical_finance module. 6 | 7 | Authors: Alberto Pedro Manzano Herrero & Gonzalo Ferro 8 | """ 9 | from functools import partial 10 | import QQuantLib.finance.classical_finance as cf 11 | from QQuantLib.utils.utils import text_is_none 12 | 13 | 14 | class PayOff: 15 | 16 | """ 17 | Class for selecting derivative options and configuring them. 18 | 19 | Parameters 20 | ---------- 21 | 22 | kwargs: dictionary 23 | Dictionary for selecting and configuring the derivative option. 24 | strike: kwargs, float 25 | strike of the option. 26 | coupon: kwargs, float 27 | only valid for Digital Options 28 | pay_off : kwargs, string 29 | type of pay_off function to load 30 | """ 31 | 32 | def __init__(self, **kwargs): 33 | """ 34 | 35 | Method for initializing the class 36 | 37 | """ 38 | 39 | self.pay_off_type = kwargs.get("pay_off_type", None) 40 | text_is_none(self.pay_off_type, "pay_off_type", variable_type=str) 41 | # European Options 42 | self.strike = kwargs.get("strike", None) 43 | # Digital Options 44 | self.coupon = kwargs.get("coupon", None) 45 | self.pay_off = None 46 | self.pay_off_bs = None 47 | self.get_pay_off() 48 | 49 | def get_pay_off(self): 50 | """ 51 | Select of a PayOff 52 | """ 53 | 54 | if self.pay_off_type == "European_Call_Option": 55 | text_is_none(self.strike, "strike", variable_type=float) 56 | # PayOff 57 | self.pay_off = partial(cf.call_payoff, strike=self.strike) 58 | # Exact Solution for PayOff under BS 59 | self.pay_off_bs = partial(cf.bs_call_price, strike=self.strike) 60 | elif self.pay_off_type == "European_Put_Option": 61 | text_is_none(self.strike, "strike", variable_type=float) 62 | # PayOff 63 | self.pay_off = partial(cf.put_payoff, strike=self.strike) 64 | # Exact Solution for PayOff under BS 65 | self.pay_off_bs = partial(cf.bs_put_price, strike=self.strike) 66 | elif self.pay_off_type == "Digital_Call_Option": 67 | text_is_none(self.strike, "strike", variable_type=float) 68 | text_is_none(self.coupon, "coupon", variable_type=float) 69 | # PayOff 70 | self.pay_off = partial( 71 | cf.digital_call_payoff, strike=self.strike, coupon=self.coupon 72 | ) 73 | # Exact Solution for PayOff under BS 74 | self.pay_off_bs = partial( 75 | cf.bs_digital_call_price, strike=self.strike, coupon=self.coupon 76 | ) 77 | elif self.pay_off_type == "Digital_Put_Option": 78 | text_is_none(self.strike, "strike", variable_type=float) 79 | text_is_none(self.coupon, "coupon", variable_type=float) 80 | # PayOff 81 | self.pay_off = partial( 82 | cf.digital_put_payoff, strike=self.strike, coupon=self.coupon 83 | ) 84 | # Exact Solution for PayOff under BS 85 | self.pay_off_bs = partial( 86 | cf.bs_digital_put_price, strike=self.strike, coupon=self.coupon 87 | ) 88 | elif self.pay_off_type == "Futures": 89 | text_is_none(self.strike, "strike", variable_type=float) 90 | # PayOff 91 | self.pay_off = partial(cf.futures_payoff, strike=self.strike) 92 | # Exact Solution for PayOff under BS 93 | self.pay_off_bs = partial(cf.bs_forward_price, strike=self.strike) 94 | else: 95 | raise ValueError( 96 | "Not valid pay off type was provided. Valid types: \ 97 | European_Call_Option,\n \ 98 | European_Put_Option,\n \ 99 | Digital_Call_Option,\n \ 100 | Digital_Put_Option" 101 | ) 102 | -------------------------------------------------------------------------------- /QQuantLib/finance/probability_class.py: -------------------------------------------------------------------------------- 1 | """ 2 | In this module, the Python DensityProbability class is defined. 3 | This class allows to the user configure the *Black-Scholes* probability 4 | density function (log-normal) by providing typical financial parameters 5 | The DensityProbability class uses functions from finance.classical_finance module. 6 | 7 | Authors: Alberto Pedro Manzano Herrero & Gonzalo Ferro 8 | """ 9 | from functools import partial 10 | import QQuantLib.finance.classical_finance as cf 11 | from QQuantLib.utils.utils import text_is_none 12 | 13 | 14 | 15 | class DensityProbability: 16 | 17 | """ 18 | Class for selecting pay off functions 19 | algorithm 20 | 21 | Parameters 22 | ---------- 23 | 24 | probability_type : string 25 | type of probability density function to load 26 | kwargs: dictionary 27 | Dictionary for configuring the asset and the probability \\ 28 | used for simulating its behaviour.Implemented keys: 29 | 30 | s_0 : kwargs, float 31 | initial value of the asset 32 | risk_free_rate : kwargs, float 33 | risk free ratio 34 | maturity : kwargs, float 35 | time where the probability wants to be calculated. 36 | volatiliy : kwargs, float 37 | volatility of the asset. 38 | """ 39 | 40 | def __init__(self, probability_type: str, **kwargs): 41 | """ 42 | 43 | Method for initializing the class 44 | 45 | """ 46 | 47 | self.probability_type = probability_type 48 | text_is_none(self.probability_type, "probability_type", variable_type=str) 49 | self.probability = None 50 | self.density_probability = None 51 | self.probability = self.get_density( 52 | self.probability_type, **kwargs) 53 | self.density_probability = self.get_density_prob( 54 | self.probability_type, **kwargs) 55 | 56 | @staticmethod 57 | def get_density(probability_type, **kwargs): 58 | """ 59 | Create the probability function 60 | 61 | Parameters 62 | ---------- 63 | 64 | probability_type : string 65 | type of probability density function to load 66 | kwargs: dictionary 67 | with necessary information for configuring the probability \\ 68 | density 69 | 70 | s_0 : kwargs, float 71 | initial value of the asset 72 | risk_free_rate : kwargs, float 73 | risk free ratio 74 | maturity : kwargs, float 75 | time where the probability wants to be calculated 76 | volatiliy : kwargs, float 77 | volatility of the asset 78 | 79 | """ 80 | 81 | if probability_type == "Black-Scholes": 82 | 83 | s_0 = kwargs.get("s_0", None) 84 | text_is_none(s_0, "s_0", variable_type=float) 85 | risk_free_rate = kwargs.get("risk_free_rate", None) 86 | text_is_none(risk_free_rate, "risk_free_rate", variable_type=float) 87 | maturity = kwargs.get("maturity", None) 88 | text_is_none(maturity, "maturity", variable_type=float) 89 | volatility = kwargs.get("volatility", None) 90 | text_is_none(volatility, "volatility", variable_type=float) 91 | 92 | else: 93 | raise ValueError() 94 | 95 | return partial( 96 | cf.bs_probability, 97 | s_0=s_0, 98 | risk_free_rate=risk_free_rate, 99 | volatility=volatility, 100 | maturity=maturity, 101 | ) 102 | 103 | @staticmethod 104 | def get_density_prob(probability_type, **kwargs): 105 | """ 106 | Configures a probability density 107 | 108 | Parameters 109 | ---------- 110 | 111 | probability_type : string 112 | type of probability density function to load 113 | kwargs: dictionary 114 | with necessary information for configuring the probability \\ 115 | density. 116 | 117 | s_0 : kwargs, float 118 | initial value of the asset 119 | risk_free_rate : kwargs, float 120 | risk free ratio 121 | maturity : kwargs, float 122 | time where the probability wants to be calculated 123 | volatiliy : kwargs, float 124 | volatility of the asset 125 | """ 126 | 127 | if probability_type == "Black-Scholes": 128 | 129 | s_0 = kwargs.get("s_0", None) 130 | text_is_none(s_0, "s_0", variable_type=float) 131 | risk_free_rate = kwargs.get("risk_free_rate", None) 132 | text_is_none(risk_free_rate, "risk_free_rate", variable_type=float) 133 | maturity = kwargs.get("maturity", None) 134 | text_is_none(maturity, "maturity", variable_type=float) 135 | volatility = kwargs.get("volatility", None) 136 | text_is_none(volatility, "volatility", variable_type=float) 137 | 138 | else: 139 | raise ValueError() 140 | return partial( 141 | cf.bs_density, 142 | s_0=s_0, 143 | risk_free_rate=risk_free_rate, 144 | volatility=volatility, 145 | maturity=maturity, 146 | ) 147 | -------------------------------------------------------------------------------- /QQuantLib/finance/quantum_integration.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains the *q_solve_integral* function that allows to the 3 | user codify easily an integral in a quantum state, using the different 4 | encoding protocols from the *Encoding* class from 5 | **QQuantLib.DL.encoding_protocols** module, and estimating it using the 6 | different **AE** algorithms implemented in the **QQuantLib.AE** package. 7 | 8 | 9 | The *q_solve_integral* function deals with all the normalisations needed 10 | for transforming the estimated amplitude into the desired integral. 11 | 12 | 13 | Authors: Alberto Pedro Manzano Herrero & Gonzalo Ferro 14 | 15 | """ 16 | 17 | import warnings 18 | from copy import deepcopy 19 | import numpy as np 20 | import pandas as pd 21 | from QQuantLib.DL.encoding_protocols import Encoding 22 | from QQuantLib.AE.ae_class import AE 23 | from QQuantLib.utils.utils import text_is_none 24 | 25 | def q_solve_integral(**kwargs): 26 | """ 27 | Function for solving an integral using quantum amplitude \\ 28 | estimation techniques. 29 | 30 | Parameters 31 | ---------- 32 | 33 | array_function : kwargs, numpy array 34 | numpy array with the desired function for encoding into the \\ 35 | Quantum Circuit. 36 | encoding : kwargs, int 37 | Selecting the encode protocol 38 | array_probability : kwargs, numpy array 39 | numpy array with the desired probability for encoding into the \\ 40 | Quantum Circuit. It can be None (uniform distribution will be used) 41 | ae_type : kwargs, string 42 | string with the desired AE algorithm: MLAE, CQPEAE, IQPEAE, \\ 43 | IQAE, RQAE 44 | 45 | Note 46 | ---- 47 | 48 | Other kwargs input dictionary keys will be related with the encoding \\ 49 | of the integral into the quantum circuit \\ 50 | (see QQuantLib.DL.encoding_protocols) and for the configuration \\ 51 | of the AE algorithm used (see QQuantLib.AE.ae_class) 52 | 53 | Return 54 | ---------- 55 | 56 | ae_estimation: pandas DataFrame 57 | DataFrame with the desired integral computation. 58 | solver_ae: objet based on the AE class 59 | 60 | """ 61 | 62 | 63 | encoding = kwargs.get("encoding", None) 64 | ae_type = kwargs.get("ae_type", None) 65 | if (encoding == 0) and (ae_type in ["RQAE", "eRQAE", "sRQAE", "mRQAE"]): 66 | string_error = ( 67 | "RQAEs methods CAN NOT BE USED with encoding protocol: "+str(encoding) 68 | ) 69 | 70 | warnings.warn(string_error) 71 | 72 | ae_estimation = pd.DataFrame( 73 | [None, None, None], 74 | index=["ae", "ae_l", "ae_u"], 75 | ).T 76 | solver_ae = None 77 | encode_class = None 78 | else: 79 | 80 | #Mandatory kwargs for encoding data 81 | array_function = kwargs.get("array_function", None) 82 | text_is_none(array_function, "array_function", variable_type=np.ndarray) 83 | array_probability = kwargs.get("array_probability", None) 84 | text_is_none(encoding, "encoding", variable_type=int) 85 | encoding_dict = {"multiplexor": kwargs.get("multiplexor", True)} 86 | #instantiate encoding class 87 | encode_class = Encoding( 88 | array_function=array_function, 89 | array_probability=array_probability, 90 | encoding=encoding, 91 | **encoding_dict 92 | ) 93 | 94 | #execute run method of the encoding class 95 | encode_class.run() 96 | 97 | if encode_class.oracle is None: 98 | raise ValueError("Oracle was not created!!") 99 | 100 | #Mandatory kwargs for ae solver 101 | # Set the QPU to use 102 | linalg_qpu = kwargs.get("qpu", None) 103 | if linalg_qpu is None: 104 | raise ValueError("qpu is None. Please provide a valid qpu") 105 | #del kwargs['qpu'] 106 | 107 | # ae_dict = deepcopy(kwargs) 108 | #ae_dict.update({"qpu": linalg_qpu}) 109 | #Delete keys from encoding 110 | # for step in ["array_function", "array_probability", "encoding", "multiplexor"]: 111 | # ae_dict.pop(step, None) 112 | # ae_dict.pop("ae_type", None) 113 | #Instantiate AE solver 114 | solver_ae = AE( 115 | oracle=encode_class.oracle, 116 | target=encode_class.target, 117 | index=encode_class.index, 118 | #ae_type=ae_type, 119 | **kwargs) 120 | 121 | # run the amplitude estimation algorithm 122 | solver_ae.run() 123 | 124 | # Recover amplitude estimation from ae_solver 125 | if encoding == 0: 126 | # In the square encoding the np.sqrt(p_x * f_norm_x) is 127 | # loaded in the amplitude of the state |x>^n|0>. 128 | # The probability of measuring a |0> in the additional qubit 129 | # is just sum_x(|p_x * f_norm_x|) 130 | ae_pdf = solver_ae.ae_pdf 131 | elif encoding == 1: 132 | if ae_type in ["RQAE", "eRQAE", "mRQAE", "sRQAE"]: 133 | #Amplitude is provided directly by this algorithm 134 | ae_pdf = solver_ae.ae_pdf 135 | else: 136 | #Other algorithms return probability 137 | ae_pdf = np.sqrt(solver_ae.ae_pdf) 138 | if ae_type != "MLAE": 139 | # We need to provided the mean of the square root bounds 140 | # as the measured ae. Not valid for IQAE 141 | ae_pdf["ae"] = (ae_pdf["ae_l"] + ae_pdf["ae_u"]) / 2.0 142 | elif encoding == 2: 143 | # In the direct encoding we load the sum_x(p_x * f_norm_x) 144 | # into the amplitude of the |0>^{n+1} state 145 | if ae_type in ["RQAE", "eRQAE", "mRQAE", "sRQAE"]: 146 | # RQAE provides amplitude directly. 147 | ae_pdf = solver_ae.ae_pdf 148 | else: 149 | # AE algorithms provide an estimation of the probability 150 | # so they provide: sum_x(p_x * f_norm_x) ** 2 151 | # we need to compute sqrt(sum_x(p_x * f_norm_x) ** 2) 152 | ae_pdf = np.sqrt(solver_ae.ae_pdf) 153 | # We need to provided the mean of the square root bounds 154 | # as the measured ae. 155 | ae_pdf["ae"] = (ae_pdf["ae_l"] + ae_pdf["ae_u"]) / 2.0 156 | else: 157 | raise ValueError("Not valid encoding key was provided!!!") 158 | #Now we need to deal with encoding normalisation 159 | ae_estimation = ae_pdf * encode_class.encoding_normalization 160 | return ae_estimation, solver_ae 161 | -------------------------------------------------------------------------------- /QQuantLib/qml4var/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/QQuantLib/qml4var/__init__.py -------------------------------------------------------------------------------- /QQuantLib/qml4var/data_utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Functions for heliping to build the datasets 3 | """ 4 | import json 5 | import numpy as np 6 | import pandas as pd 7 | from scipy.special import erf 8 | 9 | def empirical_distribution_function_old(data_points: np.array): 10 | """ 11 | Given an array of data points create the corresponding empirical 12 | distribution dunction 13 | Parameters 14 | ---------- 15 | 16 | data_points : numpy array 17 | numpy array with data sampled 18 | 19 | Returns 20 | ------- 21 | 22 | batch_ : QLM Batch 23 | QLM Batch with the jobs for computing graidents 24 | """ 25 | n_sample = data_points.shape[0] 26 | distribution = np.zeros(n_sample) 27 | for m_ in range(n_sample): 28 | count = 0 29 | for n_ in list(range(0, m_))+list(range(m_+1, n_sample)): 30 | check = np.all(data_points[m_] >= data_points[n_]) 31 | if check: 32 | count = count+1 33 | 34 | distribution[m_] = count/(n_sample-1) 35 | return distribution 36 | 37 | def empirical_cdf(data_points): 38 | """ 39 | Given an array of data points create the corresponding empirical 40 | distribution function 41 | Parameters 42 | ---------- 43 | data_points : numpy array 44 | numpy array with data sampled 45 | Returns 46 | ------- 47 | emp_cdf : numpy array 48 | numpy array with the empirical cdf of the input data 49 | """ 50 | if len(data_points.shape) == 1: 51 | data_points = data_points.reshape((data_points.shape[0], 1)) 52 | 53 | 54 | emp_cdf = np.array( 55 | [np.sum(np.all(data_points <= x, axis=1)) for x in data_points] 56 | ) / data_points.shape[0] 57 | return emp_cdf 58 | 59 | 60 | def bs_pdf( 61 | s_t: float, s_0: float = 1.0, risk_free_rate: float = 0.0, 62 | volatility: float = 0.5, maturity: float = 0.5, **kwargs): 63 | """ 64 | Black Scholes PDF 65 | """ 66 | 67 | mean = (risk_free_rate - 0.5 * volatility * volatility) * maturity + np.log(s_0) 68 | factor = s_t * volatility * np.sqrt(2 * np.pi * maturity) 69 | exponent = -((np.log(s_t) - mean) ** 2) / (2 * volatility * volatility * maturity) 70 | density = np.exp(exponent) / factor 71 | return density 72 | 73 | def bs_cdf( 74 | s_t: float, s_0: float = 1.0, risk_free_rate: float = 0.0, 75 | volatility: float = 0.5, maturity: float = 0.5, **kwargs): 76 | """ 77 | Black Scholes PDF 78 | """ 79 | mean = (risk_free_rate - 0.5 * volatility * volatility) * maturity + np.log(s_0) 80 | variance = volatility * volatility * maturity 81 | return 0.5 * (1 + erf((np.log(s_t) - mean) / (np.sqrt(2 * variance)))) 82 | 83 | def bs_samples( 84 | number_samples: int, s_0: float = 1.0, risk_free_rate: float = 0.0, 85 | volatility: float = 0.5, maturity: float = 0.5, **kwargs): 86 | """ 87 | Black Scholes Samples 88 | """ 89 | 90 | dW = np.random.randn(number_samples) 91 | s_t = s_0 * np.exp( 92 | (risk_free_rate - 0.5 * volatility * volatility) * maturity + 93 | volatility * dW * np.sqrt(maturity)) 94 | return s_t 95 | 96 | def saving_datasets(x_train, y_train, x_test, y_test, **kwargs): 97 | """ 98 | Saving Data sets 99 | """ 100 | name_for_saving = kwargs.get("name_for_saving", None) 101 | if name_for_saving is not None: 102 | features = ["Features_{}".format(x_) for x_ in range(x_train.shape[1])] 103 | pdf_training = pd.DataFrame(x_train, columns=features) 104 | pdf_training["Labels"] = y_train 105 | pdf_testing = pd.DataFrame(x_test, columns=features) 106 | pdf_testing["Labels"] = y_test 107 | pdf_training.to_csv( 108 | name_for_saving+"_training.csv", sep=";", index=True) 109 | pdf_testing.to_csv( 110 | name_for_saving+"_testing.csv", sep=";", index=True) 111 | with open(kwargs.get("folder_path") + "/data.json", "w") as outfile: 112 | outfile.write(json.dumps(kwargs)) 113 | 114 | def get_dataset(name_for_loading): 115 | # load Datasets 116 | pdf_training = pd.read_csv( 117 | name_for_loading+"_training.csv", sep=";", index_col=0 118 | ) 119 | pdf_testing = pd.read_csv( 120 | name_for_loading+"_testing.csv", sep=";", index_col=0 121 | ) 122 | feat = [col for col in pdf_training.columns if "Features" in col] 123 | x_train = pdf_training[feat].values 124 | y_train = pdf_training["Labels"].values 125 | y_train = y_train.reshape((-1, 1)) 126 | x_test = pdf_testing[feat].values 127 | y_test = pdf_testing["Labels"].values 128 | y_test = y_test.reshape((-1, 1)) 129 | return x_train, y_train, x_test, y_test 130 | -------------------------------------------------------------------------------- /QQuantLib/qpu/REAME.md: -------------------------------------------------------------------------------- 1 | # Noisy Models 2 | 3 | At the momement the noisy models from model_noise can be only used in a QLM. 4 | -------------------------------------------------------------------------------- /QQuantLib/qpu/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/QQuantLib/qpu/__init__.py -------------------------------------------------------------------------------- /QQuantLib/qpu/get_qpu.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module implements the get_qpu function that allows to the user 3 | select a **EVIDEN QPU** for ideal simulation. The qpu variable is a 4 | string that should take some of the following values: 5 | 6 | 7 | **qlmass_linalg**. 8 | For selecting the linear algebra simulator LinAlg. This QPU 9 | can be used only with QaptivaÔäó Appliance when the user sends the computations to a remote QPU. The user must have remote 10 | access to a remote QLM using the Qaptiva Access (QLM as a Service) 11 | library. 12 | **qlmass_mps**. 13 | For selecting the Matrix Product State (MPS) simulator. This QPU 14 | can be used only with QaptivaÔäó Appliance when the user sends the computations to a remote QPU. The user must have remote 15 | access to a remote QLM using the Qaptiva Access (QLM as a Service) 16 | library. 17 | **python**. 18 | For selecting the linear algebra simulator PyLinalg. This a pure 19 | Python algebra simulator. This QPU is provided by the myQLM 20 | library. It can not be used with QaptivaÔäó Appliance. 21 | **c** 22 | For selecting the linear algebra simulator CLinalg. This a pure 23 | C algebra simulator. This QPU is provided by the myQLM 24 | library. It can not be used with QaptivaÔäó Appliance. 25 | **linalg** 26 | For selecting the linear algebra simulator LinAlg. This QPU 27 | can be used only with QaptivaÔäó Appliance when the user is locally 28 | in a QLM. 29 | **mps** 30 | For selecting the Matrix Product State (MPS) simulator This QPU 31 | can be used only with QaptivaÔäó Appliance when the user is locally 32 | in a QLM. 33 | """ 34 | 35 | def get_qpu(qpu=None): 36 | """ 37 | Function for selecting solver. 38 | 39 | Parameters 40 | ---------- 41 | 42 | qpu : str 43 | string with the desired qpu 44 | 45 | Returns 46 | ---------- 47 | 48 | linal_qpu : solver for quantum jobs 49 | """ 50 | 51 | if qpu is None: 52 | raise ValueError( 53 | "qpu CAN NOT BE NONE. Please select one of the three" + 54 | " following options: qlmass, python, c") 55 | if qpu == "qlmass_linalg": 56 | try: 57 | from qlmaas.qpus import LinAlg 58 | linalg_qpu = LinAlg() 59 | except (ImportError, OSError) as exception: 60 | raise ImportError( 61 | "Problem Using QLMaaS. Please create config file" + 62 | "or use mylm solver") from exception 63 | elif qpu == "qlmass_mps": 64 | try: 65 | from qlmaas.qpus import MPS 66 | #linalg_qpu = MPS(lnnize=True) 67 | linalg_qpu = MPS() 68 | except (ImportError, OSError) as exception: 69 | raise ImportError( 70 | "Problem Using QLMaaS. Please create config file" + 71 | "or use mylm solver") from exception 72 | elif qpu == "python": 73 | from qat.qpus import PyLinalg 74 | linalg_qpu = PyLinalg() 75 | elif qpu == "c": 76 | from qat.qpus import CLinalg 77 | linalg_qpu = CLinalg() 78 | elif qpu == "linalg": 79 | from qat.qpus import LinAlg 80 | linalg_qpu = LinAlg() 81 | elif qpu == "mps": 82 | from qat.qpus import MPS 83 | linalg_qpu = MPS() 84 | return linalg_qpu 85 | -------------------------------------------------------------------------------- /QQuantLib/qpu/noise_test_bank_functions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Auxiliary functions for using with the demo notebook: NoisyModels.ipynb 3 | """ 4 | import sys 5 | import numpy as np 6 | sys.path.append("../../") 7 | from QQuantLib.DL.encoding_protocols import Encoding 8 | from QQuantLib.finance.probability_class import DensityProbability 9 | from QQuantLib.finance.payoff_class import PayOff 10 | 11 | 12 | 13 | def create_arrays(price_problem): 14 | """ 15 | This function creates the mandatory arrays for configuring an option 16 | price estimation problem for notebook NoisyModels.ipynb 17 | 18 | Parameters 19 | ---------- 20 | 21 | price_problem : dict 22 | Python dictionary with a complete dictionary for configuring 23 | the arrays for a option price estimation problem 24 | 25 | Returns 26 | ------- 27 | 28 | domain : numpy array 29 | numpy array with the domain for the price estimation problem 30 | norm_pay_off : array 31 | numpy array with the normalised payoff 32 | norm_p_x : numpy array 33 | numpy array with the normalised probability density 34 | pay_off_normalisation : float 35 | normalization constant for the payoff 36 | p_x_normalisation : float 37 | normalization constant for the probability density 38 | 39 | """ 40 | n_qbits = price_problem.get("n_qbits", None) 41 | x0 = price_problem.get("x0", 1.0) 42 | xf = price_problem.get("xf", 3.0) 43 | domain = np.linspace(x0, xf, 2**n_qbits) 44 | #Building the Probability distribution 45 | pc = DensityProbability(**price_problem) 46 | p_x = pc.probability(domain) 47 | #Normalisation of the probability distribution 48 | p_x_normalisation = np.sum(p_x) + 1e-8 49 | norm_p_x = p_x / p_x_normalisation 50 | #Building the option payoff 51 | po = PayOff(**price_problem) 52 | pay_off = po.pay_off(domain) 53 | #Normalisation of the pay off 54 | pay_off_normalisation = np.max(np.abs(pay_off)) + 1e-8 55 | norm_pay_off = pay_off / pay_off_normalisation 56 | return domain, norm_pay_off, norm_p_x, pay_off_normalisation, p_x_normalisation 57 | 58 | 59 | def first_step(epsilon, ratio, gamma): 60 | """ 61 | Configuration of the first step for a RQAE algorithm. This is an 62 | auxiliary function for notebook NoisyModels.ipynb 63 | 64 | Parameters 65 | ---------- 66 | 67 | epsilon : float 68 | epsilon for RQAE 69 | ratio : float 70 | ratio (q) for RQAE 71 | gamma : float 72 | gamma for RQAE 73 | 74 | Returns 75 | ------- 76 | 77 | shift : float 78 | shift for first step of RQAE 79 | n_i : int 80 | number of shots for first step of RQAE 81 | gamma_i : float 82 | failure probability for first step of RQAE 83 | theoretical_epsilon : float 84 | theoretical epsilon for first step of RQAE 85 | """ 86 | epsilon = 0.5 * epsilon 87 | theoretical_epsilon = 0.5 * np.sin(np.pi / (2 * (ratio + 2))) ** 2 88 | k_max = int( 89 | np.ceil( 90 | np.arcsin(np.sqrt(2 * theoretical_epsilon)) 91 | / np.arcsin(2 * epsilon) 92 | * 0.5 93 | - 0.5 94 | ) 95 | ) 96 | bigk_max = 2 * k_max + 1 97 | big_t = np.log( 98 | ratio 99 | * ratio 100 | * (np.arcsin(np.sqrt(2 * theoretical_epsilon))) 101 | / (np.arcsin(2 * epsilon)) 102 | ) / np.log(ratio) 103 | gamma_i = gamma / big_t 104 | n_i = int( 105 | np.ceil(1 / (2 * theoretical_epsilon**2) * np.log(2 * big_t / gamma)) 106 | ) 107 | epsilon_probability = np.sqrt(1 / (2 * n_i) * np.log(2 / gamma_i)) 108 | shift = theoretical_epsilon / np.sin(np.pi / (2 * (ratio + 2))) 109 | return shift, n_i, gamma_i, theoretical_epsilon 110 | -------------------------------------------------------------------------------- /QQuantLib/qpu/qpu_ideal.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "qpu_type": ["c", "python", "linalg", "mps", "qlmass_linalg", "qlmass_mps"], 5 | "t_gate_1qb" : [null], 6 | "t_gate_2qbs" : [null], 7 | "t_readout": [null], 8 | "depol_channel" : [{ 9 | "active": false, 10 | "error_gate_1qb" : null, 11 | "error_gate_2qbs" : null 12 | }], 13 | "idle" : [{ 14 | "amplitude_damping": false, 15 | "dephasing_channel": false, 16 | "t1" : null, 17 | "t2" : null 18 | }], 19 | "meas": [{ 20 | "active":false, 21 | "readout_error": null 22 | }] 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /QQuantLib/qpu/qpu_noisy.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "qpu_type": ["ideal"], 5 | "t_gate_1qb" : [null], 6 | "t_gate_2qbs" : [null], 7 | "t_readout": [null], 8 | "depol_channel" : [{ 9 | "active": false, 10 | "error_gate_1qb" : null, 11 | "error_gate_2qbs" : null 12 | }], 13 | "idle" : [{ 14 | "amplitude_damping": false, 15 | "dephasing_channel": false, 16 | "t1" : null, 17 | "t2" : null 18 | }], 19 | "meas": [{ 20 | "active":false, 21 | "readout_error": null 22 | }] 23 | }, 24 | { 25 | "qpu_type": ["noisy"], 26 | "t_gate_1qb" : [35], 27 | "t_gate_2qbs" : [660], 28 | "t_readout": [4000], 29 | "depol_channel" : [{ 30 | "active": true, 31 | "error_gate_1qb" : 1.0e-4, 32 | "error_gate_2qbs" : 1.0e-3 33 | }], 34 | "idle" : [{ 35 | "amplitude_damping": false, 36 | "dephasing_channel": false, 37 | "t1" : null, 38 | "t2" : null 39 | }], 40 | "meas": [{ 41 | "active":false, 42 | "readout_error": null 43 | }] 44 | }, 45 | { 46 | "qpu_type": ["noisy"], 47 | "t_gate_1qb" : [35], 48 | "t_gate_2qbs" : [660], 49 | "t_readout": [4000], 50 | "depol_channel" : [{ 51 | "active": true, 52 | "error_gate_1qb" : 1.0e-4, 53 | "error_gate_2qbs" : 1.0e-3 54 | }], 55 | "idle" : [{ 56 | "amplitude_damping": true, 57 | "dephasing_channel": false, 58 | "t1" : 0.2e6, 59 | "t2" : null 60 | }], 61 | "meas": [{ 62 | "active":false, 63 | "readout_error": null 64 | }] 65 | }, 66 | { 67 | "qpu_type": ["noisy"], 68 | "t_gate_1qb" : [35], 69 | "t_gate_2qbs" : [660], 70 | "t_readout": [4000], 71 | "depol_channel" : [{ 72 | "active": true, 73 | "error_gate_1qb" : 1.0e-4, 74 | "error_gate_2qbs" : 1.0e-3 75 | }], 76 | "idle" : [{ 77 | "amplitude_damping": false, 78 | "dephasing_channel": true, 79 | "t1" : 0.2e6, 80 | "t2" : 0.1e6 81 | }], 82 | "meas": [{ 83 | "active":false, 84 | "readout_error": null 85 | }] 86 | }, 87 | { 88 | "qpu_type": ["noisy"], 89 | "t_gate_1qb" : [35], 90 | "t_gate_2qbs" : [660], 91 | "t_readout": [4000], 92 | "depol_channel" : [{ 93 | "active": true, 94 | "error_gate_1qb" : 1.0e-4, 95 | "error_gate_2qbs" : 1.0e-3 96 | }], 97 | "idle" : [{ 98 | "amplitude_damping": true, 99 | "dephasing_channel": true, 100 | "t1" : 0.2e6, 101 | "t2" : 0.1e6 102 | }], 103 | "meas": [{ 104 | "active":false, 105 | "readout_error": null 106 | }] 107 | }, 108 | { 109 | "qpu_type": ["noisy"], 110 | "t_gate_1qb" : [35], 111 | "t_gate_2qbs" : [660], 112 | "t_readout": [4000], 113 | "depol_channel" : [{ 114 | "active": true, 115 | "error_gate_1qb" : 1.0e-4, 116 | "error_gate_2qbs" : 1.0e-3 117 | }], 118 | "idle" : [{ 119 | "amplitude_damping": false, 120 | "dephasing_channel": false, 121 | "t1" : null, 122 | "t2" : null 123 | }], 124 | "meas": [{ 125 | "active":true, 126 | "readout_error": 1.370e-2 127 | }] 128 | }, 129 | { 130 | "qpu_type": ["noisy"], 131 | "t_gate_1qb" : [35], 132 | "t_gate_2qbs" : [660], 133 | "t_readout": [4000], 134 | "depol_channel" : [{ 135 | "active": true, 136 | "error_gate_1qb" : 1.0e-4, 137 | "error_gate_2qbs" : 1.0e-3 138 | }], 139 | "idle" : [{ 140 | "amplitude_damping": true, 141 | "dephasing_channel": true, 142 | "t1" : 0.2e6, 143 | "t2" : 0.1e6 144 | }], 145 | "meas": [{ 146 | "active":true, 147 | "readout_error": 1.370e-2 148 | }] 149 | }, 150 | { 151 | "qpu_type": ["noisy"], 152 | "t_gate_1qb" : [35], 153 | "t_gate_2qbs" : [660], 154 | "t_readout": [4000], 155 | "depol_channel" : [{ 156 | "active": false, 157 | "error_gate_1qb" : null, 158 | "error_gate_2qbs" : null 159 | }], 160 | "idle" : [{ 161 | "amplitude_damping": true, 162 | "dephasing_channel": true, 163 | "t1" : 0.2e6, 164 | "t2" : 0.1e6 165 | }], 166 | "meas": [{ 167 | "active":true, 168 | "readout_error": 1.370e-2 169 | }] 170 | }, 171 | { 172 | "qpu_type": ["noisy"], 173 | "t_gate_1qb" : [35], 174 | "t_gate_2qbs" : [660], 175 | "t_readout": [4000], 176 | "depol_channel" : [{ 177 | "active": false, 178 | "error_gate_1qb" : null, 179 | "error_gate_2qbs" : null 180 | }], 181 | "idle" : [{ 182 | "amplitude_damping": false, 183 | "dephasing_channel": false, 184 | "t1" : null, 185 | "t2" : null 186 | }], 187 | "meas": [{ 188 | "active":true, 189 | "readout_error": 1.370e-2 190 | }] 191 | } 192 | ] 193 | -------------------------------------------------------------------------------- /QQuantLib/qpu/select_qpu.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module implements the select_qpu function that allows to the user 3 | select a complete QPU. The input of this function is a Python dictionary 4 | with the following keys: 5 | 6 | **qpu_type** 7 | The value is a Python string for selecting the type of QPU. The 8 | values can be: *c, python, linalg, mps, qlmass_linalg, qlmass_mps* 9 | for using with pure ideal QPU (the get_qpu function from 10 | QQuantLib.qpu.get_qpu module is used for getting the QPU). 11 | Additionally, the values can be: *ideal* for using an ideal qpu 12 | with a Toffoli rewritter pluging or *noisy* for configuring and 13 | using a noisy QPU. In both cases the create_qpu function from 14 | QQuantLib.qpu.model_noise module is used for creating the QPU. 15 | 16 | **t_gate_1qb** 17 | For setting the time for the 1-qubit gates (in ns). Only valid 18 | if *qpu_type* is noisy. 19 | 20 | **t_gate_2qbs** 21 | For setting the time for the 2-qubit gates (in ns). Only valid 22 | if *qpu_type* is noisy. 23 | 24 | **t_readout** 25 | For setting the time for the measuring operations (in ns). Only 26 | valid if *qpu_type* is noisy. 27 | 28 | **depol_channel** 29 | For setting the parameters for a depolarizing channel. The value 30 | is a complete dictionary with the following keys: **active** 31 | the boolean key for activating or not the channel. **error_gate_1qb** 32 | error for 1-qubit gates. **error_gate_2qbs** error for 2-qubits 33 | gates. 34 | 35 | **idle** 36 | For setting the parameters for idle qubits. The value is a 37 | complete dictionary with the following keys: **amplitude_damping** 38 | the boolean key for activating or not an Amplitude Damping channel. 39 | **dephasing_channel** boolean key for activating or not a 40 | Dephasing channel. **t1** time T1 of the qubits (in ns) 41 | **t2** time T2 of the qubits (in nsa). 42 | 43 | **meas** 44 | For setting the parameters for a measuring error. The value is a 45 | complete dictionary with the following keys: **active** boolean 46 | key for activating or not this error. **readout_error** measuring 47 | error. 48 | """ 49 | 50 | def select_qpu(hw_cfg): 51 | """ 52 | This function allows to select a QPU (a ideal or a noisy one). 53 | 54 | Parameters 55 | ---------- 56 | 57 | hw_cfg : dict 58 | Python dictionary for configuring a complete (ideal or noisy) 59 | QPU. When an "ideal" QPU is selected the get_qpu from get_qpu 60 | module is used. If a "noisy" QPU is selected then the differents 61 | keys of the dictionary are used for configruing a noisy hardware 62 | model using functions from model_noise module. 63 | """ 64 | 65 | if hw_cfg["qpu_type"] in ["noisy", "ideal"]: 66 | from QQuantLib.qpu.model_noise import create_qpu 67 | qpu = create_qpu(hw_cfg) 68 | else: 69 | from QQuantLib.qpu.get_qpu import get_qpu 70 | qpu = get_qpu(hw_cfg["qpu_type"]) 71 | return qpu 72 | 73 | if __name__ == "__main__": 74 | import json 75 | import argparse 76 | import sys 77 | sys.path.append("../../") 78 | from QQuantLib.utils.benchmark_utils import combination_for_list 79 | 80 | parser = argparse.ArgumentParser() 81 | parser.add_argument( 82 | "--count", 83 | dest="count", 84 | default=False, 85 | action="store_true", 86 | help="For counting elements on the list", 87 | ) 88 | parser.add_argument( 89 | "--print", 90 | dest="print", 91 | default=False, 92 | action="store_true", 93 | help="For printing " 94 | ) 95 | parser.add_argument( 96 | "-id", 97 | dest="id", 98 | type=int, 99 | help="For executing only one element of the list", 100 | default=None, 101 | ) 102 | parser.add_argument( 103 | "-json_qpu", 104 | dest="json_qpu", 105 | type=str, 106 | default="jsons/qpu.json", 107 | help="JSON with the qpu configuration", 108 | ) 109 | parser.add_argument( 110 | "--exe", 111 | dest="execution", 112 | default=False, 113 | action="store_true", 114 | help="For executing program", 115 | ) 116 | args = parser.parse_args() 117 | print(args) 118 | with open(args.json_qpu) as json_file: 119 | noisy_cfg = json.load(json_file) 120 | final_list = combination_for_list(noisy_cfg) 121 | if args.count: 122 | print(len(final_list)) 123 | if args.print: 124 | if args.id is not None: 125 | print(final_list[args.id]) 126 | else: 127 | print(final_list) 128 | if args.execution: 129 | if args.id is not None: 130 | print(select_qpu(final_list[args.id])) 131 | 132 | -------------------------------------------------------------------------------- /QQuantLib/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/QQuantLib/utils/__init__.py -------------------------------------------------------------------------------- /QQuantLib/utils/benchmark_utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Utils functions from benchmark purpouses. 3 | 4 | Authors: Alberto Pedro Manzano Herrero & Gonzalo Ferro 5 | """ 6 | import json 7 | import itertools as it 8 | from collections import ChainMap 9 | 10 | def combination_for_dictionary(input_dict): 11 | """ 12 | Creates a list of dictionaries with all the posible combination of 13 | the input dictionary. 14 | 15 | Parameters 16 | ---------- 17 | input_dict : python dictionary 18 | python dictionary where each key value MUST be a list. For each 19 | value of a list a new dictioanry will be created 20 | 21 | Returns 22 | ---------- 23 | list_of_dictionaries : list of python dictionaries 24 | A list with all posible combination of dictionaries from the 25 | input dictionary 26 | """ 27 | 28 | list_of_dictionaries = [ 29 | dict(zip(input_dict, x)) for x in it.product(*input_dict.values()) 30 | ] 31 | return list_of_dictionaries 32 | 33 | 34 | def combination_for_list(input_list): 35 | """ 36 | For each dictionary of the list the function creates all posible 37 | combinations. All the posible combinations are concatenated. 38 | 39 | Parameters 40 | ---------- 41 | input_list : list of python dictionary 42 | The values of each key of the each python dictionary MUST BE lists. 43 | 44 | Returns 45 | ---------- 46 | list_of_combinations : list of python dictionaries 47 | A list with the concatenation of all posible combinations for 48 | each dictionary of the input_list 49 | """ 50 | list_of_combinations = [] 51 | for step_dict in input_list: 52 | list_of_combinations = list_of_combinations + combination_for_dictionary( 53 | step_dict 54 | ) 55 | return list_of_combinations 56 | 57 | def create_pe_problem(domain_cfg, payoff_cfg, density_cfg): 58 | """ 59 | Create a list of price estimation problems. Each element is a python 60 | dictionary with a complete option price estimation problem. 61 | 62 | Parameters 63 | ---------- 64 | domain_cfg : list of dictionaries 65 | Each dictionary has a domain configuration for a price estimation problem. 66 | payoffs_cfg : list of dictionaries 67 | Each dictionary has an option configuration for a price estimation problem. 68 | density_cfg : list of dictionaries 69 | Each dictionary has probability density configuration for a price estimation problem. 70 | 71 | Returns 72 | ---------- 73 | pe_problem_list : list of dictionaries 74 | list with different price estimation problems. 75 | """ 76 | 77 | # List of density probabilities dictionaries 78 | dp_list = combination_for_list(density_cfg) 79 | # List for pay offs 80 | po_list = combination_for_list(payoff_cfg) 81 | # list of domain dictionaries 82 | do_list = combination_for_list(domain_cfg) 83 | pe_problem_list = [ 84 | dict(ChainMap(*list(x))) for x in it.product(dp_list, do_list, po_list) 85 | ] 86 | return pe_problem_list 87 | 88 | def create_ae_pe_solution(ae_list, problem_list): 89 | """ 90 | Creates a list of price estimation problems for solving with amplitude 91 | estimation (AE) techniques. Each element will have the complete 92 | information for generating a price estimation problem and the 93 | configuration for solving it using an AE algorithm. This is each element 94 | is a python dictionary that allows define a price estimation problem 95 | and solving it using a properly configure AE algorithm 96 | 97 | Parameters 98 | ---------- 99 | ae_list : list 100 | List with properly configured AE solvers. 101 | problem_list : list 102 | List with different price estimation problems. 103 | 104 | Returns 105 | ---------- 106 | solve_ae_pe_list : list 107 | List where each element is a ae_pricep dictionary 108 | The list will have the combination of each posible amplitude 109 | estimation solver with all posible price problem list 110 | """ 111 | solve_ae_pe_list = [] 112 | for ae in ae_list: 113 | step_list = [dict(ChainMap(*list(x))) for x in it.product(problem_list, [ae])] 114 | solve_ae_pe_list = solve_ae_pe_list + step_list 115 | return solve_ae_pe_list 116 | 117 | def list_of_dicts_from_jsons(ae_json_list): 118 | """ 119 | Creates a list of dictionaries from inputs jsons. 120 | 121 | Parameters 122 | ---------- 123 | ae_list : list of json. 124 | List with name of json files with a complete configuration of an 125 | amplitude estimation method 126 | 127 | Returns 128 | ---------- 129 | ae_pricep_list : list of python dictionaries 130 | """ 131 | ae_list = [] 132 | for ae_json in ae_json_list: 133 | with open(ae_json) as json_file: 134 | ae_list = ae_list + json.load(json_file) 135 | ae_list = combination_for_list(ae_list) 136 | return ae_list 137 | #ae_pricep_list = create_ae_pricep_list(ae_list, problem_list) 138 | #return ae_pricep_list 139 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Financial Applications 2 | 3 | This repo is associated with the Financial Applications use case of the Machine Learning & Optimisation group of the NEASQC European project. 4 | Its primary focus is the development of the Python library *Quantum Quantitative Finance Library* (**QQuantLib**), which encompasses various state-of-the-art quantum algorithms and techniques tailored for the financial industry. Many of these contributions were developed within the project framework. 5 | The **QQuantLib** was programmed using the quantum software stack myQLM developed by EVIDEN. 6 | 7 | ## Licence 8 | 9 | The `LICENCE` file contains the default licence statement as specified in the proposal and partner agreement. 10 | 11 | ## Building and installing 12 | 13 | The mandatory Python libraries and packages for using the **QQuantLib** can be found into the *environment.yml* file. 14 | 15 | ## Library organisation 16 | 17 | The *Quantum Quantitative Finance Library* is structured as a standard Python library within the *QQuantLib* folder. It is organized into several packages: 18 | 19 | 1. **Data Loading (DL) package**: Located at *QQuantLib/DL*, this package comprises modules responsible for loading data into quantum circuits. 20 | 2. **Amplitude Amplification (AA) package**: Found at *QQuantLib/AA*, this package contains modules for creating amplitude amplification (or Grover-like) operators. 21 | 3. **Phase Estimation (PE) package**: Located at *QQuantLib/PE*, this package includes modules for phase estimation algorithms applicable in amplitude estimation procedures. 22 | 4. **Amplitude Estimation (AE) package**: Situated in *QQuantLib/AE*, this package focuses on implementing various amplitude estimation algorithms. 23 | 5. **Finance package**: Housed in *QQuantLib/finance*, this package implements modules for employing amplitude estimation techniques to solve financial problems. 24 | 6. **Quantum Machine Learning for VaR (qml4var)**: Located in *QQuantLib/qml4var*, this package focus on implementing mandatory workflow for building and training **Parametric Quantum Circuits (PQC)** that can be used as a surrogate models for complex and time-consuming financial distributions. The trained surrogate models can be used for risk analysis and *VaR* computations. 25 | 6. **QPU package**: Located at *QQuantLib/qpu*, this package comprises modules for selecting different EVIDEN Quantum Process Units (**QPU**s) compatible with the QQuantLib library. 26 | 7. **Utils package**: Positioned at *QQuantLib/utils*, this package contains multiple modules with utilities utilized across other packages. 27 | 28 | ## Jupyter Notebooks 29 | 30 | A series of Jupyter notebooks have been developed in the **misc/notebooks** folder as tutorials. These notebooks explain the functionality of the various packages and modules within the library, as well as demonstrate how to utilize them to solve typical problems encountered in the financial industry. 31 | 32 | ## Benchmark folder 33 | 34 | In the benchmark folder, three Python packages are presented to assess the performance of various quantum algorithms: 35 | 36 | 1. **compare_ae_probability**: This package enables easy configuration of different amplitude estimation algorithms and their application to a simple amplitude estimation problem (this is getting the probability of a fixed state when a probability density array is loaded into a quantum circuit). For comparison between AE methods please review notebook CompareAEalgorithmsOnPureProbability.ipynb. 37 | 2. **q_ae_price**: This package simplifies the configuration of price estimation problems for different financial derivatives (call and put options, and futures) and solves them using various configurations of quantum amplitude estimation algorithms. For comparison between AE algorithms please refer to: *Compare_AE_algorithms_On_PriceEstimation.ipynb* 38 | 3. **qml4var**: This package allows to the user trains **PQC** that can be used as surrogate models of time consuming financial distribution functions. 39 | 4. **sine_integral**: this package allows the user to test the *QQuantLib.finance.quantum\_integration* module by estimating the defined integral of a sine function in two different domains. 40 | 41 | ## Acknowledgements 42 | 43 | This work is supported by the [NEASQC](https://cordis.europa.eu/project/id/951821) project, funded by the European Union's Horizon 2020 programme, Grant Agreement No. 951821. 44 | 45 | ## Documentation 46 | 47 | The html documentation of the **QQuantLib** library can be access at: https://neasqc.github.io/FinancialApplications 48 | ## Test it 49 | 50 | You can test the library in binder using following link: 51 | 52 | [Binder Link for QQuantLib](https://mybinder.org/v2/gh/NEASQC/FinancialApplications/HEAD) 53 | 54 | -------------------------------------------------------------------------------- /benchmark/README.md: -------------------------------------------------------------------------------- 1 | # Benchmark utilities 2 | 3 | This folder contains five different packages which allow to the user execute benchmarks for testing the more important parts of the *QQuantLib*: 4 | 5 | * **compare_ae_probability**: this package allows the user to test and compare the different quantum **AE** algorithms, from *QQuantLib*, easily. This can be done using the *probabiliy_estimation* module from the command line. How to use, results and more information can be found in the notebook *CompareAEalgorithmsOnPureProbability.ipynb* (located inside the folder). 6 | 7 | * **q_ae_price**: this package allows the user to test and compare different quantum **AE** algorithms, from **QQuantLib**, for pricing different options derivatives (using the **Black-Scholes** model for stock evolution). How to use, summary of results and more information can be found in the notebook *Compare_AE_algorithms_On_PriceEstimation.ipynb* (located inside of the folder). Two different modules can be found in the package: 8 | 9 | * *benchmark_ae_option_price.py*: allows the user compute the option price using **AE** algorithms for an user defined option problem (python benchmark_ae_option_price.py -h for help) 10 | 11 | * *benchmark_ae_option_price_step_po.py*: allows the user the compute the price of a derivative using different **AE** algorithms when the payoff function can take positive and negative values. In this case, the positive and negative parts of the payoff are loaded separately and two different estimations, using quantum **AE** algorithms, are obtained. These values should be post-processed to obtain the final desired value. 12 | 13 | * **sine_integral**: this package allows the user to test the *QQuantLib.finance.quantum\_integration* module by estimating the defined integral of a sine function in two different domains. How to use, results and more information can be found in the notebook: *QAE_SineIntegration_WindowQPE.ipynb* (located inside the folder). 14 | 15 | * **q_ae_cliquet**: this package allows the user to test and compare the different quantum **AE** algorithms, from *QQuantLib*, for pricing a type of exotic options: the *Cliquet Options* (under stock evolution using the *Black-Scholes* model). How to use, summary of results and more information can be found in the notebook *QAE_CliquetOptions.ipynb* (located inside of the folder). Two different modules can be found in the package: 16 | 17 | * *benchmark_cliquet.py*: computes the return of the configured Cliquet option using a properly configured *AE* algorithm (python benchmark_cliquet.py -h for help) 18 | 19 | * *benchmark_cliquet_step_po.py*: computes the return of the configured Cliquet option using a properly configured *AE* algorithm when the payoff function can take positive and negative values. In this case, the positive and negative parts of the payoff are loaded separately and two different estimations, using quantum **AE** algorithms, are obtained. These values should be post-processed to obtain the final desired value. 20 | 21 | 22 | * **qml4var**: this package allows the user to test the *QQuantLib.qml4var* package. The following different modules (that can be executed from the command line) can be found: 23 | 24 | * *data_sets*: this module allows to the user build datasets for training a **PQC**. The user can select between a random or a properly configured **Black-Scholes** (a.k.a. log-normal) distribution function. The module builds and stores the train and test datasets. 25 | 26 | * *new_training*: allows the user to train a properly configured **PQC** using a given training dataset, a configured Adam optimizer and the $R_{L^2, {\bar L}^2}^{S_{\chi}}$ loss function. 27 | 28 | * *new_training.py*: allows the user to continue the training of a **PQC** by loading the last stored trainable weights. The Loss function will be: $R_{L^2, {\bar L}^2}^{S_{\chi}}$ 29 | 30 | * *new_training_mse*: allows the user to train a properly configured **PQC** using a given training dataset, a configured Adam optimizer and the **Mean Square Error (MSE)** loss function. 31 | 32 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_base_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": [null], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [null], 16 | 17 | "alpha": [null], 18 | "shots": [null], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | "erqae_schedule" : [null], 23 | 24 | "multiplexor": [true], 25 | "mcz_qlm": [false], 26 | "file": [null] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_configuration_bayesqae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["BAYESQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6], 16 | 17 | "alpha": [0.05], 18 | 19 | "gamma": [null], 20 | "q": [null], 21 | "erqae_schedule" : [null], 22 | 23 | "particles" : [2000], 24 | "threshold" : [0.5], 25 | "kernel" : ["LW", "Metro"], 26 | "alpha_lw" : [0.9], 27 | "c" : [2.38], 28 | "k_0": [2], 29 | "T" : [3], 30 | "R" : [3], 31 | "n_evals" : [50], 32 | "shots": [1], 33 | "warm_shots": [10], 34 | "bayes_shots": [1], 35 | "control_bayes_shots" : [1], 36 | "save_smc_prob" : [200], 37 | "print_info" : [200], 38 | "max_iterations" : [200], 39 | 40 | "multiplexor": [true], 41 | "mcz_qlm": [false], 42 | "file": ["BAYESQAE"] 43 | 44 | } 45 | ] 46 | 47 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_configuration_cqpeae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["CQPEAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [10, 12, 14, 16], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [null], 16 | 17 | "alpha": [null], 18 | "shots": [100], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | "erqae_schedule" : [null], 23 | 24 | "multiplexor": [true], 25 | "mcz_qlm": [false], 26 | "file": ["CQPEAE"] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_configuration_erqae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["eRQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5], 16 | 17 | "alpha": [null], 18 | "shots": [null], 19 | 20 | "gamma": [0.05], 21 | "q": [2.0], 22 | "erqae_schedule" : [ 23 | {"type": "exp_const", "ratio_slope_k": 2, "ratio_slope_gamma": null}, 24 | {"type": "exp_const", "ratio_slope_k": 5, "ratio_slope_gamma": null}, 25 | {"type": "exp_const", "ratio_slope_k": 10, "ratio_slope_gamma": null}, 26 | {"type": "linear_const", "ratio_slope_k": 2, "ratio_slope_gamma": null}, 27 | {"type": "linear_const", "ratio_slope_k": 10, "ratio_slope_gamma": null}, 28 | {"type": "linear_const", "ratio_slope_k": 5, "ratio_slope_gamma": null}, 29 | {"type": "linear_linear", "ratio_slope_k": 2, "ratio_slope_gamma": 2}, 30 | {"type": "linear_linear", "ratio_slope_k": 2, "ratio_slope_gamma": 5}, 31 | {"type": "linear_linear", "ratio_slope_k": 2, "ratio_slope_gamma": 10}, 32 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": 2}, 33 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": 5}, 34 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": 10}, 35 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": -2}, 36 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": -5}, 37 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": -10} 38 | ], 39 | 40 | "multiplexor": [true], 41 | "mcz_qlm": [false], 42 | "file": ["eRQAE"] 43 | } 44 | ] 45 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_configuration_iqae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["IQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6], 16 | 17 | "alpha": [0.05], 18 | "shots": [100], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | "erqae_schedule" : [null], 23 | 24 | "multiplexor": [true], 25 | "mcz_qlm": [false], 26 | "file": ["IQAE"] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_configuration_miqae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["mIQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6], 16 | 17 | "alpha": [0.05], 18 | "shots": [100], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | "erqae_schedule" : [null], 23 | 24 | "multiplexor": [true], 25 | "mcz_qlm": [false], 26 | "file": ["mIQAE"] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_configuration_mlae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["MLAE"], 4 | 5 | "schedule": [ 6 | [ 7 | [1, 2, 3, 4], 8 | [100, 100, 100, 100] 9 | ], 10 | [ 11 | [1, 2, 3, 4, 5, 6, 7], 12 | [100, 100, 100, 100, 100, 100, 100] 13 | ], 14 | [ 15 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 16 | [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100] 17 | ], 18 | [ 19 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 20 | [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100] 21 | ], 22 | [ 23 | [1, 2, 4], 24 | [100, 100, 100] 25 | ], 26 | [ 27 | [1, 2, 4, 8], 28 | [100, 100, 100, 100] 29 | ], 30 | [ 31 | [1, 2, 4, 8, 16], 32 | [100, 100, 100, 100, 100] 33 | ], 34 | [ 35 | [1, 2, 4, 8, 16, 32], 36 | [100, 100, 100, 100, 100, 100] 37 | ], 38 | [ 39 | [1, 2, 4, 8, 16, 32, 64], 40 | [100, 100, 100, 100, 100, 100, 100] 41 | ] 42 | 43 | ], 44 | "delta": [1.0e-7], 45 | "ns": [10000], 46 | 47 | "auxiliar_qbits_number": [null], 48 | "window" : [null], 49 | "kaiser_alpha" : [null], 50 | 51 | "cbits_number": [null], 52 | 53 | "epsilon": [null], 54 | 55 | "alpha": [null], 56 | "shots": [null], 57 | 58 | "gamma": [null], 59 | "q": [null], 60 | "erqae_schedule" : [null], 61 | 62 | "multiplexor": [true], 63 | "mcz_qlm": [false], 64 | "file": ["MLAE"] 65 | } 66 | ] 67 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_configuration_mrqae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["mRQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6], 16 | 17 | "alpha": [null], 18 | "shots": [null], 19 | 20 | "gamma": [0.05], 21 | "q": [2.0], 22 | "erqae_schedule" : [null], 23 | 24 | "multiplexor": [true], 25 | "mcz_qlm": [false], 26 | "file": ["mRQAE"] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_configuration_rqae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["RQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6], 16 | 17 | "alpha": [null], 18 | "shots": [null], 19 | 20 | "gamma": [0.05], 21 | "q": [2.0], 22 | "erqae_schedule" : [null], 23 | 24 | "multiplexor": [true], 25 | "mcz_qlm": [false], 26 | "file": ["RQAE"] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/ae_configuration_srqae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["sRQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6], 16 | 17 | "alpha": [null], 18 | "shots": [100], 19 | 20 | "gamma": [0.05], 21 | "q": [2.0], 22 | "erqae_schedule" : [null], 23 | 24 | "multiplexor": [true], 25 | "mcz_qlm": [false], 26 | "file": ["sRQAE"] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/density_probability.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "probability_type": ["Black-Scholes"], 4 | "s_0": [1], 5 | "risk_free_rate": [0.05], 6 | "maturity": [1.0], 7 | "volatility": [0.5] 8 | } 9 | ] 10 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/domain_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "x0": [0.01], 4 | "xf": [4.0], 5 | "n_qbits": [5] 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/qpu_ideal.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "qpu_type": ["c"], 5 | "t_gate_1qb" : [null], 6 | "t_gate_2qbs" : [null], 7 | "t_readout": [null], 8 | "depol_channel" : [{ 9 | "active": false, 10 | "error_gate_1qb" : null, 11 | "error_gate_2qbs" : null 12 | }], 13 | "idle" : [{ 14 | "amplitude_damping": false, 15 | "dephasing_channel": false, 16 | "t1" : null, 17 | "t2" : null 18 | }], 19 | "meas": [{ 20 | "active":false, 21 | "readout_error": null 22 | }] 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /benchmark/compare_ae_probability/jsons/qpu_noisy.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "qpu_type": ["ideal"], 5 | "t_gate_1qb" : [null], 6 | "t_gate_2qbs" : [null], 7 | "t_readout": [null], 8 | "depol_channel" : [{ 9 | "active": false, 10 | "error_gate_1qb" : null, 11 | "error_gate_2qbs" : null 12 | }], 13 | "idle" : [{ 14 | "amplitude_damping": false, 15 | "dephasing_channel": false, 16 | "t1" : null, 17 | "t2" : null 18 | }], 19 | "meas": [{ 20 | "active":false, 21 | "readout_error": null 22 | }] 23 | }, 24 | { 25 | "qpu_type": ["noisy"], 26 | "t_gate_1qb" : [35], 27 | "t_gate_2qbs" : [660], 28 | "t_readout": [null], 29 | "depol_channel" : [{ 30 | "active": true, 31 | "error_gate_1qb" : 2.27e-4, 32 | "error_gate_2qbs" : 7.741e-3 33 | }], 34 | "idle" : [{ 35 | "amplitude_damping": true, 36 | "dephasing_channel": true, 37 | "t1" : 0.232e6, 38 | "t2" : 0.133e6 39 | }], 40 | "meas": [{ 41 | "active":false, 42 | "readout_error": null 43 | }] 44 | }, 45 | { 46 | "qpu_type": ["noisy"], 47 | "t_gate_1qb" : [35], 48 | "t_gate_2qbs" : [660], 49 | "t_readout": [null], 50 | "depol_channel" : [{ 51 | "active": true, 52 | "error_gate_1qb" : 2.27e-5, 53 | "error_gate_2qbs" : 7.741e-4 54 | }], 55 | "idle" : [{ 56 | "amplitude_damping": true, 57 | "dephasing_channel": true, 58 | "t1" : 2.32e6, 59 | "t2" : 1.33e6 60 | }], 61 | "meas": [{ 62 | "active":false, 63 | "readout_error": null 64 | }] 65 | }, 66 | { 67 | "qpu_type": ["noisy"], 68 | "t_gate_1qb" : [35], 69 | "t_gate_2qbs" : [660], 70 | "t_readout": [null], 71 | "depol_channel" : [{ 72 | "active": true, 73 | "error_gate_1qb" : 2.27e-6, 74 | "error_gate_2qbs" : 7.741e-5 75 | }], 76 | "idle" : [{ 77 | "amplitude_damping": true, 78 | "dephasing_channel": true, 79 | "t1" : 23.2e6, 80 | "t2" : 13.3e6 81 | }], 82 | "meas": [{ 83 | "active":false, 84 | "readout_error": null 85 | }] 86 | }, 87 | { 88 | "qpu_type": ["noisy"], 89 | "t_gate_1qb" : [35], 90 | "t_gate_2qbs" : [660], 91 | "t_readout": [null], 92 | "depol_channel" : [{ 93 | "active": true, 94 | "error_gate_1qb" : 2.27e-7, 95 | "error_gate_2qbs" : 7.741e-6 96 | }], 97 | "idle" : [{ 98 | "amplitude_damping": true, 99 | "dephasing_channel": true, 100 | "t1" : 232.0e6, 101 | "t2" : 133.0e6 102 | }], 103 | "meas": [{ 104 | "active":false, 105 | "readout_error": null 106 | }] 107 | }, 108 | { 109 | "qpu_type": ["noisy"], 110 | "t_gate_1qb" : [35], 111 | "t_gate_2qbs" : [660], 112 | "t_readout": [null], 113 | "depol_channel" : [{ 114 | "active": true, 115 | "error_gate_1qb" : 2.27e-8, 116 | "error_gate_2qbs" : 7.741e-7 117 | }], 118 | "idle" : [{ 119 | "amplitude_damping": true, 120 | "dephasing_channel": true, 121 | "t1" : 2320.0e6, 122 | "t2" : 1330.0e6 123 | }], 124 | "meas": [{ 125 | "active":false, 126 | "readout_error": null 127 | }] 128 | }, 129 | { 130 | "qpu_type": ["noisy"], 131 | "t_gate_1qb" : [35], 132 | "t_gate_2qbs" : [660], 133 | "t_readout": [null], 134 | "depol_channel" : [{ 135 | "active": true, 136 | "error_gate_1qb" : 2.27e-9, 137 | "error_gate_2qbs" : 7.741e-8 138 | }], 139 | "idle" : [{ 140 | "amplitude_damping": true, 141 | "dephasing_channel": true, 142 | "t1" : 23200.0e6, 143 | "t2" : 13300.0e6 144 | }], 145 | "meas": [{ 146 | "active":false, 147 | "readout_error": null 148 | }] 149 | } 150 | ] 151 | -------------------------------------------------------------------------------- /benchmark/q_ae_cliquet/asset_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "n_qbits" : [6], 4 | "s_0": [1], 5 | "risk_free_rate": [0.05], 6 | "volatility": [0.5], 7 | "bounds" : [7.0], 8 | "reset_dates" : [[0.0, 1.0, 2.0]] 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /benchmark/q_ae_cliquet/bayesqae_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["mIQAE"], 4 | "file": ["mIQAE"], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [null], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5], 17 | 18 | "alpha": [0.05], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | 23 | "erqae_schedule" :[null], 24 | 25 | "particles" : [2000], 26 | "threshold" : [0.5], 27 | "kernel" : ["LW", "Metro"], 28 | "alpha_lw" : [0.9], 29 | "c" : [2.38], 30 | "k_0": [2], 31 | "T" : [3], 32 | "R" : [3], 33 | "n_evals" : [50], 34 | "shots": [1], 35 | "warm_shots": [10], 36 | "bayes_shots": [1], 37 | "control_bayes_shots" : [1], 38 | "save_smc_prob" : [200], 39 | "print_info" : [200], 40 | "max_iterations" : [200], 41 | 42 | "encoding" : [0, 2], 43 | "multiplexor": [true], 44 | 45 | "mcz_qlm": [false], 46 | "shots": [100] 47 | } 48 | ] 49 | -------------------------------------------------------------------------------- /benchmark/q_ae_cliquet/cliquet_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "local_cap" : [0.1], 4 | "local_floor" : [-0.1], 5 | "global_cap" : [0.2], 6 | "global_floor": [-0.2] 7 | } 8 | ] 9 | -------------------------------------------------------------------------------- /benchmark/q_ae_cliquet/iqae_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["IQAE"], 4 | "file": ["IQAE"], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [null], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [1.0e-2], 17 | 18 | "alpha": [0.05], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | 23 | "erqae_schedule" :[null], 24 | 25 | "encoding" : [2], 26 | "multiplexor": [true], 27 | 28 | "mcz_qlm": [false], 29 | "shots": [100], 30 | "number_of_tests": [10] 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /benchmark/q_ae_cliquet/miqae_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["mIQAE"], 4 | "file": ["mIQAE"], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [null], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5], 17 | 18 | "alpha": [0.05], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | 23 | "erqae_schedule" :[null], 24 | 25 | "encoding" : [0, 2], 26 | "multiplexor": [true], 27 | 28 | "mcz_qlm": [false], 29 | "shots": [100] 30 | } 31 | ] 32 | -------------------------------------------------------------------------------- /benchmark/q_ae_cliquet/mrqae_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["mRQAE"], 4 | "file": ["mRQAE"], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [null], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5], 17 | 18 | "alpha": [null], 19 | 20 | "gamma": [0.05], 21 | "q": [2], 22 | 23 | "erqae_schedule" :[null], 24 | 25 | "encoding" : [2], 26 | "multiplexor": [true], 27 | 28 | "mcz_qlm": [false], 29 | "shots": [null] 30 | } 31 | ] 32 | -------------------------------------------------------------------------------- /benchmark/q_ae_cliquet/qpu_ideal.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "qpu_type": ["c"], 5 | "t_gate_1qb" : [null], 6 | "t_gate_2qbs" : [null], 7 | "t_readout": [null], 8 | "depol_channel" : [{ 9 | "active": false, 10 | "error_gate_1qb" : null, 11 | "error_gate_2qbs" : null 12 | }], 13 | "idle" : [{ 14 | "amplitude_damping": false, 15 | "dephasing_channel": false, 16 | "t1" : null, 17 | "t2" : null 18 | }], 19 | "meas": [{ 20 | "active":false, 21 | "readout_error": null 22 | }] 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/ae_base_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": [null], 4 | "file": [null], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [null], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [null], 17 | 18 | "alpha": [null], 19 | "shots": [null], 20 | 21 | "gamma": [null], 22 | "q": [null], 23 | "erqae_schedule" :[null], 24 | 25 | "encoding" : [0, 1, 2], 26 | "multiplexor": [true], 27 | "mcz_qlm": [false] 28 | } 29 | ] 30 | 31 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/bayes_configuration.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "ae_type": ["BAYESQAE"], 5 | "file": ["BAYESQAE"], 6 | 7 | 8 | "schedule": [null], 9 | "delta": [null], 10 | "ns": [null], 11 | 12 | "auxiliar_qbits_number": [null], 13 | "window" : [null], 14 | "kaiser_alpha" : [null], 15 | 16 | "cbits_number": [null], 17 | 18 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5], 19 | 20 | "alpha": [0.05], 21 | 22 | "gamma": [null], 23 | "q": [null], 24 | 25 | "erqae_schedule" :[null], 26 | 27 | "mcz_qlm": [false], 28 | "particles" : [2000], 29 | "threshold" : [0.5], 30 | "kernel" : ["LW", "Metro"], 31 | "alpha_lw" : [0.9], 32 | "c" : [2.38], 33 | "k_0": [2], 34 | "T" : [3], 35 | "R" : [3], 36 | "n_evals" : [50], 37 | "warm_shots": [10], 38 | "bayes_shots": [1], 39 | "control_bayes_shots" : [1], 40 | "save_smc_prob" : [200], 41 | "print_info" : [200], 42 | "max_iterations" : [200], 43 | 44 | "encoding" : [0, 2], 45 | "multiplexor": [true], 46 | 47 | "mcz_qlm": [false], 48 | "shots": [1], 49 | "number_of_tests": [10] 50 | } 51 | ] 52 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/cqpeae_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["CQPEAE"], 4 | "file": ["CQPEAE"], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [10, 12, 14, 16], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [null], 17 | 18 | "alpha": [null], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | 23 | "erqae_schedule" :[null], 24 | 25 | "encoding" : [0], 26 | "multiplexor": [true], 27 | 28 | "mcz_qlm": [false], 29 | "shots": [100], 30 | "number_of_tests": [null] 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/density_probability.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "probability_type": ["Black-Scholes"], 4 | "s_0": [1], 5 | "risk_free_rate": [0.05], 6 | "maturity": [1.0], 7 | "volatility": [0.5] 8 | } 9 | ] 10 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/domain_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "x0": [0.01], 4 | "xf": [5.0], 5 | "n_qbits": [5] 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/erqae_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["eRQAE"], 4 | "file": ["eRQAE"], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [null], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6], 17 | 18 | "alpha": [null], 19 | 20 | "gamma": [0.05], 21 | "q": [null], 22 | 23 | "erqae_schedule" :[ 24 | {"type": "exp_const", "ratio_slope_k": 2, "ratio_slope_gamma": null}, 25 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": 2}, 26 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": -2}, 27 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": -4} 28 | ], 29 | 30 | "encoding" : [0, 2], 31 | "multiplexor": [true], 32 | 33 | "mcz_qlm": [false], 34 | "shots": [100], 35 | "number_of_tests": [5] 36 | } 37 | ] 38 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/iqae_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["IQAE"], 4 | "file": ["IQAE"], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [null], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5], 17 | 18 | "alpha": [0.05], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | 23 | "erqae_schedule" :[null], 24 | 25 | "encoding" : [0, 2], 26 | "multiplexor": [true], 27 | 28 | "mcz_qlm": [false], 29 | "shots": [100], 30 | "number_of_tests": [10] 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/miqae_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["mIQAE"], 4 | "file": ["IQAE"], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [null], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6], 17 | 18 | "alpha": [0.05], 19 | 20 | "gamma": [null], 21 | "q": [null], 22 | 23 | "erqae_schedule" :[null], 24 | 25 | "encoding" : [0, 2], 26 | "multiplexor": [true], 27 | 28 | "mcz_qlm": [false], 29 | "shots": [100], 30 | "number_of_tests": [10] 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/payoffs.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pay_off_type": ["European_Call_Option"], 4 | "strike": [0.5], 5 | "coupon": [null] 6 | }, 7 | { 8 | "pay_off_type": ["European_Put_Option"], 9 | "strike": [1.5], 10 | "coupon": [null] 11 | }, 12 | { 13 | "pay_off_type": ["Futures"], 14 | "strike": [0.5, 1.0, 1.5], 15 | "coupon": [null] 16 | }, 17 | { 18 | "pay_off_type": ["Digital_Call_Option"], 19 | "strike": [0.5], 20 | "coupon": [1.0] 21 | }, 22 | { 23 | "pay_off_type": ["Digital_Put_Option"], 24 | "strike": [1.5], 25 | "coupon": [1.0] 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/qpu_ideal.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "qpu_type": ["c", "python", "linalg", "mps", "qlmass_linalg", "qlmass_mps"], 5 | "t_gate_1qb" : [null], 6 | "t_gate_2qbs" : [null], 7 | "t_readout": [null], 8 | "depol_channel" : [{ 9 | "active": false, 10 | "error_gate_1qb" : null, 11 | "error_gate_2qbs" : null 12 | }], 13 | "idle" : [{ 14 | "amplitude_damping": false, 15 | "dephasing_channel": false, 16 | "t1" : null, 17 | "t2" : null 18 | }], 19 | "meas": [{ 20 | "active":false, 21 | "readout_error": null 22 | }] 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/qpu_noisy.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "qpu_type": ["ideal"], 5 | "t_gate_1qb" : [null], 6 | "t_gate_2qbs" : [null], 7 | "t_readout": [null], 8 | "depol_channel" : [{ 9 | "active": false, 10 | "error_gate_1qb" : null, 11 | "error_gate_2qbs" : null 12 | }], 13 | "idle" : [{ 14 | "amplitude_damping": false, 15 | "dephasing_channel": false, 16 | "t1" : null, 17 | "t2" : null 18 | }], 19 | "meas": [{ 20 | "active":false, 21 | "readout_error": null 22 | }] 23 | }, 24 | { 25 | "qpu_type": ["noisy"], 26 | "t_gate_1qb" : [35], 27 | "t_gate_2qbs" : [660], 28 | "t_readout": [4000], 29 | "depol_channel" : [{ 30 | "active": true, 31 | "error_gate_1qb" : 1.0e-4, 32 | "error_gate_2qbs" : 1.0e-3 33 | }], 34 | "idle" : [{ 35 | "amplitude_damping": false, 36 | "dephasing_channel": false, 37 | "t1" : null, 38 | "t2" : null 39 | }], 40 | "meas": [{ 41 | "active":false, 42 | "readout_error": null 43 | }] 44 | }, 45 | { 46 | "qpu_type": ["noisy"], 47 | "t_gate_1qb" : [35], 48 | "t_gate_2qbs" : [660], 49 | "t_readout": [4000], 50 | "depol_channel" : [{ 51 | "active": true, 52 | "error_gate_1qb" : 1.0e-4, 53 | "error_gate_2qbs" : 1.0e-3 54 | }], 55 | "idle" : [{ 56 | "amplitude_damping": true, 57 | "dephasing_channel": false, 58 | "t1" : 0.2e6, 59 | "t2" : null 60 | }], 61 | "meas": [{ 62 | "active":false, 63 | "readout_error": null 64 | }] 65 | }, 66 | { 67 | "qpu_type": ["noisy"], 68 | "t_gate_1qb" : [35], 69 | "t_gate_2qbs" : [660], 70 | "t_readout": [4000], 71 | "depol_channel" : [{ 72 | "active": true, 73 | "error_gate_1qb" : 1.0e-4, 74 | "error_gate_2qbs" : 1.0e-3 75 | }], 76 | "idle" : [{ 77 | "amplitude_damping": false, 78 | "dephasing_channel": true, 79 | "t1" : 0.2e6, 80 | "t2" : 0.1e6 81 | }], 82 | "meas": [{ 83 | "active":false, 84 | "readout_error": null 85 | }] 86 | }, 87 | { 88 | "qpu_type": ["noisy"], 89 | "t_gate_1qb" : [35], 90 | "t_gate_2qbs" : [660], 91 | "t_readout": [4000], 92 | "depol_channel" : [{ 93 | "active": true, 94 | "error_gate_1qb" : 1.0e-4, 95 | "error_gate_2qbs" : 1.0e-3 96 | }], 97 | "idle" : [{ 98 | "amplitude_damping": true, 99 | "dephasing_channel": true, 100 | "t1" : 0.2e6, 101 | "t2" : 0.1e6 102 | }], 103 | "meas": [{ 104 | "active":false, 105 | "readout_error": null 106 | }] 107 | }, 108 | { 109 | "qpu_type": ["noisy"], 110 | "t_gate_1qb" : [35], 111 | "t_gate_2qbs" : [660], 112 | "t_readout": [4000], 113 | "depol_channel" : [{ 114 | "active": true, 115 | "error_gate_1qb" : 1.0e-4, 116 | "error_gate_2qbs" : 1.0e-3 117 | }], 118 | "idle" : [{ 119 | "amplitude_damping": false, 120 | "dephasing_channel": false, 121 | "t1" : null, 122 | "t2" : null 123 | }], 124 | "meas": [{ 125 | "active":true, 126 | "readout_error": 1.370e-2 127 | }] 128 | }, 129 | { 130 | "qpu_type": ["noisy"], 131 | "t_gate_1qb" : [35], 132 | "t_gate_2qbs" : [660], 133 | "t_readout": [4000], 134 | "depol_channel" : [{ 135 | "active": true, 136 | "error_gate_1qb" : 1.0e-4, 137 | "error_gate_2qbs" : 1.0e-3 138 | }], 139 | "idle" : [{ 140 | "amplitude_damping": true, 141 | "dephasing_channel": true, 142 | "t1" : 0.2e6, 143 | "t2" : 0.1e6 144 | }], 145 | "meas": [{ 146 | "active":true, 147 | "readout_error": 1.370e-2 148 | }] 149 | }, 150 | { 151 | "qpu_type": ["noisy"], 152 | "t_gate_1qb" : [35], 153 | "t_gate_2qbs" : [660], 154 | "t_readout": [4000], 155 | "depol_channel" : [{ 156 | "active": false, 157 | "error_gate_1qb" : null, 158 | "error_gate_2qbs" : null 159 | }], 160 | "idle" : [{ 161 | "amplitude_damping": true, 162 | "dephasing_channel": true, 163 | "t1" : 0.2e6, 164 | "t2" : 0.1e6 165 | }], 166 | "meas": [{ 167 | "active":true, 168 | "readout_error": 1.370e-2 169 | }] 170 | }, 171 | { 172 | "qpu_type": ["noisy"], 173 | "t_gate_1qb" : [35], 174 | "t_gate_2qbs" : [660], 175 | "t_readout": [4000], 176 | "depol_channel" : [{ 177 | "active": false, 178 | "error_gate_1qb" : null, 179 | "error_gate_2qbs" : null 180 | }], 181 | "idle" : [{ 182 | "amplitude_damping": false, 183 | "dephasing_channel": false, 184 | "t1" : null, 185 | "t2" : null 186 | }], 187 | "meas": [{ 188 | "active":true, 189 | "readout_error": 1.370e-2 190 | }] 191 | } 192 | ] 193 | -------------------------------------------------------------------------------- /benchmark/q_ae_price/jsons/rqae_configuration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["RQAE"], 4 | "file": ["RQAE"], 5 | 6 | "schedule": [null], 7 | "delta": [null], 8 | "ns": [null], 9 | 10 | "auxiliar_qbits_number": [null], 11 | "window" : [null], 12 | "kaiser_alpha" : [null], 13 | 14 | "cbits_number": [null], 15 | 16 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6], 17 | 18 | "alpha": [null], 19 | 20 | "gamma": [0.05], 21 | "q": [2], 22 | 23 | "erqae_schedule" :[null], 24 | 25 | "encoding" : [1, 2], 26 | "multiplexor": [true], 27 | 28 | "mcz_qlm": [false], 29 | "shots": [100], 30 | "number_of_tests": [5] 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /benchmark/qml4var/JSONs/base_optimizer.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "epochs" : 20, 4 | "tolerance" : 1.0e-5, 5 | "learning_rate" : 0.1, 6 | "beta1" : 0.9, 7 | "beta2" : 0.999, 8 | "print_step" : 2, 9 | "n_counts_tolerance" : 5, 10 | "nbshots" : 0, 11 | "points": 100 12 | } 13 | -------------------------------------------------------------------------------- /benchmark/qml4var/JSONs/base_pqc.json: -------------------------------------------------------------------------------- 1 | { 2 | "features_number": 1, 3 | "n_qubits_by_feature": 1, 4 | "n_layers": 1 5 | } 6 | 7 | -------------------------------------------------------------------------------- /benchmark/qml4var/JSONs/bs.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "n_points_train": 250, 4 | "n_points_test": 100, 5 | "features_number" : 1, 6 | "minval": 0.1, 7 | "maxval": 3.0, 8 | "distribution" : "bs", 9 | "s_0" : 1.0, 10 | "risk_free_rate" : 0.0, 11 | "maturity" : 0.5, 12 | "volatility" : 0.5 13 | } 14 | -------------------------------------------------------------------------------- /benchmark/qml4var/JSONs/new_optimizer.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "epochs" : 200, 4 | "tolerance" : 1.0e-7, 5 | "learning_rate" : 0.1, 6 | "beta1" : 0.9, 7 | "beta2" : 0.999, 8 | "print_step" : 10, 9 | "n_counts_tolerance" : 200, 10 | "nbshots" : 0, 11 | "points": 100 12 | } 13 | -------------------------------------------------------------------------------- /benchmark/qml4var/JSONs/new_pqc.json: -------------------------------------------------------------------------------- 1 | { 2 | "features_number": 1, 3 | "n_qubits_by_feature": 2, 4 | "n_layers": 3 5 | } 6 | 7 | -------------------------------------------------------------------------------- /benchmark/qml4var/JSONs/qpu_ideal.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "qpu_type": ["c", "python", "linalg", "mps", "qlmass_linalg", "qlmass_mps"], 5 | "t_gate_1qb" : [null], 6 | "t_gate_2qbs" : [null], 7 | "t_readout": [null], 8 | "depol_channel" : [{ 9 | "active": false, 10 | "error_gate_1qb" : null, 11 | "error_gate_2qbs" : null 12 | }], 13 | "idle" : [{ 14 | "amplitude_damping": false, 15 | "dephasing_channel": false, 16 | "t1" : null, 17 | "t2" : null 18 | }], 19 | "meas": [{ 20 | "active":false, 21 | "readout_error": null 22 | }] 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /benchmark/qml4var/JSONs/random.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "n_points_train": 10, 4 | "n_points_test": 100, 5 | "features_number" : 1, 6 | "minval": -3.141592653589793, 7 | "maxval": 3.141592653589793, 8 | "distribution" : "random" 9 | } 10 | -------------------------------------------------------------------------------- /benchmark/qml4var/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/benchmark/qml4var/__init__.py -------------------------------------------------------------------------------- /benchmark/qml4var/data_sets.py: -------------------------------------------------------------------------------- 1 | """ 2 | Functions for creating DataSets 3 | """ 4 | import json 5 | import sys 6 | import numpy as np 7 | from scipy.stats import norm, multivariate_normal 8 | from itertools import product 9 | sys.path.append("../../") 10 | from QQuantLib.qml4var.data_utils import empirical_cdf, bs_cdf, \ 11 | bs_samples, saving_datasets 12 | 13 | 14 | def create_random_data(**kwargs): 15 | """ 16 | Create DataSets 17 | 18 | Parameters 19 | ---------- 20 | kwargs : keyworg arguments: 21 | n_points_train : int. Number of points for training 22 | n_points_test : int. Number of points for testing 23 | min_val : float, int or list. Minimun value for testing dataset 24 | max_val : float, int or list. Maximum value for testing dataset 25 | features_number : number of features 26 | Returns 27 | ------ 28 | 29 | train_x : numpy array 30 | Array with the training dataset features: 31 | shape = (n_points_train, features_number) 32 | train_y : numpy array 33 | Array with the training dataset labels 34 | shape = (n_points_train, 1) 35 | test_x : numpy array 36 | Array with the testing dataset features 37 | shape = (n_points_test, features_number) 38 | test_y : numpy array 39 | Array with the testing dataset labels 40 | shape = (n_points_test, 1) 41 | """ 42 | 43 | n_points_train = kwargs.get("n_points_train", None) 44 | n_points_test = kwargs.get("n_points_test", None) 45 | minval = kwargs.get("minval", None) 46 | maxval = kwargs.get("maxval", None) 47 | # Create Features 48 | feature_number = kwargs.get("features_number", 1) 49 | train_x = np.random.normal(size=(n_points_train, feature_number)) 50 | # Build minval and maxval for properly dimension array generation 51 | if type(minval) in [list, float, int]: 52 | if type(maxval) in [list, float, int]: 53 | if not isinstance(maxval, list) and not isinstance(minval, list): 54 | minval = [minval] * feature_number 55 | maxval = [maxval] * feature_number 56 | else: 57 | raise ValueError("maxval SHOULD BE: int, float or list") 58 | else: 59 | raise ValueError("minval SHOULD BE: int, float or list") 60 | 61 | test_x = np.linspace(minval, maxval, n_points_test) 62 | test_x = np.array(list( 63 | product(*[test_x[:, i] for i in range(test_x.shape[1])]) 64 | )) 65 | print(test_x.shape) 66 | # Create Labels 67 | train_y = empirical_cdf(train_x) - 0.5 68 | train_y = train_y.reshape((-1, 1)) 69 | if feature_number == 1: 70 | test_y = norm.cdf(test_x) - 0.5 71 | elif feature_number > 1: 72 | means_ = [0] * feature_number 73 | covs_ = [ 74 | [int(i == j) for j in range(feature_number)] \ 75 | for i in range(feature_number) 76 | ] 77 | mnorm = multivariate_normal(mean=means_, cov=covs_) 78 | test_y = mnorm.cdf(test_x) - 0.5 79 | test_y = test_y.reshape((-1, 1)) 80 | # Saving datasets and info 81 | saving_datasets(train_x, train_y, test_x, test_y, **kwargs) 82 | return train_x, train_y, test_x, test_y 83 | 84 | def create_bs_data(**kwargs): 85 | """ 86 | Create DataSets with Black Scholes. Only for 1 input feature 87 | 88 | Parameters 89 | ---------- 90 | kwargs : keyworg arguments. In addition to the kwargs provided to 91 | create_random_data function the following arguments for configuring 92 | BS CDF can be provided. BE AWARE: features_number MUST BE 1: 93 | s_0 : initial value of the stock 94 | risk_free_rate: risk free rate 95 | volatility: volatility of the stock 96 | maturity: maturity of the stock 97 | 98 | Returns 99 | ------ 100 | 101 | train_x : numpy array 102 | Array with the training dataset features 103 | shape = (n_points_train, 1) 104 | train_y : numpy array 105 | Array with the training dataset labels 106 | shape = (n_points_train, 1) 107 | test_x : numpy array 108 | Array with the testing dataset features 109 | shape = (n_points_test, 1) 110 | test_y : numpy array 111 | Array with the testing dataset labels 112 | shape = (n_points_test, 1) 113 | """ 114 | n_points_train = kwargs.get("n_points_train", None) 115 | n_points_test = kwargs.get("n_points_test", None) 116 | minval = kwargs.get("minval", None) 117 | maxval = kwargs.get("maxval", None) 118 | # Create Features 119 | feature_number = kwargs.get("features_number", 1) 120 | # Build minval and maxval for properly dimension array generation 121 | if type(minval) != float: 122 | raise ValueError("minval SHOULD BE a float") 123 | if type(maxval) != float: 124 | raise ValueError("maxval SHOULD BE a float") 125 | train_x = bs_samples(n_points_train, **kwargs) 126 | train_x = train_x.reshape((-1, 1)) 127 | test_x = np.linspace(minval, maxval, n_points_test) 128 | test_x = test_x.reshape((-1, 1)) 129 | # Create Labels 130 | train_y = empirical_cdf( 131 | np.reshape(train_x, (n_points_train, feature_number))) - 0.5 132 | test_y = bs_cdf(test_x, **kwargs) - 0.5 133 | 134 | # Saving datasets and info 135 | saving_datasets(train_x, train_y, test_x, test_y, **kwargs) 136 | return train_x, train_y, test_x, test_y 137 | 138 | if __name__ == "__main__": 139 | 140 | 141 | import argparse 142 | import os 143 | parser = argparse.ArgumentParser() 144 | parser.add_argument( 145 | "-json", 146 | dest="json_arg", 147 | type=str, 148 | default="./random.json", 149 | help="JSON file with the data configuration", 150 | ) 151 | parser.add_argument( 152 | "-folder", 153 | dest="folder_path", 154 | type=str, 155 | help="Path for storing data", 156 | default=None, 157 | ) 158 | parser.add_argument( 159 | "-base_name", 160 | dest="base_name", 161 | type=str, 162 | help="Base name for csv with datasets", 163 | default="base_name", 164 | ) 165 | parser.add_argument( 166 | "--save", 167 | dest="save", 168 | default=False, 169 | action="store_true", 170 | help="For saving datasets", 171 | ) 172 | args = parser.parse_args() 173 | with open(args.json_arg) as json_file: 174 | data_cfg = json.load(json_file) 175 | 176 | data_cfg.update({"name_for_saving":None}) 177 | if args.save: 178 | if not os.path.exists(args.folder_path): 179 | os.makedirs(args.folder_path) 180 | name_for_saving = args.folder_path + "/" + args.base_name 181 | print(name_for_saving) 182 | data_cfg.update({"folder_path":args.folder_path}) 183 | data_cfg.update({"name_for_saving":name_for_saving}) 184 | 185 | print(data_cfg) 186 | if data_cfg["distribution"] == "bs": 187 | x_train, y_train, x_test, y_test = create_bs_data(**data_cfg) 188 | elif data_cfg["distribution"] == "random": 189 | x_train, y_train, x_test, y_test = create_random_data(**data_cfg) 190 | -------------------------------------------------------------------------------- /benchmark/qml4var/random/data.json: -------------------------------------------------------------------------------- 1 | {"n_points_train": 10, "n_points_test": 100, "feature_number": 1, "minval": -3.141592653589793, "maxval": 3.141592653589793, "distribution": "random", "name_for_saving": "./random/random", "folder_path": "./random"} -------------------------------------------------------------------------------- /benchmark/sine_integral/jsons/qae_sine_bayes.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["BAYESQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [0.01, 0.001], 16 | 17 | "alpha": [0.05], 18 | 19 | "gamma": [null], 20 | "q": [null], 21 | "erqae_schedule" : [null], 22 | 23 | "multiplexor": [true], 24 | 25 | "mcz_qlm": [false], 26 | "particles" : [2000], 27 | "threshold" : [0.5], 28 | "kernel" : ["LW", "Metro"], 29 | "alpha_lw" : [0.9], 30 | "c" : [2.38], 31 | "k_0": [2], 32 | "T" : [3], 33 | "R" : [3], 34 | "n_evals" : [50], 35 | "warm_shots": [10], 36 | "bayes_shots": [1], 37 | "control_bayes_shots" : [1], 38 | "shots": [1], 39 | "save_smc_prob" : [200], 40 | "print_info" : [200], 41 | "max_iterations" : [200] 42 | } 43 | ] 44 | -------------------------------------------------------------------------------- /benchmark/sine_integral/jsons/qae_sine_cqpeae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["CQPEAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [4, 5, 6, 7, 8, 9, 10, 11], 10 | "window" : [null, "Sine", "Kaise"], 11 | "kaiser_alpha" : [0.1, 10, 100], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [null], 16 | 17 | "alpha": [null], 18 | 19 | "gamma": [null], 20 | "q": [null], 21 | "erqae_schedule" : [null], 22 | 23 | "multiplexor": [true], 24 | 25 | "mcz_qlm": [false], 26 | "shots": [0] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/sine_integral/jsons/qae_sine_iqae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["mIQAE", "IQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [0.01, 0.001], 16 | 17 | "alpha": [0.05], 18 | 19 | "gamma": [null], 20 | "q": [null], 21 | "erqae_schedule" : [null], 22 | 23 | "multiplexor": [true], 24 | 25 | "mcz_qlm": [false], 26 | "shots": [10000] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/sine_integral/jsons/qae_sine_mlae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["MLAE"], 4 | 5 | "schedule": [ 6 | [ 7 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 8 | [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100] 9 | ] 10 | ], 11 | "delta": [1.0e-8], 12 | "ns": [100000], 13 | 14 | "auxiliar_qbits_number": [null], 15 | "window" : [null], 16 | "kaiser_alpha" : [null], 17 | 18 | "cbits_number": [null], 19 | 20 | "epsilon": [null], 21 | 22 | "alpha": [null], 23 | 24 | "gamma": [null], 25 | "q": [null], 26 | "erqae_schedule" : [null], 27 | 28 | "multiplexor": [true], 29 | 30 | "mcz_qlm": [false], 31 | "shots": [null] 32 | } 33 | ] 34 | -------------------------------------------------------------------------------- /benchmark/sine_integral/jsons/qae_sine_pattern.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": [null], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [null], 16 | 17 | "alpha": [null], 18 | 19 | "gamma": [null], 20 | "q": [null], 21 | "erqae_schedule" : [null], 22 | 23 | "multiplexor": [true], 24 | 25 | "mcz_qlm": [false], 26 | "shots": [null] 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /benchmark/sine_integral/jsons/qae_sine_rqae.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ae_type": ["mRQAE", "RQAE"], 4 | 5 | "schedule": [null], 6 | "delta": [null], 7 | "ns": [null], 8 | 9 | "auxiliar_qbits_number": [null], 10 | "window" : [null], 11 | "kaiser_alpha" : [null], 12 | 13 | "cbits_number": [null], 14 | 15 | "epsilon": [0.001], 16 | 17 | "alpha": [null], 18 | 19 | "gamma": [0.05], 20 | "q": [1.2], 21 | "erqae_schedule" : [null], 22 | 23 | "multiplexor": [true], 24 | 25 | "mcz_qlm": [false], 26 | "shots": [null] 27 | }, 28 | { 29 | "ae_type": ["sRQAE"], 30 | 31 | "schedule": [null], 32 | "delta": [null], 33 | "ns": [null], 34 | 35 | "auxiliar_qbits_number": [null], 36 | "window" : [null], 37 | "kaiser_alpha" : [null], 38 | 39 | "cbits_number": [null], 40 | 41 | "epsilon": [0.001], 42 | 43 | "alpha": [null], 44 | 45 | "gamma": [0.05], 46 | "q": [1.2], 47 | "erqae_schedule" : [null], 48 | 49 | "multiplexor": [true], 50 | 51 | "mcz_qlm": [false], 52 | "shots": [10000] 53 | }, 54 | { 55 | "ae_type": ["eRQAE"], 56 | 57 | "schedule": [null], 58 | "delta": [null], 59 | "ns": [null], 60 | 61 | "auxiliar_qbits_number": [null], 62 | 63 | "cbits_number": [null], 64 | 65 | "epsilon": [1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5], 66 | 67 | "alpha": [null], 68 | "shots": [null], 69 | 70 | "gamma": [0.05], 71 | "q": [2.0], 72 | "erqae_schedule" : [ 73 | {"type": "exp_const", "ratio_slope_k": 2, "ratio_slope_gamma": null}, 74 | {"type": "exp_const", "ratio_slope_k": 5, "ratio_slope_gamma": null}, 75 | {"type": "exp_const", "ratio_slope_k": 10, "ratio_slope_gamma": null}, 76 | {"type": "linear_const", "ratio_slope_k": 2, "ratio_slope_gamma": null}, 77 | {"type": "linear_const", "ratio_slope_k": 10, "ratio_slope_gamma": null}, 78 | {"type": "linear_const", "ratio_slope_k": 5, "ratio_slope_gamma": null}, 79 | {"type": "linear_linear", "ratio_slope_k": 2, "ratio_slope_gamma": 2}, 80 | {"type": "linear_linear", "ratio_slope_k": 2, "ratio_slope_gamma": 5}, 81 | {"type": "linear_linear", "ratio_slope_k": 2, "ratio_slope_gamma": 10}, 82 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": 2}, 83 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": 5}, 84 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": 10}, 85 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": -2}, 86 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": -5}, 87 | {"type": "exp_exp", "ratio_slope_k": 2, "ratio_slope_gamma": -10} 88 | ], 89 | 90 | "multiplexor": [true], 91 | "mcz_qlm": [false] 92 | } 93 | ] 94 | -------------------------------------------------------------------------------- /benchmark/sine_integral/jsons/qpu_ideal.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "qpu_type": ["c"], 5 | "t_gate_1qb" : [null], 6 | "t_gate_2qbs" : [null], 7 | "t_readout": [null], 8 | "depol_channel" : [{ 9 | "active": false, 10 | "error_gate_1qb" : null, 11 | "error_gate_2qbs" : null 12 | }], 13 | "idle" : [{ 14 | "amplitude_damping": false, 15 | "dephasing_channel": false, 16 | "t1" : null, 17 | "t2" : null 18 | }], 19 | "meas": [{ 20 | "active":false, 21 | "readout_error": null 22 | }] 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /binder/apt.txt: -------------------------------------------------------------------------------- 1 | libmagickwand-dev 2 | -------------------------------------------------------------------------------- /binder/postBuild: -------------------------------------------------------------------------------- 1 | python -m qat.magics.install 2 | -------------------------------------------------------------------------------- /doc/aa.amplitude_amplification.rst: -------------------------------------------------------------------------------- 1 | amplitude_amplification 2 | ======================= 3 | 4 | .. automodule:: QQuantLib.AA.amplitude_amplification 5 | :members: 6 | -------------------------------------------------------------------------------- /doc/aa.rst: -------------------------------------------------------------------------------- 1 | 2 | QQuantLib.AA 3 | ============ 4 | 5 | The **Amplitude Amplification (AA)** package contains the modules for creating amplitude amplification (Grover-like) operators. The following module can be found inside: 6 | 7 | * :doc:`aa.amplitude_amplification`: This module contains for creating Grover-like operators (including functions for generating reflections about quantum states). 8 | 9 | 10 | .. toctree:: 11 | :maxdepth: 1 12 | :caption: Amplitude Amplification 13 | :hidden: 14 | 15 | aa.amplitude_amplification.rst 16 | -------------------------------------------------------------------------------- /doc/ae.ae_class.rst: -------------------------------------------------------------------------------- 1 | ae_class 2 | ======== 3 | 4 | .. automodule:: QQuantLib.AE.ae_class 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/ae.ae_classical_qpe.rst: -------------------------------------------------------------------------------- 1 | ae_classical_qpe 2 | ================ 3 | 4 | .. automodule:: QQuantLib.AE.ae_classical_qpe 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/ae.ae_iterative_quantum_pe.rst: -------------------------------------------------------------------------------- 1 | ae_iterative_quantum_pe 2 | ======================= 3 | 4 | .. automodule:: QQuantLib.AE.ae_iterative_quantum_pe 5 | :members: 6 | -------------------------------------------------------------------------------- /doc/ae.bayesian_ae.rst: -------------------------------------------------------------------------------- 1 | bayesian_ae 2 | =========== 3 | 4 | .. automodule:: QQuantLib.AE.bayesian_ae 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/ae.ereal_quantum_ae.rst: -------------------------------------------------------------------------------- 1 | extended_real_quantum_ae 2 | ======================== 3 | 4 | .. automodule:: QQuantLib.AE.extended_real_quantum_ae 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/ae.iterative_quantum_ae.rst: -------------------------------------------------------------------------------- 1 | iterative_quantum_ae 2 | ==================== 3 | 4 | .. automodule:: QQuantLib.AE.iterative_quantum_ae 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/ae.maximum_likelihood_ae.rst: -------------------------------------------------------------------------------- 1 | maximum_likelihood_ae 2 | ===================== 3 | 4 | .. automodule:: QQuantLib.AE.maximum_likelihood_ae 5 | :members: 6 | -------------------------------------------------------------------------------- /doc/ae.miterative_quantum_ae.rst: -------------------------------------------------------------------------------- 1 | modified_iterative_quantum_ae 2 | ============================= 3 | 4 | .. automodule:: QQuantLib.AE.modified_iterative_quantum_ae 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/ae.mlae_utils.rst: -------------------------------------------------------------------------------- 1 | mlae_utils 2 | ========== 3 | 4 | .. automodule:: QQuantLib.AE.mlae_utils 5 | :members: 6 | -------------------------------------------------------------------------------- /doc/ae.montecarlo_ae.rst: -------------------------------------------------------------------------------- 1 | 2 | montecarlo_ae 3 | ============= 4 | 5 | .. automodule:: QQuantLib.AE.montecarlo_ae 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/ae.mreal_quantum_ae.rst: -------------------------------------------------------------------------------- 1 | modified_real_quantum_ae 2 | ======================== 3 | 4 | .. automodule:: QQuantLib.AE.modified_real_quantum_ae 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/ae.real_quantum_ae.rst: -------------------------------------------------------------------------------- 1 | real_quantum_ae 2 | ==================== 3 | 4 | .. automodule:: QQuantLib.AE.real_quantum_ae 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/ae.rst: -------------------------------------------------------------------------------- 1 | 2 | QQuantLib.AE 3 | ============ 4 | 5 | The **Amplitude Estimation (AE)** package comprises modules that implement different **AE** algorithms as Python classes. For a given quantum unitary operator, usually called *oracle*, **AE** algorithms aim to find the **probability** of a given target state when the operator is applied. The modules presented in the package are: 6 | 7 | * :doc:`ae.montecarlo_ae`: This module contains the Python class MCAE (for Monte Carlo Amplitude Estimation) that uses direct measurement for obtaining the desired estimation of the **probability**. 8 | * :doc:`ae.ae_classical_qpe`: This module contains the Python class CQPEAE that implements the classical Quantum Phase Estimation algorithm. 9 | * :doc:`ae.ae_iterative_quantum_pe`: This module contains the Python class IQPEAE that implements the *Kitaev* Iterative Quantum Phase Estimation algorithm. 10 | * :doc:`ae.maximum_likelihood_ae`: This module contains the Python class MLAE that implements the Maximum Likelihood Amplitude Estimation algorithm. 11 | * :doc:`ae.mlae_utils`: This module contains functions used for the: *QQuantLib.AE..maximum_likelihood_ae* module. 12 | * :doc:`ae.iterative_quantum_ae`: This module contains the Python class IQAE that implements the Iterative Quantum Amplitude Estimation algorithm. 13 | * :doc:`ae.miterative_quantum_ae`: This module contains the Python class mIQAE that implements a modification of the Iterative Quantum Amplitude Estimation algorithm that increases the performance over the IQAE. 14 | * :doc:`ae.bayesian_ae`: This module contains the Python class BAYESQAE that implements the Bayesian Quantum Amplitude Estimation algorithm. 15 | * :doc:`ae.real_quantum_ae`: This module contains the Python class RQAE that implements the Real Quantum Amplitude Estimation algorithm. This algorithm estimates the **amplitude** of the given target state instead of its probability. 16 | * :doc:`ae.mreal_quantum_ae`: This module contains the Python class mRQAE that implements a modification of the Real Quantum Amplitude Estimation algorithm that increases theoretical performance over the RQAE. This algorithm estimates the **amplitude** of the given target state instead of its probability. 17 | * :doc:`ae.sreal_quantum_ae`: This module contains the Python class sRQAE that implements a modification of the Real Quantum Amplitude Estimation algorithm where the user can provide the number of shots the generated quantum circuits should be measured. This algorithm estimates the **amplitude** of the given target state instead of its probability. 18 | * :doc:`ae.ereal_quantum_ae`: This module contains the Python class eRQAE that implements an extended Real Quantum Amplitude Estimation algorithm where the user can guide the evolution of the algorithm by providing a schedule. This algorithm estimates the **amplitude** of the given target state instead of its probability. 19 | * :doc:`ae.ae_class`: This module contains the Python class AE which can be used as a selector of the different classes that the **AE** package has implemented. 20 | 21 | 22 | .. toctree:: 23 | :maxdepth: 1 24 | :hidden: 25 | 26 | ae.montecarlo_ae.rst 27 | 28 | .. toctree:: 29 | :maxdepth: 1 30 | :hidden: 31 | 32 | ae.ae_classical_qpe.rst 33 | 34 | .. toctree:: 35 | :maxdepth: 1 36 | :hidden: 37 | 38 | ae.ae_iterative_quantum_pe.rst 39 | 40 | .. toctree:: 41 | :maxdepth: 1 42 | :hidden: 43 | 44 | ae.maximum_likelihood_ae.rst 45 | 46 | .. toctree:: 47 | :maxdepth: 1 48 | :hidden: 49 | 50 | ae.mlae_utils.rst 51 | 52 | .. toctree:: 53 | :maxdepth: 1 54 | :hidden: 55 | 56 | ae.iterative_quantum_ae.rst 57 | 58 | .. toctree:: 59 | :maxdepth: 1 60 | :hidden: 61 | 62 | ae.miterative_quantum_ae.rst 63 | 64 | .. toctree:: 65 | :maxdepth: 1 66 | :hidden: 67 | 68 | ae.bayesian_ae.rst 69 | 70 | .. toctree:: 71 | :maxdepth: 1 72 | :hidden: 73 | 74 | ae.real_quantum_ae.rst 75 | 76 | .. toctree:: 77 | :maxdepth: 1 78 | :hidden: 79 | 80 | ae.mreal_quantum_ae.rst 81 | 82 | .. toctree:: 83 | :maxdepth: 1 84 | :hidden: 85 | 86 | ae.sreal_quantum_ae.rst 87 | 88 | .. toctree:: 89 | :maxdepth: 1 90 | :hidden: 91 | 92 | ae.ereal_quantum_ae.rst 93 | 94 | .. toctree:: 95 | :maxdepth: 1 96 | :hidden: 97 | 98 | ae.ae_class.rst 99 | 100 | -------------------------------------------------------------------------------- /doc/ae.sreal_quantum_ae.rst: -------------------------------------------------------------------------------- 1 | shots_real_quantum_ae 2 | ===================== 3 | 4 | .. automodule:: QQuantLib.AE.shots_real_quantum_ae 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/dl.data_loading.rst: -------------------------------------------------------------------------------- 1 | data_loading 2 | ============ 3 | 4 | .. automodule:: QQuantLib.DL.data_loading 5 | :members: 6 | -------------------------------------------------------------------------------- /doc/dl.encoding_protocols.rst: -------------------------------------------------------------------------------- 1 | encoding_protocols 2 | ================== 3 | 4 | .. automodule:: QQuantLib.DL.encoding_protocols 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/dl.rst: -------------------------------------------------------------------------------- 1 | QQuantLib.DL 2 | ============ 3 | 4 | The **Data Loading (DL) package** comprises modules responsible for loading data into quantum circuits. Two different module can be found in this package: 5 | 6 | * :doc:`dl.data_loading`: this module contains basic functions for creating quantum circuits that loads input numpy arrays in the amplitude of the different quantum states. 7 | * :doc:`dl.encoding_protocols`: this module implements the **Encoding** Python class that allows to encode input numpy arrays in amplitudes of quantum states using different encoding protocols. 8 | 9 | 10 | .. toctree:: 11 | :maxdepth: 1 12 | :caption: data loading 13 | :hidden: 14 | 15 | 16 | dl.data_loading.rst 17 | 18 | 19 | .. toctree:: 20 | :maxdepth: 1 21 | :caption: Encoding protocols 22 | :hidden: 23 | 24 | dl.encoding_protocols.rst 25 | -------------------------------------------------------------------------------- /doc/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/doc/favicon.ico -------------------------------------------------------------------------------- /doc/finance.ae_price_estimation.rst: -------------------------------------------------------------------------------- 1 | 2 | ae_price_estimation 3 | =================== 4 | 5 | .. automodule:: QQuantLib.finance.ae_price_estimation 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/finance.ae_price_estimation_step_payoff.rst: -------------------------------------------------------------------------------- 1 | ae_price_estimation_step_payoff 2 | =============================== 3 | 4 | .. automodule:: QQuantLib.finance.ae_price_estimation_step_payoff 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/finance.classical_finance.rst: -------------------------------------------------------------------------------- 1 | 2 | classical_finance 3 | ======================= 4 | 5 | .. automodule:: QQuantLib.finance.classical_finance 6 | :members: 7 | 8 | 9 | -------------------------------------------------------------------------------- /doc/finance.cliquet_return_estimation.rst: -------------------------------------------------------------------------------- 1 | 2 | cliquet_return_estimation 3 | ========================= 4 | 5 | .. automodule:: QQuantLib.finance.cliquet_return_estimation 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/finance.cliquet_return_estimation_step_payoff.rst: -------------------------------------------------------------------------------- 1 | cliquet_return_estimation_step_payoff 2 | ===================================== 3 | 4 | .. automodule:: QQuantLib.finance.cliquet_return_estimation_step_payoff 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/finance.payoff_class.rst: -------------------------------------------------------------------------------- 1 | payoff_class 2 | ============ 3 | 4 | .. automodule:: QQuantLib.finance.payoff_class 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/finance.probability_class.rst: -------------------------------------------------------------------------------- 1 | 2 | probability_class 3 | ================= 4 | 5 | .. automodule:: QQuantLib.finance.probability_class 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/finance.quantum_integration.rst: -------------------------------------------------------------------------------- 1 | quantum_integration 2 | =================== 3 | 4 | 5 | .. automodule:: QQuantLib.finance.quantum_integration 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/finance.rst: -------------------------------------------------------------------------------- 1 | QQuantLib.finance 2 | ================= 3 | 4 | The **finance** package implements several Python modules related to financial industry problems. The following modules are presented: 5 | 6 | * :doc:`finance.classical_finance`: This module implements several classical quantitative finance functions. 7 | * :doc:`finance.probability_class`: This module implements the Python class DensityProbability that allows to the user configure a typical Black-Scholes (log-normal) probability density function by providing different financial parameters. 8 | * :doc:`finance.payoff_class`: This module implements the Python class PayOff that allows to the user configure payoffs for several financial derivatives (like options or futures) by providing different financial parameters. 9 | * :doc:`finance.quantum_integration`: This module implements the function *q_solve_integral* that allows to the user codify into a quantum circuit a desired integral (using the different encoding procedures from **QQuantLib.DL.encoding_protocols** module) and solving it using the different **AE** algorithms implemented in the **QQuantLib.AE** package. 10 | * :doc:`finance.ae_price_estimation`: This module implements the ae_price_estimation function that allows to the user configure a financial derivative price problem using typical financial parameters, codify the expected value integral in a quantum circuit, and solve it by using the different **AE** algorithms implemented in the **QQuantLib.AE** package. This module uses the *finance.quantum_integration* module. 11 | * :doc:`finance.ae_price_estimation_step_payoff`: This module implements the ae_price_estimation_step_po function that allows to the user configure a financial derivative price problem using typical financial parameters, codify the expected value integral in a quantum circuit, and solve it by using the different **AE** algorithms implemented in the **QQuantLib.AE** package. This module uses the *finance.quantum_integration* module. In this module, the positive part and the negative parts of the payoff will be loaded separately and the quantum estimations of the two parts are post-processed to get the desired price. 12 | * :doc:`finance.cliquet_return_estimation`: This module implements the ae_cliquet_estimation function that allows to the user configure a price problem for cliquet options products using using their typical financial parameters. It codifies the desired expected value in a quantum circuit, and solve it by using the different **AE** algorithms implemented in the **QQuantLib.AE** package. This module uses the *finance.quantum_integration* module. Cliquet options can have positive or negatives values for the expected payoff. 13 | * :doc:`finance.cliquet_return_estimation_step_payoff`: This module implements the ae_cliquet_estimation function that allows to the user configure a price problem for cliquet options products using using their typical financial parameters. It codifies the desired expected value in a quantum circuit, and solve it by using the different **AE** algorithms implemented in the **QQuantLib.AE** package. This module uses the *finance.quantum_integration* module. Cliquet options can have positive or negatives values for the expected payoff. In this module, the positive part and the negative parts of the payoff will be loaded separately and the quantum estimations of the two parts are post-processed to get the desired price. 14 | 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | :hidden: 19 | 20 | finance.classical_finance.rst 21 | 22 | .. toctree:: 23 | :maxdepth: 1 24 | :hidden: 25 | 26 | finance.probability_class.rst 27 | 28 | .. toctree:: 29 | :maxdepth: 1 30 | :hidden: 31 | 32 | finance.payoff_class.rst 33 | 34 | .. toctree:: 35 | :maxdepth: 1 36 | :hidden: 37 | 38 | finance.quantum_integration.rst 39 | 40 | .. toctree:: 41 | :maxdepth: 1 42 | :hidden: 43 | 44 | finance.ae_price_estimation.rst 45 | 46 | .. toctree:: 47 | :maxdepth: 1 48 | :hidden: 49 | 50 | finance.ae_price_estimation_step_payoff.rst 51 | 52 | .. toctree:: 53 | :maxdepth: 1 54 | :hidden: 55 | 56 | finance.cliquet_return_estimation.rst 57 | 58 | .. toctree:: 59 | :maxdepth: 1 60 | :hidden: 61 | 62 | finance.cliquet_return_estimation_step_payoff.rst 63 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | .. index 2 | 3 | .. only:: header 4 | 5 | NEASQC Project 6 | ============== 7 | 8 | .. only:: html 9 | 10 | Welcome to the FinancialApplications documentation 11 | ================================================== 12 | 13 | .. image:: logo-neasqc.svg 14 | :scale: 50% 15 | :align: center 16 | :alt: NEASQC Project 17 | 18 | Documentation of the *Quantum Quantitative Finance Library* (**QQuantLib**) associated with the use case of *Financial Applications* of the Work Package **Machine Learning & Optimisation** of the NEASQC European project. 19 | 20 | **QQuantLib** is a Python library developed using **myQLM** (**EVIDEN** quantum software stack) containing following packages: 21 | 22 | * :doc:`dl`: This is the *Data Loading (DL)* package which contains modules related to the loading of the data. 23 | * :doc:`aa`: This is the *Amplitude Amplification (AA)* package which contains modules related to amplitude amplification operators. 24 | * :doc:`pe`: This is the *Phase Estimation* package which contains modules for phase estimation algorithms that can be used in amplitude estimation procedures. 25 | * :doc:`ae`: This is the *Amplitude Estimation* package which is devoted to different amplitude amplification algorithms. 26 | * :doc:`finance`: This package implements different modules related to finance applications of *Amplitude Estimation* techniques. 27 | * :doc:`qml4var`: This package contains modules for training **PQCs** for using as surrogate models for Financial **CDFs** for VaR computations. 28 | * :doc:`qpu`: This package contains a module for selecting the different **EVIDEN** *Quantum Process Units* (**QPUs**) for simulating the different circuits created by the different modules of the **QQuantLib** library. 29 | * :doc:`utils`: This package contains auxiliary modules used for all the beforementioned packages. 30 | 31 | 32 | NEASQC project has received funding from the European Union’s Horizon 2020 research and innovation programme under Grant Agreement No. 951821. https://www.neasqc.eu/ 33 | 34 | Authors: Alberto Pedro Manzano Herrero & Gonzalo Ferro 35 | 36 | .. toctree:: 37 | :maxdepth: 1 38 | :hidden: 39 | 40 | dl.rst 41 | 42 | .. toctree:: 43 | :maxdepth: 1 44 | :hidden: 45 | 46 | aa.rst 47 | 48 | .. toctree:: 49 | :maxdepth: 1 50 | :hidden: 51 | 52 | ae.rst 53 | 54 | .. toctree:: 55 | :maxdepth: 1 56 | :hidden: 57 | 58 | pe.rst 59 | 60 | 61 | .. toctree:: 62 | :maxdepth: 1 63 | :hidden: 64 | 65 | finance.rst 66 | 67 | .. toctree:: 68 | :maxdepth: 1 69 | :hidden: 70 | 71 | qml4var.rst 72 | 73 | 74 | .. toctree:: 75 | :maxdepth: 1 76 | :hidden: 77 | 78 | qpu.rst 79 | 80 | .. toctree:: 81 | :maxdepth: 1 82 | :hidden: 83 | 84 | utils.rst 85 | 86 | 87 | -------------------------------------------------------------------------------- /doc/logo-neasqc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /doc/pe.classical_qpe.rst: -------------------------------------------------------------------------------- 1 | classical_qpe 2 | ============= 3 | 4 | .. automodule:: QQuantLib.PE.classical_qpe 5 | :members: 6 | -------------------------------------------------------------------------------- /doc/pe.iterative_quantum_pe.rst: -------------------------------------------------------------------------------- 1 | iterative_quantum_pe 2 | ======================= 3 | 4 | .. automodule:: QQuantLib.PE.iterative_quantum_pe 5 | :members: 6 | -------------------------------------------------------------------------------- /doc/pe.rst: -------------------------------------------------------------------------------- 1 | QQuantLib.PE 2 | ============ 3 | 4 | The **Phase Estimation (PE)** package includes modules for implementing *Quantum Phase Estimation* (**QPE**) algorithms. The following modules were implemented: 5 | 6 | * :doc:`pe.classical_qpe`: This module implements the Python class CQPE that implements the *QPE* algorithm that returns the eigenvalues of a given input unitary operator and an initial eigenstate (or a linear combination of them). The algorithm uses the Quantum Fourier Transformation Routine. 7 | * :doc:`pe.iterative_quantum_pe`: This module implements the Python class IQPE that implements the *Kitaev Iterative Phase Estimation* algorithm that returns the eigenvalues of a given input unitary operator and an initial eigenstate (or a linear combination of them). 8 | 9 | 10 | .. toctree:: 11 | :maxdepth: 1 12 | :hidden: 13 | 14 | pe.classical_qpe.rst 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | :hidden: 19 | 20 | 21 | pe.iterative_quantum_pe.rst 22 | 23 | 24 | -------------------------------------------------------------------------------- /doc/qml4var.adam.rst: -------------------------------------------------------------------------------- 1 | 2 | adam 3 | ==== 4 | 5 | .. automodule:: QQuantLib.qml4var.adam 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/qml4var.architectures.rst: -------------------------------------------------------------------------------- 1 | 2 | architectures 3 | ============= 4 | 5 | .. automodule:: QQuantLib.qml4var.architectures 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/qml4var.data_utils.rst: -------------------------------------------------------------------------------- 1 | data_utils 2 | ========== 3 | 4 | .. automodule:: QQuantLib.qml4var.data_utils 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/qml4var.losses.rst: -------------------------------------------------------------------------------- 1 | losses 2 | ====== 3 | 4 | .. automodule:: QQuantLib.qml4var.losses 5 | :members: 6 | -------------------------------------------------------------------------------- /doc/qml4var.myqlm_workflows.rst: -------------------------------------------------------------------------------- 1 | 2 | myqlm_workflows 3 | =============== 4 | 5 | .. automodule:: QQuantLib.qml4var.myqlm_workflows 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/qml4var.plugins.rst: -------------------------------------------------------------------------------- 1 | 2 | plugins 3 | ======= 4 | 5 | .. automodule:: QQuantLib.qml4var.plugins 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/qml4var.rst: -------------------------------------------------------------------------------- 1 | QQuantLib.qml4var 2 | ================= 3 | 4 | This package implements the mandatory modules and functions to train a **Parametric Quantum Circuit (PQC)** that can be used as surrogate models of complex and time consuming financial **Cumulative Distribution Functions (CDF)** using the *myQLM EVIDEN* software. 5 | 6 | The following modules are presented: 7 | 8 | * :doc:`qml4var.data_utils`: This module contains functions for generating suitable datasets for training **PQCs** for **CDF** evaluation. 9 | * :doc:`qml4var.architectures`: This module implements a hardware efficient ansatz **PQC** and define the measurement observable. 10 | * :doc:`qml4var.plugins`: This module contains home made **myQLM Plugins** used for evaluating **PQCs** for a set of trainable and feature parameters. 11 | * :doc:`qml4var.myqlm_workflows`: This module implements workflows for evaluating the **PQCs**. 12 | * :doc:`qml4var.losses`: This module implements several loss functions. 13 | * :doc:`qml4var.adam`: This module implements the ADAM optimizer. 14 | 15 | .. toctree:: 16 | :maxdepth: 1 17 | :hidden: 18 | 19 | qml4var.data_utils.rst 20 | 21 | .. toctree:: 22 | :maxdepth: 1 23 | :hidden: 24 | 25 | qml4var.architectures.rst 26 | 27 | .. toctree:: 28 | :maxdepth: 1 29 | :hidden: 30 | 31 | qml4var.plugins.rst 32 | 33 | .. toctree:: 34 | :maxdepth: 1 35 | :hidden: 36 | 37 | qml4var.myqlm_workflows.rst 38 | 39 | .. toctree:: 40 | :maxdepth: 1 41 | :hidden: 42 | 43 | qml4var.losses.rst 44 | 45 | .. toctree:: 46 | :maxdepth: 1 47 | :hidden: 48 | 49 | qml4var.adam.rst 50 | -------------------------------------------------------------------------------- /doc/qpu.get_qpu.rst: -------------------------------------------------------------------------------- 1 | get_qpu 2 | ======= 3 | 4 | .. automodule:: QQuantLib.qpu.get_qpu 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/qpu.model_noise.rst: -------------------------------------------------------------------------------- 1 | model_noise 2 | =========== 3 | 4 | .. automodule:: QQuantLib.qpu.model_noise 5 | :members: 6 | 7 | 8 | -------------------------------------------------------------------------------- /doc/qpu.noise_test_bank_functions.rst: -------------------------------------------------------------------------------- 1 | noise_test_bank_functions 2 | ========================= 3 | 4 | .. automodule:: QQuantLib.qpu.noise_test_bank_functions 5 | :members: 6 | 7 | 8 | -------------------------------------------------------------------------------- /doc/qpu.rst: -------------------------------------------------------------------------------- 1 | QQuantLib.qpu 2 | ============= 3 | The **qpu** package comprises different modules for selecting different **EVIDEN Quantum Process Units (QPUs)** that can be used for simulating (or executing in the quantum device in the future) the different quantum circuits generated by the functions of the **QQuantLib** library. 4 | 5 | * :doc:`qpu.get_qpu`: This module holds the get_qpu function that allows to the user select the desired QPU for simulating the quantum circuits 6 | * :doc:`qpu.select_qpu`: This module implements the select_qpu function that allows to the user select a pure ideal QPU or configure a noisy one using an input Python dictionary. 7 | * :doc:`qpu.model_noise`: This module implements several functions for configuring a noisy hardware model and its corresponding noisy QPU (this module should be used when the user is locally in a QLM). 8 | * :doc:`qpu.noise_test_bank_functions`: This module implements several auxiliary functions used in the demo notebook: QQuantLib/qpu/NoisyModels.ipynb 9 | 10 | 11 | .. toctree:: 12 | :maxdepth: 1 13 | :hidden: 14 | 15 | qpu.get_qpu.rst 16 | 17 | .. toctree:: 18 | :maxdepth: 1 19 | :hidden: 20 | 21 | qpu.select_qpu.rst 22 | 23 | .. toctree:: 24 | :maxdepth: 1 25 | :hidden: 26 | 27 | qpu.model_noise.rst 28 | 29 | .. toctree:: 30 | :maxdepth: 1 31 | :hidden: 32 | 33 | qpu.noise_test_bank_functions.rst 34 | -------------------------------------------------------------------------------- /doc/qpu.select_qpu.rst: -------------------------------------------------------------------------------- 1 | select_qpu 2 | ========== 3 | 4 | .. automodule:: QQuantLib.qpu.select_qpu 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /doc/utils.benchmark_utils.rst: -------------------------------------------------------------------------------- 1 | 2 | benchmark_utils 3 | =============== 4 | 5 | .. automodule:: QQuantLib.utils.benchmark_utils 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/utils.data_extracting.rst: -------------------------------------------------------------------------------- 1 | 2 | data_extracting 3 | ======================= 4 | 5 | .. automodule:: QQuantLib.utils.data_extracting 6 | :members: 7 | 8 | -------------------------------------------------------------------------------- /doc/utils.rst: -------------------------------------------------------------------------------- 1 | QQuantLib.utils 2 | =============== 3 | 4 | The **utils** package implements several modules with auxiliary functions used across other packages of the QQuantLib library. 5 | 6 | * :doc:`utils.utils_utils`: Several auxiliary functions used across other packages of QQuantLib are stored in this module. 7 | * :doc:`utils.data_extracting`: This module implements several functions that allow the execution of quantum routines (or programs) and formatting the obtained results properly (in general by returning pandas DataFrames) 8 | * :doc:`utils.benchmark_utils`: This module holds several auxiliary functions that allow to creation of combinations of several Python dictionaries. These functions are used for the modules of the benchmark folder of the FinancialApplications repository for creating easy input configurations for benchmark tests. 9 | 10 | 11 | .. toctree:: 12 | :maxdepth: 1 13 | :hidden: 14 | 15 | utils.utils_utils.rst 16 | 17 | .. toctree:: 18 | :maxdepth: 1 19 | :hidden: 20 | 21 | utils.data_extracting.rst 22 | 23 | .. toctree:: 24 | :maxdepth: 1 25 | :hidden: 26 | 27 | utils.benchmark_utils.rst 28 | 29 | 30 | -------------------------------------------------------------------------------- /doc/utils.utils_utils.rst: -------------------------------------------------------------------------------- 1 | 2 | utils 3 | ======================= 4 | 5 | .. automodule:: QQuantLib.utils.utils 6 | :members: 7 | -------------------------------------------------------------------------------- /misc/notebooks/images/GroverGeometrico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/misc/notebooks/images/GroverGeometrico.png -------------------------------------------------------------------------------- /misc/notebooks/images/OraculeReflection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/misc/notebooks/images/OraculeReflection.png -------------------------------------------------------------------------------- /misc/notebooks/images/Qiskit_IQPE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/misc/notebooks/images/Qiskit_IQPE.png -------------------------------------------------------------------------------- /misc/notebooks/images/StateReflection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/misc/notebooks/images/StateReflection.png -------------------------------------------------------------------------------- /misc/notebooks/other_staff/CZ_multiplexor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/misc/notebooks/other_staff/CZ_multiplexor.png -------------------------------------------------------------------------------- /misc/notebooks/other_staff/Multiplexor_base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/misc/notebooks/other_staff/Multiplexor_base.png -------------------------------------------------------------------------------- /misc/notebooks/other_staff/Recursive_Multiplexor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEASQC/FinancialApplications/2d77cb886f623d336af40ab647f2f9e1cfe1cd61/misc/notebooks/other_staff/Recursive_Multiplexor.png -------------------------------------------------------------------------------- /misc/notebooks/qml4var_data/2024_10_04_BS_testing.csv: -------------------------------------------------------------------------------- 1 | ;Features_0;Labels 2 | 0;0.1;-0.4999999998820334 3 | 1;0.1292929292929293;-0.49999998984061855 4 | 2;0.15858585858585858;-0.49999975686975395 5 | 3;0.18787878787878787;-0.4999973460554794 6 | 4;0.21717171717171718;-0.49998281704608144 7 | 5;0.24646464646464647;-0.4999230032278584 8 | 6;0.27575757575757576;-0.49973674808618906 9 | 7;0.305050505050505;-0.49926705399552523 10 | 8;0.33434343434343433;-0.498261098522631 11 | 9;0.36363636363636365;-0.4963676762308862 12 | 10;0.3929292929292929;-0.49315563448787714 13 | 11;0.42222222222222217;-0.4881500524137375 14 | 12;0.45151515151515154;-0.4808783186964062 15 | 13;0.4808080808080808;-0.4709169476038435 16 | 14;0.51010101010101;-0.4579313564190018 17 | 15;0.5393939393939393;-0.4417036509926389 18 | 16;0.5686868686868687;-0.42214653564697924 19 | 17;0.597979797979798;-0.39930399957315876 20 | 18;0.6272727272727272;-0.3733411017282727 21 | 19;0.6565656565656565;-0.3445259763678441 22 | 20;0.6858585858585858;-0.31320728715812635 23 | 21;0.7151515151515151;-0.27979000357478323 24 | 22;0.7444444444444444;-0.24471177781037107 25 | 23;0.7737373737373736;-0.2084215326333289 26 | 24;0.803030303030303;-0.17136124216496573 27 | 25;0.8323232323232322;-0.13395135961086435 28 | 26;0.8616161616161615;-0.09657994209587545 29 | 27;0.8909090909090909;-0.05959524162592944 30 | 28;0.9202020202020201;-0.023301357595007954 31 | 29;0.9494949494949494;0.012043541121555257 32 | 30;0.9787878787878787;0.04622693978849002 33 | 31;1.0080808080808081;0.07908014189524537 34 | 32;1.0373737373737373;0.11047532071543509 35 | 33;1.0666666666666667;0.14032184335373055 36 | 34;1.095959595959596;0.16856218539966283 37 | 35;1.1252525252525252;0.1951676888552515 38 | 36;1.1545454545454545;0.22013435591142594 39 | 37;1.183838383838384;0.24347881852178488 40 | 38;1.213131313131313;0.26523457937599537 41 | 39;1.2424242424242424;0.28544858376104354 42 | 40;1.2717171717171718;0.30417815333612475 43 | 41;1.301010101010101;0.32148829116557165 44 | 42;1.3303030303030303;0.33744935146288657 45 | 43;1.3595959595959597;0.35213505639865583 46 | 44;1.3888888888888888;0.3656208350780519 47 | 45;1.4181818181818182;0.3779824555610558 48 | 46;1.4474747474747474;0.38929491885753276 49 | 47;1.4767676767676767;0.3996315835749411 50 | 48;1.506060606060606;0.409063490835623 51 | 49;1.5353535353535352;0.4176588608208407 52 | 50;1.5646464646464646;0.4254827345349518 53 | 51;1.593939393939394;0.43259673688399636 54 | 52;1.6232323232323231;0.4390589397579112 55 | 53;1.6525252525252525;0.44492380637281226 56 | 54;1.6818181818181819;0.4502422005861362 57 | 55;1.711111111111111;0.4550614471895369 58 | 56;1.7404040404040404;0.45942543128147495 59 | 57;1.7696969696969698;0.46337472670927426 60 | 58;1.798989898989899;0.46694674524682966 61 | 59;1.8282828282828283;0.4701758996452141 62 | 60;1.8575757575757574;0.47309377497062366 63 | 61;1.8868686868686868;0.4757293037422312 64 | 62;1.9161616161616162;0.47810894131805726 65 | 63;1.9454545454545453;0.48025683876700787 66 | 64;1.9747474747474747;0.48219501112659524 67 | 65;2.004040404040404;0.483943499494645 68 | 66;2.033333333333333;0.4855205258544977 69 | 67;2.0626262626262624;0.4869426399005521 70 | 68;2.091919191919192;0.48822485742684074 71 | 69;2.121212121212121;0.48938079007667723 72 | 70;2.1505050505050503;0.4904227664359625 73 | 71;2.17979797979798;0.491361944594932 74 | 72;2.209090909090909;0.49220841641028235 75 | 73;2.238383838383838;0.49297130377800835 76 | 74;2.2676767676767677;0.4936588472822645 77 | 75;2.296969696969697;0.49427848762166327 78 | 76;2.326262626262626;0.49483694023546243 79 | 77;2.3555555555555556;0.4953402635612385 80 | 78;2.3848484848484848;0.4957939213555753 81 | 79;2.414141414141414;0.4962028395021658 82 | 80;2.4434343434343435;0.49657145771934896 83 | 81;2.4727272727272727;0.4969037765629303 84 | 82;2.502020202020202;0.4972034001013339 85 | 83;2.5313131313131314;0.49747357461966424 86 | 84;2.5606060606060606;0.4977172236878391 87 | 85;2.5898989898989897;0.49793697990619945 88 | 86;2.6191919191919193;0.498135213620329 89 | 87;2.6484848484848484;0.4983140588755859 90 | 88;2.6777777777777776;0.4984754368613018 91 | 89;2.707070707070707;0.4986210770749133 92 | 90;2.7363636363636363;0.49875253641758666 93 | 91;2.7656565656565655;0.49887121641524734 94 | 92;2.7949494949494946;0.4989783787423687 95 | 93;2.824242424242424;0.4990751592104202 96 | 94;2.8535353535353534;0.49916258036851957 97 | 95;2.8828282828282825;0.49924156285053845 98 | 96;2.912121212121212;0.4993129355906456 99 | 97;2.9414141414141413;0.4993774450179904 100 | 98;2.9707070707070704;0.49943576333087514 101 | 99;3.0;0.49948849594128486 102 | -------------------------------------------------------------------------------- /misc/notebooks/qml4var_data/data.json: -------------------------------------------------------------------------------- 1 | {"n_points_train": 250, "n_points_test": 100, "features_number": 1, "minval": 0.1, "maxval": 3.0, "distribution": "bs", "s_0": 1.0, "risk_free_rate": 0.0, "maturity": 0.5, "volatility": 0.5, "name_for_saving": "/mnt/netapp1/Store_CESGA//home/cesga/gferro/2024_10_04/2024_10_04_BS", "folder_path": "/mnt/netapp1/Store_CESGA//home/cesga/gferro/2024_10_04"} -------------------------------------------------------------------------------- /misc/notebooks/qml4var_data/optimizer_info.json: -------------------------------------------------------------------------------- 1 | {"epochs": 200, "tolerance": 1e-07, "learning_rate": 0.1, "beta1": 0.9, "beta2": 0.999, "print_step": 10, "n_counts_tolerance": 200, "nbshots": 0, "points": 100, "file_to_save": null} -------------------------------------------------------------------------------- /misc/notebooks/qml4var_data/pqc.json: -------------------------------------------------------------------------------- 1 | {"features_number": 1, "n_qubits_by_feature": 2, "n_layers": 3, "base_frecuency": [1.0833078115826873], "shift_feature": [-1.6791271079531653]} -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | from setuptools import setup, find_packages 3 | from setuptools.command.test import test as TestCommand 4 | 5 | class PyTest(TestCommand): 6 | """ 7 | A test command to run pytest on a the full repository. 8 | This means that any function name test_XXXX 9 | or any class named TestXXXX will be found and run. 10 | """ 11 | def initialize_options(self): 12 | TestCommand.initialize_options(self) 13 | self.pytest_args = [] 14 | 15 | def finalize_options(self): 16 | TestCommand.finalize_options(self) 17 | self.test_args = [] 18 | self.test_suite = True 19 | 20 | def run_tests(self): 21 | import pytest 22 | errno = pytest.main([".", "-vv"]) 23 | sys.exit(errno) 24 | 25 | setup( 26 | name="FinancialApplications", 27 | version=os.getenv("TAG_NAME", "0.0.1"), 28 | author="Alberto Pedro Manzano Herrero & Gonzalo Ferro Costas", 29 | license="European Union Public License 1.2", 30 | 31 | packages=find_packages(), 32 | install_requires=["numpy", "pandas", "myqlm", "matplotlib", "scipy"], 33 | # Don't change these two lines 34 | tests_require=["pytest"], 35 | cmdclass={'test': PyTest}, 36 | ) 37 | 38 | -------------------------------------------------------------------------------- /tests/__test_my_lib.py: -------------------------------------------------------------------------------- 1 | # -*- coding : utf-8 -*- 2 | 3 | """ 4 | Test for this module 5 | """ 6 | 7 | 8 | from my_lib import some_function, MyClass 9 | 10 | 11 | class TestMyClass: 12 | """ 13 | Testing MyClass 14 | """ 15 | 16 | def test_instantiation(self): 17 | """ 18 | Testing the constructor 19 | """ 20 | MyClass(1, 1, 2) 21 | MyClass() 22 | 23 | 24 | def test_some_fucntion(): 25 | """ 26 | Testing some_function 27 | """ 28 | assert 4 == some_function(2) 29 | -------------------------------------------------------------------------------- /tests/test_IQAE.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.append("../") 3 | import numpy as np 4 | import qat.lang.AQASM as qlm 5 | from qat.core.console import display 6 | from QQuantLib.qpu.get_qpu import get_qpu 7 | from QQuantLib.AE.iterative_quantum_ae import IQAE 8 | from QQuantLib.utils.data_extracting import get_results 9 | from QQuantLib.utils.utils import bitfield_to_int 10 | import QQuantLib.DL.data_loading as dl 11 | 12 | 13 | def test_iqae(): 14 | n = 3 15 | x = np.arange(2**n) 16 | p = x / np.sum(x) 17 | 18 | oracle = qlm.QRoutine() 19 | register = oracle.new_wires(n) 20 | oracle.apply(dl.load_probability(p), register) 21 | 22 | target = [0, 0, 1] 23 | index = [0, 1, 2] 24 | 25 | epsilon = 0.01 26 | alpha = 0.05 27 | N_shots = 100 28 | linalg_qpu = get_qpu("python") 29 | iqae_dict = { 30 | "qpu": linalg_qpu, 31 | "epsilon": epsilon, 32 | "shots": N_shots, 33 | "alpha": alpha, 34 | } 35 | 36 | iqae = IQAE(oracle, target, index, **iqae_dict) 37 | 38 | a_estimated = iqae.run() 39 | 40 | assert (p[bitfield_to_int(target)] > iqae.ae_l) and ( 41 | p[bitfield_to_int(target)] <= iqae.ae_u 42 | ) 43 | -------------------------------------------------------------------------------- /tests/test_RQAE.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sys 3 | 4 | sys.path.append("../") 5 | 6 | from QQuantLib.AE.real_quantum_ae import RQAE 7 | from QQuantLib.utils.data_extracting import get_results 8 | from QQuantLib.utils.utils import bitfield_to_int 9 | import QQuantLib.DL.data_loading as dl 10 | 11 | import qat.lang.AQASM as qlm 12 | from QQuantLib.qpu.get_qpu import get_qpu 13 | from qat.core.console import display 14 | 15 | 16 | def test_rqae(): 17 | n = 3 18 | x = np.arange(2**n) 19 | f = -x / np.max(x) 20 | 21 | oracle = qlm.QRoutine() 22 | register = oracle.new_wires(n + 1) 23 | oracle.apply(dl.uniform_distribution(n), register[:n]) 24 | oracle.apply(dl.load_array(f), register) 25 | 26 | target = [0, 0, 1, 1] 27 | index = [0, 1, 2, 3] 28 | 29 | q = 2 30 | epsilon = 0.01 31 | gamma = 0.05 32 | linalg_qpu = get_qpu("python") 33 | rqae_dict = { 34 | "qpu": linalg_qpu, 35 | "epsilon": epsilon, 36 | "ratio": q, 37 | "gamma": gamma} 38 | 39 | rqae = RQAE(oracle, target, index, **rqae_dict) 40 | a_real = f[bitfield_to_int(target)] 41 | 42 | a_estimated = rqae.run() 43 | a_low = rqae.ae_l * np.sqrt(2) ** n 44 | a_up = rqae.ae_u * np.sqrt(2) ** n 45 | 46 | assert (a_real > a_low) and (a_real <= a_up) 47 | 48 | 49 | test_rqae() 50 | -------------------------------------------------------------------------------- /tests/test_amplitude_amplification.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests For data_loading functions 3 | """ 4 | 5 | import sys 6 | sys.path.append("../") 7 | import numpy as np 8 | import qat.lang.AQASM as qlm 9 | from qat.qpus import PyLinalg 10 | from QQuantLib.utils.utils import get_histogram 11 | from QQuantLib.DL.data_loading import load_probability, load_array, load_pf 12 | from QQuantLib.utils.data_extracting import get_results 13 | from QQuantLib.AA.amplitude_amplification import reflection, create_u0_gate, create_u_gate, grover 14 | from qat.qpus import get_default_qpu 15 | linalg_qpu = get_default_qpu() 16 | 17 | 18 | # Prepare Data for loading 19 | def launch_data(n_qbits): 20 | def p(x): 21 | return x * x 22 | 23 | def f(x): 24 | return np.sin(x) 25 | 26 | # The number of bins 27 | m_bins = 2**n_qbits 28 | lower_limit = 0.0 29 | upper_limit = 1.0 30 | x, p_x = get_histogram(p, lower_limit, upper_limit, m_bins) 31 | f_x = f(x) 32 | return x, f_x, p_x 33 | 34 | 35 | def load_gates(n_qbits): 36 | x, f_x, p_x = launch_data(n_qbits) 37 | p_gate = load_probability(p_x) 38 | f_gate = load_array(np.sqrt(f_x)) 39 | pf_gate = load_pf(p_gate, f_gate) 40 | return p_gate, f_gate, pf_gate 41 | 42 | 43 | def GetAngle(Array): 44 | Modulo = np.linalg.norm(Array) 45 | cosTheta = Array[0] / Modulo 46 | Theta0 = np.arccos(cosTheta) 47 | sinTheta = Array[1] / Modulo 48 | Theta1 = np.arcsin(sinTheta) 49 | # print(Modulo, cosTheta, sinTheta, Theta0, Theta1) 50 | return Theta0 51 | 52 | 53 | def get_initial_state(pf_gate): 54 | phi_state, circuit, q_prog, job = get_results( 55 | pf_gate, linalg_qpu=linalg_qpu, shots=0 56 | ) 57 | initial_state, circuit, q_p, job = get_results( 58 | pf_gate, linalg_qpu=linalg_qpu, shots=0, qubits=[pf_gate.arity - 1] 59 | ) 60 | return phi_state, initial_state, q_prog 61 | 62 | 63 | def test_U0(): 64 | """ 65 | For Testing uphi0_gate from amplitude_amplification 66 | """ 67 | p_gate, f_gate, pf_gate = load_gates(5) 68 | phi_state, initial_state, q_prog = get_initial_state(pf_gate) 69 | u_phi0_gate = create_u0_gate(pf_gate, [0], [pf_gate.arity - 1]) 70 | routine_U0 = qlm.QRoutine() 71 | register_U0 = routine_U0.new_wires(pf_gate.arity) 72 | routine_U0.apply(pf_gate, register_U0) 73 | routine_U0.apply(u_phi0_gate, register_U0) 74 | u0_phi_state, circuit, _, _ = get_results( 75 | routine_U0, linalg_qpu=linalg_qpu, shots=0 76 | ) 77 | state_0 = np.array( 78 | [p for s, p in zip(phi_state["States"], phi_state["Amplitude"]) if s[1] == "0"] 79 | ) 80 | print(u0_phi_state) 81 | u0_state_0 = np.array( 82 | [ 83 | p 84 | for s, p in zip(u0_phi_state["States"], u0_phi_state["Amplitude"]) 85 | if s[1] == "0" 86 | ] 87 | ) 88 | 89 | # Testing Final qbit |0> should be of different sign 90 | last_qbit_0 = np.isclose(state_0, -u0_state_0).all() 91 | 92 | assert last_qbit_0 == True 93 | 94 | state_1 = np.array( 95 | [p for s, p in zip(phi_state["States"], phi_state["Amplitude"]) if s[1] == "1"] 96 | ) 97 | u_0_state_1 = np.array( 98 | [ 99 | p 100 | for s, p in zip(u0_phi_state["States"], u0_phi_state["Amplitude"]) 101 | if s[1] == "1" 102 | ] 103 | ) 104 | # Testing Final qbit |1> should be of same sign 105 | last_qbit_1 = np.isclose(state_1, u_0_state_1).all() 106 | assert last_qbit_1 == True 107 | 108 | assert (last_qbit_0 and last_qbit_1) == True 109 | 110 | 111 | def test_D0(): 112 | """ 113 | For Testing d0_gate from amplitude_amplification 114 | """ 115 | p_gate, f_gate, pf_gate = load_gates(5) 116 | phi_state, initial_state, q_prog = get_initial_state(pf_gate) 117 | routine_D0 = qlm.QRoutine() 118 | register_D0 = routine_D0.new_wires(pf_gate.arity) 119 | routine_D0.apply(pf_gate, register_D0) 120 | d0_gate = reflection([0 for i in range(pf_gate.arity)]) 121 | routine_D0.apply(d0_gate, register_D0) 122 | u_d0_state, circuit, _, _ = get_results(routine_D0, linalg_qpu=linalg_qpu, shots=0) 123 | 124 | # Testing: state |0> should change sign 125 | state_0 = np.isclose(phi_state["Amplitude"].loc[0], -u_d0_state["Amplitude"].loc[0]) 126 | # Testing: otherwise states keep sign 127 | non_state_0 = np.isclose( 128 | phi_state["Amplitude"].loc[1:], u_d0_state["Amplitude"].loc[1:] 129 | ).all() 130 | assert state_0 == True 131 | assert non_state_0 == True 132 | assert (state_0 and non_state_0) == True 133 | 134 | 135 | def test_difusor(): 136 | """ 137 | For Testing load_uphi_gate from amplitude_amplification 138 | """ 139 | p_gate, f_gate, pf_gate = load_gates(5) 140 | phi_state, initial_state, q_prog = get_initial_state(pf_gate) 141 | 142 | routine_U = qlm.QRoutine() 143 | register_U = routine_U.new_wires(pf_gate.arity) 144 | routine_U.apply(pf_gate, register_U) 145 | diffusor_gate = create_u_gate(pf_gate) 146 | routine_U.apply(diffusor_gate, register_U) 147 | 148 | diffusor_state, circuit, _, _ = get_results( 149 | routine_U, linalg_qpu=linalg_qpu, shots=0 150 | ) 151 | 152 | # Resulted state opposite to initial state 153 | opposite_states = np.isclose(diffusor_state["Amplitude"], -phi_state["Amplitude"]) 154 | assert opposite_states.all() == True 155 | 156 | 157 | def test_grover(): 158 | """ 159 | For Testing load_q_gate from amplitude_amplification 160 | """ 161 | p_gate, f_gate, pf_gate = load_gates(5) 162 | phi_state, initial_state, q_prog = get_initial_state(pf_gate) 163 | routine_grover = qlm.QRoutine() 164 | register_grover = routine_grover.new_wires(pf_gate.arity) 165 | routine_grover.apply(pf_gate, register_grover) 166 | grover_gate = grover(pf_gate, [0], [pf_gate.arity - 1]) 167 | routine_grover.apply(grover_gate, register_grover) 168 | 169 | grover_state, circuit, _, _ = get_results( 170 | routine_grover, linalg_qpu=linalg_qpu, shots=0, qubits=[grover_gate.arity - 1] 171 | ) 172 | 173 | # First get the Amplitudes for Phi state 174 | a0 = np.sqrt(initial_state.iloc[0]["Probability"]) 175 | a1 = np.sqrt(initial_state.iloc[1]["Probability"]) 176 | # Quantum state after loading data: |Psi> 177 | psi_state = np.array([a0, a1]) 178 | # Angle between |Psi> and axis |Psi_0> 179 | theta = GetAngle(psi_state) 180 | # Create a Rotation of 2*theta 181 | c, s = np.cos(2 * theta), np.sin(2.0 * theta) 182 | # Rotation matrix 183 | rotation = np.array(((c, -s), (s, c))) 184 | # Apply Ry(2*theta) to quantum state |Psi> 185 | rotated_state = np.dot(rotation, psi_state) 186 | 187 | is_equal = np.isclose(rotated_state**2, grover_state["Probability"]) 188 | 189 | assert is_equal.all() == True 190 | -------------------------------------------------------------------------------- /tests/test_classical_qpe.py: -------------------------------------------------------------------------------- 1 | """ 2 | test for classical QPE 3 | """ 4 | import sys 5 | sys.path.append("../") 6 | import numpy as np 7 | import qat.lang.AQASM as qlm 8 | 9 | from QQuantLib.utils.utils import get_histogram 10 | from QQuantLib.DL.data_loading import load_probability, load_array, load_pf 11 | from QQuantLib.AA.amplitude_amplification import grover 12 | from QQuantLib.PE.classical_qpe import CQPE 13 | from QQuantLib.qpu.get_qpu import get_qpu 14 | qpu = get_qpu("c") 15 | 16 | 17 | #### Phase Estimation Test-01: Phase of S Gate ### 18 | 19 | 20 | def test_pe_s_gate(): 21 | 22 | n_qbits = 1 23 | initial_state = qlm.QRoutine() 24 | q_bits = initial_state.new_wires(n_qbits) 25 | for i in range(n_qbits): 26 | initial_state.apply(qlm.X, q_bits[i]) 27 | unitary_operator = qlm.PH(np.pi / 2.0) 28 | auxiliar_qbits_number = 2 29 | # We create a python dictionary for configuration of class 30 | qft_pe_dict = { 31 | "initial_state": initial_state, 32 | "unitary_operator": unitary_operator, 33 | "auxiliar_qbits_number": auxiliar_qbits_number, 34 | "shots": 100, 35 | "qpu": qpu 36 | } 37 | qft_pe = CQPE(**qft_pe_dict) 38 | qft_pe.run() 39 | phi_meas = qft_pe.result.iloc[qft_pe.result["Probability"].idxmax()][ 40 | "lambda" 41 | ] 42 | assert np.isclose(phi_meas, 0.25) 43 | # 44 | # 45 | ##### Phase Estimation Test-02: Phase of Controlled-T Gate ### 46 | # 47 | # 48 | def test_pe_c_t_gate(): 49 | 50 | n_qbits = 3 51 | initial_state = qlm.QRoutine() 52 | q_bits = initial_state.new_wires(n_qbits) 53 | for i in range(n_qbits): 54 | initial_state.apply(qlm.X, q_bits[i]) 55 | # Create cT operator 56 | unitary_operator = qlm.QRoutine() 57 | uq_qbits = unitary_operator.new_wires(n_qbits) 58 | unitary_operator.apply(qlm.PH(np.pi / 4.0).ctrl(), 0, 1) 59 | auxiliar_qbits_number = 3 60 | # We create a python dictionary for configuration of class 61 | qft_pe_dict = { 62 | "initial_state": initial_state, 63 | "unitary_operator": unitary_operator, 64 | "auxiliar_qbits_number": auxiliar_qbits_number, 65 | "shots": 100, 66 | "qpu": qpu 67 | } 68 | qft_pe = CQPE(**qft_pe_dict) 69 | qft_pe.run() 70 | phi_meas = qft_pe.result.iloc[qft_pe.result["Probability"].idxmax()][ 71 | "lambda" 72 | ] 73 | assert np.isclose(phi_meas, 0.125) 74 | 75 | ###Phase Estimation with classical QPE### 76 | from QQuantLib.AE.ae_classical_qpe import CQPEAE 77 | 78 | 79 | def test_ae_w_qpe_qft(): 80 | 81 | # Here we created the mandatory oracle 82 | n = 3 83 | N = 2**n 84 | x = np.arange(N) 85 | probability = x / np.sum(x) 86 | oracle = load_probability(probability) 87 | 88 | # This will be the target state for grover and the list of qbits affected by Grover operator 89 | target = [0, 0, 1] 90 | index = range(oracle.arity) 91 | 92 | ae_pe_qft_dict = { 93 | "auxiliar_qbits_number": 4, "shots": 10, 94 | "qpu": qpu 95 | } 96 | 97 | ae_pe_qft = CQPEAE(oracle=oracle, target=target, index=index, **ae_pe_qft_dict) 98 | 99 | a_estimated = ae_pe_qft.run() 100 | 101 | classical_result = probability[1] 102 | error = abs(ae_pe_qft.ae - classical_result) 103 | assert error < 0.005 104 | 105 | -------------------------------------------------------------------------------- /tests/test_data_loading.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests For data_loading functions 3 | """ 4 | import sys 5 | sys.path.append("../") 6 | import numpy as np 7 | import qat.lang.AQASM as qlm 8 | 9 | from QQuantLib.DL.data_loading import load_probability, uniform_distribution, load_array 10 | from QQuantLib.utils.data_extracting import get_results 11 | 12 | from qat.qpus import get_default_qpu 13 | linalg_qpu = get_default_qpu() 14 | 15 | def test_load_probability(): 16 | """ 17 | Testing probability loading 18 | """ 19 | 20 | n_qbits = 3 21 | array_lenght = 2**n_qbits 22 | x = np.arange(array_lenght) 23 | probability = x / np.sum(x) 24 | q_rout = load_probability(probability) 25 | results, _, _, _ = get_results(q_rout, linalg_qpu=linalg_qpu) 26 | test_result = np.isclose( 27 | results.sort_values("Int_lsb")["Probability"].values, probability 28 | ) 29 | 30 | assert test_result.all() == True 31 | 32 | 33 | def test_load_array(): 34 | """ 35 | Testing array loading 36 | """ 37 | n_qbits = 3 38 | array_lenght = 2**n_qbits 39 | x = np.arange(array_lenght) 40 | normalization_constant = np.max(x) 41 | f = x 42 | f_normalised = x / normalization_constant 43 | q_rout = qlm.QRoutine() 44 | register = q_rout.new_wires(n_qbits + 1) 45 | q_rout.apply(uniform_distribution(n_qbits), register[:n_qbits]) 46 | q_rout.apply(load_array(f_normalised), register) 47 | results, _, _, _ = get_results(q_rout, linalg_qpu=linalg_qpu) 48 | quantum_probabilities = results.sort_values("Int_lsb")["Probability"].values 49 | quantum_f = ( 50 | np.sqrt(quantum_probabilities) * np.sqrt(array_lenght) * normalization_constant 51 | ) 52 | test_result = np.isclose(quantum_f[:array_lenght], f) 53 | assert test_result.all() == True 54 | 55 | 56 | def test_complete_load(): 57 | """ 58 | Loading a function upon a non trivial probability distribution 59 | """ 60 | 61 | n_qbits = 3 62 | array_lenght = 2**n_qbits 63 | x = np.arange(array_lenght) 64 | probability = x / np.sum(x) 65 | normalization_constant = np.max(x) 66 | f = x 67 | f_normalised = x / normalization_constant 68 | 69 | q_rout = qlm.QRoutine() 70 | register = q_rout.new_wires(n_qbits + 1) 71 | q_rout.apply(load_probability(probability), register[:n_qbits]) 72 | f_root = np.sqrt(f_normalised) 73 | q_rout.apply(load_array(f_root), register) 74 | results, _, _, _ = get_results(q_rout, linalg_qpu=linalg_qpu) 75 | quantum_probabilities = results.sort_values("Int_lsb")["Probability"].values 76 | quantum_result = quantum_probabilities * normalization_constant 77 | test_result = np.isclose(quantum_result[0:array_lenght], probability * f) 78 | assert test_result.all() == True 79 | -------------------------------------------------------------------------------- /tests/test_iqpe.py: -------------------------------------------------------------------------------- 1 | """ 2 | test for classical QPE 3 | """ 4 | import numpy as np 5 | import qat.lang.AQASM as qlm 6 | import sys 7 | sys.path.append("../") 8 | 9 | from QQuantLib.utils.utils import get_histogram 10 | from QQuantLib.DL.data_loading import load_probability, load_array, load_pf 11 | from QQuantLib.AA.amplitude_amplification import grover 12 | from QQuantLib.PE.iterative_quantum_pe import IQPE 13 | from QQuantLib.AE.ae_iterative_quantum_pe import IQPEAE 14 | from QQuantLib.utils.data_extracting import get_results 15 | from QQuantLib.qpu.get_qpu import get_qpu 16 | 17 | 18 | #### Phase Estimation Test-01: Phase of S Gate ### 19 | 20 | 21 | def test_pe_s_gate(): 22 | 23 | n_qbits = 1 24 | initial_state = qlm.QRoutine() 25 | q_bits = initial_state.new_wires(n_qbits) 26 | for i in range(n_qbits): 27 | initial_state.apply(qlm.X, q_bits[i]) 28 | unitary_operator = qlm.PH(np.pi / 2.0) 29 | auxiliar_qbits_number = 2 30 | # We create a python dictionary for configuration of class 31 | linalg_qpu = get_qpu("python") 32 | iqpe_dict = { 33 | "qpu": linalg_qpu, 34 | "initial_state": initial_state, 35 | "unitary_operator": unitary_operator, 36 | "auxiliar_qbits_number": auxiliar_qbits_number, 37 | "shots": 100, 38 | } 39 | iqpe = IQPE(**iqpe_dict) 40 | iqpe.iqpe() 41 | phi_meas = iqpe.final_results.iloc[iqpe.final_results["Frequency"].idxmax()]["Phi"] 42 | assert np.isclose(phi_meas, 0.25) 43 | # 44 | # 45 | ##### Phase Estimation Test-02: Phase of Controlled-T Gate ### 46 | # 47 | # 48 | def test_pe_c_t_gate(): 49 | 50 | n_qbits = 3 51 | initial_state = qlm.QRoutine() 52 | q_bits = initial_state.new_wires(n_qbits) 53 | for i in range(n_qbits): 54 | initial_state.apply(qlm.X, q_bits[i]) 55 | # Create cT operator 56 | unitary_operator = qlm.QRoutine() 57 | uq_qbits = unitary_operator.new_wires(n_qbits) 58 | unitary_operator.apply(qlm.PH(np.pi / 4.0).ctrl(), 0, 1) 59 | auxiliar_qbits_number = 3 60 | # We create a python dictionary for configuration of class 61 | linalg_qpu = get_qpu("python") 62 | iqpe_dict = { 63 | "qpu": linalg_qpu, 64 | "initial_state": initial_state, 65 | "unitary_operator": unitary_operator, 66 | "auxiliar_qbits_number": auxiliar_qbits_number, 67 | "shots": 100, 68 | "qpu": linalg_qpu, 69 | } 70 | iqpe = IQPE(**iqpe_dict) 71 | iqpe.iqpe() 72 | phi_meas = iqpe.final_results.iloc[iqpe.final_results["Frequency"].idxmax()]["Phi"] 73 | assert np.isclose(phi_meas, 0.125) 74 | 75 | 76 | ###Phase Estimation with IQPE### 77 | 78 | 79 | def test_ae_w_iqpe(): 80 | 81 | # Here we created the mandatory oracle 82 | n = 3 83 | N = 2**n 84 | x = np.arange(N) 85 | probability = x / np.sum(x) 86 | oracle = load_probability(probability) 87 | 88 | # This will be the target state for grover and the list of qbits affected by Grover operator 89 | target = [0, 0, 1] 90 | index = range(oracle.arity) 91 | 92 | linalg_qpu = get_qpu("python") 93 | ae_iqpe_dict = { 94 | "qpu": linalg_qpu, 95 | "auxiliar_qbits_number": 4, 96 | "shots": 10, 97 | } 98 | 99 | ae_iqpe = IQPEAE(oracle=oracle, target=target, index=index, **ae_iqpe_dict) 100 | 101 | a_estimated = ae_iqpe.run() 102 | 103 | classical_result = probability[1] 104 | error = abs(ae_iqpe.ae - classical_result) 105 | assert error < 0.005 106 | -------------------------------------------------------------------------------- /tests/test_maximum_likelihood.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests For maximum likelihood 3 | """ 4 | import numpy as np 5 | import qat.lang.AQASM as qlm 6 | import sys 7 | sys.path.append("../") 8 | 9 | from QQuantLib.utils.utils import get_histogram 10 | from QQuantLib.DL.data_loading import load_probability, load_array, load_pf 11 | from QQuantLib.AE.maximum_likelihood_ae import MLAE 12 | 13 | 14 | # Prepare Data for loading 15 | def launch_data(n_qbits): 16 | def p(x): 17 | return x * x 18 | 19 | def f(x): 20 | return np.sin(x) 21 | 22 | # The number of bins 23 | m_bins = 2**n_qbits 24 | lower_limit = 0.0 25 | upper_limit = 1.0 26 | x, p_x = get_histogram(p, lower_limit, upper_limit, m_bins) 27 | f_x = f(x) 28 | return x, f_x, p_x 29 | 30 | 31 | def load_gates(p_x, f_x): 32 | p_gate = load_probability(p_x) 33 | f_gate = load_array(np.sqrt(f_x)) 34 | pf_gate = load_pf(p_gate, f_gate) 35 | return p_gate, f_gate, pf_gate 36 | 37 | 38 | def test_maximum_likelihood(): 39 | 40 | x, f_x, p_x = launch_data(5) 41 | p_gate, f_gate, pf_gate = load_gates(p_x, f_x) 42 | 43 | m_k = list(range(7)) 44 | n_k = [200] * len(m_k) 45 | schedule = [m_k, n_k] 46 | 47 | mlae_ = MLAE(pf_gate, target=[0], index=[pf_gate.arity - 1], schedule=schedule) 48 | estimated_a = mlae_.run() 49 | calculated_integral = mlae_.ae 50 | theoric_integral = np.sum(f_x * p_x) 51 | print(calculated_integral) 52 | print(theoric_integral) 53 | 54 | Delta = np.abs(calculated_integral - theoric_integral) 55 | print("##########") 56 | print(Delta) 57 | print("##########") 58 | assert Delta < 0.01 59 | --------------------------------------------------------------------------------