{
  "__type": "IngestedDoc",
  "__tag": 4010,
  "_content": {
    "Notes": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Given data "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "y"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and case weights "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "w"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", the isotonic regression solves the following optimization problem:"
            }
          ]
        },
        {
          "__type": "Math",
          "__tag": 4058,
          "value": "\\operatorname{argmin}_{x_i} \\sum_i w_i (y_i - x_i)^2 \\quad\n\\text{subject to } x_i \\leq x_j \\text{ whenever } i \\leq j \\,."
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "For every input value "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "y_i"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", it generates a value "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x_i"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " such that "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " is increasing (but not strictly), i.e. "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x_i \\leq x_{i+1}"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". This is accomplished by the PAVA. The solution consists of pools or blocks, i.e. neighboring elements of "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", e.g. "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x_i"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x_{i+1}"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", that all have the same value."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Most interestingly, the solution stays the same if the squared loss is replaced by the wide class of Bregman functions which are the unique class of strictly consistent scoring functions for the mean, see "
            },
            {
              "__type": "FootnoteReference",
              "__tag": 4066,
              "label": "2"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and references therein."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The implemented version of PAVA according to "
            },
            {
              "__type": "FootnoteReference",
              "__tag": 4066,
              "label": "1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " has a computational complexity of O(N) with input size N."
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Warns": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Raises": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Yields": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Methods": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Returns": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Parameters",
          "__tag": 4026,
          "children": [
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "res",
              "annotation": "OptimizeResult",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The optimization result represented as a "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "OptimizeResult"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " object. Important attributes are:"
                    }
                  ]
                },
                {
                  "__type": "BulletList",
                  "__tag": 4053,
                  "ordered": false,
                  "start": 1,
                  "children": [
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "x"
                            },
                            {
                              "__type": "Text",
                              "__tag": 4046,
                              "value": ": The isotonic regression solution, i.e. an increasing (or   decreasing) array of the same length than y, with elements in the   range from min(y) to max(y)."
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "weights"
                            },
                            {
                              "__type": "Text",
                              "__tag": 4046,
                              "value": "Array with the sum of case weights for each block   (or pool) B."
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "blocks"
                            },
                            {
                              "__type": "Text",
                              "__tag": 4046,
                              "value": ": Array of length B+1 with the indices of the start   positions of each block (or pool) B. The j-th block is given by   "
                            },
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "x[blocks[j]:blocks[j+1]]"
                            },
                            {
                              "__type": "Text",
                              "__tag": 4046,
                              "value": " for which all values are the same."
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Summary": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Nonparametric isotonic regression."
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Receives": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Warnings": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Attributes": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Parameters": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Parameters",
          "__tag": 4026,
          "children": [
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "y",
              "annotation": "(N,) array_like",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Response variable."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "weights",
              "annotation": "(N,) array_like or None",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Case weights."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "increasing",
              "annotation": "bool",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "If True, fit monotonic increasing, i.e. isotonic, regression. If False, fit a monotonic decreasing, i.e. antitonic, regression. Default is True."
                    }
                  ]
                }
              ]
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Extended Summary": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "A (not strictly) monotonically increasing array "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "x",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " with the same length as "
            },
            {
              "__type": "ParamRef",
              "__tag": 4071,
              "name": "y"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " is calculated by the pool adjacent violators algorithm (PAVA), see "
            },
            {
              "__type": "FootnoteReference",
              "__tag": 4066,
              "label": "1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". See the Notes section for more details."
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Other Parameters": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    }
  },
  "_ordered_sections": [
    "Summary",
    "Extended Summary",
    "Parameters",
    "Attributes",
    "Methods",
    "Returns",
    "Yields",
    "Receives",
    "Other Parameters",
    "Raises",
    "Warns",
    "Warnings",
    "Notes"
  ],
  "item_file": "/scipy/optimize/_isotonic.py",
  "item_line": 15,
  "item_type": "function",
  "aliases": [
    "scipy.optimize.isotonic_regression"
  ],
  "example_section_data": {
    "__type": "Section",
    "__tag": 4015,
    "children": [
      {
        "__type": "Text",
        "__tag": 4046,
        "value": "This example demonstrates that ``isotonic_regression`` really solves a\nconstrained optimization problem.\n\n"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "import numpy as np\nfrom scipy.optimize import isotonic_regression, minimize\ny = [1.5, 1.0, 4.0, 6.0, 5.7, 5.0, 7.8, 9.0, 7.5, 9.5, 9.0]\ndef objective(yhat, y):\n    return np.sum((yhat - y)**2)\ndef constraint(yhat, y):\n    # This is for a monotonically increasing regression.\n    return np.diff(yhat)\nresult = minimize(objective, x0=y, args=(y,),\n                  constraints=[{'type': 'ineq',\n                                'fun': lambda x: constraint(x, y)}])\n",
        "execution_status": "success"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "result.x\n",
        "execution_status": "failure"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "result = isotonic_regression(y)\n",
        "execution_status": "success"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "result.x\n",
        "execution_status": "failure"
      },
      {
        "__type": "Text",
        "__tag": 4046,
        "value": "\nThe big advantage of ``isotonic_regression`` compared to calling\n``minimize`` is that it is more user friendly, i.e. one does not need to\ndefine objective and constraint functions, and that it is orders of\nmagnitudes faster. On commodity hardware (in 2023), for normal distributed\ninput y of length 1000, the minimizer takes about 4 seconds, while\n``isotonic_regression`` takes about 200 microseconds."
      }
    ],
    "title": [],
    "level": 0,
    "target": null
  },
  "see_also": [],
  "signature": {
    "__type": "SignatureNode",
    "__tag": 4029,
    "kind": "function",
    "parameters": [
      {
        "__type": "SigParam",
        "__tag": 4030,
        "name": "y",
        "annotation": "npt.ArrayLike",
        "kind": "POSITIONAL_OR_KEYWORD",
        "default": {
          "__type": "Empty",
          "__tag": 4031
        }
      },
      {
        "__type": "SigParam",
        "__tag": 4030,
        "name": "weights",
        "annotation": "npt.ArrayLike | None",
        "kind": "KEYWORD_ONLY",
        "default": "None"
      },
      {
        "__type": "SigParam",
        "__tag": 4030,
        "name": "increasing",
        "annotation": "bool",
        "kind": "KEYWORD_ONLY",
        "default": "True"
      }
    ],
    "return_annotation": "OptimizeResult",
    "target_name": "isotonic_regression"
  },
  "references": [
    ".. [1] Busing, F. M. T. A. (2022).",
    "       Monotone Regression: A Simple and Fast O(n) PAVA Implementation.",
    "       Journal of Statistical Software, Code Snippets, 102(1), 1-25.",
    "       :doi:`10.18637/jss.v102.c01`",
    ".. [2] Jordan, A.I., Mühlemann, A. & Ziegel, J.F.",
    "       Characterizing the optimal solutions to the isotonic regression",
    "       problem for identifiable functionals.",
    "       Ann Inst Stat Math 74, 489-514 (2022).",
    "       :doi:`10.1007/s10463-021-00808-0`"
  ],
  "qa": "scipy.optimize._isotonic:isotonic_regression",
  "arbitrary": [],
  "local_refs": [
    "increasing",
    "res",
    "weights",
    "y"
  ]
}