Skip to content

Commit

Permalink
Changes in error and exception outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
AbeerVaishnav13 committed Nov 27, 2019
1 parent 07c2dd8 commit e7d3118
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 51 deletions.
Binary file modified .DS_Store
Binary file not shown.
117 changes: 108 additions & 9 deletions QuaCLibs/QuaCExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,15 +233,17 @@ void executePrint(char *cmd, quReg *qr, QuregMap *qm) {
void executeFunc(KeyTypes *keytypes, IdentifierMap *gates, int i, int qureg_size, quReg *qr, QuregMap *qm) {
int cur_gate_num = 0;
int ret_i_val_func = 0;
char *func_name = (char*) malloc(strlen(keytypes[i].key) * sizeof(char));
strcpy(func_name, keytypes[i].key);

IdentifierMap *im;
IdentifierMap *imap;

while(keytypes[i].type != IDX_BRACKET_OPEN) i++;

while(keytypes[i].type != CMPND_STMT_CLOSE) {

if(cur_gate_num > qureg_size) {
printf("[!] Too many gates in the row. [%d]\n", cur_gate_num);
printf("[!] Too many gates in the function '%s'. [number of gates: %d]\n", func_name, cur_gate_num);
exit(-1);
}

Expand Down Expand Up @@ -276,24 +278,32 @@ void executeFunc(KeyTypes *keytypes, IdentifierMap *gates, int i, int qureg_size
qr = QSwap_reg(qr, cur_gate_num, idx2);
}
else if(keytypes[i].type == QFT) {

printf("QFT Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == CONTROL) {
printf("CONTROL Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == INV_CONTROL) {
printf("INVERSE-CONTROL Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == X_AXIS_CONTROL) {

printf("X-AXIS-CONTROL Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == Y_AXIS_CONTROL) {

printf("Y-AXIS-CONTROL Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == IDENTITY) {

}
else if((im = getIdentifier(keytypes[i].key, gates))) {
else if((imap = getIdentifier(keytypes[i].key, gates))) {
ret_i_val_func = i + 1;
i = im->idx;
executeGate(keytypes, im->idx, qr, cur_gate_num);
i = imap->idx;
executeGate(keytypes, i, qr, cur_gate_num);
i = ret_i_val_func;
}
else if(keytypes[i].type == PRINT) {
Expand All @@ -313,7 +323,96 @@ void executeFunc(KeyTypes *keytypes, IdentifierMap *gates, int i, int qureg_size
}

void executeGate(KeyTypes *keytypes, int i, quReg *qr, int gates_done) {

int gate_size = atoi(keytypes[i+2].key);
int cur_qubit_idx = 0;
int cur_gate_num = 0;
char *gate_name = (char*) malloc(strlen(keytypes[i].key) * sizeof(char));
strcpy(gate_name, keytypes[i].key);

if((gate_size + gates_done) > qr->size) {
printf("[!] Too many gates in the row. Resize the custom gate '%s' or decrease the number of pre-defined gates in the row. [%d]\n", keytypes[i].key, (gates_done + gate_size));
exit(-1);
}

i += 2;

while(keytypes[i].type != IDX_BRACKET_OPEN) i++;

while(keytypes[i].type != CMPND_STMT_CLOSE) {
if(cur_qubit_idx > gate_size) {
printf("[!] Too many gates in the custom gate '%s'. [number of gates: %d]\n", gate_name, cur_qubit_idx);
exit(-1);
}

cur_gate_num = gates_done + cur_qubit_idx;

if(keytypes[i].type == COMMA) {
}
else if(keytypes[i].type == IDX_BRACKET_CLOSE || keytypes[i].type == IDX_BRACKET_OPEN || keytypes[i].type == CMPND_STMT_CLOSE) {
cur_qubit_idx = 0;
}
else if(keytypes[i].type == PAULI_X) {
qr = X_reg(qr, cur_gate_num);
}
else if(keytypes[i].type == PAULI_Y) {
qr = Y_reg(qr, cur_gate_num);
}
else if(keytypes[i].type == PAULI_Z) {
qr = Z_reg(qr, cur_gate_num);
}
else if(keytypes[i].type == PHASE) {
qr = S_reg(qr, cur_gate_num);
}
else if(keytypes[i].type == ROTATION) {
int angle = atoi((keytypes[i].key + 2));
qr = R_reg(angle, qr, cur_gate_num);
}
else if(keytypes[i].type == HADAMARD) {
qr = H_reg(qr, cur_gate_num);
}
else if(keytypes[i].type == SWAP) {
int idx2 = cur_qubit_idx;
while(keytypes[i].type != SWAP) idx2++;

qr = QSwap_reg(qr, cur_gate_num, idx2);
}
else if(keytypes[i].type == QFT) {
printf("QFT Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == CONTROL) {
printf("CONTROL Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == INV_CONTROL) {
printf("INVERSE-CONTROL Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == X_AXIS_CONTROL) {
printf("X-AXIS-CONTROL Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == Y_AXIS_CONTROL) {
printf("Y-AXIS-CONTROL Gate: This functionality is not added right now. Please wait for the next version to use this.\n");
exit(0);
}
else if(keytypes[i].type == IDENTITY) {

}
else if(keytypes[i].type == PRINT) {
printf("[!] Cannot use print statement inside a gate.\n");
exit(-1);
}
else {
printf("[!] Invalid gate. Use one of the predefined or user defined gates.\n");
exit(-1);
}

if(keytypes[i].type != COMMA && keytypes[i].type != IDX_BRACKET_OPEN && keytypes[i].type != IDX_BRACKET_CLOSE) {
cur_qubit_idx += 1;
}
i++;
}
}

#endif
124 changes: 82 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
# Qua-C

Qua-C ( pronounced as /'kwɑ-si/) is a *domain specific programming language* for simulating **Quantum Computing Algorithms.**
Qua-C (pronounced as /'kwɑ-si/) is a *domain specific programming language* for simulating **Quantum Computing Algorithms.**

Qua-C is a language under development to make the process of coding a Quantum Algorithm easy and in a visual syntax format.

Qua-C has a different ideology from conventional programming languages, which have a sequential syntax format to apply functions and gates to data. Instead of a sequential construct, Qua-C executes code pseudo-parallel fashion for the set of qubits in the quregister.
Qua-C has a different ideology from conventional programming languages, which have a sequential syntax format to apply functions and gates to data. Instead of a sequential construct, Qua-C executes code column-wise manner for a set of qubits in the quregister.

**The Qua-C Transpiler is developed completely in 'C' language currently.**

Also see the 'Examples' folder to know more about the functionality. The 'Examples' folder contains various examples like:-

1. CNOT Gate
2. Hadamard Gate
3. Rotation of qubits about X, Y, Z - Axes of Bloch Sphere
4. Quantum NOT Gate
5. Quantum Registers
6. Quantum Rotation about imaginary axis
7. Quantum swapping of two Qubits
1. Basic Example
2. **Grover search** for 2 qubits
3. Hadamard Gate mania
4. **Shor's period finding** algorithm
5. **Grover Search** for 5 qubits with **custom gates**


## Quantum Registers
Expand All @@ -25,21 +23,27 @@ This feature allows the use to make registers consisting of multiple qubits at a

To make the coding of these gates easier, a functionality of short-hand gates is provided. The gates can be applied to the register as follows:-

*** example.qc ***
### example.qc ###

func test {
Pa()
[X, X]
[Z, Y]
gate MyOwnGate[2] {
[H, H]
[X, Z]
[Y, X]
}

quReg a = init(2)
a.name = "quReg1: "
a.prec = 6
func test {
[X, X] Pa()
[Z, Y] Pa()
[H, H] Pa()
[X, Z] Pa()
[Y, X] Pa()
[MyOwnGate]
}

#### Initialize ####
quReg a = new quReg[2] => 'myqureg1'
a.setPrecision(6)

#### Simulate ####
a.Pnz()
a.test()
a.Pnz()

Expand All @@ -48,48 +52,84 @@ OUTPUT:

./quacc example.qc

quReg2 =
[0] => {1.000000 + 0.000000 i} |00> 100.00 %
[1] => {0.000000 + 0.000000 i} |01> 0.00 %
[2] => {0.000000 + 0.000000 i} |10> 0.00 %
[3] => {0.000000 + 0.000000 i} |11> 0.00 %
[+] Parsing Successful...!!!

Executing program...
myqureg1 =
[0] => {1.000000 + 0.000000 i} |00> 100.000000 %


myqureg1 =
[0] => {0.000000 + 0.000000 i} |00> 0.000000 %
[1] => {0.000000 + 0.000000 i} |01> 0.000000 %
[2] => {0.000000 + 0.000000 i} |10> 0.000000 %
[3] => {1.000000 + 0.000000 i} |11> 100.000000 %


myqureg1 =
[0] => {0.000000 + 0.000000 i} |00> 0.000000 %
[1] => {-0.000000 + 1.000000 i} |01> 100.000000 %
[2] => {-0.000000 + 0.000000 i} |10> 0.000000 %
[3] => {0.000000 + 0.000000 i} |11> 0.000000 %

quReg2 =
[0] => {-0.000000 - 0.500000 i} |00> 25.00 %
[1] => {-0.000000 + 0.500000 i} |01> 25.00 %
[2] => {-0.000000 - 0.500000 i} |10> 25.00 %
[3] => {-0.000000 + 0.500000 i} |11> 25.00 %

myqureg1 =
[0] => {0.000000 + 0.500000 i} |00> 25.000000 %
[1] => {0.000000 - 0.500000 i} |01> 25.000000 %
[2] => {0.000000 + 0.500000 i} |10> 25.000000 %
[3] => {0.000000 - 0.500000 i} |11> 25.000000 %


myqureg1 =
[0] => {0.000000 - 0.500000 i} |00> 25.000000 %
[1] => {0.000000 + 0.500000 i} |01> 25.000000 %
[2] => {-0.000000 + 0.500000 i} |10> 25.000000 %
[3] => {-0.000000 - 0.500000 i} |11> 25.000000 %


myqureg1 =
[0] => {-0.500000 + 0.000000 i} |00> 25.000000 %
[1] => {-0.500000 + 0.000000 i} |01> 25.000000 %
[2] => {0.500000 + 0.000000 i} |10> 25.000000 %
[3] => {0.500000 + 0.000000 i} |11> 25.000000 %


myqureg1 =
[2] => {-1.000000 + 0.000000 i} |10> 100.000000 %


Time taken: 0 min, 0.000124 sec


The above code segment has the following meaning:-
- Initialize a new quRegister.
- Display text for the quRegister is "quReg1: ".
- Pa() -> Print all possible combinations of 'n' qubits in the quRegister.
- Display text for the quRegister is "quReg1".
- Pnz() -> Print only non-zero magnitude values of the 2 qubit quRegister.
- Pauli gate 'X' is applied to [qubit[0], qubit[1]] respectively.
- Print all states in the quRegister.
- Pauli gate 'Z' is applied to qubit[0] and 'Y' to qubit[1] respectively, and so on.
- Pnz() -> Print only non-zero magnitude values.

## List of short-hand gates
- Hadamard Gate: **H**
- Phase Gate: **S**
- Rotation Gate: **R(x)**
- Rotation Gate: **R_k**

x: Angle value (in degrees)(Int/Float)
- CNOT Gate:
- Control gate: **Co**
- NOT gate: **Cx**
k: power of n'th root of unity (w)
- Control gate: **@**
- Inverse Control gate: **o**
- NOOP Gate: **-**
- Pauli Gates
- Pauli X gate: **X**
- Pauli Y gate: **Y**
- Pauli Z gate: **Z**
- Swap Gate: **Sx**
- Quantum Fourier Transform (QFT) Gate: **Q**
- Inverse QFT Gate: **Qi**
- Swap Gate: **x**
- Quantum Fourier Transform (QFT) Gate: **~**


*For more info, see the examples: https://github.com/AbeerVaishnav13/qua-C/tree/master/Examples*
**For more info, see the examples:** *https://github.com/AbeerVaishnav13/qua-C/tree/master/Examples*

*\*Currently, the language supports registers upto 28-qubits with 8GB of memory.*
**Currently, the language supports registers upto 29-qubits with 8GB of memory.**

## Installation Instructions

Expand All @@ -104,7 +144,7 @@ The dependencies for QuaC language is the **gcc** compiler and **cmake**.

sudo brew install gcc cmake

(iii) For Windows platform - install MINGW GCC for windows or even better, install any Linux distribution of your choice :)
(iii) For Windows platform - install MINGW GCC for windows or even better, install any Linux distribution of your choice :)


### Install the compiler
Expand Down

0 comments on commit e7d3118

Please sign in to comment.