I'm working in Q#, a quantum programming language based on C#. Quantum operations become C# classes, from which you can do things like
QuantumOperation.run(simulator, param1, param2);
which will use a quantum simulator simulator
to run the operation QuantumOperation
with the parameters param1
and param2
.
I have many different operations which I want to run using different simulators and different parameters. What I would like to do is pass the quantum operation to another method, which will iterate through all the simulators and parameters. Then I can call this method with all the quantum operations I want.
The problem is that - as far as I can tell - a quantum operation is really a class and not an object. So, for example, if I write:
static void someMethod<Qop>(){...}
then I can call this with a quantum operation QuantumOperation
as:
someMethod<QuantumOperation>()
and it compiles fine. However, if I try to do something like
static void someMethod<Qop>(Qop quantumOperation){ ...}
someMethod<QuantumOperation>(quantumOperation);
I get an error of "QuantumOperation
is a type, which is not valid in the given context" for the second line.
If I try:
static void someMethod<Qop>(...){
...
Qop.Run(...);
...
}
it similarly says: "'Qop' is a type parameter, which is not valid in the given context".
What seems to be happening here is that I'm passing the class as a type. But then when I want to treat the type as a class, I can't. I looked for ways to pass a class as an argument, but I only see ways to do this that will create objects in that class. But I can't use an object, since "Run" is a static method.
(I could try passing an object and getting the class from that, but (a) I don't know if it's possible to create objects of quantum operation classes, and (b) I can only find public Type GetType
, which returns a type and not a class, giving the same problem).
Is there any way to pass a class as an argument, then reference static methods of that class, without ever instantiating an object?
Now, maybe I'm asking too much, since, as far as C# is concerned, it's a coincidence that all these classes have a method called "Run". It maybe shouldn't be able to attempt to call methods with the same name from different classes.
Alternatively, I could construct a method for each quantum operation and then pass those methods. The method would look like:
static void QuantumOperationWrapper(QuantumSimulator simulator, Int int_parameter){
QuantumOperation.Run(simulator, in_parameter);
}
I would need to make a new method for each quantum operation, but that's not that bad. Then I can pass this as a delegate or Func to the methods I want. The problem is that the results I want are contained in the QuantumSimulator
object. So what I want to do is something like:
QuantumOperationWrapper(simulator, 3);
simulator.GetResults();
But when I do this, the results are empty. My guess is that, somehow, the simulator is being passed by value, or treated as immutable, or something that prevents QuantumOperationWrapper
from altering internal parameters of the simulator.
Is there any way to I can ensure that a delegate/Func will alter the internal state of its arguments?
EDIT: I can make a delegate for the Run
method, as follows:
public delegate System.Threading.Tasks.Task<Microsoft.Quantum.Simulation.Core.QVoid> RunQop(QCTraceSimulator sim, long n);
Then I can construct static void someMethod(RunQop runner, ...)
, and pass QuantumOperation.Run
as the first argument.
However, I have the same problem, that the QCTraceSimulator
I pass as an argument does not keep any of the simulation results it makes when I call this.