# Path: distributions/tests/util.py
# def require_cython():
#     if not distributions.has_cython:
#         raise SkipTest('no cython support')
# 
# def assert_close(lhs, rhs, tol=TOL, err_msg=None):
#     try:
#         if isinstance(lhs, dict):
#             assert_true(
#                 isinstance(rhs, dict),
#                 'type mismatch: {} vs {}'.format(type(lhs), type(rhs)))
#             assert_equal(set(lhs.keys()), set(rhs.keys()))
#             for key, val in lhs.iteritems():
#                 msg = '{}[{}]'.format(err_msg or '', key)
#                 assert_close(val, rhs[key], tol, msg)
#         elif isinstance(lhs, float) or isinstance(lhs, numpy.float64):
#             assert_true(
#                 isinstance(rhs, float) or isinstance(rhs, numpy.float64),
#                 'type mismatch: {} vs {}'.format(type(lhs), type(rhs)))
#             diff = abs(lhs - rhs)
#             norm = 1 + abs(lhs) + abs(rhs)
#             msg = '{} off by {}% = {}'.format(
#                 err_msg or '',
#                 100 * diff / norm,
#                 diff)
#             assert_less(diff, tol * norm, msg)
#         elif isinstance(lhs, numpy.ndarray) or isinstance(rhs, numpy.ndarray):
#             assert_true(
#                 (isinstance(lhs, numpy.ndarray) or isinstance(lhs, list)) and
#                 (isinstance(rhs, numpy.ndarray) or isinstance(rhs, list)),
#                 'type mismatch: {} vs {}'.format(type(lhs), type(rhs)))
#             decimal = int(round(-math.log10(tol)))
#             assert_array_almost_equal(
#                 lhs,
#                 rhs,
#                 decimal=decimal,
#                 err_msg=(err_msg or ''))
#         elif isinstance(lhs, list) or isinstance(lhs, tuple):
#             assert_true(
#                 isinstance(rhs, list) or isinstance(rhs, tuple),
#                 'type mismatch: {} vs {}'.format(type(lhs), type(rhs)))
#             for pos, (x, y) in enumerate(izip(lhs, rhs)):
#                 msg = '{}[{}]'.format(err_msg or '', pos)
#                 assert_close(x, y, tol, msg)
#         else:
#             assert_equal(lhs, rhs, err_msg)
#     except Exception:
#         print err_msg or ''
#         print 'actual = {}'.format(print_short(lhs))
#         print 'expected = {}'.format(print_short(rhs))
#         raise


import numpy
from nose.tools import assert_equal
from distributions.tests.util import require_cython, assert_close
    from distributions.lp.special import log_stirling1_row
#
# - Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in the
#   documentation and/or other materials provided with the distribution.
# - Neither the name of Salesforce.com nor the names of its contributors
#   may be used to endorse or promote products derived from this
#   software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



def test_log_stirling1_row():
    require_cython()
    MAX_N = 128

    rows = [[1]]
    for n in range(1, MAX_N + 1):

# Path: distributions/tests/util.py
# def require_cython():
#     if not distributions.has_cython:
#         raise SkipTest('no cython support')
# 
# def assert_close(lhs, rhs, tol=TOL, err_msg=None):
#     try:
#         if isinstance(lhs, dict):
#             assert_true(
#                 isinstance(rhs, dict),
#                 'type mismatch: {} vs {}'.format(type(lhs), type(rhs)))
#             assert_equal(set(lhs.keys()), set(rhs.keys()))
#             for key, val in lhs.iteritems():
#                 msg = '{}[{}]'.format(err_msg or '', key)
#                 assert_close(val, rhs[key], tol, msg)
#         elif isinstance(lhs, float) or isinstance(lhs, numpy.float64):
#             assert_true(
#                 isinstance(rhs, float) or isinstance(rhs, numpy.float64),
#                 'type mismatch: {} vs {}'.format(type(lhs), type(rhs)))
#             diff = abs(lhs - rhs)
#             norm = 1 + abs(lhs) + abs(rhs)
#             msg = '{} off by {}% = {}'.format(
#                 err_msg or '',
#                 100 * diff / norm,
#                 diff)
#             assert_less(diff, tol * norm, msg)
#         elif isinstance(lhs, numpy.ndarray) or isinstance(rhs, numpy.ndarray):
#             assert_true(
#                 (isinstance(lhs, numpy.ndarray) or isinstance(lhs, list)) and
#                 (isinstance(rhs, numpy.ndarray) or isinstance(rhs, list)),
#                 'type mismatch: {} vs {}'.format(type(lhs), type(rhs)))
#             decimal = int(round(-math.log10(tol)))
#             assert_array_almost_equal(
#                 lhs,
#                 rhs,
#                 decimal=decimal,
#                 err_msg=(err_msg or ''))
#         elif isinstance(lhs, list) or isinstance(lhs, tuple):
#             assert_true(
#                 isinstance(rhs, list) or isinstance(rhs, tuple),
#                 'type mismatch: {} vs {}'.format(type(lhs), type(rhs)))
#             for pos, (x, y) in enumerate(izip(lhs, rhs)):
#                 msg = '{}[{}]'.format(err_msg or '', pos)
#                 assert_close(x, y, tol, msg)
#         else:
#             assert_equal(lhs, rhs, err_msg)
#     except Exception:
#         print err_msg or ''
#         print 'actual = {}'.format(print_short(lhs))
#         print 'expected = {}'.format(print_short(rhs))
#         raise


# Path: distributions/tests/test_special.py
import numpy
from nose.tools import assert_equal
from distributions.tests.util import require_cython, assert_close
    from distributions.lp.special import log_stirling1_row

#
# - Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in the
#   documentation and/or other materials provided with the distribution.
# - Neither the name of Salesforce.com nor the names of its contributors
#   may be used to endorse or promote products derived from this
#   software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



def test_log_stirling1_row():
    require_cython()
    MAX_N = 128

    rows = [[1]]
    for n in range(1, MAX_N + 1):

        prev = rows[-1]