aboutsummaryrefslogtreecommitdiff
path: root/tester/main.c
blob: cc32de16981cb697f90c8ea167959ec5ae3892cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <stdio.h>

#include "core/gates.h"
#include "core/quantum_components.h"
#include "maths/complex.h"
#include "maths/matrix.h"
#include "maths/vector.h"
#include "psi.h"

int main(void)
{
	printf("psi %s\n", psi_version());

	struct PsiComplex a = psi_new_complex(1.0, 2.0);
	struct PsiComplex b = psi_new_complex(3.0, -1.0);

	struct PsiComplex sum = psi_add_complex(a, b);
	struct PsiComplex product = psi_mul_complex(a, b);

	printf("a       = %g + %gi\n", a.real, a.imaginary);
	printf("b       = %g + %gi\n", b.real, b.imaginary);
	printf("a + b   = %g + %gi\n", sum.real, sum.imaginary);
	printf("a * b   = %g + %gi\n", product.real, product.imaginary);
	printf("|a|     = %g\n", psi_abs_complex(a));

	struct PsiVector u = psi_column_vector(
		psi_new_complex(1.0, 0.0),
		psi_new_complex(2.0, 0.0),
		psi_new_complex(3.0, 0.0));
	struct PsiVector v = psi_column_vector(
		psi_new_complex(4.0, 0.0),
		psi_new_complex(5.0, 0.0),
		psi_new_complex(6.0, 0.0));

	struct PsiComplex dot = psi_dot_vector(u, v);
	struct PsiComplex norm = psi_norm_vector(u);

	printf("u . v   = %g + %gi\n", dot.real, dot.imaginary);
	printf("|u|     = %g + %gi\n", norm.real, norm.imaginary);

	psi_free_vector(&u);
	psi_free_vector(&v);

	struct PsiMatrix m = psi_matrix(2, 2,
		psi_new_complex(1.0, 0.0), psi_new_complex(2.0, 0.0),
		psi_new_complex(3.0, 0.0), psi_new_complex(4.0, 0.0));
	struct PsiMatrix mm = psi_dot_matrix(m, m);

	printf("m*m     = [%g %g; %g %g]\n",
		psi_get_matrix(mm, 0, 0).real, psi_get_matrix(mm, 0, 1).real,
		psi_get_matrix(mm, 1, 0).real, psi_get_matrix(mm, 1, 1).real);

	struct PsiVector x = psi_column_vector(
		psi_new_complex(1.0, 0.0),
		psi_new_complex(1.0, 0.0));
	struct PsiVector mx = psi_mul_vector_matrix(x, m);

	printf("m*x     = [%g, %g]\n", mx.data[0].real, mx.data[1].real);

	psi_free_vector(&x);
	psi_free_vector(&mx);
	psi_free_matrix(&m);
	psi_free_matrix(&mm);

	double inv_sqrt2 = 0.7071067811865475;
	struct PsiMatrix h = psi_matrix(2, 2,
		psi_new_complex(inv_sqrt2, 0.0), psi_new_complex(inv_sqrt2, 0.0),
		psi_new_complex(inv_sqrt2, 0.0), psi_new_complex(-inv_sqrt2, 0.0));
	struct PsiQuantumGate gate = psi_new_quantum_gate_from_matrix("H", h);

	struct PsiVector s0 = psi_new_state_0();
	struct PsiVector hs0 = psi_mul_vector_matrix(s0, gate.matrix);

	printf("gate    = %s (%zu qubit)\n", gate.name, gate.num_qubits);
	printf("H|0>    = [%g, %g]\n", hs0.data[0].real, hs0.data[1].real);

	psi_free_vector(&s0);
	psi_free_vector(&hs0);
	psi_free_quantum_gate(&gate);

	const char *names[] = { "q0", "q1" };
	struct PsiQuantumRegister reg = psi_new_quantum_register("bell", names, 2);

	struct PsiQuantumGate hadamard = psi_hadamard_gate();
	struct PsiQuantumGate cnot = psi_cnot_gate();

	size_t t0[] = { 0 };
	size_t t01[] = { 0, 1 };
	psi_apply_gate(&reg, hadamard, t0, 1);
	psi_apply_gate(&reg, cnot, t01, 2);

	printf("bell    = [%g, %g, %g, %g]\n",
		reg.state_vector.data[0].real, reg.state_vector.data[1].real,
		reg.state_vector.data[2].real, reg.state_vector.data[3].real);

	psi_free_quantum_gate(&hadamard);
	psi_free_quantum_gate(&cnot);
	psi_free_quantum_register(&reg);

	return 0;
}