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

Suggestion: generate commands with assignment-operations on quregisters #105

Open
Strilanc opened this issue May 15, 2017 · 2 comments
Open

Comments

@Strilanc
Copy link
Contributor

Strilanc commented May 15, 2017

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
Copy link
Contributor Author

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.

@thomashaener
Copy link
Contributor

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.

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

No branches or pull requests

2 participants