<commit_before># -*- coding: utf-8 -*-

from statsmodels.base.model import Model
from .factor_rotation import rotate_factors, promax

try:
    import matplotlib.pyplot as plt
    missing_matplotlib = False
except ImportError:
    missing_matplotlib = True

if not missing_matplotlib:
    from .plots import plot_scree, plot_loadings

import numpy as np
from numpy.linalg import eigh, inv, norm, matrix_rank
import pandas as pd

from statsmodels.iolib import summary2

class Factor(Model):
    """
    Principle axis factor analysis

    .. [1] http://www.real-statistics.com/multivariate-statistics/
    factor-analysis/principal-axis-method/

    .. [2] http://stats.stackexchange.com/questions/102882/
    steps-done-in-factor-analysis-compared-to-steps-done-in-pca/102999#102999

    Supported rotations:
        'varimax', 'quartimax', 'biquartimax', 'equamax', 'oblimin',
        'parsimax', 'parsimony', 'biquartimin', 'promax'

    Parameters
    ----------
    endog : array-like
        Variables in columns, observations in rows

    n_factor : int
        The number of factors to extract

    """
    def __init__(self, endog, n_factor, exog=None, **kwargs):
        if n_factor <= 0:
            raise ValueError('n_factor must be larger than 0! %d < 0' %
                             (n_factor))
        if n_factor > endog.shape[1]:
            raise ValueError('n_factor must be smaller or equal to the number'
                             ' of columns of endog! %d > %d' %
                             (n_factor, endog.shape[1]))
        self.n_factor = n_factor
        self.loadings = None
        self.communality = None
        self.eigenvals = None
        super(Factor, self).__init__(endog, exog)

    def fit(self, n_max_iter=50, tolerance=1e-6, SMC=True):
        """
        Fit the factor model

        Parameters
        ----------
        n_max_iter : int
            Maximum number of iterations for communality estimation
        tolerance : float
            If `norm(communality - last_communality)  < tolerance`,
            estimation stops
        SMC : True or False
            Whether or not to apply squared multiple correlations

        -------

        """
        R = np.corrcoef(self.endog, rowvar=0)
        self.n_comp = matrix_rank(R)
        if self.n_factor > self.n_comp:
            raise ValueError('n_factor must be smaller or equal to the rank'
                             ' of endog! %d > %d' %
                             (self.n_factor, self.n_comp))
        if n_max_iter <= 0:
            raise ValueError('n_max_iter must be larger than 0! %d < 0' %
                             (n_max_iter))
        if tolerance <= 0 or tolerance > 0.01:
            raise ValueError('tolerance must be larger than 0 and smaller than'
                             ' 0.01! Got %f instead' % (tolerance))
        #  Initial communality estimation
        if SMC:
            c = 1 - 1 / np.diag(inv(R))
            self.SMC = np.array(c)
        else:
            c = np.ones([1, len(R)])

        # Iterative communality estimation
        eigenvals = None
        for i in range(n_max_iter):
            # Get eigenvalues/eigenvectors of R with diag replaced by
            # communality
            for j in range(len(R)):
                R[j, j] = c[j]
            L, V = eigh(R, UPLO='U')
            c_last = np.array(c)
            ind = np.argsort(L)
            ind = ind[::-1]
            L = L[ind]
            n_pos = (L > 0).sum()
            V = V[:, ind]
            eigenvals = np.array(L)

            # Select eigenvectors with positive eigenvalues
            n = np.min([n_pos, self.n_factor])
            sL = np.diag(np.sqrt(L[:n]))
            V = V[:, :n]

            # Calculate new loadings and communality
            A = V.dot(sL)
            c = np.power(A, 2).sum(axis=1)
            if norm(c_last - c) < tolerance:
                break
        self.eigenvals = eigenvals
        self.communality = c
        self.loadings = A
        return FactorResults(self)

class FactorResults(object):
    """
    Factor results class

    Parameters
    ----------
    factor : Factor
        Fitted Factor class

    """
    def __init__(self, factor):
        if not isinstance(factor, Factor):
            raise ValueError('Input must be a `Factor` class. Got %s instead'
                             % (factor.__str__))
        self.endog_names = factor.endog_names
        self.loadings_no_rot = factor.loadings
        self.loadings = factor.loadings
        self.eigenvals = factor.eigenvals
        self.communality = factor.communality
        self.rotation_method = None
        self.n_comp = factor.n_comp

    def __str__(self):
        return self.summary().__str__()

    def rotate(self, method):
        """
        Apply rotation

        Parameters
        ----------
        method : string
            rotation to be applied
        -------
        """
        self.rotation_method = method
        if method not in ['varimax', 'quartimax', 'biquartimax',
                            'equamax', 'oblimin', 'parsimax', 'parsimony',
                            'biquartimin', 'promax']:
            raise ValueError('Unknown rotation method %s' % (method))

        if method in ['varimax', 'quartimax', 'biquartimax', 'equamax',
                        'parsimax', 'parsimony', 'biquartimin']:
            self.loadings, T = rotate_factors(self.loadings_no_rot, method)
        elif method == 'oblimin':
            self.loadings, T = rotate_factors(self.loadings_no_rot, 'quartimin')
        elif method == 'promax':
            self.loadings, T = promax(self.loadings_no_rot)

    def summary(self):
        summ = summary2.Summary()
        summ.add_title('Factor analysis results')
        loadings_no_rot = pd.DataFrame(
            self.loadings_no_rot,
            columns=["factor %d" % (i)
                     for i in range(self.loadings_no_rot.shape[1])],
            index=self.endog_names
        )
        eigenvals = pd.DataFrame([self.eigenvals], columns=self.endog_names,
                                 index=[''])
        summ.add_dict({'': 'Eigenvalues'})
        summ.add_df(eigenvals)
        communality = pd.DataFrame([self.communality],
                                   columns=self.endog_names, index=[''])
        summ.add_dict({'': ''})
        summ.add_dict({'': 'Communality'})
        summ.add_df(communality)
        summ.add_dict({'': ''})
        summ.add_dict({'': 'Pre-rotated loadings'})
        summ.add_df(loadings_no_rot)
        summ.add_dict({'': ''})
        if self.rotation is not None:
            loadings = pd.DataFrame(
                self.loadings,
                columns=["factor %d" % (i)
                         for i in range(self.loadings.shape[1])],
                index=self.endog_names
            )
            summ.add_dict({'': '%s rotated loadings' % (self.rotation)})
            summ.add_df(loadings)
        return summ

    def plot_scree(self, ncomp=None):
        """
        Plot of the ordered eigenvalues and variance explained for the loadings

        Parameters
        ----------
        ncomp : int, optional
            Number of loadings to include in the plot.  If None, will
            included the same as the number of maximum possible loadings

        Returns
        -------
        fig : figure
            Handle to the figure
        """
        if missing_matplotlib:
            raise ImportError("Matplotlib missing")
        return plot_scree(self.eigenvals, self.n_comp, ncomp)

    def plot_loadings(self, loading_pairs=None, plot_prerotated=False):
        """
        Plot factor loadings in 2-d plots

        Parameters
        ----------
        loading_pairs : None or a list of tuples
            Specify plots. Each tuple (i, j) represent one figure, i and j is
            the loading number for x-axis and y-axis, respectively. If `None`,
            all combinations of the loadings will be plotted.
        plot_prerotated : True or False
            If True, the loadings before rotation applied will be plotted. If
            False, rotated loadings will be plotted.

        Returns
        -------
        figs : a list of figure handles

        """
        if missing_matplotlib:
            raise ImportError("Matplotlib missing")

        if self.rotation_method is None:
            plot_prerotated = True
        loadings = self.loadings_no_rot if plot_prerotated else self.loadings
        if plot_prerotated:
            title = 'Prerotated Factor Pattern'
        else:
            title = '%s Rotated Factor Pattern' % (self.rotation_method)
        var_explained = self.eigenvals / self.n_comp * 100

        return plot_loadings(loadings, loading_pairs=loading_pairs,
                             title=title, row_names=self.endog_names,
                             percent_variance=var_explained)
<commit_msg>Add reference Hofacker 2004<commit_after># -*- coding: utf-8 -*-

from statsmodels.base.model import Model
from .factor_rotation import rotate_factors, promax

try:
    import matplotlib.pyplot as plt
    missing_matplotlib = False
except ImportError:
    missing_matplotlib = True

if not missing_matplotlib:
    from .plots import plot_scree, plot_loadings

import numpy as np
from numpy.linalg import eigh, inv, norm, matrix_rank
import pandas as pd

from statsmodels.iolib import summary2

class Factor(Model):
    """
    Principle axis factor analysis

    .. [1] Hofacker, C. (2004). Exploratory Factor Analysis, Mathematical Marketing
    http://www.openaccesstexts.org/pdf/Quant_Chapter_11_efa.pdf

    .. [2] http://www.real-statistics.com/multivariate-statistics/
    factor-analysis/principal-axis-method/

    .. [3] http://stats.stackexchange.com/questions/102882/
    steps-done-in-factor-analysis-compared-to-steps-done-in-pca/102999#102999

    Supported rotations:
        'varimax', 'quartimax', 'biquartimax', 'equamax', 'oblimin',
        'parsimax', 'parsimony', 'biquartimin', 'promax'

    Parameters
    ----------
    endog : array-like
        Variables in columns, observations in rows

    n_factor : int
        The number of factors to extract

    """
    def __init__(self, endog, n_factor, exog=None, **kwargs):
        if n_factor <= 0:
            raise ValueError('n_factor must be larger than 0! %d < 0' %
                             (n_factor))
        if n_factor > endog.shape[1]:
            raise ValueError('n_factor must be smaller or equal to the number'
                             ' of columns of endog! %d > %d' %
                             (n_factor, endog.shape[1]))
        self.n_factor = n_factor
        self.loadings = None
        self.communality = None
        self.eigenvals = None
        super(Factor, self).__init__(endog, exog)

    def fit(self, n_max_iter=50, tolerance=1e-6, SMC=True):
        """
        Fit the factor model

        Parameters
        ----------
        n_max_iter : int
            Maximum number of iterations for communality estimation
        tolerance : float
            If `norm(communality - last_communality)  < tolerance`,
            estimation stops
        SMC : True or False
            Whether or not to apply squared multiple correlations

        -------

        """
        R = np.corrcoef(self.endog, rowvar=0)
        self.n_comp = matrix_rank(R)
        if self.n_factor > self.n_comp:
            raise ValueError('n_factor must be smaller or equal to the rank'
                             ' of endog! %d > %d' %
                             (self.n_factor, self.n_comp))
        if n_max_iter <= 0:
            raise ValueError('n_max_iter must be larger than 0! %d < 0' %
                             (n_max_iter))
        if tolerance <= 0 or tolerance > 0.01:
            raise ValueError('tolerance must be larger than 0 and smaller than'
                             ' 0.01! Got %f instead' % (tolerance))
        #  Initial communality estimation
        if SMC:
            c = 1 - 1 / np.diag(inv(R))
            self.SMC = np.array(c)
        else:
            c = np.ones([1, len(R)])

        # Iterative communality estimation
        eigenvals = None
        for i in range(n_max_iter):
            # Get eigenvalues/eigenvectors of R with diag replaced by
            # communality
            for j in range(len(R)):
                R[j, j] = c[j]
            L, V = eigh(R, UPLO='U')
            c_last = np.array(c)
            ind = np.argsort(L)
            ind = ind[::-1]
            L = L[ind]
            n_pos = (L > 0).sum()
            V = V[:, ind]
            eigenvals = np.array(L)

            # Select eigenvectors with positive eigenvalues
            n = np.min([n_pos, self.n_factor])
            sL = np.diag(np.sqrt(L[:n]))
            V = V[:, :n]

            # Calculate new loadings and communality
            A = V.dot(sL)
            c = np.power(A, 2).sum(axis=1)
            if norm(c_last - c) < tolerance:
                break
        self.eigenvals = eigenvals
        self.communality = c
        self.loadings = A
        return FactorResults(self)

