Skip to content

Commit

Permalink
'1015'
Browse files Browse the repository at this point in the history
  • Loading branch information
smasky committed Oct 15, 2024
1 parent fa37521 commit 62c45aa
Show file tree
Hide file tree
Showing 23 changed files with 6,364 additions and 4,144 deletions.
4 changes: 3 additions & 1 deletion UQPyL/DoE/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
from .sobol_sequence import Sobol_Sequence
from .fast_sequence import FAST_Sequence
from .morris_sequence import Morris_Sequence
__all__=['LHS', 'FFD', 'Random', 'Sobol_Sequence', 'Morris_Sequence','FAST_Sequence','Sampler']
from .saltelli_sequence import Saltelli_Sequence

__all__=['LHS', 'FFD', 'Random', 'Saltelli_Sequence','Sobol_Sequence', 'Morris_Sequence','FAST_Sequence','Sampler']
2 changes: 1 addition & 1 deletion UQPyL/DoE/morris_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def sample(self, nt: int, nx: Optional[int]=None, problem: Optional[Problem]=Non

nx=problem.nInput if problem is not None else nx

self._generate(nt, nx)
return self._generate(nt, nx)

def _generate_trajectory(self, nx: int):

Expand Down
90 changes: 90 additions & 0 deletions UQPyL/DoE/saltelli_sequence.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import numpy as np
from typing import Optional
from scipy.stats import qmc
from .samplerABC import Sampler, decoratorRescale
from ..problems import ProblemABC as Problem

class Saltelli_Sequence(Sampler):

def __init__(self, scramble: bool=True, skipValue: int=0, calSecondOrder: bool=False):

super().__init__()

self.scramble=scramble
self.skipValue=skipValue
self.calSecondOrder=calSecondOrder

@decoratorRescale
def sample(self, nt: int, nx: Optional[int] = None, problem: Optional[Problem] = None, random_seed: Optional[int] = None):

if random_seed is not None:
self.random_state = np.random.RandomState(random_seed)
else:
self.random_state = np.random.RandomState()

if problem is not None and nx is not None:
if(problem.nInput!=nx):
raise ValueError('The input dimensions of the problem and the samples must be the same')
elif problem is None and nx is None:
raise ValueError('Either the problem or the input dimensions must be provided')

nx=problem.nInput if problem is not None else nx

return self._generate(nt, nx)

def _generate(self, nt: int, nx: int):

N=nt
nInput=nx
skipValue=self.skipValue

calSecondOrder=self.calSecondOrder

M=None
if skipValue>0 and isinstance(skipValue, int):

M=skipValue

if not((M&(M-1))==0 and (M!=0 and M-1!=0)):
raise ValueError("skip value must be a power of 2!")

if N<M:
raise ValueError("N must be greater than skip value you set!")

elif skipValue<0 or not isinstance(skipValue, int):
raise ValueError("skip value must be a positive integer!")

sampler=qmc.Sobol(nInput*2, scramble=self.scramble, seed=1)

if M:
sampler.fast_forward(M)

if calSecondOrder:
saltelliSequence=np.zeros(((2*nInput+2)*N, nInput))
else:
saltelliSequence=np.zeros(((nInput+2)*N, nInput))

baseSequence=sampler.random(N)

index=0
for i in range(N):

saltelliSequence[index, :]=baseSequence[i, :nInput]

index+=1

saltelliSequence[index:index+nInput,:]=np.tile(baseSequence[i, :nInput], (nInput, 1))
saltelliSequence[index:index+nInput,:][np.diag_indices(nInput)]=baseSequence[i, nInput:]
index+=nInput

if calSecondOrder:
saltelliSequence[index:index+nInput,:]=np.tile(baseSequence[i, nInput:], (nInput, 1))
saltelliSequence[index:index+nInput,:][np.diag_indices(nInput)]=baseSequence[i, :nInput]
index+=nInput

saltelliSequence[index,:]=baseSequence[i, nInput:nInput*2]
index+=1

xSample=saltelliSequence

return xSample
8 changes: 4 additions & 4 deletions UQPyL/DoE/sobol_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@ class Sobol_Sequence(Sampler):
__call__ or sample: generate the shape of (nt*nx, nx) and numpy array Sobol sequence.
'''
def __init__(self, scramble: bool=True, skip_value: int=0):
def __init__(self, scramble: bool=True, skipValue: int=0):

super().__init__()

self.scramble=scramble
self.skip_value=skip_value
self.skipValue=skipValue

def _generate(self, nt: int, nx: int):
'''
generate the shape of (nt*nx, nx) and numpy array Sobol sequence.
'''

sampler=Sobol(d=nx, scramble=self.scramble)
xInit=sampler.random(nt+self.skip_value)
xInit=sampler.random(nt+self.skipValue)

return xInit[self.skip_value:, :]
return xInit[self.skipValue:, :]

@decoratorRescale
def sample(self, nt: int, nx: Optional[int] = None, problem: Optional[Problem] = None, random_seed: Optional[int] = None) -> np.ndarray:
Expand Down
8 changes: 6 additions & 2 deletions UQPyL/optimization/algorithmABC.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,12 @@ def evaluate(self, pop):

def checkTermination(self):

if self.FEs<=self.maxFEs:
if self.maxIter is None or self.iters<=self.maxIter:
if Verbose.isStop: #TODO

return False

if self.FEs<self.maxFEs:
if self.maxIter is None or self.iters<self.maxIter:
if self.maxTolerateTimes is None or self.tolerateTimes<=self.maxTolerateTimes:
self.iters+=1
return True
Expand Down
2 changes: 1 addition & 1 deletion UQPyL/sensibility/fast.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def analyze(self, problem: Problem, X: Optional[np.ndarray]=None, Y: Optional[np
idx=np.arange(i*n, (i+1)*n)
Y_sub=Y[idx]
#fft
f=np.fft.fft(Y_sub.ravel())
f=np.fft.fft(Y_sub)
# Sp = np.power(np.absolute(f[np.arange(1, np.ceil((self.N_within_sampler-1)/2), dtype=np.int32)-1])/self.N_within_sampler, 2) #TODO 1-(NS-1)/2
Sp = np.power(np.absolute(f[np.arange(1, np.ceil(n / 2), dtype=np.int32)]) / n, 2)
V=2.0*np.sum(Sp)
Expand Down
3 changes: 3 additions & 0 deletions UQPyL/sensibility/morris.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ def analyze(self, problem: Problem, X: Optional[np.ndarray]=None, Y: Optional[np
self.record('mu_star', problem.x_labels, mu_star)
self.record('sigma', problem.x_labels, sigma)

self.record('S1', problem.x_labels, mu)
self.record('ST', problem.x_labels, sigma)

return self.result

def summary(self):
Expand Down
2 changes: 1 addition & 1 deletion UQPyL/sensibility/rbd_fast.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def analyze(self, problem: Problem, X: np.ndarray=None, Y: np.ndarray=None):
S1[i]=S1_sub

self.record('S1', problem.x_labels, S1)

return self.result


Expand Down
42 changes: 31 additions & 11 deletions UQPyL/sensibility/rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,39 @@ def analyze(self, problem: Problem, X: np.ndarray=None, Y: np.ndarray=None):

X, Y=self.__check_and_scale_xy__(X, Y)

seq = np.linspace(0, 1, nRegion + 1)
seq = np.linspace(0.0, 1.0, nRegion + 1)
results = np.full((nRegion, nInput), np.nan)
X_di = np.empty(X.shape[0])

trr=Y.ravel()
mrr=X_di

for d_i in range(nInput):
X_di = X[:, d_i]
for bin_index in range(nRegion):
lower_bound, upper_bound = seq[bin_index], seq[bin_index + 1]
b = (lower_bound < X_di) & (X_di <= upper_bound)
if np.count_nonzero(b) > 0 and np.unique(X[b]).size > 1:
r_s = cramervonmises_2samp(Y[b].ravel(), Y[~b].ravel()).statistic
results[bin_index, d_i] = r_s

self.record("S1", problem.x_labels, results)
X_di[:] = X[:, d_i]

quants=np.quantile(trr, seq)

b = (quants[0] <= trr) & (trr <= quants[1])
if self._has_samples(Y, b):
results[0, d_i] = cramervonmises_2samp(mrr[b].ravel(), mrr[~b].ravel()).statistic

for bin_index in range(1, nRegion):

b = (quants[bin_index] < trr) & (trr <= quants[bin_index+1])

if self._has_samples(Y, b):
results[bin_index, d_i] = cramervonmises_2samp(mrr[b].ravel(), mrr[~b].ravel()).statistic


self.record("S1", problem.x_labels, np.mean(results, axis=0))
self.record("S1_Detail", problem.x_labels, np.mean(results, axis=0))

return self.result

def _has_samples(self, y, sel):

return self.result
return(
(np.count_nonzero(sel) !=0)
and (len(y[~sel])!=0 )
and np.unique(y[sel]).size > 1
)
10 changes: 5 additions & 5 deletions UQPyL/sensibility/sobol.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ def sample(self, problem: Problem, N: Optional[int]=None,
if not((M&(M-1))==0 and (M!=0 and M-1!=0)):
raise ValueError("skip value must be a power of 2!")

if N>M:
raise ValueError("skip value must be greater than N you set!")
if N<M:
raise ValueError("N must be greater than skip value you set!")

elif skipValue<0 or not isinstance(skipValue, int):
raise ValueError("skip value must be a positive integer!")
Expand Down Expand Up @@ -200,10 +200,10 @@ def analyze(self, problem: Problem, X: Optional[np.ndarray]=None, Y: Optional[np
S_Labels.append(f"{problem.x_labels[j]}-{problem.x_labels[k]}")

#Record Data
self.record('S1(First Order)', problem.x_labels, S1)
self.record('S1', problem.x_labels, S1)
if calSecondOrder:
self.record('S2(Second Order)', S_Labels, S2)
self.record('ST(Total Order)', problem.x_labels, ST)
self.record('S2', S_Labels, S2)
self.record('ST', problem.x_labels, ST)

return self.result

Expand Down
Loading

0 comments on commit 62c45aa

Please sign in to comment.