Пример #1
0
 def __load_parcov(self):
     """private method to set the parcov attribute from:
             a pest control file (parameter bounds)
             a pst object
             a matrix object
             an uncert file
             an ascii matrix file
     """
     # if the parcov arg was not passed but the pst arg was,
     # reset and use parbounds to build parcov
     if not self.parcov_arg:
         if self.pst_arg:
             self.parcov_arg = self.pst_arg
         else:
             raise Exception("linear_analysis.__load_parcov(): " +
                             "parcov_arg is None")
     if isinstance(self.parcov_arg, Matrix):
         self.__parcov = self.parcov_arg
         return
     if isinstance(self.parcov_arg, np.ndarray):
         # if the passed array is a vector,
         # then assume it is the diagonal of the parcov matrix
         if len(self.parcov_arg.shape) == 1:
             assert self.parcov_arg.shape[0] == self.jco.shape[1]
             isdiagonal = True
         else:
             assert self.parcov_arg.shape[0] == self.jco.shape[1]
             assert self.parcov_arg.shape[1] == self.jco.shape[1]
             isdiagonal = False
         self.logger.warn("linear_analysis.__load_parcov(): " +
                          "instantiating parcov from ndarray, can't " +
                          "verify parameters alignment with jco")
         self.__parcov = Matrix(x=self.parcov_arg,
                                isdiagonal=isdiagonal,
                                row_names=self.jco.col_names,
                                col_names=self.jco.col_names)
     self.log("loading parcov")
     if isinstance(self.parcov_arg, str):
         # if the arg is a string ending with "pst"
         # then load parcov from parbounds
         if self.parcov_arg.lower().endswith(".pst"):
             self.__parcov = Cov.from_parbounds(
                 self.parcov_arg,
                 sigma_range=self.sigma_range,
                 scale_offset=self.scale_offset)
         else:
             self.__parcov = self.__fromfile(self.parcov_arg, astype=Cov)
     # if the arg is a pst object
     elif isinstance(self.parcov_arg, Pst):
         self.__parcov = Cov.from_parameter_data(
             self.parcov_arg,
             sigma_range=self.sigma_range,
             scale_offset=self.scale_offset)
     else:
         raise Exception("linear_analysis.__load_parcov(): " +
                         "parcov_arg must be a " +
                         "matrix object or a file name: " +
                         str(self.parcov_arg))
     self.log("loading parcov")
Пример #2
0
 def __load_obscov(self):
     """private method to set the obscov attribute from:
             a pest control file (observation weights)
             a pst object
             a matrix object
             an uncert file
             an ascii matrix file
     """
     # if the obscov arg is None, but the pst arg is not None,
     # reset and load from obs weights
     if not self.obscov_arg:
         if self.pst_arg:
             self.obscov_arg = self.pst_arg
         else:
             raise Exception("linear_analysis.__load_obscov(): " +
                             "obscov_arg is None")
     if isinstance(self.obscov_arg, Matrix):
         self.__obscov = self.obscov_arg
         return
     if isinstance(self.obscov_arg, np.ndarray):
         # if the ndarray arg is a vector,
         # assume it is the diagonal of the obscov matrix
         if len(self.obscov_arg.shape) == 1:
             assert self.obscov_arg.shape[0] == self.jco.shape[1]
             isdiagonal = True
         else:
             assert self.obscov_arg.shape[0] == self.jco.shape[0]
             assert self.obscov_arg.shape[1] == self.jco.shape[0]
             isdiagonal = False
         self.logger.warn("linear_analysis.__load_obscov(): " +
                          "instantiating obscov from ndarray,  " +
                          "can't verify observation alignment with jco")
         self.__obscov = Matrix(
             x=self.obscov_arg,
             isdiagonal=isdiagonal,
             row_names=self.jco.row_names,
             col_names=self.jco.row_names,
         )
     self.log("loading obscov")
     if isinstance(self.obscov_arg, str):
         if self.obscov_arg.lower().endswith(".pst"):
             self.__obscov = Cov.from_obsweights(self.obscov_arg)
         else:
             self.__obscov = self.__fromfile(self.obscov_arg, astype=Cov)
     elif isinstance(self.obscov_arg, Pst):
         self.__obscov = Cov.from_observation_data(self.obscov_arg)
     else:
         raise Exception("linear_analysis.__load_obscov(): " +
                         "obscov_arg must be a " +
                         "matrix object or a file name: " +
                         str(self.obscov_arg))
     self.log("loading obscov")
