-
-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
get_array should return sparse matrix #55
Comments
Yeah this is a more than reasonable request. Here it is in the code: I think it would be as simple as using |
Hello! Yes it should be sparse. This is due to JuliaPy/PyCall.jl#204 . I have code locally that can convert it to sparse(by converting the PETSc backend matrices to Scipy and then Julia CSC format, I can open a PR with it in abit). |
Exactly, the Julia equivalent to the last line is |
For PETSc matrices (assuming you do not want to (provide the option to) switch the backend to Eigen nor make use of the C++ PETSc interface), you could use a loop over all rows (
|
@clason thanks for that suggestion! I was currently doing the conversion in a very verbose way as I wasn't too familiar with the different CSR/CSC formats being used. I'll try and implement your suggestion. For reference, the code currently looks as @pyimport scipy.sparse as sc
i,c,v = getValuesCSR(Pmat)
scsparse = sc.csr_matrix((v,c,i))
I,J,V = sc.find(scsparse)
return sparse(Int[i+1 for i in I], Int[j+1 for j in J],V) #0 based python to 1 based julia |
I shall investigate how to efficiently set the backend to Eigen using PyCall then, and keep you informed. |
Is it difficult to implement this via |
@MiroK I was not aware of the row,col,val = as_backend_type(A).mat().getValuesCSR()
A_csr = sp.csr_matrix((val,col,row)) works nicely in Python. This should be the easiest way. Thanks! |
@MiroK that was how the values where accessed in the snippet of code. The Pmat was an initialized PETSc matrix with the .mat method called. It still remains for me to see how to do the conversion from the CSR to CSC format efficiently without using Scipy if possible, so I'll have to read up on both implementations. |
Ah, I see the problem -- unlike the Eigen using SparseArrays,PyCall
# create a demo matrix
@pyimport fenics as fe
mesh = fe.UnitSquareMesh(64,64)
V = fe.FunctionSpace(mesh,"CG",1)
u,v = fe.TrialFunction(V),fe.TestFunction(V)
a = fe.dot(fe.grad(u),fe.grad(v))*fe.dx
PETScMat = fe.assemble(a)
# convert PETSc to Python
indptr,indices,vals = fe.as_backend_type(PETScMat)[:mat]()[:getValuesCSR]()
@pyimport scipy.sparse as sp
PyMat = sp.csr_matrix((vals,indices,indptr))[:tocoo]() # yields COO matrix
# convert Python to Julia
JuliaMat = sparse(PyMat[:row].+1,PyMat[:col].+1,PyMat[:data]) |
I stand corrected; it's not in the docs, but using SparseArrays,PyCall
# create a demo matrix
@pyimport fenics as fe
mesh = fe.UnitSquareMesh(64,64)
V = fe.FunctionSpace(mesh,"CG",1)
u,v = fe.TrialFunction(V),fe.TestFunction(V)
a = fe.dot(fe.grad(u),fe.grad(v))*fe.dx + fe.Dx(u,1)*fe.dx # non-symmetric form
A_fe = fe.assemble(a) # wrapper for dolfin matrix
# convert to PETSc matrix, accessible via petsc4py
A_py = fe.as_backend_type(FEniCSMat)[:mat]()
# convert to Julia matrix -- note that we feed the CSR structure to a CSC constructor
m,n = A_py[:getSize]()
indptr,indices,data = A_py[:getValuesCSR]()
A_jl = SparseMatrixCSC(m,n,indptr.+1,indices.+1,data)
# transpose to get correct structure (note: "SparseMatrixCSC" is much more efficient than "sparse")
A_jl = SparseMatrixCSC(A_jl') Problem solved 😊 Update: Tested and works for non-symmetric matrices now. @ChrisRackauckas I can create a PR to change the |
At the moment, the
get_array
function returns a fullArray{Float64,2}
, which is not really a reasonable option for any practical use beyond toy problems. Can the get_array function be modified to return aSparseMatrixCSC{Float64,Int64}
instead?For reference, here's how I do the same on the FEniCS/SciPy interface:
I believe the same should work for FEniCS-to-Julia.
The text was updated successfully, but these errors were encountered: