/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.model.finitedifference;
import java.util.Arrays;
import org.apache.commons.lang.Validate;
/**
*
*/
public class PDEFullResults1D implements PDEResults1D {
private final double[][] _f;
private final PDEGrid1D _grid;
private final PDETerminalResults1D _terminalResults;
public PDEFullResults1D(final PDEGrid1D grid, final double[][] fullSolverData) {
Validate.isTrue(grid.getNumTimeNodes() == fullSolverData.length, "time steps in grid not equal to that in data");
Validate.isTrue(grid.getNumSpaceNodes() == fullSolverData[0].length, "space steps in grid not equal to that in data");
_grid = grid;
_f = fullSolverData;
_terminalResults = new PDETerminalResults1D(grid, fullSolverData[grid.getNumTimeNodes() - 1]);
}
@Override
public double getFunctionValue(final int index) {
return _terminalResults.getFunctionValue(index);
}
@Override
public double getSpaceValue(final int spaceIndex) {
return _grid.getSpaceNode(spaceIndex);
}
@Override
public double getFirstSpatialDerivative(final int spaceIndex) {
return _terminalResults.getFirstSpatialDerivative(spaceIndex);
}
public double getFirstSpatialDerivative(final int spaceIndex, final int timeIndex) {
double[] coeff;
double res = 0;
final int n = _grid.getNumSpaceNodes();
int offset;
if (spaceIndex == 0) {
coeff = _grid.getFirstDerivativeForwardCoefficients(spaceIndex);
offset = 0;
} else if (spaceIndex == n - 1) {
coeff = _grid.getFirstDerivativeBackwardCoefficients(spaceIndex);
offset = -coeff.length + 1;
} else {
coeff = _grid.getFirstDerivativeCoefficients(spaceIndex);
offset = -(coeff.length - 1) / 2;
}
for (int i = 0; i < coeff.length; i++) {
res += coeff[i] * _f[timeIndex][spaceIndex + i + offset];
}
return res;
}
@Override
public double getSecondSpatialDerivative(final int spaceIndex) {
return _terminalResults.getSecondSpatialDerivative(spaceIndex);
}
public double getSecondSpatialDerivative(final int spaceIndex, final int timeIndex) {
final double[] coeff = _grid.getSecondDerivativeCoefficients(spaceIndex);
double res = 0;
int offset;
if (spaceIndex == 0) {
offset = 0;
} else if (spaceIndex == _grid.getNumSpaceNodes() - 1) {
offset = -2;
} else {
offset = -1;
}
for (int i = 0; i < coeff.length; i++) {
res += coeff[i] * _f[timeIndex][spaceIndex + i + offset];
}
return res;
}
@Override
public int getNumberSpaceNodes() {
return _grid.getNumSpaceNodes();
}
public double getFunctionValue(final int spaceIndex, final int timeIndex) {
return _f[timeIndex][spaceIndex];
}
public int getNumberTimeNodes() {
return _grid.getNumTimeNodes();
}
public double getTimeValue(final int timeIndex) {
return _grid.getTimeNode(timeIndex);
}
@Override
public PDEGrid1D getGrid() {
return _grid;
}
public double[][] getF() {
return _f;
}
public PDEFullResults1D withGrid(final PDEGrid1D grid) {
return new PDEFullResults1D(grid, _f);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(_f);
result = prime * result + ((_grid == null) ? 0 : _grid.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PDEFullResults1D other = (PDEFullResults1D) obj;
if (!Arrays.equals(_f, other._f)) {
return false;
}
if (_grid == null) {
if (other._grid != null) {
return false;
}
} else if (!_grid.equals(other._grid)) {
return false;
}
return true;
}
@Override
public double[] getTerminalResults() {
return _terminalResults.getTerminalResults();
}
}