{"id":17263300,"url":"https://github.com/yezhuoyang/nmrpulse","last_synced_at":"2025-03-26T10:41:33.572Z","repository":{"id":221902739,"uuid":"755723397","full_name":"yezhuoyang/NMRPulse","owner":"yezhuoyang","description":"Simulation of all NMR quantum gates and pulses","archived":false,"fork":false,"pushed_at":"2024-05-16T21:10:17.000Z","size":61690,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-31T11:50:19.864Z","etag":null,"topics":["nmr-spectroscopy","quantum-computing"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yezhuoyang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-10T22:16:38.000Z","updated_at":"2024-05-16T21:10:20.000Z","dependencies_parsed_at":"2024-02-10T23:27:05.324Z","dependency_job_id":"d50a7ac3-7f60-454a-9f8d-3924cd778432","html_url":"https://github.com/yezhuoyang/NMRPulse","commit_stats":null,"previous_names":["yezhuoyang/nmrpulse"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezhuoyang%2FNMRPulse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezhuoyang%2FNMRPulse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezhuoyang%2FNMRPulse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezhuoyang%2FNMRPulse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yezhuoyang","download_url":"https://codeload.github.com/yezhuoyang/NMRPulse/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245641288,"owners_count":20648636,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nmr-spectroscopy","quantum-computing"],"created_at":"2024-10-15T07:56:07.324Z","updated_at":"2025-03-26T10:41:33.550Z","avatar_url":"https://github.com/yezhuoyang.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NMRPulse\n\nSimulation of all NMR quantum gates and pulses.\nI want to highlight the following property of my simulator:\n\n\n__1. Close to reality simulation and visualization__\n\n   The proton spectrum and carbon spectrum are shown in real ppm scale.\n\n   \n__2. Handy interface and many examples__\n   \n   User can easily understand and call the interface for simulation.\n   Many examples are provided in example.py for users to learn and get familiar.\n\n   \n__3. Correctness guaranteed by testcases__\n   \n   All pulses sequence and evolution function has passed tests cases in test/ folder\n\n   \n__4. Print Spinsolve Pulse sequences for Pulse Debug__\n\n   User can print the real pulse sequence directly for further check and debug in Spinsolve machine\n   \n__4. Four lines of code for Dj algorithm and Grover algorithm__\n\n   User only need four lines of code to calculate the pulse level DJ algorithm and Grover algorithm\n\n\n\n\n# Example of Chloroform samples\n\n\n## Add a 45 degree pulse\n\n### Code\n\n```python\ndef pulse_length_change():\n    '''\n    Initialize the\n    '''\n    NMRsample = chloroform()\n    '''\n    Set the initial density matrix\n    '''\n    NMRsample.set_density(np.array([[0.4, 0, 0, 0],\n                                    [0, 0.4, 0, 0],\n                                    [0, 0, 0.1, 0],\n                                    [0, 0, 0, 0.1]], dtype=complex))\n    '''\n    Add a single pulse on proton.\n    '''\n    NMRsample.add_pulse(pulseSingle(0, 0.5 * pl90H, wH))\n    '''\n    Evolve the density matrix with all pulses\n    '''\n    NMRsample.evolve_all_pulse()\n    '''\n    Read the data signal in the time domain\n    '''\n    NMRsample.read_proton_time()\n    '''\n    Simulate what is shown on the screen\n    '''\n    NMRsample.show_proton_fid_real(maxtime=0.1, store=True, path=\"Figure/45pulsesFID.png\")\n    '''\n    Read the data signal in the frequency\n    '''\n    NMRsample.read_proton_spectrum()\n    '''\n    Simulate what is shown on the screen\n    '''\n    NMRsample.show_proton_spectrum_real(-5, 15, store=True,\n                                        path=\"Figure/45pulsespec.png\")\n```\n\n### Result of proton FID\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/45pulsesFID.png)\n\n### Result of proton spectrum\n\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/45pulsespec.png)\n\n\n\n\n\n## Proton pulse length calibration\n\n### Code\n\n```python\ndef pulse_length_calib_proton():\n    pulses_length_list = np.linspace(0, 1, 20)\n    integra_list = []\n    NMRsample = chloroform()\n    for pulse in pulses_length_list:\n        NMRsample.set_density(np.array([[0.5, 0, 0, 0],\n                                        [0, 0.3, 0, 0],\n                                        [0, 0, -0.3, 0],\n                                        [0, 0, 0, -0.5]], dtype=complex))\n        NMRsample.set_pulses([])\n        '''\n        The first 1/2 pi pulse is added to cancel \n        the sigmax in the measurement operator.\n        '''\n        NMRsample.add_pulse(pulseSingle(0, 0.5 * pl90H, wH))\n        '''\n        This is the actual varying Ix pulse we add in the pulse\n        length calibration \n        '''\n        NMRsample.add_pulse(pulseSingle(0, pulse * pl90H, wH))\n        NMRsample.evolve_all_pulse()\n        NMRsample.read_proton_time()\n        NMRsample.read_proton_spectrum(normalize=False)\n        integra_list.append(NMRsample.integral_proton_spectrum_real())\n\n    pulses_length_list = [2 * x * pl90H * 10 ** 6 for x in pulses_length_list]\n    plt.scatter(pulses_length_list, integra_list, label=\"Integral value of proton spectrum\")\n    plt.axvline(x=pl90H*10**6, color=\"red\", linestyle=\"--\", label=\"Measured 90-x pulse for proton\")\n    plt.xlabel(\"Pulse length Time/ microsecond\")\n    plt.ylabel(\"Integral value\")\n    plt.legend(fontsize=8)\n    plt.savefig(\"Figure/protoncalib.png\")\n    plt.show()\n```\n\n### Result of proton pulse length calibration\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/protoncalib.png)\n\n\n\n\n## Carbon pulse length calibration\n\n### Code\n\n```python\ndef pulse_length_calib_carbon():\n    pulses_length_list = np.linspace(0, 1, 20)\n    integra_list = []\n    NMRsample = chloroform()\n    for pulse in pulses_length_list:\n        NMRsample.set_density(np.array([[0.5, 0, 0, 0],\n                                        [0, 0.3, 0, 0],\n                                        [0, 0, -0.3, 0],\n                                        [0, 0, 0, -0.5]], dtype=complex))\n        NMRsample.set_pulses([])\n        '''\n        The first 1/2 pi pulse is added to cancel \n        the sigmax in the measurement operator.\n        '''\n        NMRsample.add_pulse(pulseSingle(0, 0.5 * pl90C, wC))\n        '''\n        This is the actual varying Ix pulse we add in the pulse\n        length calibration \n        '''\n        NMRsample.add_pulse(pulseSingle(0, pulse * pl90C, wC))\n        NMRsample.evolve_all_pulse()\n        NMRsample.read_carbon_time()\n        NMRsample.read_carbon_spectrum(normalize=False)\n        integra_list.append(NMRsample.integral_carbon_spectrum_real())\n\n    pulses_length_list = [2 * x * pl90C * 10 ** 6 for x in pulses_length_list]\n    plt.scatter(pulses_length_list, integra_list, label=\"Integral value of carbon spectrum\")\n    plt.axvline(x=pl90C*10**6, color=\"red\", linestyle=\"--\", label=\"Measured 90-x pulse for carbon\")\n    plt.xlabel(\"Pulse length Time/ microsecond\")\n    plt.ylabel(\"Integral value\")\n    plt.legend(fontsize=8)\n    plt.savefig(\"Figure/carboncalib.png\")\n    plt.show()\n```\n\n### Result of carbon pulse length calibration\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/carboncalib.png)\n\n\n\n\n\n\n## Exact CNOT gate matrix\n\n### Code\n\n```python\ndef exact_CNOT():\n    '''\n    Initialize the chloroform instance\n    '''\n    NMRsample = chloroform()\n    '''\n    Set the initial density matrix\n    '''\n    NMRsample.set_density(np.array([[0.5, 0, 0, 0],\n                                    [0, 0.3, 0, 0],\n                                    [0, 0, -0.3, 0],\n                                    [0, 0, 0, -0.5]], dtype=complex))\n    CNOTmatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]], dtype=complex)\n    '''\n    Directly evolve the density matrix by CNOT matrix\n    '''\n    NMRsample.evolve_density(CNOTmatrix)\n    '''\n    Read the data signal in the time domain\n    '''\n    NMRsample.read_proton_time()\n    NMRsample.read_carbon_time()\n    '''\n    Read the spectrum\n    '''\n    NMRsample.read_proton_spectrum()\n    NMRsample.read_carbon_spectrum()\n    '''\n    Simulate what is shown on the screen\n    '''\n    NMRsample.show_proton_spectrum_real(-5, 15, store=True,\n                                        path=\"Figure/CNOTExactproton.png\")\n\n    NMRsample.show_carbon_spectrum_real(74, 80, store=True,\n                                        path=\"Figure/CNOTExactcarbon.png\")\n```\n\n\n### Result of proton spectrum after CNOT\n\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/CNOTExactproton.png)\n\n### Result of carbon spectrum after CNOT\n\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/CNOTExactcarbon.png)\n\n\n\n## Approximate CNOT gate controlled by proton\n\n### Code\n\n```python\ndef approx_CNOT():\n    '''\n    Initialize the chloroform instance\n    '''\n    NMRsample = chloroform()\n    '''\n    Set the initial density matrix\n    '''\n    NMRsample.set_density(np.array([[0.5, 0, 0, 0],\n                                    [0, 0.3, 0, 0],\n                                    [0, 0, -0.3, 0],\n                                    [0, 0, 0, -0.5]], dtype=complex))\n\n    '''\n    Add approximate CNOT pulse sequence\n    (pi/2)Ix2---(2Iz1Iz2)---(pi/2)Iy2\n    Recall that channel 0 for +x, 1 for +y, 2 for -x, 3 for -y\n    '''\n    NMRsample.add_pulse(pulseSingle(0, 0.5 * pl90C, wC))\n    NMRsample.add_pulse(delayTime(0.5 / Jfreq))\n    NMRsample.add_pulse(pulseSingle(1, 0.5 * pl90C, wC))\n    '''\n    Evolve the density matrix with all pulses\n    '''\n    NMRsample.evolve_all_pulse()\n    '''\n    Print the unitary of all pulses:\n    '''\n    print(NMRsample.get_pulse_unitary())\n\n    '''\n    Read the data signal in the time domain\n    '''\n    NMRsample.read_proton_time()\n    NMRsample.read_carbon_time()\n    '''\n    Read the spectrum\n    '''\n    NMRsample.read_proton_spectrum()\n    NMRsample.read_carbon_spectrum()\n    '''\n    Simulate what is shown on the screen\n    '''\n    NMRsample.show_proton_spectrum_real(-5, 15, store=True,\n                                        path=\"Figure/CNOTapproxproton.png\")\n\n    NMRsample.show_carbon_spectrum_real(74, 80, store=True,\n                                        path=\"Figure/CNOTapproxcarbon.png\")\n```\n\n\n### Result of proton spectrum after approximate CNOT\n\n\n\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/CNOTapproxproton.png)\n\n### Result of carbon spectrum after approximate CNOT\n\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/CNOTapproxcarbon.png)\n\n\n\n\n\n## Exact CNOT gate controlled by proton\n\n### Code\n\n```python\ndef exact_CNOT_pulse_Hcontrol():\n    '''\n    Initialize the chloroform instance\n    '''\n    NMRsample = chloroform()\n    '''\n    Set the initial density matrix\n    '''\n    NMRsample.set_density(np.array([[0.5, 0, 0, 0],\n                                    [0, 0.3, 0, 0],\n                                    [0, 0, -0.3, 0],\n                                    [0, 0, 0, -0.5]], dtype=complex))\n\n    '''\n    Add pulse sequence for approximate h gate on carbon\n    '''\n    NMRsample.add_pulse(pulseSingle(1, 1 / 4 * pl90C, wC))\n    NMRsample.add_pulse(pulseSingle(0, 1 * pl90C, wC))\n    NMRsample.add_pulse(pulseSingle(3, 1 / 4 * pl90C, wC))\n\n    '''\n    Add pulse sequence for exact CZ gate\n    '''\n    NMRsample.add_pulse(pulseSingle(2, 1 / 2 * pl90H, wH))\n    NMRsample.add_pulse(pulseSingle(1, 1 / 2 * pl90H, wH))\n    NMRsample.add_pulse(pulseSingle(0, 1 / 2 * pl90H, wH))\n    NMRsample.add_pulse(pulseSingle(2, 1 / 2 * pl90C, wC))\n    NMRsample.add_pulse(pulseSingle(1, 1 / 2 * pl90C, wC))\n    NMRsample.add_pulse(pulseSingle(0, 1 / 2 * pl90C, wC))\n    NMRsample.add_pulse(delayTime((4 - 0.5) / Jfreq))\n\n    '''\n    Add pulse sequence for approximate h gate on carbon\n    '''\n\n    NMRsample.add_pulse(pulseSingle(1, 1 / 4 * pl90C, wC))\n    NMRsample.add_pulse(pulseSingle(0, 1 * pl90C, wC))\n    NMRsample.add_pulse(pulseSingle(3, 1 / 4 * pl90C, wC))\n\n    '''\n    Evolve the density matrix with all pulses\n    '''\n    NMRsample.evolve_all_pulse()\n    '''\n    Print the unitary of all pulses:\n    '''\n    print(NMRsample.get_pulse_unitary())\n\n    '''\n    Read the data signal in the time domain\n    '''\n    NMRsample.read_proton_time()\n    NMRsample.read_carbon_time()\n    '''\n    Read the spectrum\n    '''\n    NMRsample.read_proton_spectrum()\n    NMRsample.read_carbon_spectrum()\n    '''\n    Simulate what is shown on the screen\n    '''\n    NMRsample.show_proton_spectrum_real(-5, 15, store=True,\n                                        path=\"Figure/CNOTExactproton-Hcontrol.png\")\n\n    NMRsample.show_carbon_spectrum_real(74, 80, store=True,\n                                        path=\"Figure/CNOTExactcarbon-Hcontrol.png\")\n```\n\n\n### Result of proton spectrum after approximate CNOT\n\n\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/CNOTExactproton-Hcontrol.png)\n\n### Result of carbon spectrum after approximate CNOT\n\n![alt text](https://github.com/yezhuoyang/NMRPulse/blob/main/Figure/CNOTExactcarbon-Hcontrol.png)\n\n\n\n## Deutsch jozsa algorithm\n\n### Code\n\n\n```python\ndef permute_DJ(uf):\n    DJ = Djalgorithm()\n    DJ.set_function(uf)\n\n    DJ.construct_circuit()\n    DJ.calculate_result_circuit()\n\n    DJ.plot_measure_all()\n\n    '''\n    First, calculate the result without permutation\n    '''\n    DJ.construct_pulse()\n    DJ.calculate_result_pulse()\n\n    DJ.show_spectrum(\"Figure/DJP0f{}{}\".format(uf[0], uf[1]),\n                     title=\"Result of DJ algorithm after P0 for f{}{}\".format(uf[0], uf[1]))\n\n    density0 = DJ.get_final_density()\n\n    '''\n    Reinitialize the sample, add a P1 permutation:\n    '''\n    DJ.init_sample()\n    DJ.set_prem_value(1)\n\n    DJ.construct_pulse()\n    DJ.calculate_result_pulse()\n\n    DJ.show_spectrum(\"Figure/DJP1f{}{}\".format(uf[0], uf[1]),\n                     title=\"Result of DJ algorithm after P1 for f{}{}\".format(uf[0], uf[1]))\n\n    density1 = DJ.get_final_density()\n\n    '''\n    Reinitialize the sample, add a P2 permutation:\n    '''\n    DJ.init_sample()\n    DJ.set_prem_value(2)\n\n    DJ.construct_pulse()\n    DJ.calculate_result_pulse()\n\n    DJ.show_spectrum(\"Figure/DJP2f{}{}\".format(uf[0], uf[1]),\n                     title=\"Result of DJ algorithm after P2 for f{}{}\".format(uf[0], uf[1]))\n\n    density2 = DJ.get_final_density()\n\n    final_density = 1 / 3 * (density0 + density1 + density2)\n\n    pseudo_sample = chloroform()\n    pseudo_sample.set_density(final_density)\n\n    pseudo_sample.read_proton_time()\n    pseudo_sample.read_carbon_time()\n    '''\n    Read the spectrum\n    '''\n    pseudo_sample.read_proton_spectrum()\n    pseudo_sample.read_carbon_spectrum()\n    '''\n    Simulate what is shown on the screen\n    '''\n    pseudo_sample.show_proton_spectrum_real(-5, 15, store=True,\n                                            path=\"Figure/DJproton%d%d.png\" % (uf[0], uf[1]))\n\n    pseudo_sample.show_carbon_spectrum_real(74, 80, store=True,\n                                            path=\"Figure/DJcarbon%d%d.png\" % (uf[0], uf[1]))\n```\n\n\n\n\n\n\n## Grover's algorithm\n\n### Code\n\n\n```python\ndef permute_grover(db):\n    grover = Grover()\n    grover.set_function(db)\n\n    grover.construct_circuit()\n    grover.calculate_result_circuit()\n\n    '''\n    First, calculate the result without permutation\n    '''\n    grover.construct_pulse()\n    grover.calculate_result_pulse()\n\n    grover.show_spectrum(\"Figure/GroverP0f{}{}\".format(db[0], db[1]),\n                         title=\"Result of Grover algorithm after P0 for f{}{}\".format(db[0], db[1]))\n\n    density0 = grover.get_final_density()\n\n    '''\n    Reinitialize the sample, add a P1 permutation:\n    '''\n    grover.init_sample()\n    grover.set_prem_value(1)\n\n    grover.construct_pulse()\n    grover.calculate_result_pulse()\n\n    grover.show_spectrum(\"Figure/GroverP1f{}{}\".format(db[0], db[1]),\n                         title=\"Result of Grover algorithm after P1 for f{}{}\".format(db[0], db[1]))\n\n    density1 = grover.get_final_density()\n\n    '''\n    Reinitialize the sample, add a P2 permutation:\n    '''\n    grover.init_sample()\n    grover.set_prem_value(2)\n\n    grover.construct_pulse()\n    grover.calculate_result_pulse()\n\n    grover.show_spectrum(\"Figure/GroverP2f{}{}\".format(db[0], db[1]),\n                         title=\"Result of Grover algorithm after P2 for f{}{}\".format(db[0], db[1]))\n\n    density2 = grover.get_final_density()\n\n    final_density = 1 / 3 * (density0 + density1 + density2)\n\n    pseudo_sample = chloroform()\n    pseudo_sample.set_density(final_density)\n\n    pseudo_sample.read_proton_time()\n    pseudo_sample.read_carbon_time()\n    '''\n    Read the spectrum\n    '''\n    pseudo_sample.read_proton_spectrum()\n    pseudo_sample.read_carbon_spectrum()\n    '''\n    Simulate what is shown on the screen\n    '''\n    pseudo_sample.show_proton_spectrum_real(-5, 15, store=True,\n                                            path=\"Figure/Groverproton%d%d.png\" % (db[0], db[1]))\n\n    pseudo_sample.show_carbon_spectrum_real(74, 80, store=True,\n                                            path=\"Figure/Grovercarbon%d%d.png\" % (db[0], db[1]))\n```\n\n\n\n## Print pulse sequences:\n\n\n```python\ndef DJ_print_pulse(uf):\n    DJ = Djalgorithm()\n    '''\n    Initialize the input function\n    f1:uf=[0,0]\n    f2:uf=[0,1]\n    f3:uf=[1,0]\n    f4:uf=[1,1]\n    '''\n    DJ.set_function(uf)\n    DJ.construct_pulse()\n    '''\n    Print the real Spinsolve pulses\n    '''\n    DJ.print_pulses()\n\n\nif __name__ == \"__main__\":\n    DJ_print_pulse([0,0])\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezhuoyang%2Fnmrpulse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyezhuoyang%2Fnmrpulse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezhuoyang%2Fnmrpulse/lists"}