public void test() { final ConvectionDiffusionPDESolver solver = new ThetaMethodFiniteDifference(0.5, false); final int tNodes = 20; final int xNodes = 101; final PDEGrid1D grid = new PDEGrid1D(tNodes, xNodes, T, LOWER.getLevel(), UPPER.getLevel()); final PDEResults1D res = solver.solve(DATA, grid, LOWER, UPPER); final int i = (int) (xNodes * SPOT / UPPER.getLevel()); final double spot = res.getSpaceValue(i); final double price = res.getFunctionValue(i); final double df = YIELD_CURVE.getDiscountFactor(T); assertEquals(SPOT, spot, 1e-9); assertEquals(SABR_PRICE_SURFACE.getPrice(T, STRIKE), price, price * 2e-3); final BlackFunctionData data = new BlackFunctionData(spot / df, df, 0.0); double impVol; try { impVol = BLACK_IMPLIED_VOL.getImpliedVolatility(data, OPTION, price); } catch (final Exception e) { impVol = 0.0; } assertEquals(SABR_VOL_SURFACE.getVolatility(T, STRIKE), impVol, 1e-3); }
public static BoundaryCondition forName(String name) { for (BoundaryCondition bc : BoundaryCondition.values()) { if (bc.name.equals(name)) { return bc; } } return null; }
/** * Sets a thermal boundary condition for an edge of the polygon. * * @param edgeId The ID of the edge that will have the new BoundaryCondition. * @param condition The new BoundaryCondition. */ public void setThermalBoundaryCondition(int edgeId, BoundaryCondition condition) { // First, check that the edgeId is valid by performing a map lookup. EdgeProperties properties = edgeProperties.get(edgeId); if (condition != null && properties != null) { // If the edgeId is valid, try to set the new condition. If the new // condition is set, we need to register with the new condition and // notify listeners of the change. BoundaryCondition oldCondition = properties.getThermalBoundaryCondition(); if (properties.setThermalBoundaryCondition(condition)) { // Unregister from the old condition and register with the new. oldCondition.unregister(this); condition.register(this); // Notify listeners of the change. notifyListeners(); } } return; }
/** * Sets a passive scalar boundary condition for an edge of the polygon. * * @param edgeId The ID of the edge that will have the new BoundaryCondition. * @param otherId The ID or index of the set of passive scalar boundary conditions. * @param condition The new BoundaryCondition. */ public void setOtherBoundaryCondition(int edgeId, int otherId, BoundaryCondition condition) { // First, check that the edgeId is valid by performing a map lookup. EdgeProperties properties = edgeProperties.get(edgeId); if (condition != null && properties != null) { // If the edgeId is valid, try to set the new condition. If the new // condition is set, we need to register with the new condition and // notify listeners of the change. BoundaryCondition oldCondition = properties.getOtherBoundaryCondition(otherId); if (properties.setOtherBoundaryCondition(otherId, condition)) { // Unregister from the old condition and register with the new. // We need a null check because the scalar index ID may be new. if (oldCondition != null) { oldCondition.unregister(this); } condition.register(this); // Notify listeners of the change. notifyListeners(); } } return; }
/** * The default constructor. * * @param edges * <p>A collection of edges connecting a collection of vertices. * @param vertices * <p>A collection of vertices connected by a collection of edges. */ public Polygon(ArrayList<Edge> edges, ArrayList<Vertex> vertices) { // Initialize the defaults. this(); // A Polygon has the following requirements: // Edge i must have as its start and end points vertices i and i+1. // (for the last edge, these are vertices i and 0). // The Vertex references stored in the Edge should be the same as stored // in the Polygon's list of vertices. // This does not check for simple/complex polygons, only that the outer // edges form a cycle. // Check the parameters for null values. if (vertices == null || vertices.contains(null) || vertices.size() < 3) { throw new IllegalArgumentException( "Polygon error: The vertex list must be a non-null list with at least 3 vertices."); } else if (edges == null || edges.contains(null) || edges.size() < 3) { throw new IllegalArgumentException( "Polygon error: The edge list must be a non-null list with at least 3 edges."); } // Get the sizes of the two lists. int size = vertices.size(); // Use a Set of vertex IDs to make sure no vertex connects more than two // edges. TreeSet<Integer> vertexIds = new TreeSet<Integer>(); TreeSet<Integer> edgeIds = new TreeSet<Integer>(); // Make sure the edges form a cycle. for (int i = 0, j = 1; i < size; i++, j = (i + 1) % size) { int v1 = vertices.get(i).getId(); int v2 = vertices.get(j).getId(); int[] ids = edges.get(i).getVertexIds(); // Add the current vertex ID to the Set. vertexIds.add(v1); // Make sure the two adjacent vertex IDs are not the same. if (v1 == v2) { throw new IllegalArgumentException("Polygon error: Same ID for adjacent vertices."); } // Make sure the IDs v1 and v2 are both in the edge's vertex ID // list. else if ((v1 != ids[0] && v1 != ids[1]) || (v2 != ids[0] && v2 != ids[1])) { throw new IllegalArgumentException("Polygon error: Edge " + i + " uses unknown vertex."); } edgeIds.add(edges.get(i).getId()); } // Check the size of the Set of vertex IDs. Every ID should be unique! if (vertexIds.size() < size) { throw new IllegalArgumentException("Polygon error: A vertex connects more than two edges."); } else if (edgeIds.size() < size) { throw new IllegalArgumentException("Polygon error: Same edge ID used more than once."); } // If the vertices/edges supplied are valid, duplicate them. We also // must ensure the edges are registered with the correct vertex // instances. for (int i = 0; i < size; i++) { // Get the edge from the supplied list. Edge edge = edges.get(i); // Get the new start and end vertices for this edge. Vertex start = vertices.get(i); Vertex end = vertices.get((i + 1) % size); // Register the clone with the start and end. start.register(edge); end.register(edge); // Send the start and end vertices to the clone. edge.update(start); edge.update(end); // Add the edge and vertex to the Polygon's lists. this.edges.add(edge); this.vertices.add(start); // Create an entry for the edge in the map of edge properties. EdgeProperties properties = new EdgeProperties(); edgeProperties.put(edge.getId(), properties); // Register with all of the boundary conditions in the properties. properties.getFluidBoundaryCondition().register(this); properties.getThermalBoundaryCondition().register(this); for (BoundaryCondition condition : properties.getOtherBoundaryConditions()) { condition.register(this); } } return; }
/** * This operation copies the contents of a Polygon into the current object using a deep copy. * * @param polygon * <p>The Object from which the values should be copied. */ public void copy(Polygon polygon) { // Check the parameters. if (polygon == null) { return; } // Copy the super's data. super.copy(polygon); // Deep copy the vertices. vertices.clear(); for (Vertex vertex : polygon.getVertices()) { vertices.add((Vertex) vertex.clone()); } // Deep copy the edges. edges.clear(); ArrayList<Edge> otherEdges = polygon.getEdges(); int size = otherEdges.size(); for (int i = 0; i < size; i++) { // Clone the edge. This deep copies the other edge's vertices, so we // must hook the clone up to our vertex instances. Edge clone = (Edge) otherEdges.get(i).clone(); // Add the clone to the list of edges. edges.add(clone); // Get the new start and end vertices for this edge. Vertex start = vertices.get(i); Vertex end = vertices.get((i + 1) % size); // Register the clone with the start and end. start.register(clone); end.register(clone); // Send the start and end vertices to the clone. clone.update(start); clone.update(end); } /* ---- Deep copy the edge properties. ---- */ // Unregister from any of the current boundary conditions. for (Entry<Integer, EdgeProperties> entry : edgeProperties.entrySet()) { EdgeProperties properties = entry.getValue(); // Unregister from the fluid and thermal boundary conditions. properties.getFluidBoundaryCondition().unregister(this); properties.getThermalBoundaryCondition().unregister(this); // Unregister from all passive scalar boundary conditions. for (BoundaryCondition condition : properties.getOtherBoundaryConditions()) { condition.unregister(this); } } // Clone all of the edge properties from the other polygon and register // with their boundary conditions. for (Entry<Integer, EdgeProperties> entry : polygon.edgeProperties.entrySet()) { // Clone and add the edge's properties. EdgeProperties properties = (EdgeProperties) entry.getValue().clone(); edgeProperties.put(entry.getKey(), properties); // Unregister from the fluid and thermal boundary conditions. properties.getFluidBoundaryCondition().register(this); properties.getThermalBoundaryCondition().register(this); // Unregister from all passive scalar boundary conditions. for (BoundaryCondition condition : properties.getOtherBoundaryConditions()) { condition.register(this); } } /* ---------------------------------------- */ // Copy the PolygonProperties polygonProperties = (PolygonProperties) polygon.getPolygonProperties().clone(); return; }