Special Topics
This page provides detailed information on specialized functionalities in MIMIQ.
Repeated Targets
By default, MIMIQ does not allow repeated targets in a single instruction. This means that if an operation acts on several targets of the same register, those targets are normally expected to be distinct.
Qubit targets are a special case: they can never be repeated.
For some operations, repeated classical-bit or Z-register targets are meaningful and therefore explicitly allowed. This is useful when the same register is both read and written by the operation.
Repeated classical-bit targets
Some classical and control-flow operations allow repeated classical-bit targets. This includes IfStatement, WhileStatement, And, Or, and Xor.
For IfStatement and WhileStatement, this means that the same classical register can appear both in the body of the operation and in the condition bits.
c = Circuit()
# Toggle c[1] if c[1] == 1
push!(c, IfStatement(Not(), bs"1"), 1, 1)1-bit circuit with 1 instruction:
└── IF(c==1) ~ @ c[1], condition[1]c = Circuit()
# Repeatedly apply Not() while c[1] == 1
push!(c, WhileStatement(Not(), bs"1"), 1, 1)1-bit circuit with 1 instruction:
└── WHILE(c==1) ~ @ c[1], condition[1]For classical Boolean operations such as And, Or, and Xor, repeated bit targets allow in-place updates.
c = Circuit()
push!(c, And(), 1, 1, 2)2-bit circuit with 1 instruction:
└── c[1] = c[1] & c[2]This means that the result is written to c[1] while also reading c[1] as one of the inputs.
Repeated Z-register targets
Some Z-register operations also allow repeated targets. This includes Add, Multiply, Pow, and also the wrapper operations IfStatement and WhileStatement.
This is useful for in-place updates of Z-register variables.
c = Circuit()
push!(c, Add(3), 1, 1, 2)2-vars circuit with 1 instruction:
└── z[1] = z[1] + z[2]push!(c, Multiply(3), 1, 1, 2)2-vars circuit with 2 instructions:
├── z[1] = z[1] + z[2]
└── z[1] = z[1] * z[2]In the first case we compute z[1] = z[1] + z[2], and in the second case z[1] = z[1] * z[2].
BitString
The BitString class represents the state of bits and can be used to represent classical registers with specified values for each bit (0 or 1). At its core, it is simply a vector of Bools. BitString allows direct bit manipulation, bitwise operations, and conversion to other data formats like integers. It’s designed for flexibility in binary manipulation tasks within quantum computations.
Using BitString in MIMIQ Operations
In MIMIQ, several operations use BitString as a direct input for conditional logic or specific quantum operations, such as IfStatement, WhileStatement, and Amplitude, see non-unitary operations and statistical operations pages. Here are some examples:
# Conditional Operation: IfStatement
if_statement = IfStatement(GateX(), BitString("01011"))
# Conditional Loop: WhileStatement
while_statement = WhileStatement(Not(), BitString("1"))
# Amplitude Operation
Amplitude(BitString("001"))Amplitude(bs"001")Constructors
BitStrings can be constructed in different ways.
From a String: You can use the
BitString("binary_string")to initialize aBitStringby parsing a string in binary format.# Initialize a BitString from a binary string representation BitString("1101")4-bits BitString with integer value 11: 1101Alternatively, you can use the syntax
bs"binary_string"to create the sameBitString.# Initialize a BitString using the bs"..." literal syntax bs"01"2-bits BitString with integer value 2: 01From bit locations: You can use the
BitString(numbits[; bit_indices])syntax to initialize aBitStringofnumbitsbits, setting specific bits indicated bybit_indicesto 1.# Initializing with Specific Bits BitString(8, [2, 4, 6])8-bits BitString with integer value 42: 01010100From a function: You can use the
BitString(f::Function, numbits)syntax to initialize aBitStringwithnumbits, where each bit is set based on the result of the provided functionfapplied on each index.# Initialize an 8-bit BitString where bits are set based on even indices BitString(8) do i iseven(i) end8-bits BitString with integer value 170: 01010101
Accessing and Modifying Bits
Each bit in a BitString can be accessed or modified individually in the same way as vectors, making it easy to retrieve or set specific bit values.
using MimiqCircuits # hide
# Accessing a Bit
bs=BitString(4, [1, 3])
println(bs[2])
# Modifying a Bit
bs[2] = true
bsA useful function is nonzeros which returns the indices of the non-zero bits in a BitString.
# Retrieve Non-Zero Indices
nonzeros(bs)3-element Vector{Int64}:
1
3
5Conversion and Manipulation Methods
The BitString class includes functionality for conversion to integer representations, indexing, and other methods for retrieving and manipulating bit values:
BitString to Integer: To convert a
BitStringinto its integer representation, you can use the functionbitstring_to_integer. By default it uses a big-endian order.bs = BitString("101010") # Convert BitString to Integer (big-endian by default) bitstring_to_integer(bs)21Alternatively, you can use the function
bitstring_to_index, which converts aBitStringto an index for purposes like vector indexing, checking bounds, and compatibility with 64-bit indexing constraints. It's essentially the same asbitstring_to_integerbut shifted by 1.bs = BitString("101010") # Convert BitString to Index (Offset by 1 for Julia's 1-based indexing) bitstring_to_index(bs)22BitString to String: To convert a
BitStringinto aStringof "0" and "1" characters, you can use the functionto01.bs = BitString("101010") # Convert BitString to String of "0"s and "1"s (big-endian) println(to01(bs)) # Convert BitString to String of "0"s and "1"s (little-endian) to01(bs, endianess=:little)"010101"
Bitwise Operators
BitString supports bitwise operations such as NOT, AND, OR, XOR, as well as bitwise shifts:
Bitwise NOT:
~bs = BitString("1011") # Bitwise NOT ~bs4-bits BitString with integer value 2: 0100Bitwise AND and OR:
&,|bs1 = BitString("1100") bs2 = BitString("0110") # Bitwise AND bs1 & bs24-bits BitString with integer value 2: 0100# Bitwise OR bs1 | bs24-bits BitString with integer value 7: 1110Bitwise XOR:
⊻# Bitwise XOR bs1 ⊻ bs24-bits BitString with integer value 5: 1010Left Shift:
<<, and Right Shift:>># Left Shift bs << 14-bits BitString with integer value 14: 0111# Right Shift bs >> 14-bits BitString with integer value 11: 1101
Concatenation and Repetition
BitString supports concatenation and repetition, allowing you to combine or extend bitstrings efficiently:
Concatenation: Use
vcatto combines twoBitStringobjects by appending the bits ofrhstolhs.Repetition: Use
repeatto repeats theBitStringa specified number of times, creating a newBitStringwith the pattern repeated.
Examples:
# Define two BitString objects
bs1 = BitString("1010")
bs2 = BitString("0101")
# Concatenate bs1 and bs2
vcat(bs1, bs2)8-bits BitString with integer value 165:
10100101
# Repeat bs1 two times
repeat(bs1, 2)8-bits BitString with integer value 85:
10101010