class FactorResults(object):
    """
    Factor results class

    Parameters
    ----------
    factor : Factor
        Fitted Factor class

    """
    def __init__(self, factor):
        if not isinstance(factor, Factor):
            raise ValueError('Input must be a `Factor` class. Got %s instead'
                             % (factor.__str__))
        self.endog_names = factor.endog_names
        self.loadings_no_rot = factor.loadings
        self.loadings = factor.loadings
        self.eigenvals = factor.eigenvals
        self.communality = factor.communality
        self.rotation_method = None
        self.n_comp = factor.n_comp

    def __str__(self):
        return self.summary().__str__()

    def rotate(self, method):
        """
        Apply rotation

        Parameters
        ----------
        method : string
            rotation to be applied
        -------
        """
        self.rotation_method = method
        if method not in ['varimax', 'quartimax', 'biquartimax',
                            'equamax', 'oblimin', 'parsimax', 'parsimony',
                            'biquartimin', 'promax']:
            raise ValueError('Unknown rotation method %s' % (method))

        if method in ['varimax', 'quartimax', 'biquartimax', 'equamax',
                        'parsimax', 'parsimony', 'biquartimin']:
            self.loadings, T = rotate_factors(self.loadings_no_rot, method)
        elif method == 'oblimin':
            self.loadings, T = rotate_factors(self.loadings_no_rot, 'quartimin')
        elif method == 'promax':
            self.loadings, T = promax(self.loadings_no_rot)

    def summary(self):
        summ = summary2.Summary()
        summ.add_title('Factor analysis results')
        loadings_no_rot = pd.DataFrame(
            self.loadings_no_rot,
            columns=["factor %d" % (i)
                     for i in range(self.loadings_no_rot.shape[1])],
            index=self.endog_names
        )
        eigenvals = pd.DataFrame([self.eigenvals], columns=self.endog_names,
                                 index=[''])
        summ.add_dict({'': 'Eigenvalues'})
        summ.add_df(eigenvals)
        communality = pd.DataFrame([self.communality],
                                   columns=self.endog_names, index=[''])
        summ.add_dict({'': ''})
        summ.add_dict({'': 'Communality'})
        summ.add_df(communality)
        summ.add_dict({'': ''})
        summ.add_dict({'': 'Pre-rotated loadings'})
        summ.add_df(loadings_no_rot)
        summ.add_dict({'': ''})
        if self.rotation is not None:
            loadings = pd.DataFrame(
                self.loadings,
                columns=["factor %d" % (i)
                         for i in range(self.loadings.shape[1])],
                index=self.endog_names
            )
            summ.add_dict({'': '%s rotated loadings' % (self.rotation)})
            summ.add_df(loadings)
        return summ

    def plot_scree(self, ncomp=None):
        """
        Plot of the ordered eigenvalues and variance explained for the loadings

        Parameters
        ----------
        ncomp : int, optional
            Number of loadings to include in the plot.  If None, will
            included the same as the number of maximum possible loadings

        Returns
        -------
        fig : figure
            Handle to the figure
        """
        if missing_matplotlib:
            raise ImportError("Matplotlib missing")
        return plot_scree(self.eigenvals, self.n_comp, ncomp)

    def plot_loadings(self, loading_pairs=None, plot_prerotated=False):
        """
        Plot factor loadings in 2-d plots

        Parameters
        ----------
        loading_pairs : None or a list of tuples
            Specify plots. Each tuple (i, j) represent one figure, i and j is
            the loading number for x-axis and y-axis, respectively. If `None`,
            all combinations of the loadings will be plotted.
        plot_prerotated : True or False
            If True, the loadings before rotation applied will be plotted. If
            False, rotated loadings will be plotted.

        Returns
        -------
        figs : a list of figure handles

        """
        if missing_matplotlib:
            raise ImportError("Matplotlib missing")

        if self.rotation_method is None:
            plot_prerotated = True
        loadings = self.loadings_no_rot if plot_prerotated else self.loadings
        if plot_prerotated:
            title = 'Prerotated Factor Pattern'
        else:
            title = '%s Rotated Factor Pattern' % (self.rotation_method)
        var_explained = self.eigenvals / self.n_comp * 100

        return plot_loadings(loadings, loading_pairs=loading_pairs,
                             title=title, row_names=self.endog_names,
                             percent_variance=var_explained)
<|endoftext|>


<commit_before>#!/usr/bin/python
#
#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
#
#                     The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#

r"""
ClangFormat Diff Reformatter
============================

This script reads input from a unified diff and reformats all the changed
lines. This is useful to reformat all the lines touched by a specific patch.
Example usage for git users:

  git diff -U0 HEAD^ | clang-format-diff.py -p1

"""

import argparse
import re
import subprocess
import sys

# Change this to the full path if clang-format is not on the path.
binary = 'clang-format'

def getOffsetLength(filename, line_number, line_count):
  """
  Calculates the field offset and length based on line number and count.
  """
  offset = 0
  length = 0
  with open(filename, 'r') as f:
    for line in f:
      if line_number > 1:
        offset += len(line)
        line_number -= 1
      elif line_count > 0:
        length += len(line)
        line_count -= 1
      else:
        break
  return offset, length

def formatRange(r, style):
  """
  Formats range 'r' according to style 'style'.
  """
  filename, line_number, line_count = r
  # FIXME: Add other types containing C++/ObjC code.
  if not (filename.endswith(".cpp") or filename.endswith(".cc") or
          filename.endswith(".h")):
    return

  offset, length = getOffsetLength(filename, line_number, line_count)
  with open(filename, 'r') as f:
    text = f.read()
  command = [binary, '-offset', str(offset), '-length', str(length)]
  if style:
    command.append('-style', style)
  p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                       stdin=subprocess.PIPE)
  stdout, stderr = p.communicate(input=text)
  if stderr:
    print stderr
    return
  if not stdout:
    print 'Segfault occurred while formatting', filename
    print 'Please report a bug on llvm.org/bugs.'
    return
  with open(filename, 'w') as f:
    f.write(stdout)

def main():
  parser = argparse.ArgumentParser(description=
                                   'Reformat changed lines in diff')
  parser.add_argument('-p', default=1,
                      help='strip the smallest prefix containing P slashes')
  parser.add_argument('-style', help='formatting style to apply (LLVM, Google)')
  args = parser.parse_args()

  filename = None
  ranges = []

  for line in sys.stdin:
    match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
    if match:
      filename = match.group(2)
    if filename == None:
      continue

    match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
    if match:
      line_count = 1
      if match.group(3):
        line_count = int(match.group(3))
      ranges.append((filename, int(match.group(1)), line_count))

  # Reverse the ranges so that the reformatting does not influence file offsets.
  for r in reversed(ranges):
    # Do the actual formatting.
    formatRange(r, args.style)

if __name__ == '__main__':
  main()
<commit_msg>Fix clang-format-diff.py script.<commit_after>#!/usr/bin/python
#
#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
#
#                     The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#

r"""
ClangFormat Diff Reformatter
============================

This script reads input from a unified diff and reformats all the changed
lines. This is useful to reformat all the lines touched by a specific patch.
Example usage for git users:

  git diff -U0 HEAD^ | clang-format-diff.py -p1

"""

import argparse
import re
import subprocess
import sys

# Change this to the full path if clang-format is not on the path.
binary = 'clang-format'

def getOffsetLength(filename, line_number, line_count):
  """
  Calculates the field offset and length based on line number and count.
  """
  offset = 0
  length = 0
  with open(filename, 'r') as f:
    for line in f:
      if line_number > 1:
        offset += len(line)
        line_number -= 1
      elif line_count > 0:
        length += len(line)
        line_count -= 1
      else:
        break
  return offset, length

def formatRange(r, style):
  """
  Formats range 'r' according to style 'style'.
  """
  filename, line_number, line_count = r
  # FIXME: Add other types containing C++/ObjC code.
  if not (filename.endswith(".cpp") or filename.endswith(".cc") or
          filename.endswith(".h")):
    return

  offset, length = getOffsetLength(filename, line_number, line_count)
  with open(filename, 'r') as f:
    text = f.read()
  command = [binary, '-offset', str(offset), '-length', str(length)]
  if style:
    command.extend(['-style', style])
  p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                       stdin=subprocess.PIPE)
  stdout, stderr = p.communicate(input=text)
  if stderr:
    print stderr
    return
  if not stdout:
    print 'Segfault occurred while formatting', filename
    print 'Please report a bug on llvm.org/bugs.'
    return
  with open(filename, 'w') as f:
    f.write(stdout)

def main():
  parser = argparse.ArgumentParser(description=
                                   'Reformat changed lines in diff')
  parser.add_argument('-p', default=1,
                      help='strip the smallest prefix containing P slashes')
  parser.add_argument('-style', help='formatting style to apply (LLVM, Google)')
  args = parser.parse_args()

  filename = None
  ranges = []

  for line in sys.stdin:
    match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
    if match:
      filename = match.group(2)
    if filename == None:
      continue

    match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
    if match:
      line_count = 1
      if match.group(3):
        line_count = int(match.group(3))
      ranges.append((filename, int(match.group(1)), line_count))

  # Reverse the ranges so that the reformatting does not influence file offsets.
  for r in reversed(ranges):
    # Do the actual formatting.
    formatRange(r, args.style)

if __name__ == '__main__':
  main()
<|endoftext|>


<commit_before>#!/usr/bin/env python

import numpy as np
import scipy.stats as stats
from scipy.linalg import pinv
from scipy.stats import logistic, norm
from statsmodels.tools.tools import chain_dot as dot
from statsmodels.tools.decorators import cache_readonly
from statsmodels.regression.linear_model import (RegressionModel,
                                                 RegressionResults,
                                                 RegressionResultsWrapper)

