def propagate_uncertainties(self, columns, depending_variables=None, cov_matrix='<STR_LIT>',<EOL>covariance_format="<STR_LIT>",<EOL>uncertainty_format="<STR_LIT>"):
names = _ensure_strings_from_expressions(columns)<EOL>virtual_columns = self._expr(*columns, always_list=True)<EOL>if depending_variables is None:<EOL><INDENT>depending_variables = set()<EOL>for expression in virtual_columns:<EOL><INDENT>depending_variables |= expression.variables()<EOL><DEDENT>depending_variables = list(sorted(list(depending_variables)))<EOL><DEDENT>fs = [self[self.virtual_columns[name]] for name in names]<EOL>jacobian = self._jacobian(fs, depending_variables)<EOL>m = len(fs)<EOL>n = len(depending_variables)<EOL>cov_matrix = self._covariance_matrix_guess(depending_variables, full=cov_matrix == "<STR_LIT>", as_expression=True)<EOL>cov_matrix_out = [[self['<STR_LIT:0>'] for __ in range(m)] for __ in range(m)]<EOL>for i in range(m):<EOL><INDENT>for j in range(m):<EOL><INDENT>for k in range(n):<EOL><INDENT>for l in range(n):<EOL><INDENT>if jacobian[i][k].expression == '<STR_LIT:0>' or jacobian[j][l].expression == '<STR_LIT:0>' or cov_matrix[k][l].expression == '<STR_LIT:0>':<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>cov_matrix_out[i][j] = cov_matrix_out[i][j] + jacobian[i][k] * cov_matrix[k][l] * jacobian[j][l]<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>for i in range(m):<EOL><INDENT>for j in range(i + <NUM_LIT:1>):<EOL><INDENT>sigma = cov_matrix_out[i][j]<EOL>sigma = self._expr(vaex.expresso.simplify(_ensure_string_from_expression(sigma)))<EOL>if i != j:<EOL><INDENT>self.add_virtual_column(covariance_format.format(names[i], names[j]), sigma)<EOL><DEDENT>else:<EOL><INDENT>self.add_virtual_column(uncertainty_format.format(names[i]), np.sqrt(sigma))<EOL><DEDENT><DEDENT><DEDENT>
Propagates uncertainties (full covariance matrix) for a set of virtual columns.

        Covariance matrix of the depending variables is guessed by finding columns prefixed by "e"
        or `"e_"` or postfixed by "_error", "_uncertainty", "e" and `"_e"`.
        Off diagonals (covariance or correlation) by postfixes with "_correlation" or "_corr" for
        correlation or "_covariance" or "_cov" for covariances.
        (Note that x_y_cov = x_e * y_e * x_y_correlation.)


        Example

        >>> df = vaex.from_scalars(x=1, y=2, e_x=0.1, e_y=0.2)
        >>> df["u"] = df.x + df.y
        >>> df["v"] = np.log10(df.x)
        >>> df.propagate_uncertainties([df.u, df.v])
        >>> df.u_uncertainty, df.v_uncertainty

        :param columns: list of columns for which to calculate the covariance matrix.
        :param depending_variables: If not given, it is found out automatically, otherwise a list of columns which have uncertainties.
        :param cov_matrix: List of list with expressions giving the covariance matrix, in the same order as depending_variables. If 'full' or 'auto',
            the covariance matrix for the depending_variables will be guessed, where 'full' gives an error if an entry was not found.