Пример #3
0
    def G(self, singular_value):
        """get the parameter solution Matrix at a singular value
            V_1 * S_1^(_1) * U_1^T

        Parameters
        ----------
        singular_value : int
            singular value to calc R at

        Returns
        -------
        G : pyemu.Matrix
            parameter solution matrix at singular value

        """
        if self.__G is not None and singular_value == self.__G_sv:
            return self.__G

        if singular_value == 0:
            self.__G_sv = 0
            self.__G = Matrix(
                x=np.zeros((self.jco.ncol,self.jco.nrow)),
                row_names=self.jco.col_names, col_names=self.jco.row_names)
            return self.__G
        mn = min(self.jco.shape)
        try:
            mn = min(self.pst.npar_adj, self.pst.nnz_obs)
        except:
            pass
        if singular_value > mn:
            self.logger.warn(
                "ErrVar.G(): singular_value > min(npar,nobs):" +
                "resetting to min(npar,nobs): " +
                str(min(self.pst.npar_adj, self.pst.nnz_obs)))
            singular_value = min(self.pst.npar_adj, self.pst.nnz_obs)
        self.log("calc G @" + str(singular_value))
        #v1 = self.qhalfx.v[:, :singular_value]
        v1 = self.xtqx.v[:, :singular_value]
        #s1 = ((self.qhalfx.s[:singular_value]) ** 2).inv
        s1 = (self.xtqx.s[:singular_value]).inv
        self.__G = v1 * s1 * v1.T * self.jco.T * self.obscov.inv
        self.__G_sv = singular_value
        self.__G.row_names = self.jco.col_names
        self.__G.col_names = self.jco.row_names
        self.__G.autoalign = True
        self.log("calc G @" + str(singular_value))
        return self.__G
Пример #4
0
 def as_pyemu_matrix(self):
     x = self.copy().as_matrix()
     return Matrix(x=x,
                   row_names=list(self.index),
                   col_names=list(self.columns))
Пример #5
0
    def __load_predictions(self):
        """private method set the predictions attribute from:
                mixed list of row names, matrix files and ndarrays
                a single row name
                an ascii file
            can be none if only interested in parameters.

        """
        if self.prediction_arg is None:
            self.__predictions = None
            return
        self.log("loading forecasts")
        if not isinstance(self.prediction_arg, list):
            self.prediction_arg = [self.prediction_arg]

        row_names = []
        vecs = []
        mat = None
        for arg in self.prediction_arg:
            if isinstance(arg, Matrix):
                # a vector
                if arg.shape[1] == 1:
                    vecs.append(arg)
                else:
                    assert arg.shape[0] == self.jco.shape[1],\
                    "linear_analysis.__load_predictions(): " +\
                    "multi-prediction matrix(npar,npred) not aligned " +\
                    "with jco(nobs,npar): " + str(arg.shape) +\
                    ' ' + str(self.jco.shape)
                    #for pred_name in arg.row_names:
                    #    vecs.append(arg.extract(row_names=pred_name).T)
                    mat = arg
            elif isinstance(arg, str):
                if arg.lower() in self.jco.row_names:
                    row_names.append(arg.lower())
                else:
                    try:
                        pred_mat = self.__fromfile(arg, astype=Matrix)
                    except Exception as e:
                        raise Exception("forecast argument: "+arg+" not found in " +\
                                        "jco row names and could not be " +\
                                        "loaded from a file.")
                    # vector
                    if pred_mat.shape[1] == 1:
                        vecs.append(pred_mat)
                    else:
                        #for pred_name in pred_mat.row_names:
                        #    vecs.append(pred_mat.get(row_names=pred_name))
                        if mat is None:
                            mat = pred_mat
                        else:
                            mat = mat.extend((pred_mat))
            elif isinstance(arg, np.ndarray):
                self.logger.warn("linear_analysis.__load_predictions(): " +
                                 "instantiating prediction matrix from " +
                                 "ndarray, can't verify alignment")
                self.logger.warn(
                    "linear_analysis.__load_predictions(): " +
                    "instantiating prediction matrix from " +
                    "ndarray, generating generic prediction names")

                pred_names = [
                    "pred_{0}".format(i + 1) for i in range(arg.shape[0])
                ]

                if self.jco:
                    names = self.jco.col_names
                elif self.parcov:
                    names = self.parcov.col_names
                else:
                    raise Exception("linear_analysis.__load_predictions(): " +
                                    "ndarray passed for predicitons " +
                                    "requires jco or parcov to get " +
                                    "parameter names")
                if mat is None:
                    mat = Matrix(x=arg, row_names=pred_names,
                                 col_names=names).T
                else:
                    mat = mat.extend(
                        Matrix(x=arg, row_names=pred_names, col_names=names).T)
                #for pred_name in pred_names:
                #    vecs.append(pred_matrix.get(row_names=pred_name).T)
            else:
                raise Exception("unrecognized predictions argument: " +
                                str(arg))
        # turn vecs into a pyemu.Matrix

        if len(vecs) > 0:
            xs = vecs[0].x
            for vec in vecs[1:]:
                xs = xs.extend(vec.x)
            names = [vec.col_names[0] for vec in vecs]
            if mat is None:
                mat = Matrix(x=xs,
                             row_names=vecs[0].row_names,
                             col_names=names)
            else:
                mat = mat.extend(
                    Matrix(x=np.array(xs),
                           row_names=vecs[0].row_names,
                           col_names=names))

        if len(row_names) > 0:
            extract = self.jco.extract(row_names=row_names).T
            if mat is None:
                mat = extract
            else:
                mat = mat.extend(extract)
            #for row_name in row_names:
            #    vecs.append(extract.get(row_names=row_name).T)
            # call obscov to load __obscov so that __obscov
            # (priavte) can be manipulated
            self.obscov
            self.__obscov.drop(row_names, axis=0)
        self.__predictions = mat
        try:
            fnames = [
                fname for fname in self.forecast_names
                if fname in self.pst.nnz_obs_names
            ]
        except:
            fnames = []
        if len(fnames) > 0:
            raise Exception(
                "forecasts with non-zero weight in pst: {0}".format(
                    ','.join(fnames)))
        self.log("loading forecasts")
        self.logger.statement("forecast names: {0}".format(','.join(
            mat.col_names)))
        return self.__predictions
