anchor.diff:      override d.ToString() = sprintf "Categorical(probs:%A)" d.probs
   
   
  -// type Empirical(values:obj[], ?weights:Tensor, ?logweights:Tensor) =
  -//     inherit Distribution()
  -//     member d.Values = values
  -//     member d.Length = d.Values.Length
  -//     member d.Weights =
  -//         let weights =
  -//             match weights with
  -//             | None ->
  -//                 match logweights with
  -//                 | None -> failwith "Expecting either weights or logweights"
  -//                 | Some logweights -> Tensor.Exp(logweights)
  -//             | Some weights -> weights
  -//         if weights.dim <> 1 then failwithf "Expecting a vector (1d) of weights or logweights, received shape %A" weights.shape
  -//         weights
  -//     member d.Logweights = d.Weights |> dsharp.log
  -//     member d.Categorical = Categorical(probs=d.Weights)
  -//     override d.batchShape = failwith "Not implemented"
  -//     override d.eventShape = failwith "Not implemented"
  -//     override d.logprob(value) = failwith "Not implemented"
  -//     override d.mean = d.Values |> Tensor.Create |> Tensor.mean
  -//     override d.variance = d.Values |> Tensor.Create |> Tensor.variance
  -//     override d.sample() = failwith "Not implemented"
  -//     override d.ToString() = sprintf "Empirical(length:%A)" d.Length+type Empirical<'T>(values:seq<'T>, ?weights:Tensor, ?logWeights:Tensor) =
  +    inherit Distribution<'T>()
  +    let _categorical =
  +        match weights, logWeights with
  +        | Some _, Some _ -> failwithf "Expecting only one of weights, logWeights"
  +        | Some w, None -> Categorical(probs=w)
  +        | None, Some lw -> Categorical(logits=lw)
  +        | None, None -> Categorical(probs=dsharp.ones([values |> Seq.length]))
  +    member d.values = values |> Array.ofSeq
  +    member d.length = d.values.Length
  +    member d.weights = _categorical.probs
  +    member d.logWeights = _categorical.logits
  +    override d.sample() = let i = int <| _categorical.sample() in d.values.[i]
  +    override d.logprob(_) = failwith "Not supported"
  +    override d.ToString() = sprintf "Empirical(length:%A)" d.length
positive.code: 
  
  type Categorical(?probs:Tensor, ?logits:Tensor) =
      inherit Distribution()
      let _probs, _logits, _dtype =
          match probs, logits with
          | Some _, Some _ -> failwithf "Expecting only one of probs, logits"
  
negative.code: 
  
  [<AbstractClass>]
  type Distribution<'T>() =
      abstract member sample: unit -> 'T
      abstract member logprob: 'T -> Tensor
  
  
  [<AbstractClass>]
  type TensorDistribution() =
      inherit Distribution<Tensor>()
      member d.sample(numSamples:int) = Array.init numSamples (fun _ -> d.sample()) |> dsharp.stack
      abstract member batchShape: int[]
      abstract member eventShape: int[]
      abstract member mean: Tensor
      abstract member stddev: Tensor
      abstract member variance: Tensor
      default d.stddev = d.variance.sqrt()
      default d.variance = d.stddev * d.stddev
      member d.prob(value) = d.logprob(value).exp()
  
  
  type Normal(mean:Tensor, stddev:Tensor) =
      inherit TensorDistribution()
      do if mean.shape <> stddev.shape then failwithf "Expecting mean and standard deviation with same shape, received %A, %A" mean.shape stddev.shape
      do if mean.dim > 1 then failwithf "Expecting scalar parameters (0-dimensional mean and stddev) or a batch of scalar parameters (1-dimensional mean and stddev)"
      override d.batchShape = d.mean.shape
  