# Source code for obspy.signal.regression

    # -*- coding: utf-8 -*-
    """
    Python Module for (Weighted) Linear Regression.

    :authors:
        Thomas Lecocq (thomas.lecocq@seismology.be)

    :copyright:
        The ObsPy Development Team (devs@obspy.org)
    :license:
        GNU Lesser General Public License, Version 3
        (https://www.gnu.org/copyleft/lesser.html)
    """

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    from future.builtins import *  # NOQA

    import numpy as np
    import scipy.optimize

    def linear_regression(xdata, ydata, weights=None, p0=None,
                          intercept_origin=True, **kwargs):
        """
        Use linear least squares to fit a function, f, to data.
        This method is a generalized version of
        :func:`scipy.optimize.minpack.curve_fit`; allowing for Ordinary Least
        Square and Weighted Least Square regressions:

        * OLS through origin: ``linear_regression(xdata, ydata)``
        * OLS with any intercept: ``linear_regression(xdata, ydata,
          intercept_origin=False)``
        * WLS through origin: ``linear_regression(xdata, ydata, weights)``
        * WLS with any intercept: ``linear_regression(xdata, ydata, weights,
          intercept_origin=False)``

        If the expected values of slope (and intercept) are different from 0.0,
        provide the p0 value(s).

        :param xdata: The independent variable where the data is measured.
        :param ydata: The dependent data - nominally f(xdata, ...)
        :param weights: If not None, the uncertainties in the ydata array. These
            are used as weights in the least-squares problem. If ``None``, the
            uncertainties are assumed to be 1. In SciPy vocabulary, our weights are
            1/sigma.
        :param p0: Initial guess for the parameters. If ``None``, then the initial
            values will all be 0 (Different from SciPy where all are 1)
        :param intercept_origin: If ``True``: solves ``y=a*x`` (default);
            if ``False``: solves ``y=a*x+b``.

        Extra keword arguments will be passed to
        :func:`scipy.optimize.minpack.curve_fit`.

        :rtype: tuple
        :returns: (slope, std_slope) if ``intercept_origin`` is ``True``;
            (slope, intercept, std_slope, std_intercept) if ``False``.
        """
        if weights is not None:
            sigma = 1. / weights
        else:
            sigma = None

        if p0 is None:
            if intercept_origin:
                p0 = 0.0
            else:
                p0 = [0.0, 0.0]

        if intercept_origin:
            p, cov = scipy.optimize.curve_fit(lambda x, a: a * x,
                                              xdata, ydata, p0, sigma=sigma,
                                              **kwargs)
            slope = p[0]
            std_slope = np.sqrt(cov[0, 0])
            return slope, std_slope

        else:
            p, cov = scipy.optimize.curve_fit(lambda x, a, b: a * x + b,
                                              xdata, ydata, p0, sigma=sigma,
                                              **kwargs)
            slope, intercept = p
            std_slope = np.sqrt(cov[0, 0])
            std_intercept = np.sqrt(cov[1, 1])
            return slope, intercept, std_slope, std_intercept

    if __name__ == '__main__':
        import doctest
        doctest.testmod(exclude_empty=True)

### Thank you!

We would like to thank our contributors, whose efforts make this software what it is. These people have helped by writing code and documentation, and by testing. They have created and maintained this product, its associated libraries and applications, our build tools and our web sites.

#### Contributors

- Ackerley, Nick
- Allgeyer, Sebastien
- Ammon, Charles J.
- Antunes, Emanuel
- Arnarsson, Ólafur St.
- Bank, Markus
- Barsch, Robert
- Behr, Yannik
- Bernardi, Fabrizio
- Bernauer, Felix
- Bes de Berc, Maxime
- Beyreuther, Moritz
- Boltz, Shawn
- Bonaimé, Sébastien
- Carothers, Lloyd
- Chamberlain, Calum
- Chambers, Derrick
- Chen, Zhao
- Clark, Adam
- Danecek, Peter
- Egdorf, Sven
- Engels, Fabian
- Ermert, Laura
- Eulenfeld, Tom

- Fabbri, Tommaso
- Falco, Nicholas
- Fee, Jeremy
- Grellier, Clément
- Grunberg, Marc
- Hammer, Conny
- Heimann, Sebastian
- Heiniger, Lukas
- Hope, Gaute
- Igel, Heiner
- Inza, Adolfo
- Isken, Marius
- Ketchum, David
- Koymans, Mathijs
- Kremers, Simon
- Kress, Victor
- Krieger, Lars
- Krischer, Lion
- Kula, Damian
- Käufl, Paul
- Köhler, Andreas
- Lecocq, Thomas
- Leeman, John
- Legovini, Paride

- Lesage, Philippe
- Li, Yulin
- Lomax, Anthony
- Lopes, Rui L.
- MacCarthy, Jonathan
- Maggi, Alessia
- Martin, Henri
- Medlin, Andrew
- Megies, Tobias
- Meschede, Matthias
- Michelini, Alberto
- Miller, Nathaniel C.
- Morgenstern, Bernhard
- Nof, Ran Novitsky
- Panning, Mark P.
- Parker, Tom
- Pestourie, Romain
- Rapagnani, Giovanni
- Reyes, Celso
- Ringler, Adam
- Rothenhäusler, Nicolas
- Russo, Emiliano
- Sales de Andrade, Elliott

- Satriano, Claudio
- Saul, Joachim
- Scheingraber, Chris
- Schneider, Simon
- Sippl, Christian
- Snoke, Arthur
- Stange, Stefan
- Stähler, Simon C.
- Sullivan, Benjamin
- Tian, Dongdong
- Trabant, Chad
- Trani, Luca
- Uieda, Leonardo
- Walker, Andrew
- Walther, Marcus
- Wassermann, Joachim
- Williams, Mark C.
- Winkelman, Andrew
- Zaccarelli, Riccardo
- Zad, Seyed Kasra Hosseini
- Zhu, Lijun
- van Driel, Martin
- van Wijk, Kasper

#### Funds

ObsPy was partially funded by the

- German Science Foundation (DFG) via grant DFG IG 16/9-1
- German Ministry for Education and Research (BMBF), GEOTECHNOLOGIEN grant 03G0646H.
- NERA project (Network of European Research Infrastructures for Earthquake Risk Assessment and Mitigation) under the European Community's Seventh Framework Programme (FP7/2007-2013) grant agreement n° 262330
- Leibniz Institute for Applied Geophysics (LIAG)
- VERCE EU-FP7 project (no. 283543)