Derivative.java
package edu.udel.cis.vsl.tass.model.impl;
import java.util.Arrays;
import edu.udel.cis.vsl.tass.model.IF.AbstractFunctionIF;
import edu.udel.cis.vsl.tass.model.IF.ContinuityException;
import edu.udel.cis.vsl.tass.model.IF.DerivativeIF;
import edu.udel.cis.vsl.tass.model.IF.SyntaxException;
import edu.udel.cis.vsl.tass.model.IF.scope.ScopeIF;
import edu.udel.cis.vsl.tass.model.IF.variable.FormalVariableIF;
/**
* Clairaut's theorem states that if a function from R^n->R has continuous
* second partial derivatives at any given point, then any pair of partial
* derivatives commute at that point. By induction, this means that any n
* partial derivatives will commute if the function has continuous nth partial
* derivatives at that point.
*
* Our assumption is that at any point the function is differentiable up to the
* continuity value in any variable.
*
* For now, we will apply Clairut's theorem to any parameter/return types.
* Later, we can either prove this is correct or restrict as necessary.
*/
public class Derivative extends AbstractFunction implements DerivativeIF {
private int orders[];
private AbstractFunctionIF function;
public Derivative(ScopeIF containingScope, String name,
AbstractFunctionIF function, int[] orders) throws SyntaxException {
super(containingScope, name, function.returnType(), function
.numFormals());
this.orders = orders;
/*
* Check if this is the derivative of a derivative. If it is, "flatten"
* it so that it is a single derivative with the orders added point-wise
* and the base function used as the function.
*/
if (function instanceof DerivativeIF) {
this.function = ((DerivativeIF) function).function();
for (int i = 0; i < orders.length; i++) {
orders[i] += ((Derivative) function).orders()[i];
}
} else {
this.function = function;
}
int c = 0;
for (int i = 0; i < orders.length; i++) {
c += orders[i];
}
if (c > function.continuity()) {
throw new ContinuityException(
this,
"The continuity of the function "
+ function
+ " is insufficient to assure that the derivative is valid.");
}
setContinuity(function.continuity() - c);
}
public int[] orders() {
return orders;
}
public AbstractFunctionIF function() {
return function;
}
public int orderForVariable(FormalVariableIF variable) {
return orders[variable.index()];
}
public String toString() {
String result = "\\D[" + name;
for (int i = 0; i < orders.length; i++) {
result += ",{" + function.formal(i).name() + "," + orders[i] + "}";
}
result += "]";
return result;
}
public int hashCode() {
int result = function.hashCode();
for (int order : orders)
result += order;
return result;
}
public boolean equals(Object object) {
if (object instanceof Derivative) {
Derivative that = (Derivative) object;
return function.equals(that.function)
&& Arrays.equals(orders, that.orders);
}
return false;
}
}