/*
    TCFbETable.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 "TCFbETable.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// コンストラクタ（空のテーブルを作成
__fastcall TCFbETable::TCFbETable(void)
    : TCFbEPrimitiveTable()
{
    this->MaxOfRowList = new TObjectList();
    this->MinOfRowList = new TObjectList();
    this->AverageOfRowList = new TObjectList();
    this->MedianOfRowList = new TObjectList();
    this->StdevOfRowList = new TObjectList();
    this->InversedDistanceOfRowList = new TObjectList();
    this->CachedBaseRowListForID = new TList();
    this->MaxOfColumnList = new TObjectList();
    this->MinOfColumnList = new TObjectList();
    this->AverageOfColumnList = new TObjectList();
    this->MedianOfColumnList = new TObjectList();
    this->StdevOfColumnList = new TObjectList();
    this->InversedDistanceOfColumnList = new TObjectList();
    this->CachedBaseColumnListForID = new TList();
}

//---------------------------------------------------------------------------
// 指定された行列を備えた空テーブルを作成
__fastcall TCFbETable::TCFbETable(TStringList* RowLabelList, TStringList* ColumnLabelList)
    : TCFbEPrimitiveTable(RowLabelList, ColumnLabelList)
{
    this->MaxOfRowList = new TObjectList();
    this->MinOfRowList = new TObjectList();
    this->AverageOfRowList = new TObjectList();
    this->MedianOfRowList = new TObjectList();
    this->StdevOfRowList = new TObjectList();
    this->InversedDistanceOfRowList = new TObjectList();
    this->CachedBaseRowListForID = new TList();
    this->MaxOfColumnList = new TObjectList();
    this->MinOfColumnList = new TObjectList();
    this->AverageOfColumnList = new TObjectList();
    this->MedianOfColumnList = new TObjectList();
    this->StdevOfColumnList = new TObjectList();
    this->InversedDistanceOfColumnList = new TObjectList();
    this->CachedBaseColumnListForID = new TList();

    for (int j = 0; j < ColumnLabelList->Count; j++) {
        this->AddColumnCache();
    }

    for (int i = 0; i < RowLabelList->Count; i++) {
        this->AddRowCache();
    }
}

//---------------------------------------------------------------------------
// デストラクタ
__fastcall TCFbETable::~TCFbETable()
{
    delete this->CachedBaseColumnListForID;
    delete this->InversedDistanceOfColumnList;
    delete this->StdevOfColumnList;
    delete this->MedianOfColumnList;
    delete this->AverageOfColumnList;
    delete this->MinOfColumnList;
    delete this->MaxOfColumnList;
    delete this->CachedBaseRowListForID;
    delete this->InversedDistanceOfRowList;
    delete this->StdevOfRowList;
    delete this->MedianOfRowList;
    delete this->AverageOfRowList;
    delete this->MinOfRowList;
    delete this->MaxOfRowList;
}

//---------------------------------------------------------------------------
// SourceTable の各要素をコピーする
void __fastcall TCFbETable::Assign(TCFbETable* SourceTable)
{
    TCFbEPrimitiveTable::Assign(SourceTable);

    for (int j = 0; j < SourceTable->GetNumberOfColumns(); j++) {
        this->CopyColumnCache(SourceTable, j);
    }

    for (int i = 0; i < SourceTable->GetNumberOfRows(); i++) {
        this->CopyRowCache(SourceTable, i);
    }
}

//---------------------------------------------------------------------------
// SourceTable の各要素の行と列を入替えてコピーする
void __fastcall TCFbETable::AssignWithTurn(TCFbETable* SourceTable) {
    TCFbEPrimitiveTable::AssignWithTurn(SourceTable);

    for (int i = 0; i < SourceTable->GetNumberOfRows(); i++) {
        this->CopyColumnCacheFromRow(SourceTable, i);
    }

    // SourceTable の列要素を行要素としてコピー
    for (int j = 0; j < SourceTable->GetNumberOfColumns(); j++) {
        this->CopyRowCacheFromColumn(SourceTable, j);
    }
}

//---------------------------------------------------------------------------
void __fastcall TCFbETable::RowIsUpdated(int RowIndex)
{
    if (RowIndex >= 0) {
        ((TCFbECell*)this->MaxOfRowList->Items[RowIndex])->SetEnabled(false);
        ((TCFbECell*)this->MinOfRowList->Items[RowIndex])->SetEnabled(false);
        ((TCFbECell*)this->AverageOfRowList->Items[RowIndex])->SetEnabled(false);
        ((TCFbECell*)this->MedianOfRowList->Items[RowIndex])->SetEnabled(false);
        ((TCFbECell*)this->StdevOfRowList->Items[RowIndex])->SetEnabled(false);
//        ((TCFbECell*)this->InversedDistanceOfRowList->Items[RowIndex])->SetEnabled(false);
        for (int i = 0; i < this->CachedBaseRowListForID->Count; i++) {
            if ((int)this->CachedBaseRowListForID->Items[i] == RowIndex) {
                this->CachedBaseRowListForID->Items[i] = (void*)-1;
            }
        }
        this->CachedBaseRowListForID->Items[RowIndex] = (void*)-1;
    }
    return;
}

//---------------------------------------------------------------------------
// 行のアップデートをマークし，関係するキャッシュをクリアする．
// アップデートされた行の添字を返す．
int __fastcall TCFbETable::RowIsUpdated(AnsiString RowLabel)
{
    int RowIndex = this->FRowLabelList->IndexOf(RowLabel);
    this->RowIsUpdated(RowIndex);
    return RowIndex;
}

//---------------------------------------------------------------------------
void __fastcall TCFbETable::ColumnIsUpdated(int  ColumnIndex)
{
    if (ColumnIndex >= 0) {
        ((TCFbECell*)this->MaxOfColumnList->Items[ColumnIndex])->SetEnabled(false);
        ((TCFbECell*)this->MinOfColumnList->Items[ColumnIndex])->SetEnabled(false);
        ((TCFbECell*)this->AverageOfColumnList->Items[ColumnIndex])->SetEnabled(false);
        ((TCFbECell*)this->MedianOfColumnList->Items[ColumnIndex])->SetEnabled(false);
        ((TCFbECell*)this->StdevOfColumnList->Items[ColumnIndex])->SetEnabled(false);
//        ((TCFbECell*)this->InversedDistanceOfColumnList->Items[ColumnIndex])->SetEnabled(false);
        for (int j = 0; j < this->CachedBaseColumnListForID->Count; j++) {
            if ((int)this->CachedBaseColumnListForID->Items[j] == ColumnIndex) {
                this->CachedBaseColumnListForID->Items[j] = (void*)-1;
            }
        }
        this->CachedBaseColumnListForID->Items[ColumnIndex] = (void*)-1;
    }
    return;
}

//---------------------------------------------------------------------------
// 列のアップデートをマークし，関係するキャッシュをクリアする．
// アップデートされた列の添字を返す．
int __fastcall TCFbETable::ColumnIsUpdated(AnsiString ColumnLabel)
{
    int ColumnIndex = this->FColumnLabelList->IndexOf(ColumnLabel);
    this->ColumnIsUpdated(ColumnIndex);
    return ColumnIndex;
}

//---------------------------------------------------------------------------
// Normalize する（Cell の値を更新したら true，しなかったら false を返す
bool __fastcall TCFbETable::Normalize(TCFbECell* Cell, double MaxValue, double MinValue)
{
    if (!Cell->GetEnabled()) {
        return false;
    }
    if (TCFbEToolkit::GetToolkit()->Equals(MaxValue - MinValue, 0.0)) {
        Cell->SetValue(0.0);
    } else {
        Cell->SetValue((Cell->GetValue() - MinValue) / (MaxValue - MinValue));
    }
    return true;
}

//---------------------------------------------------------------------------
// Table の要素を部分的に Normalize する
void __fastcall TCFbETable::PartialNormalize(int ColumnIndex, bool RowUpdate)
{
    double MaxValue;
    double MinValue;
    try {
        MaxValue = this->GetMaxOfColumn(ColumnIndex);
        MinValue = this->GetMinOfColumn(ColumnIndex);
    } catch (...) {    // 列に enabled な要素がない
        return;    // この列は終わり
    }
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        if (this->Normalize(this->GetCellByIndex(i, ColumnIndex), MaxValue, MinValue) && RowUpdate) {
            this->RowIsUpdated(i);
        }
    }
    this->ColumnIsUpdated(ColumnIndex);
}

//---------------------------------------------------------------------------
// Table の要素を Normalize する
void __fastcall TCFbETable::Normalize(void)
{
    for (int j = 0; j < this->GetNumberOfColumns(); j++) {
        this->PartialNormalize(j, false);
    }
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        this->RowIsUpdated(i);
    }
}

//---------------------------------------------------------------------------
// Standardize する（Cell の値を更新したら true，しなかったら false を返す
bool __fastcall TCFbETable::Standardize(TCFbECell* Cell, double AverageValue, double StdevValue)
{
    if (!Cell->GetEnabled()) {
        return false;
    }
    if (TCFbEToolkit::GetToolkit()->Equals(StdevValue, 0.0)) {
        Cell->SetValue(0.0);
    } else {
        Cell->SetValue((Cell->GetValue() - AverageValue) / StdevValue);
    }
    return true;
}

//---------------------------------------------------------------------------
// Table の要素を部分的に Standardize する
void __fastcall TCFbETable::PartialStandardize(int ColumnIndex, bool RowUpdate)
{
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        if (this->Standardize(this->GetCellByIndex(i, ColumnIndex), this->GetAverageOfColumn(ColumnIndex), this->GetStdevOfColumn(ColumnIndex)) && RowUpdate) {
            this->RowIsUpdated(i);
        }
    }
    this->ColumnIsUpdated(ColumnIndex);
}

//---------------------------------------------------------------------------
// Table の要素を Standardize する
void __fastcall TCFbETable::Standardize(void)
{
    for (int j = 0; j < this->GetNumberOfColumns(); j++) {
        this->PartialStandardize(j, false);
    }
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        this->RowIsUpdated(i);
    }
}

//---------------------------------------------------------------------------
// Ordering する
void __fastcall TCFbETable::Ordering(TList* SortedCellList)
{
    int i = 0;
    while (i < SortedCellList->Count) {
        int EqualsCount = 0;
        while (((i+EqualsCount < SortedCellList->Count))
            && (((TCFbECell*)SortedCellList->Items[i])->GetValue() == ((TCFbECell*)SortedCellList->Items[i+EqualsCount])->GetValue())) {
            EqualsCount++;
        }

        int IndexCount = i;

        for (int k = 0; k < EqualsCount; k++) {
            ((TCFbECell*)SortedCellList->Items[i])->SetValue((SortedCellList->Count - (IndexCount + 1 + (EqualsCount - 1) * 0.5)) / (SortedCellList->Count - 1));
            i++;
        }
    }
}

//---------------------------------------------------------------------------
// Table の要素を部分的に Ordering する
void __fastcall TCFbETable::PartialOrdering(int ColumnIndex, bool RowUpdate)
{
    TList* SortedCellList = new TList();
    this->GetSortedCellListOfColumn(ColumnIndex, SortedCellList);
    this->Ordering(SortedCellList);

    if (RowUpdate) {
        for (int i = 0; i < this->GetNumberOfRows(); i++) {
            if (this->GetCellByIndex(i, ColumnIndex)->GetEnabled()) {
                this->RowIsUpdated(i);
            }
        }
    }

    this->ColumnIsUpdated(ColumnIndex);
    delete SortedCellList;
}

//---------------------------------------------------------------------------
// Table の要素を Ordering する
void __fastcall TCFbETable::Ordering(void)
{
    for (int j = 0; j < this->GetNumberOfColumns(); j++) {
        this->PartialOrdering(j, false);
    }
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        this->RowIsUpdated(i);
    }
}

//---------------------------------------------------------------------------
// Table の要素を横方向に部分的に Normalize する
void __fastcall TCFbETable::PartialRowNormalize(int RowIndex, bool ColumnUpdate)
{
    double MaxValue;
    double MinValue;
    try {
        MaxValue = this->GetMaxOfRow(RowIndex);
        MinValue = this->GetMinOfRow(RowIndex);
    } catch (...) {    // 行に enabled な要素がない
        return;    // この行は終わり
    }

    for (int j = 0; j < this->GetNumberOfColumns(); j++) {
        if (this->Normalize(this->GetCellByIndex(RowIndex, j), MaxValue, MinValue) && ColumnUpdate) {
            this->ColumnIsUpdated(j);
        }
    }
    this->RowIsUpdated(RowIndex);
}

//---------------------------------------------------------------------------
// ColumnIndex 番目の列の Table の要素を横方向に部分的に Normalize する
void __fastcall TCFbETable::PartialRowNormalizeOnColumn(int ColumnIndex, bool RowUpdate)
{
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        if (this->Normalize(this->GetCellByIndex(i, ColumnIndex), this->GetMaxOfRow(i), this->GetMinOfRow(i)) && RowUpdate) {
            this->RowIsUpdated(i);
        }
    }
    this->ColumnIsUpdated(ColumnIndex);
}

//---------------------------------------------------------------------------
// Table の要素を横方向に Normalize する
void __fastcall TCFbETable::RowNormalize(void)
{
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        this->PartialRowNormalize(i, false);
    }
    for (int j = 0; j < this->GetNumberOfColumns(); j++) {
        this->ColumnIsUpdated(j);
    }
}

//---------------------------------------------------------------------------
// Table の要素を横方向に部分的に Standardize する
void __fastcall TCFbETable::PartialRowStandardize(int RowIndex, bool ColumnUpdate)
{
    for (int j = 0; j < this->GetNumberOfColumns(); j++) {
        if (this->Standardize(this->GetCellByIndex(RowIndex, j), this->GetAverageOfRow(RowIndex), this->GetStdevOfRow(RowIndex)) && ColumnUpdate) {
            this->ColumnIsUpdated(j);
        }
    }
    this->RowIsUpdated(RowIndex);
}

//---------------------------------------------------------------------------
// ColumnIndex 番目の列の Table の要素を横方向に部分的に Standardize する
void __fastcall TCFbETable::PartialRowStandardizeOnColumn(int ColumnIndex, bool RowUpdate)
{
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        if (this->Standardize(this->GetCellByIndex(i, ColumnIndex), this->GetAverageOfRow(i), this->GetStdevOfRow(i)) && RowUpdate) {
            this->RowIsUpdated(i);
        }
    }
    this->ColumnIsUpdated(ColumnIndex);
}

//---------------------------------------------------------------------------
// Table の要素を横方向に Standardize する
void __fastcall TCFbETable::RowStandardize(void)
{
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        this->PartialRowStandardize(i, false);
    }
    for (int j = 0; j < this->GetNumberOfColumns(); j++) {
        this->ColumnIsUpdated(j);
    }
}

//---------------------------------------------------------------------------
// Table の要素を横方向に部分的に Ordering する
void __fastcall TCFbETable::PartialRowOrdering(int RowIndex, bool ColumnUpdate)
{
    TList* SortedCellList = new TList();
    this->GetSortedCellListOfRow(RowIndex, SortedCellList);
    this->Ordering(SortedCellList);

    if (ColumnUpdate) {
        for (int j = 0; j < this->GetNumberOfColumns(); j++) {
            if (this->GetCellByIndex(RowIndex, j)->GetEnabled()) {
                this->ColumnIsUpdated(j);
            }
        }
    }

    this->ColumnIsUpdated(RowIndex);
    delete SortedCellList;
}

//---------------------------------------------------------------------------
// Table の要素を横方向に Ordering する
void __fastcall TCFbETable::RowOrdering(void)
{
    for (int i = 0; i < this->GetNumberOfRows(); i++) {
        this->PartialRowOrdering(i, false);
    }
    for (int j = 0; j < this->GetNumberOfRows(); j++) {
        this->ColumnIsUpdated(j);
    }
}

//---------------------------------------------------------------------------
// TargetRowIndex 行 TargetColumnIndex 列目のNormalize された値 Value を DisNormalize して返す
double __fastcall TCFbETable::DisNormalize(int ColumnIndex, double NormalizedValue)
{
    return NormalizedValue * (this->GetMaxOfColumn(ColumnIndex) - this->GetMinOfColumn(ColumnIndex)) + this->GetMinOfColumn(ColumnIndex);
}

//---------------------------------------------------------------------------
// ColumnIndex 列目の Standardize された値 StandardizedValue を DisNormalize して返す
double __fastcall TCFbETable::DisStandardize(int ColumnIndex, double StandardizedValue)
{
    return StandardizedValue * this->GetStdevOfColumn(ColumnIndex) + this->GetAverageOfColumn(ColumnIndex);
}

//---------------------------------------------------------------------------
// ColumnIndex 列目の Ordering された値 Order を DisOrdering して返す
double __fastcall TCFbETable::DisOrdering(int ColumnIndex, double Order, TDoubleDynArray& SortedOrders)
{
    TDoubleDynArray SortedValues;
    this->GetEnabledCellsInColumn(ColumnIndex, SortedValues);
    return this->DisOrderingCommon(ColumnIndex, Order, SortedOrders, SortedValues);
}

//---------------------------------------------------------------------------
// RowIndex 列目の横方向に Normalize された値 RowNormalizedValue を DisRowNormalize して返す
double __fastcall TCFbETable::DisRowNormalize(int RowIndex, double RowNormalizedValue)
{
    return RowNormalizedValue * (this->GetMaxOfRow(RowIndex) - this->GetMinOfRow(RowIndex)) + this->GetMinOfRow(RowIndex);
}

//---------------------------------------------------------------------------
// RowIndex 列目の横方向に Standardize された値 RowStandardizedValue を DisRowStandardize して返す
double __fastcall TCFbETable::DisRowStandardize(int RowIndex, double RowStandardizedValue)
{
    return RowStandardizedValue * this->GetStdevOfRow(RowIndex) + this->GetAverageOfRow(RowIndex);
}

//---------------------------------------------------------------------------
// RowIndex 列目の横方向に Ordering された値 RowOrder を DisRowOrdering して返す
double __fastcall TCFbETable::DisRowOrdering(int RowIndex, double RowOrder, TDoubleDynArray& SortedOrders)
{
    TDoubleDynArray SortedValues;
    this->GetEnabledCellsInRow(RowIndex, SortedValues);
    double result = this->DisOrderingCommon(RowIndex, RowOrder, SortedOrders, SortedValues);
    return result;
}

//---------------------------------------------------------------------------
// DisOrdering と DisRowOrdering で使う共通の処理
double __fastcall TCFbETable::DisOrderingCommon(int Index, double Order, TDoubleDynArray& SortedOrders, TDoubleDynArray& SortedValues)
{
    TCFbEToolkit::GetToolkit()->SortDoubleDynArray(SortedValues, sdDescending);    // 降順ソート

    if (SortedValues.Length != SortedOrders.Length) {
        SortedValues.Length = 0;
        throw Exception("SortedValues.Length differed from SortedOrders.Length (in TCFbETable::DisRowOrdering).");
    }

    if (SortedOrders.Length <= 0) {
        throw Exception("There is no elememt in SortedOrders (in TCFbETable::DisRowOrdering).");
    }

    // 既存のいずれかのメトリクスの中に，予測値と同じものがある場合
    for (int i = 0; i < SortedOrders.Length; i++) {
        if (TCFbEToolkit::GetToolkit()->Equals(SortedOrders[i], Order)) {
            double ReturnValue = SortedValues[i];
            SortedValues.Length = 0;
            return ReturnValue;
        }
    }

    double LowestOrder = SortedOrders[SortedOrders.High];
    double HighestOrder = SortedOrders[0];

    // orderOf(pa,j) < orderOf(mlowest,j)である場合
    if (Order < LowestOrder) {
        int i = SortedOrders.High;
        while (--i > 0) {
            if (SortedOrders[i] > LowestOrder) {
                break;
            }
        }

        double SecondLowestOrder = (i >= 0) ? SortedOrders[i] : HighestOrder;    // RowIndex 列目の値の中で2番目に小さいもの
        double LowestValue = SortedValues[SortedValues.High];

        if (TCFbEToolkit::GetToolkit()->Equals(SecondLowestOrder - LowestOrder, 0.0)) {
            SortedValues.Length = 0;
            return LowestValue * (Order - LowestOrder) + LowestValue;
        }

        double SecondLowestValue = SortedValues[i];
        SortedValues.Length = 0;

        return (SecondLowestValue - LowestValue) / (SecondLowestOrder - LowestOrder) * (Order - LowestOrder) + LowestValue;

    // (2) orderOf(pa,j) > orderOf(mhighest,j)である場合
    } else if (Order > HighestOrder) {
        int i = 0;
        while (++i < SortedOrders.Length) {
            if (SortedOrders[i] < HighestOrder) {
                break;
            }
        }

        double SecondHighestOrder = (i >= 0) ? SortedOrders[i] : LowestOrder;    // RowIndex 列目の値の中で2番目に大きいもの
        double HighestValue = SortedValues[0];

        if (TCFbEToolkit::GetToolkit()->Equals(HighestOrder - SecondHighestOrder, 0.0)) {
            SortedValues.Length = 0;
            return HighestValue * (Order - HighestOrder) + HighestValue;
        }

        double SecondHighestValue = SortedValues[i];
        SortedValues.Length = 0;

        return (HighestValue - SecondHighestValue) / (HighestOrder - SecondHighestOrder) * (Order - HighestOrder) + HighestValue;
    }

    // それ以外の場合
    int    HighIndex = 0;
    int    LowIndex = SortedOrders.High;

    for (int i = 0; i < SortedOrders.Length; i++) {
        double CurrentOrder = SortedOrders[i];
        if ((CurrentOrder < Order) && (CurrentOrder > SortedOrders[LowIndex])) {
            LowIndex = i;
        } else if ((CurrentOrder > Order) && (CurrentOrder < SortedOrders[HighIndex])) {
            HighIndex = i;
        }
    }

    double HighOrder    = SortedOrders[HighIndex];
    double LowOrder    = SortedOrders[LowIndex];
    double HighValue    = SortedValues[HighIndex];
    double LowValue    = SortedValues[LowIndex];
    SortedValues.Length = 0;

    if (TCFbEToolkit::GetToolkit()->Equals(HighOrder - LowOrder, 0.0)) {
        return LowValue * (Order - LowOrder) + LowValue;
    }

    return ((HighValue - LowValue) / (HighOrder - LowOrder)) * (Order - LowOrder) + LowValue;
}

//---------------------------------------------------------------------------
// 行の最大値を返す．
// 行の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetMaxOfRow(int i)
{
    TCFbECell* CachedCell = (TCFbECell*)this->MaxOfRowList->Items[i];

    if (!CachedCell->GetEnabled()) {
        for (int j = 0; j < this->GetNumberOfColumns(); j++) {
            TCFbECell* CurrentCell = this->GetCellByIndex(i, j);
            if (CurrentCell->GetEnabled() && (!CachedCell->GetEnabled() || (CurrentCell->GetValue() > CachedCell->GetValue()))) {
                CachedCell->SetValue(CurrentCell->GetValue());
            }
        }

        if (!CachedCell->GetEnabled()) {
            throw Exception("There is no elements in the row (in TCFbETable::GetMaxOfRow).");
        }
    }

    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// 行の最小値を返す．
// 行の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetMinOfRow(int i)
{
    TCFbECell* CachedCell = (TCFbECell*)this->MinOfRowList->Items[i];

    if (!CachedCell->GetEnabled()) {
        for (int j = 0; j < this->GetNumberOfColumns(); j++) {
            TCFbECell* CurrentCell = this->GetCellByIndex(i, j);
            if (CurrentCell->GetEnabled() && (!CachedCell->GetEnabled() || (CurrentCell->GetValue() < CachedCell->GetValue()))) {
                CachedCell->SetValue(CurrentCell->GetValue());
            }
        }

        if (!CachedCell->GetEnabled()) {
            throw Exception("There is no elements in the row (in TCFbETable::GetMinOfRow).");
        }
    }
    
    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// 行の平均値を返す．
// 行の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetAverageOfRow(int i)
{
    TCFbECell* CachedCell = (TCFbECell*)this->AverageOfRowList->Items[i];

    if (!CachedCell->GetEnabled()) {
        int Count = 0;
        double Sum = 0;

        for (int j = 0; j < this->GetNumberOfColumns(); j++) {
            TCFbECell* CurrentCell = this->GetCellByIndex(i, j);
            if (CurrentCell->GetEnabled()) {
                Sum += CurrentCell->GetValue();
                Count++;
            }
        }

        if (Count == 0) {
            throw Exception("There is no elements in the row (in TCFbETable::GetAverageOfRow).");
        }

        CachedCell->SetValue(Sum / Count);
    }

    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// 行の中間値を返す．
// 行の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetMedianOfRow(int i)
{
    TCFbECell* CachedCell = (TCFbECell*)this->MedianOfRowList->Items[i];

    if (!CachedCell->GetEnabled()) {
        TDoubleDynArray EnabledValues;
        this->GetEnabledCellsInRow(i, EnabledValues);

        if (EnabledValues.Length == 0) {
            throw Exception("There is no elements in the row (in TCFbETable::GetMedianOfRow).");
        }

        TCFbEToolkit::GetToolkit()->SortDoubleDynArray(EnabledValues, sdDescending);
        CachedCell->SetValue(TCFbEToolkit::GetToolkit()->GetMedianOfDynArray(EnabledValues));
        EnabledValues.Length = 0;
    }

    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// 行の標準偏差を返す．
// 行の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetStdevOfRow(int i)
{
    TCFbECell* CachedCell = (TCFbECell*)this->StdevOfRowList->Items[i];

    if (!CachedCell->GetEnabled()) {
        double Average;
        try {
            Average = this->GetAverageOfRow(i);
        } catch (...) {
            throw Exception("There is no elements in the row (in TCFbETable::GetStdevOfRow).");
        }

        double    Sum = 0.0;
        int    Count = 0;
        for (int j = 0; j < this->GetNumberOfColumns(); j++) {
            TCFbECell* CurrentCell = this->GetCellByIndex(i, j);
            if (CurrentCell->GetEnabled()) {
                Sum += pow(CurrentCell->GetValue() - Average, 2.0);
                Count++;
            }
        }

        CachedCell->SetValue(sqrt(Sum / (double)Count));
    }

    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// ComparedRowIndex 番目の行の BaseRowIndex 番目の行に対する Inversed Distance を返す．
double __fastcall TCFbETable::GetInversedDistanceOfRow(int BaseRowIndex, int ComparedRowIndex)
{
    if ((int)this->CachedBaseRowListForID->Items[ComparedRowIndex] != BaseRowIndex) {
        double Sum = 0.0;
        int Count = 0;
        for (int j = 0; j < this->GetNumberOfColumns(); j++) {
            TCFbECell* DenominatorOfComparedCell = this->GetCellByIndex(ComparedRowIndex, j);
            TCFbECell* DenominatorOfBaseCell = this->GetCellByIndex(BaseRowIndex, j);

            if (DenominatorOfComparedCell->GetEnabled() && DenominatorOfBaseCell->GetEnabled() && !TCFbEToolkit::GetToolkit()->Equals(DenominatorOfComparedCell->GetValue(), 0.0) && !TCFbEToolkit::GetToolkit()->Equals(DenominatorOfBaseCell->GetValue(), 0.0)) {
                for (int k = 0; k < this->GetNumberOfColumns(); k++) {
                    TCFbECell* NumeratorOfComparedCell = this->GetCellByIndex(ComparedRowIndex, k);
                    TCFbECell* NumeratorOfBaseCell = this->GetCellByIndex(BaseRowIndex, k);

                    if (NumeratorOfComparedCell->GetEnabled() && NumeratorOfBaseCell->GetEnabled() && (j != k)) {
                        Sum += sqrt( pow((NumeratorOfComparedCell->GetValue() / DenominatorOfComparedCell->GetValue()) - (NumeratorOfBaseCell->GetValue() / DenominatorOfBaseCell->GetValue()), 2.0));
                        Count++;
                    }
                }
            }
        }

        if (Sum == 0.0) {
            ((TCFbECell*)this->InversedDistanceOfRowList->Items[ComparedRowIndex])->SetValue(0.0);
        } else {
            ((TCFbECell*)this->InversedDistanceOfRowList->Items[ComparedRowIndex])->SetValue((double)Count / Sum);
        }

        this->CachedBaseRowListForID->Items[ComparedRowIndex] = (void*)BaseRowIndex;
    }

    return ((TCFbECell*)this->InversedDistanceOfRowList->Items[ComparedRowIndex])->GetValue();
}

//---------------------------------------------------------------------------
// ComparedRowIndex 番目の行の BaseRowIndex 番目の行に対する Averaged Multiplier を返す．
double __fastcall TCFbETable::GetAveragedMultiplierOfRow(int BaseRowIndex, int ComparedRowIndex)
{
    double    Sum = 0.0;
    int    Count = 0;

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

        if (ComparedCell->GetEnabled() && BaseCell->GetEnabled() && !TCFbEToolkit::GetToolkit()->Equals(ComparedCell->GetValue(), 0.0)) {
            Sum += fabs(BaseCell->GetValue() / ComparedCell->GetValue());
            Count++;
        }
    }

    if (Count == 0) {
        return 0.0;
    }

    return Sum / Count;
}

//---------------------------------------------------------------------------
// ComparedRowIndex 番目の行の BaseRowIndex 番目の行に対する Median of Multiplier を返す．
double __fastcall TCFbETable::GetMedianOfMultiplierOfRow(int BaseRowIndex, int ComparedRowIndex)
{
    TDoubleDynArray EnabledValues;

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

        if (ComparedCell->GetEnabled() && BaseCell->GetEnabled() && !TCFbEToolkit::GetToolkit()->Equals(ComparedCell->GetValue(), 0)) {
            EnabledValues.Length++;
            EnabledValues[EnabledValues.High] = fabs(BaseCell->GetValue() / ComparedCell->GetValue());
        }
    }

    double ReturnValue = 0.0;
    if (EnabledValues.Length > 0) {
        TCFbEToolkit::GetToolkit()->SortDoubleDynArray(EnabledValues, sdDescending);
        ReturnValue = TCFbEToolkit::GetToolkit()->GetMedianOfDynArray(EnabledValues);
        EnabledValues.Length = 0;
    }

    return ReturnValue;
}

//---------------------------------------------------------------------------
// BaseColumnIndex 番目の列に関する ComparedRowIndex 番目の行の BaseRowIndex 番目の行に対する Weighted Multiplier を返す．
double __fastcall TCFbETable::GetWeightedMultiplierOfRow(int BaseRowIndex, int ComparedRowIndex, int BaseColumnIndex)
{
    double    Numerator = 0.0;
    double    Denominator = 0;

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

        if (ComparedCell->GetEnabled() && BaseCell->GetEnabled() && !TCFbEToolkit::GetToolkit()->Equals(ComparedCell->GetValue(), 0)) {
            double Weight = this->GetInversedDistanceOfColumn(BaseColumnIndex, j);
            Numerator += fabs(BaseCell->GetValue() / ComparedCell->GetValue()) * Weight;
            Denominator += Weight;
        }
    }

    if (Denominator == 0.0) {
        return 0.0;
    }

    return Numerator / Denominator;
}

//---------------------------------------------------------------------------
// 列の最大値を返す．
// 列の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetMaxOfColumn(int j)
{
    TCFbECell* CachedCell = (TCFbECell*)this->MaxOfColumnList->Items[j];

    if (!CachedCell->GetEnabled()) {
        for (int i = 0; i < this->GetNumberOfRows(); i++) {
            TCFbECell* CurrentCell = this->GetCellByIndex(i, j);
            if (CurrentCell->GetEnabled() && (!CachedCell->GetEnabled() || (CurrentCell->GetValue() > CachedCell->GetValue()))) {
                CachedCell->SetValue(CurrentCell->GetValue());
            }
        }

        if (!CachedCell->GetEnabled()) {
            throw Exception("There is no elements in the column (in TCFbETable::GetMaxOfColumn).");
        }
    }

    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// 列の最小値を返す．
// 列の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetMinOfColumn(int j)
{
    TCFbECell* CachedCell = (TCFbECell*)this->MinOfColumnList->Items[j];

    if (!CachedCell->GetEnabled()) {
        for (int i = 0; i < this->GetNumberOfRows(); i++) {
            TCFbECell* CurrentCell = this->GetCellByIndex(i, j);
            if (CurrentCell->GetEnabled() && (!CachedCell->GetEnabled() || (CurrentCell->GetValue() < CachedCell->GetValue()))) {
                CachedCell->SetValue(CurrentCell->GetValue());
            }
        }

        if (!CachedCell->GetEnabled()) {
            throw Exception("There is no elements in the column (in TCFbETable::GetMinOfColumn).");
        }
    }

    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// 列の平均値を返す．
// 列の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetAverageOfColumn(int j)
{
    TCFbECell* CachedCell = (TCFbECell*)this->AverageOfColumnList->Items[j];

    if (!CachedCell->GetEnabled()) {
        int Count = 0;
        double Sum = 0;

        for (int i = 0; i < this->GetNumberOfRows(); i++) {
            TCFbECell* CurrentCell = this->GetCellByIndex(i, j);
            if (CurrentCell->GetEnabled()) {
                Sum += CurrentCell->GetValue();
                Count++;
            }
        }

        if (Count == 0) {
            throw Exception("There is no elements in the column (in TCFbETable::GetAverageOfColumn).");
        }

        CachedCell->SetValue(Sum / Count);
    }

    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// 列の中間値を返す．
// 列の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetMedianOfColumn(int j)
{
    TCFbECell* CachedCell = (TCFbECell*)this->MedianOfColumnList->Items[j];

    if (!CachedCell->GetEnabled()) {
        TDoubleDynArray EnabledValues;
        this->GetEnabledCellsInColumn(j, EnabledValues);

        if (EnabledValues.Length == 0) {
            throw Exception("There is no elements in the column (in TCFbETable::GetMedianOfColumn).");
        }

        TCFbEToolkit::GetToolkit()->SortDoubleDynArray(EnabledValues, sdDescending);
        CachedCell->SetValue(TCFbEToolkit::GetToolkit()->GetMedianOfDynArray(EnabledValues));
        EnabledValues.Length = 0;
    }

    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// 列の標準偏差を返す．
// 列の要素がない場合は例外を送出する．
double __fastcall TCFbETable::GetStdevOfColumn(int j)
{
    TCFbECell* CachedCell = (TCFbECell*)this->StdevOfColumnList->Items[j];

    if (!CachedCell->GetEnabled()) {
        double Average;
        try {
            Average = this->GetAverageOfColumn(j);
        } catch (...) {
            throw Exception("There is no elements in the column (in TCFbETable::GetStdevOfColumn).");
        }

        double    Sum = 0.0;
        int    Count = 0;
        for (int i = 0; i < this->GetNumberOfRows(); i++) {
            TCFbECell* CurrentCell = this->GetCellByIndex(i, j);
            if (CurrentCell->GetEnabled()) {
                Sum += pow(CurrentCell->GetValue() - Average, 2.0);
                Count++;
            }
        }

        CachedCell->SetValue(sqrt(Sum / (double)Count));
    }

    return CachedCell->GetValue();
}

//---------------------------------------------------------------------------
// ComparedColumnIndex 番目の列の BaseColumnIndex 番目の列に対する Inversed Distance を返す．
double __fastcall TCFbETable::GetInversedDistanceOfColumn(int BaseColumnIndex, int ComparedColumnIndex)
{
    if ((int)this->CachedBaseColumnListForID->Items[ComparedColumnIndex] != BaseColumnIndex) {
        double Sum = 0.0;
        int Count = 0;
        for (int i = 0; i < this->GetNumberOfRows(); i++) {
            TCFbECell* DenominatorOfComparedCell = this->GetCellByIndex(i, ComparedColumnIndex);
            TCFbECell* DenominatorOfBaseCell = this->GetCellByIndex(i, BaseColumnIndex);

            if (DenominatorOfComparedCell->GetEnabled() && DenominatorOfBaseCell->GetEnabled() && (DenominatorOfComparedCell->GetValue() != 0.0) && (DenominatorOfBaseCell->GetValue() != 0.0)) {
                for (int k = 0; k < this->GetNumberOfRows(); k++) {
                    TCFbECell* NumeratorOfComparedCell = this->GetCellByIndex(k, ComparedColumnIndex);
                    TCFbECell* NumeratorOfBaseCell = this->GetCellByIndex(k, BaseColumnIndex);

                    if (NumeratorOfComparedCell->GetEnabled() && NumeratorOfBaseCell->GetEnabled() && (i != k)) {
                        Sum += sqrt( pow((NumeratorOfComparedCell->GetValue() / DenominatorOfComparedCell->GetValue()) - (NumeratorOfBaseCell->GetValue() / DenominatorOfBaseCell->GetValue()), 2.0));
                        Count++;
                    }
                }
            }
        }

        if (Sum == 0.0) {
            ((TCFbECell*)this->InversedDistanceOfColumnList->Items[ComparedColumnIndex])->SetValue(0.0);
        } else {
            ((TCFbECell*)this->InversedDistanceOfColumnList->Items[ComparedColumnIndex])->SetValue((double)Count / Sum);
        }

        this->CachedBaseColumnListForID->Items[ComparedColumnIndex] = (void*)BaseColumnIndex;
    }

    return ((TCFbECell*)this->InversedDistanceOfColumnList->Items[ComparedColumnIndex])->GetValue();
}

//---------------------------------------------------------------------------
// ComparedColumnIndex 番目の列の BaseColumnIndex 番目の列に対する Averaged Multiplier を返す．
double __fastcall TCFbETable::GetAveragedMultiplierOfColumn(int BaseColumnIndex, int ComparedColumnIndex)
{
    double    Sum = 0.0;
    int    Count = 0;

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

        if (ComparedCell->GetEnabled() && BaseCell->GetEnabled() && ComparedCell->GetValue() != 0) {
            Sum += fabs(BaseCell->GetValue() / ComparedCell->GetValue());
            Count++;
        }
    }

    if (Count == 0) {
        return 0.0;
    }

    return Sum / Count;
}

//---------------------------------------------------------------------------
// ComparedColumnIndex 番目の列の BaseColumnIndex 番目の列に対する Median of Multiplier を返す．
double __fastcall TCFbETable::GetMedianOfMultiplierOfColumn(int BaseColumnIndex, int ComparedColumnIndex)
{
    TDoubleDynArray EnabledValues;

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

        if (ComparedCell->GetEnabled() && BaseCell->GetEnabled() && ComparedCell->GetValue() != 0) {
            EnabledValues.Length++;
            EnabledValues[EnabledValues.High] = fabs(BaseCell->GetValue() / ComparedCell->GetValue());
        }
    }

    double ReturnValue = 0.0;
    if (EnabledValues.Length > 0) {
        TCFbEToolkit::GetToolkit()->SortDoubleDynArray(EnabledValues, sdDescending);
        ReturnValue = TCFbEToolkit::GetToolkit()->GetMedianOfDynArray(EnabledValues);
        EnabledValues.Length = 0;
    }

    return ReturnValue;
}

//---------------------------------------------------------------------------
// BaseRowIndex 番目の行に関する ComparedColumnIndex 番目の列の BaseColumnIndex 番目の列に対する Weighted Multiplier を返す．
double __fastcall TCFbETable::GetWeightedMultiplierOfColumn(int BaseColumnIndex, int ComparedColumnIndex, int BaseRowIndex)
{
    double    Numerator = 0.0;
    double    Denominator = 0;

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

        if (ComparedCell->GetEnabled() && BaseCell->GetEnabled() && (ComparedCell->GetValue() != 0)) {
            double Weight = this->GetInversedDistanceOfRow(BaseRowIndex, i);
            Numerator += fabs(BaseCell->GetValue() / ComparedCell->GetValue()) * Weight;
            Denominator += Weight;
        }
    }

    if (Denominator == 0.0) {
        return 0.0;
    }

    return Numerator / Denominator;
}

//---------------------------------------------------------------------------
// 以下，protected method
//---------------------------------------------------------------------------
// 行方向のキャッシュを追加する
void __fastcall TCFbETable::AddRowCache(void)
{
    this->MaxOfRowList->Add(new TCFbECell());
    this->MinOfRowList->Add(new TCFbECell());
    this->AverageOfRowList->Add(new TCFbECell());
    this->MedianOfRowList->Add(new TCFbECell());
    this->StdevOfRowList->Add(new TCFbECell());
    this->InversedDistanceOfRowList->Add(new TCFbECell());
    this->CachedBaseRowListForID->Add((void*)-1);
}

//---------------------------------------------------------------------------
// 列方向のキャッシュを追加する
void __fastcall TCFbETable::AddColumnCache(void)
{
    this->MaxOfColumnList->Add(new TCFbECell());
    this->MinOfColumnList->Add(new TCFbECell());
    this->AverageOfColumnList->Add(new TCFbECell());
    this->MedianOfColumnList->Add(new TCFbECell());
    this->StdevOfColumnList->Add(new TCFbECell());
    this->InversedDistanceOfColumnList->Add(new TCFbECell());
    this->CachedBaseColumnListForID->Add((void*)-1);
}

//---------------------------------------------------------------------------
// 行方向のキャッシュを削除する
void __fastcall TCFbETable::DeleteRowCache(int TargetRowIndex)
{
    this->MaxOfRowList->Delete(TargetRowIndex);
    this->MinOfRowList->Delete(TargetRowIndex);
    this->AverageOfRowList->Delete(TargetRowIndex);
    this->MedianOfRowList->Delete(TargetRowIndex);
    this->StdevOfRowList->Delete(TargetRowIndex);
    this->InversedDistanceOfRowList->Delete(TargetRowIndex);
    this->CachedBaseRowListForID->Delete(TargetRowIndex);
}

//---------------------------------------------------------------------------
// 列方向のキャッシュを削除する
void __fastcall TCFbETable::DeleteColumnCache(int TargetColumnIndex)
{
    this->MaxOfColumnList->Delete(TargetColumnIndex);
    this->MinOfColumnList->Delete(TargetColumnIndex);
    this->AverageOfColumnList->Delete(TargetColumnIndex);
    this->MedianOfColumnList->Delete(TargetColumnIndex);
    this->StdevOfColumnList->Delete(TargetColumnIndex);
    this->InversedDistanceOfColumnList->Delete(TargetColumnIndex);
    this->CachedBaseColumnListForID->Delete(TargetColumnIndex);
}

//---------------------------------------------------------------------------
// 行方向のキャッシュをコピーする
void __fastcall TCFbETable::CopyRowCache(TCFbETable* SourceTable, int TargetRowIndex)
{
    ((TCFbECell*)this->MaxOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->MaxOfRowList->Items[TargetRowIndex]);
    ((TCFbECell*)this->MinOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->MinOfRowList->Items[TargetRowIndex]);
    ((TCFbECell*)this->AverageOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->AverageOfRowList->Items[TargetRowIndex]);
    ((TCFbECell*)this->MedianOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->MedianOfRowList->Items[TargetRowIndex]);
    ((TCFbECell*)this->StdevOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->StdevOfRowList->Items[TargetRowIndex]);
    ((TCFbECell*)this->InversedDistanceOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->InversedDistanceOfRowList->Items[TargetRowIndex]);
    this->CachedBaseRowListForID->Items[TargetRowIndex] = (void*)((int)SourceTable->CachedBaseRowListForID->Items[TargetRowIndex]);
}

//---------------------------------------------------------------------------
// 列方向のキャッシュをコピーする
void __fastcall TCFbETable::CopyColumnCache(TCFbETable* SourceTable, int TargetColumnIndex)
{
    ((TCFbECell*)this->MaxOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->MaxOfColumnList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->MinOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->MinOfColumnList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->AverageOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->AverageOfColumnList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->MedianOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->MedianOfColumnList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->StdevOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->StdevOfColumnList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->InversedDistanceOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->InversedDistanceOfColumnList->Items[TargetColumnIndex]);
    this->CachedBaseColumnListForID->Items[TargetColumnIndex] = (void*)((int)SourceTable->CachedBaseColumnListForID->Items[TargetColumnIndex]);
}

//---------------------------------------------------------------------------
// 行方向のキャッシュを列方向のキャッシュからコピーする
void __fastcall TCFbETable::CopyRowCacheFromColumn(TCFbETable* SourceTable, int TargetRowIndex)
{
    ((TCFbECell*)this->MaxOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->MaxOfColumnList->Items[TargetRowIndex]);
    ((TCFbECell*)this->MinOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->MinOfColumnList->Items[TargetRowIndex]);
    ((TCFbECell*)this->AverageOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->AverageOfColumnList->Items[TargetRowIndex]);
    ((TCFbECell*)this->MedianOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->MedianOfColumnList->Items[TargetRowIndex]);
    ((TCFbECell*)this->StdevOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->StdevOfColumnList->Items[TargetRowIndex]);
    ((TCFbECell*)this->InversedDistanceOfRowList->Items[TargetRowIndex])->Assign((TCFbECell*)SourceTable->InversedDistanceOfColumnList->Items[TargetRowIndex]);
    this->CachedBaseRowListForID->Items[TargetRowIndex] = (void*)((int)SourceTable->CachedBaseColumnListForID->Items[TargetRowIndex]);
}

//---------------------------------------------------------------------------
// 列方向のキャッシュを行方向のキャッシュからコピーする
void __fastcall TCFbETable::CopyColumnCacheFromRow(TCFbETable* SourceTable, int TargetColumnIndex)
{
    ((TCFbECell*)this->MaxOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->MaxOfRowList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->MinOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->MinOfRowList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->AverageOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->AverageOfRowList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->MedianOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->MedianOfRowList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->StdevOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->StdevOfRowList->Items[TargetColumnIndex]);
    ((TCFbECell*)this->InversedDistanceOfColumnList->Items[TargetColumnIndex])->Assign((TCFbECell*)SourceTable->InversedDistanceOfRowList->Items[TargetColumnIndex]);
    this->CachedBaseColumnListForID->Items[TargetColumnIndex] = (void*)((int)SourceTable->CachedBaseRowListForID->Items[TargetColumnIndex]);
}

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

