ProjectQ icon indicating copy to clipboard operation
ProjectQ copied to clipboard

Suggestion: generate commands with assignment-operations on quregisters

Open Strilanc opened this issue 8 years ago • 2 comments

Add +=, ^=, etc operators to Qureg:

class Qureg(list):
    ...
    def __iadd__(self, other):
        if isinstance(other, int):
            OffsetGate(other) | self
            return self

        if isinstance(other, Qureg):
            Add | (other, self)
            return self

        if isinstance(other, RValue):
            other.add_into(self)
            return self

        raise NotImplementedError()

    def __ixor__(self, other):
        if isinstance(other, Qureg):
            for dst, src in zip(self, other):
                X & src | dst
            return self

        if isinstance(other, int):
            for i in range(len(self)):
                if (other >> i) & 1:
                    X | self[i]
            return self

        if isinstance(other, RValue):
            other.xor_into(self)
            return self

        raise NotImplementedError()
    ...

Also add RValue-producing +, ~, & etc operators:

class Qureg(list):
    def __invert__(self):
        return RValueNotQureg(self)

    def __neg__(self):
        return RValueNegQureg(self)

    def __and__(self, other):
        return RValueAndQuregs((self, other))

Add RValue classes:

class RValueAndQuregs(RValue):
    def __init__(self, quregs):
        self.quregs = quregs

    def xor_into(self, target_qureg):
        for dst_bit, src_bits in zip(self, zip(*self.quregs)):
            X & src_bits | dst_bit

...

And then users can do arithmetic in a way that looks quite like normal python:

def multiply_accumulate(src_qureg, factor, dst_qureg):
    i = 0
    while factor >= 1 << i:
        if (factor >> i) & 1:
            dst_qureg += src_qureg << i  # Generates command(s)
        i += 1

Strilanc avatar May 15 '17 18:05 Strilanc

Some downsides:

  • Assignment really feels like it should create a new register, but instead it just holds an RValue.
  • The RValues have reference semantics. c = a + b; a += 1; d += c; is equivalent to d += a + b + 1; a += 1 not d += a + b; a += 1. Might need some kind of copy-on-write mechanism.
  • Some operations are irreversible. Can't support a %= 5 unless it implies a measurement of a//5.
  • Modular arithmetic doesn't work as nicely as I'd like. You can't say a.working_modulo(5) += 2.

Strilanc avatar May 15 '17 19:05 Strilanc

Sure! But as mentioned in #71 , I'd prefer to put such functionality in a new type (e.g., Quint in this case).

Indeed, this works nicely for some functions and not so nicely for others... I think we should nevertheless try to make "quantum math" easy to use and implementing, e.g., addition and multiplication would be a good first step.

thomashaener avatar May 16 '17 03:05 thomashaener