예제 #1
0
    def test_get_cntl(self):
        ma27 = MA27Interface()
        self.assertEqual(ma27.get_icntl(1), 6)

        self.assertAlmostEqual(ma27.get_cntl(1),
                               1e-1)  # Numerical pivot threshold
        self.assertAlmostEqual(ma27.get_cntl(3), 0.0)  # Null pivot threshold
예제 #2
0
    def test_do_numeric_factorization(self):
        ma27 = MA27Interface()

        n = 5
        ne = 7
        irn = np.array([1, 1, 2, 2, 3, 3, 5], dtype=np.intc)
        icn = np.array([1, 2, 3, 5, 3, 4, 5], dtype=np.intc)
        irn = irn - 1
        icn = icn - 1
        ent = np.array([2., 3., 4., 6., 1., 5., 1.], dtype=np.double)
        ma27.do_symbolic_factorization(n, irn, icn)

        status = ma27.do_numeric_factorization(irn, icn, n, ent)
        self.assertEqual(status, 0)

        expected_ent = [
            2.,
            3.,
            4.,
            6.,
            1.,
            5.,
            1.,
        ]
        for i in range(ne):
            self.assertAlmostEqual(ent[i], expected_ent[i])

        self.assertEqual(ma27.get_info(15), 2)  # 2 negative eigenvalues
        self.assertEqual(ma27.get_info(14), 1)  # 1 2x2 pivot

        # Check that we can successfully perform another numeric factorization
        # with same symbolic factorization
        ent2 = np.array([1.5, 5.4, 1.2, 6.1, 4.2, 3.3, 2.0], dtype=np.double)
        status = ma27.do_numeric_factorization(irn, icn, n, ent2)
        self.assertEqual(ma27.get_info(15), 2)
        self.assertEqual(status, 0)

        bad_ent = np.array([2., 3., 4., 6., 1., 5.], dtype=np.double)
        with self.assertRaisesRegex(AssertionError, 'Wrong number of entries'):
            ma27.do_numeric_factorization(irn, icn, n, bad_ent)
        with self.assertRaisesRegex(AssertionError, 'Dimension mismatch'):
            ma27.do_numeric_factorization(irn, icn, n + 1, ent)

        # Check that we can successfully perform another symbolic and
        # numeric factorization with the same ma27 struct
        #
        # n is still 5, ne has changed to 8.
        irn = np.array([1, 1, 2, 2, 3, 3, 5, 1], dtype=np.intc)
        icn = np.array([1, 2, 3, 5, 3, 4, 5, 5], dtype=np.intc)
        irn = irn - 1
        icn = icn - 1
        ent = np.array([2., 3., 4., 6., 1., 5., 1., 3.], dtype=np.double)
        status = ma27.do_symbolic_factorization(n, irn, icn)
        self.assertEqual(status, 0)
        status = ma27.do_numeric_factorization(irn, icn, n, ent)
        self.assertEqual(status, 0)
        self.assertEqual(ma27.get_info(15), 3)
예제 #3
0
    def __init__(self, cntl_options=None, icntl_options=None, iw_factor=1.2, a_factor=2):
        self._ma27 = MA27Interface(iw_factor=iw_factor, a_factor=a_factor)

        if cntl_options is None:
            cntl_options = dict()
        if icntl_options is None:
            icntl_options = dict()

        for k, v in cntl_options.items():
            self.set_cntl(k, v)
        for k, v in icntl_options.items():
            self.set_icntl(k, v)

        self._dim = None
        self._num_status = None
예제 #4
0
    def test_set_icntl(self):
        ma27 = MA27Interface()
        ma27.set_icntl(5, 4)  # Set output printing to max verbosity
        ma27.set_icntl(8, 1)  # Keep factors when we run out of space
        # (so MA27ED can be used)
        icntl5 = ma27.get_icntl(5)
        icntl8 = ma27.get_icntl(8)
        self.assertEqual(icntl5, 4)
        self.assertEqual(icntl8, 1)

        with self.assertRaisesRegex(TypeError, 'must be an integer'):
            ma27.set_icntl(1.0, 0)
        with self.assertRaisesRegex(IndexError, 'is out of range'):
            ma27.set_icntl(100, 0)
        with self.assertRaises(ctypes.ArgumentError):
            ma27.set_icntl(1, 0.0)
예제 #5
0
    def test_do_backsolve(self):
        ma27 = MA27Interface()

        n = 5
        ne = 7
        irn = np.array([1, 1, 2, 2, 3, 3, 5], dtype=np.intc)
        icn = np.array([1, 2, 3, 5, 3, 4, 5], dtype=np.intc)
        irn = irn - 1
        icn = icn - 1
        ent = np.array([2., 3., 4., 6., 1., 5., 1.], dtype=np.double)
        rhs = np.array([8., 45., 31., 15., 17.], dtype=np.double)
        status = ma27.do_symbolic_factorization(n, irn, icn)
        status = ma27.do_numeric_factorization(irn, icn, n, ent)
        sol = ma27.do_backsolve(rhs)

        expected_sol = [1, 2, 3, 4, 5]
        old_rhs = np.array([8., 45., 31., 15., 17.])
        for i in range(n):
            self.assertAlmostEqual(sol[i], expected_sol[i])
            self.assertEqual(old_rhs[i], rhs[i])
