src/HOL/Matrix/FloatSparseMatrixBuilder.ML
author obua
Fri, 10 Sep 2004 14:54:54 +0200
changeset 15196 c7d69df58482
parent 15179 b8ef323fd41e
child 15531 08c8dad8e399
permissions -rw-r--r--
IntInf.divMod replaced by IntInf.div, IntInt.mod
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15179
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
     1
structure FloatSparseMatrixBuilder :
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
     2
sig
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
     3
    include MATRIX_BUILDER
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
     4
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
     5
    structure cplex : CPLEX
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
     6
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
     7
    type float = IntInf.int*IntInf.int
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
     8
    type floatfunc = float -> float
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
     9
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    10
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    11
    val float2cterm : IntInf.int * IntInf.int -> cterm
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    12
       
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    13
    val approx_value : int -> floatfunc -> string -> cterm * cterm
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    14
    val approx_vector : int -> floatfunc -> vector -> cterm * cterm
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    15
    val approx_matrix : int -> floatfunc -> matrix -> cterm * cterm
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    16
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    17
    val mk_spvec_entry : int -> float -> term
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    18
    val empty_spvec : term
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    19
    val cons_spvec : term -> term -> term
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    20
    val empty_spmat : term
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    21
    val mk_spmat_entry : int -> term -> term
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    22
    val cons_spmat : term -> term -> term
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    23
    val sign_term : term -> cterm
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    24
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    25
    val v_elem_at : vector -> int -> string option
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    26
    val m_elem_at : matrix -> int -> vector option
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    27
    val v_only_elem : vector -> int option
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    28
    val v_fold : ('a * (int * string) -> 'a) -> 'a -> vector -> 'a
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    29
    val m_fold : ('a * (int * vector) -> 'a) -> 'a -> matrix -> 'a
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    30
				   
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    31
    val transpose_matrix : matrix -> matrix
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    32
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    33
    val cut_vector : int -> vector -> vector
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    34
    val cut_matrix : vector -> (int option) -> matrix -> matrix
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    35
    
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    36
    (* cplexProg c A b *)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    37
    val cplexProg : vector -> matrix -> vector -> (cplex.cplexProg * (string -> int))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    38
    (* dual_cplexProg c A b *)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    39
    val dual_cplexProg : vector -> matrix -> vector -> (cplex.cplexProg * (string -> int))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    40
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    41
    val real_spmatT : typ
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    42
    val real_spvecT : typ
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    43
end 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    44
= 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    45
struct
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    46
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    47
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    48
structure Inttab = TableFun(type key = int val ord = (rev_order o int_ord));
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    49
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    50
type vector = string Inttab.table
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    51
type matrix = vector Inttab.table
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    52
type float = IntInf.int*IntInf.int
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    53
type floatfunc = float -> float
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    54
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    55
val th = theory "Float"
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    56
val sg = sign_of th
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    57
	 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    58
fun readtype s = Sign.intern_tycon sg s
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    59
fun readterm s = Sign.intern_const sg s
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    60
		 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    61
val ty_list = readtype "list"
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    62
val term_Nil = readterm "Nil"
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    63
val term_Cons = readterm "Cons"
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    64
		
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    65
val spvec_elemT = HOLogic.mk_prodT (HOLogic.natT, HOLogic.realT)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    66
val spvecT = Type (ty_list, [spvec_elemT])
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    67
val spmat_elemT = HOLogic.mk_prodT (HOLogic.natT, spvecT)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    68
val spmatT = Type (ty_list, [spmat_elemT])
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    69
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    70
val real_spmatT = spmatT
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    71
val real_spvecT = spvecT
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    72
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    73
val empty_matrix_const = Const (term_Nil, spmatT)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    74
val empty_vector_const = Const (term_Nil, spvecT)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    75
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    76
val Cons_spvec_const = Const (term_Cons, spvec_elemT --> spvecT --> spvecT)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    77
val Cons_spmat_const = Const (term_Cons, spmat_elemT --> spmatT --> spmatT) 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    78
			 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    79
val float_const = Const (readterm "float", HOLogic.mk_prodT (HOLogic.intT, HOLogic.intT) --> HOLogic.realT)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    80
		  
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    81
val zero = IntInf.fromInt 0
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    82
val minus_one = IntInf.fromInt ~1
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    83
val two = IntInf.fromInt 2
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    84
	  
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    85
fun mk_intinf ty n =
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    86
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    87
	fun mk_bit n = if n = zero then HOLogic.false_const else HOLogic.true_const
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    88
								 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    89
	fun bin_of n = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    90
	    if n = zero then HOLogic.pls_const
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    91
	    else if n = minus_one then HOLogic.min_const
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    92
	    else 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    93
		let 
