def predict(params, ctx): parameters = {param_name: param for param_name, param in zip(ctx['symbols_to_fit'], params)} zpf_kwargs = ctx.get('zpf_kwargs') activity_kwargs = ctx.get('activity_kwargs') thermochemical_kwargs = ctx.get('thermochemical_kwargs') starttime = time.time() if zpf_kwargs is not None: try: multi_phase_error = calculate_zpf_error(parameters=parameters, **zpf_kwargs) except (ValueError, np.linalg.LinAlgError) as e: raise e print(e) multi_phase_error = -np.inf else: multi_phase_error = 0 if activity_kwargs is not None: actvity_error = calculate_activity_error(parameters=parameters, **activity_kwargs) else: actvity_error = 0 if thermochemical_kwargs is not None: single_phase_error = calculate_non_equilibrium_thermochemical_probability(parameters=parameters, **thermochemical_kwargs) else: single_phase_error = 0 total_error = multi_phase_error + single_phase_error + actvity_error _log.trace('Likelihood - %0.2fs - Thermochemical: %0.3f. ZPF: %0.3f. Activity: %0.3f. Total: %0.3f.', time.time() - starttime, single_phase_error, multi_phase_error, actvity_error, total_error) error = np.array(total_error, dtype=np.float64) return error
def test_zpf_error_zero(datasets_db): """Test that sum of square ZPF errors returns 0 for an exactly correct result""" datasets_db.insert(CU_MG_DATASET_ZPF_ZERO_ERROR) dbf = Database(CU_MG_TDB) errors = calculate_zpf_error(dbf, ['CU','MG','VA'], list(dbf.phases.keys()), datasets_db, {}, {}, {}) assert np.isclose(np.sum(np.square(errors)), 0)
def lnprob( params, comps=None, dbf=None, phases=None, datasets=None, symbols_to_fit=None, phase_models=None, scheduler=None, callables=None, thermochemical_callables=None, ): """ Returns the error from multiphase fitting as a log probability. """ starttime = time.time() parameters = { param_name: param for param_name, param in zip(symbols_to_fit, params) } try: multi_phase_error = calculate_zpf_error(dbf, comps, phases, datasets, phase_models, parameters=parameters, callables=callables) except (ValueError, LinAlgError) as e: multi_phase_error = [np.inf] multi_phase_error = [ np.inf if np.isnan(x) else x**2 for x in multi_phase_error ] multi_phase_error = -np.sum(multi_phase_error) single_phase_error = calculate_thermochemical_error( dbf, comps, phases, datasets, parameters, phase_models=phase_models, callables=thermochemical_callables) actvity_error = calculate_activity_error(dbf, comps, phases, datasets, parameters=parameters, phase_models=phase_models, callables=callables) total_error = multi_phase_error + single_phase_error + actvity_error logging.debug( 'Single phase error: {:0.2f}. Multi phase error: {:0.2f}. Activity Error: {:0.2f}. Total error: {:0.2f}' .format(single_phase_error, multi_phase_error, actvity_error, total_error)) logging.debug('lnprob time: {}'.format(time.time() - starttime)) return np.array(total_error, dtype=np.float64)
def test_datasets_convert_zpf_string_values_producing_correct_value( datasets_db): """Strings where floats are expected should give correct answers for ZPF datasets""" datasets_db.insert(clean_dataset(CU_MG_DATASET_ZPF_STRING_VALUES)) dbf = Database(CU_MG_TDB) errors = calculate_zpf_error(dbf, ['CU', 'MG', 'VA'], list(dbf.phases.keys()), datasets_db, {}, {}, {}) assert np.isclose(-np.sum(np.square(errors)), -5741.61962949)
def predict(params, **ctx): """ Calculate lnprob = lnlike + lnprior """ logging.debug('Parameters - {}'.format(params)) # lnprior prior_rvs = ctx['prior_rvs'] lnprior_multivariate = [rv.logpdf(theta) for rv, theta in zip(prior_rvs, params)] logging.debug('Priors: {}'.format(lnprior_multivariate)) lnprior = np.sum(lnprior_multivariate) if np.isneginf(lnprior): # It doesn't matter what the likelihood is. We can skip calculating it to save time. logging.log(TRACE, 'Proposal - lnprior: {:0.4f}, lnlike: {}, lnprob: {:0.4f}'.format(lnprior, np.nan, lnprior)) return lnprior # lnlike parameters = {param_name: param for param_name, param in zip(ctx['symbols_to_fit'], params)} zpf_kwargs = ctx.get('zpf_kwargs') activity_kwargs = ctx.get('activity_kwargs') non_equilibrium_thermochemical_kwargs = ctx.get('thermochemical_kwargs') equilibrium_thermochemical_kwargs = ctx.get('equilibrium_thermochemical_kwargs') starttime = time.time() if zpf_kwargs is not None: try: multi_phase_error = calculate_zpf_error(parameters=np.array(params), **zpf_kwargs) except (ValueError, np.linalg.LinAlgError) as e: raise e print(e) multi_phase_error = -np.inf else: multi_phase_error = 0 if equilibrium_thermochemical_kwargs is not None: eq_thermochemical_prob = calculate_equilibrium_thermochemical_probability(parameters=np.array(params), **equilibrium_thermochemical_kwargs) else: eq_thermochemical_prob = 0 if activity_kwargs is not None: actvity_error = calculate_activity_error(parameters=parameters, **activity_kwargs) else: actvity_error = 0 if non_equilibrium_thermochemical_kwargs is not None: non_eq_thermochemical_prob = calculate_non_equilibrium_thermochemical_probability(parameters=np.array(params), **non_equilibrium_thermochemical_kwargs) else: non_eq_thermochemical_prob = 0 total_error = multi_phase_error + eq_thermochemical_prob + non_eq_thermochemical_prob + actvity_error logging.log(TRACE, f'Likelihood - {time.time() - starttime:0.2f}s - Non-equilibrium thermochemical: {non_eq_thermochemical_prob:0.3f}. Equilibrium thermochemical: {eq_thermochemical_prob:0.3f}. ZPF: {multi_phase_error:0.3f}. Activity: {actvity_error:0.3f}. Total: {total_error:0.3f}.') lnlike = np.array(total_error, dtype=np.float64) lnprob = lnprior + lnlike logging.log(TRACE, 'Proposal - lnprior: {:0.4f}, lnlike: {:0.4f}, lnprob: {:0.4f}'.format(lnprior, lnlike, lnprob)) return lnprob
def test_zpf_error_zero(datasets_db): """Test that sum of square ZPF errors returns 0 for an exactly correct result""" datasets_db.insert(CU_MG_DATASET_ZPF_ZERO_ERROR) dbf = Database(CU_MG_TDB) comps = ['CU', 'MG', 'VA'] phases = list(dbf.phases.keys()) # ZPF weight = 1 kJ and there are two points in the tieline zero_error_prob = 2 * scipy.stats.norm(loc=0, scale=1000.0).logpdf(0.0) zpf_data = get_zpf_data(comps, phases, datasets_db) error = calculate_zpf_error(dbf, phases, zpf_data) assert np.isclose(error, zero_error_prob, rtol=1e-6)
def predict(params, ctx): parameters = { param_name: param for param_name, param in zip(ctx['symbols_to_fit'], params) } zpf_kwargs = ctx.get('zpf_kwargs') activity_kwargs = ctx.get('activity_kwargs') thermochemical_kwargs = ctx.get('thermochemical_kwargs') starttime = time.time() if zpf_kwargs is not None: try: multi_phase_error = calculate_zpf_error(parameters=parameters, **zpf_kwargs) except (ValueError, np.linalg.LinAlgError) as e: raise e print(e) multi_phase_error = -np.inf else: multi_phase_error = 0 if activity_kwargs is not None: actvity_error = calculate_activity_error(parameters=parameters, **activity_kwargs) else: actvity_error = 0 if thermochemical_kwargs is not None: single_phase_error = calculate_thermochemical_error( parameters=parameters, **thermochemical_kwargs) else: single_phase_error = 0 total_error = multi_phase_error + single_phase_error + actvity_error logging.log( TRACE, 'Likelihood - {:0.2f}s - Thermochemical: {:0.3f}. ZPF: {:0.3f}. Activity: {:0.3f}. Total: {:0.3f}.' .format(time.time() - starttime, single_phase_error, multi_phase_error, actvity_error, total_error)) error = np.array(total_error, dtype=np.float64) return error
def predict(params, **ctx): """ Calculate lnprob = lnlike + lnprior """ _log.debug('Parameters - %s', params) # Important to coerce to floats here because the values _must_ be floats if # they are used to update PhaseRecords directly params = np.asarray(params, dtype=np.float_) # lnprior prior_rvs = ctx['prior_rvs'] lnprior_multivariate = [ rv.logpdf(theta) for rv, theta in zip(prior_rvs, params) ] _log.debug('Priors: %s', lnprior_multivariate) lnprior = np.sum(lnprior_multivariate) if np.isneginf(lnprior): # It doesn't matter what the likelihood is. We can skip calculating it to save time. _log.trace( 'Proposal - lnprior: %0.4f, lnlike: %0.4f, lnprob: %0.4f', lnprior, np.nan, lnprior) return lnprior # lnlike parameters = { param_name: param for param_name, param in zip(ctx['symbols_to_fit'], params.tolist()) } zpf_kwargs = ctx.get('zpf_kwargs') activity_kwargs = ctx.get('activity_kwargs') non_equilibrium_thermochemical_kwargs = ctx.get( 'thermochemical_kwargs') equilibrium_thermochemical_kwargs = ctx.get( 'equilibrium_thermochemical_kwargs') starttime = time.time() if zpf_kwargs is not None: try: multi_phase_error = calculate_zpf_error(parameters=params, **zpf_kwargs) except (ValueError, np.linalg.LinAlgError) as e: raise e print(e) multi_phase_error = -np.inf else: multi_phase_error = 0 if equilibrium_thermochemical_kwargs is not None: eq_thermochemical_prob = calculate_equilibrium_thermochemical_probability( parameters=params, **equilibrium_thermochemical_kwargs) else: eq_thermochemical_prob = 0 if activity_kwargs is not None: actvity_error = calculate_activity_error(parameters=parameters, **activity_kwargs) else: actvity_error = 0 if non_equilibrium_thermochemical_kwargs is not None: non_eq_thermochemical_prob = calculate_non_equilibrium_thermochemical_probability( parameters=params, **non_equilibrium_thermochemical_kwargs) else: non_eq_thermochemical_prob = 0 total_error = multi_phase_error + eq_thermochemical_prob + non_eq_thermochemical_prob + actvity_error _log.trace( 'Likelihood - %0.2fs - Non-equilibrium thermochemical: %0.3f. Equilibrium thermochemical: %0.3f. ZPF: %0.3f. Activity: %0.3f. Total: %0.3f.', time.time() - starttime, non_eq_thermochemical_prob, eq_thermochemical_prob, multi_phase_error, actvity_error, total_error) lnlike = np.array(total_error, dtype=np.float64) lnprob = lnprior + lnlike _log.trace('Proposal - lnprior: %0.4f, lnlike: %0.4f, lnprob: %0.4f', lnprior, lnlike, lnprob) return lnprob