Lecture 018

cost graph (series-parallel graph)

1+2

1+2

(1+2)(3+4)

(1+2)(3+4)

Brent's Theorem: suppose an expression as work W and span S, being run on p processors

Pebbling

Pebbling

signature SEQUENCE =
  sig
    type 'a seq (*abstract, think of <v0, v1, v2, ..., vn> and <>*)
    val empty: unit -> 'a sequence
    exception Range of String

    (*
    REQUIRES: f total
    ENSURES: f n == <f 0, ... f (n-1)>
    *)
    val tabulate: (int -> 'a) => int -> 'a seq
    val lengt: 'a seq -> int
    val nth: 'a seq -> int -> 'a
    val map: ('a -> 'b) -> 'a seq -> 'b seq
    val reduce: ('a * 'a -> 'a') -> 'a -> 'a seq -> 'a
    val mapreduce: ('a -> 'a) -> 'b -> ('b * 'b -> 'b) -> 'a seq -> 'b
    val filter: ('a -> bool) -> 'a seq -> 'a seq
  end

Specification

suppose Seq :> SEQUENCE

Seq.empty () == <>, with cost graph o--o, O(1) work and span

Seq.tabulate f n == <f 0, ..., f(n-1)>
    o
/ / | ... \
G0 G1 ... Gn-1
\ \ | ... /
    o
where Gi is the cost graph of f i
if f is constant work and span, then Seq.tabulate has work O(n), span of O(1)

Seq.length <v0, ..., vn-1> == n, o--o, O(1) work and span

Seq.nth <v0, ..., vn-1> i == vi if 0 <= i < n, else raise Range, o--o, work span of O(1)

Seq.map f <v0, ..., vn-1> == <f vo, ... f vn-1) given f total,
    o
/ / | ... \
G0 G1 ... Gn-1
\ \ | ... /
    o
where Gi is the cost graph of f vi
if f is constant work and span, then Seq.map has work O(n), span of O(1)

Seq.filter has O(n) work and O(logn) span. IT DOES NOT TAKE O(n) BECAUSE WE AVE TO PUT THEM TOGETHER AGAIN

Seq.zip <> <>, Work: O(min(m, n)) Span: O(1) (because we preserve index)
Seq.append Work O(m+n), Span: O(1)

In case of reduce

reduce g z <v0, ... vn-1> == fold... (linear)
suppose g is associative (g(x, g(y, z))) == g(g(x, y), z)
write g(x, y) as x@y, then x@(y@z) == (x@y)@z
reduce g z <v0, ... vn-1> == (v0 @ v1 @, ... @ vn-1 @ z) can be grouped
reduce g z <> == z
    o
/ / | ... \
G0 G1 ... Gn-1
\ \ | ... /
  o o ... o
  \ | ... o
    o    /
     \  /
      o (inversed tree here)
if g is O(1) work and span, Seq.reduce is O(n) work, O(logn) span

have reduce defined, we can

fun sum(S: int Seq.seq) : int = Seq.reduce (op +) 0 S

fun count(class : int Seq.seq Seq.seq) : int = sum (Seq.map sum class)
    o
/ / | ... \
sum sum ... sum  <- O(logn) span, O(n) work
\ \ | ... /
    o
total of O(logn) span, O(n^2) work

Difference between List and Sequence

Difference between List and Sequence

Difference between List and Sequence

Difference between List and Sequence

(* rev: 'a Seq.seq * 'a Seq.seq *)
fun rev s = Seq.tabulate (fn i => (Seq.nth (Seq.length s -i-1))) n

(* maxIndex: int Seq.sqe -> int
REQUIRES: S nonempty
ENSURES: maxIndex S => the index of the largest element
COST: O(n) work, O(log n) span
*)
fun maxIndex S
  = S |> Seq.enum |> Seq.reduce1 (fn ((i, x), (j, y))
  => case Int.compare (x, y) of
       GREATER => (i, x)
     | _ => (j, y))  |> (fn (x, _) => x)

Table of Content