def _test():
     size1, size2 = 6, 6
     numpy_A, vcl_A = getter1(size1, size2, layout, dt, A_form)
     numpy_b, vcl_b = getter2(size1, dt)
     vcl_x = p.solve(vcl_A, vcl_b, forms_tags[A_form])
     act_diff = math.fabs(diff(vcl_A.dot(vcl_x), vcl_b))
     assert act_diff <= tol, "diff was {} > tolerance {}".format(act_diff, tol)
def _solve_cuda(lap_sparse, B, return_full_prob=False, maxiter=100, tol=5e-5):
    # get row col data
    lap_size = lap_sparse.get_shape()
    lap_sparse = lap_sparse.tocoo()
    rows = lap_sparse.row
    cols = lap_sparse.col
    data = lap_sparse.data
    lap_p = p.CompressedMatrix(lap_size[0], lap_size[1])
    for row, col, val in zip(rows, cols, data):
        row = int(row)
        col = int(col)
        lap_p[row, col] = float(val)
    X = []
    for i in range(len(B)):
        bi = -B[i].todense()
        bi = np.asarray(bi)
        bi = bi.reshape(-1)
        bi = bi.astype('float64')
        B_p = p.Vector(bi)
        x = p.solve(lap_p, B_p, p.upper_tag())
        X.append(x)
    if not return_full_prob:
        X = np.array(X)
        X = np.argmax(X, axis=0)
    return X
        def _test():
            solver_tag = solver_tag_type(tolerance=tol / 10)
            precond_tag = precond_tag_type()

            vcl_system = sparse_type.generate_fdm_laplace(points_x_y, points_x_y, dtype=dt, context=default_context)
            # vcl_system = get_sparse_matrix(10, dtype=dt, sparse_type=sparse_type)

            numpy_solution, vcl_solution = vector_getter(
                vcl_system.size1, dt, vector=np.ones(vcl_system.size1).astype(dt)
            )

            numpy_rhs, vcl_rhs = vector_getter(vcl_system.size1, dt, vector=vcl_system * vcl_solution)

            # solve using pyviennacl
            vcl_solution = p.solve(vcl_system, vcl_rhs, solver_tag, precond_tag)

            # compare with known solution
            act_diff = math.fabs(diff(vcl_rhs, vcl_system.dot(vcl_solution)))
            assert act_diff <= tol, "diff was {} > tolerance {}".format(act_diff, tol)
            del solver_tag, precond_tag, vcl_system, vcl_solution, vcl_rhs
