OpenJij/OpenJij

View on GitHub
docs/tutorial/en/physics/IntroductionCoreInterface.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction to OpenJij Core Interface"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This tutorial explains how to use OpenJij's core interface (core python interface).\n",
    "\n",
    "The core interface is a low-layer API than the previous tutorials.\n",
    "The readers are assumed to have gone through the previous OpenJij tutorials and to be familiar with terms such as Ising models and Monte Carlo methods.\n",
    "\n",
    "The purpose of the core interface are:\n",
    "\n",
    "* To use OpenJij for more specialized applications such as sampling and research applications as well as optimization problems.\n",
    "* To set up annealing schedules\n",
    "* To directly modify the algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## About the OpenJij Core Interface\n",
    "\n",
    "In the previous tutorials, we introduced how to solve various problems using OpenJij and how to benchmark it.\n",
    "OpenJij is implemented in C++ based on the Markov Chain Monte Carlo (MCMC) method, which is a numerical computation method in statistical physics.\n",
    "The Python modules mentioned so far call **openjij.cxxjij**, a python library that directly wraps this C++ interface.\n",
    "The diagram shows the following inclusions.\n",
    "\n",
    "![OpenJij hierarchy](../../../assets/core_interface_hierarchy.png)\n",
    "\n",
    "The OpenJij core interface allows you to use all the functionality on OpenJij. Thus, it can be used not only for optimization problems but also for research purposes as **a numerical tool for statistical physics**.\n",
    "The C++ interface allows for faster operations.\n",
    "\n",
    "This tutorial introduces openjij.cxxjij, a more user-friendly Python interface.\n",
    "pip is used for installation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Overview of OpenJij Core Interface\n",
    "\n",
    "First, to see how to use the OpenJij core interface, let us solve the classical spin ($\\sigma = \\pm 1$) Ising problem with variable size $N=5$ using simulated annealing.\n",
    "The Hamiltonian is as follows:\n",
    "\\begin{align*}\n",
    "H &= \\sum_{i<j}J_{ij}\\sigma_i \\sigma_j + \\sum_{i=1}^{N}h_i \\sigma_i \\\\\n",
    "\\sigma_i &= \\pm 1 (i=1 \\cdots N)\n",
    "\\end{align*}\n",
    "\n",
    "We set the longitudinal magnetic field and the interaction to be:\n",
    "\n",
    "\\begin{align*}\n",
    "h_i = -1 \\ \\mathrm{for\\ } \\forall i,\\ J_{ij} = -1 \\ \\mathrm{for\\ } \\forall i,\\ j\n",
    "\\end{align*}\n",
    "\n",
    "\n",
    "$\\{\\sigma_i\\} = \\{1,1,1,1,1,1\\}$ is the optimal solution since each spin has lower energy if it takes the value of 1.\n",
    "Let us solve this problem.\n",
    "The process using Python code is as follows:\n",
    "\n",
    "> The core interface is a specialized solver for Ising problems. To convert to QUBO, please refer to the previous tutorials and convert from QUBO to the Ising problem before calling the core interface."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The solution is [1, 1, 1, 1, 1].\n"
     ]
    }
   ],
   "source": [
    "# import cxxjij instead of openjij\n",
    "import openjij.cxxjij as cj\n",
    "\n",
    "# Create the interaction matrix using the Graph module\n",
    "import openjij.cxxjij.graph as G\n",
    "\n",
    "# Define a densely connected graph (Dense) with problem size N = 5.\n",
    "N = 5\n",
    "J = G.Dense(N)\n",
    "# Set interactions\n",
    "for i in range(N):\n",
    "    for j in range(N):\n",
    "        #Enter -1 for j[i,i] else\n",
    "        J[i,j] = 0 if i == j else -1.0\n",
    "\n",
    "# Set a vertical magnetic field\n",
    "for i in range(N):\n",
    "    # J[i,i] = -1 will give the same result\n",
    "    J[i] = -1\n",
    "\n",
    "# Create a system to perform the calculation\n",
    "import openjij.cxxjij.system as S\n",
    "\n",
    "# We use the usual classical Monte Carlo system\n",
    "system = S.make_classical_ising(J.gen_spin(), J)\n",
    "# Set an annealing schedule using the Utility module\n",
    "import openjij.cxxjij.utility as U\n",
    "schedule = U.make_classical_schedule_list(0.1, 100, 10, 10)\n",
    "\n",
    "# Run the annealing using the Algorithm module\n",
    "# Use a simple SingleSpinFlip to update the Monte Carlo step\n",
    "import openjij.cxxjij.algorithm as A\n",
    "A.Algorithm_SingleSpinFlip_run(system, schedule)\n",
    "\n",
    "# Get the result using get_solution in the Result module\n",
    "import openjij.cxxjij.result as R\n",
    "print(\"The solution is {}.\".format(R.get_solution(system)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The answer that comes out is $[1,1,1,1,1,1]$.\n",
    "There are many items to be configured for the low-layer API, but this allows for a more detailed configuration."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Module List\n",
    "\n",
    "As shown in the code example, the OpenJij core interface mainly consists of modules such as `graph`, `system`, `updater`, `algorithm` and `result`. By combining these modules, it is possible to compute the Ising model with various types and algorithms. The modules can be easily extended to implement new algorithms. A detailed explanation will be given in the following notebooks."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Graph\n",
    "\n",
    "This module is used to store the coefficients $J_{ij}$ of the Ising Hamiltonian.\n",
    "`Dense` deals with tight coupling (suitable for models where all $J_ij$ have non-zero values), and `Sparse` deals with sparse coupling (suitable for models where many of the $J_ij$ values are zero)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### System\n",
    "\n",
    "The `system` defines a data structure to hold the current system state for Monte Carlo and other calculations such as:\n",
    "\n",
    "- Classical Ising model (spins)\n",
    "- Transverse field Ising model (spins including Trotter decomposition)\n",
    "- GPU-implemented classical and quantum Ising models\n",
    "\n",
    "There are (and/or will be) a variety of Monte Carlo and other computational methods.\n",
    "Therefore, OpenJij is designed to facilitate the addition of various algorithms by separating the data structures and algorithms for each method and the interface for retrieving the results."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Updater\n",
    "\n",
    "This defines how the `system` is to be updated such as:\n",
    "\n",
    "- SingleSpinFlip Update\n",
    "- SwendsenWang Update\n",
    "\n",
    "The Updater that can be used is determined by the type of System.\n",
    "The specific types of updaters that can be used on each system type will be discussed in the following tutorials.\n",
    "\n",
    "> In the core python interface, it is integrated into `algorithm`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Algorithm\n",
    "\n",
    "It is responsible for running the algorithm, including what schedule to run the annealing algorithm using `updater`.\n",
    "It can be run using the corresponding updater at `Algorithm_[Updater type]_run`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Result\n",
    "\n",
    "This is used to get information from `system`, such as spin configuration."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Coding Flow\n",
    "\n",
    "The coding flow is shown below.\n",
    "This flow does not change even when the scale of the problem grows.\n",
    "\n",
    "- Define $J_{ij}, h_{i}$ in the `graph` module\n",
    "- Create `system` based on the `graph` module\n",
    "- Select `updater` corresponding to `system` and run the algorithm with `Algorithm_[Updater type]_run`\n",
    "- Get the spin configuration of the system with `result.get_solution(system)` or directly from `system`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.15"
  },
  "vscode": {
   "interpreter": {
    "hash": "2e8d7574d7ec71e14cb1575cf43673432d6fae464c836a7b3733d4f6c20243fb"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}