I think some of this is already in the documentation in bits and pieces,
but we should probably add Doug's explanation into the manual.
Regarding colamd, like Doug said, it is already included, and it should be
easy enough to expose it with a few ccalls.
-viral
On Friday, August 1, 2014 2:19:21 AM UTC+5:30, Douglas Bates wrote:
>
> Rats, I had a reply with code and examples then Google groups croaked and
> when it reloaded my draft reply was gone.
>
> On Thursday, July 31, 2014 2:13:36 PM UTC-5, Donald Lacombe wrote:
>>
>> Dear Doug,
>>
>> I've created a small example to show what the MATLAB code is actually
>> doing. Here is the output with some comments:
>>
>> % Create random coordinates
>> >> xc = randn(5,1);
>> >> yc = randn(5,1);
>>
>> % Create 2 nearest neighbor weight matrix
>> >> W = make_neighborsw(xc,yc,2);
>> >> W
>>
>> W =
>>
>> (2,1) 0.5000
>> (3,1) 0.5000
>> (1,2) 0.5000
>> (4,2) 0.5000
>> (1,3) 0.5000
>> (5,3) 0.5000
>> (5,4) 0.5000
>> (2,5) 0.5000
>> (3,5) 0.5000
>> (4,5) 0.5000
>>
>> % Full version
>> >> full(W)
>>
>> ans =
>>
>> 0 0.5000 0.5000 0 0
>> 0.5000 0 0 0 0.5000
>> 0.5000 0 0 0 0.5000
>> 0 0.5000 0 0 0.5000
>> 0 0 0.5000 0.5000 0
>>
>
> Notice that this matrix is not symmetric but the description of the
> arguments for indetfull below says that W should be symmetric. I am going
> to assume that W should be symmetric and the allowable values of rho are
> such that I - rho*W is positive-definite. I will use the matrix
>
> julia> W = sparse([2,3,1,5,1,5,5,2,3,4],[1,1,2,2,3,3,4,5,5,5],0.5)
> 5x5 sparse matrix with 10 Float64 entries:
> [2, 1] = 0.5
> [3, 1] = 0.5
> [1, 2] = 0.5
> [5, 2] = 0.5
> [1, 3] = 0.5
> [5, 3] = 0.5
> [5, 4] = 0.5
> [2, 5] = 0.5
> [3, 5] = 0.5
> [4, 5] = 0.5
>
> julia> issym(W)
> true
>
> julia> full(W)
> 5x5 Array{Float64,2}:
> 0.0 0.5 0.5 0.0 0.0
> 0.5 0.0 0.0 0.0 0.5
> 0.5 0.0 0.0 0.0 0.5
> 0.0 0.0 0.0 0.0 0.5
> 0.0 0.5 0.5 0.5 0.0
>
>
> for illustration.
>
>
>> % Find colamd
>> >> z = speye(n) - 0.1*sparse(W)
>>
>> z =
>>
>> (1,1) 1.0000
>> (2,1) -0.0500
>> (3,1) -0.0500
>> (1,2) -0.0500
>> (2,2) 1.0000
>> (4,2) -0.0500
>> (1,3) -0.0500
>> (3,3) 1.0000
>> (5,3) -0.0500
>> (4,4) 1.0000
>> (5,4) -0.0500
>> (2,5) -0.0500
>> (3,5) -0.0500
>> (4,5) -0.0500
>> (5,5) 1.0000
>>
>> % Full z
>> >> full(z)
>>
>> ans =
>>
>> 1.0000 -0.0500 -0.0500 0 0
>> -0.0500 1.0000 0 0 -0.0500
>> -0.0500 0 1.0000 0 -0.0500
>> 0 -0.0500 0 1.0000 -0.0500
>> 0 0 -0.0500 -0.0500 1.0000
>>
>> >> p = colamd(z)
>>
>> p =
>>
>> 4 3 1 2 5
>>
>> What I'm looking for is the "p" vector above. The full MATLAB code for
>> the routine is as follows:
>>
>
> You don't need colamd for the calculations in indetfull. Julia has a
> logdet function with a method for the sparse Cholesky factorization so the
> core calculation becomes
>
> julia> rho = 0.1
> 0.1
>
> julia> cf = cholfact(speye(W) - rho*W);
>
> julia> logdet(cf)
> -0.012566124059126464
>
> You don't need it but for interest, the 0-based permutation is stored as
> the .Perm member of the cf object. To make it 1-based we add 1 to it
>
> julia> show(cf.Perm .+ 1)
> [4,5,1,3,2]
>
> As with most sparse matrix operations the Cholesky factorization is done
> as a symbolic phase followed by a numeric phase. If you are just modfiying
> rho you don't need to do the symbolic phase over and over. You can save
> the factor from the first one and do the subsequent factorizations in place.
>
> function indetfull(W::SparseMatrixCSC,lmin,lmax)
> issym(W) || error("Sparse matrix W must be symmetric")
> rhos = lmin:0.01:lmax
> I = speye(W)
> cf = cholfact(I - lmin*W)
> hcat(rhos, [logdet(cholfact!(cf,I-rho*W))::Float64 for rho in rhos])
> end
>
> (By the way, be careful not to use lmin = 0. or else change the code so
> that cf is defined using lmax instead of lmin. The pattern of I - 0.*W is
> the pattern of the identity, after you have dropped the zero values, and is
> different from the pattern of I - rho*W for non-zero rho. It is important
> that the pattern be the same for all values of rho.)
>
> Here is an example of its use
>
> julia> indetfull(W,0.01,0.1)
> 10x2 Array{Float64,2}:
> 0.01 -0.000125007
> 0.02 -0.000500105
> 0.03 -0.00112553
> 0.04 -0.00200168
> 0.05 -0.00312911
> 0.06 -0.00450853
> 0.07 -0.00614082
> 0.08 -0.00802701
> 0.09 -0.0101683
> 0.1 -0.0125661
>
>
>
>
>
>> function out=lndetfull(W,lmin,lmax)
>> % PURPOSE: computes Pace and Barry's grid for log det(I-rho*W) using
>> sparse matrices
>> % -----------------------------------------------------------------------
>> % USAGE: out = lndetfull(W,lmin,lmax)
>> % where:
>> % W = symmetric spatial weight matrix (standardized)
>> % lmin = lower bound on rho
>> % lmax = upper bound on rho
>> % -----------------------------------------------------------------------
>> % RETURNS: out = a structure variable
>> % out.lndet = a vector of log determinants for 0 < rho < 1
>> % out.rho = a vector of rho values associated with lndet values
>> % -----------------------------------------------------------------------
>> % NOTES: should use 1/lambda(max) to 1/lambda(min) for all possible rho
>> values
>> % -----------------------------------------------------------------------
>> % References: % R. Kelley Pace and Ronald Barry. 1997. ``Quick
>> % Computation of Spatial Autoregressive Estimators'', Geographical
>> Analysis
>> % -----------------------------------------------------------------------
>>
>> % written by:
>> % James P. LeSage, Dept of Economics
>> % University of Toledo
>> % 2801 W. Bancroft St,
>> % Toledo, OH 43606
>>
>>
>> rvec = lmin:.01:lmax;
>> spparms('tight');
>> [n junk] = size(W);
>> z = speye(n) - 0.1*sparse(W);
>> p = colamd(z);
>> niter = length(rvec);
>> dettmp = zeros(niter,2);
>> for i=1:niter;
>> rho = rvec(i);
>> z = speye(n) - rho*sparse(W);
>> [l,u] = lu(z(:,p));
>> dettmp(i,1) = rho;
>> dettmp(i,2) = sum(log(abs(diag(u))));
>> end;
>>
>> out.lndet = dettmp(:,2);
>> out.rho = dettmp(:,1);
>>
>> The code will be very easy to convert once I figure out this one command,
>>
>> Thank you in advance for any help that you are able or willing to
>> provide. I'm not an expert as sparse matrices but these routines come in
>> very handy for these types of calculations.
>>
>> Thanks,
>> Don
>>
>>
>> On Thursday, July 31, 2014 10:42:55 AM UTC-4, Douglas Bates wrote:
>>>
>>> On Wednesday, July 30, 2014 8:10:37 PM UTC-5, Donald Lacombe wrote:
>>>>
>>>> Dear Julia Users:
>>>>
>>>> I am attempting to speed up some code regarding some Bayesian spatial
>>>> econometric models and would like to translate some MATLAB code for
>>>> computing the log determinant term in the log-likelihood function.
>>>> Specifically, I'm interested in the Pace and Barry approximation to the
>>>> log-determinant term as in R. Kelley Pace and Ronald Barry. (1997) "Quick
>>>> Computation
>>>> of Spatial Autoregressive Estimators''. The term in question is det(In -
>>>> rho*W) which has to be calculated through each iteration of the
>>>> Metropolis-Hastings algorithm I'm using.
>>>>
>>>> The MATLAB code for this has the command "colamd" which MATLAB's help
>>>> defines as "P = colamd(S) returns the column approximate minimum
>>>> degree permutation vector for the sparse matrix S".
>>>>
>>>
>>> colamd is indirectly available in the Cholmod module but I don't think
>>> there is a direct way of calling it. It is a method for determining a
>>> fill-reducing permutation for a sparse, symmetric matrix of the form X'X
>>> directly from X. There are several other approaches implemented in amd,
>>> Metis, Scotch, MUMPS, etc. for dealing with the symmetric matrix itself.
>>> All of these just use the pattern of nonzeros in the matrix as they are
>>> part of the symbolic stage of the sparse Cholesky or sparse QR
>>> factorization.
>>>
>>> Can you be more specific about how it is to be used? In particular, is
>>> it important to work with the pattern of X rather than the pattern of X'X?
>>>
>>>
>>>> Is there an equivalent Julia command? I've tried looking at "symperm"
>>>> but I do not think I am using it correctly and more importantly I have no
>>>> real clue.
>>>>
>>>> Any help would be appreciated and if I successfully code this I would
>>>> be happy to share with anyone who is interested.
>>>>
>>>> Thanks,
>>>> Don
>>>>
>>>