15196
c7d69df58482 IntInf.divMod replaced by IntInf.div, IntInt.mod
obua
parents: 15179
diff changeset
    94
		    (*val (q,r) = IntInf.divMod (n, two): doesn't work in SML 10.0.7, but in newer versions!!!*)
c7d69df58482 IntInf.divMod replaced by IntInf.div, IntInt.mod
obua
parents: 15179
diff changeset
    95
	            val q = IntInf.div (n, two)
c7d69df58482 IntInf.divMod replaced by IntInf.div, IntInt.mod
obua
parents: 15179
diff changeset
    96
		    val r = IntInf.mod (n, two)
15179
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    97
		in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    98
		    HOLogic.bit_const $ bin_of q $ mk_bit r
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
    99
		end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   100
    in 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   101
	HOLogic.number_of_const ty $ (bin_of n)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   102
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   103
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   104
fun mk_float (a,b) = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   105
    float_const $ (HOLogic.mk_prod ((mk_intinf HOLogic.intT a), (mk_intinf HOLogic.intT b)))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   106
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   107
fun float2cterm (a,b) = cterm_of sg (mk_float (a,b))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   108
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   109
fun approx_value_term prec f value = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   110
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   111
	val (flower, fupper) = ExactFloatingPoint.approx_decstr_by_bin prec value
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   112
	val (flower, fupper) = (f flower, f fupper)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   113
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   114
	(mk_float flower, mk_float fupper)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   115
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   116
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   117
fun approx_value prec pprt value = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   118
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   119
	val (flower, fupper) = approx_value_term prec pprt value			       
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   120
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   121
	(cterm_of sg flower, cterm_of sg fupper)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   122
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   123
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   124
fun sign_term t = cterm_of sg t
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   125
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   126
val empty_spvec = empty_vector_const
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   127
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   128
val empty_spmat = empty_matrix_const
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   129
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   130
fun mk_spvec_entry i f = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   131
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   132
	val term_i = mk_intinf HOLogic.natT (IntInf.fromInt i)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   133
	val term_f = mk_float f
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   134
    in 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   135
	HOLogic.mk_prod (term_i, term_f)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   136
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   137
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   138
fun mk_spmat_entry i e = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   139
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   140
	val term_i = mk_intinf HOLogic.natT (IntInf.fromInt i)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   141
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   142
	HOLogic.mk_prod (term_i, e)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   143
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   144
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   145
fun cons_spvec h t = Cons_spvec_const $ h $ t
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   146
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   147
fun cons_spmat h t = Cons_spmat_const $ h $ t 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   148
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   149
fun approx_vector_term prec pprt vector = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   150
    let 	 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   151
	fun app ((vlower, vupper), (index, s)) = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   152
	    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   153
		val (flower, fupper) = approx_value_term prec pprt s
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   154
		val index = mk_intinf HOLogic.natT (IntInf.fromInt index)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   155
		val elower = HOLogic.mk_prod (index, flower)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   156
		val eupper = HOLogic.mk_prod (index, fupper)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   157
	    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   158
		(Cons_spvec_const $ elower $ vlower,
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   159
		 Cons_spvec_const $ eupper $ vupper)	
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   160
	    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   161
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   162
	Inttab.foldl app ((empty_vector_const, empty_vector_const), vector)	
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   163
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   164
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   165
fun approx_matrix_term prec pprt matrix =
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   166
    let 	 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   167
	fun app ((mlower, mupper), (index, vector)) = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   168
	    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   169
		val (vlower, vupper) = approx_vector_term prec pprt vector  
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   170
		val index = mk_intinf HOLogic.natT (IntInf.fromInt index)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   171
		val elower = HOLogic.mk_prod (index, vlower)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   172
		val eupper = HOLogic.mk_prod (index, vupper)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   173
	    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   174
		(Cons_spmat_const $ elower $ mlower,
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   175
		 Cons_spmat_const $ eupper $ mupper)		
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   176
	    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   177
		
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   178
	val (mlower, mupper) = Inttab.foldl app ((empty_matrix_const, empty_matrix_const), matrix)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   179
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   180
	Inttab.foldl app ((empty_matrix_const, empty_matrix_const), matrix)	
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   181
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   182
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   183
fun approx_vector prec pprt vector =
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   184
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   185
	val (l, u) = approx_vector_term prec pprt vector
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   186
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   187
	(cterm_of sg l, cterm_of sg u)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   188
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   189
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   190
fun approx_matrix prec pprt matrix = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   191
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   192
	val (l, u) = approx_matrix_term prec pprt matrix
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   193
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   194
	(cterm_of sg l, cterm_of sg u)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   195
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   196
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   197
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   198
exception Nat_expected of int;
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   199
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   200
val zero_interval = approx_value_term 1 I "0"
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   201
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   202
fun set_elem vector index str = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   203
    if index < 0 then 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   204
	raise (Nat_expected index)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   205
    else if (approx_value_term 1 I str) = zero_interval then 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   206
	vector
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   207
    else  
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   208
	Inttab.update ((index, str), vector)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   209
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   210
fun set_vector matrix index vector = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   211
    if index < 0 then
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   212
	raise (Nat_expected index)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   213
    else if Inttab.is_empty vector then
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   214
	matrix
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   215
    else
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   216
	Inttab.update ((index, vector), matrix)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   217
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   218
val empty_matrix = Inttab.empty
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   219
val empty_vector = Inttab.empty
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   220
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   221
(* dual stuff *)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   222
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   223
structure cplex = Cplex
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   224
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   225
fun transpose_matrix matrix = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   226
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   227
	fun upd m j i x =
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   228
	    case Inttab.lookup (m, j) of
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   229
		Some v => Inttab.update ((j, Inttab.update ((i, x), v)), m)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   230
	      | None => Inttab.update ((j, Inttab.update ((i, x), Inttab.empty)), m) 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   231
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   232
	fun updv j (m, (i, s)) = upd m i j s
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   233
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   234
	fun updm (m, (j, v)) = Inttab.foldl (updv j) (m, v)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   235
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   236
	Inttab.foldl updm (empty_matrix, matrix)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   237
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   238
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   239
exception No_name of string;
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   240
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   241
exception Superfluous_constr_right_hand_sides
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   242
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   243
fun cplexProg c A b = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   244
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   245
	val ytable = ref Inttab.empty
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   246
	fun indexof s = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   247
	    if String.size s = 0 then raise (No_name s)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   248
	    else case Int.fromString (String.extract(s, 1, NONE)) of 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   249
		     SOME i => i | NONE => raise (No_name s)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   250
				     
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   251
	fun nameof i = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   252
	    let 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   253
		val s = "x"^(Int.toString i)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   254
		val _ = ytable := (Inttab.update ((i, s), !ytable))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   255
	    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   256
		s
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   257
	    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   258
	    
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   259
	fun split_numstr s = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   260
	    if String.isPrefix "-" s then (false,String.extract(s, 1, NONE))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   261
	    else if String.isPrefix "+" s then (true, String.extract(s, 1, NONE))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   262
	    else (true, s)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   263
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   264
	fun mk_term index s =
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   265
	    let 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   266
		val (p, s) = split_numstr s
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   267
		val prod = cplex.cplexProd (cplex.cplexNum s, cplex.cplexVar (nameof index))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   268
	    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   269
		if p then prod else cplex.cplexNeg prod
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   270
	    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   271
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   272
	fun vec2sum vector =
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   273
	    cplex.cplexSum (Inttab.foldl (fn (list, (index, s)) => (mk_term index s)::list) ([], vector))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   274
		       		       
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   275
	fun mk_constr index vector c = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   276
	    let 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   277
		val s = case Inttab.lookup (c, index) of Some s => s | None => "0"
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   278
		val (p, s) = split_numstr s
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   279
		val num = if p then cplex.cplexNum s else cplex.cplexNeg (cplex.cplexNum s)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   280
	    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   281
		(None, cplex.cplexConstr (cplex.cplexLeq, (vec2sum vector, num)))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   282
	    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   283
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   284
	fun delete index c = Inttab.delete index c handle Inttab.UNDEF _ => c
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   285
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   286
	val (list, b) = Inttab.foldl 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   287
			    (fn ((list, c), (index, v)) => ((mk_constr index v c)::list, delete index c))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   288
			    (([], b), A)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   289
	val _ = if Inttab.is_empty b then () else raise Superfluous_constr_right_hand_sides
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   290
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   291
	fun mk_free y = cplex.cplexBounds (cplex.cplexNeg cplex.cplexInf, cplex.cplexLeq, 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   292
					   cplex.cplexVar y, cplex.cplexLeq,
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   293
					   cplex.cplexInf)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   294
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   295
	val yvars = Inttab.foldl (fn (l, (i, y)) => (mk_free y)::l) ([], !ytable)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   296
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   297
	val prog = cplex.cplexProg ("original", cplex.cplexMaximize (vec2sum c), list, yvars)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   298
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   299
	(prog, indexof)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   300
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   301
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   302
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   303
fun dual_cplexProg c A b = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   304
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   305
	fun indexof s = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   306
	    if String.size s = 0 then raise (No_name s)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   307
	    else case Int.fromString (String.extract(s, 1, NONE)) of 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   308
		     SOME i => i | NONE => raise (No_name s)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   309
				     
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   310
	fun nameof i = "y"^(Int.toString i)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   311
	    
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   312
	fun split_numstr s = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   313
	    if String.isPrefix "-" s then (false,String.extract(s, 1, NONE))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   314
	    else if String.isPrefix "+" s then (true, String.extract(s, 1, NONE))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   315
	    else (true, s)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   316
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   317
	fun mk_term index s =
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   318
	    let 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   319
		val (p, s) = split_numstr s
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   320
		val prod = cplex.cplexProd (cplex.cplexNum s, cplex.cplexVar (nameof index))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   321
	    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   322
		if p then prod else cplex.cplexNeg prod
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   323
	    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   324
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   325
	fun vec2sum vector =
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   326
	    cplex.cplexSum (Inttab.foldl (fn (list, (index, s)) => (mk_term index s)::list) ([], vector))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   327
		       		       
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   328
	fun mk_constr index vector c = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   329
	    let 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   330
		val s = case Inttab.lookup (c, index) of Some s => s | None => "0"
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   331
		val (p, s) = split_numstr s
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   332
		val num = if p then cplex.cplexNum s else cplex.cplexNeg (cplex.cplexNum s)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   333
	    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   334
		(None, cplex.cplexConstr (cplex.cplexEq, (vec2sum vector, num)))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   335
	    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   336
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   337
	fun delete index c = Inttab.delete index c handle Inttab.UNDEF _ => c
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   338
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   339
	val (list, c) = Inttab.foldl 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   340
			    (fn ((list, c), (index, v)) => ((mk_constr index v c)::list, delete index c))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   341
			    (([], c), transpose_matrix A)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   342
	val _ = if Inttab.is_empty c then () else raise Superfluous_constr_right_hand_sides
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   343
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   344
	val prog = cplex.cplexProg ("dual", cplex.cplexMinimize (vec2sum b), list, [])
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   345
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   346
	(prog, indexof)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   347
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   348
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   349
fun cut_vector size v = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   350
    let
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   351
	val count = ref 0 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   352
	fun app (v, (i, s)) = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   353
	    if (!count < size) then
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   354
		(count := !count +1 ; Inttab.update ((i,s),v))
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   355
	    else
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   356
		v
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   357
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   358
	Inttab.foldl app (empty_vector, v)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   359
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   360
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   361
fun cut_matrix vfilter vsize m = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   362
    let 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   363
	fun app (m, (i, v)) = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   364
	    if (Inttab.lookup (vfilter, i) = None) then 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   365
		m 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   366
	    else 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   367
		case vsize of
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   368
		    None => Inttab.update ((i,v), m)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   369
		  | Some s => Inttab.update((i, cut_vector s v),m)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   370
    in
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   371
	Inttab.foldl app (empty_matrix, m)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   372
    end
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   373
		 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   374
fun v_elem_at v i = Inttab.lookup (v,i)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   375
fun m_elem_at m i = Inttab.lookup (m,i)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   376
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   377
fun v_only_elem v = 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   378
    case Inttab.min_key v of
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   379
	None => None
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   380
      | Some vmin => (case Inttab.max_key v of
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   381
			  None => Some vmin
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   382
			| Some vmax => if vmin = vmax then Some vmin else None)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   383
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   384
fun v_fold f a v = Inttab.foldl f (a,v) 
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   385
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   386
fun m_fold f a m = Inttab.foldl f (a,m)
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   387
b8ef323fd41e Matrix theory
obua
parents:
diff changeset
   388
end;