summaryrefslogtreecommitdiff
path: root/modules/scicos/src/modelica_compiler/squareSparseMatrix.ml
blob: d6f637e1f7b5b37f7ebb8a1cb9eb9f4316a802ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
(*
 *  Modelicac
 *
 *  Copyright (C) 2005 - 2007 Imagine S.A.
 *  For more information or commercial use please contact us at www.amesim.com
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 *)

module type MatrixElement =
    sig
        type t
        val equal : t -> t -> bool
    end

module type S =
    sig
        type elt
        type t
        val make : int -> elt -> t
        val init : int -> elt -> (int -> int -> elt) -> t
        val size : t -> int * int
        val get : t -> int -> int -> elt
        val set : t -> int -> int -> elt -> unit
        val iter : (elt -> unit) -> t -> unit
        val iterij : (int -> int -> elt -> unit) -> t -> unit
        val row_iter : int -> (elt -> unit) -> t -> unit
        val row_iterj : int -> (int -> elt -> unit) -> t -> unit
        val row_storage_iterj : int -> (int -> elt -> unit) -> t -> unit
        val update_row_storage : int -> (int -> elt -> elt) -> t -> unit
        val column_iter : int -> (elt -> unit) -> t -> unit
        val column_iteri : int -> (int -> elt -> unit) -> t -> unit
        val column_storage_iteri : int -> (int -> elt -> unit) -> t -> unit
        val update_column_storage : int -> (int -> elt -> elt) -> t -> unit
    end

module Make (M : MatrixElement) : (S with type elt = M.t) =

    struct

        type elt = M.t
        type t =
          {
            default : elt;
            rows : (int * elt ref) list array;
            columns : (int * elt ref) list array
          }

        let make size elt =
          {
            default = elt;
            rows = Array.make size [];
            columns = Array.make size []
          }

        let init size elt f =
            let rows = Array.make size []
            and columns = Array.make size [] in
            for i = 0 to size - 1 do
                for j = 0 to size - 1 do
                    let elt' = f i j in
                    if M.equal elt' elt then ()
                    else
                        let elt'_ref = ref elt' in
                        rows.(i) <- (j, elt'_ref) :: rows.(i);
                        columns.(j) <- (i, elt'_ref) :: columns.(j)
                done
            done;
              {
                default = elt;
                rows = rows;
                columns = columns
              }

        let size mtrx = let size = Array.length mtrx.rows in (size, size)

        let get mtrx i j = try !(List.assoc j mtrx.rows.(i)) with
            | Not_found -> mtrx.default

        let set mtrx i j elt = try (List.assoc j mtrx.rows.(i)) := elt with
            | Not_found ->
                mtrx.rows.(i) <- (j, ref elt) :: mtrx.rows.(i);
                mtrx.columns.(j) <- (i, ref elt) :: mtrx.columns.(j)
        
        let row_iter i f mtrx =
            for j = 0 to Array.length mtrx.rows - 1 do
                f (get mtrx i j)
            done

        let row_iterj i f mtrx =
            for j = 0 to Array.length mtrx.rows - 1 do
                f j (get mtrx i j)
            done

        let row_storage_iterj i f mtrx =
            List.iter (fun (j, elt_ref) -> f j !elt_ref) mtrx.rows.(i)

        let update_row_storage i f mtrx =
            List.iter (fun (j, elt_ref) -> elt_ref := f j !elt_ref) mtrx.rows.(i)

        let column_iter j f mtrx =
            for i = 0 to Array.length mtrx.rows - 1 do
                f (get mtrx i j)
            done

        let column_iteri j f mtrx =
            for i = 0 to Array.length mtrx.rows - 1 do
                f i (get mtrx i j)
            done

        let column_storage_iteri j f mtrx =
            List.iter (fun (i, elt_ref) -> f i !elt_ref) mtrx.columns.(j)

        let update_column_storage j f mtrx =
            List.iter (fun (i, elt_ref) -> elt_ref := f i !elt_ref) mtrx.columns.(j)

        let iter f mtrx =
            for i = 0 to Array.length mtrx.rows - 1 do row_iter i f mtrx done

        let iterij f mtrx =
            for i = 0 to Array.length mtrx.rows - 1 do
                row_iterj i (fun j -> f i j) mtrx
            done

    end

(*
module IntElement =
    struct
        type t = int
        let equal = ( = )
    end

module IntSparseMatrix = SquareSparseMatrix.Make(IntElement)

open IntSparseMatrix;;

let m = make 10 0;;

row_iter 0 (fun elt -> print_int elt; print_newline ()) m;;

row_iterj 0 (fun j elt -> print_int j; print_string " -> ";print_int elt; print_newline ()) m;;

row_iterj 1 (fun j elt -> set m 1 j j) m;;

swap_rows m 0 1;;

row_iterj 0 (fun j elt -> print_int j; print_string " -> ";print_int elt; print_newline ()) m;;

iterij (fun i j elt -> print_int i; print_string ", "; print_int j; print_string " -> ";print_int elt; print_newline ()) m;;

let m = init 10 0 (fun i j -> i * 10 + j);;

iterij (fun i j elt -> print_int i; print_string ", "; print_int j; print_string " -> ";print_int elt; print_newline ()) m;;

*)