class QuantReg(RegressionModel):

    '''Quantile Regression

    Estimate a quantile regression model using iterative reweighted least
    squares.

    Parameters
    ----------

    endog : array or dataframe
        endogenous/response variable
    exog : array or dataframe
        exogenous/explanatory variable(s)

    Notes
    -----

    The Least Absolute Deviation (LAD) estimator is a special case where
    quantile is set to 0.5 (q argument of the fit method).

    The asymptotic covariance matrix is estimated following the procedure in
    Greene (2008, p.407-408), using either the logistic or gaussian kernels
    (kernel argument of the fit method).

    References
    ----------

    General:

    * Birkes, D. and Y. Dodge(1993). Alternative Methods of Regression, John Wiley and Sons.
    * Green,W. H. (2008). Econometric Analysis. Sixth Edition. International Student Edition.
    * Koenker, R. (2005). Quantile Regression. New York: Cambridge University Press.
    * LeSage, J. P.(1999). Applied Econometrics Using MATLAB,

    Kernels:

    * Green (2008) Table 14.2

    Bandwidth selection:

    * Bofinger, E. (1975). Estimation of a density function using order statistics. Australian Journal of Statistics 17: 1-17.
    * Chamberlain, G. (1994). Quantile regression, censoring, and the structure of wages. In Advances in Econometrics, Vol. 1: Sixth World Congress, ed. C. A. Sims, 171-209. Cambridge: Cambridge University Press.
    * Hall, P., and S. Sheather. (1988). On the distribution of the Studentized quantile. Journal of the Royal Statistical Society, Series B 50: 381-391.

    License
    -------

    Original Matlab code by Shapour Mohammadi, University of Tehran, 2008
    (shmohammadi@gmail.com). First translation to python with permission from
    original author by Christian Prinoth (christian at prinoth dot name).
    Further adapted and modified by the statsmodels team.

    Keywords
    --------

    Keywords: Least Absolute Deviation(LAD) Regression, Quantile Regression,
    Regression, Robust Estimation.
    '''

    def __init__(self, endog, exog):
        super(QuantReg, self).__init__(endog, exog)

    def whiten(self, Y):
        """
        QuantReg model whitener does nothing: returns Y.
        """
        return Y

    def fit(self, q=.5, vcov='robust', kernel='epa', bandwidth='hsheather', **kwargs):
        '''Solve by Iterative Weighted Least Squares

        Parameters
        ----------

        q : float
            quantile must be between 0 and 1
        kernel : string ('logistic' or 'gaussian')
            kernel to use for computation of estimate asymptotic covariance
            matrix

        Notes
        -----

        Some lines of this section is based on a code written by
        James P. Lesage in Applied Econometrics Using MATLAB(1999).PP. 73-4.
        '''

        self.q = q

        if q < 0 or q > 1:
            raise Exception('p must be between 0 and 1')

        kern_names = ['biw', 'cos', 'epa', 'gau', 'par' ]
        if kernel not in kern_names:
            raise Exception("kernel must be in " + ', '.join(kern_names))
        else:
            kernel = kernels[kernel]

        bwidth_names = ['hsheather', 'bofinger', 'chamberlain']
        if bandwidth not in bwidth_names:
            raise Exception("kernel must be in " + ', '.join(bwidth_names))
        elif bandwidth == 'hsheather':
            bandwidth = hall_sheather
        elif bandwidth == 'bofinger':
            bandwidth = bofinger
        else:
            bandwidth = chamberlain

        endog = self.endog
        exog = self.exog
        nobs = self.nobs
        rank = self.rank
        itrat = 0
        xstar = exog
        beta = np.ones(rank)  # TODO: better start
        diff = 10

        while itrat < 1000 and diff > 1e-6:
            itrat += 1
            beta0 = beta
            beta = dot(pinv(dot(xstar.T, exog)), xstar.T, endog)
            resid = endog - dot(exog, beta)
            #JP: bound resid away from zero,
            #    why not symmetric: * np.sign(resid), shouldn't matter
            resid[np.abs(resid) < .000001] = .000001
            resid = np.where(resid < 0, q * resid, (1-q) * resid)
            resid = np.abs(resid)
            xstar = exog / resid[:, np.newaxis]
            diff = np.max(np.abs(beta - beta0))

        e = endog - dot(exog, beta)
        # Greene (2008, p.407) writes that Stata 6 uses this bandwidth:
        #h = 0.9 * np.std(e) / (nobs**0.2)
        # Instead, we calculate bandwidth as in Stata 12
        iqre = stats.scoreatpercentile(e, 75) - stats.scoreatpercentile(e, 25)
        h = bandwidth(nobs, q)
        h = min(np.std(endog), iqre / 1.34) * (norm.ppf(q + h) - norm.ppf(q - h))

        fhat0 = 1. / (nobs * h) * np.sum(kernel(e / h))

        self.sparsity = 1. / fhat0
        self.bandwidth = h

        if vcov == 'robust':
            D = np.where(e > 0, (q/fhat0)**2, ((1-q)/fhat0)**2)
            D = np.diag(D)
            vcov = dot(pinv(dot(exog.T, exog)), dot(exog.T, D, exog),
                       pinv(dot(exog.T, exog)))
        elif vcov == 'iid':
            vcov = self.sparsity**2 * self.q * (1-self.q) * pinv(dot(exog.T, exog))
        else:
            raise Exception("vcov must be 'robust' or 'iid'")

        lfit = QuantRegResults(self, beta, normalized_cov_params=vcov)
        return RegressionResultsWrapper(lfit)

def _parzen(u):
    z = np.where(np.abs(u) <= .5, 4./3 - 8. * u**2 + 8. * np.abs(u)**3,
                               8. * (1 - np.abs(u))**3 / 3.)
    z[np.abs(u) > 1] = 0
    return z
kernels = {}
kernels['biw'] = lambda u: 15. / 16 * (1 - u**2)**2 * np.where(np.abs(u) <= 1, 1, 0)
kernels['cos'] = lambda u: np.where(np.abs(u) <= .5, 1 + np.cos(2 * np.pi * u), 0)
kernels['epa'] = lambda u: 3. / 4 * (1-u**2) * np.where(np.abs(u) <= 1, 1, 0)
kernels['gau'] = lambda u: norm.pdf(u)
kernels['par'] = _parzen
#kernels['bet'] = lambda u: np.where(np.abs(u) <= 1, .75 * (1 - u) * (1 + u), 0)
#kernels['log'] = lambda u: logistic.pdf(u) * (1 - logistic.pdf(u))
#kernels['tri'] = lambda u: np.where(np.abs(u) <= 1, 1 - np.abs(u), 0)
#kernels['trw'] = lambda u: 35. / 32 * (1 - u**2)**3 * np.where(np.abs(u) <= 1, 1, 0)
#kernels['uni'] = lambda u: 1. / 2 * np.where(np.abs(u) <= 1, 1, 0)

def hall_sheather(n, q, alpha=.05):
    num = 1.5 * norm.pdf(norm.ppf(q))**2.
    den = 2. * norm.ppf(q)**2. + 1.
    h = n**(-1./3) * norm.ppf(1. - alpha / 2.)**(2./3) * (num / den)**(1./3)
    return h

def bofinger(n, q):
    num = 9./2 * norm.pdf(2 * norm.ppf(q))**4
    den = (2 * norm.ppf(q)**2 + 1)**2
    h = n**(-1./5) * (num/den)**(1./5)
    return h

def chamberlain(n, q, alpha=.05):
    return norm.ppf(1-alpha/2) * np.sqrt(q*(1-q)/n)

class QuantRegResults(RegressionResults):
    '''Results instance for the QuantReg model'''

    @cache_readonly
    def prsquared(self):
        q = self.model.q
        endog = self.model.endog
        e = self.resid
        e = np.where(e < 0, (1-q) * e, q * e)
        e = np.abs(e)
        ered = endog - stats.scoreatpercentile(endog, q * 100)
        ered = np.where(ered < 0, (1-q) * ered, q * ered)
        ered = np.abs(ered)
        return 1 - np.sum(e) / np.sum(ered)

    @cache_readonly
    def sparsity(self):
        return self.model.sparsity
    @cache_readonly
    def bandwidth(self):
        return self.model.bandwidth
    @cache_readonly
    def scale(self):
        return 1.
    #@cache_readonly
    #def aic(self):
        #return np.nan
    @cache_readonly
    def bic(self):
        return np.nan
    @cache_readonly
    def aic(self):
        return np.nan
    @cache_readonly
    def llf(self):
        return np.nan
    @cache_readonly
    def rsquared(self):
        return np.nan
    @cache_readonly
    def HC0_se(self):
        raise NotImplementedError
    @cache_readonly
    def HC1_se(self):
        raise NotImplementedError
    @cache_readonly
    def HC2_se(self):
        raise NotImplementedError
    @cache_readonly
    def HC3_se(self):
        raise NotImplementedError
<commit_msg>docstrings<commit_after>#!/usr/bin/env python

import numpy as np
import scipy.stats as stats
from scipy.linalg import pinv
from scipy.stats import logistic, norm
from statsmodels.tools.tools import chain_dot as dot
from statsmodels.tools.decorators import cache_readonly
from statsmodels.regression.linear_model import (RegressionModel,
                                                 RegressionResults,
                                                 RegressionResultsWrapper)

class QuantReg(RegressionModel):

    '''Quantile Regression

    Estimate a quantile regression model using iterative reweighted least
    squares.

    Parameters
    ----------

    endog : array or dataframe
        endogenous/response variable
    exog : array or dataframe
        exogenous/explanatory variable(s)

    Notes
    -----

    The Least Absolute Deviation (LAD) estimator is a special case where
    quantile is set to 0.5 (q argument of the fit method).

    The asymptotic covariance matrix is estimated following the procedure in
    Greene (2008, p.407-408), using either the logistic or gaussian kernels
    (kernel argument of the fit method).

    References
    ----------

    General:

    * Birkes, D. and Y. Dodge(1993). Alternative Methods of Regression, John Wiley and Sons.
    * Green,W. H. (2008). Econometric Analysis. Sixth Edition. International Student Edition.
    * Koenker, R. (2005). Quantile Regression. New York: Cambridge University Press.
    * LeSage, J. P.(1999). Applied Econometrics Using MATLAB,

    Kernels (used by the fit method):

    * Green (2008) Table 14.2

    Bandwidth selection (used by the fit method):

    * Bofinger, E. (1975). Estimation of a density function using order statistics. Australian Journal of Statistics 17: 1-17.
    * Chamberlain, G. (1994). Quantile regression, censoring, and the structure of wages. In Advances in Econometrics, Vol. 1: Sixth World Congress, ed. C. A. Sims, 171-209. Cambridge: Cambridge University Press.
    * Hall, P., and S. Sheather. (1988). On the distribution of the Studentized quantile. Journal of the Royal Statistical Society, Series B 50: 381-391.

    License
    -------

    Original Matlab code by Shapour Mohammadi, University of Tehran, 2008
    (shmohammadi@gmail.com). First translation to python with permission from
    original author by Christian Prinoth (christian at prinoth dot name).
    Further adapted and modified by the statsmodels team.

    Keywords
    --------

    Keywords: Least Absolute Deviation(LAD) Regression, Quantile Regression,
    Regression, Robust Estimation.
    '''

    def __init__(self, endog, exog):
        super(QuantReg, self).__init__(endog, exog)

    def whiten(self, Y):
        """
        QuantReg model whitener does nothing: returns Y.
        """
        return Y

    def fit(self, q=.5, vcov='robust', kernel='epa', bandwidth='hsheather', **kwargs):
        '''Solve by Iterative Weighted Least Squares

        Parameters
        ----------

        q : float
            Quantile must be between 0 and 1
        vcov : string
            robust : heteroskedasticity robust standard errors (as suggested in
                     Greene 6th edition)
            iid : iid errors (as in Stata 12)
        kernel : string, Kernel to use in the estimation of the asymptotic
                 covariance
            epa: Epanechnikov
            cos: Cosine
            gau: Gaussian
            par: Parzene
        bandwidth: string, Bandwidth selection method in kernel density
                   estimation for asymptotic covariance estimate (full
                   references in QuantReg docstring)
            hsheather: Hall-Sheather (1988)
            bofinger: Bofinger (1975)
            chamberlain: Chamberlain (1994)

        Notes
        -----

        Some lines of this section are based on a code written by
        James P. Lesage in Applied Econometrics Using MATLAB(1999).PP. 73-4.
        '''

        self.q = q
        if q < 0 or q > 1:
            raise Exception('p must be between 0 and 1')

        kern_names = ['biw', 'cos', 'epa', 'gau', 'par' ]
        if kernel not in kern_names:
            raise Exception("kernel must be in " + ', '.join(kern_names))
        else:
            kernel = kernels[kernel]

        if bandwidth == 'hsheather':
            bandwidth = hall_sheather
        elif bandwidth == 'bofinger':
            bandwidth = bofinger
        elif bandwidth == 'chamberlain':
            bandwidth = chamberlain
        else:
            raise Exception("bandwidth must be in 'hsheather', 'bofinger', 'chamberlain'")

        endog = self.endog
        exog = self.exog
        nobs = self.nobs
        rank = self.rank
        itrat = 0
        xstar = exog
        beta = np.ones(rank)  # TODO: better start
        diff = 10

        while itrat < 1000 and diff > 1e-6:
            itrat += 1
            beta0 = beta
            beta = dot(pinv(dot(xstar.T, exog)), xstar.T, endog)
            resid = endog - dot(exog, beta)
            #JP: bound resid away from zero,
            #    why not symmetric: * np.sign(resid), shouldn't matter
            resid[np.abs(resid) < .000001] = .000001
            resid = np.where(resid < 0, q * resid, (1-q) * resid)
            resid = np.abs(resid)
            xstar = exog / resid[:, np.newaxis]
            diff = np.max(np.abs(beta - beta0))

        e = endog - dot(exog, beta)
        # Greene (2008, p.407) writes that Stata 6 uses this bandwidth:
        #h = 0.9 * np.std(e) / (nobs**0.2)
        # Instead, we calculate bandwidth as in Stata 12
        iqre = stats.scoreatpercentile(e, 75) - stats.scoreatpercentile(e, 25)
        h = bandwidth(nobs, q)
        h = min(np.std(endog), iqre / 1.34) * (norm.ppf(q + h) - norm.ppf(q - h))

        fhat0 = 1. / (nobs * h) * np.sum(kernel(e / h))

        self.sparsity = 1. / fhat0
        self.bandwidth = h

        if vcov == 'robust':
            D = np.where(e > 0, (q/fhat0)**2, ((1-q)/fhat0)**2)
            D = np.diag(D)
            vcov = dot(pinv(dot(exog.T, exog)), dot(exog.T, D, exog),
                       pinv(dot(exog.T, exog)))
        elif vcov == 'iid':
            vcov = self.sparsity**2 * self.q * (1-self.q) * pinv(dot(exog.T, exog))
        else:
            raise Exception("vcov must be 'robust' or 'iid'")

        lfit = QuantRegResults(self, beta, normalized_cov_params=vcov)
        return RegressionResultsWrapper(lfit)

