let _sgd_basic b s t l g r o a i p x y =
let p = if i = false then ref p
else ref MX.(p @= uniform 1 (col_num p)) in
let x = if i = false then x
else MX.(x @|| ones (row_num x) 1) in
let st = ref 0.1 in
let cost = ref (Array.make 5000 0.) in
let obj0 = ref max_float in
let obj1 = ref min_float in
let counter = ref 0 in
while not (t (abs_float (!obj1 -. !obj0)) !counter) do
let _ = obj0 := !obj1 in
let xt, idx = MX.draw_rows x b in
let yt = MX.rows y idx in
let yt' = MX.(xt $@ !p) in
let lt = l yt yt' in
let dt = g xt yt yt' in
let lt = if a = 0. then lt else MX.(lt +@ (a $* (r !p))) in
let dt = if a = 0. then dt else MX.(dt +@ (a $* (o !p))) in
let _ = st := s a !st !counter in
let _ = p := MX.(!p -@ (dt *$ !st)) in
let _ = obj1 := MX.sum lt in
let _ = if !counter < (Array.length !cost) then !cost.(!counter) <- !obj1 in
let _ = counter := !counter + 1 in
Log.info "iteration #%i: %.4f" !counter !obj1;
flush stdout
done; !p