exception Unnormalizable; exception Misshaped; (* normalize(a,L) divides each element of list L by a *) fun normalize(a,nil) = nil | normalize(a,r::rs) = r/a::normalize(a,rs); (* condense1(b,L1,L2) subtracts from the jth element of L2 b times the jth element of L1 for all j and produces the resulting L2 *) fun condense1(b:real,nil,nil) = nil | condense1(b,x::xs,y::ys) = (y-b*x)::condense1(b,xs,ys) | condense1(_) = raise Misshaped; (* one list is longer than the other *) (* condense2(L,M) takes a list L and a list of lists M, and considers each list L' on M. For L', we subtract from each element in the tail of L' the product of the head of L' and the corresponding element of list L *) fun condense2(L,nil) = nil | condense2(L,(x::xs)::Rs) = condense1(x,L,xs)::condense2(L,Rs); (* condense(M) applies pivotal condensation to matrix M *) fun condense([[a]]) = a | condense((b::bs)::Rs) = if b <= 0.0 andalso b >= 0.0 then raise Unnormalizable (* above tests if b=0.0; recall that testing equality with a real is illegal, as is using a real in a pattern. If b=0.0, then we cannot normalize, because a division by 0.0 is called for *) else let val L = normalize(b,bs); val M' = condense2(L,Rs) in b*condense(M') end | condense(_) = raise Misshaped; (* the number of rows does not equal the length of each row *)