def _parzen(u):
    z = np.where(np.abs(u) <= .5, 4./3 - 8. * u**2 + 8. * np.abs(u)**3,
                               8. * (1 - np.abs(u))**3 / 3.)
    z[np.abs(u) > 1] = 0
    return z
kernels = {}
kernels['biw'] = lambda u: 15. / 16 * (1 - u**2)**2 * np.where(np.abs(u) <= 1, 1, 0)
kernels['cos'] = lambda u: np.where(np.abs(u) <= .5, 1 + np.cos(2 * np.pi * u), 0)
kernels['epa'] = lambda u: 3. / 4 * (1-u**2) * np.where(np.abs(u) <= 1, 1, 0)
kernels['gau'] = lambda u: norm.pdf(u)
kernels['par'] = _parzen
#kernels['bet'] = lambda u: np.where(np.abs(u) <= 1, .75 * (1 - u) * (1 + u), 0)
#kernels['log'] = lambda u: logistic.pdf(u) * (1 - logistic.pdf(u))
#kernels['tri'] = lambda u: np.where(np.abs(u) <= 1, 1 - np.abs(u), 0)
#kernels['trw'] = lambda u: 35. / 32 * (1 - u**2)**3 * np.where(np.abs(u) <= 1, 1, 0)
#kernels['uni'] = lambda u: 1. / 2 * np.where(np.abs(u) <= 1, 1, 0)

def hall_sheather(n, q, alpha=.05):
    num = 1.5 * norm.pdf(norm.ppf(q))**2.
    den = 2. * norm.ppf(q)**2. + 1.
    h = n**(-1./3) * norm.ppf(1. - alpha / 2.)**(2./3) * (num / den)**(1./3)
    return h

def bofinger(n, q):
    num = 9./2 * norm.pdf(2 * norm.ppf(q))**4
    den = (2 * norm.ppf(q)**2 + 1)**2
    h = n**(-1./5) * (num/den)**(1./5)
    return h

def chamberlain(n, q, alpha=.05):
    return norm.ppf(1-alpha/2) * np.sqrt(q*(1-q)/n)

class QuantRegResults(RegressionResults):
    '''Results instance for the QuantReg model'''

    @cache_readonly
    def prsquared(self):
        q = self.model.q
        endog = self.model.endog
        e = self.resid
        e = np.where(e < 0, (1-q) * e, q * e)
        e = np.abs(e)
        ered = endog - stats.scoreatpercentile(endog, q * 100)
        ered = np.where(ered < 0, (1-q) * ered, q * ered)
        ered = np.abs(ered)
        return 1 - np.sum(e) / np.sum(ered)

    @cache_readonly
    def sparsity(self):
        return self.model.sparsity
    @cache_readonly
    def bandwidth(self):
        return self.model.bandwidth
    @cache_readonly
    def scale(self):
        return 1.
    #@cache_readonly
    #def aic(self):
        #return np.nan
    @cache_readonly
    def bic(self):
        return np.nan
    @cache_readonly
    def aic(self):
        return np.nan
    @cache_readonly
    def llf(self):
        return np.nan
    @cache_readonly
    def rsquared(self):
        return np.nan
    @cache_readonly
    def HC0_se(self):
        raise NotImplementedError
    @cache_readonly
    def HC1_se(self):
        raise NotImplementedError
    @cache_readonly
    def HC2_se(self):
        raise NotImplementedError
    @cache_readonly
    def HC3_se(self):
        raise NotImplementedError
<|endoftext|>


<commit_before># handelsregisternummer.py - functions for handling German company registry id
# coding: utf-8
#
# Copyright (C) 2015 Holvi Payment Services Oy
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA

""" Handelsregisternummer (German company register number).

The number consists of the court where the company has registered, the type
of register and the individual number

The type of the register is either HRA or HRB where the letter "B" stands
for HR section B, where limited liability companies and corporations are
entered (GmbH's and AG's). There is also a section HRA for business
partnerships (OHG's, KG's etc.). In other words: businesses in section
HRB are limited liability companies, while businesses in HRA have personally
liable partners.

>>> validate('Achen HRA 11223')
u'Achen HRA 11223'

>>> validate('0 HRB 44123')
u'Achen HRB 44123'

>>> validate('Achen HRC 44123')
Traceback (most recent call last):
  ...
stdnum.exceptions.InvalidFormat: The number has an invalid format.

"""

import re
from stdnum.exceptions import *
from stdnum.util import clean

GERMAN_COURTS = [
    u"Achen",
    u"Altenburg",
    u"Amberg",
    u"Ansbach",
    u"Apolda",
    u"Arnsberg",
    u"Arnstadt",
    u"Aschaffenburg",
    u"Augsburg",
    u"Aurich",
    u"Bad Hersfeld",
    u"Bad Homburg v.d.H.",
    u"Bad Kreuznach",
    u"Bad Langensalza",
    u"Bad Lobenstein",
    u"Bad Oeynhausen",
    u"Bad Salzungen",
    u"Bamberg",
    u"Bayreuth",
    u"Berlin (Charlottenburg)",
    u"Bielefeld",
    u"Bochum",
    u"Bonn",
    u"Braunschweig",
    u"Bremen",
    u"Bückeburg",
    u"Chemnitz",
    u"Coburg",
    u"Coesfeld",
    u"Cottbus",
    u"Darmstadt",
    u"Deggendorf",
    u"Delmenhorst",
    u"Dortmund",
    u"Dresden",
    u"Duisburg",
    u"Düren",
    u"Düsseldorf",
    u"Eisenach",
    u"Erfurt",
    u"Eschwege",
    u"Essen",
    u"Flensburg",
    u"Frankfurt am Main",
    u"Frankfurt/Oder",
    u"Freiburg",
    u"Friedberg",
    u"Fritzlar",
    u"Fulda",
    u"Fürth",
    u"Gelsenkirchen",
    u"Gera",
    u"Gießen",
    u"Gotha",
    u"Göttingen",
    u"Greiz",
    u"Gütersloh",
    u"Hagen",
    u"Hamburg",
    u"Hamm",
    u"Hanau",
    u"Hannover",
    u"Heilbad Heiligenstadt",
    u"Hildburghausen",
    u"Hildesheim",
    u"Hof",
    u"Homburg",
    u"Ilmenau",
    u"Ingolstadt",
    u"Iserlohn",
    u"Jena",
    u"Kaiserslautern",
    u"Kassel",
    u"Kempten (Allgäu)",
    u"Kiel",
    u"Kleve",
    u"Koblenz",
    u"Köln",
    u"Königstein",
    u"Korbach",
    u"Krefeld",
    u"Landau",
    u"Landshut",
    u"Langenfeld",
    u"Lebach",
    u"Leipzig",
    u"Lemgo",
    u"Limburg",
    u"Lübeck",
    u"Ludwigshafen a.Rhein (Ludwigshafen)",
    u"Lüneburg",
    u"Mainz",
    u"Mannheim",
    u"Marburg",
    u"Meiningen",
    u"Memmingen",
    u"Merzig",
    u"Mönchengladbach",
    u"Montabaur",
    u"Mühlhausen",
    u"München",
    u"Münster",
    u"Neubrandenburg",
    u"Neunkirchen",
    u"Neuruppin",
    u"Neuss",
    u"Nienburg (Weser)",
    u"Nordhausen",
    u"Nürnberg",
    u"Offenbach am Main",
    u"Oldenburg (Oldenburg)",
    u"Osnabrück",
    u"Osterholz-Scharmbeck",
    u"Ottweiler",
    u"Paderborn",
    u"Passau",
    u"Pinneberg",
    u"Pößneck",
    u"Potsdam",
    u"Recklinghausen",
    u"Regensburg",
    u"Rinteln",
    u"Rostock",
    u"Rotenburg (Wümme) (Rotenburg/Wümme)",
    u"Rudolstadt",
    u"Saalfeld",
    u"Saarbrücken",
    u"Saarlouis",
    u"Schweinfurt",
    u"Schwerin",
    u"Siegburg",
    u"Siegen",
    u"Sömmerda",
    u"Sondershausen",
    u"Sonneberg",
    u"Stadthagen",
    u"Stadtroda",
    u"Steinfurt",
    u"Stendal",
    u"St. Ingbert (St Ingbert)",
    u"Stralsund",
    u"Straubing",
    u"Stuttgart",
    u"St. Wendel (St Wendel)",
    u"Suhl",
    u"Tostedt",
    u"Traunstein",
    u"Ulm",
    u"Vechta",
    u"Verden (Aller)",
    u"Völklingen",
    u"Walsrode",
    u"Weiden i. d. OPf.",
    u"Weimar",
    u"Wetzlar",
    u"Wiesbaden",
    u"Wittlich",
    u"Wuppertal",
    u"Würzburg",
    u"Zweibrücken"
]

