prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Get rid of netket::Ising and other hard-coded hamiltonians in c++
  In the spirit of #199 , we can safely remove the Ising and Heisenberg hamiltonians from the C++ classes, since those are nothing but specific cases of more general hamiltonians (basically they are just LocalOperators or even GraphOperator). 
  Convenient constructors can be defined in few lines of python, and moved to the python part of the library. 
  
  The BoseHubbard hamiltonian is a bit trickier, we can keep it as it is for the moment. 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `netket/operator.py`
  Content:
  ```
  1 from ._C_netket.operator import *
  2
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/netket/operator.py b/netket/operator.py
  --- a/netket/operator.py
  +++ b/netket/operator.py
  @@ -1 +1,52 @@
   from ._C_netket.operator import *
  +import numpy as _np
  +
  +
  +def Ising(hilbert, h, J=1.0):
  +    """
  +    Constructs a new ``Ising`` given a hilbert space, a transverse field,
  +    and (if specified) a coupling constant.
  +
  +    Args:
  +        hilbert: Hilbert space the operator acts on.
  +        h: The strength of the transverse field.
  +        J: The strength of the coupling. Default is 1.0.
  +
  +    Examples:
  +        Constructs an ``Ising`` operator for a 1D system.
  +
  +        ```python
  +        >>> import netket as nk
  +        >>> g = nk.graph.Hypercube(length=20, n_dim=1, pbc=True)
  +        >>> hi = nk.hilbert.Spin(s=0.5, graph=g)
  +        >>> op = nk.operator.Ising(h=1.321, hilbert=hi, J=0.5)
  +        >>> print(op.hilbert.size)
  +        20
  +    """
  +    sigma_x = _np.array([[0, 1], [1, 0]])
  +    sz_sz = _np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
  +    return GraphOperator(hilbert, siteops=[-h * sigma_x], bondops=[J * sz_sz])
  +
  +
  +def Heisenberg(hilbert):
  +    """
  +    Constructs a new ``Heisenberg`` given a hilbert space.
  +    Args:
  +        hilbert: Hilbert space the operator acts on.
  +    Examples:
  +     Constructs a ``Heisenberg`` operator for a 1D system.
  +        ```python
  +        >>> import netket as nk
  +        >>> g = nk.graph.Hypercube(length=20, n_dim=1, pbc=True)
  +        >>> hi = nk.hilbert.Spin(s=0.5, total_sz=0, graph=g)
  +        >>> op = nk.operator.Heisenberg(hilbert=hi)
  +        >>> print(op.hilbert.size)
  +        20
  +    """
  +    sz_sz = _np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
  +    exchange = _np.array([[0, 0, 0, 0], [0, 0, 2, 0], [0, 2, 0, 0], [0, 0, 0, 0]])
  +    if hilbert.graph.is_bipartite:
  +        heis_term = sz_sz - exchange
  +    else:
  +        heis_term = sz_sz + exchange
  +    return GraphOperator(hilbert, bondops=[heis_term])
  
verification_info: {"golden_diff": "diff --git a/netket/operator.py b/netket/operator.py\n--- a/netket/operator.py\n+++ b/netket/operator.py\n@@ -1 +1,52 @@\n from ._C_netket.operator import *\n+import numpy as _np\n+\n+\n+def Ising(hilbert, h, J=1.0):\n+    \"\"\"\n+    Constructs a new ``Ising`` given a hilbert space, a transverse field,\n+    and (if specified) a coupling constant.\n+\n+    Args:\n+        hilbert: Hilbert space the operator acts on.\n+        h: The strength of the transverse field.\n+        J: The strength of the coupling. Default is 1.0.\n+\n+    Examples:\n+        Constructs an ``Ising`` operator for a 1D system.\n+\n+        ```python\n+        >>> import netket as nk\n+        >>> g = nk.graph.Hypercube(length=20, n_dim=1, pbc=True)\n+        >>> hi = nk.hilbert.Spin(s=0.5, graph=g)\n+        >>> op = nk.operator.Ising(h=1.321, hilbert=hi, J=0.5)\n+        >>> print(op.hilbert.size)\n+        20\n+    \"\"\"\n+    sigma_x = _np.array([[0, 1], [1, 0]])\n+    sz_sz = _np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])\n+    return GraphOperator(hilbert, siteops=[-h * sigma_x], bondops=[J * sz_sz])\n+\n+\n+def Heisenberg(hilbert):\n+    \"\"\"\n+    Constructs a new ``Heisenberg`` given a hilbert space.\n+    Args:\n+        hilbert: Hilbert space the operator acts on.\n+    Examples:\n+     Constructs a ``Heisenberg`` operator for a 1D system.\n+        ```python\n+        >>> import netket as nk\n+        >>> g = nk.graph.Hypercube(length=20, n_dim=1, pbc=True)\n+        >>> hi = nk.hilbert.Spin(s=0.5, total_sz=0, graph=g)\n+        >>> op = nk.operator.Heisenberg(hilbert=hi)\n+        >>> print(op.hilbert.size)\n+        20\n+    \"\"\"\n+    sz_sz = _np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])\n+    exchange = _np.array([[0, 0, 0, 0], [0, 0, 2, 0], [0, 2, 0, 0], [0, 0, 0, 0]])\n+    if hilbert.graph.is_bipartite:\n+        heis_term = sz_sz - exchange\n+    else:\n+        heis_term = sz_sz + exchange\n+    return GraphOperator(hilbert, bondops=[heis_term])\n", "issue": "Get rid of netket::Ising and other hard-coded hamiltonians in c++\nIn the spirit of #199 , we can safely remove the Ising and Heisenberg hamiltonians from the C++ classes, since those are nothing but specific cases of more general hamiltonians (basically they are just LocalOperators or even GraphOperator). \r\nConvenient constructors can be defined in few lines of python, and moved to the python part of the library. \r\n\r\nThe BoseHubbard hamiltonian is a bit trickier, we can keep it as it is for the moment. \n", "before_files": [{"content": "from ._C_netket.operator import *\n", "path": "netket/operator.py"}], "after_files": [{"content": "from ._C_netket.operator import *\nimport numpy as _np\n\n\ndef Ising(hilbert, h, J=1.0):\n    \"\"\"\n    Constructs a new ``Ising`` given a hilbert space, a transverse field,\n    and (if specified) a coupling constant.\n\n    Args:\n        hilbert: Hilbert space the operator acts on.\n        h: The strength of the transverse field.\n        J: The strength of the coupling. Default is 1.0.\n\n    Examples:\n        Constructs an ``Ising`` operator for a 1D system.\n\n        ```python\n        >>> import netket as nk\n        >>> g = nk.graph.Hypercube(length=20, n_dim=1, pbc=True)\n        >>> hi = nk.hilbert.Spin(s=0.5, graph=g)\n        >>> op = nk.operator.Ising(h=1.321, hilbert=hi, J=0.5)\n        >>> print(op.hilbert.size)\n        20\n    \"\"\"\n    sigma_x = _np.array([[0, 1], [1, 0]])\n    sz_sz = _np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])\n    return GraphOperator(hilbert, siteops=[-h * sigma_x], bondops=[J * sz_sz])\n\n\ndef Heisenberg(hilbert):\n    \"\"\"\n    Constructs a new ``Heisenberg`` given a hilbert space.\n    Args:\n        hilbert: Hilbert space the operator acts on.\n    Examples:\n     Constructs a ``Heisenberg`` operator for a 1D system.\n        ```python\n        >>> import netket as nk\n        >>> g = nk.graph.Hypercube(length=20, n_dim=1, pbc=True)\n        >>> hi = nk.hilbert.Spin(s=0.5, total_sz=0, graph=g)\n        >>> op = nk.operator.Heisenberg(hilbert=hi)\n        >>> print(op.hilbert.size)\n        20\n    \"\"\"\n    sz_sz = _np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])\n    exchange = _np.array([[0, 0, 0, 0], [0, 0, 2, 0], [0, 2, 0, 0], [0, 0, 0, 0]])\n    if hilbert.graph.is_bipartite:\n        heis_term = sz_sz - exchange\n    else:\n        heis_term = sz_sz + exchange\n    return GraphOperator(hilbert, bondops=[heis_term])\n", "path": "netket/operator.py"}]}