return m.ptr;
}
+void qansel_queue_init
+(
+ cpx_mtx_t* queueVectors,
+ int qubitCount,
+ int dofree
+)
+{
+ for (int i = 0; i < qubitCount; i++)
+ {
+ if (dofree) free(queueVectors[i].ptr);
+ int vectLen = queueVectors[i].rows * (queueVectors[i].cols * 2) + queueVectors[i].cols * 2;
+ queueVectors[i].rows = 2;
+ queueVectors[i].cols = 2;
+ queueVectors[i].ptr = malloc(vectLen);
+ memcpy(queueVectors[i].ptr, Identity, vectLen);
+ }
+}
+
+void qansel_instruction_queue
+(
+ cpx_mtx_t** queueVectors,
+ int qubitCount,
+ unsigned char instr,
+ unsigned char index,
+ float arg0,
+ float arg1,
+ float arg2
+)
+{
+ cpx_mtx_t gate, tmp;
+ gate.rows = 2;
+ gate.cols = 2;
+ float* gate_ptr;
+ int needToFreeGate = 0;
+ switch (instr)
+ {
+ case QANSEL_INSTRUCTION_H: gate_ptr = Hadamard; break;
+ case QANSEL_INSTRUCTION_X: gate_ptr = PauliX; break;
+ case QANSEL_INSTRUCTION_Y: gate_ptr = PauliY; break;
+ case QANSEL_INSTRUCTION_Z: gate_ptr = PauliZ; break;
+ case QANSEL_INSTRUCTION_S: gate_ptr = PhaseS; break;
+ case QANSEL_INSTRUCTION_T: gate_ptr = PhaseT; break;
+ case QANSEL_INSTRUCTION_RX:
+ case QANSEL_INSTRUCTION_RY:
+ case QANSEL_INSTRUCTION_RZ:
+ case QANSEL_INSTRUCTION_U1:
+ case QANSEL_INSTRUCTION_U2:
+ case QANSEL_INSTRUCTION_U3:
+ gate_ptr = qansel_unitary(arg0, arg1, arg2);
+ needToFreeGate = 1;
+ break;
+ default: gate_ptr = Identity; break;
+ }
+ unsigned char qubit = qubitCount - (index) - 1;
+ gate.rows = 2;
+ gate.cols = 2;
+ gate.ptr = gate_ptr;
+ tmp.rows = 1;
+ tmp.cols = 2;
+ tmp.ptr = malloc(tmp.rows * (tmp.cols * 2) * sizeof(float));
+ cpx_mtx_dot(tmp.ptr, queueVectors[index]->ptr, gate_ptr, queueVectors[index]->rows, queueVectors[index]->cols, 2, 2);
+ free(queueVectors[index]->ptr);
+ queueVectors[index]->rows = tmp.rows;
+ queueVectors[index]->cols = tmp.cols;
+ queueVectors[index]->ptr = tmp.ptr;
+ if (needToFreeGate) free(gate);
+}
+
void qansel_instruction
(
cpx_mtx_t* stateVector,
unsigned char index,
float arg0,
float arg1,
- float arg2
+ float arg2,
+ //if using gate queueing
+ cpx_mtx_t* queueVectors,
+ int queueStatus
)
{
+ if (queueStatus == 0) queueVectors = NULL;
cpx_mtx_t tmp;
cpx_mtx_t gate;
gate.rows = 2;
gate.cols = 2;
float* gate_ptr;
+ int needToFreeGate = 0;
switch (instr)
{
case QANSEL_INSTRUCTION_H: gate_ptr = Hadamard; break;
case QANSEL_INSTRUCTION_U2:
case QANSEL_INSTRUCTION_U3:
gate_ptr = qansel_unitary(arg0, arg1, arg2);
+ needToFreeGate = 1;
break;
default: gate_ptr = Identity; break;
}
cpx_t n;
cpx_mtx_t filter;
cpx_mtx_init(&filter, 2, 2);
- unsigned char qubit = qubitCount - (index) - 1;
- if (qubit == 0)
+ unsigned char qubit = qubitCount - (queueVectors == NULL ? index : 0) - 1;
+ if (qubit == 0 && queueVectors == NULL)
{
memcpy(filter.ptr, gate_ptr, 8 * sizeof(float));
}
- else
+ else if (queueVectors == NULL)
{
memcpy(filter.ptr, Identity, 8 * sizeof(float));
}
+ else
+ {
+ memcpy(filter.ptr, queueVectors[0].ptr, 8 * sizeof(float));
+ }
for (unsigned char i = 1; i < qubitCount; i++)
{
- if (index != 0x0F)
+ if (index != 0x0F && queueVectors == NULL)
{
if (qubit == i)
{
gate.ptr = Identity;
}
}
- else
+ else if (queueVectors == NULL)
{
gate.ptr = gate_ptr;
}
+ else
+ {
+ gate.ptr = queueVectors[i].ptr;
+ }
tmp.rows = filter.rows * gate.rows;
tmp.cols = filter.cols * gate.cols;
free(stateVector->ptr);
stateVector->ptr = tmp.ptr;
free(filter.ptr);
- if (instr == QANSEL_INSTRUCTION_U1 || instr == QANSEL_INSTRUCTION_U2 || instr == QANSEL_INSTRUCTION_U3)
- {
- free(gate_ptr);
- }
+ if (needToFreeGate) free(gate_ptr);
}
unsigned char qansel_measure(cpx_mtx_t* stateVector, unsigned char qubitCount, unsigned char qubit)
unsigned char bit = qansel_measure(stateVector, qubitCount, q0);
if (bit)
{
- qansel_instruction(stateVector, qubitCount, QANSEL_INSTRUCTION_X, q0, 0, 0, 0);
+ qansel_instruction(stateVector, qubitCount, QANSEL_INSTRUCTION_X, q0, 0, 0, 0, NULL, 0);
}
}
else if (q0 >= 0x10 && q0 <= 0x1D)
void qansel_run(unsigned char* program, int programSize, int qubitCount, int bitCount, unsigned char* outputBitVector)
{
+ int useQueue = 0;
int PC = 0;
unsigned int qubitCountPow2 = (unsigned int)pow(2, qubitCount);
unsigned char bitVector[bitCount];
memset(bitVector, 0, bitCount);
cpx_mtx_t stateVector;
+ cpx_mtx_t* queueVector = NULL;
+ int queueStatus = 0;
cpx_mtx_init(&stateVector, 1, qubitCountPow2);
cpx_mtx_set2(&stateVector, 0, 0, 1, 0);
+ if (useQueue)
+ {
+ queueVector = malloc(qubitCount * sizeof(cpx_mtx_t));
+ for (int i = 0; i < qubitCount; i++)
+ {
+ cpx_mtx_init(&(queueVector[i]), 1, 2);
+ cpx_mtx_set2(&(queueVector[i]), 0, 0, 1, 0);
+ }
+ }
if (QANSEL_USE_DISPLAY) { QANSEL_USE_DISPLAY = display(&stateVector, qubitCount, QANSEL_USE_DISPLAY); }
unsigned char skip = 0, a0 = 0, a1 = 0, a2 = 0;
unsigned char flags = 0;
case QANSEL_INSTRUCTION_S:
case QANSEL_INSTRUCTION_T:
a0 = program[PC + 1];
- qansel_instruction(&stateVector, qubitCount, instr, program[PC + 1], 0, 0, 0);
+ qansel_instruction(&stateVector, qubitCount, instr, program[PC + 1], 0, 0, 0, queueVector, queueStatus);
break;
case QANSEL_INSTRUCTION_RX:
a0 = program[PC + 1];
qansel_instruction
(
&stateVector, qubitCount, instr, a0,
- M_PI / 2, -M_PI / 2, qansel_get_float(program, PC + 2) - (M_PI / 2)
+ M_PI / 2, -M_PI / 2, qansel_get_float(program, PC + 2) - (M_PI / 2),
+ queueVector, queueStatus
);
break;
case QANSEL_INSTRUCTION_RY:
qansel_instruction
(
&stateVector, qubitCount, instr, a0,
- qansel_get_float(program, PC + 2), 0, 0
+ qansel_get_float(program, PC + 2), 0, 0,
+ queueVector, queueStatus
);
break;
case QANSEL_INSTRUCTION_RZ:
qansel_instruction
(
&stateVector, qubitCount, instr, a0,
- 0, 0, qansel_get_float(program, PC + 2)
+ 0, 0, qansel_get_float(program, PC + 2),
+ queueVector, queueStatus
);
break;
case QANSEL_INSTRUCTION_U2:
&stateVector, qubitCount, instr, a0,
qansel_get_float(program, PC + 2),
qansel_get_float(program, PC + 2 + sizeof(float)),
- 0
+ 0, queueVector, queueStatus
);
break;
case QANSEL_INSTRUCTION_U3:
&stateVector, qubitCount, instr, a0,
qansel_get_float(program, PC + 2),
qansel_get_float(program, PC + 2 + sizeof(float)),
- qansel_get_float(program, PC + 2 + sizeof(float) * 2)
+ qansel_get_float(program, PC + 2 + sizeof(float) * 2),
+ queueVector, queueStatus
);
break;
case QANSEL_INSTRUCTION_CX:
}
}
cpx_mtx_free(&stateVector);
+ if (useQueue)
+ {
+ for (int i = 0; i < qubitCount; i++)
+ {
+ cpx_mtx_free(&(queueVector[i]));
+ }
+ free(queueVector);
+ }
if (QANSEL_USE_DISPLAY) { display(NULL, 0, 0); }
}