root/trunk/ProjectFortress/demos/conjGrad.fss

Revision 3550, 3.4 KB (checked in by sukyoungryu, 9 months ago)

[copyright] Fixed the copyright notices.

Line 
1(*******************************************************************************
2    Copyright 2009 Sun Microsystems, Inc.,
3    4150 Network Circle, Santa Clara, California 95054, U.S.A.
4    All rights reserved.
5
6    U.S. Government Rights - Commercial software.
7    Government users are subject to the Sun Microsystems, Inc. standard
8    license agreement and applicable provisions of the FAR and its supplements.
9
10    Use is subject to license terms.
11
12    This distribution may include materials developed by third parties.
13
14    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
15    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
16 ******************************************************************************)
17
18component conjGrad
19import Sparse.{...}
20export Executable
21
22mkMatrix[\nat n\]() : RR64[n,n] = do
23  (* We generate a symmetric positive-definite matrix by generating
24     a lower-triangular positive matrix and multiplying by its
25     transpose. *)
26  lambda_inv = - 4 n / log n
27  rt2 = SQRT 2
28  row(i:ZZ32):SparseVector[\RR64,n\] = do
29    mem0 = array[\(ZZ32,RR64)\](n-i)
30    j : ZZ32 := i
31    o : ZZ32 := 0
32    while (j < n) do
33      mem0[o] := (j,random(rt2))
34      (* Approximate Bernoulli interarrival with Poisson *)
35      ii = 1 + narrow |\lambda_inv log random(1.0)/|
36      j += ii
37      o += 1
38    end
39    SparseVector[\RR64,n\](trim(mem0,o))
40  end
41  l = Csr[\RR64,n,n\](array1[\SparseVector[\RR64,n\],n\](row))
42  (* We multiply by the transpose and hope the result is positive-definite.
43     It will be with high probability. *)
44  l l.t()
45end
46
47mkVector[\nat n\]() : RR64[n] = do
48  f(i): RR64 = random(4.0)-2.0
49  array1[\RR64,n\](f)
50end
51
52testSparse[\nat n\](A: Csr[\RR64,n,n\]) = do
53  D = matrix[\RR64,n,n\]().assign(A)
54  if D=/=A then
55    println("FAIL: dense =/= sparse" // "D" D // "A" A)
56  else
57    println("dense OK")
58  end
59  A2 = identity[\Csr[\RR64,n,n\]\](A A.t())
60  D2 = D D.t()
61  if D2=/=A2 then
62    println("FAIL: dense^2 =/= sparse^2" // "D^2" D2 // "A^2" A2)
63  else
64    println("dense^2 OK")
65  end
66  v = mkVector[\n\]()
67  Av = A v
68  Dv = D v
69  (* Small variations may occur based on summation order for dot
70     product. *)
71  if ||Dv - Av|| > 0.000000000001 then
72    println("Fail: Dv =/= Av" // "Dv = " Dv // "Av = " Av)
73  else
74    println("Dv OK")
75  end
76end
77
78(************************************************************)
79
80(* conjGrad returns the approximate solution z to the linear equation:
81 *    A z = x
82 * along with the approximate cartesian error of the solution.  This
83 * method is considered superior to LU decomposition when A is
84 * sparse, symmetric, and positive-definite. *)
85conjGrad[\Elt extends Number, nat N,
86          Vec extends Vector[\Elt,N\],
87          Mat extends Matrix[\Elt,N,N\]\]
88        (A: Mat, x: Vec): (Vec, RR64) = do
89  cgit_max = 25
90  z: Vec := x.replica[\Elt\]().fill(0)
91  r: Vec := x
92  p: Vec := r
93  rho: Elt := r DOT r
94  for j <- seq(1#cgit_max) do
95    q = A p
96    alpha = rho / (p DOT q)
97    z += alpha p
98    rho0 = rho
99    r -= alpha q
100    rho := r DOT r
101    beta = rho / rho0
102    p := r + beta p
103    println("Iter " j " alpha = " alpha // "z" z)
104  end
105  (z, ||x - A z||)
106end
107
108(************************************************************)
109
110run():() = do
111  testSparse(mkMatrix[\16\]())
112  A = mkMatrix[\50\]()
113  v = mkVector[\50\]()
114  println(A)
115  println("v" v)
116  (s,e) = conjGrad[\RR64,50,Vector[\RR64,50\],Matrix[\RR64,50,50\]\](A,v)
117  println("s" s)
118  println("Error = " e)
119end
120
121end
Note: See TracBrowser for help on using the browser.