Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refac] Improve/refactor the behavior of set_trainable function #313

Open
jpmoutinho opened this issue Jan 30, 2024 · 3 comments
Open

[Refac] Improve/refactor the behavior of set_trainable function #313

jpmoutinho opened this issue Jan 30, 2024 · 3 comments
Labels
refactoring Refactoring of legacy code

Comments

@jpmoutinho
Copy link
Collaborator

By @madagra

Description

Currently, the set_trainable function is confusing and not very easy to use for more complex tasks such as QEL. This issue aims to improve the current interface by making more explicit what is fixed in the parameters and what is not. See below the proposed interface.

Proposed interface

We have three types of parameters in Qadence: variational, feature, and fixed. Let's make this explicit in the high-level QuantumModel interface and not only at the block level.

High-level interface for the QuantumModel

# model with all types of parameters
optmodel = QuantumModel(...)

# select the variational parameters and return a list of IDs (names)
# and not the current values
vparams = optmodel.vparams(only_ids=True)

# make the parameters fixed with the current values: this modifies the 
underlying QuantumCircuit in place and freeze the variational parameters
set_as_fixed(vparams, optmodel)

# select the feature parameters and return a list of IDs (names)
fparams = optmodel.fparams()

# set the feature parameters as variational
set_as_variational(fparams, optmodel) 

Alternatively and likely better (following the principle of OOP interface and functional core), we can also use class methods:

optmodel = QuantumModel(...)
optmodel.set_as_fixed(optmodel.vparams())
optmodel.set_as_variational(optmodel.fparams())

Low-level interface for blocks

The low-level interface for blocks can remain similar to what we have today, except that we can replace the set_trainable function with suitable and more explicit functions. For example:

circuit = ...

fm_b = circuit.get_blocks_by_tag("feature_map")
ansatz_b = circuit.get_blocks_by_tag("ansatz")

# set all the parameters in the block variational/fixed
set_as_variational(fm_b, inplace=True)
set_as_fixed(ansatz_b, inplace=True)

# set one parameter only as a feature
set_as_feature(ansatz_b, params=["th1"], inplace=True)

# recreate the circuit with the new, updated, blocks
circuit = QuantumCircuit(2, fm_b, ansatz_b)
@jpmoutinho jpmoutinho added the refactoring Refactoring of legacy code label Jan 30, 2024
@mlahariya
Copy link
Collaborator

Discuss with @inafergra - if this is still relevant?

@jpmoutinho
Copy link
Collaborator Author

For context @inafergra, we are pinging you because we were thinking you had an issue with QEL at some point that would have been fixed by having a better developed set_trainable function.

@inafergra
Copy link
Collaborator

Thanks for raising this. I think being able to set specific parameters as trainable/non-trainable at the QuantumModel level would be very useful indeed. Both for QEL and for more complicated algorithms where you might need a finer control of the parameters. There was no issue per se with the current set_trainable() function but it only operates at the block level which means you normally have to write some bolier-plate code to rebuild the QuantumModel if you change the trainability of its params.

No preference over the OOP or functional form, the functional maybe seems more neat to me but just a personal preference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactoring Refactoring of legacy code
Projects
None yet
Development

No branches or pull requests

3 participants