/*
    TCFbERankCorrelation.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.
*/
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

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

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

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

    TList*    TargetSortedList = new TList();
    TList*    ComparedSortedList = new TList();

    SimilarityComputationTable->GetBothEnableSortedCellList(TargetRowIndex, ComparedRowIndex, TargetSortedList, ComparedSortedList);
    this->DoRanking(TargetSortedList);
    this->DoRanking(ComparedSortedList);

    delete TargetSortedList;
    delete ComparedSortedList;

    double    FirstTerm = 0.0;    // 分子第1項
    double    SecondTerm = 0.0;    // 分子第2項
    double    ThirdTerm = 0.0;    // 分子第3項
    double    n = 0.0;

    for (int j = 0; j < SimilarityComputationTable->GetNumberOfColumns(); j++) {
        if (SimilarityComputationTable->GetCellByIndex(TargetRowIndex, j)->GetEnabled() && SimilarityComputationTable->GetCellByIndex(ComparedRowIndex, j)->GetEnabled()) {
            double    AppliedRank = SimilarityComputationTable->GetCellByIndex(TargetRowIndex, j)->GetRank();
            double    ComparedRank = SimilarityComputationTable->GetCellByIndex(ComparedRowIndex, j)->GetRank();
            FirstTerm += pow(AppliedRank, 2.0);
            SecondTerm += pow(ComparedRank, 2.0);
            ThirdTerm += pow(AppliedRank - ComparedRank, 2.0);
            n = n + 1.0;
        }
    }

    double    T = n * (n + 1.0) / 2.0;
    double    Numerator = (FirstTerm + SecondTerm - ThirdTerm) * n / 2.0 - pow(T, 2.0);
    double    Denominator = sqrt(n * FirstTerm - pow(T, 2.0)) * sqrt(n * SecondTerm - pow(T, 2.0));

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

    return Numerator / Denominator;
}

//---------------------------------------------------------------------------
// 以下，protected メソッドの定義
//---------------------------------------------------------------------------
// ランキングを作成する
void __fastcall TCFbERankCorrelation::DoRanking(TList* RankedList)
{
    int j = 0;
    while (j < RankedList->Count) {
        int EqualsCount = 0;
        while ((j+EqualsCount < RankedList->Count) && (((TCFbECell*)RankedList->Items[j])->GetValue() == ((TCFbECell*)RankedList->Items[j+EqualsCount])->GetValue())) {
            EqualsCount++;
        }

        int IndexCount = j;

        for (int k = 0; k < EqualsCount; k++) {
            ((TCFbECell*)RankedList->Items[j])->SetRank( IndexCount + 1 + (EqualsCount - 1) * 0.5);
            j++;
        }
    }
}

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

