Merge branch 'master' of https://bitbucket.org/rcockett/simpeg into BoundConstraint

Conflicts:
	.gitignore
	SimPEG/utils/__init__.py
This commit is contained in:
Rowan Cockett
2013-11-12 11:24:40 -08:00
7 changed files with 186 additions and 383 deletions
+2
View File
@@ -1,4 +1,6 @@
*.pyc
*.so
*.sublime-project
*.sublime-workspace
docs/_build/
myNotebooks/*
+8
View File
@@ -0,0 +1,8 @@
import os
print 'Compiling TriSolve.'
os.system('f2py -c utils/TriSolve.f -m TriSolve')
print 'TriSolve Compiled! yay.'
print 'Moving TriSolve into Utils.'
os.system('mv TriSolve.so utils/TriSolve.so')
print 'Thats it. Well Done Computer.'
-355
View File
@@ -1,355 +0,0 @@
.. _api_TestResults:
.. raw:: html
<style type="text/css" media="screen">
body { font-family: verdana, arial, helvetica, sans-serif; font-size: 80%; }
table { font-size: 100%; }
pre { }
/* -- heading ---------------------------------------------------------------------- */
h1 {
font-size: 16pt;
color: gray;
}
.heading {
margin-top: 0ex;
margin-bottom: 1ex;
}
.heading .attribute {
margin-top: 1ex;
margin-bottom: 0;
}
.heading .description {
margin-top: 4ex;
margin-bottom: 6ex;
}
/* -- css div popup ------------------------------------------------------------------------ */
a.popup_link {
}
a.popup_link:hover {
color: red;
}
.popup_window {
display: none;
position: relative;
left: 0px;
top: 0px;
/*border: solid #627173 1px; */
padding: 10px;
background-color: #E6E6D6;
font-family: "Lucida Console", "Courier New", Courier, monospace;
text-align: left;
font-size: 8pt;
width: 500px;
}
}
/* -- report ------------------------------------------------------------------------ */
#show_detail_line {
margin-top: 3ex;
margin-bottom: 1ex;
}
#result_table {
width: 80%;
border-collapse: collapse;
border: 1px solid #777;
}
#header_row {
font-weight: bold;
color: white;
background-color: #777;
}
#result_table td {
border: 1px solid #777;
padding: 2px;
}
#total_row { font-weight: bold; }
.passClass { background-color: #6c6; }
.failClass { background-color: #c60; }
.errorClass { background-color: #c00; }
.passCase { color: #6c6; }
.failCase { color: #c60; font-weight: bold; }
.errorCase { color: #c00; font-weight: bold; }
.hiddenRow { display: none; }
.testcase { margin-left: 2em; }
/* -- ending ---------------------------------------------------------------------- */
#ending {
}
</style>
<body>
<script language="javascript" type="text/javascript"><!--
output_list = Array();
/* level - 0:Summary; 1:Failed; 2:All */
function showCase(level) {
trs = document.getElementsByTagName("tr");
for (var i = 0; i < trs.length; i++) {
tr = trs[i];
id = tr.id;
if (id.substr(0,2) == 'ft') {
if (level < 1) {
tr.className = 'hiddenRow';
}
else {
tr.className = '';
}
}
if (id.substr(0,2) == 'pt') {
if (level > 1) {
tr.className = '';
}
else {
tr.className = 'hiddenRow';
}
}
}
}
function showClassDetail(cid, count) {
var id_list = Array(count);
var toHide = 1;
for (var i = 0; i < count; i++) {
tid0 = 't' + cid.substr(1) + '.' + (i+1);
tid = 'f' + tid0;
tr = document.getElementById(tid);
if (!tr) {
tid = 'p' + tid0;
tr = document.getElementById(tid);
}
id_list[i] = tid;
if (tr.className) {
toHide = 0;
}
}
for (var i = 0; i < count; i++) {
tid = id_list[i];
if (toHide) {
document.getElementById('div_'+tid).style.display = 'none'
document.getElementById(tid).className = 'hiddenRow';
}
else {
document.getElementById(tid).className = '';
}
}
}
function showTestDetail(div_id){
var details_div = document.getElementById(div_id)
var displayState = details_div.style.display
// alert(displayState)
if (displayState != 'block' ) {
displayState = 'block'
details_div.style.display = 'block'
}
else {
details_div.style.display = 'none'
}
}
function html_escape(s) {
s = s.replace(/&/g,'&amp;');
s = s.replace(/</g,'&lt;');
s = s.replace(/>/g,'&gt;');
return s;
}
/* obsoleted by detail in <div>
function showOutput(id, name) {
var w = window.open("", //url
name,
"resizable,scrollbars,status,width=800,height=450");
d = w.document;
d.write("<pre>");
d.write(html_escape(output_list[id]));
d.write("\n");
d.write("<a href='javascript:window.close()'>close</a>\n");
d.write("</pre>\n");
d.close();
}
*/
--></script>
<div class='heading'>
<h1>Test Report</h1>
<p class='attribute'><strong>Start Time:</strong> 2013-11-05 15:24:44</p>
<p class='attribute'><strong>Duration:</strong> 0:00:00.007500</p>
<p class='attribute'><strong>Status:</strong> Pass 22</p>
<p class='description'>This demonstrates the report output by Prasanna.Yelsangikar.</p>
</div>
<p id='show_detail_line'>Show
<a href='javascript:showCase(0)'>Summary</a>
<a href='javascript:showCase(1)'>Failed</a>
<a href='javascript:showCase(2)'>All</a>
</p>
<table id='result_table'>
<colgroup>
<col align='left' />
<col align='right' />
<col align='right' />
<col align='right' />
<col align='right' />
<col align='right' />
</colgroup>
<tr id='header_row'>
<td>Test Group/Test case</td>
<td>Count</td>
<td>Pass</td>
<td>Fail</td>
<td>Error</td>
<td>View</td>
</tr>
<tr class='passClass'>
<td>test_basemesh.TestBaseMesh</td>
<td>11</td>
<td>11</td>
<td>0</td>
<td>0</td>
<td><a href="javascript:showClassDetail('c1',11)">Detail</a></td>
</tr>
<tr id='pt1.1' class='hiddenRow'>
<td class='none'><div class='testcase'>test_meshDimensions</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.2' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_nc</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.3' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_nc_xyz</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.4' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_ne</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.5' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_nf</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.6' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_numbers</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.7' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_CC_M</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.8' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_E_M</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.9' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_E_V</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.10' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_F_M</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt1.11' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_F_V</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr class='passClass'>
<td>test_basemesh.TestMeshNumbers2D</td>
<td>11</td>
<td>11</td>
<td>0</td>
<td>0</td>
<td><a href="javascript:showClassDetail('c2',11)">Detail</a></td>
</tr>
<tr id='pt2.1' class='hiddenRow'>
<td class='none'><div class='testcase'>test_meshDimensions</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.2' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_nc</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.3' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_nc_xyz</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.4' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_ne</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.5' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_nf</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.6' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_numbers</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.7' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_CC_M</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.8' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_E_M</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.9' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_E_V</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.10' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_F_M</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='pt2.11' class='hiddenRow'>
<td class='none'><div class='testcase'>test_mesh_r_F_V</div></td>
<td colspan='5' align='center'>pass</td>
</tr>
<tr id='total_row'>
<td>Total</td>
<td>22</td>
<td>22</td>
<td>0</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
</table>
+39 -6
View File
@@ -58,23 +58,39 @@ class TestSolver(unittest.TestCase):
x = solve.solve(rhs)
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
def test_directLower_1(self):
def test_directLower_1_python(self):
AL = sparse.tril(self.A)
solve = Solver(AL, doDirect=True, flag='L', options={})
solve = Solver(AL, doDirect=True, flag='L', options={'backend':'python'})
e = np.ones(self.M.nC)
rhs = AL.dot(e)
x = solve.solve(rhs)
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
def test_directLower_M(self):
def test_directLower_M_python(self):
AL = sparse.tril(self.A)
solve = Solver(AL, doDirect=True, flag='L', options={})
solve = Solver(AL, doDirect=True, flag='L', options={'backend':'python'})
e = np.ones((self.M.nC,numRHS))
rhs = AL.dot(e)
x = solve.solve(rhs)
def test_directLower_1_fortran(self):
AL = sparse.tril(self.A)
solve = Solver(AL, doDirect=True, flag='L', options={'backend':'fortran'})
e = np.ones(self.M.nC)
rhs = AL.dot(e)
x = solve.solve(rhs)
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
def test_directUpper_1(self):
def test_directLower_M_fortran(self):
AL = sparse.tril(self.A)
solve = Solver(AL, doDirect=True, flag='L', options={'backend':'fortran'})
e = np.ones((self.M.nC,numRHS))
rhs = AL.dot(e)
x = solve.solve(rhs)
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
def test_directUpper_1_python(self):
AU = sparse.triu(self.A)
solve = Solver(AU, doDirect=True, flag='U', options={})
e = np.ones(self.M.nC)
@@ -82,7 +98,7 @@ class TestSolver(unittest.TestCase):
x = solve.solve(rhs)
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
def test_directUpper_M(self):
def test_directUpper_M_python(self):
AU = sparse.triu(self.A)
solve = Solver(AU, doDirect=True, flag='U', options={})
e = np.ones((self.M.nC,numRHS))
@@ -90,6 +106,23 @@ class TestSolver(unittest.TestCase):
x = solve.solve(rhs)
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
def test_directUpper_1_fortran(self):
AU = sparse.triu(self.A)
solve = Solver(AU, doDirect=True, flag='U', options={'backend':'fortran'})
e = np.ones(self.M.nC)
rhs = AU.dot(e)
x = solve.solve(rhs)
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
def test_directUpper_M_fortran(self):
AU = sparse.triu(self.A)
solve = Solver(AU, doDirect=True, flag='U', options={'backend':'fortran'})
e = np.ones((self.M.nC,numRHS))
rhs = AU.dot(e)
x = solve.solve(rhs)
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
def test_directDiagonal_1(self):
AD = sdiag(self.A.diagonal())
solve = Solver(AD, doDirect=True, flag='D', options={})
+71 -19
View File
@@ -1,7 +1,22 @@
import numpy as np
import scipy.sparse as sparse
import scipy.sparse.linalg as linalg
from SimPEG.utils import mkvc
DEFAULTS = {'direct':'scipy', 'forward':'fortran', 'backward':'fortran', 'diagonal':'python'}
try:
import TriSolve
except Exception, e:
try:
import os
# Note: this may not work from SublimeText, if that is the case, just run the command in your shell.
os.system('f2py -c TriSolve.f -m TriSolve')
import TriSolve
except Exception, e:
print 'Warning: Python backend is being used for solver. Run setup.py from the command line.'
DEFAULTS['forward'] = 'python'
DEFAULTS['backward'] = 'python'
class Solver(object):
"""
@@ -55,11 +70,11 @@ class Solver(object):
elif self.flag is None and not self.doDirect:
return self.solveIter(b, **self.options)
elif self.flag == 'U':
return self.solveBackward(b)
return self.solveBackward(b, **self.options)
elif self.flag == 'L':
return self.solveForward(b)
return self.solveForward(b, **self.options)
elif self.flag == 'D':
return self.solveDiagonal(b)
return self.solveDiagonal(b, **self.options)
else:
raise Exception('Unknown flag.')
pass
@@ -69,7 +84,7 @@ class Solver(object):
del self.dsolve
self.dsolve = None
def solveDirect(self, b, factorize=False, backend='scipy'):
def solveDirect(self, b, factorize=False, backend=None):
"""
Use solve instead of this interface.
@@ -78,6 +93,8 @@ class Solver(object):
:rtype: numpy.ndarray
:return: x
"""
if backend is None: backend = DEFAULTS['scipy']
assert np.shape(self.A)[1] == np.shape(b)[0], 'Dimension mismatch'
if factorize and self.dsolve is None:
@@ -104,7 +121,7 @@ class Solver(object):
def solveIter(self, b, M=None, iterSolver='CG'):
pass
def solveBackward(self, b, backend='python'):
def solveBackward(self, b, backend=None):
"""
Use solve instead of this interface.
@@ -114,21 +131,29 @@ class Solver(object):
:rtype: numpy.ndarray
:return: x
"""
if backend is None: backend = DEFAULTS['backward']
if type(self.A) is not sparse.csr.csr_matrix:
from scipy.sparse import csr_matrix
self.A = csr_matrix(self.A)
vals = self.A.data
rowptr = self.A.indptr
colind = self.A.indices
x = np.empty_like(b) # empty() is faster than zeros().
for i in reversed(xrange(self.A.shape[0])):
ith_row = vals[rowptr[i] : rowptr[i+1]]
cols = colind[rowptr[i] : rowptr[i+1]]
x_vals = x[cols]
x[i] = (b[i] - np.dot(ith_row[1:], x_vals[1:])) / ith_row[0]
if backend == 'fortran':
if len(b.shape) == 1 or b.shape[1] == 1:
x = TriSolve.backward(vals, rowptr, colind, b, self.A.data.size, b.size, 1)
x = mkvc(x)
else:
x = TriSolve.backward(vals, rowptr, colind, b, self.A.data.size, b.shape[0], b.shape[1])
elif backend == 'python':
x = np.empty_like(b) # empty() is faster than zeros().
for i in reversed(xrange(self.A.shape[0])):
ith_row = vals[rowptr[i] : rowptr[i+1]]
cols = colind[rowptr[i] : rowptr[i+1]]
x_vals = x[cols]
x[i] = (b[i] - np.dot(ith_row[1:], x_vals[1:])) / ith_row[0]
return x
def solveForward(self, b, backend='python'):
def solveForward(self, b, backend=None):
"""
Use solve instead of this interface.
@@ -138,21 +163,29 @@ class Solver(object):
:rtype: numpy.ndarray
:return: x
"""
if backend is None: backend = DEFAULTS['forward']
if type(self.A) is not sparse.csr.csr_matrix:
from scipy.sparse import csr_matrix
self.A = csr_matrix(self.A)
vals = self.A.data
rowptr = self.A.indptr
colind = self.A.indices
x = np.empty_like(b) # empty() is faster than zeros().
for i in xrange(self.A.shape[0]):
ith_row = vals[rowptr[i] : rowptr[i+1]]
cols = colind[rowptr[i] : rowptr[i+1]]
x_vals = x[cols]
x[i] = (b[i] - np.dot(ith_row[:-1], x_vals[:-1])) / ith_row[-1]
if backend == 'fortran':
if len(b.shape) == 1 or b.shape[1] == 1:
x = TriSolve.forward(vals, rowptr, colind, b, self.A.data.size, b.size, 1)
x = mkvc(x)
else:
x = TriSolve.forward(vals, rowptr, colind, b, self.A.data.size, b.shape[0], b.shape[1])
elif backend == 'python':
x = np.empty_like(b) # empty() is faster than zeros().
for i in xrange(self.A.shape[0]):
ith_row = vals[rowptr[i] : rowptr[i+1]]
cols = colind[rowptr[i] : rowptr[i+1]]
x_vals = x[cols]
x[i] = (b[i] - np.dot(ith_row[:-1], x_vals[:-1])) / ith_row[-1]
return x
def solveDiagonal(self, b, backend='python'):
def solveDiagonal(self, b, backend=None):
"""
Use solve instead of this interface.
@@ -162,6 +195,8 @@ class Solver(object):
:rtype: numpy.ndarray
:return: x
"""
if backend is None: backend = DEFAULTS['diagonal']
diagA = self.A.diagonal()
if len(b.shape) == 1 or b.shape[1] == 1:
# Just one RHS
@@ -205,3 +240,20 @@ if __name__ == '__main__':
print np.linalg.norm(e-x,np.inf)
n = 6000
A_dense = np.random.random((n,n))
L = np.tril(np.dot(A_dense, A_dense)) # Positive definite is better conditioned.
e = np.ones(n)
b = np.dot(L, e)
A = sparse.csr_matrix(L)
pSolve = Solver(A,flag='L',options={'backend':'python'});
fSolve = Solver(A,flag='L',options={'backend':'fortran'})
tic = time()
x = pSolve.solve(b)
toc = time() - tic
print 'Error Forward Python = ', np.linalg.norm(x-e, np.inf), 'Time: ', toc
tic = time()
x = fSolve.solve(b)
toc = time() - tic
print 'Error Forward Fortran = ', np.linalg.norm(x-e, np.inf), 'Time: ', toc
+64
View File
@@ -0,0 +1,64 @@
c File TriSolve.f
subroutine forward(al, ial, jal, b, nv, n, nRHS, x)
double precision al(nv)
integer ial(n+1)
integer jal(nv)
double precision b(n,nRHS)
double precision x(n,nRHS)
integer nv
integer n
integer nRHS
integer rhs
cf2py intent(in) :: al
cf2py intent(in) :: ial
cf2py intent(in) :: jal
cf2py intent(in) :: b
cf2py intent(in) :: nv
cf2py intent(in) :: n
cf2py intent(in) :: nRHS
cf2py intent(out) :: x
real ( kind = 8 ) t
do rhs = 1, nRHS
do k = 1, n
t = b(k,rhs)
do j = ial(k)+1, ial(k+1)
t = t - al(j) * x(jal(j)+1,rhs)
end do
x(k,rhs) = t/al(ial(k+1))
end do
end do
end subroutine forward
subroutine backward(au,iau, jau, b, nv, n, nRHS, x)
double precision au(nv)
integer iau(n+1)
integer jau(nv)
double precision b(n,nRHS)
double precision x(n,nRHS)
integer nv
integer n
integer nRHS
integer rhs
cf2py intent(in) :: au
cf2py intent(in) :: iau
cf2py intent(in) :: jau
cf2py intent(in) :: b
cf2py intent(in) :: nv
cf2py intent(in) :: n
cf2py intent(in) :: nRHS
cf2py intent(out) :: x
real ( kind = 8 ) t
do rhs = 1, nRHS
do k = n, 1, -1
t = b(k,rhs)
do j = iau(k)+1, iau(k+1)
t = t - au(j) * x(jau(j)+1,rhs)
end do
x(k,rhs) = t/au(iau(k)+1)
end do
end do
end subroutine backward
+2 -3
View File
@@ -3,14 +3,13 @@ import sputils
import lomutils
import interputils
import ModelBuilder
import Solver
from Solver import Solver
from matutils import getSubArray, mkvc, ndgrid, ind2sub, sub2ind
from sputils import spzeros, kron3, speye, sdiag
from lomutils import volTetra, faceInfo, inv2X2BlockDiagonal, inv3X3BlockDiagonal, indexCube, exampleLomGird
from interputils import interpmat
from ipythonUtils import easyAnimate as animate
import Solver
from Solver import Solver
def setKwargs(obj, **kwargs):
"""Sets key word arguments (kwargs) that are present in the object, throw an error if they don't exist."""