/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package systole.math;
import java.math.BigDecimal;
import systole.domain.signals.FinalSignal;
import systole.domain.signals.Segment;
/**
*
* @author user
*/
public class DividedDifferences implements Derivative {
public FinalSignal derivate(Segment f) {
FinalSignal derivatives = new FinalSignal();
derivatives.setFinalSegment(f);
derivatives.setFirstDerivatite(this.getFirstDerivative(f));
derivatives.setSecondDerivative(this.getSecondDerivative(f));
derivatives.setThirdDerivative(this.getThirdDerivative(f));
derivatives.setFourthDerivative(this.getFourthDerivative(f));
return derivatives;
}
public Segment getFirstDerivative(Segment segment) {
int nPoints = segment.size();
int h = 1; //h interval taken
int step = 1;
BigDecimal diff = BigDecimal.ZERO;
Segment derivated = new Segment();
//f'(x) = f(x+h) - f(x-h)/h ; En este caso, h = 1
for (int j = 0; j < nPoints - 2; j++) {
diff = (segment.elementAt(j + h).subtract(segment.elementAt(j))).divide(new BigDecimal(2 * h),MathUtils.CONTEXT);
derivated.add(diff);
}
diff = derivated.elementAt(1).subtract(derivated.firstElement());
derivated.insertElementAt(derivated.firstElement().subtract(diff), 0);
return derivated;
}
public Segment getSecondDerivative(Segment segment) {
int nPoints = segment.size();
BigDecimal h = BigDecimal.ONE; //h interval taken
BigDecimal diff = BigDecimal.ZERO;
int step = 2;
BigDecimal two = new BigDecimal(2);
Segment derivated = new Segment();
for (int j = 0; j < (nPoints - 3); j++) {
//f''(x) = (f(x+2) - 2f(x+1) + f(x))/h^2 ; En este caso, h = 1
diff = (segment.elementAt(j + 2).subtract(two.multiply(segment.elementAt(j + 1))).add(segment.elementAt(j).divide(h.pow(step),MathUtils.CONTEXT)));
derivated.add(diff);
}
diff = derivated.elementAt(1).subtract(derivated.firstElement());
derivated.insertElementAt(derivated.firstElement().subtract(diff), 0);
return derivated;
}
public Segment getThirdDerivative(Segment segment) {
int nPoints = segment.size();
BigDecimal h = BigDecimal.ONE; //h interval taken
int step = 3;
BigDecimal three = new BigDecimal(3);
BigDecimal diff = BigDecimal.ZERO;
Segment derivated = new Segment();
//f'''(x) = (f(x+3) - 3f(x+2) + 3f(x+1) -f(x))/h^3 ; En este caso, h = 1
for (int j = 0; j < (nPoints - 3); j++) {
diff = ((segment.elementAt(j + 3)).subtract(three.multiply(segment.elementAt(j + 2))).
add(three.multiply(segment.elementAt(j + 1))).
subtract(segment.elementAt(j))).divide(h.pow(step),MathUtils.CONTEXT);
derivated.add(diff);
}
diff = derivated.elementAt(1).subtract(derivated.firstElement());
derivated.insertElementAt(derivated.firstElement().subtract(diff), 0);
derivated.insertElementAt(derivated.firstElement().subtract(diff), 0);
return derivated;
}
public Segment getFourthDerivative(Segment segment) {
int nPoints = segment.size();
BigDecimal h = BigDecimal.ONE; //h interval taken
int step = 4;
BigDecimal four = new BigDecimal(4);
BigDecimal six = new BigDecimal(6);
BigDecimal diff = BigDecimal.ZERO;
Segment derivated = new Segment();
//f'''(x) = (f(x+4) - 4f(x+3) + 6f(x+2) -4f(x+1) + f(x))/h^3 ; En este caso, h = 1
for (int j = 0; j < (nPoints - 4); j++) {
diff = ((segment.elementAt(j + 4)).subtract(
(four.multiply(segment.elementAt(j + 3)))).add(
(six.multiply(segment.elementAt(j + 2)))).subtract(
(four.multiply(segment.elementAt(j + 1)))).add(
(segment.elementAt(j)))).divide(h.pow(step),MathUtils.CONTEXT);
derivated.add(diff);
}
diff = derivated.elementAt(1).subtract(derivated.firstElement());
derivated.insertElementAt(derivated.firstElement().subtract(diff), 0);
derivated.insertElementAt(derivated.firstElement().subtract(diff), 0);
derivated.insertElementAt(derivated.firstElement().subtract(diff), 0);
return derivated;
}
}