/*
    TCFbECosineSimilarity.cpp    June 6, 2004.

    Copyright (C) 2003-2005 CFbE Research Group,
    Software Engineering Laboratory,
    Graduate School of Information Science,
    Nara Institute of Science and Technology,
    All rights reserved.

    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, (at your option) or
    any later version.

    This program is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with GNU Emacs; see the file COPYING.  If not, write to the
    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/
//---------------------------------------------------------------------------
#pragma hdrstop

#include "TCFbECosineSimilarity.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// コンストラクタ
__fastcall TCFbECosineSimilarity::TCFbECosineSimilarity(void)
    : TCFbESimilarityComputationAlgorithm()
{
}

//---------------------------------------------------------------------------
// デストラクタ
__fastcall TCFbECosineSimilarity::~TCFbECosineSimilarity()
{
}

//---------------------------------------------------------------------------
// TargetRowIndex と AnotherRowIndex の類似度を計算する
double __fastcall TCFbECosineSimilarity::ComputeSimilarity(TCFbECustomTableEx* SimilarityComputationTable, int TargetRowIndex, int ComparedRowIndex)
{
    this->SimilarityComputationTable = SimilarityComputationTable;

    double    Numerator = 0.0;    // 分子
    double    DenominatorFirstTerm = 0.0;    // 分母第一項
    double    DenominatorSecondTerm = 0.0;    // 分母第二項

    for (int j = 0; j < SimilarityComputationTable->GetNumberOfColumns(); j++) {
        if (SimilarityComputationTable->GetCellByIndex(TargetRowIndex, j)->GetEnabled() && SimilarityComputationTable->GetCellByIndex(ComparedRowIndex, j)->GetEnabled()) {
            double    TargetValue = this->GetValue(TargetRowIndex, j);
            double    ComparedValue = this->GetValue(ComparedRowIndex, j);
            Numerator += TargetValue * ComparedValue;
            DenominatorFirstTerm += pow(TargetValue, 2.0);
            DenominatorSecondTerm += pow(ComparedValue, 2.0);
        }
    }

    double Denominator = sqrt(DenominatorFirstTerm) * sqrt(DenominatorSecondTerm);

    if (TCFbEToolkit::GetToolkit()->Equals(Denominator, 0.0)) {
//    if (Denominator == 0.0) {
        return 0.0;
    }

    return Numerator / Denominator;
}

//---------------------------------------------------------------------------
// 計算のための値を取得する
double __fastcall TCFbECosineSimilarity::GetValue(int RowIndex, int ColumnIndex)
{
    return SimilarityComputationTable->GetCellByIndex(RowIndex, ColumnIndex)->GetValue();
}

//---------------------------------------------------------------------------

