Skip to content

Commit

Permalink
Updated notebooks and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
gonfeco committed Oct 15, 2024
1 parent afe16dd commit 0e51ea7
Show file tree
Hide file tree
Showing 23 changed files with 443 additions and 208 deletions.
165 changes: 94 additions & 71 deletions QQuantLib/qml4var/losses.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
"""
Functions for computing losses
"""

import copy
import numpy as np

def compute_integral(y_array, x_array, dask_client=None):
"""
Function for computing numerical integral of inputs arrays. Considerations:
* if x_array has shape(n, 1) then numpy trapz is used for computing integral.
* if x_array has shape(n, 2) and dask_client is None numpy trapz
is used for computing the double integral.
* if x_array has shape(n, 2) and dask_client is provided then MonteCarlo
integration is used
* if x_array has shape(n, > 2) MonteCarlo integration is used
* if x_array has shape(n, 1) then numpy trapz is used for computing integral.
* if x_array has shape(n, 2) and dask_client is None numpy trapz
is used for computing the double integral.
* if x_array has shape(n, 2) and dask_client is provided then MonteCarlo
integration is used
* if x_array has shape(n, > 2) MonteCarlo integration is used
Parameters
----------
y_array : np.array or dask futures:
Expand Down Expand Up @@ -69,12 +70,14 @@ def compute_integral(y_array, x_array, dask_client=None):
def trapezoidal_rule(x_domain,y_range):
"""
Computes the integral using the trapezoidal_rule
Parameters
----------
x_domain : numpy array
domain for computing the integral
y_range : numpy array
range for computing the integral
Returns
-------
integral : float
Expand All @@ -88,6 +91,7 @@ def loss_function_qdml(
labels, predict_cdf, predict_pdf, integral, loss_weights=[1.0, 5.0]):
"""
Computes the function for Quantum Differential Machine Learning
Parameters
----------
labels : numpy array
Expand All @@ -101,48 +105,7 @@ def loss_function_qdml(
domain
loss_weights : list
Weights for each part of the Loss function
Returns
-------
loss_ : float
evaluation of the loss function for QDML
"""

