{"action":"created","comment":{"url":"https://api.github.com/repos/sympy/sympy/pulls/comments/37812623","id":37812623,"diff_hunk":"@@ -1,12 +1,463 @@\n Solveset\n-==========\n+========\n \n .. module:: sympy.solvers.solveset\n \n-This module contains functions to solve a single equation for a single variable.\n+This is the official documentation of the ``solveset`` module in solvers.\n+It contains the Frequently asked Questions about our new module to solve\n+equations.\n+\n+What's wrong with solve():\n+--------------------------\n+\n+SymPy already has a pretty powerful ``solve`` function. But it has a lot of major\n+issues\n+\n+1. It doesn't have a consistent output for various types of solutions\n+   It needs to return a lot of types of solutions consistently:\n+\n+   * single solution : `x == 1`\n+   * Multiple solutions: `x^2 == 1`\n+   * No Solution: `x^2 + 1 == 0` ; x is real\n+   * Interval of solution: `floor(x) == 0`\n+   * Infinitely many solutions: `sin(x) == 0`\n+   * Multivariate functions with point solutions: `x^2 + y^2 == 0`\n+   * Multivariate functions with non point solution: `x^2 + y^2 == 1`\n+   * System of equations: `x + y == 1` and `x - y == 0`\n+   * Relational: `x > 0`\n+   * And the most important case \"We don't Know\"\n+\n+2. The input API is also a mess, there are a lot of parameters. Many of them\n+   are not needed and they make it hard for the user and the developers to\n+   work on solvers.\n+\n+3. There are cases like finding the maxima and minima of function using\n+   critical points where it is important to know if it has returned all the\n+   solutions. ``solve`` does not guarantee this.\n+\n+\n+Why Solveset?\n+-------------\n+\n+* ``solveset`` has a cleaner input and output interface: ``solveset`` returns\n+  a set object and a set object takes care of all types of output. For\n+  cases where it doesn't \"know\" all the solutions a `ConditionSet` with partial\n+  solution is returned. For input it only takes the equation, the variables\n+  to solve for & the optional argument `domain` in which the equations has to\n+  be solved.\n+\n+* ``solveset`` can return infinitely many solutions. For example solving for\n+  `sin(x) = 0` returns `\\{2 n \\pi \\| n \\in \\mathbb{Z}\\} \\cup \\{2 n \\pi + \\pi \\| n \\in \\mathbb{Z}\\}`, whereas `solve`\n+  only returns [0, π].\n+\n+* There is a clear code level and interface level separation between solvers\n+  for equations in complex domain and equations in real domain. For example\n+  solving `exp(x) == 1` when `x` is to be solved in complex `domain`, returns\n+  the set of all solutions that is `\\{2 n i \\pi \\| n \\in \\mathbb{Z}\\}`, whereas if `x` is to be\n+  solved in the Real `domain` then only `\\{0\\}` is returned.\n+\n+\n+Why do we use Sets as an output type?\n+-------------------------------------\n+\n+SymPy has a well developed sets module, which can represent most of the set\n+containers in Mathematics such as:\n+\n+ * ``FiniteSet``\n+   Represents a finite set of discrete numbers.\n+\n+ * ``Interval`` \n+   Represents a real interval as a Set.\n+\n+ * ``ProductSet``\n+   Represents a Cartesian Product of Sets.\n+\n+ * ``ImageSet``\n+   Represents the Image of a set under a mathematical function\n+\n+    >>> from sympy import ImageSet, S, Lambda\n+    >>> from sympy.abc import x\n+    >>> from sympy.sets import ImageSet\n+    >>> squares = ImageSet(Lambda(x, x**2), S.Naturals)  # {x**2 for x in N}\n+    >>> 4 in squares\n+    True\n+\n+ * ``ComplexPlane``\n+   Represents the Set of all Complex Numbers\n+\n+ * ``ConditionSet``\n+   Represents the Set of elements which satisfies a given condition\n+\n+Also, the predefined set classes such as:\n+\n+ * ``Naturals`` `\\mathbb{N}`\n+   Represents the natural numbers (or counting numbers) which are all\n+   positive integers starting from 1 \n+\n+ * ``Naturals0`` `\\mathbb{W}`\n+   Represents the whole numbers which are all the non-negative integers,\n+   inclusive of zero\n+\n+ * ``Integers`` `\\mathbb{Z}`\n+   Represents all integers: positive, negative and zero. This set is also\n+   available as the Singleton, ``S.Integers``.\n+\n+ * ``Reals`` `\\mathbb{R}`\n+   Represents the Set of all Real numbers.\n+\n+ * ``Complexes`` `\\mathbb{C}`\n+   Represents the Set of all Complex numbers.\n+\n+It is capable of most of the set operations in Mathematics:\n+\n+ * ``Union``\n+ * ``Intersection``\n+ * ``Complement``\n+ * ``SymmetricDifference``\n+\n+The main reason for using sets as output to solvers is that it can consistently\n+represent many types of solutions. For single variable case it can represent:\n+\n+ * No solution (by null set)\n+\n+ * Finitely many solutions (by FiniteSet)\n+\n+ * Infinitely many solutions, both countably and uncountably infinite solutions\n+   (using the ImageSet module) Interval\n+\n+ * There can also be bizarre solutions to equations like set of all rational number.\n+\n+No other programmer's object (list, dictionary, python sets) provides the\n+flexibility of mathematical sets which our sets module try to emulate. The\n+second reason to use sets is that they are close to the entities which\n+mathematician's deals with and it makes it easier to reason about them.\n+Another advantage of using objects closer to mathematical entities is that the\n+user won't have to \"learn\" our representation and she can have her expectations\n+transferred from her mathematical experience.\n+\n+For multivariate case we are representing solutions as a set of points in a\n+n-dimensional space and a point is represented by a FiniteSet of ordered tuple.\n+Please Note that, the General FiniteSet is unordered, but a FiniteSet with\n+a tuple as it's first argument is ordered. For example:\n+\n+ - ``FiniteSet(1, 2, 3) : {1, 2, 3}``   # Unordered\n+ - ``FiniteSet((1, 2, 3)) {(1, 2, 3)}``  # Ordered\n+\n+\n+Why not use Dictionary as Output?\n+\n+  Dictionary are easy to deal with programatically but mathematically they are\n+  not very precise and use of them can quickly lead to inconsistency and a lot\n+  of confusion. For example addition of two solutions is a fairly valid\n+  operation but dictionaries by themselves have no add operation. Since we are\n+  representing solutions as dictionary we can define a custom add operation\n+  where value of `x` variable is added with value of other `x` variable and\n+  value of `y` variable with the value of other `y` variable. But what if the user\n+  tries to add solution of two equations which have different sets of variables?\n+  Say one has `x` and `y` as variables and other has `u` and `v`? We cannot allow this\n+  addition because the keys of dictionaries are unordered but this behavior will\n+  be inconsistent with the one variable case because it will be absurd to not to\n+  allow addition of two numbers, say one obtained by solution of `x = 1` and\n+  other by solving `y = 2`.\n+\n+\n+\n+Input API of `Solveset`\n+-----------------------\n+\n+``solveset`` has a cleaner input API, unlike ``solve``, It takes a maximum\n+of three arguments:\n+\n+* Equation(s)\n+  The equation(s) to solve.\n+\n+* Variable(s)\n+  The variable(s) for which the equation is to be solved.\n+\n+* domain\n+  The domain in which the equation is to be solved.\n+\n+\n+ ``solveset`` removes the ``flags`` argument of ``solve``, which had made\n+ the input API messy and output API inconsistent in ``solve``.\n+\n+\n+What is this domain argument about?\n+-----------------------------------\n+\n+ Solveset is designed to be independent of the assumptions on the\n+ variable being solved for and instead, uses the ``domain`` argument to\n+ decide the solver to dispatch the equation to, namely ``solveset\\_real``\n+ or ``solveset\\_complex``. It's unlike the old ``solve`` which considers the\n+ assumption on the variable.\n+\n+    >>> from sympy.solvers.solveset import solveset\n+    >>> from sympy.abc import x\n+    >>> from sympy import S\n+    >>> solveset(x**2 + 1, x) # domain=S.Complexes is default\n+    {-I, I}\n+    >>> solveset(x**2 + 1, x, domain=S.Reals)\n+    EmptySet()\n+\n+\n+What are the general methods employed by solveset to solve an equation?\n+-----------------------------------------------------------------------\n+\n+ Solveset uses various methods to solve an equation, here is a brief overview\n+ of the methodology:\n+\n+ * The ``domain`` argument is first considered to know the domain in which\n+   the user is interested to get the solution.\n+\n+ * If the given function is a relational (`>=`, `<=`, `>`, `<`), and the\n+   domain is real, then `solve\\_univariate\\_inequality` and solutions are\n+   returned. Solving for complex inequalities are not supported yet.\n+\n+\n+ * Based on the ``domain``, the equation is dispatched to one of the two\n+   functions ``solveset\\_real`` or ``solveset\\_complex``, which solves the\n+   given equation in complex and real domain respectively.\n+\n+ * If the given function (equation) is a product of two or more functions,\n+   like say `f = g*h`, then the solution to the given equation is the Union\n+   of the solution of the equations `g = 0` and `h = 0`, if and only if both\n+   `g` and `h` are finite for a finite input. So, the solution is build up\n+   recursively.\n+\n+ * The function class is now checked if it's Trigonometric or Hyperbolic, then\n+   the function ``\\_solve\\_real\\_trig`` is called, which solves it by converting\n+   it in terms of ``exp`` complex exponential form.\n+\n+ * The function is now checked if there is any instance of Piecewise\n+   expression, if it is, then it's converted to explict expression and\n+   set pairs and then solved recursively.\n+\n+ * The respective solvers now tries to invert the equation using the routines\n+   ``invert\\_real`` and ``invert\\_complex``.\n+\n+ * After the invert, the equations are checked for radical or Abs (Modulus),\n+   then the method ``\\_solve\\_radical`` tries to simplify the radical, by\n+   removing it using techniques like squarring, cubing etc, and ``\\_solve\\_abs``\n+   solves nested Modulus by considering the positive and negative variants,\n+   iteratively.\n+\n+ * If none of the above method is successful, then method of polynomial is\n+   used as follows:\n+\n+   - ``\\_solve\\_as\\_rational`` is called, it's third argument is the\n+     ``solveset\\_solver`` which can either be ``solveset_real`` or\n+     ``solveset\\_complex`` based on these respective poly solvers\n+     ``\\_solve\\_as\\_poly\\_real`` and ``\\_solve\\_as\\_poly\\_complex`` is called.\n+\n+   - The underlying method ``\\_solve\\_as\\_poly`` solves the equation using\n+     polynomial techniques if it already is a polynomial equation or, with\n+     a change of variables, can be made so.\n+\n+ * The Final solution set obtained is taken intersection with the input\n+   domain, and the resultant solution is returned.\n+\n+.. Remember to change the above part when the new solver is implemented.\n+\n+\n+How do we manipulate and return an infinite solution?\n+-----------------------------------------------------\n+\n+ * In Real Domain, we use our ``ImageSet`` class in the sets module to\n+   return infinite solutions. ``ImageSet`` is an Image of a set under\n+   a mathematical function. For example, to represent the solution\n+   of the equation `sin(x) == 0`, we can use the ImageSet as:\n+\n+   ``ImageSet(Lambda(n, 2*n*pi), Integers())``\n+\n+   Where n is a dummy variable. It is basically the image of the\n+   Integers set under the function `2*n*pi`.\n+\n+ * In Complex Domain, we use Complex Sets, which is implemented as\n+   ``ComplexPlane`` class in the sets module, to represent infinite\n+   solution in the argand plane. For example to represent the solution\n+   of the equation `|z| == 1`, which is a unit circle, we can use\n+   the ComplexPlane as:\n+\n+   ``ComplexPlane(FiniteSet(1)*Interval(0, 2*pi), polar=True)``\n+\n+   Where the ``FiniteSet`` in the ``ProductSet`` is the range of the value of `r`,\n+   which is the radius of the circle and the ``Interval`` is the range of theta,\n+   representing a unit circle in the argand plane.\n+\n+   Note: We also have non-polar form notation for representing solution\n+   in rectangular form. For example, to represent first quadrant in argand\n+   plane, we can write the ComplexPlane as:\n+\n+   ``ComplexPlane(Interval(0, oo)*Interval(0, oo))``\n+\n+   where the Intervals are the range of `x` and `y` for the set of complex\n+   number `(x + I*y)`.\n+\n+\n+How does solveset ensures that it is not returning any wrong solution?\n+----------------------------------------------------------------------\n+\n+ Solvers in a Computer Algebra System are based on heuristics algorithms,\n+ so it's usually very hard to ensure cent percent correctness, in every\n+ possible case. However there are still a lot of cases where we can ensure\n+ correctness. Solveset tries to verify correctness wherever it can for\n+ example:\n+\n+ Consider the equation `|x| = n`, a naive method to solve this equation\n+ would return {-n, n} as it's solution, which is not correct since {-n, n}\n+ can only be it's solution if and only if n is positive. Solveset returns\n+ this information as well to ensure correctness.\n+\n+    >>> from sympy.solvers.solveset import solveset\n+    >>> from sympy import symbols, S\n+    >>> x, n = symbols('x, n')\n+    >>> solveset(abs(x) - n, x, domain=S.Reals)\n+    Intersection([0, oo), {n}) U Intersection((-oo, 0], {-n})\n+\n+ Though, there still a lot of work needs to be done in this regard.\n+\n+\n+Search Based solver & Step by Step Solution\n+-------------------------------------------\n+\n+ Note: This is under Development.\n+\n+ After the introduction of ``ConditionSet`` [10], the solving of equations can be\n+ seen as set transformation, We can do the following things to solve equations\n+ (abstract View):\n+\n+ * Apply Various Set Transformations on the given Set.\n+ * Define a Metric of the usability or define a notion of better solution over others.\n+ * Different Transformation would be the nodes of the tree.\n+ * Suitable searching techniques could be applied to get the best solution.\n+\n+ ConditionSet gives us the ability to represent unevaluated equations and\n+ inequalities in forms like `{x|f(x)=0; x in S}` and `{x|f(x)>0; x in S}`\n+ but a more powerful thing about ConditionSet is that it allows us to write\n+ the intermediate steps as set to set transformation. Some of the transformations\n+ are:\n+\n+ * Composition: `{x|f(g(x))=0;x in S} => {x|g(x)=y; x in S,y in {z|f(z)=0; z in S}}`\n+\n+ * Polynomial Solver: `{x|P(x)=0;x in S} => {x_1,x_2, ... ,x_n}.intersection(S)`\n+   where `x_i` are roots of P(x)\n+\n+ * Invert solver: `{x|f(x)=0;x in S} => {g(0)| all g such that f(g(x)) = x}`\n+\n+ * logcombine: `{x| log(f(x)) + log(g(x));x in S}`\n+                => `{x| log(f(x)*g(x)); x in S}` if f(x) > 0 and g(x) > 0\n+                => `{x| log(f(x)) + log(g(x));x in S}` otherwise\n+\n+ * product solve: {x|f(x)*g(x)=0; x in S}\n+                => `{x|f(x)=0; x in S} U {x|g(x)=0; x in S}` given f(x) and g(x) are bounded\n+                => {x|f(x)*g(x)=0; x in S}, otherwise\n+\n+ Since the output type is same as input type any composition of these\n+ transformations is also a valid transformation. And our aim is to find\n+ the right sequence of compositions (given the atoms) which transforms\n+ the given condition set to a set which is not a condition set i.e.,\n+ FiniteSet, Interval, Set of Integers and their Union, Intersection,\n+ Complement or ImageSet. We can assign a cost function to each set,\n+ such that, more desirable that form of set is to us, the less the value\n+ of cost function. This way our problem is now reduced to finding the path\n+ from the initial ConditionSet to the lowest valued set on a graph where\n+ the atomic transformations forms the edges.\n+\n+\n+How do we deal with cases where only some of the solutions are known?\n+---------------------------------------------------------------------\n+\n+ Creating a Universal equation solver, which can solve each and every\n+ equation we encounter in mathematics is an ideal case for solvers in\n+ a Computer Algebra System. We always have some cases, which are not\n+ solved, or solved with incomplete solutions, so it's very important\n+ to represent that situation. For this type of situation we use\n+ `ConditionSet` class in the sets module, which acts as an unevaluated\n+ solveset object.\n+\n+ ConditionSet is basically a Set of elements which satisfies a given\n+ condition. For example, to represent the solutions of the Equation\n+ in Real domain:\n+\n+ .. math::  (x^2 - 4)*(sin(x) + x)\n+\n+ We can represent it as:\n+\n+ `{-2, 2} ∪ {x | x ∊ ℝ ∧ x + sin(x) = 0}`\n+\n+\n+What will you do with the old solve?\n+------------------------------------\n+\n+ There is still a few things `solveset` can't do, which the old `solve`","path":"doc/src/modules/solvers/solveset.rst","position":394,"original_position":394,"commit_id":"94b5be433d56cbd7567ab7bab69190d74342f04c","original_commit_id":"94b5be433d56cbd7567ab7bab69190d74342f04c","user":{"login":"asmeurer","id":71486,"avatar_url":"https://avatars.githubusercontent.com/u/71486?v=3","gravatar_id":"","url":"https://api.github.com/users/asmeurer","html_url":"https://github.com/asmeurer","followers_url":"https://api.github.com/users/asmeurer/followers","following_url":"https://api.github.com/users/asmeurer/following{/other_user}","gists_url":"https://api.github.com/users/asmeurer/gists{/gist_id}","starred_url":"https://api.github.com/users/asmeurer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asmeurer/subscriptions","organizations_url":"https://api.github.com/users/asmeurer/orgs","repos_url":"https://api.github.com/users/asmeurer/repos","events_url":"https://api.github.com/users/asmeurer/events{/privacy}","received_events_url":"https://api.github.com/users/asmeurer/received_events","type":"User","site_admin":false},"body":"\\`\\`solveset\\`\\` and \\`\\`solve\\`\\` (two backquotes)","created_at":"2015-08-24T22:26:33Z","updated_at":"2015-08-24T22:26:33Z","html_url":"https://github.com/sympy/sympy/pull/9500#discussion_r37812623","pull_request_url":"https://api.github.com/repos/sympy/sympy/pulls/9500","_links":{"self":{"href":"https://api.github.com/repos/sympy/sympy/pulls/comments/37812623"},"html":{"href":"https://github.com/sympy/sympy/pull/9500#discussion_r37812623"},"pull_request":{"href":"https://api.github.com/repos/sympy/sympy/pulls/9500"}}},"pull_request":{"url":"https://api.github.com/repos/sympy/sympy/pulls/9500","id":37337778,"html_url":"https://github.com/sympy/sympy/pull/9500","diff_url":"https://github.com/sympy/sympy/pull/9500.diff","patch_url":"https://github.com/sympy/sympy/pull/9500.patch","issue_url":"https://api.github.com/repos/sympy/sympy/issues/9500","number":9500,"state":"open","locked":false,"title":"[WIP] Documenting Solveset","user":{"login":"aktech","id":5647941,"avatar_url":"https://avatars.githubusercontent.com/u/5647941?v=3","gravatar_id":"","url":"https://api.github.com/users/aktech","html_url":"https://github.com/aktech","followers_url":"https://api.github.com/users/aktech/followers","following_url":"https://api.github.com/users/aktech/following{/other_user}","gists_url":"https://api.github.com/users/aktech/gists{/gist_id}","starred_url":"https://api.github.com/users/aktech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aktech/subscriptions","organizations_url":"https://api.github.com/users/aktech/orgs","repos_url":"https://api.github.com/users/aktech/repos","events_url":"https://api.github.com/users/aktech/events{/privacy}","received_events_url":"https://api.github.com/users/aktech/received_events","type":"User","site_admin":false},"body":"As lot of people are not aware of the purpose of `solveset` , to answer questions like *why we are doing, what we are doing*,  We decided to open a PR , to document it. Where the community can participate and give their views and suggestions.\r\n\r\n**TODO**\r\n- [x] Move docs to sphinx docs\r\n\r\nThe documentation should answer the following questions either explicitly or implicitly:\r\n- [x] What was the need of a new solvers module?\r\n- [x] Why do we use sets as an output type?\r\n- [x] What is this `domain` argument about?\r\n- [x] What will you do with the old `solve`?\r\n- [x] What are the general design principles behind the development of solveset?\r\n- [x] What are the general methods employed by solveset to solve an equation?\r\n- [x] How do we manipulate and return an infinite solutions?\r\n- [x] How does solveset ensures that it is not returning any wrong solution?\r\n- [x] How are symbolic parameters handled in solveset?\r\n- [ ] What is future direction of the development of solveset?\r\n- [x] How do we deal with cases where only some of the solutions are known?","created_at":"2015-06-10T09:05:54Z","updated_at":"2015-08-24T22:26:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"173c12a2bb60672e52ed14422c02352e755eec42","assignee":{"login":"aktech","id":5647941,"avatar_url":"https://avatars.githubusercontent.com/u/5647941?v=3","gravatar_id":"","url":"https://api.github.com/users/aktech","html_url":"https://github.com/aktech","followers_url":"https://api.github.com/users/aktech/followers","following_url":"https://api.github.com/users/aktech/following{/other_user}","gists_url":"https://api.github.com/users/aktech/gists{/gist_id}","starred_url":"https://api.github.com/users/aktech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aktech/subscriptions","organizations_url":"https://api.github.com/users/aktech/orgs","repos_url":"https://api.github.com/users/aktech/repos","events_url":"https://api.github.com/users/aktech/events{/privacy}","received_events_url":"https://api.github.com/users/aktech/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/sympy/sympy/milestones/44","html_url":"https://github.com/sympy/sympy/milestones/GSoC%202015%20Solveset%20/%20Sets%20Infrastructure","labels_url":"https://api.github.com/repos/sympy/sympy/milestones/44/labels","id":1185328,"number":44,"title":"GSoC 2015 Solveset / Sets Infrastructure","description":"This includes all the work related to this proposal: https://github.com/sympy/sympy/wiki/GSoC-2015-Application-AMiT-Kumar--Solvers-:-Extending-Solveset","creator":{"login":"aktech","id":5647941,"avatar_url":"https://avatars.githubusercontent.com/u/5647941?v=3","gravatar_id":"","url":"https://api.github.com/users/aktech","html_url":"https://github.com/aktech","followers_url":"https://api.github.com/users/aktech/followers","following_url":"https://api.github.com/users/aktech/following{/other_user}","gists_url":"https://api.github.com/users/aktech/gists{/gist_id}","starred_url":"https://api.github.com/users/aktech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aktech/subscriptions","organizations_url":"https://api.github.com/users/aktech/orgs","repos_url":"https://api.github.com/users/aktech/repos","events_url":"https://api.github.com/users/aktech/events{/privacy}","received_events_url":"https://api.github.com/users/aktech/received_events","type":"User","site_admin":false},"open_issues":3,"closed_issues":29,"state":"open","created_at":"2015-06-29T14:03:27Z","updated_at":"2015-08-22T22:37:08Z","due_on":"2015-08-27T18:30:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/sympy/sympy/pulls/9500/commits","review_comments_url":"https://api.github.com/repos/sympy/sympy/pulls/9500/comments","review_comment_url":"https://api.github.com/repos/sympy/sympy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/sympy/sympy/issues/9500/comments","statuses_url":"https://api.github.com/repos/sympy/sympy/statuses/94b5be433d56cbd7567ab7bab69190d74342f04c","head":{"label":"aktech:document-solveset","ref":"document-solveset","sha":"94b5be433d56cbd7567ab7bab69190d74342f04c","user":{"login":"aktech","id":5647941,"avatar_url":"https://avatars.githubusercontent.com/u/5647941?v=3","gravatar_id":"","url":"https://api.github.com/users/aktech","html_url":"https://github.com/aktech","followers_url":"https://api.github.com/users/aktech/followers","following_url":"https://api.github.com/users/aktech/following{/other_user}","gists_url":"https://api.github.com/users/aktech/gists{/gist_id}","starred_url":"https://api.github.com/users/aktech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aktech/subscriptions","organizations_url":"https://api.github.com/users/aktech/orgs","repos_url":"https://api.github.com/users/aktech/repos","events_url":"https://api.github.com/users/aktech/events{/privacy}","received_events_url":"https://api.github.com/users/aktech/received_events","type":"User","site_admin":false},"repo":{"id":28193645,"name":"sympy","full_name":"aktech/sympy","owner":{"login":"aktech","id":5647941,"avatar_url":"https://avatars.githubusercontent.com/u/5647941?v=3","gravatar_id":"","url":"https://api.github.com/users/aktech","html_url":"https://github.com/aktech","followers_url":"https://api.github.com/users/aktech/followers","following_url":"https://api.github.com/users/aktech/following{/other_user}","gists_url":"https://api.github.com/users/aktech/gists{/gist_id}","starred_url":"https://api.github.com/users/aktech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aktech/subscriptions","organizations_url":"https://api.github.com/users/aktech/orgs","repos_url":"https://api.github.com/users/aktech/repos","events_url":"https://api.github.com/users/aktech/events{/privacy}","received_events_url":"https://api.github.com/users/aktech/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/aktech/sympy","description":"A computer algebra system written in pure Python","fork":true,"url":"https://api.github.com/repos/aktech/sympy","forks_url":"https://api.github.com/repos/aktech/sympy/forks","keys_url":"https://api.github.com/repos/aktech/sympy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aktech/sympy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aktech/sympy/teams","hooks_url":"https://api.github.com/repos/aktech/sympy/hooks","issue_events_url":"https://api.github.com/repos/aktech/sympy/issues/events{/number}","events_url":"https://api.github.com/repos/aktech/sympy/events","assignees_url":"https://api.github.com/repos/aktech/sympy/assignees{/user}","branches_url":"https://api.github.com/repos/aktech/sympy/branches{/branch}","tags_url":"https://api.github.com/repos/aktech/sympy/tags","blobs_url":"https://api.github.com/repos/aktech/sympy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aktech/sympy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aktech/sympy/git/refs{/sha}","trees_url":"https://api.github.com/repos/aktech/sympy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aktech/sympy/statuses/{sha}","languages_url":"https://api.github.com/repos/aktech/sympy/languages","stargazers_url":"https://api.github.com/repos/aktech/sympy/stargazers","contributors_url":"https://api.github.com/repos/aktech/sympy/contributors","subscribers_url":"https://api.github.com/repos/aktech/sympy/subscribers","subscription_url":"https://api.github.com/repos/aktech/sympy/subscription","commits_url":"https://api.github.com/repos/aktech/sympy/commits{/sha}","git_commits_url":"https://api.github.com/repos/aktech/sympy/git/commits{/sha}","comments_url":"https://api.github.com/repos/aktech/sympy/comments{/number}","issue_comment_url":"https://api.github.com/repos/aktech/sympy/issues/comments{/number}","contents_url":"https://api.github.com/repos/aktech/sympy/contents/{+path}","compare_url":"https://api.github.com/repos/aktech/sympy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aktech/sympy/merges","archive_url":"https://api.github.com/repos/aktech/sympy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aktech/sympy/downloads","issues_url":"https://api.github.com/repos/aktech/sympy/issues{/number}","pulls_url":"https://api.github.com/repos/aktech/sympy/pulls{/number}","milestones_url":"https://api.github.com/repos/aktech/sympy/milestones{/number}","notifications_url":"https://api.github.com/repos/aktech/sympy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aktech/sympy/labels{/name}","releases_url":"https://api.github.com/repos/aktech/sympy/releases{/id}","created_at":"2014-12-18T17:24:39Z","updated_at":"2015-04-24T19:03:04Z","pushed_at":"2015-08-24T17:27:40Z","git_url":"git://github.com/aktech/sympy.git","ssh_url":"git@github.com:aktech/sympy.git","clone_url":"https://github.com/aktech/sympy.git","svn_url":"https://github.com/aktech/sympy","homepage":"http://sympy.org/","size":73106,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"sympy:master","ref":"master","sha":"675648788733e812cd2f0ffe74116923b3f23166","user":{"login":"sympy","id":260832,"avatar_url":"https://avatars.githubusercontent.com/u/260832?v=3","gravatar_id":"","url":"https://api.github.com/users/sympy","html_url":"https://github.com/sympy","followers_url":"https://api.github.com/users/sympy/followers","following_url":"https://api.github.com/users/sympy/following{/other_user}","gists_url":"https://api.github.com/users/sympy/gists{/gist_id}","starred_url":"https://api.github.com/users/sympy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sympy/subscriptions","organizations_url":"https://api.github.com/users/sympy/orgs","repos_url":"https://api.github.com/users/sympy/repos","events_url":"https://api.github.com/users/sympy/events{/privacy}","received_events_url":"https://api.github.com/users/sympy/received_events","type":"Organization","site_admin":false},"repo":{"id":640534,"name":"sympy","full_name":"sympy/sympy","owner":{"login":"sympy","id":260832,"avatar_url":"https://avatars.githubusercontent.com/u/260832?v=3","gravatar_id":"","url":"https://api.github.com/users/sympy","html_url":"https://github.com/sympy","followers_url":"https://api.github.com/users/sympy/followers","following_url":"https://api.github.com/users/sympy/following{/other_user}","gists_url":"https://api.github.com/users/sympy/gists{/gist_id}","starred_url":"https://api.github.com/users/sympy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sympy/subscriptions","organizations_url":"https://api.github.com/users/sympy/orgs","repos_url":"https://api.github.com/users/sympy/repos","events_url":"https://api.github.com/users/sympy/events{/privacy}","received_events_url":"https://api.github.com/users/sympy/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sympy/sympy","description":"A computer algebra system written in pure Python","fork":false,"url":"https://api.github.com/repos/sympy/sympy","forks_url":"https://api.github.com/repos/sympy/sympy/forks","keys_url":"https://api.github.com/repos/sympy/sympy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sympy/sympy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sympy/sympy/teams","hooks_url":"https://api.github.com/repos/sympy/sympy/hooks","issue_events_url":"https://api.github.com/repos/sympy/sympy/issues/events{/number}","events_url":"https://api.github.com/repos/sympy/sympy/events","assignees_url":"https://api.github.com/repos/sympy/sympy/assignees{/user}","branches_url":"https://api.github.com/repos/sympy/sympy/branches{/branch}","tags_url":"https://api.github.com/repos/sympy/sympy/tags","blobs_url":"https://api.github.com/repos/sympy/sympy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sympy/sympy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sympy/sympy/git/refs{/sha}","trees_url":"https://api.github.com/repos/sympy/sympy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sympy/sympy/statuses/{sha}","languages_url":"https://api.github.com/repos/sympy/sympy/languages","stargazers_url":"https://api.github.com/repos/sympy/sympy/stargazers","contributors_url":"https://api.github.com/repos/sympy/sympy/contributors","subscribers_url":"https://api.github.com/repos/sympy/sympy/subscribers","subscription_url":"https://api.github.com/repos/sympy/sympy/subscription","commits_url":"https://api.github.com/repos/sympy/sympy/commits{/sha}","git_commits_url":"https://api.github.com/repos/sympy/sympy/git/commits{/sha}","comments_url":"https://api.github.com/repos/sympy/sympy/comments{/number}","issue_comment_url":"https://api.github.com/repos/sympy/sympy/issues/comments{/number}","contents_url":"https://api.github.com/repos/sympy/sympy/contents/{+path}","compare_url":"https://api.github.com/repos/sympy/sympy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sympy/sympy/merges","archive_url":"https://api.github.com/repos/sympy/sympy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sympy/sympy/downloads","issues_url":"https://api.github.com/repos/sympy/sympy/issues{/number}","pulls_url":"https://api.github.com/repos/sympy/sympy/pulls{/number}","milestones_url":"https://api.github.com/repos/sympy/sympy/milestones{/number}","notifications_url":"https://api.github.com/repos/sympy/sympy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sympy/sympy/labels{/name}","releases_url":"https://api.github.com/repos/sympy/sympy/releases{/id}","created_at":"2010-04-30T20:37:14Z","updated_at":"2015-08-24T20:51:57Z","pushed_at":"2015-08-24T18:37:09Z","git_url":"git://github.com/sympy/sympy.git","ssh_url":"git@github.com:sympy/sympy.git","clone_url":"https://github.com/sympy/sympy.git","svn_url":"https://github.com/sympy/sympy","homepage":"http://sympy.org/","size":158150,"stargazers_count":2302,"watchers_count":2302,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1114,"mirror_url":null,"open_issues_count":1962,"forks":1114,"open_issues":1962,"watchers":2302,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/sympy/sympy/pulls/9500"},"html":{"href":"https://github.com/sympy/sympy/pull/9500"},"issue":{"href":"https://api.github.com/repos/sympy/sympy/issues/9500"},"comments":{"href":"https://api.github.com/repos/sympy/sympy/issues/9500/comments"},"review_comments":{"href":"https://api.github.com/repos/sympy/sympy/pulls/9500/comments"},"review_comment":{"href":"https://api.github.com/repos/sympy/sympy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/sympy/sympy/pulls/9500/commits"},"statuses":{"href":"https://api.github.com/repos/sympy/sympy/statuses/94b5be433d56cbd7567ab7bab69190d74342f04c"}}}}