def scramble_range(self, nrange, stream, scores=False): """ Returns a list containing a random permutation of integers "in range(nrange)", i. e. in [0, nrange-1]. Van der Waerden normal scores are also returned if so requested. An input random stream is made an argument in order for the method to be able to use any of the two random streams defined for the class. """ # A list comprehension is used, AND # It is assumed that there are no ties in the list of # floats generated by runif01... permut = extract_ranks([stream.runif01() for k in range(nrange)]) if scores: scorelist = normalscores(permut) return permut, scorelist else: return permut
def lhs_sample(self, nparams, nintervals, rcorrmatrix=None, checklevel=0): """ Generates a full Latin Hypercube Sample of uniformly distributed random variates in [0.0, 1.0] placed in a matrix with one realization in each row. A target rank correlation matrix can be given (must have the dimension nsamples*nsamples). checklevel may be 0, 1 or 2 and is used to control trace printout. 0 produces no trace output, whereas 2 produces the most. NB. IN ORDER FOR LATIN HYPERCUBE SAMPLING TO BE MEANINGFUL THE OUTPUT STREAM OF RANDOM VARIATES MUST BE HANDLED BY INVERSE METHODS !!!! Latin Hypercube Sampling was first described by McKay, Conover & Beckman in a Technometrics article 1979. The use of the LHS technique to introduce rank correlations was first described by Iman & Conover 1982 in an issue of Communications of Statistics. """ # lhs_sample uses the Matrix class to a great extent if nparams > nintervals: warn("nparams > nintervals in RandomStructure.lhs_sample") nsamples = nintervals # Just to remember rstreaminner = self.rstream rstreamouter = self.rstream2 factor = 1.0 / float(nintervals) tlhsmatrix1 = Matrix() # tlhsmatrix1 belongs to the Matrix class if rcorrmatrix: tscorematrix = Matrix() for k in range(0, nparams): if rcorrmatrix: tnvector, tscorevector = \ self.scramble_range(nsamples, rstreamouter, True) rowk = array('d', tscorevector) tscorematrix.append(rowk) else: tnvector = self.scramble_range(nsamples, rstreamouter) pvector = array('d', []) for number in tnvector: p = factor * (float(number) + rstreaminner.runif01()) p = max(p, 0.0) # Probabilities must be in [0.0, 1.0] p = min(p, 1.0) pvector.append(p) tlhsmatrix1.append(pvector) # tlhsmatrix1 (and tscorematrix) are now transposed to run with # one subsample per row to fit with output as well as Iman-Conover # formulation. tlhsmatrix1 and tscorematrix will be used anyway # for some manipulations which are more simple when matrices run # with one variable per row lhsmatrix1 = transposed(tlhsmatrix1) if rcorrmatrix: scorematrix = transposed(tscorematrix) if checklevel == 2: print("lhs_sample: Original LHS sample matrix") mxdisplay(lhsmatrix1) if rcorrmatrix: print("lhs_sample: Target rank correlation matrix") mxdisplay(rcorrmatrix) if checklevel == 1 or checklevel == 2: print("lhs_sample: Rank correlation matrix of") print(" original LHS sample matrix") trankmatrix1 = Matrix() for k in range (0, nparams): rowk = array('d', extract_ranks(tlhsmatrix1[k])) trankmatrix1.append(rowk) mxdisplay(Matrix(corrmatrix(trankmatrix1))) if not rcorrmatrix: return lhsmatrix1 else: scorecorr = Matrix(corrmatrix(tscorematrix)) if checklevel == 2: print("lhs_sample: Score matrix of original LHS sample matrix") mxdisplay(scorematrix) print("lhs_sample: Correlation matrix of scores of") print(" original LHS sample") mxdisplay(scorecorr) slower, slowert = ludcmp_chol(scorecorr) slowerinverse = inverted(slower) tslowerinverse = transposed(slowerinverse) clower, clowert = ludcmp_chol(rcorrmatrix) scoresnostar = scorematrix*tslowerinverse # Matrix multiplication if checklevel == 2: print("lhs_sample: Correlation matrix of scoresnostar") mxdisplay(corrmatrix(transposed(scoresnostar))) scoresstar = scoresnostar*clowert # Matrix multiplication tscoresstar = transposed(scoresstar) trankmatrix = Matrix() for k in range (0, nparams): trankmatrix.append(extract_ranks(tscoresstar[k])) if checklevel == 2: print("lhs_sample: scoresstar matrix") mxdisplay(scoresstar) print("lhs_sample: Correlation matrix of scoresstar") mxdisplay(corrmatrix(tscoresstar)) print("lhs_sample: scoresstar matrix converted to rank") mxdisplay(transposed(trankmatrix)) for k in range(0, nparams): tlhsmatrix1[k] = array('d', sorted(list(tlhsmatrix1[k]))) print("RandomStructure.lhs_sample: Sorted LHS sample matrix") mxdisplay(transposed(tlhsmatrix1)) tlhsmatrix2 = Matrix() for k in range(0, nparams): # Sort each row in tlhsmatrix1 and reorder # according to trankmatrix rows auxvec = reorder(tlhsmatrix1[k], trankmatrix[k], \ straighten=True) tlhsmatrix2.append(auxvec) lhsmatrix2 = transposed(tlhsmatrix2) if checklevel == 2: print("lhs_sample: Corrected/reordered LHS sample matrix") mxdisplay(transposed(tlhsmatrix2)) if checklevel == 1 or checklevel == 2: trankmatrix2 = Matrix() auxmatrix2 = tlhsmatrix2 for k in range (0, nparams): trankmatrix2.append(extract_ranks(auxmatrix2[k])) print("lhs_sample: Rank correlation matrix of corrected/") print(" /reordered LHS sample matrix") mxdisplay(corrmatrix(trankmatrix2)) return lhsmatrix2
def lhs_sample(self, nparams, nintervals, rcorrmatrix=None, checklevel=0): """ Generates a full Latin Hypercube Sample of uniformly distributed random variates in [0.0, 1.0] placed in a matrix with one realization in each row. A target rank correlation matrix can be given (must have the dimension nsamples*nsamples). checklevel may be 0, 1 or 2 and is used to control trace printout. 0 produces no trace output, whereas 2 produces the most. NB. IN ORDER FOR LATIN HYPERCUBE SAMPLING TO BE MEANINGFUL THE OUTPUT STREAM OF RANDOM VARIATES MUST BE HANDLED BY INVERSE METHODS !!!! Latin Hypercube Sampling was first described by McKay, Conover & Beckman in a Technometrics article 1979. The use of the LHS technique to introduce rank correlations was first described by Iman & Conover 1982 in an issue of Communications of Statistics. """ # lhs_sample uses the Matrix class to a great extent if nparams > nintervals: warn("nparams > nintervals in RandomStructure.lhs_sample") nsamples = nintervals # Just to remember rstreaminner = self.rstream rstreamouter = self.rstream2 factor = 1.0 / float(nintervals) tlhsmatrix1 = Matrix() # tlhsmatrix1 belongs to the Matrix class if rcorrmatrix: tscorematrix = Matrix() for k in range(0, nparams): if rcorrmatrix: tnvector, tscorevector = \ self.scramble_range(nsamples, rstreamouter, True) rowk = array('d', tscorevector) tscorematrix.append(rowk) else: tnvector = self.scramble_range(nsamples, rstreamouter) pvector = array('d', []) for number in tnvector: p = factor * (float(number) + rstreaminner.runif01()) p = max(p, 0.0) # Probabilities must be in [0.0, 1.0] p = min(p, 1.0) pvector.append(p) tlhsmatrix1.append(pvector) # tlhsmatrix1 (and tscorematrix) are now transposed to run with # one subsample per row to fit with output as well as Iman-Conover # formulation. tlhsmatrix1 and tscorematrix will be used anyway # for some manipulations which are more simple when matrices run # with one variable per row lhsmatrix1 = transposed(tlhsmatrix1) if rcorrmatrix: scorematrix = transposed(tscorematrix) if checklevel == 2: print("lhs_sample: Original LHS sample matrix") mxdisplay(lhsmatrix1) if rcorrmatrix: print("lhs_sample: Target rank correlation matrix") mxdisplay(rcorrmatrix) if checklevel == 1 or checklevel == 2: print("lhs_sample: Rank correlation matrix of") print(" original LHS sample matrix") trankmatrix1 = Matrix() for k in range(0, nparams): rowk = array('d', extract_ranks(tlhsmatrix1[k])) trankmatrix1.append(rowk) mxdisplay(Matrix(corrmatrix(trankmatrix1))) if not rcorrmatrix: return lhsmatrix1 else: scorecorr = Matrix(corrmatrix(tscorematrix)) if checklevel == 2: print("lhs_sample: Score matrix of original LHS sample matrix") mxdisplay(scorematrix) print("lhs_sample: Correlation matrix of scores of") print(" original LHS sample") mxdisplay(scorecorr) slower, slowert = ludcmp_chol(scorecorr) slowerinverse = inverted(slower) tslowerinverse = transposed(slowerinverse) clower, clowert = ludcmp_chol(rcorrmatrix) scoresnostar = scorematrix * tslowerinverse # Matrix multiplication if checklevel == 2: print("lhs_sample: Correlation matrix of scoresnostar") mxdisplay(corrmatrix(transposed(scoresnostar))) scoresstar = scoresnostar * clowert # Matrix multiplication tscoresstar = transposed(scoresstar) trankmatrix = Matrix() for k in range(0, nparams): trankmatrix.append(extract_ranks(tscoresstar[k])) if checklevel == 2: print("lhs_sample: scoresstar matrix") mxdisplay(scoresstar) print("lhs_sample: Correlation matrix of scoresstar") mxdisplay(corrmatrix(tscoresstar)) print("lhs_sample: scoresstar matrix converted to rank") mxdisplay(transposed(trankmatrix)) for k in range(0, nparams): tlhsmatrix1[k] = array('d', sorted(list(tlhsmatrix1[k]))) print("RandomStructure.lhs_sample: Sorted LHS sample matrix") mxdisplay(transposed(tlhsmatrix1)) tlhsmatrix2 = Matrix() for k in range(0, nparams): # Sort each row in tlhsmatrix1 and reorder # according to trankmatrix rows auxvec = reorder(tlhsmatrix1[k], trankmatrix[k], \ straighten=True) tlhsmatrix2.append(auxvec) lhsmatrix2 = transposed(tlhsmatrix2) if checklevel == 2: print("lhs_sample: Corrected/reordered LHS sample matrix") mxdisplay(transposed(tlhsmatrix2)) if checklevel == 1 or checklevel == 2: trankmatrix2 = Matrix() auxmatrix2 = tlhsmatrix2 for k in range(0, nparams): trankmatrix2.append(extract_ranks(auxmatrix2[k])) print("lhs_sample: Rank correlation matrix of corrected/") print(" /reordered LHS sample matrix") mxdisplay(corrmatrix(trankmatrix2)) return lhsmatrix2