/*
    TCFbEAmplifiedWeightedSumWithVWWeightedMultiplier.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 "TCFbEAmplifiedWeightedSumWithVWWeightedMultiplier.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// コンストラクタ
__fastcall TCFbEAmplifiedWeightedSumWithVWWeightedMultiplier::TCFbEAmplifiedWeightedSumWithVWWeightedMultiplier(void)
    : TCFbEWeightedSum()
{
}

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

//---------------------------------------------------------------------------
// 以降，protected メソッド
//---------------------------------------------------------------------------
// 分子の値を得る
double __fastcall TCFbEAmplifiedWeightedSumWithVWWeightedMultiplier::GetNumerator(int NeighborIndex, int TargetColumnIndex)
{
    TCFbENeighbor*    Neighbor = (TCFbENeighbor*)this->NeighborList->Items[NeighborIndex];
    int Index = this->PredictionTable->GetRowLabelList()->IndexOf(Neighbor->GetLabel());
    return Neighbor->GetValue() * this->GetVWWeightedMultiplierOfRow(this->TargetRowIndex, Index, TargetColumnIndex) * Neighbor->GetSimilarity();
}

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

// ComparedRowIndex 番目の行の BaseRowIndex 番目の行に対する Variable Weighting Weighted Multiplier を返す．
double __fastcall TCFbEAmplifiedWeightedSumWithVWWeightedMultiplier::GetVWWeightedMultiplierOfRow(int BaseRowIndex, int ComparedRowIndex, int TargetColumnIndex)
{
    double Numerator = 0.0;
    double Denominator = 0;

    for (int i = 0; i < this->VWPredictionTable->GetNumberOfRows(); i++) {
        TCFbECell* BaseCell = this->VWPredictionTable->GetCellByIndex(i, BaseRowIndex);
        TCFbECell* ComparedCell = this->VWPredictionTable->GetCellByIndex(i, ComparedRowIndex);

        if (BaseCell->GetEnabled() && ComparedCell->GetEnabled() && !TCFbEToolkit::GetToolkit()->Equals(BaseCell->GetValue(), 0.0) && !TCFbEToolkit::GetToolkit()->Equals(ComparedCell->GetValue(), 0.0)) {
            double Weight = this->GetVWPredictionOfColumn(TargetColumnIndex, i);
            if (Weight >= 0) {
                Numerator += fabs(BaseCell->GetValue() / ComparedCell->GetValue()) * Weight;
            } else {
                Numerator += fabs(ComparedCell->GetValue() / BaseCell->GetValue() * Weight);
            }
            Denominator += fabs(Weight);
        }
    }

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

    return Numerator / Denominator;
}

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

// ComparedColumnIndex 番目の列の BaseColumnIndex 番目の列に対する Variable Weighting を返す．
double __fastcall TCFbEAmplifiedWeightedSumWithVWWeightedMultiplier::GetVWPredictionOfColumn(int BaseColumnIndex, int ComparedColumnIndex)
{
    if (!this->VWPredictionCache->GetEnabledByIndex(BaseColumnIndex, ComparedColumnIndex)) {
        this->VWPredictionCache->SetValueByIndex(BaseColumnIndex, ComparedColumnIndex, this->VWPredictionAlgorithm->ComputeSimilarity(this->VWPredictionTable, BaseColumnIndex, ComparedColumnIndex));
    }
    return this->VWPredictionCache->GetValueByIndex(BaseColumnIndex, ComparedColumnIndex);
}

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