예제 #6
0
    def test_do_backsolve(self):
        ma27 = MA27Interface()

        n = 5
        ne = 7
        irn = np.array([1, 1, 2, 2, 3, 3, 5], dtype=np.intc)
        icn = np.array([1, 2, 3, 5, 3, 4, 5], dtype=np.intc)
        ent = np.array([2., 3., 4., 6., 1., 5., 1.], dtype=np.double)
        irn = irn - 1
        icn = icn - 1
        rhs = np.array([8., 45., 31., 15., 17.], dtype=np.double)
        status = ma27.do_symbolic_factorization(n, irn, icn)
        status = ma27.do_numeric_factorization(irn, icn, n, ent)
        sol = ma27.do_backsolve(rhs)

        expected_sol = [1, 2, 3, 4, 5]
        old_rhs = np.array([8., 45., 31., 15., 17.])
        for i in range(n):
            self.assertAlmostEqual(sol[i], expected_sol[i])
            self.assertEqual(old_rhs[i], rhs[i])

        # Check that we can perform a numeric factorization with different ordering
        irn_mod = np.array([1, 2, 2, 1, 3, 3, 5], dtype=np.intc)
        icn_mod = np.array([2, 3, 5, 1, 3, 4, 5], dtype=np.intc)
        ent_mod = np.array([3., 4., 6., 2., 1., 5., 1.], dtype=np.double)
        irn_mod -= 1
        icn_mod -= 1
        status = ma27.do_numeric_factorization(irn_mod, icn_mod, n, ent_mod)
        sol = ma27.do_backsolve(rhs)
        self.assertTrue(np.allclose(sol, np.array(expected_sol)))

        # Check that we can perform a numeric factorization with differnt lengths
        # due to extra zero entries
        irn_mod = irn_mod[1:]
        icn_mod = icn_mod[1:]
        ent_mod = ent_mod[1:]
        status = ma27.do_numeric_factorization(irn_mod, icn_mod, n, ent_mod)
        sol = ma27.do_backsolve(rhs)
        expected_sol = np.array([4.0, 1.91666666667, 3.0, 4.06666666667, 5.5])
        self.assertTrue(np.allclose(sol, expected_sol))
예제 #7
0
    def test_do_symbolic_factorization(self):
        ma27 = MA27Interface()

        n = 5
        ne = 7
        irn = np.array([1,1,2,2,3,3,5], dtype=np.intc)
        icn = np.array([1,2,3,5,3,4,5], dtype=np.intc)
        # These arrays, copied out of HSL docs, contain Fortran indices.
        # Interfaces accept C indices as this is what I typically expect.
        irn = irn - 1
        icn = icn - 1

        bad_icn = np.array([1,2,3,5,3,4], dtype=np.intc)
        # ^No need to update these indices

        ma27.do_symbolic_factorization(n, irn, icn)

        self.assertEqual(ma27.get_info(1), 0)
        self.assertEqual(ma27.get_info(5), 14) # Min required num. integer words
        self.assertEqual(ma27.get_info(6), 20) # Min required num. real words

        with self.assertRaisesRegex(AssertionError, 'Dimension mismatch'):
            ma27.do_symbolic_factorization(n, irn, bad_icn)
예제 #8
0
import unittest
from pyomo.common.dependencies import attempt_import
import numpy as np
from scipy.sparse import coo_matrix, tril
import parapint
from pyomo.contrib.pynumero.linalg.ma27 import MA27Interface

ma27_available = MA27Interface.available()
mumps, mumps_available = attempt_import('mumps')


def get_base_matrix(use_tril):
    if use_tril:
        row = [0, 1, 1, 2, 2]
        col = [0, 0, 1, 0, 2]
        data = [1, 7, 4, 3, 6]
    else:
        row = [0, 0, 0, 1, 1, 2, 2]
        col = [0, 1, 2, 0, 1, 0, 2]
        data = [1, 7, 3, 7, 4, 3, 6]
    mat = coo_matrix((data, (row, col)), shape=(3,3), dtype=np.double)
    return mat


def get_base_matrix_wrong_order(use_tril):
    if use_tril:
        row = [1, 0, 1, 2, 2]
        col = [0, 0, 1, 0, 2]
        data = [7, 1, 4, 3, 6]
    else:
        row = [1, 0, 0, 0, 1, 2, 2]
