126c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi/*
226c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi * Copyright (C) 2014 The Android Open Source Project
326c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi *
426c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License");
526c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi * you may not use this file except in compliance with the License.
626c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi * You may obtain a copy of the License at
726c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi *
826c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi *      http://www.apache.org/licenses/LICENSE-2.0
926c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi *
1026c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software
1126c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS,
1226c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1326c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi * See the License for the specific language governing permissions and
1426c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi * limitations under the License.
1526c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi */
1626c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi
1726c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi#include "suggest/core/layout/normal_distribution_2d.h"
1826c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi
1926c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi#include <gtest/gtest.h>
2026c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi
2126c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi#include <vector>
2226c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi
2326c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanaginamespace latinime {
2426c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanaginamespace {
2526c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi
2626c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagistatic const float ORIGIN_X = 0.0f;
2726c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagistatic const float ORIGIN_Y = 0.0f;
2826c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagistatic const float LARGE_STANDARD_DEVIATION = 100.0f;
2926c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagistatic const float SMALL_STANDARD_DEVIATION = 10.0f;
3026c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagistatic const float ZERO_RADIAN = 0.0f;
3126c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi
3226c806620c26e048918624367ee624526613b0d2Keisuke KuroyanagiTEST(NormalDistribution2DTest, ProbabilityDensity) {
3326c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    const NormalDistribution2D distribution(ORIGIN_X, LARGE_STANDARD_DEVIATION, ORIGIN_Y,
3426c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            SMALL_STANDARD_DEVIATION, ZERO_RADIAN);
3526c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi
3626c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    static const float SMALL_COORDINATE = 10.0f;
3726c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    static const float LARGE_COORDINATE = 20.0f;
3826c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    // The probability density of the point near the distribution center is larger than the
3926c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    // probability density of the point that is far from distribution center.
4026c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    EXPECT_GE(distribution.getProbabilityDensity(SMALL_COORDINATE, SMALL_COORDINATE),
4126c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            distribution.getProbabilityDensity(LARGE_COORDINATE, LARGE_COORDINATE));
4226c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    // The probability density of the point shifted toward the direction that has larger standard
4326c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    // deviation is larger than the probability density of the point shifted towards another
4426c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    // direction.
4526c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    EXPECT_GE(distribution.getProbabilityDensity(LARGE_COORDINATE, SMALL_COORDINATE),
4626c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            distribution.getProbabilityDensity(SMALL_COORDINATE, LARGE_COORDINATE));
4726c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi}
4826c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi
4926c806620c26e048918624367ee624526613b0d2Keisuke KuroyanagiTEST(NormalDistribution2DTest, Rotate) {
5026c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    static const float COORDINATES[] = {0.0f, 10.0f, 100.0f, -20.0f};
5126c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    static const float EPSILON = 0.01f;
5226c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    const NormalDistribution2D distribution(ORIGIN_X, LARGE_STANDARD_DEVIATION, ORIGIN_Y,
5326c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            SMALL_STANDARD_DEVIATION, ZERO_RADIAN);
5426c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    const NormalDistribution2D rotatedDistribution(ORIGIN_X, LARGE_STANDARD_DEVIATION, ORIGIN_Y,
5526c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            SMALL_STANDARD_DEVIATION, M_PI_4);
5626c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    for (const float x : COORDINATES) {
5726c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi        for (const float y : COORDINATES) {
5826c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            // The probability density of the rotated distribution at the point and the probability
5926c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            // density of the original distribution at the rotated point are the same.
6026c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            const float probabilityDensity0 = distribution.getProbabilityDensity(x, y);
6126c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            const float probabilityDensity1 = rotatedDistribution.getProbabilityDensity(-y, x);
6226c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi            EXPECT_NEAR(probabilityDensity0, probabilityDensity1, EPSILON);
6326c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi        }
6426c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi    }
6526c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi}
6626c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi
6726c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi}  // namespace
6826c806620c26e048918624367ee624526613b0d2Keisuke Kuroyanagi}  // namespace latinime
69