github.com/grailbio/bigslice@v0.0.0-20230519005545-30c4c12152ad/cmd/slicetrace/quartile.go (about)

     1  // Copyright 2020 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache 2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"time"
     9  )
    10  
    11  // computeQuartiles returns the quartiles of ds, using Tukey's method. q2 is the
    12  // median of ds. q2 splits ds into two halves. q1 is the median of the lower
    13  // half. q3 is the median of the upper half. If len(ds) is odd, q2 is included
    14  // in the halves. ds must be non-empty.
    15  func computeQuartiles(ds []time.Duration) (q1, q2, q3 time.Duration) {
    16  	mid := len(ds) / 2
    17  	q2 = computeMedian(ds)
    18  	q3 = ds[(len(ds) - 1)]
    19  	if len(ds) > 1 {
    20  		q3 = computeMedian(ds[mid:])
    21  	}
    22  	var right int
    23  	if len(ds)%2 == 0 {
    24  		right = mid
    25  	} else {
    26  		right = mid + 1
    27  	}
    28  	q1 = computeMedian(ds[0:right])
    29  	return
    30  }
    31  
    32  func computeMedian(ds []time.Duration) (d time.Duration) {
    33  	mid := len(ds) / 2
    34  	if len(ds)%2 == 0 {
    35  		// Compute average without overflow.
    36  		a, b := ds[mid-1], ds[mid]
    37  		return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2)
    38  	} else {
    39  		return ds[mid]
    40  	}
    41  }