예제 #9
0
 def test_set_cntl(self):
     ma27 = MA27Interface()
     ma27.set_cntl(1, 1e-8)
     ma27.set_cntl(3, 1e-12)
     self.assertAlmostEqual(ma27.get_cntl(1), 1e-8)
     self.assertAlmostEqual(ma27.get_cntl(3), 1e-12)
예제 #10
0
#  Copyright (c) 2008-2022
#  National Technology and Engineering Solutions of Sandia, LLC
#  Under the terms of Contract DE-NA0003525 with National Technology and
#  Engineering Solutions of Sandia, LLC, the U.S. Government retains certain
#  rights in this software.
#  This software is distributed under the 3-clause BSD License.
#  ___________________________________________________________________________
import pyomo.common.unittest as unittest
from pyomo.contrib.pynumero.dependencies import numpy as np, numpy_available
if not numpy_available:
    raise unittest.SkipTest('pynumero MA27 tests require numpy')
import ctypes
from pyomo.contrib.pynumero.linalg.ma27 import MA27Interface


@unittest.skipIf(not MA27Interface.available(), reason='MA27 not available')
class TestMA27Interface(unittest.TestCase):
    def test_get_cntl(self):
        ma27 = MA27Interface()
        self.assertEqual(ma27.get_icntl(1), 6)

        self.assertAlmostEqual(ma27.get_cntl(1),
                               1e-1)  # Numerical pivot threshold
        self.assertAlmostEqual(ma27.get_cntl(3), 0.0)  # Null pivot threshold

    def test_set_icntl(self):
        ma27 = MA27Interface()
        ma27.set_icntl(5, 4)  # Set output printing to max verbosity
        ma27.set_icntl(8, 1)  # Keep factors when we run out of space
        # (so MA27ED can be used)
        icntl5 = ma27.get_icntl(5)
예제 #11
0
class TestLinearSolvers(unittest.TestCase):
    def create_blocks(self, m: np.ndarray, x: np.ndarray):
        m = coo_matrix(m)
        r = m * x
        bm = BlockMatrix(2, 2)
        bm.set_block(0, 0, m.copy())
        bm.set_block(1, 1, m.copy())
        br = BlockVector(2)
        br.set_block(0, r.copy())
        br.set_block(1, r.copy())
        bx = BlockVector(2)
        bx.set_block(0, x.copy())
        bx.set_block(1, x.copy())
        return bm, bx, br

    def solve_helper(self, m: np.ndarray, x: np.ndarray, solver: LinearSolverInterface):
        bm, bx, br = self.create_blocks(m, x)
        bx2, res = solver.solve(bm, br)
        self.assertEqual(res.status, LinearSolverStatus.successful)
        err = np.max(np.abs(bx - bx2))
        self.assertAlmostEqual(err, 0)

    def symmetric_helper(self, solver: LinearSolverInterface):
        m = np.array([[1, 2], [2, -1]], dtype=np.double)
        x = np.array([4, 7], dtype=np.double)
        self.solve_helper(m, x, solver)

    def unsymmetric_helper(self, solver: LinearSolverInterface):
        m = np.array([[1, 2], [0, -1]], dtype=np.double)
        x = np.array([4, 7], dtype=np.double)
        self.solve_helper(m, x, solver)

    def singular_helper(self, solver: LinearSolverInterface):
        m = np.array([[1, 1], [1, 1]], dtype=np.double)
        x = np.array([4, 7], dtype=np.double)
        bm, bx, br = self.create_blocks(m, x)
        br.get_block(0)[1] += 1
        br.get_block(1)[1] += 1
        bx2, res = solver.solve(bm, br, raise_on_error=False)
        self.assertNotEqual(res.status, LinearSolverStatus.successful)

    @unittest.skipIf(not MA27Interface.available(), reason="MA27 not available")
    def test_ma27(self):
        solver = MA27()
        self.symmetric_helper(solver)
        self.singular_helper(solver)

    @unittest.skipIf(not MA57Interface.available(), reason="MA57 not available")
    def test_ma57(self):
        solver = MA57()
        self.symmetric_helper(solver)
        self.singular_helper(solver)

    def test_scipy_direct(self):
        solver = ScipyLU()
        self.symmetric_helper(solver)
        self.unsymmetric_helper(solver)
        self.singular_helper(solver)

    def test_scipy_iterative(self):
        solver = ScipyIterative(gmres)
        solver.options["atol"] = 1e-8
        self.symmetric_helper(solver)
        self.unsymmetric_helper(solver)
        self.singular_helper(solver)

    @unittest.skipIf(not mumps_available, reason="mumps not available")
    def test_mumps(self):
        solver = MumpsCentralizedAssembledLinearSolver(sym=2)
        self.symmetric_helper(solver)
        self.singular_helper(solver)
        solver = MumpsCentralizedAssembledLinearSolver(sym=0)
        self.unsymmetric_helper(solver)