Hello there, >> def make_cov(cov_type, n_comp, n_fea): >> mincv = 0.1 >> rand = np.random.random >> return { >> 'spherical': (mincv + mincv * np.dot(rand((n_components, 1)), >> np.ones((1, n_features)))) ** >> 2, >> 'tied': (make_spd_matrix(n_features) >> + mincv * np.eye(n_features)), >> 'diag': (mincv + mincv * rand((n_components, n_features))) ** 2, >> 'full': np.array([(make_spd_matrix(n_features) >> + mincv * np.eye(n_features)) >> for x in range(n_components)]) >> }[cov_type] >> >> Specifically, could you explain the meaning of >> >> { >> ... }[cov_type] >> >> to me? > >It is a dictionary lookup. { ... } sets up a dictionary with keys > > 'spherical' > 'tied' > 'diag' > 'full' > >then { ... }[cov_type] extracts one of the values depending on >whether cov_type is 'spherical', 'tied', 'diag', or 'full'.
You will see that Steven has answered your question. I will add to his answer. Your original function could be improved many ways, but especially in terms of readability. Here's how I might go at improving the readability, without understanding anything about the actual computation. def make_cov_spherical(mincv, n_components, n_features): return (mincv + mincv * np.dot(np.random.random((n_components, 1)), np.ones((1, n_features)))) ** 2 def make_cov_diag(mincv, n_components, n_features): return (mincv + mincv * np.random.random((n_components, n_features))) ** 2 def make_cov_tied(mincv, n_components, n_features): return make_spd_matrix(n_features) + mincv * np.eye(n_features) def make_cov_full(mincv, n_components, n_features): return np.array([(make_spd_matrix(n_features) + mincv * np.eye(n_features)) for x in range(n_components)]) def make_cov(cov_type, n_comp, n_fea): mincv = 0.1 dispatch_table = { 'spherical': make_cov_spherical, 'tied': make_cov_tied, 'diag': make_cov_diag, 'full': make_cov_full, } func = dispatch_table[cov_type] return func(mincv, n_comp, n_fea) Some thoughts (and reaction to the prior code): * Your originally posted code referred to n_comp and n_fea in the signature, but then used n_components and n_features in the processing lines. Did this function ever work? * Individual functions are easier to read and understand. I would find it easier to write testing code (and docstrings) for these functions, also. * The assignment of a name (rand = np.random.random) can make sense, but I think it simply shows that the original function was trying to do too many things and was hoping to save space with this shorter name for the np.random.random. Not bad, but I dropped it anyway for the sake of clarity. * Each of the above functions (which I copied nearly verbatim) could probably now be broken into one or two lines. That would make the computation even clearer. * There may be a better way to make a function dispatch table than the one I demonstrate above, but I think it makes the point nicely. * If you break the individual computations into functions, then you only run the specific computation when it's needed. In the original example, all of the computations were run AND then, one of the results was selected. It may not matter, since computers are so fast, but, practicing basic parsimony can avoid little obvious performance hazards like this. * In short, longer, but much much clearer. Good luck, -Martin -- Martin A. Brown http://linux-ip.net/ -- https://mail.python.org/mailman/listinfo/python-list