Example #4
0
def test_kernel(*args, **kwargs):
    """
    A, A_trans, B, B_trans must be numpy array or matrix instances
    """

    epsilon = args[0]
    A_upper, A_unit_upper, A_lower, A_unit_lower, A_trans_upper, A_trans_unit_upper, A_trans_lower, A_trans_unit_lower = args[1]
    B, B_trans = args[2]
    vcl_A_upper, vcl_A_unit_upper, vcl_A_lower, vcl_A_unit_lower, vcl_A_trans_upper, vcl_A_trans_unit_upper, vcl_A_trans_lower, vcl_A_trans_unit_lower = args[3]
    vcl_B, vcl_B_trans = args[4]

    Bvec = B[::, 0]
    vcl_Bvec = p.Vector(vcl_B.value[::, 0]) # TODO: get rid of .value
    if not (Bvec == vcl_Bvec).all():
        print(Bvec)
        print(vcl_Bvec)
        raise RuntimeError("Failed creating B vector")

    # A \ B
    vcl_X = p.solve(vcl_A_upper, vcl_B, p.upper_tag())
    X = sp.solve(A_upper, B)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B for upper triangular A: %s" % act_diff)
    print("Test passed: solving A \ B for upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_unit_upper, vcl_B, p.unit_upper_tag())
    X = sp.solve(A_unit_upper, B)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B for unit upper triangular A: %s" % act_diff)
    print("Test passed: solving A \ B for unit upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_lower, vcl_B, p.lower_tag())
    X = sp.solve(A_lower, B, lower = True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B for lower triangular A: %s" % act_diff)
    print("Test passed: solving A \ B for lower triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_unit_lower, vcl_B, p.unit_lower_tag())
    X = sp.solve(A_unit_lower, B, lower = True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B for unit lower triangular A: %s" % act_diff)
    print("Test passed: solving A \ B for unit lower triangular A: %s" % act_diff)

    # A^T \ B
    vcl_X = p.solve(vcl_A_trans_upper, vcl_B, p.upper_tag())
    X = sp.solve(A_trans_upper, B)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A^T \ B for upper triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B for upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_trans_unit_upper, vcl_B, p.unit_upper_tag())
    X = sp.solve(A_trans_unit_upper, B)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A^T \ B for unit upper triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B for unit upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_trans_lower, vcl_B, p.lower_tag())
    X = sp.solve(A_trans_lower, B, lower = True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A^T \ B for lower triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B for lower triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_trans_unit_lower, vcl_B, p.unit_lower_tag())
    X = sp.solve(A_trans_unit_lower, B, lower = True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A^T \ B for unit lower triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B for unit lower triangular A: %s" % act_diff)

    # A \ B^T
    vcl_X = p.solve(vcl_A_upper, vcl_B_trans, p.upper_tag())
    X = sp.solve(A_upper, B_trans)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B^T for upper triangular A: %s" % act_diff)
    print("Test passed: solving A \ B^T for upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_unit_upper, vcl_B_trans, p.unit_upper_tag())
    X = sp.solve(A_unit_upper, B_trans)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B^T for unit upper triangular A: %s" % act_diff)
    print("Test passed: solving A \ B^T for unit upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_lower, vcl_B_trans, p.lower_tag())
    X = sp.solve(A_lower, B_trans, lower = True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B^T for lower triangular A: %s" % act_diff)
    print("Test passed: solving A \ B^T for lower triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_unit_lower, vcl_B_trans, p.unit_lower_tag())
    X = sp.solve(A_unit_lower, B_trans, lower = True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B^T for unit lower triangular A: %s" % act_diff)
    print("Test passed: solving A \ B^T for unit lower triangular A: %s" % act_diff)

    # A^T \ B^T
    vcl_X = p.solve(vcl_A_trans_upper, vcl_B_trans, p.upper_tag())
    X = sp.solve(A_trans_upper, B_trans)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A^T \ B^T for upper triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B^T for upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_trans_unit_upper, vcl_B_trans, p.unit_upper_tag())
    X = sp.solve(A_trans_unit_upper, B_trans)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A^T \ B^T for unit upper triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B^T for unit upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_trans_lower, vcl_B_trans, p.lower_tag())
    X = sp.solve(A_trans_lower, B_trans, lower = True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A^T \ B^T for lower triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B^T for lower triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_trans_unit_lower, vcl_B_trans, p.unit_lower_tag())
    X = sp.solve(A_trans_unit_lower, B_trans, lower = True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A^T \ B^T for unit lower triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B^T for unit lower triangular A: %s" % act_diff)

    # GMRES
    vcl_X = p.solve(vcl_A_upper, vcl_Bvec, p.gmres_tag(tolerance=(epsilon/10)))
    X, info = spsp.gmres(A_upper, Bvec, tol=(epsilon/10))
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ b using GMRES: %s" % act_diff)
    print("Test passed: solving A \ b using GMRES: %s" % act_diff)

    # CG -- TODO: need a symmetric positive definite matrix for test
    #vcl_X = p.solve(vcl_A_upper, vcl_Bvec, p.cg_tag())
    #X, info = spsp.cg(A_upper, Bvec)
    #act_diff = math.fabs(diff(X, vcl_X))
    #if act_diff > epsilon:
    #    raise RuntimeError("Failed solving A \ b using CG: %s" % act_diff)
    #print("Test passed: solving A \ b using CG: %s" % act_diff)

    # BiCGStab -- TODO: need a non-symmetric matrix for test
    #vcl_X = p.solve(vcl_A_upper, vcl_Bvec, p.cg_tag())
    #X, info = spsp.cg(A_upper, Bvec)
    #act_diff = math.fabs(diff(X, vcl_X))
    #if act_diff > epsilon:
    #    raise RuntimeError("Failed solving A \ b using CG: %s" % act_diff)
    #print("Test passed: solving A \ b using CG: %s" % act_diff)

    # TODO: in-place solvers

    return os.EX_OK
Example #5
0
# We want a square N x N system.
N = 5 

# Create a NumPy matrix with float32 precision to hold the data on the host.
# Firstly, we create an empty matrix, then fill the upper triangle with values.
A = np.zeros((N, N), dtype = np.float32)

for i in range(N):
    for j in range(N):
        if j >= i:
            A[i, j] = np.float32(random.randint(0,1000) / 100.0)

# Transfer the system matrix to the compute device
A = p.Matrix(A)

print("A is\n%s" % A)

# Create a right-hand-side vector on the host with random elements
# and transfer it to the compute device
b = p.Vector(np.random.rand(N).astype(np.float32))

print("b is %s" % b)

# Solve the system; note the choice of tag to denote an upper triangular system
x = p.solve(A, b, p.tags.Upper())

# Copy the solution from the device to host and display it
print("Solution of Ax = b for x:\n%s" % x)

Example #6
0
def test_kernel(*args, **kwargs):
    """
    A, A_trans, B, B_trans must be numpy array or matrix instances
    """

    epsilon = args[0]
    A_upper, A_unit_upper, A_lower, A_unit_lower, A_trans_upper, A_trans_unit_upper, A_trans_lower, A_trans_unit_lower = args[
        1]
    B, B_trans = args[2]
    vcl_A_upper, vcl_A_unit_upper, vcl_A_lower, vcl_A_unit_lower, vcl_A_trans_upper, vcl_A_trans_unit_upper, vcl_A_trans_lower, vcl_A_trans_unit_lower = args[
        3]
    vcl_B, vcl_B_trans = args[4]

    Bvec = B[::, 0]
    vcl_Bvec = p.Vector(vcl_B.value[::, 0])  # TODO: get rid of .value
    if not (Bvec == vcl_Bvec).all():
        print(Bvec)
        print(vcl_Bvec)
        raise RuntimeError("Failed creating B vector")

    # A \ B
    vcl_X = p.solve(vcl_A_upper, vcl_B, p.upper_tag())
    X = sp.solve(A_upper, B)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B for upper triangular A: %s" %
                           act_diff)
    print("Test passed: solving A \ B for upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_unit_upper, vcl_B, p.unit_upper_tag())
    X = sp.solve(A_unit_upper, B)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A \ B for unit upper triangular A: %s" % act_diff)
    print("Test passed: solving A \ B for unit upper triangular A: %s" %
          act_diff)

    vcl_X = p.solve(vcl_A_lower, vcl_B, p.lower_tag())
    X = sp.solve(A_lower, B, lower=True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ B for lower triangular A: %s" %
                           act_diff)
    print("Test passed: solving A \ B for lower triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_unit_lower, vcl_B, p.unit_lower_tag())
    X = sp.solve(A_unit_lower, B, lower=True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A \ B for unit lower triangular A: %s" % act_diff)
    print("Test passed: solving A \ B for unit lower triangular A: %s" %
          act_diff)

    # A^T \ B
    vcl_X = p.solve(vcl_A_trans_upper, vcl_B, p.upper_tag())
    X = sp.solve(A_trans_upper, B)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A^T \ B for upper triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B for upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_trans_unit_upper, vcl_B, p.unit_upper_tag())
    X = sp.solve(A_trans_unit_upper, B)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A^T \ B for unit upper triangular A: %s" %
            act_diff)
    print("Test passed: solving A^T \ B for unit upper triangular A: %s" %
          act_diff)

    vcl_X = p.solve(vcl_A_trans_lower, vcl_B, p.lower_tag())
    X = sp.solve(A_trans_lower, B, lower=True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A^T \ B for lower triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B for lower triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_trans_unit_lower, vcl_B, p.unit_lower_tag())
    X = sp.solve(A_trans_unit_lower, B, lower=True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A^T \ B for unit lower triangular A: %s" %
            act_diff)
    print("Test passed: solving A^T \ B for unit lower triangular A: %s" %
          act_diff)

    # A \ B^T
    vcl_X = p.solve(vcl_A_upper, vcl_B_trans, p.upper_tag())
    X = sp.solve(A_upper, B_trans)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A \ B^T for upper triangular A: %s" % act_diff)
    print("Test passed: solving A \ B^T for upper triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_unit_upper, vcl_B_trans, p.unit_upper_tag())
    X = sp.solve(A_unit_upper, B_trans)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A \ B^T for unit upper triangular A: %s" %
            act_diff)
    print("Test passed: solving A \ B^T for unit upper triangular A: %s" %
          act_diff)

    vcl_X = p.solve(vcl_A_lower, vcl_B_trans, p.lower_tag())
    X = sp.solve(A_lower, B_trans, lower=True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A \ B^T for lower triangular A: %s" % act_diff)
    print("Test passed: solving A \ B^T for lower triangular A: %s" % act_diff)

    vcl_X = p.solve(vcl_A_unit_lower, vcl_B_trans, p.unit_lower_tag())
    X = sp.solve(A_unit_lower, B_trans, lower=True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A \ B^T for unit lower triangular A: %s" %
            act_diff)
    print("Test passed: solving A \ B^T for unit lower triangular A: %s" %
          act_diff)

    # A^T \ B^T
    vcl_X = p.solve(vcl_A_trans_upper, vcl_B_trans, p.upper_tag())
    X = sp.solve(A_trans_upper, B_trans)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A^T \ B^T for upper triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B^T for upper triangular A: %s" %
          act_diff)

    vcl_X = p.solve(vcl_A_trans_unit_upper, vcl_B_trans, p.unit_upper_tag())
    X = sp.solve(A_trans_unit_upper, B_trans)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A^T \ B^T for unit upper triangular A: %s" %
            act_diff)
    print("Test passed: solving A^T \ B^T for unit upper triangular A: %s" %
          act_diff)

    vcl_X = p.solve(vcl_A_trans_lower, vcl_B_trans, p.lower_tag())
    X = sp.solve(A_trans_lower, B_trans, lower=True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A^T \ B^T for lower triangular A: %s" % act_diff)
    print("Test passed: solving A^T \ B^T for lower triangular A: %s" %
          act_diff)

    vcl_X = p.solve(vcl_A_trans_unit_lower, vcl_B_trans, p.unit_lower_tag())
    X = sp.solve(A_trans_unit_lower, B_trans, lower=True)
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError(
            "Failed solving A^T \ B^T for unit lower triangular A: %s" %
            act_diff)
    print("Test passed: solving A^T \ B^T for unit lower triangular A: %s" %
          act_diff)

    # GMRES
    vcl_X = p.solve(vcl_A_upper, vcl_Bvec,
                    p.gmres_tag(tolerance=(epsilon / 10)))
    X, info = spsp.gmres(A_upper, Bvec, tol=(epsilon / 10))
    act_diff = math.fabs(diff(X, vcl_X))
    if act_diff > epsilon:
        raise RuntimeError("Failed solving A \ b using GMRES: %s" % act_diff)
    print("Test passed: solving A \ b using GMRES: %s" % act_diff)

    # CG -- TODO: need a symmetric positive definite matrix for test
    #vcl_X = p.solve(vcl_A_upper, vcl_Bvec, p.cg_tag())
    #X, info = spsp.cg(A_upper, Bvec)
    #act_diff = math.fabs(diff(X, vcl_X))
    #if act_diff > epsilon:
    #    raise RuntimeError("Failed solving A \ b using CG: %s" % act_diff)
    #print("Test passed: solving A \ b using CG: %s" % act_diff)

    # BiCGStab -- TODO: need a non-symmetric matrix for test
    #vcl_X = p.solve(vcl_A_upper, vcl_Bvec, p.cg_tag())
    #X, info = spsp.cg(A_upper, Bvec)
    #act_diff = math.fabs(diff(X, vcl_X))
    #if act_diff > epsilon:
    #    raise RuntimeError("Failed solving A \ b using CG: %s" % act_diff)
    #print("Test passed: solving A \ b using CG: %s" % act_diff)

    # TODO: in-place solvers

    return os.EX_OK
and various requirements for the form of the system matrix, as described in the
documentation for the corresponding tag classes.

For this reason, we only demonstrate here the use of the GMRES solver for a
general system.
"""

import pyviennacl as p
import numpy as np
import os, random
from p.io import read_mtx, read_vector

A = read_mtx(os.path.join(os.path.dirname(os.path.realpath(__file__)), "mat65k.mtx"),
             dtype=np.float32)
print("Loaded system matrix")

b = read_vector(os.path.join(os.path.dirname(os.path.realpath(__file__)), "rhs65025.txt"),
                dtype=np.float32)
print("Loaded RHS vector")

# Construct the tag to denote the GMRES solver
tag = p.tags.GMRES(tolerance = 1e-5, max_iterations = 150, krylov_dim = 50)

# Solve the system
x = p.solve(A, b, tag)

# Show some info
print("Num. iterations: %s" % tag.iters)
print("Estimated error: %s" % tag.error)

Example #8
0
# We want a square N x N system.
N = 5 

# Create a NumPy matrix with float32 precision to hold the data on the host.
# Firstly, we create an empty matrix, then fill the upper triangle with values.
A = np.zeros((N, N), dtype = np.float32)

for i in range(N):
    for j in range(N):
        if j >= i:
            A[i, j] = np.float32(random.randint(0,1000) / 100.0)

# Transfer the system matrix to the compute device
A = p.Matrix(A)

print("A is\n%s" % A)

# Create a right-hand-side vector on the host with random elements
# and transfer it to the compute device
b = p.Vector(np.random.rand(N).astype(np.float32))

print("b is %s" % b)

# Solve the system; note the choice of tag to denote an upper triangular system
x = p.solve(A, b, p.upper_tag())

# Copy the solution from the device to host and display it
print("Solution of Ax = b for x:\n%s" % x)

Example #9
0
and various requirements for the form of the system matrix, as described in the
documentation for the corresponding tag classes.

For this reason, we only demonstrate here the use of the GMRES solver for a
general system.
"""

import pyviennacl as p
import numpy as np
import os, random
from util import read_mtx, read_vector

A = read_mtx(os.path.join(os.path.dirname(os.path.realpath(__file__)), "mat65k.mtx"),
             dtype=np.float32)
print("Loaded system matrix")

b = read_vector(os.path.join(os.path.dirname(os.path.realpath(__file__)), "rhs65025.txt"),
                dtype=np.float32)
print("Loaded RHS vector")

# Construct the tag to denote the GMRES solver
tag = p.gmres_tag(tolerance = 1e-5, max_iterations = 150, krylov_dim = 50)

# Solve the system
x = p.solve(A, b, tag)

# Show some info
print("Num. iterations: %s" % tag.iters)
print("Estimated error: %s" % tag.error)