|
From: Dominique O. <dom...@gm...> - 2009-11-05 15:12:49
|
On Thu, Nov 5, 2009 at 4:00 AM, zipeppe <zi...@gm...> wrote:
> Dear all,
>
> I don't know it this is the right place to ask, but unfortunately the
> official Python-forum doesn't help.
>
This is the right place for Pysparse questions.
> I am quite new to Python and I am unable to correctly translate the
> following MATLAB script in Python code, specially because of the *spdiags*proprietary function:
>
> function bd=BLC(b,A,B,s)
> L=length(b);
> Bs=-B/s; As=-A/s;
> bd=ones(L,1)*median(b);bd0=b;nm=norm(bd-bd0);nm0=RealMax;
> M0=-ones(L,1)/As;
> e=ones(L,1);
> D0=spdiags([1*e -4*e 6*e -4*e 1*e],-2:2,L,L);
> D0(1,1)=2; D0(L,L)=2;
> D0(2,1)=-4; D0(1,2)=-4; D0(L,L-1)=-4; D0(L-1,L)=-4;
> D0(2,2)=10;D0(L-1,L-1)=10;
> I=0;
> while nm>10 & I<30
> %& nm<nm0;
> I=I+1;
> M=M0;D=D0;bd0=bd;nm0=nm;
> for i=1:L
> if bd(i)>b(i)
> M(i)=M(i)+2*Bs*b(i)/As;
> D(i,i)=D(i,i)+2*Bs/As;
> end
> end
> bd=D\M;
> nm=norm(bd0-bd);
> end
>
> The algorithm receives *b* as (Nx1 data vector), *A* (1x1), *B* (1x1) and
> *s* (1x1) as local parameters, and creates *bd* (Nx1data vector) as
> output.
>
The Matlab command that you highlighted creates an L x L matrix with the
vectors e, -4*e, 6*e, -4*e and e on and around the main diagonal. The
position argument is -2:2 which means that the first vector (e) goes on the
sub-sub-diagonal, the second vector (-4e) goes on the sub-diagonal, 6e goes
on the main diagonal, -4e goes one above the main diagonal and e goes two
above the main diagonal like so.
Here is a code fragment that performs the same operation with Pysparse:
In [1]: from pysparse.pysparseMatrix import PysparseSpDiagsMatrix as spdiags
In [2]: import numpy as np
In [3]: L = 5 # The length of b in your Matlab code
In [4]: e = np.ones(L)
In [5]: D0 = spdiags(L, (e, -4*e, 6*e, -4*e, e), (-2,-1,0,1,2))
In [6]: print D0
6.000000 -4.000000 1.000000 --- ---
-4.000000 6.000000 -4.000000 1.000000 ---
1.000000 -4.000000 6.000000 -4.000000 1.000000
--- 1.000000 -4.000000 6.000000 -4.000000
--- --- 1.000000 -4.000000 6.000000
The first argument (L) specifies the matrix size, the second is the set of
vectors that should be laid out on the diagonals and the third gives the
indices of the diagonals that are concerned.
For a more Matlab-like notation, the last argument can also be written
np.r_[-2:2] (see the Numpy function r_ ... note the underscore).
I hope this helps.
--
Dominique
|