def validate(number):
    """
    Validate the format of a German company registry number.

    First split the provided number with the HRA or HRB. Expect
    the first part to be the name of the court and the second
    part to be the registry number. Returns a cleaned representation
    of the number with the court, HRA/HRB and the number.
    """
    try:
        parts = re.split('HR(A|B)', number, flags=re.IGNORECASE)
    except TypeError:
        return ''

    if len(parts) != 3:
        raise InvalidFormat()
    if parts[1].upper() not in ['A', 'B']:
        raise InvalidFormat()
    court = clean(parts[0], ':').strip()
    if court.lower() not in (name.lower() for name in GERMAN_COURTS):
        try:
            ordinal = int(court)
            if ordinal < len(GERMAN_COURTS) and ordinal >= 0:
                court = GERMAN_COURTS[ordinal]
            else:
                raise InvalidFormat()
        except ValueError:
            raise InvalidFormat()
    else:
        index = [name.lower() for name in GERMAN_COURTS].index(court.lower())
        court = GERMAN_COURTS[index]
    registry = 'HR'+parts[1].upper()
    number = clean(parts[2], ' -./,').upper().strip()
    if not number.isdigit():
        raise InvalidFormat()
    return "%s %s %s" % (court, registry, number)

def is_valid(number):
    """Checks to see if the number provided is a valid company registry number.
    This checks that the court exists and the format is correct."""
    try:
        return bool(validate(number))
    except ValidationError:
        return False
<commit_msg>Fix the name of Achen to Aachen<commit_after># handelsregisternummer.py - functions for handling German company registry id
# coding: utf-8
#
# Copyright (C) 2015 Holvi Payment Services Oy
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA

""" Handelsregisternummer (German company register number).

The number consists of the court where the company has registered, the type
of register and the individual number

The type of the register is either HRA or HRB where the letter "B" stands
for HR section B, where limited liability companies and corporations are
entered (GmbH's and AG's). There is also a section HRA for business
partnerships (OHG's, KG's etc.). In other words: businesses in section
HRB are limited liability companies, while businesses in HRA have personally
liable partners.

>>> validate('Aachen HRA 11223')
u'Aachen HRA 11223'

>>> validate('0 HRB 44123')
u'Aachen HRB 44123'

>>> validate('Aachen HRC 44123')
Traceback (most recent call last):
  ...
stdnum.exceptions.InvalidFormat: The number has an invalid format.

"""

import re
from stdnum.exceptions import *
from stdnum.util import clean

GERMAN_COURTS = [
    u"Aachen",
    u"Altenburg",
    u"Amberg",
    u"Ansbach",
    u"Apolda",
    u"Arnsberg",
    u"Arnstadt",
    u"Aschaffenburg",
    u"Augsburg",
    u"Aurich",
    u"Bad Hersfeld",
    u"Bad Homburg v.d.H.",
    u"Bad Kreuznach",
    u"Bad Langensalza",
    u"Bad Lobenstein",
    u"Bad Oeynhausen",
    u"Bad Salzungen",
    u"Bamberg",
    u"Bayreuth",
    u"Berlin (Charlottenburg)",
    u"Bielefeld",
    u"Bochum",
    u"Bonn",
    u"Braunschweig",
    u"Bremen",
    u"Bückeburg",
    u"Chemnitz",
    u"Coburg",
    u"Coesfeld",
    u"Cottbus",
    u"Darmstadt",
    u"Deggendorf",
    u"Delmenhorst",
    u"Dortmund",
    u"Dresden",
    u"Duisburg",
    u"Düren",
    u"Düsseldorf",
    u"Eisenach",
    u"Erfurt",
    u"Eschwege",
    u"Essen",
    u"Flensburg",
    u"Frankfurt am Main",
    u"Frankfurt/Oder",
    u"Freiburg",
    u"Friedberg",
    u"Fritzlar",
    u"Fulda",
    u"Fürth",
    u"Gelsenkirchen",
    u"Gera",
    u"Gießen",
    u"Gotha",
    u"Göttingen",
    u"Greiz",
    u"Gütersloh",
    u"Hagen",
    u"Hamburg",
    u"Hamm",
    u"Hanau",
    u"Hannover",
    u"Heilbad Heiligenstadt",
    u"Hildburghausen",
    u"Hildesheim",
    u"Hof",
    u"Homburg",
    u"Ilmenau",
    u"Ingolstadt",
    u"Iserlohn",
    u"Jena",
    u"Kaiserslautern",
    u"Kassel",
    u"Kempten (Allgäu)",
    u"Kiel",
    u"Kleve",
    u"Koblenz",
    u"Köln",
    u"Königstein",
    u"Korbach",
    u"Krefeld",
    u"Landau",
    u"Landshut",
    u"Langenfeld",
    u"Lebach",
    u"Leipzig",
    u"Lemgo",
    u"Limburg",
    u"Lübeck",
    u"Ludwigshafen a.Rhein (Ludwigshafen)",
    u"Lüneburg",
    u"Mainz",
    u"Mannheim",
    u"Marburg",
    u"Meiningen",
    u"Memmingen",
    u"Merzig",
    u"Mönchengladbach",
    u"Montabaur",
    u"Mühlhausen",
    u"München",
    u"Münster",
    u"Neubrandenburg",
    u"Neunkirchen",
    u"Neuruppin",
    u"Neuss",
    u"Nienburg (Weser)",
    u"Nordhausen",
    u"Nürnberg",
    u"Offenbach am Main",
    u"Oldenburg (Oldenburg)",
    u"Osnabrück",
    u"Osterholz-Scharmbeck",
    u"Ottweiler",
    u"Paderborn",
    u"Passau",
    u"Pinneberg",
    u"Pößneck",
    u"Potsdam",
    u"Recklinghausen",
    u"Regensburg",
    u"Rinteln",
    u"Rostock",
    u"Rotenburg (Wümme) (Rotenburg/Wümme)",
    u"Rudolstadt",
    u"Saalfeld",
    u"Saarbrücken",
    u"Saarlouis",
    u"Schweinfurt",
    u"Schwerin",
    u"Siegburg",
    u"Siegen",
    u"Sömmerda",
    u"Sondershausen",
    u"Sonneberg",
    u"Stadthagen",
    u"Stadtroda",
    u"Steinfurt",
    u"Stendal",
    u"St. Ingbert (St Ingbert)",
    u"Stralsund",
    u"Straubing",
    u"Stuttgart",
    u"St. Wendel (St Wendel)",
    u"Suhl",
    u"Tostedt",
    u"Traunstein",
    u"Ulm",
    u"Vechta",
    u"Verden (Aller)",
    u"Völklingen",
    u"Walsrode",
    u"Weiden i. d. OPf.",
    u"Weimar",
    u"Wetzlar",
    u"Wiesbaden",
    u"Wittlich",
    u"Wuppertal",
    u"Würzburg",
    u"Zweibrücken"
]

def validate(number):
    """
    Validate the format of a German company registry number.

    First split the provided number with the HRA or HRB. Expect
    the first part to be the name of the court and the second
    part to be the registry number. Returns a cleaned representation
    of the number with the court, HRA/HRB and the number.
    """
    try:
        parts = re.split('HR(A|B)', number, flags=re.IGNORECASE)
    except TypeError:
        return ''

    if len(parts) != 3:
        raise InvalidFormat()
    if parts[1].upper() not in ['A', 'B']:
        raise InvalidFormat()
    court = clean(parts[0], ':').strip()
    if court.lower() not in (name.lower() for name in GERMAN_COURTS):
        try:
            ordinal = int(court)
            if ordinal < len(GERMAN_COURTS) and ordinal >= 0:
                court = GERMAN_COURTS[ordinal]
            else:
                raise InvalidFormat()
        except ValueError:
            raise InvalidFormat()
    else:
        index = [name.lower() for name in GERMAN_COURTS].index(court.lower())
        court = GERMAN_COURTS[index]
    registry = 'HR'+parts[1].upper()
    number = clean(parts[2], ' -./,').upper().strip()
    if not number.isdigit():
        raise InvalidFormat()
    return "%s %s %s" % (court, registry, number)

