def train_with_interface(self, fun, N, NMC=10): Y, X, ind = as_design(self.avmap, N, NMC=NMC) if isinstance(self.avmap.domain, BoundedActiveVariableDomain): X = np.vstack((X, self.avmap.domain.vertX)) Y = np.vstack((Y, self.avmap.domain.vertY)) il = np.amax(ind) + 1 iu = np.amax(ind) + self.avmap.domain.vertX.shape[0] + 1 iind = np.arange(il, iu) ind = np.vstack(( ind, iind.reshape((iind.size,1)) )) # run simulation interface at all design points sr = SimulationRunner(fun) f = sr.run(X) Ef, Vf = conditional_expectations(f, ind) self.train(Y, Ef, v=Vf)
def build_from_interface(self, m, fun, dfun=None, avdim=None): self.m = m # number of gradient samples M = int(np.floor(6*(m+1)*np.log(m))) # sample points for gradients if self.bndflag: X = np.random.uniform(-1.0, 1.0, size=(M, m)) else: X = np.random.normal(size=(M, m)) funr = SimulationRunner(fun) f = funr.run(X) self.X, self.f, self.funr = X, f, funr # sample the simulation's gradients if dfun == None: df = finite_difference_gradients(X, fun) else: dfunr = SimulationGradientRunner(dfun) df = dfunr.run(X) self.dfunr = dfunr # compute the active subspace ss = Subspaces() ss.compute(df) if avdim is not None: ss.partition(avdim) self.n = ss.W1.shape[1] print 'Dimension of subspace is {:d}'.format(self.n) # set up the active variable domain and map if self.bndflag: avdom = BoundedActiveVariableDomain(ss) avmap = BoundedActiveVariableMap(avdom) else: avdom = UnboundedActiveVariableDomain(ss) avmap = UnboundedActiveVariableMap(avdom) # build the response surface avrs = ActiveSubspaceResponseSurface(avmap) avrs.train_with_interface(fun, int(np.power(5,self.n))) self.av_respsurf = avrs
def build_from_interface(self, fun, dfun=None, avdim=None): """ Build the active subspace-enabled model with interfaces to the simulation. :param function fun: A function that interfaces with the simulation. It should take an ndarray of shape 1-by-m (e.g., a row of `X`), and it should return a scalar. That scalar is the quantity of interest from the simulation. :param function dfun: A function that interfaces with the simulation. It should take an ndarray of shape 1-by-m (e.g., a row of `X`), and it should return the gradient of the quantity of interest as an ndarray of shape 1-by-m. :param int avdim: The dimension of the active subspace. If `avdim` is not present, it is chosen after computing the active subspaces using the given interfaces. **Notes** This method follows these steps: #. Draw random points according to the weight function on the space\ of simulation inputs. #. Compute the quantity of interest and its gradient at the sampled\ inputs. If `dfun` is None, use finite differences. #. Use the collection of gradients to estimate the eigenvectors and\ eigenvalues that determine and define the active subspace. #. Train a response surface using the interface, which uses a careful\ design of experiments on the space of active variables. This design\ uses about 5 points per dimension of the active subspace. """ if not hasattr(fun, '__call__'): raise TypeError('fun should be a callable function.') if dfun is not None: if not hasattr(dfun, '__call__'): raise TypeError('dfun should be a callable function.') if avdim is not None: if not isinstance(avdim, int): raise TypeError('avdim should be an integer') m = self.m # number of gradient samples M = int(np.floor(6*(m+1)*np.log(m))) # sample points for gradients if self.bounded_inputs: X = np.random.uniform(-1.0, 1.0, size=(M, m)) else: X = np.random.normal(size=(M, m)) fun = SimulationRunner(fun) f = fun.run(X) self.X, self.f, self.fun = X, f, fun # sample the simulation's gradients if dfun == None: df = finite_difference_gradients(X, fun) else: dfun = SimulationGradientRunner(dfun) df = dfun.run(X) self.dfun = dfun # compute the active subspace ss = Subspaces() ss.compute(df) if avdim is not None: ss.partition(avdim) self.n = ss.W1.shape[1] print 'The dimension of the active subspace is {:d}.'.format(self.n) # set up the active variable domain and map if self.bounded_inputs: avdom = BoundedActiveVariableDomain(ss) avmap = BoundedActiveVariableMap(avdom) else: avdom = UnboundedActiveVariableDomain(ss) avmap = UnboundedActiveVariableMap(avdom) # build the response surface asrs = ActiveSubspaceResponseSurface(avmap) asrs.train_with_interface(fun, int(np.power(5,self.n))) # compute testing error as an R-squared self.Rsqr = 1.0 - ( np.linalg.norm(asrs.predict(X)[0] - f)**2 \ / np.var(f) ) self.as_respsurf = asrs