alpha_0 = loss_weights[0]
alpha_1 = loss_weights[1]
# Loss Computation
#Typical DL error
if predict_cdf.shape != labels.shape:
raise ValueError("predict_cdf and labels have different shape!!")
error_ = (predict_cdf - labels)
loss_1 = np.mean(error_ ** 2)
if predict_pdf.shape != labels.shape:
raise ValueError("predict_pdf and labels have different shape!!")
#print("\t loss_1 : {}".format(loss_1))
mean = -2 * np.mean(predict_pdf)
#print("\t mean : {}".format(mean))
loss_ = alpha_0 * loss_1 + alpha_1 * (mean + integral)
#print("\t loss: {}".format(loss))
return loss_
def loss_function_qdml_old(
labels, predict_cdf, predict_pdf,
x_quad, predict_quad, loss_weights=[1.0, 5.0]):
"""
Computes the function for Quantum Differential Machine Learning
Parameters
----------
labels : numpy array
numpy array with the labels. Shape: (-1, 1)
predict_cdf : numpy array
numpy array with the predictions for the CDF. Shape: (-1, 1)
predict_pdf : numpy array
numpy array with the predictions for the PDF. Shape: (-1, 1)
x_quad : numpy array
numpy array with the domain for computing the integral of the PDF
Shape: (-1, number of features)
predict_quad : numpy array
numpy array with the PDF for computing the integral of the PDF
Shape: (-1, 1)
Returns
-------
loss_ : float
Expand All @@ -162,42 +125,90 @@ def loss_function_qdml_old(
#print("\t loss_1 : {}".format(loss_1))
mean = -2 * np.mean(predict_pdf)
#print("\t mean : {}".format(mean))
square_for_integral = predict_quad ** 2

if x_quad.shape[1] == 1:
# Typical 1-D trapezoidal integration
integral = np.trapz(y=square_for_integral[:, 0], x=x_quad[:, 0])
elif x_quad.shape[1] == 2:
# 2-D Trapezoidal integration
x_domain, y_domain = np.meshgrid(
np.unique(x_quad[:, 0]),
np.unique(x_quad[:, 1])
)
square_for_integral = square_for_integral.reshape(x_domain.shape)
integral = np.trapz(
np.trapz(y=square_for_integral, x=x_domain),
x=y_domain[:, 0]
)
else:
# MonteCarlo approach
integral = np.sum(square_for_integral) * np.prod(
x_quad.max(axis=0) - x_quad.min(axis=0)
) / square_for_integral.size
#integral = trapezoidal_rule(x_quad[:, 0], predict_quad[:, 0] * predict_quad[:, 0])
#print("\t integral: {}".format(integral))
loss_ = alpha_0 * loss_1 + alpha_1 * (mean + integral)
#print("\t loss: {}".format(loss))
return loss_

# def loss_function_qdml_old(
# labels, predict_cdf, predict_pdf,
# x_quad, predict_quad, loss_weights=[1.0, 5.0]):
# """
# Computes the function for Quantum Differential Machine Learning
# Parameters
# ----------
# labels : numpy array
# numpy array with the labels. Shape: (-1, 1)
# predict_cdf : numpy array
# numpy array with the predictions for the CDF. Shape: (-1, 1)
# predict_pdf : numpy array
# numpy array with the predictions for the PDF. Shape: (-1, 1)
# x_quad : numpy array
# numpy array with the domain for computing the integral of the PDF
# Shape: (-1, number of features)
# predict_quad : numpy array
# numpy array with the PDF for computing the integral of the PDF
# Shape: (-1, 1)
# Returns
# -------
# loss_ : float
# evaluation of the loss function for QDML
# """
#
# alpha_0 = loss_weights[0]
# alpha_1 = loss_weights[1]
# # Loss Computation
# #Typical DL error
# if predict_cdf.shape != labels.shape:
# raise ValueError("predict_cdf and labels have different shape!!")
# error_ = (predict_cdf - labels)
# loss_1 = np.mean(error_ ** 2)
# if predict_pdf.shape != labels.shape:
# raise ValueError("predict_pdf and labels have different shape!!")
# #print("\t loss_1 : {}".format(loss_1))
# mean = -2 * np.mean(predict_pdf)
# #print("\t mean : {}".format(mean))
# square_for_integral = predict_quad ** 2
#
# if x_quad.shape[1] == 1:
# # Typical 1-D trapezoidal integration
# integral = np.trapz(y=square_for_integral[:, 0], x=x_quad[:, 0])
# elif x_quad.shape[1] == 2:
# # 2-D Trapezoidal integration
# x_domain, y_domain = np.meshgrid(
# np.unique(x_quad[:, 0]),
# np.unique(x_quad[:, 1])
# )
# square_for_integral = square_for_integral.reshape(x_domain.shape)
# integral = np.trapz(
# np.trapz(y=square_for_integral, x=x_domain),
# x=y_domain[:, 0]
# )
# else:
# # MonteCarlo approach
# integral = np.sum(square_for_integral) * np.prod(
# x_quad.max(axis=0) - x_quad.min(axis=0)
# ) / square_for_integral.size
# #integral = trapezoidal_rule(x_quad[:, 0], predict_quad[:, 0] * predict_quad[:, 0])
# #print("\t integral: {}".format(integral))
# loss_ = alpha_0 * loss_1 + alpha_1 * (mean + integral)
# #print("\t loss: {}".format(loss))
# return loss_

def mse(labels, prediction):
"""
Compute Mean Square Error
Parameters
----------
labels : numpy array
numpy array with the labels
prediction : numpy array
numpy array with the predictions
Returns
-------
mse_v : float
MSE value
"""
error_ = (prediction - labels.reshape(prediction.shape))
mse_v = np.mean(error_ ** 2)
Expand All @@ -207,6 +218,7 @@ def mse(labels, prediction):
def compute_loss(weights, produce_results, loss_function):
"""
Workflow for computing loss:
Parameters
----------
weights : list
Expand All @@ -215,6 +227,11 @@ def compute_loss(weights, produce_results, loss_function):
Function for producing mandatory inputs for computing loss
loss_function : python function
Function for computing loss function
Returns
-------
loss_ : float
Loss value
"""

