Skip to content

Commit

Permalink
Add gate-info for menu gates
Browse files Browse the repository at this point in the history
  • Loading branch information
juanrein committed Jul 31, 2023
1 parent b4d8014 commit 00df636
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 116 deletions.
118 changes: 118 additions & 0 deletions timApp/static/scripts/tim/plugin/quantumcircuit/active-gate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import {format} from "mathjs";
import type {FormatOptions, Matrix} from "mathjs";
import type {Qubit} from "tim/plugin/quantumcircuit/qubit";

/**
* Content to show in table cell as rounded and longer version
*/
export interface TableCellData {
rounded: string;
long: string;
}

/**
* Information about gate.
*/
export class ActiveGateInfo {
name: string;
description: string;
matrix: Matrix;
/**
* @param name the name of gate
* @param description more detailed info about gate than its name
* @param mat actual matrix presentation of the gate
*/
constructor(name: string, description: string, mat: Matrix) {
this.name = name;
this.description = description;
this.matrix = mat;
}

/**
* Formats the matrix into an array with elements as strings
* to be used in html table.
*/
formatMatrixAsTable() {
const arr = this.matrix.toArray();
const formatOptions: FormatOptions = {
precision: 2,
};
const res: TableCellData[][] = [];
arr.forEach((row) => {
if (Array.isArray(row)) {
const rowValues = row.map((v) => ({
rounded: format(v, formatOptions).replace(/\s/g, ""),
long: format(v).replace(/\s/g, ""),
}));
res.push(rowValues);
}
});
return res;
}
}

