q-optimize/c3

View on GitHub
examples/Parametermap.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Parameter handling\n",
    "The tool within $C^3$ to manipulate the parameters of both the model and controls is the `ParameterMap`. It provides methods to present the same data for human interaction, i.e. structured information with physical units and for numerical optimization algorithms that prefer a linear vector of scale 1. Here, we'll show some example usage.\n",
    "We'll use the `ParameterMap` of the model also used in the simulated calibration example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from single_qubit_blackbox_exp import create_experiment\n",
    "\n",
    "exp = create_experiment()\n",
    "pmap = exp.pmap"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The pmap contains a list of all parameters and their values:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Q1-freq': 5.000 GHz 2pi,\n",
       " 'Q1-anhar': -210.000 MHz 2pi,\n",
       " 'Q1-temp': 0.000 K,\n",
       " 'init_ground-init_temp': -3.469 aK,\n",
       " 'resp-rise_time': 300.000 ps,\n",
       " 'v_to_hz-V_to_Hz': 1.000 GHz/V,\n",
       " 'id[0]-d1-no_drive-amp': 1.000 V,\n",
       " 'id[0]-d1-no_drive-delta': 0.000 V,\n",
       " 'id[0]-d1-no_drive-freq_offset': 0.000 Hz 2pi,\n",
       " 'id[0]-d1-no_drive-xy_angle': 0.000 rad,\n",
       " 'id[0]-d1-no_drive-sigma': 5.000 ns,\n",
       " 'id[0]-d1-no_drive-t_final': 7.000 ns,\n",
       " 'id[0]-d1-carrier-freq': 5.050 GHz 2pi,\n",
       " 'id[0]-d1-carrier-framechange': 5.933 rad,\n",
       " 'rx90p[0]-d1-gauss-amp': 450.000 mV,\n",
       " 'rx90p[0]-d1-gauss-delta': -1.000 ,\n",
       " 'rx90p[0]-d1-gauss-freq_offset': -50.500 MHz 2pi,\n",
       " 'rx90p[0]-d1-gauss-xy_angle': -444.089 arad,\n",
       " 'rx90p[0]-d1-gauss-sigma': 1.750 ns,\n",
       " 'rx90p[0]-d1-gauss-t_final': 7.000 ns,\n",
       " 'rx90p[0]-d1-carrier-freq': 5.050 GHz 2pi,\n",
       " 'rx90p[0]-d1-carrier-framechange': 0.000 rad,\n",
       " 'ry90p[0]-d1-gauss-amp': 450.000 mV,\n",
       " 'ry90p[0]-d1-gauss-delta': -1.000 ,\n",
       " 'ry90p[0]-d1-gauss-freq_offset': -50.500 MHz 2pi,\n",
       " 'ry90p[0]-d1-gauss-xy_angle': 1.571 rad,\n",
       " 'ry90p[0]-d1-gauss-sigma': 1.750 ns,\n",
       " 'ry90p[0]-d1-gauss-t_final': 7.000 ns,\n",
       " 'ry90p[0]-d1-carrier-freq': 5.050 GHz 2pi,\n",
       " 'ry90p[0]-d1-carrier-framechange': 0.000 rad,\n",
       " 'rx90m[0]-d1-gauss-amp': 450.000 mV,\n",
       " 'rx90m[0]-d1-gauss-delta': -1.000 ,\n",
       " 'rx90m[0]-d1-gauss-freq_offset': -50.500 MHz 2pi,\n",
       " 'rx90m[0]-d1-gauss-xy_angle': 3.142 rad,\n",
       " 'rx90m[0]-d1-gauss-sigma': 1.750 ns,\n",
       " 'rx90m[0]-d1-gauss-t_final': 7.000 ns,\n",
       " 'rx90m[0]-d1-carrier-freq': 5.050 GHz 2pi,\n",
       " 'rx90m[0]-d1-carrier-framechange': 0.000 rad,\n",
       " 'ry90m[0]-d1-gauss-amp': 450.000 mV,\n",
       " 'ry90m[0]-d1-gauss-delta': -1.000 ,\n",
       " 'ry90m[0]-d1-gauss-freq_offset': -50.500 MHz 2pi,\n",
       " 'ry90m[0]-d1-gauss-xy_angle': 4.712 rad,\n",
       " 'ry90m[0]-d1-gauss-sigma': 1.750 ns,\n",
       " 'ry90m[0]-d1-gauss-t_final': 7.000 ns,\n",
       " 'ry90m[0]-d1-carrier-freq': 5.050 GHz 2pi,\n",
       " 'ry90m[0]-d1-carrier-framechange': 0.000 rad}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_full_params()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To access a specific parameter, e.g. the frequency of qubit 1, we use the identifying tuple `('Q1','freq')`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.000 GHz 2pi"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_parameter(('Q1','freq'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The opt_map\n",
    "To deal with multiple parameters we use the `opt_map`, a nested list of identifyers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "opt_map = [\n",
    "    [\n",
    "        (\"Q1\", \"freq\")\n",
    "    ],\n",
    "    [\n",
    "        (\"Q1\", \"anhar\")\n",
    "    ],  \n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, we get a list of the parameter values:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5.000 GHz 2pi, -210.000 MHz 2pi]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_parameters(opt_map)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's look at the amplitude values of two gaussian control pulses, rotations about the $X$ and $Y$ axes repsectively."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "opt_map = [\n",
    "    [\n",
    "        ('rx90p[0]','d1','gauss','amp')\n",
    "    ],\n",
    "    [\n",
    "        ('ry90p[0]','d1','gauss','amp')\n",
    "    ],  \n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[450.000 mV, 450.000 mV]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_parameters(opt_map)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can set the parameters to new values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "pmap.set_parameters([0.5, 0.6], opt_map)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[500.000 mV, 600.000 mV]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_parameters(opt_map)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The opt_map also allows us to specify that two parameters should have identical values. Here, let's demand our $X$ and $Y$ rotations use the same amplitude."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "opt_map_ident = [\n",
    "    [\n",
    "        ('rx90p[0]','d1','gauss','amp'),\n",
    "        ('ry90p[0]','d1','gauss','amp')\n",
    "    ],\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The grouping here means that these parameters share their numerical value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[432.000 mV]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.set_parameters([0.432], opt_map_ident)\n",
    "pmap.get_parameters(opt_map_ident)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[432.000 mV, 432.000 mV]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_parameters(opt_map)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "During an optimization, the varied parameters do not change, so we fix the opt_map"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "pmap.set_opt_map(opt_map)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[432.000 mV, 432.000 mV]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_parameters()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Optimizer scaling\n",
    "To be independent of the choice of numerical optimizer, they should use the methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.68, -0.68])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_parameters_scaled()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To provide values bound to $[-1, 1]$. Let's set the parameters to their allowed minimum an maximum value with"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "pmap.set_parameters_scaled([1.0,-1.0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[600.000 mV, 400.000 mV]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_parameters()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As a safeguard, when setting values outside of the unit range, their physical values get looped back in the specified limits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "pmap.set_parameters_scaled([2.0, 3.0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[500.000 mV, 400.000 mV]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pmap.get_parameters()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Storing and reading\n",
    "For optimization purposes, we can store and load parameter values in [HJSON](https://hjson.github.io/) format."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "pmap.store_values(\"current_vals.c3log\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "  opt_map:\r\n",
      "  [\r\n",
      "    [\r\n",
      "      rx90p[0]-d1-gauss-amp\r\n",
      "    ]\r\n",
      "    [\r\n",
      "      ry90p[0]-d1-gauss-amp\r\n",
      "    ]\r\n",
      "  ]\r\n",
      "  units:\r\n",
      "  [\r\n",
      "    V\r\n",
      "    V\r\n",
      "  ]\r\n",
      "  optim_status:\r\n",
      "  {\r\n",
      "    params:\r\n",
      "    [\r\n",
      "      0.5\r\n",
      "      0.4000000059604645\r\n",
      "    ]\r\n",
      "  }\r\n",
      "}\r\n"
     ]
    }
   ],
   "source": [
    "!cat current_vals.c3log"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "pmap.load_values(\"current_vals.c3log\")"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "8fc56ae400e717d872a76f4d6b257151d16696a9d0a72e6998d355f9b43887c7"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}