/*
    TCFbEWeightedSum.cpp    June 6, 2004.

    Copyright (C) 2003-2004 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 "TCFbEWeightedSum.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// コンストラクタ
__fastcall TCFbEWeightedSum::TCFbEWeightedSum(void)
    : TCFbEPredictionAlgorithm()
{
    this->NeighborList = new TObjectList();
}

//---------------------------------------------------------------------------
// デストラクタ
__fastcall TCFbEWeightedSum::~TCFbEWeightedSum()
{
    delete this->NeighborList;
}

//---------------------------------------------------------------------------
// TargetRowIndex 行目の TargetColumnIndex の値を予測する
double __fastcall TCFbEWeightedSum::Predict(int TargetRowIndex, int TargetColumnIndex, int NeighborhoodSize)
{
    this->TargetRowIndex = TargetRowIndex;
    this->TargetColumnIndex = TargetColumnIndex;

    this->DataSet->GetNearestNeighbors(TargetRowIndex, TargetColumnIndex, NeighborhoodSize, this->NeighborList);

    double    Numerator = 0.0;        // 分子
    double    Denominator = 0.0;    // 分母

    for (int i = 0; i < this->NeighborList->Count; i++) {
        Numerator += this->GetNumerator(i);
        Denominator += this->GetDenominator(i);
    }
                               
    if (TCFbEToolkit::GetToolkit()->Equals(Denominator, 0.0)) {
//    if (Denominator == 0.0) {
        return 0.0;
    } else {
        return this->GetPredictedValue(Numerator, Denominator);
    }
}

//---------------------------------------------------------------------------
// 以降，protected メソッド
//---------------------------------------------------------------------------
// キャッシュをクリアする
void __fastcall TCFbEWeightedSum::ClearCash(void)
{
    this->NeighborList->Clear();
}

//---------------------------------------------------------------------------
// 分子の値を得る
double __fastcall TCFbEWeightedSum::GetNumerator(int NeighborIndex)
{
    TCFbENeighbor*    Neighbor = (TCFbENeighbor*)this->NeighborList->Items[NeighborIndex];
    return    Neighbor->Value * Neighbor->Similarity;
}

//---------------------------------------------------------------------------
// 分母の値を得る
double __fastcall TCFbEWeightedSum::GetDenominator(int NeighborIndex)
{
    return fabs(((TCFbENeighbor*)this->NeighborList->Items[NeighborIndex])->Similarity);
}

//---------------------------------------------------------------------------
// 予測値を得る
double __fastcall TCFbEWeightedSum::GetPredictedValue(double Numerator, double Denominator)
{
    return Numerator / Denominator;
}

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

