Commit a5837706 authored by Nikolay's avatar Nikolay

* Removed the dependency on the flanagan library. It is now replaced with Apache Math.

* The minimal time between events is now configurable
parent 60e69f4a
#!/bin/sh
wget http://www.ee.ucl.ac.uk/~mflanaga/java/flanagan.jar
mvn install:install-file -DgroupId=org.flanagan -DartifactId=flanagan -Dversion=1.0 -Dfile=flanagan.jar -Dpackaging=jar -DgeneratePom=true
rm flanagan.jar
......@@ -12,6 +12,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.core.CloudSim;
/**
* CloudletSchedulerDynamicWorkload implements a policy of scheduling performed by a virtual machine
* assuming that there is just one cloudlet which is working as an online service.
......@@ -81,8 +83,8 @@ public class CloudletSchedulerDynamicWorkload extends CloudletSchedulerTimeShare
continue;
} else { // not finish: estimate the finish time
double estimatedFinishTime = getEstimatedFinishTime(rcl, currentTime);
if (estimatedFinishTime - currentTime < 0.1) {
estimatedFinishTime = currentTime + 0.1;
if (estimatedFinishTime - currentTime < CloudSim.getMinTimeBetweenEvents()) {
estimatedFinishTime = currentTime + CloudSim.getMinTimeBetweenEvents();
}
if (estimatedFinishTime < nextEvent) {
nextEvent = estimatedFinishTime;
......
......@@ -136,8 +136,8 @@ public class CloudletSchedulerSpaceShared extends CloudletScheduler {
for (ResCloudlet rcl : getCloudletExecList()) {
double remainingLength = rcl.getRemainingCloudletLength();
double estimatedFinishTime = currentTime + (remainingLength / (capacity * rcl.getNumberOfPes()));
if (estimatedFinishTime - currentTime < 0.1) {
estimatedFinishTime = currentTime + 0.1;
if (estimatedFinishTime - currentTime < CloudSim.getMinTimeBetweenEvents()) {
estimatedFinishTime = currentTime + CloudSim.getMinTimeBetweenEvents();
}
if (estimatedFinishTime < nextEvent) {
nextEvent = estimatedFinishTime;
......
......@@ -90,8 +90,8 @@ public class CloudletSchedulerTimeShared extends CloudletScheduler {
for (ResCloudlet rcl : getCloudletExecList()) {
double estimatedFinishTime = currentTime
+ (rcl.getRemainingCloudletLength() / (getCapacity(mipsShare) * rcl.getNumberOfPes()));
if (estimatedFinishTime - currentTime < 0.1) {
estimatedFinishTime = currentTime + 0.1;
if (estimatedFinishTime - currentTime < CloudSim.getMinTimeBetweenEvents()) {
estimatedFinishTime = currentTime + CloudSim.getMinTimeBetweenEvents();
}
if (estimatedFinishTime < nextEvent) {
......
......@@ -440,7 +440,7 @@ public class Datacenter extends SimEntity {
} else {
data[2] = CloudSimTags.FALSE;
}
send(vm.getUserId(), 0.1, CloudSimTags.VM_CREATE_ACK, data);
send(vm.getUserId(), CloudSim.getMinTimeBetweenEvents(), CloudSimTags.VM_CREATE_ACK, data);
}
if (result) {
......@@ -866,7 +866,7 @@ public class Datacenter extends SimEntity {
// if some time passed since last processing
// R: for term is to allow loop at simulation start. Otherwise, one initial
// simulation step is skipped and schedulers are not properly initialized
if (CloudSim.clock() < 0.111 || CloudSim.clock() > getLastProcessTime() + 0.1) {
if (CloudSim.clock() < 0.111 || CloudSim.clock() > getLastProcessTime() + CloudSim.getMinTimeBetweenEvents()) {
List<? extends Host> list = getVmAllocationPolicy().getHostList();
double smallerTime = Double.MAX_VALUE;
// for each host...
......@@ -880,8 +880,8 @@ public class Datacenter extends SimEntity {
}
}
// gurantees a minimal interval before scheduling the event
if (smallerTime < CloudSim.clock() + 0.11) {
smallerTime = CloudSim.clock() + 0.11;
if (smallerTime < CloudSim.clock() + CloudSim.getMinTimeBetweenEvents() + 0.01) {
smallerTime = CloudSim.clock() + CloudSim.getMinTimeBetweenEvents() + 0.01;
}
if (smallerTime != Double.MAX_VALUE) {
schedule(getId(), (smallerTime - CloudSim.clock()), CloudSimTags.VM_DATACENTER_EVENT);
......
......@@ -62,6 +62,9 @@ public class CloudSim {
/** The termination time. */
private static double terminateAt = -1;
/** The minimal time between events. Events within shorter periods after the last event are discarded. */
private static double minTimeBetweenEvents = 0.1;
/**
* Initialises all the common attributes.
*
......@@ -131,6 +134,40 @@ public class CloudSim {
}
}
/**
* Initialises CloudSim parameters. This method should be called before creating any entities.
* <p>
* Inside this method, it will create the following CloudSim entities:
* <ul>
* <li>CloudInformationService.
* <li>CloudSimShutdown
* </ul>
* <p>
*
* @param numUser the number of User Entities created. This parameters indicates that
* {@link gridsim.CloudSimShutdown} first waits for all user entities's
* END_OF_SIMULATION signal before issuing terminate signal to other entities
* @param cal starting time for this simulation. If it is <tt>null</tt>, then the time will be
* taken from <tt>Calendar.getInstance()</tt>
* @param traceFlag <tt>true</tt> if CloudSim trace need to be written
* @param periodBetweenEvents - the minimal period between events. Events within shorter periods
* after the last event are discarded.
* @see gridsim.CloudSimShutdown
* @see CloudInformationService.CloudInformationService
* @pre numUser >= 0
* @post $none
*/
public static void init(int numUser, Calendar cal, boolean traceFlag, double periodBetweenEvents) {
if (periodBetweenEvents <= 0) {
throw new IllegalArgumentException("The minimal time between events should be positive, but is:" + periodBetweenEvents);
}
init(numUser, cal, traceFlag);
minTimeBetweenEvents = periodBetweenEvents;
}
/**
* Starts the execution of CloudSim simulation. It waits for complete execution of all entities,
* i.e. until all entities threads reach non-RUNNABLE state or there are no more events in the
......@@ -212,6 +249,15 @@ public class CloudSim {
return true;
}
/**
* Returns the minimum time between events. Events within shorter periods after the last event are discarded.
* @return the minimum time between events.
*/
public static double getMinTimeBetweenEvents() {
return minTimeBetweenEvents;
}
/**
* Gets a new copy of initial simulation Calendar.
*
......
......@@ -218,8 +218,8 @@ public class NetworkCloudletSpaceSharedScheduler extends CloudletScheduler {
for (ResCloudlet rcl : getCloudletExecList()) {
double remainingLength = rcl.getRemainingCloudletLength();
double estimatedFinishTime = currentTime + (remainingLength / (capacity * rcl.getNumberOfPes()));
if (estimatedFinishTime - currentTime < 0.1) {
estimatedFinishTime = currentTime + 0.1;
if (estimatedFinishTime - currentTime < CloudSim.getMinTimeBetweenEvents()) {
estimatedFinishTime = currentTime + CloudSim.getMinTimeBetweenEvents();
}
if (estimatedFinishTime < nextEvent) {
nextEvent = estimatedFinishTime;
......
......@@ -16,8 +16,6 @@ import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.util.MathUtil;
import flanagan.analysis.Stat;
/**
* The class of a VM that stores its CPU utilization history. The history is used by VM allocation
* and selection policies.
......@@ -63,17 +61,17 @@ public class PowerVm extends Vm {
* @param schedulingInterval the scheduling interval
*/
public PowerVm(
int id,
int userId,
double mips,
int pesNumber,
int ram,
long bw,
long size,
int priority,
String vmm,
CloudletScheduler cloudletScheduler,
double schedulingInterval) {
final int id,
final int userId,
final double mips,
final int pesNumber,
final int ram,
final long bw,
final long size,
final int priority,
final String vmm,
final CloudletScheduler cloudletScheduler,
final double schedulingInterval) {
super(id, userId, mips, pesNumber, ram, bw, size, vmm, cloudletScheduler);
setSchedulingInterval(schedulingInterval);
}
......@@ -91,7 +89,7 @@ public class PowerVm extends Vm {
* @post $none
*/
@Override
public double updateVmProcessing(double currentTime, List<Double> mipsShare) {
public double updateVmProcessing(final double currentTime, final List<Double> mipsShare) {
double time = super.updateVmProcessing(currentTime, mipsShare);
if (currentTime > getPreviousTime() && (currentTime - 0.1) % getSchedulingInterval() == 0) {
double utilization = getTotalUtilizationOfCpu(getCloudletScheduler().getPreviousTime());
......@@ -120,7 +118,7 @@ public class PowerVm extends Vm {
for (int i = 0; i < n; i++) {
deviationSum[i] = Math.abs(median - getUtilizationHistory().get(i));
}
mad = Stat.median(deviationSum);
mad = MathUtil.median(deviationSum);
}
return mad;
}
......@@ -172,7 +170,7 @@ public class PowerVm extends Vm {
*
* @param utilization the utilization
*/
public void addUtilizationHistoryValue(double utilization) {
public void addUtilizationHistoryValue(final double utilization) {
getUtilizationHistory().add(0, utilization);
if (getUtilizationHistory().size() > HISTORY_LENGTH) {
getUtilizationHistory().remove(HISTORY_LENGTH);
......@@ -202,7 +200,7 @@ public class PowerVm extends Vm {
*
* @param previousTime the new previous time
*/
public void setPreviousTime(double previousTime) {
public void setPreviousTime(final double previousTime) {
this.previousTime = previousTime;
}
......@@ -220,7 +218,7 @@ public class PowerVm extends Vm {
*
* @param schedulingInterval the schedulingInterval to set
*/
protected void setSchedulingInterval(double schedulingInterval) {
protected void setSchedulingInterval(final double schedulingInterval) {
this.schedulingInterval = schedulingInterval;
}
......
......@@ -11,9 +11,9 @@ package org.cloudbus.cloudsim.power;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.cloudbus.cloudsim.Vm;
import flanagan.analysis.Regression;
import org.cloudbus.cloudsim.util.MathUtil;
/**
* The Maximum Correlation (MC) VM selection policy.
......@@ -39,19 +39,19 @@ public class PowerVmSelectionPolicyMaximumCorrelation extends PowerVmSelectionPo
*
* @param fallbackPolicy the fallback policy
*/
public PowerVmSelectionPolicyMaximumCorrelation(PowerVmSelectionPolicy fallbackPolicy) {
public PowerVmSelectionPolicyMaximumCorrelation(final PowerVmSelectionPolicy fallbackPolicy) {
super();
setFallbackPolicy(fallbackPolicy);
}
/*
* (non-Javadoc)
* @see
* org.cloudbus.cloudsim.experiments.power.PowerVmSelectionPolicy#getVmsToMigrate(org.cloudbus
* .cloudsim.power.PowerHost)
*
* @see org.cloudbus.cloudsim.experiments.power.PowerVmSelectionPolicy#
* getVmsToMigrate(org.cloudbus .cloudsim.power.PowerHost)
*/
@Override
public Vm getVmToMigrate(PowerHost host) {
public Vm getVmToMigrate(final PowerHost host) {
List<PowerVm> migratableVms = getMigratableVms(host);
if (migratableVms.isEmpty()) {
return null;
......@@ -80,7 +80,7 @@ public class PowerVmSelectionPolicyMaximumCorrelation extends PowerVmSelectionPo
* @param vmList the host
* @return the utilization matrix
*/
protected double[][] getUtilizationMatrix(List<PowerVm> vmList) {
protected double[][] getUtilizationMatrix(final List<PowerVm> vmList) {
int n = vmList.size();
int m = getMinUtilizationHistorySize(vmList);
double[][] utilization = new double[n][m];
......@@ -99,7 +99,7 @@ public class PowerVmSelectionPolicyMaximumCorrelation extends PowerVmSelectionPo
* @param vmList the vm list
* @return the min utilization history size
*/
protected int getMinUtilizationHistorySize(List<PowerVm> vmList) {
protected int getMinUtilizationHistorySize(final List<PowerVm> vmList) {
int minSize = Integer.MAX_VALUE;
for (PowerVm vm : vmList) {
int size = vm.getUtilizationHistory().size();
......@@ -116,7 +116,7 @@ public class PowerVmSelectionPolicyMaximumCorrelation extends PowerVmSelectionPo
* @param data the data
* @return the correlation coefficients
*/
protected List<Double> getCorrelationCoefficients(double[][] data) {
protected List<Double> getCorrelationCoefficients(final double[][] data) {
int n = data.length;
int m = data[0].length;
List<Double> correlationCoefficients = new LinkedList<Double>();
......@@ -129,9 +129,12 @@ public class PowerVmSelectionPolicyMaximumCorrelation extends PowerVmSelectionPo
}
}
Regression reg = new Regression(x, data[i]);
reg.linear();
correlationCoefficients.add(reg.getCoefficientOfDetermination());
// Transpose the matrix so that it fits the linear model
double[][] xT = new Array2DRowRealMatrix(x).transpose().getData();
// RSquare is the "coefficient of determination"
correlationCoefficients.add(MathUtil.createLinearRegression(xT,
data[i]).calculateRSquared());
}
return correlationCoefficients;
}
......@@ -150,7 +153,7 @@ public class PowerVmSelectionPolicyMaximumCorrelation extends PowerVmSelectionPo
*
* @param fallbackPolicy the new fallback policy
*/
public void setFallbackPolicy(PowerVmSelectionPolicy fallbackPolicy) {
public void setFallbackPolicy(final PowerVmSelectionPolicy fallbackPolicy) {
this.fallbackPolicy = fallbackPolicy;
}
......
......@@ -11,14 +11,12 @@ package org.cloudbus.cloudsim.util;
import java.util.Arrays;
import java.util.List;
import flanagan.analysis.Regression;
import flanagan.analysis.Stat;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression;
import org.apache.commons.math3.stat.regression.SimpleRegression;
/**
* A class containing multiple convenient math functions. To use some of the function you must
* download Michael Thomas Flanagan's Java Scientific Library:
*
* http://www.ee.ucl.ac.uk/~mflanaga/java/
* A class containing multiple convenient math functions.
*
* @author Anton Beloglazov
* @since CloudSim Toolkit 3.0
......@@ -31,7 +29,7 @@ public class MathUtil {
* @param list the list
* @return the double
*/
public static double sum(List<? extends Number> list) {
public static double sum(final List<? extends Number> list) {
double sum = 0;
for (Number number : list) {
sum += number.doubleValue();
......@@ -45,7 +43,7 @@ public class MathUtil {
* @param list the list
* @return the double[]
*/
public static double[] listToArray(List<? extends Number> list) {
public static double[] listToArray(final List<? extends Number> list) {
double[] array = new double[list.size()];
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i).doubleValue();
......@@ -59,8 +57,54 @@ public class MathUtil {
* @param list the list
* @return the median
*/
public static double median(List<Double> list) {
return Stat.median(listToArray(list));
public static double median(final List<Double> list) {
return getStatistics(list).getPercentile(50);
}
/**
* Gets the median.
*
* @param list the list
*
* @return the median
*/
public static double median(final double[] list) {
return getStatistics(list).getPercentile(50);
}
/**
* Returns descriptive statistics for the list of numbers.
*
* @param list
* - the list of numbers. Must not be null.
* @return - descriptive statistics for the list of numbers.
*/
public static DescriptiveStatistics getStatistics(final List<Double> list) {
// Get a DescriptiveStatistics instance
DescriptiveStatistics stats = new DescriptiveStatistics();
// Add the data from the array
for (Double d : list) {
stats.addValue(d);
}
return stats;
}
/**
* Returns descriptive statistics for the array of numbers.
*
* @param list - the array of numbers. Must not be null.
* @return - descriptive statistics for the array of numbers.
*/
public static DescriptiveStatistics getStatistics(final double[] list) {
// Get a DescriptiveStatistics instance
DescriptiveStatistics stats = new DescriptiveStatistics();
// Add the data from the array
for (int i = 0; i < list.length; i++) {
stats.addValue(list[i]);
}
return stats;
}
/**
......@@ -70,7 +114,7 @@ public class MathUtil {
*
* @return the average
*/
public static double mean(List<Double> list) {
public static double mean(final List<Double> list) {
double sum = 0;
for (Double number : list) {
sum += number;
......@@ -84,7 +128,7 @@ public class MathUtil {
* @param list the list
* @return the double
*/
public static double variance(List<Double> list) {
public static double variance(final List<Double> list) {
long n = 0;
double mean = mean(list);
double s = 0.0;
......@@ -106,7 +150,7 @@ public class MathUtil {
* @param list the list
* @return the double
*/
public static double stDev(List<Double> list) {
public static double stDev(final List<Double> list) {
return Math.sqrt(variance(list));
}
......@@ -116,15 +160,15 @@ public class MathUtil {
* @param data the data
* @return the mad
*/
public static double mad(double[] data) {
public static double mad(final double[] data) {
double mad = 0;
if (data.length > 0) {
double median = Stat.median(data);
double median = median(data);
double[] deviationSum = new double[data.length];
for (int i = 0; i < data.length; i++) {
deviationSum[i] = Math.abs(median - data[i]);
}
mad = Stat.median(deviationSum);
mad = median(deviationSum);
}
return mad;
}
......@@ -135,7 +179,7 @@ public class MathUtil {
* @param data the data
* @return the IQR
*/
public static double iqr(double[] data) {
public static double iqr(final double[] data) {
Arrays.sort(data);
int q1 = (int) Math.round(0.25 * (data.length + 1)) - 1;
int q3 = (int) Math.round(0.75 * (data.length + 1)) - 1;
......@@ -148,7 +192,7 @@ public class MathUtil {
* @param data the data
* @return the int
*/
public static int countNonZeroBeginning(double[] data) {
public static int countNonZeroBeginning(final double[] data) {
int i = data.length - 1;
while (i >= 0) {
if (data[i--] != 0) {
......@@ -164,7 +208,7 @@ public class MathUtil {
* @param data the data
* @return the int
*/
public static int countShortestRow(double[][] data) {
public static int countShortestRow(final double[][] data) {
int minLength = 0;
for (double[] row : data) {
if (row.length < minLength) {
......@@ -180,7 +224,7 @@ public class MathUtil {
* @param data the data
* @return the double[]
*/
public static double[] trimZeroTail(double[] data) {
public static double[] trimZeroTail(final double[] data) {
return Arrays.copyOfRange(data, 0, countNonZeroBeginning(data));
}
......@@ -190,19 +234,58 @@ public class MathUtil {
* @param y the y
* @return the loess parameter estimates
*/
public static double[] getLoessParameterEstimates(double[] y) {
public static double[] getLoessParameterEstimates(final double[] y) {
int n = y.length;
double[] x = new double[n];
for (int i = 0; i < n; i++) {
x[i] = i + 1;
}
Regression regression = new Regression(x, y, getTricubeWeigts(n));
regression.linear();
double[] estimates = regression.getBestEstimates();
if (estimates[0] == Double.NaN || estimates[1] == Double.NaN) {
return regression.getBestEstimates();
return createWeigthedLinearRegression(x, y, getTricubeWeigts(n))
.regress().getParameterEstimates();
}
return estimates;
public static SimpleRegression createLinearRegression(final double[] x,
final double[] y) {
SimpleRegression regression = new SimpleRegression();
for (int i = 0; i < x.length; i++) {
regression.addData(x[i], y[i]);
}
return regression;
}
public static OLSMultipleLinearRegression createLinearRegression(
final double[][] x, final double[] y) {
OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression();
regression.newSampleData(y, x);
return regression;
}
public static SimpleRegression createWeigthedLinearRegression(
final double[] x, final double[] y, final double[] weigths) {
double[] xW = new double[x.length];
double[] yW = new double[y.length];
// As to Flanagan's documentation they perform weigthed regression if the
// number or non-zero weigths is more than 40%
int numZeroWeigths = 0;
for (int i = 0; i < weigths.length; i++) {
if (weigths[i] <= 0) {
numZeroWeigths++;
}
}
for (int i = 0; i < x.length; i++) {
if (numZeroWeigths >= 0.4 * weigths.length) {
// See: http://www.ncsu.edu/crsc/events/ugw07/Presentations/Crooks_Qiao/Crooks_Qiao_Alt_Presentation.pdf
xW[i] = Math.sqrt(weigths[i]) * x[i];
yW[i] = Math.sqrt(weigths[i]) * y[i];
} else {
xW[i] = x[i];
yW[i] = y[i];
}
}
return createLinearRegression(xW, yW);
}
/**
......@@ -211,19 +294,25 @@ public class MathUtil {
* @param y the y
* @return the robust loess parameter estimates
*/
public static double[] getRobustLoessParameterEstimates(double[] y) {
public static double[] getRobustLoessParameterEstimates(final double[] y) {
int n = y.length;
double[] x = new double[n];
for (int i = 0; i < n; i++) {
x[i] = i + 1;
}
Regression regression = new Regression(x, y, getTricubeWeigts(n));
regression.linear();
Regression regression2 = new Regression(x, y, getTricubeBisquareWeigts(regression.getResiduals()));
regression2.linear();
double[] estimates = regression2.getBestEstimates();
SimpleRegression tricubeRegression = createWeigthedLinearRegression(x,
y, getTricubeWeigts(n));
double[] residuals = new double[n];
for (int i = 0; i < n; i++) {
residuals[i] = y[i] - tricubeRegression.predict(x[i]);
}
SimpleRegression tricubeBySquareRegression = createWeigthedLinearRegression(
x, y, getTricubeBisquareWeigts(residuals));
double[] estimates = tricubeBySquareRegression.regress()
.getParameterEstimates();
if (estimates[0] == Double.NaN || estimates[1] == Double.NaN) {
return regression.getBestEstimates();
return tricubeRegression.regress().getParameterEstimates();
}
return estimates;
}
......@@ -234,7 +323,7 @@ public class MathUtil {
* @param n the n
* @return the tricube weigts
*/
public static double[] getTricubeWeigts(int n) {
public static double[] getTricubeWeigts(final int n) {
double[] weights = new double[n];
double top = n - 1;
double spread = top;
......@@ -256,11 +345,11 @@ public class MathUtil {
* @param residuals the residuals
* @return the tricube bisquare weigts
*/
public static double[] getTricubeBisquareWeigts(double[] residuals) {
public static double[] getTricubeBisquareWeigts(final double[] residuals) {
int n = residuals.length;
double[] weights = getTricubeWeigts(n);
double[] weights2 = new double[n];
double s6 = Stat.median(abs(residuals)) * 6;
double s6 = median(abs(residuals)) * 6;
for (int i = 2; i < n; i++) {
double k = Math.pow(1 - Math.pow(residuals[i] / s6, 2), 2);
if (k > 0) {
......@@ -279,7 +368,7 @@ public class MathUtil {
* @param data the data
* @return the double[]
*/
public static double[] abs(double[] data) {
public static double[] abs(final double[] data) {
double[] result = new double[data.length];
for (int i = 0; i < result.length; i++) {
result[i] = Math.abs(data[i]);
......
......@@ -17,6 +17,16 @@
<build>
<plugins>
<!-- Sets the version of the code -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
......@@ -49,10 +59,11 @@
<artifactId>easymockclassextension</artifactId>
</dependency>
<dependency>
<groupId>org.flanagan</groupId>
<artifactId>flanagan</artifactId>
<version>1.0</version>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
</project>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment