Sample2_ServiceFunctions.java
Created with JBuilder
import mads.core.*;


/**
 * <p><H1>Introducing service functions</H1></p>
 *
 * <p><B>Sample project no. 2 </B><BR\> </p>
 *  * This sample shows how to create and work with service functions. Receiving service functions
 * from remote agents will not be shown here but in the following samples. Various types of
 * service functions will be created, both from templates and from scratch. Arithmetics and
 * plotting will then be showed. The tutorial on service functions will be continued in the next
 * sample as well. <BR\>
 * The user should notice the following things:<BR\>
 * <UL>
 *    <LI> Service functions hold three important elements: the base, the range and the actual data.
 *         The base and the range show the time range of the function, the years between the service
 *         function is valid. This is important to know, because most predictions are only done for
 *         a limited time range. For example, fuel price predictions from this year are usually valid
 *         only 20 or 30 years. We call the first year when the prediction is valid the <I>base</I> and
 *         the number of following years the prediction remains valid the <I>range</I>. By default,
 *         a service function has range = 0 and base = 10000. In MADS, 10000 values is the maximum
 *         number of values a service function can hold.
 *    <LI> If the user tries to write or read a value outside the time range, an error will be thrown.
 *    <LI> To get and set the value of the service function at some point in time, one must use the
 *         getValue / setValue functions.
 *    <LI> Service function can be plotted either value by value or automatically. One can also
 *         plot service functions very easy. Both the plotting and printing routines can function.
 *         either between specified years or, if nothing is specified, for the whole time range.
 *         Exporting a service function to a text file is also possible.
 *    <LI> MADS provides functions for automatically finding the minimum, maximum, mean and other
 *         important values from a service function.
 *    <LI> Arithmetical operations can be performed between service functions. The time range
 *         of the result will automatically become the intersection of the time ranges of the
 *         operands, to ensure consistency.
 * </UL>
 *
 * <p>This sample simulation takes the user a step further and shows the basics of working with service
 * functions. Service functions are created and their values are set and read in various ways. Important
 * values like minimum, maximum, the mean and so on are then computed. Simple arithmetics and plotting are
 * also shown.
 * </p>

**/

public class Sample2_ServiceFunctions extends ASimulationAgent
{
  public void doWork(){

    /**
     * Defining a new service function. By default, this service function will have the base = 0
     * and the range = 10000. The base and range of the function specify where (better said, when)
     * the function is valid. If one tries to get or set values outside this interval, an error message
     * will be returned.
     */

    // Define the function
    ServiceFunction sf1 = new ServiceFunction();


    /**
     * We now define a second service function. This time, we will specify the base and the range.
     * We will make the service function valid only between 2000 and 2030.
     */

    // Define the service function and specify the base and range. The function is valid <range>
    // years, starting from the base. Here, is valid 30 years, starting from 2000, therefore on
    // 2000 - 2030.
    ServiceFunction sf2 = new ServiceFunction(2000, 30);


    /**
     * If not set from the beginning, the base and range can also be set afterwords. We will now
     * do this for sf1
     */

    // Setting the base and range for sf1, so it becomes valid for 2000 -> 2050.
    sf1.setBase(2000);
    sf1.setRange(50);


    /**
     * For every valid year (year Y is valid if <base> <= Y <= <base> + <range>), we can set the
     * value the function will have. Let's now make sf1 to have the same value (say, 100) for the
     * whole time range. All values are real numbers, in double precision.
     */

    // For the whole time range, set the values to 100
    for (int time = 2000; time <= 2050; time++)
      sf1.setValue(time, 100);


    /**
     * Usually, when considering all the time interval, is better to use the base and range info
     * present in the service function rather that the actual years. Doing this will make mistakes
     * less likely. We will use this method and make sf2 hold for each year the value of that year.
     */

    for (int time = sf2.getBase(); time <= sf2.getBase() + sf2.getRange(); time++)
      sf2.setValue(time, time);


    /**
     * Now that we have created these service functions, we want to check if they are indeed holding
     * the information we provided. This can be done in four different ways.
     * The first is to get each value using the getValue function, and print it.
     * The second is to use the provided print function, which will basically do the same thing
     * The third is to print a short version, by inserting directly into a println statement
     * The fourth is to plot the function
     */

     // The first method, using getValue()
     System.out.println("\n -- printing sf2, using getValue()");
     for (int time = sf2.getBase(); time <= sf2.getBase() + sf2.getRange(); time++)
       System.out.println(time + " -> " + sf2.getValue(time));

     // The second method, using the print() function
     System.out.println("\n -- printing sf1, using print(), for the whole time range");
     sf1.print();

     // The second method, but not for the whole time range
     System.out.println("\n -- printing sf2, using print(), between 2010 and 2020");
     sf2.print(2010, 2020);

     // The third method, the short version
     System.out.println("\n -- printing sf2 in the short form");
     System.out.println(sf2);

     // The fourth method, plotting for the whole time range
     sf2.plot("Y axis title", "sf2 for the whole time range");

     // The fourth method, plotting between 2010 - 2020
     sf2.plot(2010, 2020, "Y axis title", "sf2 between 2010 and 2020");


     /**
      * We can combine two or more service functions using arithmetics, like addition,
      * subtraction and so on. If service functions with different base and range are involved
      * in an operation, the resulting service function's range will be the intersection of the
      * ranges. So, if we add a service function defined on 2000 - 2030 with one defined on
      * 2010 - 2040, the sum will be defined on 2010 - 2030. This ensures that at every time point,
      * the operands are well defined.
      * In the following, we will so some sample arithmetics
      */

     // Defining a service function whose value is s1 + s2
     ServiceFunction sfSum = sf1.plus(sf2);

     // Now print the service function and see that both the base, range and values are correct
     // To see this, look at the values for sf1 and sf2 printed above and compare.
     System.out.println("\n -- printing sfSum = sf1 + sf2");
     sfSum.print();

     // Let's check if the difference between sf1 and itself is zero by analysing the plot.
     // You can see there is no need to define a new service function for this, it can be done
     // directly. See that the time range is 2000 - 2050, the same as sf1. In the previous case,
     // the time range of the results had to be reduced to 2000 - 2030 because of sf2
     sf1.minus(sf1).plot("Value", "Difference between sf1 and sf1");


     /**
      * Sometimes one needs to know some additional data regarding the service function, like
      * the mean of the values, the minimum or maximum or the first time the function reaches
      * a certain value.
      */

     // Find the minimum, maximum and mean of sf2
     System.out.println("\nThe minimum of sf2 is : " + sf2.min());
     System.out.println("The maximum of sf2 is : " + sf2.max());
     System.out.println("The mean of sf2 is :" + sf2.mean());

     // Finding when the sf1 reaches its maximum and minimum
     System.out.println("The maximum of sf2 is reached in : " + sf2.tmax());
     System.out.println("The minimum of sf2 is reached in : " + sf2.tmin());

     // Finding the first time sf2 reaches 2015. We search starting with the year 2000
     System.out.println("The function sf2 reaches 2015 for the first time in : " + sf2.firstTimeIn(2000, 2015));

     /**
      * In some cases, a service function has to be saved to a file, so that it can be further
      * processed in another software (e.g. plotting in some professional soft, etc). This is
      * how it can be done. The values are saved in text format.
      */

     // Saving sf2 in a text file (the sample text file is c:\sf2.txt). After running the program,
     // go to this location and open the file.
     sf2.saveToFile("c:\\sf2.txt");

    }
}



Sample2_ServiceFunctions.java
Created with JBuilder