Skip to content
This repository has been archived by the owner on Sep 13, 2019. It is now read-only.

Add print circuit method #59

Merged
merged 1 commit into from
May 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### 🎉 Added

- `@qiskit/qiskit-sim`: Add print circuit method

## [0.8.0] - 2019-04-25

### 🎉 Added
Expand Down
90 changes: 90 additions & 0 deletions packages/qiskit-sim/lib/Circuit.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,13 @@ class Circuit {
id,
name: (gate instanceof Gate) ? gate.name : gate.toLowerCase(),
connector,
multiQubit: numConnectors > 1,
};
}
return this;
}


createTransform(U, qubits) {
const dimension = this.numAmplitudes();
this.initTransform(dimension);
Expand Down Expand Up @@ -362,6 +364,94 @@ class Circuit {
return s;
}

print(writable = process.stdout) {
const columnLen = 10;
const spaceLen = 4;
const gateLen = 4;

const connectionsMap = new Map();
for (let column = 0; column < this.gates[0].length; column += 1) {
for (let wire = 0; wire < this.nQubits; wire += 1) {
const gate = this.gates[wire][column];
if (gate && gate.multiQubit) {
const m = connectionsMap.has(column) ? connectionsMap.get(column) :
new Map();
let entry;
if (m.has(gate.id)) {
entry = m.get(gate.id);
entry.to = wire;
} else {
entry = {from: wire,
fromVisited: false,
to: null,
toVisited: false};
}
m.set(gate.id, entry);
connectionsMap.set(column, m);
}
}
}

let columnHeader = ''.padStart(columnLen);
for (let i = 0; i < this.numCols(); i += 1) {
columnHeader += `column ${i}`.padEnd(columnLen, ' ');
columnHeader += ''.padEnd(spaceLen, ' ');
}
writable.write('\n');
writable.write(columnHeader);
writable.write('\n');

for (let wire = 0; wire < this.nQubits; wire += 1) {
writable.write(`wire ${wire} `.padEnd(columnLen, '-'));
let wireOutput = '';
let connOutput = ''.padStart(columnLen, ' ');
for (let column = 0; column < this.gates[wire].length; column += 1) {
const gate = this.getGateAt(column, wire);
const connections = connectionsMap.get(column);
if (connections) {
if (gate && connections.has(gate.id)) {
const c = connections.get(gate.id);
if (c.from === wire) {
c.fromVisited = true;
}
if (c.to === wire) {
c.toVisited = true;
}

if (c.fromVisited === true && c.toVisited === true) {
connections.delete(gate.id);
if (connections.size === 0) {
connectionsMap.delete(column);
}
} else {
connOutput += ` |`;
}
} else {
connOutput += ` |`;
}
}

if (gate) {
if (gate.multiQubit && gate.connector !== 0) {
wireOutput += `[*]`.padEnd(gateLen, '-');
} else {
wireOutput += `[${gate.name}]`.padEnd(gateLen, '-');
connOutput += ''.padEnd(gateLen, ' ');
}
} else {
wireOutput += ''.padEnd(gateLen, '-');
connOutput += ''.padEnd(gateLen, ' ');
}
wireOutput += ''.padEnd(columnLen, '-');
connOutput += ''.padEnd(columnLen, ' ');
}
writable.write(wireOutput);
writable.write('\n');
writable.write(connOutput);
writable.write('\n');
}
}

static createCircuit(qubits) {
if (typeof qubits !== 'number')
throw new TypeError('The "qubits" argument must be of type number. ' +
Expand Down
72 changes: 72 additions & 0 deletions packages/qiskit-sim/test/functional/Circuit.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
'use strict';

const assert = require('assert');
const { Writable } = require('stream');

const { Circuit, Gate } = require('../..');

Expand Down Expand Up @@ -150,3 +151,74 @@ describe('sim:Circuit:createCircuit', () => {
});
});
});

describe('sim:Circuit:print', () => {
let result = '';
const writable = new Writable({
write(chunk, encoding, callback) {
result += chunk.toString();
callback();
}
});

function stripWhitespace(str) {
return str.replace(/\s+/g, '');
}

afterEach( () => { result = ''; } )

it('should print circuit with single hadamard gate', () => {
const expected = `
column 0
wire 0 ---[h]-----------`;

Circuit.createCircuit(1).addGate(Gate.h, 0, 0).print(writable);
assert.strictEqual(stripWhitespace(result), stripWhitespace(expected));
});

it('should print circuit with multiple gates', () => {
const expected = `
column 0
wire 0 ---[h]-----------

wire 1 ---[h]-----------`;

Circuit.createCircuit(2).addGate(Gate.h, 0, 0)
.addGate(Gate.h, 0, 1)
.print(writable);
assert.strictEqual(stripWhitespace(result), stripWhitespace(expected));
});

it('should print circuit with connections', () => {
const expected = `
column 0 column 1
wire 0 ---[x]-----------[cx]----------
|
wire 1 -----------------[*]-----------`;
// Note that the star in this case represents the target qubit
// and the control qubit will be qubit 0.

Circuit.createCircuit(2).addGate(Gate.x, 0, 0)
.addGate(Gate.cx, 1, [0, 1])
.print(writable);
assert.strictEqual(stripWhitespace(result), stripWhitespace(expected));
});

it('should print circuit with connections over mutiple wires', () => {
const expected = `
column 0 column 1
wire 0 ---[x]-----------[cx]----------
|
wire 1 -------------------------------
|
wire 2 -----------------[*]-----------

wire 3 -------------------------------`;

Circuit.createCircuit(4).addGate(Gate.x, 0, 0)
.addGate(Gate.cx, 1, [0, 2])
.print(writable);
assert.strictEqual(stripWhitespace(result), stripWhitespace(expected));
});

});