@masabando/quantum-gates 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,788 @@
1
+ 'use strict';
2
+
3
+ // src/Complex/index.ts
4
+ var Complex = class _Complex {
5
+ constructor(realPart, imaginaryPart) {
6
+ this.realPart = realPart;
7
+ this.imaginaryPart = imaginaryPart;
8
+ }
9
+ add(other) {
10
+ return new _Complex(
11
+ this.realPart + other.realPart,
12
+ this.imaginaryPart + other.imaginaryPart
13
+ );
14
+ }
15
+ multiply(other) {
16
+ return new _Complex(
17
+ this.realPart * other.realPart - this.imaginaryPart * other.imaginaryPart,
18
+ this.realPart * other.imaginaryPart + this.imaginaryPart * other.realPart
19
+ );
20
+ }
21
+ scale(scalar) {
22
+ return new _Complex(this.realPart * scalar, this.imaginaryPart * scalar);
23
+ }
24
+ toString(digits) {
25
+ if (digits !== void 0) {
26
+ return `${this.realPart.toFixed(digits)} + ${this.imaginaryPart.toFixed(digits)}i`;
27
+ } else {
28
+ return `${this.realPart} + ${this.imaginaryPart}i`;
29
+ }
30
+ }
31
+ magnitude() {
32
+ return Math.sqrt(this.realPart ** 2 + this.imaginaryPart ** 2);
33
+ }
34
+ conjugate() {
35
+ return new _Complex(this.realPart, -this.imaginaryPart);
36
+ }
37
+ };
38
+
39
+ // src/QMatrix/index.ts
40
+ var QMatrix = class _QMatrix {
41
+ constructor(matrix) {
42
+ this.matrix = matrix.map(
43
+ (row) => row.map(
44
+ (value) => value instanceof Complex ? value : new Complex(value, 0)
45
+ )
46
+ );
47
+ }
48
+ get rows() {
49
+ return this.matrix.length;
50
+ }
51
+ get cols() {
52
+ return this.matrix[0].length;
53
+ }
54
+ add(other) {
55
+ if (this.rows !== other.rows || this.cols !== other.cols) {
56
+ throw new Error("Matrices must have the same dimensions for addition");
57
+ }
58
+ const result = this.matrix.map(
59
+ (row, i) => row.map((value, j) => value.add(other.matrix[i][j]))
60
+ );
61
+ return new _QMatrix(result);
62
+ }
63
+ multiply(other) {
64
+ if (this.cols !== other.rows) {
65
+ throw new Error("Incompatible matrix sizes for multiplication");
66
+ }
67
+ const result = Array.from(
68
+ { length: this.rows },
69
+ () => Array.from({ length: other.cols }, () => new Complex(0, 0))
70
+ );
71
+ for (let i = 0; i < this.rows; i++) {
72
+ for (let j = 0; j < other.cols; j++) {
73
+ for (let k = 0; k < this.cols; k++) {
74
+ result[i][j] = result[i][j].add(this.matrix[i][k].multiply(other.matrix[k][j]));
75
+ }
76
+ }
77
+ }
78
+ return new _QMatrix(result);
79
+ }
80
+ toString(digits) {
81
+ return this.matrix.map((row) => row.map((value) => value.toString(digits)).join(" ")).join("\n");
82
+ }
83
+ scale(scalar) {
84
+ const scalarComplex = scalar instanceof Complex ? scalar : new Complex(scalar, 0);
85
+ const result = this.matrix.map(
86
+ (row) => row.map((value) => value.multiply(scalarComplex))
87
+ );
88
+ return new _QMatrix(result);
89
+ }
90
+ conjugate() {
91
+ const result = this.matrix.map(
92
+ (row) => row.map((value) => value.conjugate())
93
+ );
94
+ return new _QMatrix(result);
95
+ }
96
+ transpose() {
97
+ const result = Array.from(
98
+ { length: this.cols },
99
+ () => Array.from({ length: this.rows }, () => new Complex(0, 0))
100
+ );
101
+ for (let i = 0; i < this.rows; i++) {
102
+ for (let j = 0; j < this.cols; j++) {
103
+ result[j][i] = this.matrix[i][j];
104
+ }
105
+ }
106
+ return new _QMatrix(result);
107
+ }
108
+ dagger() {
109
+ return this.conjugate().transpose();
110
+ }
111
+ trace() {
112
+ let trace = new Complex(0, 0);
113
+ for (let i = 0; i < Math.min(this.rows, this.cols); i++) {
114
+ trace = trace.add(this.matrix[i][i]);
115
+ }
116
+ return trace;
117
+ }
118
+ };
119
+
120
+ // src/Constant/index.ts
121
+ var Constant = class {
122
+ //static readonly NOT_GATE = new QGate(Math.PI, [1, 0, 0]);
123
+ };
124
+ Constant.PI = Math.PI;
125
+ Constant.E = Math.E;
126
+ // identity matrix for 2x2
127
+ Constant.IDENTITY_2x2 = new QMatrix([
128
+ [1, 0],
129
+ [0, 1]
130
+ ]);
131
+ // identity matrix for 3x3
132
+ Constant.IDENTITY_3x3 = new QMatrix([
133
+ [1, 0, 0],
134
+ [0, 1, 0],
135
+ [0, 0, 1]
136
+ ]);
137
+ // identity matrix for 4x4
138
+ Constant.IDENTITY_4x4 = new QMatrix([
139
+ [1, 0, 0, 0],
140
+ [0, 1, 0, 0],
141
+ [0, 0, 1, 0],
142
+ [0, 0, 0, 1]
143
+ ]);
144
+ Constant.identity = (dim) => {
145
+ return new QMatrix(
146
+ Array.from(
147
+ { length: dim },
148
+ (_, i) => Array.from({ length: dim }, (_2, j) => i === j ? 1 : 0)
149
+ )
150
+ );
151
+ };
152
+ Constant.zero = (dim) => {
153
+ return new QMatrix(
154
+ Array.from(
155
+ { length: dim },
156
+ () => Array.from({ length: dim }, () => 0)
157
+ )
158
+ );
159
+ };
160
+ // zero matrix for 2x2
161
+ Constant.ZERO_2x2 = new QMatrix([
162
+ [0, 0],
163
+ [0, 0]
164
+ ]);
165
+ // zero matrix for 3x3
166
+ Constant.ZERO_3x3 = new QMatrix([
167
+ [0, 0, 0],
168
+ [0, 0, 0],
169
+ [0, 0, 0]
170
+ ]);
171
+ // zero matrix for 4x4
172
+ Constant.ZERO_4x4 = new QMatrix([
173
+ [0, 0, 0, 0],
174
+ [0, 0, 0, 0],
175
+ [0, 0, 0, 0],
176
+ [0, 0, 0, 0]
177
+ ]);
178
+ // common complex numbers
179
+ Constant.COMPLEX_I = new Complex(0, 1);
180
+ Constant.COMPLEX_ONE = new Complex(1, 0);
181
+ Constant.COMPLEX_ZERO = new Complex(0, 0);
182
+ // pauli matrices
183
+ Constant.PAULI_X = new QMatrix([
184
+ [0, 1],
185
+ [1, 0]
186
+ ]);
187
+ Constant.PAULI_Y = new QMatrix([
188
+ [new Complex(0, 0), new Complex(0, -1)],
189
+ [new Complex(0, 1), new Complex(0, 0)]
190
+ ]);
191
+ Constant.PAULI_Z = new QMatrix([
192
+ [1, 0],
193
+ [0, -1]
194
+ ]);
195
+
196
+ // src/QState/index.ts
197
+ var QState = class _QState {
198
+ constructor(vector, column = true) {
199
+ this.column = true;
200
+ this.column = column;
201
+ this.vector = vector.map(
202
+ (value) => value instanceof Complex ? value : new Complex(value, 0)
203
+ );
204
+ }
205
+ toString(digit) {
206
+ return `[${this.vector.map((value) => value.toString(digit)).join(this.column ? "\n" : ", ")}]`;
207
+ }
208
+ scale(scalar) {
209
+ const factor = scalar instanceof Complex ? scalar : new Complex(scalar, 0);
210
+ const scaledVector = this.vector.map((value) => value.multiply(factor));
211
+ return new _QState(scaledVector, this.column);
212
+ }
213
+ magnitude() {
214
+ let sum = 0;
215
+ for (const value of this.vector) {
216
+ sum += value.magnitude() ** 2;
217
+ }
218
+ return Math.sqrt(sum);
219
+ }
220
+ normalize() {
221
+ const mag = this.magnitude();
222
+ if (mag === 0) {
223
+ throw new Error("Cannot normalize a zero vector");
224
+ }
225
+ return this.scale(1 / mag);
226
+ }
227
+ transpose() {
228
+ return new _QState(this.vector, !this.column);
229
+ }
230
+ conjugate() {
231
+ const conjugatedVector = this.vector.map((value) => value.conjugate());
232
+ return new _QState(conjugatedVector, this.column);
233
+ }
234
+ dagger() {
235
+ return this.conjugate().transpose();
236
+ }
237
+ get isColumn() {
238
+ return this.column;
239
+ }
240
+ get values() {
241
+ return this.vector;
242
+ }
243
+ applyMatrix(matrix) {
244
+ if (this.column) {
245
+ throw new Error("Matrix application is only defined for row vectors");
246
+ }
247
+ if (matrix.cols !== this.vector.length) {
248
+ throw new Error("Incompatible sizes for matrix application");
249
+ }
250
+ const result = Array.from({ length: matrix.rows }, () => new Complex(0, 0));
251
+ for (let i = 0; i < matrix.rows; i++) {
252
+ for (let j = 0; j < matrix.cols; j++) {
253
+ result[i] = result[i].add(matrix.matrix[j][i].multiply(this.vector[j]));
254
+ }
255
+ }
256
+ return new _QState(result, false);
257
+ }
258
+ // <v1|v2>
259
+ applyState(state) {
260
+ if (this.column || !state.column) {
261
+ throw new Error("Incompatible sizes for state application");
262
+ }
263
+ if (this.vector.length !== state.vector.length) {
264
+ throw new Error("State vectors must be of the same length for application");
265
+ }
266
+ let result = new Complex(0, 0);
267
+ for (let i = 0; i < this.vector.length; i++) {
268
+ result = result.add(this.vector[i].multiply(state.vector[i]));
269
+ }
270
+ return result;
271
+ }
272
+ get xyz() {
273
+ if (!this.column) {
274
+ throw new Error("State vector must be a column vector to compute xyz coordinates");
275
+ }
276
+ const dagger = this.dagger();
277
+ const x = dagger.applyMatrix(Constant.PAULI_X).applyState(this).realPart;
278
+ const y = dagger.applyMatrix(Constant.PAULI_Y).applyState(this).realPart;
279
+ const z = dagger.applyMatrix(Constant.PAULI_Z).applyState(this).realPart;
280
+ return { x, y, z };
281
+ }
282
+ };
283
+
284
+ // src/QGate/index.ts
285
+ var QGate = class _QGate {
286
+ constructor(theta = 0, n = [1, 0, 0]) {
287
+ const [nx, ny, nz] = n;
288
+ const magnitude = Math.sqrt(nx * nx + ny * ny + nz * nz);
289
+ if (magnitude === 0) {
290
+ throw new Error("Rotation axis vector cannot be zero");
291
+ }
292
+ const [ux, uy, uz] = [nx / magnitude, ny / magnitude, nz / magnitude];
293
+ const cos = Math.cos(theta / 2);
294
+ const sin = -Math.sin(theta / 2);
295
+ const realPart = Constant.IDENTITY_2x2.scale(new Complex(cos, 0));
296
+ const imaginaryPartX = Constant.PAULI_X.scale(new Complex(0, ux * sin));
297
+ const imaginaryPartY = Constant.PAULI_Y.scale(new Complex(0, uy * sin));
298
+ const imaginaryPartZ = Constant.PAULI_Z.scale(new Complex(0, uz * sin));
299
+ this.matrix = realPart.add(imaginaryPartX).add(imaginaryPartY).add(imaginaryPartZ);
300
+ }
301
+ setMatrix(matrix) {
302
+ this.matrix = matrix;
303
+ return this;
304
+ }
305
+ dagger() {
306
+ const m = this.matrix.dagger();
307
+ const gate = new _QGate(0, [1, 0, 0]);
308
+ gate.setMatrix(m);
309
+ return gate;
310
+ }
311
+ conjugate() {
312
+ const m = this.matrix.conjugate();
313
+ const gate = new _QGate(0, [1, 0, 0]);
314
+ gate.setMatrix(m);
315
+ return gate;
316
+ }
317
+ transpose() {
318
+ const m = this.matrix.transpose();
319
+ const gate = new _QGate(0, [1, 0, 0]);
320
+ gate.setMatrix(m);
321
+ return gate;
322
+ }
323
+ apply(stateVector) {
324
+ const resultVector = new Array(this.matrix.rows).fill(new Complex(0, 0));
325
+ for (let i = 0; i < this.matrix.rows; i++) {
326
+ for (let j = 0; j < this.matrix.cols; j++) {
327
+ resultVector[i] = resultVector[i].add(
328
+ this.matrix.matrix[i][j].multiply(stateVector.vector[j])
329
+ );
330
+ }
331
+ }
332
+ return new QState(resultVector);
333
+ }
334
+ multiply(other) {
335
+ const m = this.matrix.multiply(other.matrix);
336
+ const gate = new _QGate(0, [1, 0, 0]);
337
+ gate.setMatrix(m);
338
+ return gate;
339
+ }
340
+ trace() {
341
+ return this.matrix.trace();
342
+ }
343
+ fidelity(ideal) {
344
+ const dim = this.matrix.rows;
345
+ const product = this.matrix.dagger().multiply(ideal.matrix);
346
+ const trace = product.trace();
347
+ const fidelity = trace.magnitude() / dim;
348
+ return fidelity;
349
+ }
350
+ };
351
+
352
+ // src/CPList/index.ts
353
+ var CPList = {
354
+ plain: {
355
+ name: "plain",
356
+ pulse: [
357
+ {
358
+ theta: (_theta, _phi) => _theta,
359
+ phi: (_theta, _phi) => _phi
360
+ }
361
+ ]
362
+ },
363
+ BB1: {
364
+ name: "BB1",
365
+ robustType: "ple",
366
+ rep: "ore",
367
+ pulse: [
368
+ {
369
+ canReduce: true,
370
+ theta: (_theta, _phi) => Math.PI,
371
+ phi: (_theta, _phi) => _phi + Math.acos(-_theta / (4 * Math.PI))
372
+ },
373
+ {
374
+ canReduce: true,
375
+ theta: (_theta, _phi) => 2 * Math.PI,
376
+ phi: (_theta, _phi) => 3 * (_phi + Math.acos(-_theta / (4 * Math.PI))) - 2 * _phi
377
+ },
378
+ {
379
+ canReduce: true,
380
+ theta: (_theta, _phi) => Math.PI,
381
+ phi: (_theta, _phi) => _phi + Math.acos(-_theta / (4 * Math.PI))
382
+ },
383
+ {
384
+ theta: (_theta, _phi) => _theta,
385
+ phi: (_theta, _phi) => _phi
386
+ }
387
+ ]
388
+ },
389
+ SK1: {
390
+ name: "SK1",
391
+ robustType: "ple",
392
+ rep: "ore",
393
+ pulse: [
394
+ {
395
+ theta: (_theta, _phi) => _theta,
396
+ phi: (_theta, _phi) => _phi
397
+ },
398
+ {
399
+ canReduce: true,
400
+ theta: (_theta, _phi) => 2 * Math.PI,
401
+ phi: (_theta, _phi) => _phi - Math.acos(-_theta / (4 * Math.PI))
402
+ },
403
+ {
404
+ canReduce: true,
405
+ theta: (_theta, _phi) => 2 * Math.PI,
406
+ phi: (_theta, _phi) => _phi + Math.acos(-_theta / (4 * Math.PI))
407
+ }
408
+ ]
409
+ },
410
+ CORPSE: {
411
+ name: "CORPSE",
412
+ robustType: "ore",
413
+ rep: "ple",
414
+ pulse: [
415
+ {
416
+ theta: (_theta, _phi) => 2 * Math.PI + _theta / 2 - Math.asin(Math.sin(_theta / 2) / 2),
417
+ phi: (_theta, _phi) => _phi
418
+ },
419
+ {
420
+ theta: (_theta, _phi) => 2 * Math.PI - 2 * Math.asin(Math.sin(_theta / 2) / 2),
421
+ phi: (_theta, _phi) => _phi + Math.PI
422
+ },
423
+ {
424
+ theta: (_theta, _phi) => _theta / 2 - Math.asin(Math.sin(_theta / 2) / 2),
425
+ phi: (_theta, _phi) => _phi
426
+ }
427
+ ]
428
+ },
429
+ shortCORPSE: {
430
+ name: "shortCORPSE",
431
+ robustType: "ore",
432
+ rep: false,
433
+ pulse: [
434
+ {
435
+ theta: (_theta, _phi) => _theta / 2 - Math.asin(Math.sin(_theta / 2) / 2),
436
+ phi: (_theta, _phi) => _phi
437
+ },
438
+ {
439
+ theta: (_theta, _phi) => 2 * Math.PI - 2 * Math.asin(Math.sin(_theta / 2) / 2),
440
+ phi: (_theta, _phi) => _phi + Math.PI
441
+ },
442
+ {
443
+ theta: (_theta, _phi) => _theta / 2 - Math.asin(Math.sin(_theta / 2) / 2),
444
+ phi: (_theta, _phi) => _phi
445
+ }
446
+ ]
447
+ }
448
+ };
449
+ function concatenate(pulseA, pulseB, reduced = false) {
450
+ return CPList[pulseB].pulse.map((pulseBElement) => {
451
+ if (reduced && pulseBElement.canReduce) {
452
+ return pulseBElement;
453
+ } else {
454
+ return CPList[pulseA].pulse.map((pulseAElement) => {
455
+ return {
456
+ theta: (_theta, _phi) => pulseAElement.theta(
457
+ pulseBElement.theta(_theta, _phi),
458
+ pulseBElement.phi(_theta, _phi)
459
+ ),
460
+ phi: (_theta, _phi) => pulseAElement.phi(
461
+ pulseBElement.theta(_theta, _phi),
462
+ pulseBElement.phi(_theta, _phi)
463
+ )
464
+ };
465
+ });
466
+ }
467
+ }).flat();
468
+ }
469
+ function createCCCP(pulseA, pulseB, reduced = false) {
470
+ return {
471
+ name: `${reduced ? "reduced " : ""}${pulseA}/${pulseB}`,
472
+ robustType: "both",
473
+ rep: false,
474
+ pulse: concatenate(pulseA, pulseB, reduced)
475
+ };
476
+ }
477
+ CPList["CORPSE/SK1"] = createCCCP("CORPSE", "SK1");
478
+ CPList["SK1/CORPSE"] = createCCCP("SK1", "CORPSE");
479
+ CPList["CORPSE/BB1"] = createCCCP("CORPSE", "BB1");
480
+ CPList["BB1/CORPSE"] = createCCCP("BB1", "CORPSE");
481
+ CPList["reduced CORPSE/SK1"] = createCCCP("CORPSE", "SK1", true);
482
+ CPList["reduced CORPSE/BB1"] = createCCCP("CORPSE", "BB1", true);
483
+ var CPList_default = CPList;
484
+
485
+ // src/QTool/index.ts
486
+ var QTool = class _QTool {
487
+ static evalGate(pulse, theta, phi, ple, ore) {
488
+ let gate = new QGate();
489
+ pulse.map((p) => {
490
+ const th = p.theta(theta, phi);
491
+ const ph = p.phi(theta, phi);
492
+ return new QGate(th * (1 + ple), [Math.cos(ph), Math.sin(ph), ore]);
493
+ }).reverse().forEach((g) => {
494
+ gate = gate.multiply(g);
495
+ });
496
+ return gate;
497
+ }
498
+ static createCanvas2D(targetId, { width = 400, height = 400 } = {}) {
499
+ const canvas = document.createElement("canvas");
500
+ canvas.width = width;
501
+ canvas.height = height;
502
+ const t = document.querySelector(`${targetId}`);
503
+ if (!t) {
504
+ throw new Error(`Target element with id "${targetId}" not found.`);
505
+ }
506
+ t.appendChild(canvas);
507
+ const ctx = canvas.getContext("2d");
508
+ const clearCanvas = () => {
509
+ ctx?.clearRect(0, 0, canvas.width, canvas.height);
510
+ };
511
+ return { canvas, ctx, clearCanvas };
512
+ }
513
+ static createErrorList(errorRange = {
514
+ ple: { min: -0.1, max: 0.1, step: 1e-3 },
515
+ ore: { min: -0.1, max: 0.1, step: 1e-3 }
516
+ }) {
517
+ const N = {
518
+ ple: Math.floor((errorRange.ple.max - errorRange.ple.min) / errorRange.ple.step) + 1,
519
+ ore: Math.floor((errorRange.ore.max - errorRange.ore.min) / errorRange.ore.step) + 1
520
+ };
521
+ const errorList = [];
522
+ for (let i = 0; i < N.ple; i++) {
523
+ const l = [];
524
+ for (let j = 0; j < N.ore; j++) {
525
+ l.push({
526
+ ple: errorRange.ple.min + i * errorRange.ple.step,
527
+ ore: errorRange.ore.min + j * errorRange.ore.step
528
+ });
529
+ }
530
+ errorList.push(l);
531
+ }
532
+ return errorList;
533
+ }
534
+ static calculateFidelity(gateName, theta, phi, error = {
535
+ ple: { min: -0.1, max: 0.1, step: 1e-3 },
536
+ ore: { min: -0.1, max: 0.1, step: 1e-3 }
537
+ }) {
538
+ const CompositeGate = CPList_default[gateName].pulse;
539
+ const plain = CPList_default.plain.pulse;
540
+ const idealGate = _QTool.evalGate(plain, theta, phi, 0, 0);
541
+ const errorList = _QTool.createErrorList(error);
542
+ const fidelityList = [];
543
+ errorList.forEach((row, pleIdx) => {
544
+ row.forEach((error2, oreIdx) => {
545
+ const { ple, ore } = error2;
546
+ const gate = _QTool.evalGate(CompositeGate, theta, phi, ple, ore);
547
+ fidelityList.push({
548
+ fidelity: gate.fidelity(idealGate),
549
+ pleIdx,
550
+ oreIdx
551
+ });
552
+ });
553
+ });
554
+ return { errorList, fidelityList };
555
+ }
556
+ static createFidelityMap({
557
+ target,
558
+ gateName,
559
+ theta,
560
+ phi,
561
+ width,
562
+ height,
563
+ threshold = 0.9999,
564
+ fillStyle = (val) => `rgb(${val}, ${val}, ${val})`,
565
+ overFill = 1,
566
+ error = {
567
+ ple: { min: -0.1, max: 0.1, step: 5e-3 },
568
+ ore: { min: -0.1, max: 0.1, step: 5e-3 }
569
+ }
570
+ }) {
571
+ const { errorList, fidelityList } = _QTool.calculateFidelity(gateName, theta, phi, error);
572
+ const pleMesh = height / errorList.length;
573
+ const oreMesh = width / errorList[0].length;
574
+ const { canvas, ctx, clearCanvas } = _QTool.createCanvas2D(target, { width, height });
575
+ clearCanvas();
576
+ if (ctx) {
577
+ fidelityList.forEach(({ fidelity, pleIdx, oreIdx }) => {
578
+ const colorValue = Math.floor((Math.max(fidelity, threshold) - threshold) / (1 - threshold) * 255);
579
+ ctx.fillStyle = fillStyle(colorValue);
580
+ ctx.fillRect(oreIdx * oreMesh - overFill / 2, pleIdx * pleMesh - overFill / 2, oreMesh + overFill, pleMesh + overFill);
581
+ });
582
+ }
583
+ }
584
+ static drawBloch(create, {
585
+ ringWeight = 0.01,
586
+ ringNum = { azimuthal: 7, polar: 8 },
587
+ color = {
588
+ sphere: 8947848,
589
+ ringMain: 5592575,
590
+ ringSub: 16777215
591
+ }
592
+ } = {}) {
593
+ create.group({
594
+ children: [
595
+ create.sphere({
596
+ option: {
597
+ transparent: true,
598
+ opacity: 0.5,
599
+ color: color.sphere
600
+ },
601
+ autoAdd: false
602
+ }),
603
+ create.group({
604
+ children: new Array(ringNum.polar).fill(0).map((_, i) => {
605
+ create.cylinder({
606
+ size: [1, 1, ringWeight],
607
+ segments: [128, 1],
608
+ rotation: [Math.PI / 2, 0, i * Math.PI / ringNum.polar],
609
+ openEnded: true,
610
+ option: {
611
+ side: 2,
612
+ color: i === 0 || i === ringNum.polar / 2 ? color.ringMain : color.ringSub
613
+ },
614
+ autoAdd: true
615
+ });
616
+ }),
617
+ autoAdd: false
618
+ }),
619
+ create.group({
620
+ children: new Array(ringNum.azimuthal).fill(0).map((_, i) => {
621
+ const theta = (i + 1) / (ringNum.azimuthal + 1) * Math.PI;
622
+ const r = Math.sin(theta);
623
+ create.cylinder({
624
+ size: [r, r, ringWeight],
625
+ segments: [128, 1],
626
+ position: [0, Math.cos(theta), 0],
627
+ openEnded: true,
628
+ option: {
629
+ side: 2,
630
+ color: ringNum.azimuthal % 2 !== 0 && i === ~~(ringNum.azimuthal / 2) ? color.ringMain : color.ringSub
631
+ },
632
+ autoAdd: true
633
+ });
634
+ }),
635
+ autoAdd: false
636
+ })
637
+ ]
638
+ });
639
+ }
640
+ static createAnimation({
641
+ init,
642
+ target,
643
+ pulseName,
644
+ angle,
645
+ phi,
646
+ initState,
647
+ speed,
648
+ light = {
649
+ ambient: { intensity: 0.4 },
650
+ directional: { intensity: 0.6, position: [-10, 10, -10] }
651
+ },
652
+ bloch = {
653
+ ringWeight: 0.01,
654
+ ringNum: { azimuthal: 7, polar: 8 },
655
+ color: {
656
+ sphere: 8947848,
657
+ ringMain: 5592575,
658
+ ringSub: 16777215
659
+ }
660
+ },
661
+ point = {
662
+ size: {
663
+ normal: 0.04,
664
+ errorP: 0.04,
665
+ errorN: 0.04
666
+ },
667
+ color: {
668
+ normal: 7829503,
669
+ errorP: 16742263,
670
+ errorN: 16755370
671
+ }
672
+ }
673
+ }) {
674
+ const pulses = CPList_default[pulseName].pulse.map((p) => ({
675
+ theta: p.theta(angle, phi),
676
+ phi: p.phi(angle, phi)
677
+ }));
678
+ let currentState = initState;
679
+ let eState = [
680
+ initState,
681
+ initState
682
+ ];
683
+ const { create, camera, controls, animate, helper } = init(target);
684
+ camera.position.set(0, 0, -2);
685
+ controls.connect();
686
+ create.ambientLight({ intensity: light.ambient.intensity });
687
+ const directionalLight = create.directionalLight({
688
+ intensity: light.directional.intensity,
689
+ position: light.directional.position
690
+ });
691
+ directionalLight.shadow.bias = -1e-4;
692
+ helper.axes({ size: 1 });
693
+ _QTool.drawBloch(create, {
694
+ ringWeight: bloch.ringWeight,
695
+ ringNum: bloch.ringNum,
696
+ color: bloch.color
697
+ });
698
+ const idealPoint = create.sphere({
699
+ size: point?.size?.normal ?? 0.04,
700
+ position: [0, 1, 0],
701
+ option: {
702
+ color: point?.color?.normal ?? 7829503
703
+ }
704
+ });
705
+ const errorPoint = [
706
+ create.sphere({
707
+ size: point?.size?.errorP ?? 0.04,
708
+ position: [0, 1, 0],
709
+ option: {
710
+ color: point?.color?.errorP ?? 16742263
711
+ }
712
+ }),
713
+ create.sphere({
714
+ size: point?.size?.errorN ?? 0.04,
715
+ position: [0, 1, 0],
716
+ option: {
717
+ color: point?.color?.errorN ?? 16755370
718
+ }
719
+ })
720
+ ];
721
+ let mode = 0;
722
+ let counter = 0;
723
+ const waitTime = [1, 2];
724
+ let currentTheta = 0;
725
+ let gateIndex = 0;
726
+ const ple = 0.05, ore = 0.05;
727
+ animate(({ delta }) => {
728
+ switch (mode) {
729
+ case 0:
730
+ counter += delta;
731
+ if (counter >= waitTime[0]) {
732
+ mode = 1;
733
+ counter = 0;
734
+ }
735
+ return;
736
+ case 1:
737
+ break;
738
+ case 2:
739
+ counter += delta;
740
+ if (counter >= waitTime[1]) {
741
+ mode = 0;
742
+ counter = 0;
743
+ currentState = initState;
744
+ }
745
+ return;
746
+ }
747
+ let dTheta = delta * speed;
748
+ let flag = false;
749
+ if (currentTheta + dTheta > pulses[gateIndex].theta) {
750
+ dTheta = pulses[gateIndex].theta - currentTheta;
751
+ flag = true;
752
+ }
753
+ const g = new QGate(dTheta, [Math.cos(pulses[gateIndex].phi), Math.sin(pulses[gateIndex].phi), 0]);
754
+ const eg = [
755
+ new QGate((1 + ple) * dTheta, [Math.cos(pulses[gateIndex].phi), Math.sin(pulses[gateIndex].phi), ore]),
756
+ new QGate((1 - ple) * dTheta, [Math.cos(pulses[gateIndex].phi), Math.sin(pulses[gateIndex].phi), -ore])
757
+ ];
758
+ currentState = g.apply(currentState);
759
+ eState = eState.map((st, i) => eg[i].apply(st));
760
+ const xyz = currentState.xyz;
761
+ const Exyz = eState.map((st) => st.xyz);
762
+ idealPoint.position.set(xyz.x, xyz.z, xyz.y);
763
+ errorPoint[0].position.set(Exyz[0].x, Exyz[0].z, Exyz[0].y);
764
+ errorPoint[1].position.set(Exyz[1].x, Exyz[1].z, Exyz[1].y);
765
+ currentTheta += dTheta;
766
+ if (flag) {
767
+ gateIndex++;
768
+ currentTheta = 0;
769
+ if (gateIndex >= pulses.length) {
770
+ gateIndex = 0;
771
+ currentState = initState;
772
+ eState = [initState, initState];
773
+ mode = 2;
774
+ }
775
+ }
776
+ });
777
+ }
778
+ };
779
+
780
+ exports.CPList = CPList_default;
781
+ exports.Complex = Complex;
782
+ exports.Constant = Constant;
783
+ exports.QGate = QGate;
784
+ exports.QMatrix = QMatrix;
785
+ exports.QState = QState;
786
+ exports.QTool = QTool;
787
+ //# sourceMappingURL=index.cjs.map
788
+ //# sourceMappingURL=index.cjs.map