// import java.util.HashMap; // I downloaded this file from http://commons.apache.org/math/download_math.cgi and placed the .jar and other files // in this project. I then did File > Project Structure and added the jar using the + button below the list. import org.apache.commons.math3.distribution.*; //import org.apache.commons.math3.*; //import org.apache.commons.math3.distribution.AbstractRealDistribution.*; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Scanner; /** * Created with IntelliJ IDEA. * User: rebeccamancy * Date: 26/10/2012 * Time: 12:22 * To change this template use File | Settings | File Templates. */ public class LandscapeHabitat extends Habitat { private double[] K; // carrying capacity of patches (or area) private Point[] space; // sets the min and max points of the rectangle describing the space private Point[] patchLocs; // array of patch locations as Points private double[][] distances; // distances (should be int[][] in discrete space) /** * Constructor forms new LandscapeHabitat on the basis of parameters from configuration file * @param numPatches total number of patches to include topology */ public LandscapeHabitat(int numPatches, Point[] space, String kInit, double scale, double shape) { super(numPatches); this.space = space; this.K = new double[numPatches]; this.patchLocs = new Point[super.getNumPatches()]; this.distances = new double[super.getNumPatches()][super.getNumPatches()]; // Position each patch randomly in space and set patch capacities (areas) for (int patch = 0; patch < super.getNumPatches(); patch ++) { this.patchLocs[patch] = new Point(this.space[0], this.space[1]); // if args two Points, generates a random Point setK(patch, this.genK(kInit, scale, shape)); } // Work out distances between patches and put into 2-d array distances setDistances(super.getNumPatches()); } /** * Constructor forms new LandscapeHabitat on the basis of a file name from which reading in takes place * @param filename filename to read in from ... todo this needs numPatches!!! */ public LandscapeHabitat(String filename, int numPatches) { super(numPatches); this.K = new double[numPatches]; this.patchLocs = new Point[super.getNumPatches()]; this.distances = new double[super.getNumPatches()][super.getNumPatches()]; Scanner scanner; try { scanner = new Scanner(new File(filename)); scanner.useDelimiter(",|\\n"); // delimiters in the csv file are new lines and commas int counter = 0; int patch = -1; double curr; // holds the next thing that's read in double x = 0, y = 0; while(scanner.hasNext()){ curr = Double.parseDouble(scanner.next()); if (counter%3 == 0) { // first number is the x-coord patch = patch + 1; x = curr; } else if (counter%3 == 1) { // second number is the y-coord y = curr; } else if (counter%3 == 2) { this.patchLocs[patch] = new Point(x, y); // make an x-y point setK(patch, curr); // third number is the patch area or K } counter = counter + 1; // increment loop counter ... } scanner.close(); } catch (FileNotFoundException ex) { ex.printStackTrace(); System.exit(1); } // Work out distances between patches and put into 2-d array distances setDistances(super.getNumPatches()); } /** * Constructor forms a new LandscapeHabitat from an existing habitat, an intervention type and parameters * @param existHab an existing LandscapeHabitat * @param intervType a type of intervention (e.g. remove patch) * @param intervParams parameters required for the intervention */ public LandscapeHabitat(LandscapeHabitat existHab, int intervType, int[] intervParams) { super(existHab.getNumPatches()); // do this to start with by default - may be changed by intervention if (intervType == Interv.REMOVE_PATCH) { int newNumPatches = existHab.getNumPatches() - 1; super.setNumPatches(newNumPatches); int patchToRemove = intervParams[0]; this.K = Util.subArray(existHab.getK(), patchToRemove); this.patchLocs = Util.subArray(existHab.getPatchLocs(), patchToRemove); this.distances = new double[newNumPatches][newNumPatches]; // Work out distances between patches and put into 2-d array distances setDistances(newNumPatches); } } /** * Constructor forms a new LandscapeHabitat from an existing habitat, an intervention type and parameters * @param existHab an existing LandscapeHabitat * @param patchToRemove patch to remove */ public LandscapeHabitat(LandscapeHabitat existHab, int patchToRemove) { super(existHab.getNumPatches()); // do this to start with by default - may be changed by intervention int newNumPatches = existHab.getNumPatches() - 1; super.setNumPatches(newNumPatches); this.K = Util.subArray(existHab.getK(), patchToRemove); this.patchLocs = Util.subArray(existHab.getPatchLocs(), patchToRemove); this.distances = new double[newNumPatches][newNumPatches]; // Work out distances between patches and put into 2-d array distances setDistances(newNumPatches); } /** * Returns a Point containing the coordinates of the given patch * @param patchID patch identifier * @return Point corresponding to centre of patch */ public Point getPatchLoc (int patchID) { return patchLocs[patchID]; } /** * Returns the list of Points containing the coordinates of all patches in the LandscapeHabitat * @return array of Points for all patches in the LandscapeHabitat */ public Point[] getPatchLocs () { return patchLocs; } /** * Draws a single K from a given distribution, or sets all to K=1.0 * @param kInit functional form of the distrubtion of K * @param scale parameter of the distribution * @param shape parameter of the distribution * @return carrying capacity for a single patch */ public double genK (String kInit, Double scale, Double shape) { if (kInit.equals("logNormal")) { // http://commons.apache.org/math/apidocs/org/apache/commons/math3/distribution/LogNormalDistribution.html LogNormalDistribution distrib = new LogNormalDistribution(scale, shape); return distrib.sample(); } else if (kInit.equals("same")) { return 1.0; } return 1.0; } public double getK(int patchID) { return this.K[patchID]; } public double[] getK() { return this.K; } public void setK(int patchID, double carryCap) { K[patchID] = carryCap; } public void setDist(int focPatch, int othPatch, double dist) { this.distances[focPatch][othPatch] = dist; } public void setDistances(int numPatches) { for (int focPatch = 0; focPatch < numPatches; focPatch ++ ){ for (int othPatch = 0; othPatch < numPatches; othPatch ++ ){ this.distances[focPatch][othPatch] = Point.dist(patchLocs[focPatch], patchLocs[othPatch]); } } } public double lookupDist(int focPatch, int othPatch ) { return this.distances[focPatch][othPatch]; } /** * Print out distances matrix to System.out (for debugging purposes) */ public void printDists() { System.out.println("numPatches" + super.getNumPatches() ); for (int i = 0; i < super.getNumPatches(); i++) { for (int j = 0; j < super.getNumPatches(); j++) { System.out.print("["+ i + "," + j + "]" + distances[i][j] + " "); } System.out.println(); } System.out.println(); } public void printLocs() { for (int i = 0; i < super.getNumPatches(); i++) { System.err.print("[" +this.patchLocs[i].getX()+"," + this.patchLocs[i].getY()+"]"); } //System.err.println(); } public String toString() { String returnString = ""; for (int i = 0; i < patchLocs.length; i++) { returnString += patchLocs[i].toString() + ", " + K[i] + " \n"; } return returnString; } }