34 fun b (c1, c2, c3, c4, c5, _) = c3 |
34 fun b (c1, c2, c3, c4, c5, _) = c3 |
35 fun c (c1, c2, c3, c4, c5, _) = c4 |
35 fun c (c1, c2, c3, c4, c5, _) = c4 |
36 fun r (c1, c2, c3, c4, c5, _) = c5 |
36 fun r (c1, c2, c3, c4, c5, _) = c5 |
37 fun r12 (c1, c2, c3, c4, c5, c6) = c6 |
37 fun r12 (c1, c2, c3, c4, c5, c6) = c6 |
38 |
38 |
39 structure CplexFloatSparseMatrixConverter = |
39 structure CplexFloatSparseMatrixConverter = |
40 MAKE_CPLEX_MATRIX_CONVERTER(structure cplex = Cplex and matrix_builder = FloatSparseMatrixBuilder); |
40 MAKE_CPLEX_MATRIX_CONVERTER(structure cplex = Cplex and matrix_builder = FloatSparseMatrixBuilder); |
41 |
41 |
42 datatype bound_type = LOWER | UPPER |
42 datatype bound_type = LOWER | UPPER |
43 |
43 |
44 fun intbound_ord ((i1, b1),(i2,b2)) = |
44 fun intbound_ord ((i1, b1),(i2,b2)) = |
45 if i1 < i2 then LESS |
45 if i1 < i2 then LESS |
46 else if i1 = i2 then |
46 else if i1 = i2 then |
47 (if b1 = b2 then EQUAL else if b1=LOWER then LESS else GREATER) |
47 (if b1 = b2 then EQUAL else if b1=LOWER then LESS else GREATER) |
48 else GREATER |
48 else GREATER |
49 |
49 |
50 structure Inttab = TableFun(type key = int val ord = (rev_order o int_ord)); |
50 structure Inttab = TableFun(type key = int val ord = (rev_order o int_ord)); |
51 |
51 |
52 structure VarGraph = TableFun(type key = int*bound_type val ord = intbound_ord); |
52 structure VarGraph = TableFun(type key = int*bound_type val ord = intbound_ord); |
53 (* key -> (float option) * (int -> (float * (((float * float) * key) list)))) *) |
53 (* key -> (float option) * (int -> (float * (((float * float) * key) list)))) *) |
54 (* dest_key -> (sure_bound * (row_index -> (row_bound * (((coeff_lower * coeff_upper) * src_key) list)))) *) |
54 (* dest_key -> (sure_bound * (row_index -> (row_bound * (((coeff_lower * coeff_upper) * src_key) list)))) *) |
55 |
55 |
56 exception Internal of string; |
56 exception Internal of string; |
57 |
57 |
58 fun add_row_bound g dest_key row_index row_bound = |
58 fun add_row_bound g dest_key row_index row_bound = |
59 let |
59 let |
60 val x = |
60 val x = |
61 case VarGraph.lookup g dest_key of |
61 case VarGraph.lookup g dest_key of |
62 NONE => (NONE, Inttab.update (row_index, (row_bound, [])) Inttab.empty) |
62 NONE => (NONE, Inttab.update (row_index, (row_bound, [])) Inttab.empty) |
63 | SOME (sure_bound, f) => |
63 | SOME (sure_bound, f) => |
64 (sure_bound, |
64 (sure_bound, |
65 case Inttab.lookup f row_index of |
65 case Inttab.lookup f row_index of |
66 NONE => Inttab.update (row_index, (row_bound, [])) f |
66 NONE => Inttab.update (row_index, (row_bound, [])) f |
67 | SOME _ => raise (Internal "add_row_bound")) |
67 | SOME _ => raise (Internal "add_row_bound")) |
68 in |
68 in |
69 VarGraph.update (dest_key, x) g |
69 VarGraph.update (dest_key, x) g |
70 end |
|
71 |
|
72 fun update_sure_bound g (key as (_, btype)) bound = |
|
73 let |
|
74 val x = |
|
75 case VarGraph.lookup g key of |
|
76 NONE => (SOME bound, Inttab.empty) |
|
77 | SOME (NONE, f) => (SOME bound, f) |
|
78 | SOME (SOME old_bound, f) => |
|
79 (SOME ((case btype of |
|
80 UPPER => FloatArith.min |
|
81 | LOWER => FloatArith.max) |
|
82 old_bound bound), f) |
|
83 in |
|
84 VarGraph.update (key, x) g |
|
85 end |
70 end |
86 |
71 |
87 fun get_sure_bound g key = |
72 fun update_sure_bound g (key as (_, btype)) bound = |
88 case VarGraph.lookup g key of |
73 let |
89 NONE => NONE |
74 val x = |
|
75 case VarGraph.lookup g key of |
|
76 NONE => (SOME bound, Inttab.empty) |
|
77 | SOME (NONE, f) => (SOME bound, f) |
|
78 | SOME (SOME old_bound, f) => |
|
79 (SOME ((case btype of |
|
80 UPPER => FloatArith.min |
|
81 | LOWER => FloatArith.max) |
|
82 old_bound bound), f) |
|
83 in |
|
84 VarGraph.update (key, x) g |
|
85 end |
|
86 |
|
87 fun get_sure_bound g key = |
|
88 case VarGraph.lookup g key of |
|
89 NONE => NONE |
90 | SOME (sure_bound, _) => sure_bound |
90 | SOME (sure_bound, _) => sure_bound |
91 |
91 |
92 (*fun get_row_bound g key row_index = |
92 (*fun get_row_bound g key row_index = |
93 case VarGraph.lookup g key of |
93 case VarGraph.lookup g key of |
94 NONE => NONE |
94 NONE => NONE |
95 | SOME (sure_bound, f) => |
95 | SOME (sure_bound, f) => |
96 (case Inttab.lookup f row_index of |
96 (case Inttab.lookup f row_index of |
97 NONE => NONE |
97 NONE => NONE |
98 | SOME (row_bound, _) => (sure_bound, row_bound))*) |
98 | SOME (row_bound, _) => (sure_bound, row_bound))*) |
99 |
99 |
100 fun add_edge g src_key dest_key row_index coeff = |
100 fun add_edge g src_key dest_key row_index coeff = |
101 case VarGraph.lookup g dest_key of |
101 case VarGraph.lookup g dest_key of |
102 NONE => raise (Internal "add_edge: dest_key not found") |
102 NONE => raise (Internal "add_edge: dest_key not found") |
103 | SOME (sure_bound, f) => |
103 | SOME (sure_bound, f) => |
104 (case Inttab.lookup f row_index of |
104 (case Inttab.lookup f row_index of |
105 NONE => raise (Internal "add_edge: row_index not found") |
105 NONE => raise (Internal "add_edge: row_index not found") |
106 | SOME (row_bound, sources) => |
106 | SOME (row_bound, sources) => |
107 VarGraph.update (dest_key, (sure_bound, Inttab.update (row_index, (row_bound, (coeff, src_key) :: sources)) f)) g) |
107 VarGraph.update (dest_key, (sure_bound, Inttab.update (row_index, (row_bound, (coeff, src_key) :: sources)) f)) g) |
108 |
108 |
109 fun split_graph g = |
109 fun split_graph g = |
110 let |
110 let |
111 fun split (key, (sure_bound, _)) (r1, r2) = case sure_bound |
111 fun split (key, (sure_bound, _)) (r1, r2) = case sure_bound |
112 of NONE => (r1, r2) |
112 of NONE => (r1, r2) |
113 | SOME bound => (case key |
113 | SOME bound => (case key |
114 of (u, UPPER) => (r1, Inttab.update (u, bound) r2) |
114 of (u, UPPER) => (r1, Inttab.update (u, bound) r2) |
117 |
117 |
118 fun it2list t = Inttab.fold cons t []; |
118 fun it2list t = Inttab.fold cons t []; |
119 |
119 |
120 (* If safe is true, termination is guaranteed, but the sure bounds may be not optimal (relative to the algorithm). |
120 (* If safe is true, termination is guaranteed, but the sure bounds may be not optimal (relative to the algorithm). |
121 If safe is false, termination is not guaranteed, but on termination the sure bounds are optimal (relative to the algorithm) *) |
121 If safe is false, termination is not guaranteed, but on termination the sure bounds are optimal (relative to the algorithm) *) |
122 fun propagate_sure_bounds safe names g = |
122 fun propagate_sure_bounds safe names g = |
123 let |
123 let |
124 (* returns NONE if no new sure bound could be calculated, otherwise the new sure bound is returned *) |
124 (* returns NONE if no new sure bound could be calculated, otherwise the new sure bound is returned *) |
125 fun calc_sure_bound_from_sources g (key as (_, btype)) = |
125 fun calc_sure_bound_from_sources g (key as (_, btype)) = |
126 let |
126 let |
127 fun mult_upper x (lower, upper) = |
127 fun mult_upper x (lower, upper) = |
128 if FloatArith.is_negative x then |
128 if FloatArith.is_negative x then |
129 FloatArith.mul x lower |
129 FloatArith.mul x lower |
130 else |
130 else |
131 FloatArith.mul x upper |
131 FloatArith.mul x upper |
132 |
132 |
133 fun mult_lower x (lower, upper) = |
133 fun mult_lower x (lower, upper) = |
134 if FloatArith.is_negative x then |
134 if FloatArith.is_negative x then |
135 FloatArith.mul x upper |
135 FloatArith.mul x upper |
136 else |
136 else |
137 FloatArith.mul x lower |
137 FloatArith.mul x lower |
138 |
138 |
139 val mult_btype = case btype of UPPER => mult_upper | LOWER => mult_lower |
139 val mult_btype = case btype of UPPER => mult_upper | LOWER => mult_lower |
140 |
140 |
141 fun calc_sure_bound (row_index, (row_bound, sources)) sure_bound = |
141 fun calc_sure_bound (row_index, (row_bound, sources)) sure_bound = |
142 let |
142 let |
143 fun add_src_bound (coeff, src_key) sum = |
143 fun add_src_bound (coeff, src_key) sum = |
144 case sum of |
144 case sum of |
145 NONE => NONE |
145 NONE => NONE |
146 | SOME x => |
146 | SOME x => |
147 (case get_sure_bound g src_key of |
147 (case get_sure_bound g src_key of |
148 NONE => NONE |
148 NONE => NONE |
149 | SOME src_sure_bound => SOME (FloatArith.add x (mult_btype src_sure_bound coeff))) |
149 | SOME src_sure_bound => SOME (FloatArith.add x (mult_btype src_sure_bound coeff))) |
150 in |
150 in |
151 case fold add_src_bound sources (SOME row_bound) of |
151 case fold add_src_bound sources (SOME row_bound) of |
152 NONE => sure_bound |
152 NONE => sure_bound |
153 | new_sure_bound as (SOME new_bound) => |
153 | new_sure_bound as (SOME new_bound) => |
154 (case sure_bound of |
154 (case sure_bound of |
155 NONE => new_sure_bound |
155 NONE => new_sure_bound |
156 | SOME old_bound => |
156 | SOME old_bound => |
157 SOME (case btype of |
157 SOME (case btype of |
158 UPPER => FloatArith.min old_bound new_bound |
158 UPPER => FloatArith.min old_bound new_bound |
159 | LOWER => FloatArith.max old_bound new_bound)) |
159 | LOWER => FloatArith.max old_bound new_bound)) |
160 end |
160 end |
161 in |
161 in |
162 case VarGraph.lookup g key of |
162 case VarGraph.lookup g key of |
163 NONE => NONE |
163 NONE => NONE |
164 | SOME (sure_bound, f) => |
164 | SOME (sure_bound, f) => |
165 let |
165 let |
166 val x = Inttab.fold calc_sure_bound f sure_bound |
166 val x = Inttab.fold calc_sure_bound f sure_bound |
167 in |
167 in |
168 if x = sure_bound then NONE else x |
168 if x = sure_bound then NONE else x |
169 end |
169 end |
170 end |
170 end |
171 |
171 |
172 fun propagate (key, _) (g, b) = |
172 fun propagate (key, _) (g, b) = |
173 case calc_sure_bound_from_sources g key of |
173 case calc_sure_bound_from_sources g key of |
174 NONE => (g,b) |
174 NONE => (g,b) |
175 | SOME bound => (update_sure_bound g key bound, |
175 | SOME bound => (update_sure_bound g key bound, |
176 if safe then |
176 if safe then |
177 case get_sure_bound g key of |
177 case get_sure_bound g key of |
178 NONE => true |
178 NONE => true |
179 | _ => b |
179 | _ => b |
180 else |
180 else |
181 true) |
181 true) |
182 |
182 |
183 val (g, b) = VarGraph.fold propagate g (g, false) |
183 val (g, b) = VarGraph.fold propagate g (g, false) |
184 in |
184 in |
185 if b then propagate_sure_bounds safe names g else g |
185 if b then propagate_sure_bounds safe names g else g |
186 end |
186 end |
187 |
187 |
188 exception Load of string; |
188 exception Load of string; |
189 |
189 |
190 fun calcr safe_propagation xlen names prec A b = |
190 fun calcr safe_propagation xlen names prec A b = |
191 let |
191 let |
192 val empty = Inttab.empty |
192 val empty = Inttab.empty |
193 |
193 |
194 fun instab t i x = Inttab.update (i, x) t |
194 fun instab t i x = Inttab.update (i, x) t |
195 |
195 |
196 fun isnegstr x = String.isPrefix "-" x |
196 fun isnegstr x = String.isPrefix "-" x |
197 fun negstr x = if isnegstr x then String.extract (x, 1, NONE) else "-"^x |
197 fun negstr x = if isnegstr x then String.extract (x, 1, NONE) else "-"^x |
198 |
198 |
199 fun test_1 (lower, upper) = |
199 fun test_1 (lower, upper) = |
200 if lower = upper then |
200 if lower = upper then |
201 (if FloatArith.is_equal lower (IntInf.fromInt ~1, FloatArith.izero) then ~1 |
201 (if FloatArith.is_equal lower (IntInf.fromInt ~1, FloatArith.izero) then ~1 |
202 else if FloatArith.is_equal lower (IntInf.fromInt 1, FloatArith.izero) then 1 |
202 else if FloatArith.is_equal lower (IntInf.fromInt 1, FloatArith.izero) then 1 |
203 else 0) |
203 else 0) |
204 else 0 |
204 else 0 |
205 |
205 |
206 fun calcr (row_index, a) g = |
206 fun calcr (row_index, a) g = |
207 let |
207 let |
208 val b = FloatSparseMatrixBuilder.v_elem_at b row_index |
208 val b = FloatSparseMatrixBuilder.v_elem_at b row_index |
209 val (_, b2) = ExactFloatingPoint.approx_decstr_by_bin prec (case b of NONE => "0" | SOME b => b) |
209 val (_, b2) = ExactFloatingPoint.approx_decstr_by_bin prec (case b of NONE => "0" | SOME b => b) |
210 val approx_a = FloatSparseMatrixBuilder.v_fold (fn (i, s) => fn l => |
210 val approx_a = FloatSparseMatrixBuilder.v_fold (fn (i, s) => fn l => |
211 (i, ExactFloatingPoint.approx_decstr_by_bin prec s)::l) a [] |
211 (i, ExactFloatingPoint.approx_decstr_by_bin prec s)::l) a [] |
212 |
212 |
213 fun fold_dest_nodes (dest_index, dest_value) g = |
213 fun fold_dest_nodes (dest_index, dest_value) g = |
214 let |
214 let |
215 val dest_test = test_1 dest_value |
215 val dest_test = test_1 dest_value |
216 in |
216 in |
217 if dest_test = 0 then |
217 if dest_test = 0 then |
218 g |
218 g |
219 else let |
219 else let |
220 val (dest_key as (_, dest_btype), row_bound) = |
220 val (dest_key as (_, dest_btype), row_bound) = |
221 if dest_test = ~1 then |
221 if dest_test = ~1 then |
222 ((dest_index, LOWER), FloatArith.neg b2) |
222 ((dest_index, LOWER), FloatArith.neg b2) |
223 else |
223 else |
224 ((dest_index, UPPER), b2) |
224 ((dest_index, UPPER), b2) |
225 |
225 |
226 fun fold_src_nodes (src_index, src_value as (src_lower, src_upper)) g = |
226 fun fold_src_nodes (src_index, src_value as (src_lower, src_upper)) g = |
227 if src_index = dest_index then g |
227 if src_index = dest_index then g |
228 else |
228 else |
229 let |
229 let |
230 val coeff = case dest_btype of |
230 val coeff = case dest_btype of |
231 UPPER => (FloatArith.neg src_upper, FloatArith.neg src_lower) |
231 UPPER => (FloatArith.neg src_upper, FloatArith.neg src_lower) |
232 | LOWER => src_value |
232 | LOWER => src_value |
233 in |
233 in |
234 if FloatArith.is_negative src_lower then |
234 if FloatArith.is_negative src_lower then |
235 add_edge g (src_index, UPPER) dest_key row_index coeff |
235 add_edge g (src_index, UPPER) dest_key row_index coeff |
236 else |
236 else |
237 add_edge g (src_index, LOWER) dest_key row_index coeff |
237 add_edge g (src_index, LOWER) dest_key row_index coeff |
238 end |
238 end |
239 in |
239 in |
240 fold fold_src_nodes approx_a (add_row_bound g dest_key row_index row_bound) |
240 fold fold_src_nodes approx_a (add_row_bound g dest_key row_index row_bound) |
241 end |
241 end |
242 end |
242 end |
243 in |
243 in |
244 case approx_a of |
244 case approx_a of |
245 [] => g |
245 [] => g |
246 | [(u, a)] => |
246 | [(u, a)] => |
247 let |
247 let |
248 val atest = test_1 a |
248 val atest = test_1 a |
249 in |
249 in |
250 if atest = ~1 then |
250 if atest = ~1 then |
251 update_sure_bound g (u, LOWER) (FloatArith.neg b2) |
251 update_sure_bound g (u, LOWER) (FloatArith.neg b2) |
252 else if atest = 1 then |
252 else if atest = 1 then |
253 update_sure_bound g (u, UPPER) b2 |
253 update_sure_bound g (u, UPPER) b2 |
254 else |
254 else |
255 g |
255 g |
256 end |
256 end |
257 | _ => fold fold_dest_nodes approx_a g |
257 | _ => fold fold_dest_nodes approx_a g |
258 end |
258 end |
259 |
259 |
260 val g = FloatSparseMatrixBuilder.m_fold calcr A VarGraph.empty |
260 val g = FloatSparseMatrixBuilder.m_fold calcr A VarGraph.empty |
261 val g = propagate_sure_bounds safe_propagation names g |
261 val g = propagate_sure_bounds safe_propagation names g |
262 |
262 |
263 val (r1, r2) = split_graph g |
263 val (r1, r2) = split_graph g |
264 |
264 |
265 fun add_row_entry m index value = |
265 fun add_row_entry m index value = |
266 let |
266 let |
267 val vec = FloatSparseMatrixBuilder.cons_spvec (FloatSparseMatrixBuilder.mk_spvec_entry 0 value) FloatSparseMatrixBuilder.empty_spvec |
267 val vec = FloatSparseMatrixBuilder.cons_spvec (FloatSparseMatrixBuilder.mk_spvec_entry 0 value) FloatSparseMatrixBuilder.empty_spvec |
268 in |
268 in |
269 FloatSparseMatrixBuilder.cons_spmat (FloatSparseMatrixBuilder.mk_spmat_entry index vec) m |
269 FloatSparseMatrixBuilder.cons_spmat (FloatSparseMatrixBuilder.mk_spmat_entry index vec) m |
270 end |
270 end |
271 |
271 |
272 fun abs_estimate i r1 r2 = |
272 fun abs_estimate i r1 r2 = |
273 if i = 0 then |
273 if i = 0 then |
274 let val e = FloatSparseMatrixBuilder.empty_spmat in (e, (e, e)) end |
274 let val e = FloatSparseMatrixBuilder.empty_spmat in (e, (e, e)) end |
275 else |
275 else |
276 let |
276 let |
277 val index = xlen-i |
277 val index = xlen-i |
278 val (r, (r12_1, r12_2)) = abs_estimate (i-1) r1 r2 |
278 val (r, (r12_1, r12_2)) = abs_estimate (i-1) r1 r2 |
279 val b1 = case Inttab.lookup r1 index of NONE => raise (Load ("x-value not bounded from below: "^(names index))) | SOME x => x |
279 val b1 = case Inttab.lookup r1 index of NONE => raise (Load ("x-value not bounded from below: "^(names index))) | SOME x => x |
280 val b2 = case Inttab.lookup r2 index of NONE => raise (Load ("x-value not bounded from above: "^(names index))) | SOME x => x |
280 val b2 = case Inttab.lookup r2 index of NONE => raise (Load ("x-value not bounded from above: "^(names index))) | SOME x => x |
281 val abs_max = FloatArith.max (FloatArith.neg (FloatArith.negative_part b1)) (FloatArith.positive_part b2) |
281 val abs_max = FloatArith.max (FloatArith.neg (FloatArith.negative_part b1)) (FloatArith.positive_part b2) |
282 in |
282 in |
283 (add_row_entry r index abs_max, (add_row_entry r12_1 index b1, add_row_entry r12_2 index b2)) |
283 (add_row_entry r index abs_max, (add_row_entry r12_1 index b1, add_row_entry r12_2 index b2)) |
284 end |
284 end |
285 val sign = FloatSparseMatrixBuilder.sign_term |
285 val sign = FloatSparseMatrixBuilder.sign_term |
286 val (r, (r1, r2)) = abs_estimate xlen r1 r2 |
286 val (r, (r1, r2)) = abs_estimate xlen r1 r2 |
287 in |
287 in |
288 (sign r, (sign r1, sign r2)) |
288 (sign r, (sign r1, sign r2)) |
289 end |
289 end |
290 |
290 |
291 fun load filename prec safe_propagation = |
291 fun load filename prec safe_propagation = |
292 let |
292 let |
293 val prog = Cplex.load_cplexFile filename |
293 val prog = Cplex.load_cplexFile filename |
294 val prog = Cplex.elim_nonfree_bounds prog |
294 val prog = Cplex.elim_nonfree_bounds prog |
295 val prog = Cplex.relax_strict_ineqs prog |
295 val prog = Cplex.relax_strict_ineqs prog |
296 val (maximize, c, A, b, (xlen, names, _)) = CplexFloatSparseMatrixConverter.convert_prog prog |
296 val (maximize, c, A, b, (xlen, names, _)) = CplexFloatSparseMatrixConverter.convert_prog prog |
297 val (r, (r1, r2)) = calcr safe_propagation xlen names prec A b |
297 val (r, (r1, r2)) = calcr safe_propagation xlen names prec A b |
298 val _ = if maximize then () else raise Load "sorry, cannot handle minimization problems" |
298 val _ = if maximize then () else raise Load "sorry, cannot handle minimization problems" |
299 val (dualprog, indexof) = FloatSparseMatrixBuilder.dual_cplexProg c A b |
299 val (dualprog, indexof) = FloatSparseMatrixBuilder.dual_cplexProg c A b |
300 val results = Cplex.solve dualprog |
300 val results = Cplex.solve dualprog |
301 val (optimal,v) = CplexFloatSparseMatrixConverter.convert_results results indexof |
301 val (optimal,v) = CplexFloatSparseMatrixConverter.convert_results results indexof |
302 val A = FloatSparseMatrixBuilder.cut_matrix v NONE A |
302 val A = FloatSparseMatrixBuilder.cut_matrix v NONE A |
303 fun id x = x |
303 fun id x = x |
304 val v = FloatSparseMatrixBuilder.set_vector FloatSparseMatrixBuilder.empty_matrix 0 v |
304 val v = FloatSparseMatrixBuilder.set_vector FloatSparseMatrixBuilder.empty_matrix 0 v |
305 val b = FloatSparseMatrixBuilder.transpose_matrix (FloatSparseMatrixBuilder.set_vector FloatSparseMatrixBuilder.empty_matrix 0 b) |
305 val b = FloatSparseMatrixBuilder.transpose_matrix (FloatSparseMatrixBuilder.set_vector FloatSparseMatrixBuilder.empty_matrix 0 b) |
306 val c = FloatSparseMatrixBuilder.set_vector FloatSparseMatrixBuilder.empty_matrix 0 c |
306 val c = FloatSparseMatrixBuilder.set_vector FloatSparseMatrixBuilder.empty_matrix 0 c |
307 val (y1, _) = FloatSparseMatrixBuilder.approx_matrix prec FloatArith.positive_part v |
307 val (y1, _) = FloatSparseMatrixBuilder.approx_matrix prec FloatArith.positive_part v |
308 val A = FloatSparseMatrixBuilder.approx_matrix prec id A |
308 val A = FloatSparseMatrixBuilder.approx_matrix prec id A |
309 val (_,b2) = FloatSparseMatrixBuilder.approx_matrix prec id b |
309 val (_,b2) = FloatSparseMatrixBuilder.approx_matrix prec id b |
310 val c = FloatSparseMatrixBuilder.approx_matrix prec id c |
310 val c = FloatSparseMatrixBuilder.approx_matrix prec id c |
311 in |
311 in |
312 (y1, A, b2, c, r, (r1, r2)) |
312 (y1, A, b2, c, r, (r1, r2)) |
313 end handle CplexFloatSparseMatrixConverter.Converter s => (raise (Load ("Converter: "^s))) |
313 end handle CplexFloatSparseMatrixConverter.Converter s => (raise (Load ("Converter: "^s))) |
314 |
|
315 |
314 |
316 end |
315 end |