output_dict = produce_results(weights)
Expand All @@ -224,7 +241,8 @@ def compute_loss(weights, produce_results, loss_function):
def numeric_gradient(weights, data_x, data_y, loss):
"""
Compute the numeric gradient for some input loss function properly
configured
configured.
Parameters
----------
weights : numpy array
Expand All @@ -235,6 +253,11 @@ def numeric_gradient(weights, data_x, data_y, loss):
Array with targets (labes) dataset
loss : function
function for computing the loss properly configured
Returns
-------
gradient_i : numpy array
Array with the gradients of the Loss Function
"""
gradient_i = []
epsilon = 1.0e-7
Expand Down
1 change: 1 addition & 0 deletions QQuantLib/qml4var/myqlm_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This module contains the different myqlm workflows mandatory for
the different PQCs evaluations needed for a training proccess
"""

import numpy as np
from itertools import product
from qat.core import Batch
Expand Down
7 changes: 7 additions & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* :doc:`pe`: This is the *Phase Estimation* package which contains modules for phase estimation algorithms that can be used in amplitude estimation procedures.
* :doc:`ae`: This is the *Amplitude Estimation* package which is devoted to different amplitude amplification algorithms.
* :doc:`finance`: This package implements different modules related to finance applications of *Amplitude Estimation* techniques.
* :doc:`qml4var`: This package contains modules for training **PQC**s for using as surrogate models for Financial **CDF**s for VaR computations.
* :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.
* :doc:`utils`: This package contains auxiliary modules used for all the beforementioned packages.

Expand Down Expand Up @@ -63,6 +64,12 @@

finance.rst

.. toctree::
:maxdepth: 1
:hidden:

qml4var.rst


.. toctree::
:maxdepth: 1
Expand Down
6 changes: 6 additions & 0 deletions doc/qml4var.adam.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

adam
====

.. automodule:: QQuantLib.qml4var.adam
:members:
7 changes: 7 additions & 0 deletions doc/qml4var.architectures.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

architectures
=============

.. automodule:: QQuantLib.qml4var.architectures
:members:

6 changes: 6 additions & 0 deletions doc/qml4var.data_utils.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
data_utils
==========

.. automodule:: QQuantLib.qml4var.data_utils
:members:

5 changes: 5 additions & 0 deletions doc/qml4var.losses.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
losses
======

.. automodule:: QQuantLib.qml4var.losses
:members:
6 changes: 6 additions & 0 deletions doc/qml4var.myqlm_workflows.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

myqlm_workflows
===============

.. automodule:: QQuantLib.qml4var.myqlm_workflows
:members:
6 changes: 6 additions & 0 deletions doc/qml4var.plugins.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

plugins
=======

.. automodule:: QQuantLib.qml4var.plugins
:members:
52 changes: 52 additions & 0 deletions doc/qml4var.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
QQuantLib.qml4var
=================

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.

The following modules are presented:

* :doc:`qml4var.data_utils`: This module contains functions for generating suitable datasets for training **PQC**s for **CDF** evaluation.
* :doc:`qml4var.architectures`: This module implements a hardware efficient ansatz **PQC** and define the measurement observable.
* :doc:`qml4var.plugins`: This module contains home made **myQLM Plugins** used for evaluating **PQC** s for a set of trainable and feature parameters.
* :doc:`qml4var.myqlm\_workflows`: This module implements workflows for evaluating the **PQC** s.
* :doc:`qml4var.losses`: This module implements several loss functions.
* :doc:`qml4var.adam`: This module implements the ADAM optimizer.


.. toctree::
:maxdepth: 1
:hidden:

qml4var.data_utils.rst

.. toctree::
:maxdepth: 1
:hidden:

qml4var.architectures.rst

.. toctree::
:maxdepth: 1
:hidden:

qml4var.plugins.rst

.. toctree::
:maxdepth: 1
:hidden:

qml4var.myqlm_workflows.rst

.. toctree::
:maxdepth: 1
:hidden:

qml4var.losses.rst

.. toctree::
:maxdepth: 1
:hidden:

qml4var.adam.rst


Loading

0 comments on commit 0e51ea7

Please sign in to comment.