Skip to content

Commit

Permalink
Adding multiple measurements to model, see #54
Browse files Browse the repository at this point in the history
  • Loading branch information
AgustinVallejo committed Jan 6, 2025
1 parent d9d7c2a commit 0fca8c1
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 23 deletions.
57 changes: 34 additions & 23 deletions js/bloch-sphere/model/BlochSphereModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
import Multilink from '../../../../axon/js/Multilink.js';
import NumberProperty from '../../../../axon/js/NumberProperty.js';
import Property from '../../../../axon/js/Property.js';
import dotRandom from '../../../../dot/js/dotRandom.js';
import Range from '../../../../dot/js/Range.js';
import TModel from '../../../../joist/js/TModel.js';
import { EmptySelfOptions } from '../../../../phet-core/js/optionize.js';
Expand All @@ -34,6 +33,7 @@ export default class BlochSphereModel implements TModel {

public readonly preparationBlochSphere: ComplexBlochSphere;
public readonly singleMeasurementBlochSphere: ComplexBlochSphere;
public readonly multiMeasurementBlochSpheres: ComplexBlochSphere[] = [];

// Coefficients of the state equation. They are derived from the Bloch Sphere representation on the multilink below.
// |psi> = upCoefficient |up> + downCoefficient * exp( i * phase * PI ) |down>
Expand Down Expand Up @@ -79,7 +79,13 @@ export default class BlochSphereModel implements TModel {
this.singleMeasurementBlochSphere = new ComplexBlochSphere( {
tandem: providedOptions.tandem.createTandem( 'singleMeasurementBlochSphere' )
} );
this.singleMeasurementBlochSphere.polarAngleProperty.value = Math.PI / 2;

const multiMeasurementTandem = providedOptions.tandem.createTandem( 'multiMeasurementBlochSpheres' );
_.times( 10, index => {
this.multiMeasurementBlochSpheres.push( new ComplexBlochSphere( {
tandem: multiMeasurementTandem.createTandem( `blochSphere${index}` )
} ) );
} );

this.upCoefficientProperty = new NumberProperty( 0, {
tandem: providedOptions.tandem.createTandem( 'upCoefficientProperty' ),
Expand Down Expand Up @@ -170,15 +176,26 @@ export default class BlochSphereModel implements TModel {
this.singleMeasurementBlochSphere.rotatingSpeedProperty.value = selectedScene === BlochSphereScene.PRECESSION ?
magneticFieldStrength :
0;
this.multiMeasurementBlochSpheres.forEach( blochSphere => {
blochSphere.rotatingSpeedProperty.value = selectedScene === BlochSphereScene.PRECESSION ?
magneticFieldStrength :
0;
} );
}
);

this.preparationBlochSphere.polarAngleProperty.link( polarAngle => {
this.singleMeasurementBlochSphere.polarAngleProperty.value = polarAngle;
this.multiMeasurementBlochSpheres.forEach( blochSphere => {
blochSphere.polarAngleProperty.value = polarAngle;
} );
} );

this.preparationBlochSphere.azimuthalAngleProperty.link( azimuthalAngle => {
this.singleMeasurementBlochSphere.azimuthalAngleProperty.value = azimuthalAngle;
this.multiMeasurementBlochSpheres.forEach( blochSphere => {
blochSphere.azimuthalAngleProperty.value = azimuthalAngle;
} );
} );

this.measurementBasisProperty.link( () => {
Expand All @@ -192,29 +209,13 @@ export default class BlochSphereModel implements TModel {
public observe(): void {
if ( this.readyToObserveProperty.value ) {

const measurementVector = StateDirection.directionToVector( this.measurementBasisProperty.value );
const stateVector = StateDirection.anglesToVector(
this.singleMeasurementBlochSphere.polarAngleProperty.value,
this.singleMeasurementBlochSphere.azimuthalAngleProperty.value
);

const dotProduct = measurementVector.dot( stateVector );

const isUp = ( dotRandom.nextDouble() * 2 - 1 ) < dotProduct;
if ( isUp ) {
this.upMeasurementCountProperty.value++;
this.singleMeasurementBlochSphere.setDirection(
this.measurementBasisProperty.value.polarAngle,
this.measurementBasisProperty.value.azimuthalAngle
);
if ( this.isSingleMeasurementModeProperty.value ) {
this.singleMeasurementBlochSphere.measure( this.measurementBasisProperty.value, this.upMeasurementCountProperty, this.downMeasurementCountProperty );
}
else {
this.downMeasurementCountProperty.value++;
const oppositeDirection = this.measurementBasisProperty.value.oppositeDirection;
this.singleMeasurementBlochSphere.setDirection(
oppositeDirection.polarAngle,
oppositeDirection.azimuthalAngle
);
this.multiMeasurementBlochSpheres.forEach( blochSphere => {
blochSphere.measure( this.measurementBasisProperty.value, this.upMeasurementCountProperty, this.downMeasurementCountProperty );
} );
}

// Update the measurement state.
Expand All @@ -233,6 +234,13 @@ export default class BlochSphereModel implements TModel {
this.preparationBlochSphere.polarAngleProperty.value,
this.preparationBlochSphere.azimuthalAngleProperty.value
);

this.multiMeasurementBlochSpheres.forEach( blochSphere => {
blochSphere.setDirection(
this.preparationBlochSphere.polarAngleProperty.value,
this.preparationBlochSphere.azimuthalAngleProperty.value
);
} );
}

/**
Expand Down Expand Up @@ -262,6 +270,9 @@ export default class BlochSphereModel implements TModel {
*/
public step( dt: number ): void {
this.singleMeasurementBlochSphere.step( dt );
this.multiMeasurementBlochSpheres.forEach( blochSphere => {
blochSphere.step( dt );
} );
}
}

Expand Down
36 changes: 36 additions & 0 deletions js/bloch-sphere/model/ComplexBlochSphere.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
*/

import NumberProperty from '../../../../axon/js/NumberProperty.js';
import dotRandom from '../../../../dot/js/dotRandom.js';
import Range from '../../../../dot/js/Range.js';
import Utils from '../../../../dot/js/Utils.js';
import optionize from '../../../../phet-core/js/optionize.js';
import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js';
import AbstractBlochSphere, { AbstractBlochSphereOptions } from '../../common/model/AbstractBlochSphere.js';
import quantumMeasurement from '../../quantumMeasurement.js';
import { MeasurementBasis } from './MeasurementBasis.js';
import { StateDirection } from './StateDirection.js';

type SelfOptions = {
initialRotationSpeed?: number;
Expand Down Expand Up @@ -56,6 +59,39 @@ export default class ComplexBlochSphere extends AbstractBlochSphere {
this.azimuthalAngleProperty.value = azimuthalAngle;
}

/**
* Given a measurement basis, measures along that axis and updates the counters accordingly.
* @param measurementBasis
* @param upCounterProperty
* @param downCounterProperty
*/
public measure( measurementBasis: MeasurementBasis, upCounterProperty: NumberProperty, downCounterProperty: NumberProperty ): void {
const measurementVector = StateDirection.directionToVector( measurementBasis );
const stateVector = StateDirection.anglesToVector(
this.polarAngleProperty.value,
this.azimuthalAngleProperty.value
);

const dotProduct = measurementVector.dot( stateVector );

const isUp = ( dotRandom.nextDouble() * 2 - 1 ) < dotProduct;
if ( isUp ) {
upCounterProperty.value++;
this.setDirection(
measurementBasis.polarAngle,
measurementBasis.azimuthalAngle
);
}
else {
downCounterProperty.value++;
const oppositeDirection = measurementBasis.oppositeDirection;
this.setDirection(
oppositeDirection.polarAngle,
oppositeDirection.azimuthalAngle
);
}
}

public override reset(): void {
super.reset();
}
Expand Down

0 comments on commit 0fca8c1

Please sign in to comment.