Пример #6
0
    def __load_predictions(self):
        """private: set the predictions attribute from:
                mixed list of row names, matrix files and ndarrays
                a single row name
                an ascii file
            can be none if only interested in parameters.

            linear_analysis.__predictions is stored as a list of column vectors

        """
        if self.prediction_arg is None:
            self.__predictions = None
            return
        self.log("loading forecasts")
        if not isinstance(self.prediction_arg, list):
            self.prediction_arg = [self.prediction_arg]

        row_names = []
        vecs = []
        for arg in self.prediction_arg:
            if isinstance(arg, Matrix):
                # a vector
                if arg.shape[1] == 1:
                    vecs.append(arg)
                else:
                    assert arg.shape[1] == self.jco.shape[1],\
                    "linear_analysis.__load_predictions(): " +\
                    "multi-prediction matrix(npred,npar) not aligned " +\
                    "with jco(nobs,npar): " + str(arg.shape) +\
                    ' ' + str(self.jco.shape)
                    for pred_name in arg.row_names:
                        vecs.append(arg.extract(row_names=pred_name).T)
            elif isinstance(arg, str):
                if arg.lower() in self.jco.row_names:
                    row_names.append(arg.lower())
                else:
                    pred_mat = self.__fromfile(arg)
                    # vector
                    if pred_mat.shape[1] == 1:
                        vecs.append(pred_mat)
                    else:
                        for pred_name in pred_mat.row_names:
                            vecs.append(pred_mat.get(row_names=pred_name))
            elif isinstance(arg, np.ndarray):
                self.logger.warn("linear_analysis.__load_predictions(): " +
                                 "instantiating prediction matrix from " +
                                 "ndarray, can't verify alignment")
                self.logger.warn(
                    "linear_analysis.__load_predictions(): " +
                    "instantiating prediction matrix from " +
                    "ndarray, generating generic prediction names")

                pred_names = [
                    "pred_{0}".format(i + 1) for i in range(arg.shape[0])
                ]

                if self.jco:
                    names = self.jco.col_names
                elif self.parcov:
                    names = self.parcov.col_names
                else:
                    raise Exception("linear_analysis.__load_predictions(): " +
                                    "ndarray passed for predicitons " +
                                    "requires jco or parcov to get " +
                                    "parameter names")
                pred_matrix = Matrix(x=arg,
                                     row_names=pred_names,
                                     col_names=names)
                for pred_name in pred_names:
                    vecs.append(pred_matrix.get(row_names=pred_name).T)
            else:
                raise Exception("unrecognized predictions argument: " +
                                str(arg))
        if len(row_names) > 0:
            extract = self.jco.extract(row_names=row_names)
            for row_name in row_names:
                vecs.append(extract.get(row_names=row_name).T)

            # call obscov to load __obscov so that __obscov
            # (priavte) can be manipulated
            self.obscov
            self.__obscov.drop(row_names, axis=0)
        self.__predictions = vecs
        self.log("loading forecasts")
        return self.__predictions