Skip to content

Commit

Permalink
Now computes mean or median on union domain. Closes #7.
Browse files Browse the repository at this point in the history
  • Loading branch information
astamm committed Jul 4, 2023
1 parent 5cfb780 commit 3e659f9
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 24 deletions.
84 changes: 69 additions & 15 deletions src/meanCenterClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ CenterType MeanCenterMethod::GetCenter(const arma::mat& inputGrid,
Rcpp::stop("The number of columns in x should match the third dimension of y.");

// Find intersection grid
double gridLowerBound = inputGrid.col(0).max();
double gridUpperBound = inputGrid.col(numberOfPoints - 1).min();
arma::rowvec outGrid = arma::linspace<arma::rowvec>(gridLowerBound, gridUpperBound, numberOfPoints);
// double gridLowerBound = inputGrid.col(0).max();
// double gridUpperBound = inputGrid.col(numberOfPoints - 1).min();
// arma::rowvec outGrid = arma::linspace<arma::rowvec>(gridLowerBound, gridUpperBound, numberOfPoints);

arma::uvec finiteIndices;
arma::mat meanValue(numberOfDimensions, numberOfPoints, arma::fill::zeros);
arma::mat workMatrix;
// Define union grid
double unionLowerBound = inputGrid.min();
double unionUpperBound = inputGrid.max();
arma::rowvec outGrid = arma::linspace<arma::rowvec>(unionLowerBound, unionUpperBound, numberOfPoints);

arma::uvec finiteIndices, nonFiniteIndices;
arma::mat centroidValue(numberOfDimensions, numberOfPoints, arma::fill::zeros);
arma::mat workMatrix(numberOfObservations, numberOfDimensions);
arma::cube yIn(numberOfObservations, numberOfDimensions, numberOfPoints);

// First interpolate to common grid
Expand All @@ -44,28 +49,77 @@ CenterType MeanCenterMethod::GetCenter(const arma::mat& inputGrid,
}

// Next, compute point-wise mean
arma::uvec numberOfMissingPoints(numberOfPoints);
for (unsigned int i = 0;i < numberOfPoints;++i)
{
finiteIndices = arma::find_finite(yIn.slice(i).col(0));
numberOfMissingPoints(i) = numberOfObservations - finiteIndices.size();
workMatrix = yIn.slice(i).rows(finiteIndices);
meanValue.col(i) = arma::mean(workMatrix, 0).as_col();
centroidValue.col(i) = arma::mean(workMatrix, 0).as_col();
}

// Next, compute point-wise median
int halfPoint = (int)(numberOfPoints / 2);
arma::rowvec localSlopeValues, localInterceptValues, localPredictedValues;
arma::rowvec shiftValues;

for (int i = halfPoint;i < numberOfPoints;++i)
{
nonFiniteIndices = arma::find_nonfinite(yIn.slice(i).col(0));
for (unsigned int j = 0;j < nonFiniteIndices.size();++j)
{
unsigned int rowIndex = nonFiniteIndices(j);
localSlopeValues = (yIn.slice(i - 1).row(rowIndex) - yIn.slice(i - 2).row(rowIndex)) / (outGrid(i - 1) - outGrid(i - 2));
localInterceptValues = yIn.slice(i - 2).row(rowIndex) - localSlopeValues * outGrid(i - 2);
localPredictedValues = localInterceptValues + localSlopeValues * outGrid(i);
shiftValues = localPredictedValues - centroidValue.col(i).as_row();
for (int k = i;k < numberOfPoints;++k)
{
if (k > i && numberOfMissingPoints(k) != numberOfMissingPoints(k - 1))
break;
yIn.slice(k).row(rowIndex) = centroidValue.col(k).as_row() + shiftValues;
}
}

centroidValue.col(i) = arma::mean(yIn.slice(i), 0).as_col();
}

for (int i = halfPoint - 1;i >= 0;--i)
{
nonFiniteIndices = arma::find_nonfinite(yIn.slice(i).col(0));
for (unsigned int j = 0;j < nonFiniteIndices.size();++j)
{
unsigned int rowIndex = nonFiniteIndices(j);
localSlopeValues = (yIn.slice(i + 1).row(rowIndex) - yIn.slice(i + 2).row(rowIndex)) / (outGrid(i + 1) - outGrid(i + 2));
localInterceptValues = yIn.slice(i + 2).row(rowIndex) - localSlopeValues * outGrid(i + 2);
localPredictedValues = localInterceptValues + localSlopeValues * outGrid(i);
shiftValues = localPredictedValues - centroidValue.col(i).as_row();
for (int k = i;k >= 0;--k)
{
if (k < i && numberOfMissingPoints(k) != numberOfMissingPoints(k + 1))
break;
yIn.slice(k).row(rowIndex) = centroidValue.col(k).as_row() + shiftValues;
}
}

centroidValue.col(i) = arma::mean(yIn.slice(i), 0).as_col();
}

// Finally, compute dissimilarity between observations and center
arma::rowvec distancesToCenter(numberOfObservations);
for (unsigned int i = 0;i < numberOfObservations;++i)
{
workMatrix = inputValues.row(i);
distancesToCenter(i) = dissimilarityPointer->GetDistance(
outGrid,
inputGrid.row(i),
meanValue,
workMatrix
);
workMatrix = inputValues.row(i);
distancesToCenter(i) = dissimilarityPointer->GetDistance(
outGrid,
inputGrid.row(i),
centroidValue,
workMatrix
);
}

outputCenter.centerGrid = outGrid;
outputCenter.centerValues = meanValue;
outputCenter.centerValues = centroidValue;
outputCenter.distancesToCenter = distancesToCenter;

return outputCenter;
Expand Down
72 changes: 63 additions & 9 deletions src/medianCenterClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ CenterType MedianCenterMethod::GetCenter(const arma::mat& inputGrid,
Rcpp::stop("The number of columns in x should match the third dimension of y.");

// Find intersection grid
double gridLowerBound = inputGrid.col(0).max();
double gridUpperBound = inputGrid.col(numberOfPoints - 1).min();
arma::rowvec outGrid = arma::linspace<arma::rowvec>(gridLowerBound, gridUpperBound, numberOfPoints);
// double gridLowerBound = inputGrid.col(0).max();
// double gridUpperBound = inputGrid.col(numberOfPoints - 1).min();
// arma::rowvec outGrid = arma::linspace<arma::rowvec>(gridLowerBound, gridUpperBound, numberOfPoints);

arma::uvec finiteIndices;
arma::mat medianValue(numberOfDimensions, numberOfPoints, arma::fill::zeros);
arma::mat workMatrix;
// Define union grid
double unionLowerBound = inputGrid.min();
double unionUpperBound = inputGrid.max();
arma::rowvec outGrid = arma::linspace<arma::rowvec>(unionLowerBound, unionUpperBound, numberOfPoints);

arma::uvec finiteIndices, nonFiniteIndices;
arma::mat centroidValue(numberOfDimensions, numberOfPoints, arma::fill::zeros);
arma::mat workMatrix(numberOfObservations, numberOfDimensions);
arma::cube yIn(numberOfObservations, numberOfDimensions, numberOfPoints);

// First interpolate to common grid
Expand All @@ -44,11 +49,60 @@ CenterType MedianCenterMethod::GetCenter(const arma::mat& inputGrid,
}

// Next, compute point-wise mean
arma::uvec numberOfMissingPoints(numberOfPoints);
for (unsigned int i = 0;i < numberOfPoints;++i)
{
finiteIndices = arma::find_finite(yIn.slice(i).col(0));
numberOfMissingPoints(i) = numberOfObservations - finiteIndices.size();
workMatrix = yIn.slice(i).rows(finiteIndices);
medianValue.col(i) = arma::median(workMatrix, 0).as_col();
centroidValue.col(i) = arma::median(workMatrix, 0).as_col();
}

// Next, compute point-wise median
int halfPoint = (int)(numberOfPoints / 2);
arma::rowvec localSlopeValues, localInterceptValues, localPredictedValues;
arma::rowvec shiftValues;

for (int i = halfPoint;i < numberOfPoints;++i)
{
nonFiniteIndices = arma::find_nonfinite(yIn.slice(i).col(0));
for (unsigned int j = 0;j < nonFiniteIndices.size();++j)
{
unsigned int rowIndex = nonFiniteIndices(j);
localSlopeValues = (yIn.slice(i - 1).row(rowIndex) - yIn.slice(i - 2).row(rowIndex)) / (outGrid(i - 1) - outGrid(i - 2));
localInterceptValues = yIn.slice(i - 2).row(rowIndex) - localSlopeValues * outGrid(i - 2);
localPredictedValues = localInterceptValues + localSlopeValues * outGrid(i);
shiftValues = localPredictedValues - centroidValue.col(i).as_row();
for (int k = i;k < numberOfPoints;++k)
{
if (k > i && numberOfMissingPoints(k) != numberOfMissingPoints(k - 1))
break;
yIn.slice(k).row(rowIndex) = centroidValue.col(k).as_row() + shiftValues;
}
}

centroidValue.col(i) = arma::median(yIn.slice(i), 0).as_col();
}

for (int i = halfPoint - 1;i >= 0;--i)
{
nonFiniteIndices = arma::find_nonfinite(yIn.slice(i).col(0));
for (unsigned int j = 0;j < nonFiniteIndices.size();++j)
{
unsigned int rowIndex = nonFiniteIndices(j);
localSlopeValues = (yIn.slice(i + 1).row(rowIndex) - yIn.slice(i + 2).row(rowIndex)) / (outGrid(i + 1) - outGrid(i + 2));
localInterceptValues = yIn.slice(i + 2).row(rowIndex) - localSlopeValues * outGrid(i + 2);
localPredictedValues = localInterceptValues + localSlopeValues * outGrid(i);
shiftValues = localPredictedValues - centroidValue.col(i).as_row();
for (int k = i;k >= 0;--k)
{
if (k < i && numberOfMissingPoints(k) != numberOfMissingPoints(k + 1))
break;
yIn.slice(k).row(rowIndex) = centroidValue.col(k).as_row() + shiftValues;
}
}

centroidValue.col(i) = arma::median(yIn.slice(i), 0).as_col();
}

// Finally, compute dissimilarity between observations and center
Expand All @@ -59,13 +113,13 @@ CenterType MedianCenterMethod::GetCenter(const arma::mat& inputGrid,
distancesToCenter(i) = dissimilarityPointer->GetDistance(
outGrid,
inputGrid.row(i),
medianValue,
centroidValue,
workMatrix
);
}

outputCenter.centerGrid = outGrid;
outputCenter.centerValues = medianValue;
outputCenter.centerValues = centroidValue;
outputCenter.distancesToCenter = distancesToCenter;

return outputCenter;
Expand Down

0 comments on commit 3e659f9

Please sign in to comment.