Source code for hybparsimony.lhs.base.randomLHS

# -*- coding: utf-8 -*-

from hybparsimony.lhs.util import findorder
from hybparsimony import order
import numpy as np

   
[docs]def randomLHS(n, k, bPreserveDraw=False, seed=None): r"""Construct a random Latin hypercube design `randomLHS(4,3)` returns a 4x3 matrix with each column constructed as follows: A random per-mutation of (1,2,3,4) is generated, say (3,1,2,4) for each of K columns. Then a uniform randomnumber is picked from each indicated quartile. In this example a random number between `0.5` and `0.75` is chosen, then one between `0 `and `0.25`, then one between `0.25` and `0.5`, finally one between `0.75` and `1`. Parameters ---------- n : int The number of rows or samples. k : int The number of columns or parameters/variables. bPreserveDraw : bool, optional Should the draw be constructed so that it is the same for variable numbers of columns?. Default `False` seed : int, optional Random seed. Default `None`. Returns ------- numpy.array A `numpy.array` of `float` with shape `(n, k)`. """ if n < 1 or k < 1: raise Exception("nsamples are less than 1 (n) or nparameters less than 1 (k)") if seed: np.random.seed(seed) result = np.zeros(n*k).reshape((n, k)) randomunif1 = np.empty(n).astype(np.double) if bPreserveDraw: randomunif2 = np.empty(n).astype(np.double) for jcol in range(k): for irow in range(n): randomunif1[irow] = np.random.uniform(low=0, high=1) for irow in range(n): randomunif2[irow] = np.random.uniform(low=0, high=1) orderVector = order(randomunif1) for irow in range(n): result[irow,jcol] = orderVector[irow] + randomunif2[irow] result[irow,jcol] = result[irow,jcol] / np.double(n) else: randomunif2 = np.empty(n*k).astype(np.double) for jcol in range(k): for irow in range(n): randomunif1[irow] = np.random.uniform(low=0, high=1) orderVector = order(randomunif1) for irow in range(n): result[irow,jcol] = orderVector[irow] for i in range(n*k): randomunif2[i] = np.random.uniform(low=0, high=1) randomunif2 = randomunif2.reshape((n, k)) for jcol in range(k): for irow in range(n): result[irow,jcol] = result[irow,jcol] + randomunif2[irow, jcol] result[irow,jcol] = result[irow,jcol] / np.double(n) return result
[docs]def randomLHS_int(n, k, seed=None): r"""Construct a random Latin hypercube design `randomLHS(4,3)` returns a 4x3 matrix with each column constructed as follows: A random per-mutation of (1,2,3,4) is generated, say (3,1,2,4) for each of K columns. Then a uniform randomnumber is picked from each indicated quartile. In this example a random number between `0.5` and `0.75` is chosen, then one between `0 `and `0.25`, then one between `0.25` and `0.5`, finally one between `0.75` and `1`. Parameters ---------- n : int The number of rows or samples. k : int The number of columns or parameters/variables. seed : int, optional Random seed. Default `None`. Returns ------- numpy.array A `numpy.array` of `int` with shape `(n, k)`. """ if seed: np.random.seed(seed) result = np.empty((n, k)).astype(np.int32) randomunif1 = np.empty(n).astype(np.double) for jcol in range(k): for irow in range(n): randomunif1[irow] = np.random.uniform(low=0, high=1) orderVector = findorder(randomunif1) for irow in range(n): result[irow,jcol] = orderVector[irow] return result