```# Carl is free software; you can redistribute it and/or modify it
# under the terms of the Revised BSD License; see LICENSE file for
# more details.

import numpy as np

from numpy.testing import assert_array_almost_equal

from carl.distributions import Normal
from carl.ratios import ClassifierRatio
from carl.learning import CalibratedClassifierCV

from sklearn.linear_model import ElasticNetCV
from sklearn.naive_bayes import GaussianNB

def check_classifier_ratio(clf, method, cv):
# Passing distributions directly
p0 = Normal(mu=0.0)
p1 = Normal(mu=0.1)

ratio = ClassifierRatio(CalibratedClassifierCV(base_estimator=clf,
method=method,
cv=cv))
ratio.fit(numerator=p0, denominator=p1, n_samples=10000)

reals = np.linspace(-1, 1, num=100).reshape(-1, 1)
assert ratio.score(reals, p0.pdf(reals) / p1.pdf(reals)) > -0.1
assert np.mean(np.abs(np.log(ratio.predict(reals)) -
ratio.predict(reals, log=True))) < 0.01

# Passing X, y only
X = np.vstack((p0.rvs(5000), p1.rvs(5000)))
y = np.zeros(10000, dtype=np.int)
y[5000:] = 1

ratio = ClassifierRatio(CalibratedClassifierCV(base_estimator=clf,
method=method,
cv=cv))
ratio.fit(X=X, y=y)

reals = np.linspace(-1, 1, num=100).reshape(-1, 1)
assert ratio.score(reals, p0.pdf(reals) / p1.pdf(reals)) > -0.1
assert np.mean(np.abs(np.log(ratio.predict(reals)) -
ratio.predict(reals, log=True))) < 0.01

def test_classifier_ratio():
for clf, calibration, cv in [(ElasticNetCV(), "histogram", 3),
(GaussianNB(), "kde", 3),
(ElasticNetCV(), "isotonic", 3),
(GaussianNB(), "sigmoid", 3)]:
yield check_classifier_ratio, clf, calibration, cv

def test_classifier_ratio_identity():
p = Normal(mu=0.0)
ratio = ClassifierRatio(
CalibratedClassifierCV(base_estimator=ElasticNetCV()))
ratio.fit(numerator=p, denominator=p, n_samples=10000)

reals = np.linspace(-0.5, 1.0, num=100).reshape(-1, 1)
assert ratio.score(reals, p.pdf(reals) / p.pdf(reals)) == 0.0
assert_array_almost_equal(ratio.predict(reals), np.ones(len(reals)))
assert_array_almost_equal(ratio.predict(reals, log=True),
np.zeros(len(reals)))
```