def is_valid(number):
    """Checks to see if the number provided is a valid company registry number.
    This checks that the court exists and the format is correct."""
    try:
        return bool(validate(number))
    except ValidationError:
        return False
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright (C) 2013 Agile Business Group sagl (<http://www.agilebg.com>)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published
#    by the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

{
    'name': "Lot Valuation",
    'version': '0.1',
    'category': 'Warehouse Management',
    'description': """
Stock valuation (standard or average price, ...) based on lots.
This module extends standard stock valuation (based on products). Valuing lots allows to have different costs for different lots of the same product.
""",
    'author': 'Agile Business Group',
    'website': 'http://www.agilebg.com',
    'license': 'AGPL-3',
    "depends" : ['stock'],
    "data" : [
        "wizard/stock_change_standard_price_view.xml",
        "product_view.xml",
        "stock_view.xml",
        ],
    "demo" : [],
    'test': [
        'test/stock.yml',
        ],
    "active": False,
    "installable": True
}
<commit_msg>[imp] description<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright (C) 2013 Agile Business Group sagl (<http://www.agilebg.com>)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published
#    by the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

{
    'name': "Lot Valuation",
    'version': '0.1',
    'category': 'Warehouse Management',
    'description': """
Stock valuation (standard or average price, ...) based on lots.
This module extends standard stock valuation (based on products). Valuing lots allows to have different costs for different lots of the same product.

Usage
-----
Set the 'Lot valuation' flag on product form (used for real time valuation).
As for products, lots have 'cost' and 'costing method' fields. Also, a 'Change Standard Price' wizard is available.
""",
    'author': 'Agile Business Group',
    'website': 'http://www.agilebg.com',
    'license': 'AGPL-3',
    "depends" : ['stock'],
    "data" : [
        "wizard/stock_change_standard_price_view.xml",
        "product_view.xml",
        "stock_view.xml",
        ],
    "demo" : [],
    'test': [
        'test/stock.yml',
        ],
    "active": False,
    "installable": True
}
<|endoftext|>


<commit_before># coding: utf-8

from __future__ import division, print_function

__author__ = "adrn <adrn@astro.columbia.edu>"

# Standard library
import os, sys
import time

# Third-party
import numpy as np
from astropy import log as logger
import astropy.units as u
from scipy.linalg import solve
from scipy.optimize import leastsq

# Project
from ..potential import HarmonicOscillatorPotential, IsochronePotential

__all__ = ['classify_orbit', 'find_box_actions']

def L(w):
    """
    Compute the angular momentum vector of phase-space point(s), `w`

    Parameters
    ----------
    w : array_like
        Array of phase-space positions.
    """
    ndim = w.shape[-1]
    return np.cross(w[...,:ndim//2], w[...,ndim//2:])

def classify_orbit(w):
    """
    Determine whether an orbit is a Box or Loop orbit by figuring out
    whether there is a change of sign of the angular momentum about an
    axis. Returns an array with 3 integers per phase-space point, such
    that:

    - Box = [0,0,0]
    - Short axis Loop = [0,0,1]
    - Long axis Loop = [1,0,0]

    Parameters
    ----------
    w : array_like
        Array of phase-space positions.

    """
    # get angular momenta
    Ls = L(w)

    # if only 2D, add another empty axis
    if w.ndim == 2:
        ntimesteps,ndim = w.shape
        w = w.reshape(ntimesteps*norbits,1,ndim)

    ntimes,norbits,ndim = w.shape

    # initial angular momentum
    L0 = Ls[0]

    # see if at any timestep the sign has changed
    loop = np.ones((norbits,3))
    for ii in range(3):
        ix = np.any(np.sign(L0[...,ii]) != np.sign(Ls[1:,...,ii]), axis=0)
        loop[ix,ii] = 0

    return loop.astype(int)

def flip_coords(w, loop_bit):
    """
    Align circulation with z-axis.

    Parameters
    ----------
    w : array_like
        Array of phase-space positions.
    loop_bit : array_like
        Array of bits that specify axis about which the orbit circulates.
        See docstring for `classify_orbit()`.
    """
    ix = loop_bit[:,0] == 1
    w[:,ix,:3] = w[:,ix,2::-1] # index magic to flip positions
    w[:,ix,3:] = w[:,ix,:2:-1] # index magic to flip velocities
    return w

def generate_n_vectors(N_max, dx=1, dy=1, dz=1):
    """
    TODO:

    """
    vecs = np.meshgrid(np.arange(-N_max, N_max+1, dx),
                       np.arange(-N_max, N_max+1, dy),
                       np.arange(-N_max, N_max+1, dz))
    vecs = np.vstack(map(np.ravel,vecs)).T
    vecs = vecs[np.linalg.norm(vecs,axis=1) <= N_max]
    ix = ((vecs[:,2] > 0) | ((vecs[:,2] == 0) & (vecs[:,1] > 0)) | ((vecs[:,2] == 0) & (vecs[:,1] == 0) & (vecs[:,0] > 0)))
    vecs = vecs[ix]
    return vecs

def unroll_angles(angles, sign=1.):
    """
    Unrolls the angles, `angles`, so they increase continuously instead of
    wrapping at 2π.

    Parameters
    ----------
    angles : array_like
        Array of angles, (ntimes,3).
    sign : numeric (optional)
        TODO:
    """
    n = np.array([0,0,0])
    P = np.zeros_like(angles)
    P[0] = angles[0]

    n = np.cumsum(((angles[1:] - angles[:-1] + 0.5*sign*np.pi)*sign < 0) * 2.*np.pi, axis=0)
    P[1:] = angles[1:] + sign*n
    return P

def check_angle_sampling(nvecs, angles):
    """
    returns a list of the index of elements of n which do not have adequate
    toy angle coverage. The criterion is that we must have at least one sample
    in each Nyquist box when we project the toy angles along the vector n
    """

    checks = np.array([])
    P = np.array([])

    logger.debug("Checking modes:")
    for i,vec in enumerate(nvecs):
        N = np.linalg.norm(vec)
        X = np.dot(angles,vec)

        if(np.abs(np.max(X)-np.min(X)) < 2.*np.pi):
            logger.warning("Need a longer integration window for mode " + str(vec))
            checks = np.append(checks,vec)
            P = np.append(P,(2.*np.pi-np.abs(np.max(X)-np.min(X))))

        elif(np.abs(np.max(X)-np.min(X))/len(X) > np.pi):
            logger.warning("Need a finer sampling for mode " + str(vec))
            checks = np.append(checks,vec)
            P = np.append(P,(2.*np.pi-np.abs(np.max(X)-np.min(X))))

    return checks,P

def action_solver(aa, N_max, dx, dy, dz):
    """
    TODO:

    """

    # unroll the angles so they increase continuously instead of wrap
    angles = unroll_angles(aa[:,3:])

    # generate integer vectors for fourier modes
    nvecs = generate_n_vectors(N_max, dx, dy, dz)

    # make sure we have enough angle coverage
    modes,P = check_angle_sampling(nvecs, angles)

    # TODO: throw out modes?

    n = len(nvecs) + 3
    b = np.zeros(shape=(n, ))
    A = np.zeros(shape=(n,n))

    # top left block matrix: identity matrix summed over timesteps
    A[:3,:3] = len(aa)*np.identity(3)

    actions = aa[:,:3]
    angles = aa[:,3:]

    # top right block matrix: transpose of C_nk matrix (Eq. 12)
    C_T = 2.*nvecs.T * np.sum(np.cos(np.dot(nvecs,angles.T)), axis=-1)
    A[:3,3:] = C_T
    A[3:,:3] = C_T.T

    # lower right block matrix: C_nk dotted with C_nk^T
    CdotC_T = 0.
    for ang in angles:
        v = np.cos(np.dot(nvecs,ang))
        CdotC_T += np.outer(v,v)
    CdotC_T *= 4.*np.dot(nvecs,nvecs.T)
    A[3:,3:] = CdotC_T

    # b vector first three is just sum of toy actions
    b[:3] = np.sum(actions, axis=0)

    # rest of the vector is C dotted with actions
    b[3:] = np.sum(C_T.T.dot(actions.T),axis=1)

    return np.array(solve(A,b)), nvecs

def find_box_actions(t, w, N_max=8):
    """
    Finds actions, angles, and frequencies for a box orbit.
    Takes a series of phase-space points, `w`, from an orbit integration at
    times `t`.

    This code is adapted from Jason Sanders'
    `genfunc <https://github.com/jlsanders/genfunc>`_

    Parameters
    ----------
    t : array_like
        Array of times with shape (ntimes,).
    w : array_like
        Phase-space orbit at times, `t`. Should have shape (ntimes,6).
    N_max : int
        Maximum integer Fourier mode vector length, |n|.
    """

    if w.ndim > 2:
        raise ValueError("w must be a single orbit")

    logger.debug("===== Using triaxial harmonic oscillator toy potential =====")

    t1 = time.time()

    # find best toy potential parameters
    potential = HarmonicOscillatorPotential(omega=[1.,1.,1.])
    def f(omega,w):
        potential.parameters['omega'] = omega
        H = potential.energy(w[...,:3], w[...,3:])
        return np.squeeze(H - np.median(H))

    p,ier = leastsq(f, np.array([10.,10.,10.]), args=(w,))

    if ier < 1 or ier > 4:
        raise ValueError("Failed to fit toy potential to orbit.")

    best_omega = np.abs(p)
    potential = HarmonicOscillatorPotential(omega=best_omega)
    logger.debug("Best omegas ({}) found in {} seconds".format(best_omega,time.time()-t1))

    # Now find toy actions and angles
    action,angle = potential.action_angle(w[...,:3], w[...,3:])
    aa = np.hstack((action,angle))
    if np.any(np.isnan(aa)):
        raise ValueError("NaN value in toy actions or angles!")

    t1 = time.time()
    actions,nvecs = action_solver(aa, N_max, dx=2, dy=2, dz=2)

    logger.debug("Action solution found for N_max={}, size {} symmetric"
                 " matrix in {} seconds"\
                 .format(N_max,len(actions),time.time()-t1))

    print(actions[:3])
    return

    np.savetxt("GF.Sn_box",np.vstack((act[1].T,act[0][3:])).T)

    ang = solver.angle_solver(AA,times,N_matrix,np.ones(3))
    if(ifprint):
        print("Angle solution found for N_max = "+str(N_matrix)+", size "+str(len(ang))+" symmetric matrix in "+str(time.time()-t)+" seconds")

    # Just some checks
    if(len(ang)>len(AA)):
        print("More unknowns than equations")

    return act[0], ang, act[1], AA, omega

def find_actions(t, w, N_max=8):
    """
    Find approximate actions and angles for samples of a phase-space orbit,
    `w`, at times `t`. Uses toy potentials with known, analytic action-angle
    transformations to approximate the true coordinates as a Fourier sum. Uses
    the formalism presented in Sanders & Binney (2014).

    This code is adapted from Jason Sanders'
    `genfunc <https://github.com/jlsanders/genfunc>`_

    Parameters
    ----------
    t : array_like
        Array of times with shape (ntimes,).
    w : array_like
        Phase-space orbits at times, `t`. Should have shape (ntimes,norbits,6).
    N_max : int
        Maximum integer Fourier mode vector length, |n|.
    """

    # first determine orbit
<commit_msg>sped up and added angle solvers<commit_after># coding: utf-8

from __future__ import division, print_function

__author__ = "adrn <adrn@astro.columbia.edu>"

# Standard library
import os, sys
import time

# Third-party
import numpy as np
from astropy import log as logger
import astropy.units as u
from scipy.linalg import solve
from scipy.optimize import leastsq

# Project
from ..potential import HarmonicOscillatorPotential, IsochronePotential

__all__ = ['classify_orbit', 'find_box_actions']

def L(w):
    """
    Compute the angular momentum vector of phase-space point(s), `w`

    Parameters
    ----------
    w : array_like
        Array of phase-space positions.
    """
    ndim = w.shape[-1]
    return np.cross(w[...,:ndim//2], w[...,ndim//2:])

def classify_orbit(w):
    """
    Determine whether an orbit is a Box or Loop orbit by figuring out
    whether there is a change of sign of the angular momentum about an
    axis. Returns an array with 3 integers per phase-space point, such
    that:

    - Box = [0,0,0]
    - Short axis Loop = [0,0,1]
    - Long axis Loop = [1,0,0]

    Parameters
    ----------
    w : array_like
        Array of phase-space positions.

    """
    # get angular momenta
    Ls = L(w)

    # if only 2D, add another empty axis
    if w.ndim == 2:
        ntimesteps,ndim = w.shape
        w = w.reshape(ntimesteps*norbits,1,ndim)

    ntimes,norbits,ndim = w.shape

    # initial angular momentum
    L0 = Ls[0]

    # see if at any timestep the sign has changed
    loop = np.ones((norbits,3))
    for ii in range(3):
        ix = np.any(np.sign(L0[...,ii]) != np.sign(Ls[1:,...,ii]), axis=0)
        loop[ix,ii] = 0

    return loop.astype(int)

def flip_coords(w, loop_bit):
    """
    Align circulation with z-axis.

    Parameters
    ----------
    w : array_like
        Array of phase-space positions.
    loop_bit : array_like
        Array of bits that specify axis about which the orbit circulates.
        See docstring for `classify_orbit()`.
    """
    ix = loop_bit[:,0] == 1
    w[:,ix,:3] = w[:,ix,2::-1] # index magic to flip positions
    w[:,ix,3:] = w[:,ix,:2:-1] # index magic to flip velocities
    return w

def generate_n_vectors(N_max, dx=1, dy=1, dz=1):
    """
    TODO:

    """
    vecs = np.meshgrid(np.arange(-N_max, N_max+1, dx),
                       np.arange(-N_max, N_max+1, dy),
                       np.arange(-N_max, N_max+1, dz))
    vecs = np.vstack(map(np.ravel,vecs)).T
    vecs = vecs[np.linalg.norm(vecs,axis=1) <= N_max]
    ix = ((vecs[:,2] > 0) | ((vecs[:,2] == 0) & (vecs[:,1] > 0)) | ((vecs[:,2] == 0) & (vecs[:,1] == 0) & (vecs[:,0] > 0)))
    vecs = vecs[ix]
    return vecs

def unroll_angles(angles, sign=1.):
    """
    Unrolls the angles, `angles`, so they increase continuously instead of
    wrapping at 2π.

    Parameters
    ----------
    angles : array_like
        Array of angles, (ntimes,3).
    sign : numeric (optional)
        TODO:
    """
    n = np.array([0,0,0])
    P = np.zeros_like(angles)
    P[0] = angles[0]

    n = np.cumsum(((angles[1:] - angles[:-1] + 0.5*sign*np.pi)*sign < 0) * 2.*np.pi, axis=0)
    P[1:] = angles[1:] + sign*n
    return P

def check_angle_sampling(nvecs, angles):
    """
    returns a list of the index of elements of n which do not have adequate
    toy angle coverage. The criterion is that we must have at least one sample
    in each Nyquist box when we project the toy angles along the vector n
    """

    checks = np.array([])
    P = np.array([])

    logger.debug("Checking modes:")
    for i,vec in enumerate(nvecs):
        N = np.linalg.norm(vec)
        X = np.dot(angles,vec)

        if(np.abs(np.max(X)-np.min(X)) < 2.*np.pi):
            logger.warning("Need a longer integration window for mode " + str(vec))
            checks = np.append(checks,vec)
            P = np.append(P,(2.*np.pi-np.abs(np.max(X)-np.min(X))))

        elif(np.abs(np.max(X)-np.min(X))/len(X) > np.pi):
            logger.warning("Need a finer sampling for mode " + str(vec))
            checks = np.append(checks,vec)
            P = np.append(P,(2.*np.pi-np.abs(np.max(X)-np.min(X))))

    return checks,P

def action_solver(aa, N_max, dx, dy, dz):
    """
    TODO:

    """

    # unroll the angles so they increase continuously instead of wrap
    angles = unroll_angles(aa[:,3:])

    # generate integer vectors for fourier modes
    nvecs = generate_n_vectors(N_max, dx, dy, dz)

    # make sure we have enough angle coverage
    modes,P = check_angle_sampling(nvecs, angles)

    # TODO: throw out modes?

    n = len(nvecs) + 3
    b = np.zeros(shape=(n, ))
    A = np.zeros(shape=(n,n))

    # top left block matrix: identity matrix summed over timesteps
    A[:3,:3] = len(aa)*np.identity(3)

    actions = aa[:,:3]
    angles = aa[:,3:]

    # top right block matrix: transpose of C_nk matrix (Eq. 12)
    C_T = 2.*nvecs.T * np.sum(np.cos(np.dot(nvecs,angles.T)), axis=-1)
    A[:3,3:] = C_T
    A[3:,:3] = C_T.T

    # lower right block matrix: C_nk dotted with C_nk^T
    cosv = np.cos(np.dot(nvecs,angles.T))
    A[3:,3:] = 4.*np.dot(nvecs,nvecs.T)*np.einsum('it,jt->ij', cosv, cosv)

    # b vector first three is just sum of toy actions
    b[:3] = np.sum(actions, axis=0)

    # rest of the vector is C dotted with actions
    b[3:] = np.sum(C_T.T.dot(actions.T),axis=1)

    return np.array(solve(A,b)), nvecs

def angle_solver(aa, t, N_max, dx, dy, dz):
    """
    TODO:

    """

    # unroll the angles so they increase continuously instead of wrap
    angles = unroll_angles(aa[:,3:])

    # generate integer vectors for fourier modes
    nvecs = generate_n_vectors(N_max, dx, dy, dz)

    # make sure we have enough angle coverage
    modes,P = check_angle_sampling(nvecs, angles)

    # TODO: throw out modes?
    # if(throw_out_modes):
    #     n_vectors = np.delete(n_vectors,check_each_direction(n_vectors,angs),axis=0)

    nv = len(nvecs)
    n = 3 + 3 + 3*nv # angle(0)'s, freqs, 3 derivatives of Sn

    b = np.zeros(shape=(n,))
    A = np.zeros(shape=(n,n))

    # top left block matrix: identity matrix summed over timesteps
    A[:3,:3] = len(aa)*np.identity(3)

    # identity matrices summed over times
    A[:3,3:6] = A[3:6,:3] = np.sum(t)*np.identity(3)
    A[3:6,3:6] = np.sum(t*t)*np.identity(3)

    # S1,2,3
    A[6:6+nv,0] = -2.*np.sum(np.sin(np.dot(nvecs,angles.T)),axis=1)
    A[6+nv:6+2*nv,1] = A[6:6+nv,0]
    A[6+2*nv:6+3*nv,2] = A[6:6+nv,0]

    # t*S1,2,3
    A[6:6+nv,3] = -2.*np.sum(t[None,:]*np.sin(np.dot(nvecs,angles.T)),axis=1)
    A[6+nv:6+2*nv,4] = A[6:6+nv,3]
    A[6+2*nv:6+3*nv,5] = A[6:6+nv,3]

    # lower right block structure: S dot S^T
    sinv = np.sin(np.dot(nvecs,angles.T))
    SdotST = np.einsum('it,jt->ij', sinv, sinv)
    A[6:6+nv,6:6+nv] = A[6+nv:6+2*nv,6+nv:6+2*nv] = \
        A[6+2*nv:6+3*nv,6+2*nv:6+3*nv] = SdotST

    # top rectangle
    A[:6,:] = A[:,:6].T

    b[:3] = np.sum(angles, axis=0)
    b[3:6] = np.sum(t[:,None]*angles, axis=0)
    b[6:6+nv] = -2.*np.sum(angles[:,0]*np.sin(np.dot(nvecs,angles.T)), axis=1)
    b[6+nv:6+2*nv] = -2.*np.sum(angles[:,1]*np.sin(np.dot(nvecs,angles.T)), axis=1)
    b[6+2*nv:6+3*nv] = -2.*np.sum(angles[:,2]*np.sin(np.dot(nvecs,angles.T)), axis=1)

    return np.array(solve(A,b)), nvecs

def find_box_actions(t, w, N_max=8):
    """
    Finds actions, angles, and frequencies for a box orbit.
    Takes a series of phase-space points, `w`, from an orbit integration at
    times `t`.

    This code is adapted from Jason Sanders'
    `genfunc <https://github.com/jlsanders/genfunc>`_

    Parameters
    ----------
    t : array_like
        Array of times with shape (ntimes,).
    w : array_like
        Phase-space orbit at times, `t`. Should have shape (ntimes,6).
    N_max : int
        Maximum integer Fourier mode vector length, |n|.
    """

    if w.ndim > 2:
        raise ValueError("w must be a single orbit")

    logger.debug("===== Using triaxial harmonic oscillator toy potential =====")

    t1 = time.time()

    # find best toy potential parameters
    potential = HarmonicOscillatorPotential(omega=[1.,1.,1.])
    def f(omega,w):
        potential.parameters['omega'] = omega
        H = potential.energy(w[...,:3], w[...,3:])
        return np.squeeze(H - np.median(H))

    p,ier = leastsq(f, np.array([10.,10.,10.]), args=(w,))

    if ier < 1 or ier > 4:
        raise ValueError("Failed to fit toy potential to orbit.")

    best_omega = np.abs(p)
    potential = HarmonicOscillatorPotential(omega=best_omega)
    logger.debug("Best omegas ({}) found in {} seconds".format(best_omega,time.time()-t1))

    # Now find toy actions and angles
    action,angle = potential.action_angle(w[...,:3], w[...,3:])
    aa = np.hstack((action,angle))
    if np.any(np.isnan(aa)):
        raise ValueError("NaN value in toy actions or angles!")

    t1 = time.time()
    actions,nvecs = action_solver(aa, N_max, dx=2, dy=2, dz=2)

    logger.debug("Action solution found for N_max={}, size {} symmetric"
                 " matrix in {} seconds"\
                 .format(N_max,len(actions),time.time()-t1))

    print(actions[:3])
    return

    np.savetxt("GF.Sn_box",np.vstack((act[1].T,act[0][3:])).T)

    ang = solver.angle_solver(AA,times,N_matrix,np.ones(3))
    if(ifprint):
        print("Angle solution found for N_max = "+str(N_matrix)+", size "+str(len(ang))+" symmetric matrix in "+str(time.time()-t)+" seconds")

    # Just some checks
    if(len(ang)>len(AA)):
        print("More unknowns than equations")

    return act[0], ang, act[1], AA, omega

def find_actions(t, w, N_max=8):
    """
    Find approximate actions and angles for samples of a phase-space orbit,
    `w`, at times `t`. Uses toy potentials with known, analytic action-angle
    transformations to approximate the true coordinates as a Fourier sum. Uses
    the formalism presented in Sanders & Binney (2014).

    This code is adapted from Jason Sanders'
    `genfunc <https://github.com/jlsanders/genfunc>`_

    Parameters
    ----------
    t : array_like
        Array of times with shape (ntimes,).
    w : array_like
        Phase-space orbits at times, `t`. Should have shape (ntimes,norbits,6).
    N_max : int
        Maximum integer Fourier mode vector length, |n|.
    """

    # first determine orbit
<|endoftext|>


<commit_before>import datetime
import pickle
import time
import threading
import sets

class Contest:
    verdicts = {'QU': 'In Queue',
                'CE': 'Compile Error',
                'AC': 'Accepted',
                'WA': 'Wrong Answer',
                'RE': 'Runtime Error',
                'TL': 'Time Limit Exceeded',
                'ML': 'Memory Limit Exceeded',
                'JE': 'Judging System Error'}

    def __init__(self, delay, duration, prob_ids, penalty, logger):
        """Initializes the contest.

        Parameter:
            delay - delay, in seconds, before starting the contest
            duration - duration, in seconds, of the contest
            problems - list of all prob_id's
        """
        assert delay >= 0
        assert duration >= 0
        self.init_time = int(time.time())
        self.start_time = self.init_time + delay
        self.end_time = self.start_time + duration
        self.prob_ids = prob_ids
        self.next_subm_id = 0
        self.submissions = {}
        self.scoreboard = []
        self.penalty = penalty
        self.frozen = False
        self.clarifs = []
        self.logger = logger

    def is_running(self):
        """Returns whether the contest is currently running."""
        return self.start_time <= time.time() < self.end_time

    def is_over(self):
        """Returns whether the contest is over."""
        return self.end_time <= time.time()

    def remaining_time(self):
        """Returns the remaining time of the contest in seconds."""
        now = time.time()
        if self.start_time - now > 0:
            return int(self.start_time - now)
        rem = int(self.end_time - now)
        return rem if rem > 0 else 0

    def extend(self, duration):
        """Extends the duration of the contest by duration.

        Parameters:
            duration - duration, in seconds, to extend the contest
        """
        self.end_time += duration

    def is_frozen(self):
        return self.frozen

    def freeze_scoreboard(self, freeze):
        """Freezes or unfreezes the scoreboard.

        Parameters:
            freeze - whether to freeze the scoreboard
        """
        if self.frozen == freeze:
            return
        self.frozen = freeze
        if freeze:
            self.scoreboard_copy = self.scoreboard
        else:
            self.scoreboard_copy = []

    def get_scoreboard(self, live=False):
        """Returns the current scoreboard or if the scoreboard is frozen,
        the scoreboard at the time of the freeze, unless live is set to
        True.

        Parameters:
            live - if this value is True, the scoreboard returned will always
                   be live, ignoring the frozen state of the scoreboard
        """
        return self.scoreboard if not self.frozen or live else self.scoreboard_copy

    def get_submissions(self, user_id):
        """Returns all submissions made by user_id sorted by submission time.

        Parameters:
            user_id - user id
        """
        return [self.submissions[subm_id] for subm_id in xrange(self.next_subm_id - 1, -1, -1)
                if self.submissions[subm_id]['user_id'] == user_id]

    def get_solved(self, user_id):
        """Returns whether each problem has been solved.

        Parameters:
            user_id - user id
        """
        solved = {prob_id: False for prob_id in self.prob_ids}
        for submission in self.get_submissions(user_id):
            if submission['result'] == 'AC':
                solved[submission['prob_id']] = True
        return solved

    def add_submission(self, user_id, prob_id, lang, submit_time, result='QU'):
        """Adds a submission result to the scoreboard.

        A submission is in the following format:
            {'user_id': ...,
             'prob_id': ...,
             'lang': ...,
             'submit_time': ...,
             'run_time': ...,
             'result': ...}

        Parameters:
            user_id - user id
            prob_id - problem id of submission
            submit_time - minute into contest of submission
            result - 'QU': In Queue
                     'CE': Compile Error
                     'JE': Judge System Error

                     'AC': Accepted
                     'WA': Wrong Answer
                     'RE': Runtime Error
                     'TL': Time Limit Exceeded
                     'ML': Memory Limit Exceeded
        """
        subm_id = self.next_subm_id
        self.next_subm_id += 1
        self.submissions[subm_id] = {'user_id': user_id,
                                     'prob_id': prob_id,
                                     'lang': lang,
                                     'submit_time': submit_time,
                                     'subm_id': subm_id,
                                     'run_time': 0.0,
                                     'result': result}
        self.logger.debug("submission: " + str(self.submissions[subm_id]))
        if result not in ('QU', 'CE', 'JE'):
            self.update_scoreboard()
        return subm_id

    def change_submission(self, subm_id, result, run_time=0.0):
        """Changes the result of a submission.

        Parameters:
            subm_id - id of the submission to change.
            result - see #add_submission(...) for valid results
        """
        self.submissions[subm_id]['result'] = result
        self.submissions[subm_id]['run_time'] = run_time
        self.update_scoreboard()

    def update_scoreboard(self):
        """Updates the scoreboard by recalculating each user's points and
        penalties.
        """
        points = {}
        for i in xrange(self.next_subm_id):
            s = self.submissions[i]
            u = s['user_id']
            if u not in points:
                points[u] = {'num_solved': 0, 'penalty': 0,
                             'solved': {pid: [-1, 0] for pid in self.prob_ids},
                             'accum': {pid: 0 for pid in self.prob_ids}}
            if points[u]['accum'][s['prob_id']] >= 0:
                if s['result'] == 'AC':
                    points[u]['solved'][s['prob_id']][1] += 1
                    points[u]['solved'][s['prob_id']][0] = s['submit_time']
                    points[u]['num_solved'] += 1
                    points[u]['penalty'] += points[u]['accum'][s['prob_id']]
                    points[u]['penalty'] += s['submit_time']
                    points[u]['accum'][s['prob_id']] = -1
                elif s['result'] not in ('QU', 'CE', 'JE'):
                    points[u]['solved'][s['prob_id']][1] += 1
                    points[u]['accum'][s['prob_id']] += self.penalty

        # Make solved negative to sort by highest score, and fix negative after.
        self.scoreboard = sorted([(-points[user_id]['num_solved'],
                                   points[user_id]['penalty'],
                                   user_id,
                                   points[user_id]['solved'])
                                   for user_id in points])
        self.scoreboard = [(c, -a, b, d) for a, b, c, d in self.scoreboard]

    def reset_scoreboard(self):
        """Clears the entire scoreboard.

        Used by the judge for rejudging problems, in the event that
        there were incorrect specifications.
        """
        self.next_subm_id = 0
        self.submissions = {}
        self.scoreboard = []

    def get_clarifs(self, user_id):
        """Gets the clarifications/responses for a user.

        Parameters:
            user_id - id of the user to query
        """
        if user_id == -1:
            return tuple(self.clarifs)
        return tuple(c for c in self.clarifs if not c['private'] or c['user_id'] == user_id)

    def submit_clarif(self, user_id, prob_id, message):
        """Submits a clarification request.

        Parameters:
            user_id - id of the user submitting a request
            prob_id - id of the problem in question
            message - a short description of the clarification request
        """
        self.clarifs.append({'user_id': user_id, 'prob_id': prob_id,
                             'message': message, 'response': None,
                             'private': True})

    def respond_clarif(self, clarif_id, response, private=True):
        """Responds to a clarification request.

        Parameters:
            clarif_id - id of the clarif to respond to
            response - response to the clarification
            private - whether response should be private to user who submitted
                the request (default: True)
        """
        try:
            self.clarifs[clarif_id]['response'] = response
            self.clarifs[clarif_id]['private'] = private
            return True
        except:
            return False

    def create_global_clarif(self, prob_id, response):
        try:
            self.clarifs.append({'user_id': -1, 'prob_id': prob_id,
                             'message': 'Judge Clarification', 'response': response,
                             'private': False})
            return True;
        except:
            return False;
<commit_msg>Added In-Judging (JU) status.<commit_after>import datetime
import pickle
import time
import threading
import sets

class Contest:
    verdicts = {'QU': 'In Queue',
                'CJ': 'Judging',
                'CE': 'Compile Error',
                'AC': 'Accepted',
                'WA': 'Wrong Answer',
                'RE': 'Runtime Error',
                'TL': 'Time Limit Exceeded',
                'ML': 'Memory Limit Exceeded',
                'JE': 'Judging System Error'}

    def __init__(self, delay, duration, prob_ids, penalty, logger):
        """Initializes the contest.

        Parameter:
            delay - delay, in seconds, before starting the contest
            duration - duration, in seconds, of the contest
            problems - list of all prob_id's
        """
        assert delay >= 0
        assert duration >= 0
        self.init_time = int(time.time())
        self.start_time = self.init_time + delay
        self.end_time = self.start_time + duration
        self.prob_ids = prob_ids
        self.next_subm_id = 0
        self.submissions = {}
        self.scoreboard = []
        self.penalty = penalty
        self.frozen = False
        self.clarifs = []
        self.logger = logger

    def is_running(self):
        """Returns whether the contest is currently running."""
        return self.start_time <= time.time() < self.end_time

    def is_over(self):
        """Returns whether the contest is over."""
        return self.end_time <= time.time()

    def remaining_time(self):
        """Returns the remaining time of the contest in seconds."""
        now = time.time()
        if self.start_time - now > 0:
            return int(self.start_time - now)
        rem = int(self.end_time - now)
        return rem if rem > 0 else 0

    def extend(self, duration):
        """Extends the duration of the contest by duration.

        Parameters:
            duration - duration, in seconds, to extend the contest
        """
        self.end_time += duration

    def is_frozen(self):
        return self.frozen

    def freeze_scoreboard(self, freeze):
        """Freezes or unfreezes the scoreboard.

        Parameters:
            freeze - whether to freeze the scoreboard
        """
        if self.frozen == freeze:
            return
        self.frozen = freeze
        if freeze:
            self.scoreboard_copy = self.scoreboard
        else:
            self.scoreboard_copy = []

    def get_scoreboard(self, live=False):
        """Returns the current scoreboard or if the scoreboard is frozen,
        the scoreboard at the time of the freeze, unless live is set to
        True.

        Parameters:
            live - if this value is True, the scoreboard returned will always
                   be live, ignoring the frozen state of the scoreboard
        """
        return self.scoreboard if not self.frozen or live else self.scoreboard_copy

    def get_submissions(self, user_id):
        """Returns all submissions made by user_id sorted by submission time.

        Parameters:
            user_id - user id
        """
        return [self.submissions[subm_id] for subm_id in xrange(self.next_subm_id - 1, -1, -1)
                if self.submissions[subm_id]['user_id'] == user_id]

    def get_solved(self, user_id):
        """Returns whether each problem has been solved.

        Parameters:
            user_id - user id
        """
        solved = {prob_id: False for prob_id in self.prob_ids}
        for submission in self.get_submissions(user_id):
            if submission['result'] == 'AC':
                solved[submission['prob_id']] = True
        return solved

    def add_submission(self, user_id, prob_id, lang, submit_time, result='QU'):
        """Adds a submission result to the scoreboard.

        A submission is in the following format:
            {'user_id': ...,
             'prob_id': ...,
             'lang': ...,
             'submit_time': ...,
             'run_time': ...,
             'result': ...}

        Parameters:
            user_id - user id
            prob_id - problem id of submission
            submit_time - minute into contest of submission
            result - 'QU': In Queue
                     'CJ': Judging
                     'CE': Compile Error
                     'JE': Judge System Error

                     'AC': Accepted
                     'WA': Wrong Answer
                     'RE': Runtime Error
                     'TL': Time Limit Exceeded
                     'ML': Memory Limit Exceeded
        """
        subm_id = self.next_subm_id
        self.next_subm_id += 1
        self.submissions[subm_id] = {'user_id': user_id,
                                     'prob_id': prob_id,
                                     'lang': lang,
                                     'submit_time': submit_time,
                                     'subm_id': subm_id,
                                     'run_time': 0.0,
                                     'result': result}
        self.logger.debug("submission: " + str(self.submissions[subm_id]))
        if result not in ('QU', 'CJ', 'CE', 'JE'):
            self.update_scoreboard()
        return subm_id

    def change_submission(self, subm_id, result, run_time=0.0):
        """Changes the result of a submission.

        Parameters:
            subm_id - id of the submission to change.
            result - see #add_submission(...) for valid results
        """
        self.submissions[subm_id]['result'] = result
        self.submissions[subm_id]['run_time'] = run_time
        self.update_scoreboard()

    def update_scoreboard(self):
        """Updates the scoreboard by recalculating each user's points and
        penalties.
        """
        points = {}
        for i in xrange(self.next_subm_id):
            s = self.submissions[i]
            u = s['user_id']
            if u not in points:
                points[u] = {'num_solved': 0, 'penalty': 0,
                             'solved': {pid: [-1, 0] for pid in self.prob_ids},
                             'accum': {pid: 0 for pid in self.prob_ids}}
            if points[u]['accum'][s['prob_id']] >= 0:
                if s['result'] == 'AC':
                    points[u]['solved'][s['prob_id']][1] += 1
                    points[u]['solved'][s['prob_id']][0] = s['submit_time']
                    points[u]['num_solved'] += 1
                    points[u]['penalty'] += points[u]['accum'][s['prob_id']]
                    points[u]['penalty'] += s['submit_time']
                    points[u]['accum'][s['prob_id']] = -1
                elif s['result'] not in ('QU', 'CJ', 'CE', 'JE'):
                    points[u]['solved'][s['prob_id']][1] += 1
                    points[u]['accum'][s['prob_id']] += self.penalty

        # Make solved negative to sort by highest score, and fix negative after.
        self.scoreboard = sorted([(-points[user_id]['num_solved'],
                                   points[user_id]['penalty'],
                                   user_id,
                                   points[user_id]['solved'])
                                   for user_id in points])
        self.scoreboard = [(c, -a, b, d) for a, b, c, d in self.scoreboard]

    def reset_scoreboard(self):
        """Clears the entire scoreboard.

        Used by the judge for rejudging problems, in the event that
        there were incorrect specifications.
        """
        self.next_subm_id = 0
        self.submissions = {}
        self.scoreboard = []

    def get_clarifs(self, user_id):
        """Gets the clarifications/responses for a user.

        Parameters:
            user_id - id of the user to query
        """
        if user_id == -1:
            return tuple(self.clarifs)
        return tuple(c for c in self.clarifs if not c['private'] or c['user_id'] == user_id)

    def submit_clarif(self, user_id, prob_id, message):
        """Submits a clarification request.

        Parameters:
            user_id - id of the user submitting a request
            prob_id - id of the problem in question
            message - a short description of the clarification request
        """
        self.clarifs.append({'user_id': user_id, 'prob_id': prob_id,
                             'message': message, 'response': None,
                             'private': True})

    def respond_clarif(self, clarif_id, response, private=True):
        """Responds to a clarification request.

        Parameters:
            clarif_id - id of the clarif to respond to
            response - response to the clarification
            private - whether response should be private to user who submitted
                the request (default: True)
        """
        try:
            self.clarifs[clarif_id]['response'] = response
            self.clarifs[clarif_id]['private'] = private
            return True
        except:
            return False

    def create_global_clarif(self, prob_id, response):
        try:
            self.clarifs.append({'user_id': -1, 'prob_id': prob_id,
                             'message': 'Judge Clarification', 'response': response,
                             'private': False})
            return True;
        except:
            return False;
<|endoftext|>