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