001/*
002 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
003 * Copyright (C) 2006 - JScience (http://jscience.org/)
004 * All rights reserved.
005 * 
006 * Permission to use, copy, modify, and distribute this software is
007 * freely granted, provided that this notice is preserved.
008 */
009package org.jscience.mathematics.function;
010
011import javolution.lang.Reference;
012import javolution.context.LocalContext;
013
014/**
015 * <p> This interface represents a symbol on whose value a {@link Function}
016 *     depends. If the functions is not shared between multiple-threads the 
017 *     simple {@link Variable.Local} implementation can be used. 
018 *     For global functions (functions used concurrently by multiple threads)
019 *     the {@link Variable.Global} implementation with 
020 *     {@link javolution.context.LocalContext context-local} settings is 
021 *     recommended.</p>
022 *   
023 * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
024 * @version 3.0, February 13, 2006
025 * @see  Function#evaluate 
026 */
027public interface Variable<X> extends Reference<X> {
028
029    /**
030     * Returns the symbol for this variable.
031     * 
032     * @return this variable's symbol.
033     */
034    String getSymbol();
035
036    /**
037     * This class represents a simple {@link Variable} implementation for 
038     * functions not shared between threads (non static).
039     * Functions shared between multiple-threads should use a different 
040     * type of variable such as {@link Variable.Global}. 
041     */
042    public static class Local<X> implements Variable<X> {
043
044        /**
045         * Holds the reference value.
046         */
047        private X _value;
048
049        /**
050         * Holds the variable symbol.
051         */
052        private final String _symbol;
053
054        /**
055         * Creates a new local variable with a unique symbol.
056         * 
057         * @param symbol the variable symbol.
058         */
059        public Local(String symbol) {
060            _symbol = symbol;
061        }
062
063        public String getSymbol() {
064            return _symbol;
065        }
066
067        public X get() {
068            return _value;
069        }
070
071        public void set(X arg0) {
072            _value = arg0;
073        }
074    }
075
076    /**
077     * This class represents a simple {@link Variable} implementation with 
078     * {@link javolution.context.LocalContext context-local} values.
079     * Instances of this class can be set independently by multiple-threads 
080     * as long as each concurrent thread executes within a 
081     * {@link javolution.context.LocalContext LocalContext}. For example:[code]
082     * public abstract class Engine  {
083     *     public static final Variable.Global<Amount<AngularVelocity>> RPM
084     *         = new Variable.Global<Amount<AngularVelocity>>("rpm");
085     *     public abstract Function<Amount<AngularVelocity>, Amount<Torque>> getTorque();    
086     * }
087     * ...
088     * LocalContext.enter(); 
089     * try {
090     *     RPM.set(rpm);
091     *     Amount<Torque> torque = myEngine.getTorque().evaluate();
092     * } finally {
093     *     LocalContext.exit();
094     * }[/code]
095     * It should be noted that parameterized evaluations are performed within
096     *  a local context. Therefore, the example
097     * above could also be rewritten:[code]
098     *     Amount<Torque> torque = myEngine.getTorque().evaluate(rpm);
099     * [/code]
100     */
101    public static class Global<X> implements Variable<X> {
102
103        /**
104         * Holds the reference value.
105         */
106        private LocalContext.Reference<X> _value = new LocalContext.Reference<X>();
107
108        /**
109         * Holds the variable symbol.
110         */
111        private final String _symbol;
112
113        /**
114         * Creates a new global variable with a unique symbol.
115         * 
116         * @param symbol the variable symbol.
117         */
118        public Global(String symbol) {
119            _symbol = symbol;
120        }
121
122        public String getSymbol() {
123            return _symbol;
124        }
125
126        public X get() {
127            return _value.get();
128        }
129
130        public void set(X arg0) {
131            _value.set(arg0);
132        }
133    }
134
135}