{"action":"created","comment":{"url":"https://api.github.com/repos/odlgroup/odl/pulls/comments/53449263","id":53449263,"diff_hunk":"@@ -34,206 +33,346 @@\n __all__ = ('PartialDerivative', 'Gradient', 'Divergence', 'Laplacian')\n \n \n-def finite_diff(f, out=None, axis=0, dx=1.0, edge_order=2,\n-                zero_padding=False, method='central'):\n+# TODO: make helper function to set edge slices\n+\n+def finite_diff(f, axis=0, dx=1.0, method='forward', padding_method=None,\n+                padding_value=0, **kwargs):\n     \"\"\"Calculate the partial derivative of ``f`` along a given ``axis``.\n \n-    The partial derivative is computed using second-order accurate central\n-    differences in the interior and either first- or second-order accurate\n-    one-sides (forward or backward) differences at the boundaries.\n+    In the interior of the domain of f, the partial derivative is computed\n+    using first-order accurate forward or backward difference or\n+    second-order accurate central differences.\n+\n+    With padding the same method and thus accuracy is used on endpoints as\n+    in the interior i.e. forward and backward differences use first-order\n+    accuracy on edges while central differences use second-order accuracy at\n+    edges.\n \n-    Assuming (implicit) zero padding central differences are used on the\n-    interior and on endpoints. Otherwise one-sided differences are used. If\n-    ``zero_padding`` is `False` first-order accuracy can be triggered on\n-    endpoints with parameter ``edge_order``.\n+    Without padding one-sided forward or backward differences are used at\n+    the boundaries. The accuracy at the endpoints can then also be\n+    triggered by the edge order.\n \n     The returned array has the same shape as the input array ``f``.\n \n+    Per default forward difference with dx=1 and no padding is used.\n+\n     Parameters\n     ----------\n     f : `array-like`\n          An N-dimensional array\n-    out : `numpy.ndarray`, optional\n-         An N-dimensional array to which the output is written.\n     axis : `int`, optional\n-        The axis along which the partial derivative is evaluated. Default: 0\n+        The axis along which the partial derivative is evaluated\n     dx : `float`, optional\n-        Scalar specifying the sample distances in each dimension ``axis``.\n-        Default distance: 1.0\n-    edge_order : {1, 2}, optional\n-        First-order accurate differences (1) can be used at the boundaries\n-        if no zero padding is used. Default edge order: 2\n-    zero_padding : `bool`, optional\n-        Implicit zero padding. Assumes values outside the domain of ``f`` to be\n-        zero. Default: `False`\n+        Scalar specifying the distance between sampling points along ``axis``\n     method : {'central', 'forward', 'backward'}, optional\n-        The method that should be used.\n+        Finite difference method which is used in the interior of the domain\n+         of ``f``.\n+    padding_method : {'constant', 'symmetric'}, optional\n+        'constant' : Pads values outside the domain of ``f`` with a constant\n+            value given by ``padding_value``\n+        'symmetric' : Pads with the reflection of the vector mirrored\n+            along the edge of the array\n+        If `None` one-sided forward or backward differences are used at the\n+        boundary.\n+    padding_value : `float`, optional\n+        If ``padding_method`` is 'constant' ``f`` assumes ``padding_value``\n+        for indices outside the domain of ``f``\n+\n+    Other Parameters\n+    ----------------\n+    edge_order : {1, 2}, optional\n+        Edge-order accuracy at the boundaries if no padding is used. If\n+        `None` the edge-order accuracy at endpoints corresponds to the\n+        accuracy in the interior. Default: `None`\n+    out : `numpy.ndarray`, optional\n+         An N-dimensional array to which the output is written. Has to have\n+         the same shape as the input array ``f``. Default: `None`\n \n     Returns\n     -------\n     out : `numpy.ndarray`\n-        N-dimensional array of the same shape as ``f``. If ``out`` was\n-            provided, the returned object is a reference to it.\n+        N-dimensional array of the same shape as ``f``. If ``out`` is\n+        provided, the returned object is a reference to it.\n+\n+    Notes\n+    -----\n+    Without padding the use of second-order accurate edges requires at\n+    least three elements.\n+\n+    Central differences with padding cannot be used with first-order\n+    accurate edges.\n+\n+    Forward and backward differences with padding use the first-order\n+    accuracy on edges (as in the interior).\n+\n+    An edge-order accuracy different from the interior can only be triggered\n+    without padding i.e. when one-sided differences are used at the edges.\n \n     Examples\n     --------\n     >>> f = np.array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])\n+\n     >>> finite_diff(f)\n     array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])\n-    >>> finite_diff(f, axis=0, dx=1.0, edge_order=2, zero_padding=False)\n+\n+    Without arguments the above defaults to:\n+\n+    >>> finite_diff(f, axis=0, dx=1.0, method='forward', padding_method=None,\n+    ... edge_order=None)\n     array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])\n+\n     >>> finite_diff(f, dx=0.5)\n     array([ 2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.])\n-    >>> finite_diff(f, zero_padding=True)\n-    array([ 0.5,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. , -4. ])\n-    >>> finite_diff(f, zero_padding=False, edge_order=1)\n-    array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])\n-    >>> out = finite_diff(f)\n-    >>> out is finite_diff(f)\n-    False\n-    >>> out is finite_diff(f, out)\n+    >>> finite_diff(f, padding_method='constant')\n+    array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1., -9.])\n+\n+    Central differences and different edge orders:\n+\n+    >>> finite_diff(1/2*f**2, method='central')\n+    array([-0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.])\n+    >>> finite_diff(1/2*f**2, method='central', edge_order=1)\n+    array([ 0.5,  1. ,  2. ,  3. ,  4. ,  5. ,  6. ,  7. ,  8. ,  8.5])\n+\n+    In-place evaluation:\n+\n+    >>> out = f.copy()\n+    >>> out is finite_diff(f, out=out)\n     True\n     \"\"\"\n     # TODO: implement alternative boundary conditions\n \n-    if zero_padding is True and edge_order == 1:\n-        raise ValueError(\"zero padding uses second-order accurate \"\n-                         \"differences at boundaries. First-order accurate \"\n-                         \"edges can only be used without zero padding.\")\n-    f_data = np.asarray(f)\n-    ndim = f_data.ndim\n-\n-    if not 0 <= axis < ndim:\n-        raise IndexError(\"axis parameter ({0}) exceeds the number of \"\n-                         \"dimensions ({1}).\".format(axis, ndim))\n+    f_arr = np.asarray(f)\n+    ndim = f_arr.ndim\n \n-    if f_data.shape[axis] < 2:\n-        raise ValueError(\"shape ({0}) of array too small to calculate a \"\n-                         \"numerical gradient, at least two elements are \"\n-                         \"required.\".format(f_data.shape))\n-\n-    if out is None:\n-        out = np.empty_like(f_data)\n-    else:\n-        if out.shape != f.shape:\n-            raise ValueError(\n-                \"shape of `out` array ({0}) does not match the shape of \"\n-                \"input array `f` ({1}).\".format(out.shape, f.shape))\n+    if f_arr.shape[axis] < 2:\n+        raise ValueError('In axis {}: at least two elements required, got {}.'\n+                         ''.format(axis, f_arr.shape[axis]))\n \n-    if edge_order not in [1, 2]:\n-        raise ValueError(\"edge order ({0}) not valid\".format(edge_order))\n+    if axis < 0:\n+        axis += ndim\n+    if axis >= ndim:\n+        raise IndexError('axis {} outside the valid range 0 ... {}'\n+                         ''.format(axis, ndim - 1))\n \n     if dx <= 0:\n-        raise ValueError(\"step length ({0}) not positive.\".format(dx))\n+        raise ValueError(\"step length {} not positive.\".format(dx))\n     else:\n         dx = float(dx)\n \n     method, method_in = str(method).lower(), method\n     if method not in ('central', 'forward', 'backward'):\n-        raise ValueError(\"method '{}' has to be central, forward or backward\"\n-                         ''.format(method_in))\n+        raise ValueError('method {} is not understood'.format(method_in))\n+\n+    if padding_method not in ('constant', 'symmetric', None):\n+        raise ValueError('padding value {} not valid'.format(padding_method))\n+    if padding_method is 'constant':\n+        padding_value = float(padding_value)\n+\n+    edge_order = kwargs.pop('edge_order', None)\n+    if edge_order is None:\n+        if method == 'central':\n+            edge_order = 2\n+        else:\n+            edge_order = 1\n+    else:\n+        if edge_order not in (1, 2):\n+            raise ValueError('edge order {} not valid'.format(edge_order))\n+\n+    out = kwargs.pop('out', None)\n+    if out is None:\n+        out = np.empty_like(f_arr)\n+    else:\n+        if out.shape != f.shape:\n+            raise ValueError('expected output shape {}, got {}.'\n+                             ''.format(f.shape, out.shape))\n+\n+    if f_arr.shape[axis] == 2 and edge_order == 2:\n+        raise ValueError('shape of array to small to use edge order 2')\n+\n+    if padding_method is not None:\n+        if method == 'central' and edge_order == 1:\n+            raise ValueError(\n+                'central differences with padding cannot be used with '\n+                'first-order accurate edges')\n+        if method in ('forward', 'backward') and edge_order == 2:\n+            raise ValueError('{} differences with padding only use edge '\n+                             'order 1'.format(method))\n \n     # create slice objects: initially all are [:, :, ..., :]\n+\n     # current slice\n     slice_out = [slice(None)] * ndim\n+\n     # slices used to calculate finite differences\n     slice_node1 = [slice(None)] * ndim\n     slice_node2 = [slice(None)] * ndim\n     slice_node3 = [slice(None)] * ndim\n \n+    # Interior of the domain of f\n+\n     if method == 'central':\n-        # Numerical differentiation: 2nd order interior\n+        # 2nd order differences in the interior of the domain of f\n         slice_out[axis] = slice(1, -1)\n         slice_node1[axis] = slice(2, None)\n         slice_node2[axis] = slice(None, -2)\n         # 1D equivalent: out[1:-1] = (f[2:] - f[:-2])/2.0\n-        np.subtract(f_data[slice_node1], f_data[slice_node2], out[slice_out])\n+        np.subtract(f_arr[slice_node1], f_arr[slice_node2], out[slice_out])\n         out[slice_out] /= 2.0\n+\n     elif method == 'forward':\n-        # Numerical differentiation: 1nd order interior\n+        # 1st order differences in the interior of the domain of f\n         slice_out[axis] = slice(1, -1)\n         slice_node1[axis] = slice(2, None)\n         slice_node2[axis] = slice(1, -1)\n         # 1D equivalent: out[1:-1] = (f[2:] - f[1:-1])\n-        np.subtract(f_data[slice_node1], f_data[slice_node2], out[slice_out])\n+        np.subtract(f_arr[slice_node1], f_arr[slice_node2], out[slice_out])\n+\n     elif method == 'backward':\n-        # Numerical differentiation: 1nd order interior\n+        # 1st order differences in the interior of the domain of f\n         slice_out[axis] = slice(1, -1)\n         slice_node1[axis] = slice(1, -1)\n         slice_node2[axis] = slice(None, -2)\n         # 1D equivalent: out[1:-1] = (f[1:-1] - f[:-2])\n-        np.subtract(f_data[slice_node1], f_data[slice_node2], out[slice_out])\n+        np.subtract(f_arr[slice_node1], f_arr[slice_node2], out[slice_out])\n+\n+    # Boundaries\n+\n+    if padding_method is 'constant':","path":"odl/discr/discr_ops.py","position":281,"original_position":281,"commit_id":"384ca44d326df4a0f5842a3d47b31c212d15e735","original_commit_id":"384ca44d326df4a0f5842a3d47b31c212d15e735","user":{"login":"kohr-h","id":5030250,"avatar_url":"https://avatars.githubusercontent.com/u/5030250?v=3","gravatar_id":"","url":"https://api.github.com/users/kohr-h","html_url":"https://github.com/kohr-h","followers_url":"https://api.github.com/users/kohr-h/followers","following_url":"https://api.github.com/users/kohr-h/following{/other_user}","gists_url":"https://api.github.com/users/kohr-h/gists{/gist_id}","starred_url":"https://api.github.com/users/kohr-h/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kohr-h/subscriptions","organizations_url":"https://api.github.com/users/kohr-h/orgs","repos_url":"https://api.github.com/users/kohr-h/repos","events_url":"https://api.github.com/users/kohr-h/events{/privacy}","received_events_url":"https://api.github.com/users/kohr-h/received_events","type":"User","site_admin":false},"body":"==","created_at":"2016-02-19T11:18:37Z","updated_at":"2016-02-19T11:18:37Z","html_url":"https://github.com/odlgroup/odl/pull/230#discussion_r53449263","pull_request_url":"https://api.github.com/repos/odlgroup/odl/pulls/230","_links":{"self":{"href":"https://api.github.com/repos/odlgroup/odl/pulls/comments/53449263"},"html":{"href":"https://github.com/odlgroup/odl/pull/230#discussion_r53449263"},"pull_request":{"href":"https://api.github.com/repos/odlgroup/odl/pulls/230"}}},"pull_request":{"url":"https://api.github.com/repos/odlgroup/odl/pulls/230","id":56778302,"html_url":"https://github.com/odlgroup/odl/pull/230","diff_url":"https://github.com/odlgroup/odl/pull/230.diff","patch_url":"https://github.com/odlgroup/odl/pull/230.patch","issue_url":"https://api.github.com/repos/odlgroup/odl/issues/230","number":230,"state":"open","locked":false,"title":"Issue 226  chambolle pock solver","user":{"login":"adler-j","id":2202312,"avatar_url":"https://avatars.githubusercontent.com/u/2202312?v=3","gravatar_id":"","url":"https://api.github.com/users/adler-j","html_url":"https://github.com/adler-j","followers_url":"https://api.github.com/users/adler-j/followers","following_url":"https://api.github.com/users/adler-j/following{/other_user}","gists_url":"https://api.github.com/users/adler-j/gists{/gist_id}","starred_url":"https://api.github.com/users/adler-j/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adler-j/subscriptions","organizations_url":"https://api.github.com/users/adler-j/orgs","repos_url":"https://api.github.com/users/adler-j/repos","events_url":"https://api.github.com/users/adler-j/events{/privacy}","received_events_url":"https://api.github.com/users/adler-j/received_events","type":"User","site_admin":false},"body":"Created a pull request of this to be able to comment. @moosmann and @aringh are main authors.","created_at":"2016-01-21T17:02:14Z","updated_at":"2016-02-19T11:18:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"acd2d1dad68033227af5924c572cc00054e2d059","assignee":{"login":"moosmann","id":6815901,"avatar_url":"https://avatars.githubusercontent.com/u/6815901?v=3","gravatar_id":"","url":"https://api.github.com/users/moosmann","html_url":"https://github.com/moosmann","followers_url":"https://api.github.com/users/moosmann/followers","following_url":"https://api.github.com/users/moosmann/following{/other_user}","gists_url":"https://api.github.com/users/moosmann/gists{/gist_id}","starred_url":"https://api.github.com/users/moosmann/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/moosmann/subscriptions","organizations_url":"https://api.github.com/users/moosmann/orgs","repos_url":"https://api.github.com/users/moosmann/repos","events_url":"https://api.github.com/users/moosmann/events{/privacy}","received_events_url":"https://api.github.com/users/moosmann/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/odlgroup/odl/pulls/230/commits","review_comments_url":"https://api.github.com/repos/odlgroup/odl/pulls/230/comments","review_comment_url":"https://api.github.com/repos/odlgroup/odl/pulls/comments{/number}","comments_url":"https://api.github.com/repos/odlgroup/odl/issues/230/comments","statuses_url":"https://api.github.com/repos/odlgroup/odl/statuses/384ca44d326df4a0f5842a3d47b31c212d15e735","head":{"label":"odlgroup:issue-226__Chambolle-Pock_solver","ref":"issue-226__Chambolle-Pock_solver","sha":"384ca44d326df4a0f5842a3d47b31c212d15e735","user":{"login":"odlgroup","id":15667171,"avatar_url":"https://avatars.githubusercontent.com/u/15667171?v=3","gravatar_id":"","url":"https://api.github.com/users/odlgroup","html_url":"https://github.com/odlgroup","followers_url":"https://api.github.com/users/odlgroup/followers","following_url":"https://api.github.com/users/odlgroup/following{/other_user}","gists_url":"https://api.github.com/users/odlgroup/gists{/gist_id}","starred_url":"https://api.github.com/users/odlgroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odlgroup/subscriptions","organizations_url":"https://api.github.com/users/odlgroup/orgs","repos_url":"https://api.github.com/users/odlgroup/repos","events_url":"https://api.github.com/users/odlgroup/events{/privacy}","received_events_url":"https://api.github.com/users/odlgroup/received_events","type":"Organization","site_admin":false},"repo":{"id":45596393,"name":"odl","full_name":"odlgroup/odl","owner":{"login":"odlgroup","id":15667171,"avatar_url":"https://avatars.githubusercontent.com/u/15667171?v=3","gravatar_id":"","url":"https://api.github.com/users/odlgroup","html_url":"https://github.com/odlgroup","followers_url":"https://api.github.com/users/odlgroup/followers","following_url":"https://api.github.com/users/odlgroup/following{/other_user}","gists_url":"https://api.github.com/users/odlgroup/gists{/gist_id}","starred_url":"https://api.github.com/users/odlgroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odlgroup/subscriptions","organizations_url":"https://api.github.com/users/odlgroup/orgs","repos_url":"https://api.github.com/users/odlgroup/repos","events_url":"https://api.github.com/users/odlgroup/events{/privacy}","received_events_url":"https://api.github.com/users/odlgroup/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/odlgroup/odl","description":"Operator Discretization Library","fork":false,"url":"https://api.github.com/repos/odlgroup/odl","forks_url":"https://api.github.com/repos/odlgroup/odl/forks","keys_url":"https://api.github.com/repos/odlgroup/odl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/odlgroup/odl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/odlgroup/odl/teams","hooks_url":"https://api.github.com/repos/odlgroup/odl/hooks","issue_events_url":"https://api.github.com/repos/odlgroup/odl/issues/events{/number}","events_url":"https://api.github.com/repos/odlgroup/odl/events","assignees_url":"https://api.github.com/repos/odlgroup/odl/assignees{/user}","branches_url":"https://api.github.com/repos/odlgroup/odl/branches{/branch}","tags_url":"https://api.github.com/repos/odlgroup/odl/tags","blobs_url":"https://api.github.com/repos/odlgroup/odl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/odlgroup/odl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/odlgroup/odl/git/refs{/sha}","trees_url":"https://api.github.com/repos/odlgroup/odl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/odlgroup/odl/statuses/{sha}","languages_url":"https://api.github.com/repos/odlgroup/odl/languages","stargazers_url":"https://api.github.com/repos/odlgroup/odl/stargazers","contributors_url":"https://api.github.com/repos/odlgroup/odl/contributors","subscribers_url":"https://api.github.com/repos/odlgroup/odl/subscribers","subscription_url":"https://api.github.com/repos/odlgroup/odl/subscription","commits_url":"https://api.github.com/repos/odlgroup/odl/commits{/sha}","git_commits_url":"https://api.github.com/repos/odlgroup/odl/git/commits{/sha}","comments_url":"https://api.github.com/repos/odlgroup/odl/comments{/number}","issue_comment_url":"https://api.github.com/repos/odlgroup/odl/issues/comments{/number}","contents_url":"https://api.github.com/repos/odlgroup/odl/contents/{+path}","compare_url":"https://api.github.com/repos/odlgroup/odl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/odlgroup/odl/merges","archive_url":"https://api.github.com/repos/odlgroup/odl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/odlgroup/odl/downloads","issues_url":"https://api.github.com/repos/odlgroup/odl/issues{/number}","pulls_url":"https://api.github.com/repos/odlgroup/odl/pulls{/number}","milestones_url":"https://api.github.com/repos/odlgroup/odl/milestones{/number}","notifications_url":"https://api.github.com/repos/odlgroup/odl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/odlgroup/odl/labels{/name}","releases_url":"https://api.github.com/repos/odlgroup/odl/releases{/id}","deployments_url":"https://api.github.com/repos/odlgroup/odl/deployments","created_at":"2015-11-05T07:57:55Z","updated_at":"2016-02-03T10:05:06Z","pushed_at":"2016-02-18T21:02:33Z","git_url":"git://github.com/odlgroup/odl.git","ssh_url":"git@github.com:odlgroup/odl.git","clone_url":"https://github.com/odlgroup/odl.git","svn_url":"https://github.com/odlgroup/odl","homepage":null,"size":15110,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":75,"forks":3,"open_issues":75,"watchers":3,"default_branch":"master"}},"base":{"label":"odlgroup:master","ref":"master","sha":"6b60739a741db48d0f89c065af7c1a0056b63d74","user":{"login":"odlgroup","id":15667171,"avatar_url":"https://avatars.githubusercontent.com/u/15667171?v=3","gravatar_id":"","url":"https://api.github.com/users/odlgroup","html_url":"https://github.com/odlgroup","followers_url":"https://api.github.com/users/odlgroup/followers","following_url":"https://api.github.com/users/odlgroup/following{/other_user}","gists_url":"https://api.github.com/users/odlgroup/gists{/gist_id}","starred_url":"https://api.github.com/users/odlgroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odlgroup/subscriptions","organizations_url":"https://api.github.com/users/odlgroup/orgs","repos_url":"https://api.github.com/users/odlgroup/repos","events_url":"https://api.github.com/users/odlgroup/events{/privacy}","received_events_url":"https://api.github.com/users/odlgroup/received_events","type":"Organization","site_admin":false},"repo":{"id":45596393,"name":"odl","full_name":"odlgroup/odl","owner":{"login":"odlgroup","id":15667171,"avatar_url":"https://avatars.githubusercontent.com/u/15667171?v=3","gravatar_id":"","url":"https://api.github.com/users/odlgroup","html_url":"https://github.com/odlgroup","followers_url":"https://api.github.com/users/odlgroup/followers","following_url":"https://api.github.com/users/odlgroup/following{/other_user}","gists_url":"https://api.github.com/users/odlgroup/gists{/gist_id}","starred_url":"https://api.github.com/users/odlgroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odlgroup/subscriptions","organizations_url":"https://api.github.com/users/odlgroup/orgs","repos_url":"https://api.github.com/users/odlgroup/repos","events_url":"https://api.github.com/users/odlgroup/events{/privacy}","received_events_url":"https://api.github.com/users/odlgroup/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/odlgroup/odl","description":"Operator Discretization Library","fork":false,"url":"https://api.github.com/repos/odlgroup/odl","forks_url":"https://api.github.com/repos/odlgroup/odl/forks","keys_url":"https://api.github.com/repos/odlgroup/odl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/odlgroup/odl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/odlgroup/odl/teams","hooks_url":"https://api.github.com/repos/odlgroup/odl/hooks","issue_events_url":"https://api.github.com/repos/odlgroup/odl/issues/events{/number}","events_url":"https://api.github.com/repos/odlgroup/odl/events","assignees_url":"https://api.github.com/repos/odlgroup/odl/assignees{/user}","branches_url":"https://api.github.com/repos/odlgroup/odl/branches{/branch}","tags_url":"https://api.github.com/repos/odlgroup/odl/tags","blobs_url":"https://api.github.com/repos/odlgroup/odl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/odlgroup/odl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/odlgroup/odl/git/refs{/sha}","trees_url":"https://api.github.com/repos/odlgroup/odl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/odlgroup/odl/statuses/{sha}","languages_url":"https://api.github.com/repos/odlgroup/odl/languages","stargazers_url":"https://api.github.com/repos/odlgroup/odl/stargazers","contributors_url":"https://api.github.com/repos/odlgroup/odl/contributors","subscribers_url":"https://api.github.com/repos/odlgroup/odl/subscribers","subscription_url":"https://api.github.com/repos/odlgroup/odl/subscription","commits_url":"https://api.github.com/repos/odlgroup/odl/commits{/sha}","git_commits_url":"https://api.github.com/repos/odlgroup/odl/git/commits{/sha}","comments_url":"https://api.github.com/repos/odlgroup/odl/comments{/number}","issue_comment_url":"https://api.github.com/repos/odlgroup/odl/issues/comments{/number}","contents_url":"https://api.github.com/repos/odlgroup/odl/contents/{+path}","compare_url":"https://api.github.com/repos/odlgroup/odl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/odlgroup/odl/merges","archive_url":"https://api.github.com/repos/odlgroup/odl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/odlgroup/odl/downloads","issues_url":"https://api.github.com/repos/odlgroup/odl/issues{/number}","pulls_url":"https://api.github.com/repos/odlgroup/odl/pulls{/number}","milestones_url":"https://api.github.com/repos/odlgroup/odl/milestones{/number}","notifications_url":"https://api.github.com/repos/odlgroup/odl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/odlgroup/odl/labels{/name}","releases_url":"https://api.github.com/repos/odlgroup/odl/releases{/id}","deployments_url":"https://api.github.com/repos/odlgroup/odl/deployments","created_at":"2015-11-05T07:57:55Z","updated_at":"2016-02-03T10:05:06Z","pushed_at":"2016-02-18T21:02:33Z","git_url":"git://github.com/odlgroup/odl.git","ssh_url":"git@github.com:odlgroup/odl.git","clone_url":"https://github.com/odlgroup/odl.git","svn_url":"https://github.com/odlgroup/odl","homepage":null,"size":15110,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":75,"forks":3,"open_issues":75,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/odlgroup/odl/pulls/230"},"html":{"href":"https://github.com/odlgroup/odl/pull/230"},"issue":{"href":"https://api.github.com/repos/odlgroup/odl/issues/230"},"comments":{"href":"https://api.github.com/repos/odlgroup/odl/issues/230/comments"},"review_comments":{"href":"https://api.github.com/repos/odlgroup/odl/pulls/230/comments"},"review_comment":{"href":"https://api.github.com/repos/odlgroup/odl/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/odlgroup/odl/pulls/230/commits"},"statuses":{"href":"https://api.github.com/repos/odlgroup/odl/statuses/384ca44d326df4a0f5842a3d47b31c212d15e735"}}}}