@@ -5471,6 +5471,7 @@ QuantumCircuit.prototype.registerGate = function(name, obj) {
54715471 connectors . push ( rootGate . drawingInfo . connectors [ rootGate . drawingInfo . connectors . length - 1 ] ) ;
54725472
54735473 this . customGates [ name ] . drawingInfo . connectors = connectors ;
5474+ this . customGates [ name ] . drawingInfo . root = rootGate . drawingInfo . root ;
54745475 }
54755476 }
54765477} ;
@@ -5479,12 +5480,80 @@ QuantumCircuit.prototype.registerGate = function(name, obj) {
54795480QuantumCircuit . prototype . registerMCXGate = function ( ctrlQubits ) {
54805481 var gateName = this . multiControlledGateName ( "mcx" , ctrlQubits ) ;
54815482 this . registerGate ( gateName , this . MCXCircuit ( ctrlQubits ) . save ( true ) ) ;
5483+ return gateName ;
54825484} ;
54835485
54845486
54855487QuantumCircuit . prototype . registerMCU1Gate = function ( ctrlQubits ) {
54865488 var gateName = this . multiControlledGateName ( "mcu1" , ctrlQubits ) ;
54875489 this . registerGate ( gateName , this . MCU1Circuit ( ctrlQubits ) . save ( true ) ) ;
5490+ return gateName ;
5491+ } ;
5492+
5493+
5494+ QuantumCircuit . prototype . registerMultiControlledGate = function ( rootName , ctrlQubits ) {
5495+ switch ( rootName ) {
5496+ case "cx" : return this . registerMCXGate ( ctrlQubits ) ; break ;
5497+ case "cu1" : return this . registerMCU1Gate ( ctrlQubits ) ; break ;
5498+ }
5499+
5500+ return "" ;
5501+ } ;
5502+
5503+ QuantumCircuit . prototype . getOrRegisterMultiControlledEquivalent = function ( gateName , inverseControl ) {
5504+ var gateDef = this . basicGates [ gateName ] ;
5505+ if ( gateDef ) {
5506+ if ( gateDef . drawingInfo ) {
5507+ // Basic gate with multi-controlled/inverse controlled implementation
5508+ if ( gateName == "x" || gateName == "u1" || gateDef . drawingInfo . root == "x" || gateDef . drawingInfo . root == "u1" ) {
5509+ if ( ! this . basicGates [ "c" + gateName ] || inverseControl ) {
5510+ // create multi controlled version and return its name
5511+ var rootName = "c" + ( gateDef . drawingInfo . root || gateName ) ;
5512+ var numCtrlQubits = math . log2 ( gateDef . matrix . length ) ;
5513+ var ctrlQubits = [ ] ;
5514+ for ( var i = 0 ; i < numCtrlQubits - 1 ; i ++ ) {
5515+ ctrlQubits . push ( true ) ;
5516+ }
5517+ ctrlQubits . unshift ( ! inverseControl ) ;
5518+
5519+ return this . registerMultiControlledGate ( rootName , ctrlQubits ) ;
5520+ } else {
5521+ // there is basic gate with additional control
5522+ return "c" + gateName ;
5523+ }
5524+ }
5525+ }
5526+
5527+ // Basic gate for which we don't have multi-controlled or inverse controlled implementation
5528+ // but maybe we have basic gate with additional control
5529+ for ( var gn in this . basicGates ) {
5530+ var tmpGateDef = this . basicGates [ gn ] ;
5531+ if ( tmpGateDef && tmpGateDef . drawingInfo && tmpGateDef . drawingInfo . root && tmpGateDef . drawingInfo . root == gateName ) {
5532+ if ( ! inverseControl ) {
5533+ // there is basic gate with additional control
5534+ return gn ;
5535+ }
5536+ }
5537+ }
5538+ return null ;
5539+ }
5540+
5541+ if ( this . customGates [ gateName ] ) {
5542+ var mcInfo = this . decodeMultiControlledGateName ( gateName ) ;
5543+ if ( ! mcInfo || ! mcInfo . numCtrlQubits ) {
5544+ return null ;
5545+ }
5546+
5547+ if ( mcInfo . rootName == "cx" || mcInfo . rootName == "cu1" ) {
5548+ // create multi controlled version and return its name
5549+ mcInfo . ctrlQubits . unshift ( ! inverseControl ) ;
5550+ return this . registerMultiControlledGate ( mcInfo . rootName , mcInfo . ctrlQubits ) ;
5551+ }
5552+
5553+ return null ;
5554+ }
5555+
5556+ return null ;
54885557} ;
54895558
54905559
@@ -5561,17 +5630,21 @@ QuantumCircuit.prototype.multiControlledGateName = function(namePrefix, ctrlQubi
55615630 return gateName ;
55625631} ;
55635632
5633+
55645634QuantumCircuit . prototype . isMultiControlledGate = function ( gateName ) {
55655635 var mcInfo = this . decodeMultiControlledGateName ( gateName ) ;
55665636 return ! ! this . customGates [ gateName ] && ! ! mcInfo && ! ! mcInfo . numCtrlQubits ;
55675637} ;
55685638
5569- QuantumCircuit . prototype . isControllableGate = function ( gateName ) {
5570- if ( gateName == "cx" ) {
5571- return true ;
5572- }
55735639
5574- if ( this . basicGates [ gateName ] ) {
5640+ QuantumCircuit . prototype . isControllableGate = function ( gateName ) {
5641+ var gateDef = this . basicGates [ gateName ] ;
5642+ if ( gateDef ) {
5643+ if ( gateDef . drawingInfo ) {
5644+ if ( gateDef . drawingInfo . root == "x" || gateDef . drawingInfo . root == "u1" ) {
5645+ return true ;
5646+ }
5647+ }
55755648 for ( var gn in this . basicGates ) {
55765649 var gateDef = this . basicGates [ gn ] ;
55775650 if ( gateDef && gateDef . drawingInfo && gateDef . drawingInfo . root && gateDef . drawingInfo . root == gateName ) {
@@ -5580,8 +5653,7 @@ QuantumCircuit.prototype.isControllableGate = function(gateName) {
55805653 }
55815654 }
55825655
5583- // return this.isMultiControlledGate(gateName);
5584- return false ;
5656+ return this . isMultiControlledGate ( gateName ) ;
55855657} ;
55865658
55875659QuantumCircuit . prototype . getGatePosById = function ( gateId ) {
@@ -7428,14 +7500,13 @@ QuantumCircuit.prototype.exportToSVG = function(options) {
74287500 gateList . push ( { name : "dot" , svg : dotsvg } ) ;
74297501 }
74307502
7431- /*
74327503 // special item: inverted dot
74337504 var ndotsvg = "" ;
74347505 if ( ! options . embedded ) {
74357506 ndotsvg += "<?xml version=\"1.0\"?>" ;
74367507 ndotsvg += "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" ;
74377508 }
7438- ndotsvg += "<svg class=\"qc-gate-gallery-item\" data-gate=\"dot \" data-content=\"Control\" width=\"" + options.cellWidth + "\" height=\"" + options.cellHeight + "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">";
7509+ ndotsvg += "<svg class=\"qc-gate-gallery-item\" data-gate=\"ndot \" data-content=\"Control\" width=\"" + options . cellWidth + "\" height=\"" + options . cellHeight + "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">" ;
74397510 ndotsvg = ndotsvg + gateSVG ( 0 , 0 , "ndot" , "ndot" , "ndot" , ! ! options . gateGallery , false ) ;
74407511 ndotsvg += "</svg>" ;
74417512
@@ -7444,10 +7515,8 @@ QuantumCircuit.prototype.exportToSVG = function(options) {
74447515 } else {
74457516 gateList . push ( { name : "dot" , svg : ndotsvg } ) ;
74467517 }
7447- */
74487518 }
74497519
7450-
74517520 // custom gates
74527521 if ( options . customGateGallery ) {
74537522 for ( var gateName in this . customGates ) {
0 commit comments