/**
* Information about gate that is placed on board.
*/
export class CircuitActiveGateInfo extends ActiveGateInfo {
target: number;
time: number;
controls: number[];
qubits: Qubit[];
editable: boolean;
swap?: [number, number];

/**
* @param target the index of qubit related to this gate
* @param time the time moment related to this gate
* @param name the name of gate
* @param mat actual matrix presentation of the gate
* @param controls indices of qubits that control this gate if any or just an empty array
* @param qubits qubit objects used to get names of qubits
* @param description more detailed info about gate than its name
* @param swap pair of qubit indices for swap gate
* @param editable whether this gate can be edited or not
*/
constructor(
target: number,
time: number,
name: string,
mat: Matrix,
controls: number[],
qubits: Qubit[],
description: string,
editable: boolean,
swap?: [number, number]
) {
super(name, description, mat);
this.target = target;
this.time = time;
this.qubits = qubits;
this.controls = controls;
this.editable = editable;
this.swap = swap;
}

formatControlsAsString() {
return this.controls.map((ci) => this.qubits[ci].name).join(", ");
}

formatSwapAsString() {
if (!this.swap) {
return "";
}
return (
this.qubits[this.swap[0]].name +
", " +
this.qubits[this.swap[1]].name
);
}

formatTimeAsString() {
return this.time.toString();
}

formatQubitAsString() {
return this.qubits[this.target].name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ import {
withDefault,
} from "tim/plugin/attributes";
import {QuantumGateMenuComponent} from "tim/plugin/quantumcircuit/quantum-gate-menu.component";
import {
ActiveGateInfo,
QuantumToolboxComponent,
} from "tim/plugin/quantumcircuit/quantum-toolbox.component";
import {QuantumToolboxComponent} from "tim/plugin/quantumcircuit/quantum-toolbox.component";
import type {
GateDrop,
GateMove,
Expand Down Expand Up @@ -51,6 +48,10 @@ import {DomSanitizer} from "@angular/platform-browser";
import {SvgCellComponent} from "tim/plugin/quantumcircuit/svg-cell.component";
import {PurifyModule} from "tim/util/purify.module";
import {Qubit} from "tim/plugin/quantumcircuit/qubit";
import {
ActiveGateInfo,
CircuitActiveGateInfo,
} from "tim/plugin/quantumcircuit/active-gate";

export interface QubitOutput {
value: number;
Expand Down Expand Up @@ -187,13 +188,6 @@ export interface CircuitStyleOptions {
gateBorderRadius: number;
}

/**
* Content to show in table cell as rounded and longer version
*/
export interface TableCellData {
rounded: string;
long: string;
}
@Component({
selector: "tim-quantum-circuit",
template: `
Expand All @@ -205,7 +199,10 @@ export interface TableCellData {
<ng-container body>
<div #qcContainer class="circuit-container" (window:resize)="handleResize()">
<div class="top-menu">
<tim-quantum-gate-menu [circuitStyleOptions]="circuitStyleOptions"></tim-quantum-gate-menu>
<tim-quantum-gate-menu
[circuitStyleOptions]="circuitStyleOptions"
(select)="handleMenuGateSelect($event)">
</tim-quantum-gate-menu>
<tim-quantum-toolbox [activeGateInfo]="activeGateInfo" (close)="handleActiveGateHide()"></tim-quantum-toolbox>
</div>
Expand Down Expand Up @@ -650,7 +647,7 @@ export class QuantumCircuitComponent
const editable =
this.board.get(gate.target, gate.time)?.editable === true;

this.activeGateInfo = new ActiveGateInfo(
this.activeGateInfo = new CircuitActiveGateInfo(
gate.target,
gate.time,
name,
Expand All @@ -667,6 +664,17 @@ export class QuantumCircuitComponent
this.activeGateInfo = undefined;
}

handleMenuGateSelect(gateName: string) {
const gateInfo = this.gateService.getGate(gateName);
if (gateInfo) {
this.activeGateInfo = new ActiveGateInfo(
gateInfo.name,
gateInfo.description,
gateInfo.matrix
);
}
}

/**
* Marks gate as selected.
* @param gate position of gate on board
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {OnDestroy, OnInit} from "@angular/core";
import {Component, Input} from "@angular/core";
import {Component, EventEmitter, Input, Output} from "@angular/core";
import type {Color} from "tim/plugin/quantumcircuit/quantum-circuit.component";
import {CircuitStyleOptions} from "tim/plugin/quantumcircuit/quantum-circuit.component";
import type {ServiceGate} from "tim/plugin/quantumcircuit/gate.service";
Expand All @@ -25,6 +25,7 @@ interface MenuGate {
[title]="gate.description"
[style.width.px]="circuitStyleOptions.gateSize"
[style.height.px]="circuitStyleOptions.gateSize"
(click)="handleClick(gate.name)"
(dragstart)="handleDragStart($event, gate.name)">
<div [ngSwitch]="gate.name">
<svg *ngSwitchCase="'control'"
Expand Down Expand Up @@ -84,6 +85,9 @@ export class QuantumGateMenuComponent implements OnInit, OnDestroy {
@Input()
circuitStyleOptions!: CircuitStyleOptions;

@Output()
select = new EventEmitter<string>();

constructor(private gateService: GateService) {}

ngOnInit(): void {
Expand Down Expand Up @@ -123,4 +127,8 @@ export class QuantumGateMenuComponent implements OnInit, OnDestroy {
ngOnDestroy(): void {
this.subscription.unsubscribe();
}

handleClick(name: string) {
this.select.emit(name);
}
}
Original file line number Diff line number Diff line change
@@ -1,99 +1,10 @@
import type {OnChanges, OnInit, SimpleChanges} from "@angular/core";
import {Component, EventEmitter, Input, Output} from "@angular/core";
import type {TableCellData} from "tim/plugin/quantumcircuit/quantum-circuit.component";
import type {FormatOptions, Matrix} from "mathjs";
import {format} from "mathjs";
import type {Qubit} from "tim/plugin/quantumcircuit/qubit";

export class ActiveGateInfo {
matrix: Matrix;
name: string;
target: number;
time: number;
controls: number[];
qubits: Qubit[];
description: string;
editable: boolean;
swap?: [number, number];

/**
* @param target the index of qubit related to this gate
* @param time the time moment related to this gate
* @param name the name of gate
* @param mat actual matrix presentation of the gate
* @param controls indices of qubits that control this gate if any or just an empty array
* @param qubits qubit objects used to get names of qubits
* @param description more detailed info about gate than its name
* @param swap pair of qubit indices for swap gate
* @param editable whether this gate can be edited or not
*/
constructor(
target: number,
time: number,
name: string,
mat: Matrix,
controls: number[],
qubits: Qubit[],
description: string,
editable: boolean,
swap?: [number, number]
) {
this.target = target;
this.time = time;
this.name = name;
this.matrix = mat;
this.qubits = qubits;
this.controls = controls;
this.description = description;
this.editable = editable;
this.swap = swap;
}

/**
* Formats the matrix into an array with elements as strings
* to be used in html table.
*/
formatMatrixAsTable() {
const arr = this.matrix.toArray();
const formatOptions: FormatOptions = {
precision: 2,
};
const res: TableCellData[][] = [];
arr.forEach((row) => {
if (Array.isArray(row)) {
const rowValues = row.map((v) => ({
rounded: format(v, formatOptions).replace(/\s/g, ""),
long: format(v).replace(/\s/g, ""),
}));
res.push(rowValues);
}
});
return res;
}

formatControlsAsString() {
return this.controls.map((ci) => this.qubits[ci].name).join(", ");
}

formatSwapAsString() {
if (!this.swap) {
return "";
}
return (
this.qubits[this.swap[0]].name +
", " +
this.qubits[this.swap[1]].name
);
}

formatTimeAsString() {
return this.time.toString();
}

formatQubitAsString() {
return this.qubits[this.target].name;
}
}
import type {TableCellData} from "tim/plugin/quantumcircuit/active-gate";
import {
CircuitActiveGateInfo,
ActiveGateInfo,
} from "tim/plugin/quantumcircuit/active-gate";

@Component({
selector: "tim-quantum-toolbox",
Expand All @@ -102,10 +13,11 @@ export class ActiveGateInfo {
<div class="gate-info" *ngIf="activeGateInfo">
<div class="gate-info-header">
<div>{{activeGateInfo.description}}</div>
<div *ngIf="!activeGateInfo.editable" class="text-info gate-editable-message">
<div *ngIf="showEditableInfo" class="text-info gate-editable-message">
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
Tätä porttia ei pysty muokkaamaan
</div>
<button title="piilota" type="button" class="btn btn-default btn-sm" (click)="handleClose()">
<span class="glyphicon glyphicon-remove"></span>
</button>
Expand All @@ -119,14 +31,14 @@ export class ActiveGateInfo {
</tr>
</tbody>
</table>
<p>Qubitti: {{qubitString}}</p>
<p>Aika: {{timeString}}</p>
<p *ngIf="qubitString">Qubitti: {{qubitString}}</p>
<p *ngIf="timeString">Aika: {{timeString}}</p>
<p *ngIf="controlsString" class="controls">
Kontrollit:
{{controlsString}}
</p>
<p *ngIf="activeGateInfo.swap">
<p *ngIf="swapString">
Swap:
{{swapString}}
</p>
Expand All @@ -152,6 +64,8 @@ export class QuantumToolboxComponent implements OnInit, OnChanges {
qubitString: string = "";
timeString: string = "";

showEditableInfo: boolean = false;

@Output()
close = new EventEmitter<void>();

Expand All @@ -164,11 +78,14 @@ export class QuantumToolboxComponent implements OnInit, OnChanges {
return;
}
this.matrixTable = this.activeGateInfo.formatMatrixAsTable();
this.controlsString = this.activeGateInfo.formatControlsAsString();
this.swapString = this.activeGateInfo.formatSwapAsString();
if (this.activeGateInfo instanceof CircuitActiveGateInfo) {
this.controlsString = this.activeGateInfo.formatControlsAsString();
this.swapString = this.activeGateInfo.formatSwapAsString();

this.qubitString = this.activeGateInfo.formatQubitAsString();
this.timeString = this.activeGateInfo.formatTimeAsString();
this.qubitString = this.activeGateInfo.formatQubitAsString();
this.timeString = this.activeGateInfo.formatTimeAsString();
this.showEditableInfo = !this.activeGateInfo.editable;
}
}

handleClose() {
Expand Down

0 comments on commit 00df636

Please sign in to comment.