KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lsmp > djep > djep > DVariable


1 /* @author rich
2  * Created on 26-Oct-2003
3  *
4  * This code is covered by a Creative Commons
5  * Attribution, Non Commercial, Share Alike license
6  * <a HREF="http://creativecommons.org/licenses/by-nc-sa/1.0">License</a>
7  */

8 package org.lsmp.djep.djep;
9 import java.util.*;
10 import org.nfunk.jep.*;
11 import org.lsmp.djep.xjep.*;
12
13 /**
14  * Holds all info about a variable.
15  * Has a name, an equation, a dimension (or sent of dimensions if matrix or tensor)
16  * and also a set of {@link PartialDerivative PartialDerivative}.
17  * The derivatives are stored in a hashtable index by
18  * the sorted names of derivatives.
19  * i.e. d^2f/dxdy, and d^2f/dydx will both be indexed by {"x","y"}.
20  * df/dx is indexed by {"x"}, d^2f/dx^2 is index by {"x","x"}.
21  * Partial derivatives are calculated as required by the
22  * findDerivative method.
23  * @author Rich Morris
24  * Created on 26-Oct-2003
25  */

26 public class DVariable extends XVariable
27 {
28     protected Hashtable derivatives = new Hashtable();
29     
30     protected PartialDerivative createDerivative(String JavaDoc derivnames[],Node eqn)
31     {
32         return new PartialDerivative(this,derivnames,eqn);
33     }
34     /**
35      * The constructor is package private. Variables should be created
36      * using the VariableTable.find(Sting name) method.
37      */

38     protected DVariable(String JavaDoc name)
39     {
40         super(name);
41     }
42
43     protected DVariable(String JavaDoc name,Object JavaDoc value)
44     {
45         super(name,value);
46     }
47
48     /** sets the equation */
49     public void setEquation(Node eqn)
50     {
51         super.setEquation(eqn);
52         derivatives.clear();
53     }
54
55     /** makes value and values of all derivatives invalid. **/
56     public void invalidateAll()
57     {
58         setValidValue(false);
59         for(Enumeration e = derivatives.elements(); e.hasMoreElements(); )
60         {
61             PartialDerivative deriv = (PartialDerivative) e.nextElement();
62             deriv.setValidValue(false);
63         }
64     }
65     /** Produces a string to represent the derivative.
66      * The string will be of the form "dx^2/dxdy".
67      * This string is used to index the derivatives of a variable.
68      * @param rootname name of the variable we are calculating the derivative of.
69      * @param dnames An array of the names of each of the partial derivatives.
70      * @return the string representation
71      */

72     public static String JavaDoc makeDerivString(String JavaDoc rootname,String JavaDoc dnames[])
73     {
74         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
75         sb.append('d');
76         if( dnames.length!= 1) sb.append("^" + dnames.length);
77         sb.append(rootname);
78         sb.append('/');
79         // TODO print d^2f/dxdx as d^2f/dx^2
80
for(int i=0;i<dnames.length;++i)
81         {
82             sb.append('d');
83             sb.append(dnames[i]);
84         }
85         return sb.toString();
86
87     }
88     /** returns a sorted copy of the input array of strings */
89     private String JavaDoc[] sortedNames(String JavaDoc names[])
90     {
91         String JavaDoc newnames[] = new String JavaDoc[names.length];
92         System.arraycopy(names,0,newnames,0,names.length);
93         Arrays.sort(newnames);
94         return newnames;
95     }
96     /** Sets the derivative wrt the variables specified in
97      * deriv names. Note the names are sorted so that
98      * d^2z/dxdy = d^2z/dydx.
99      */

100     public void setDerivative(String JavaDoc derivnames[],PartialDerivative eqn)
101     {
102         String JavaDoc newnames[] = sortedNames(derivnames);
103         derivatives.put(makeDerivString(name,newnames),eqn);
104     }
105
106     public void setDerivativeSorted(String JavaDoc derivnames[],PartialDerivative eqn)
107     {
108         derivatives.put(makeDerivString(name,derivnames),eqn);
109     }
110
111 /* public PartialDerivative getDerivative(String derivname)
112     {
113         return (PartialDerivative) derivatives.get(derivname);
114     }
115 */

116     public PartialDerivative getDerivative(String JavaDoc derivnames[])
117     {
118         String JavaDoc newnames[] = sortedNames(derivnames);
119         return (PartialDerivative) derivatives.get(makeDerivString(name,newnames));
120     }
121
122     public PartialDerivative getDerivativeSorted(String JavaDoc derivnames[])
123     {
124         return (PartialDerivative) derivatives.get(makeDerivString(name,derivnames));
125     }
126
127
128 /**
129  * Finds the derivative of this variable wrt the names.
130  * If the derivative already exists just return that.
131  * Otherwise use the visitor to calculate the derivative.
132  * If the derivative cannot be calculated (say if the equation is null)
133  * then return null.
134  *
135  * @param derivnames
136  * @param dv
137  * @return The derivative or null if it cannot be calculated.
138  * @throws ParseException
139  */

140     public PartialDerivative findDerivativeSorted(String JavaDoc derivnames[],DJep jep)
141         throws ParseException
142     {
143         if(getEquation()==null) return null;
144         
145         if(derivnames == null) throw new ParseException("findDerivativeSorted: Null array of names");
146         PartialDerivative res = getDerivativeSorted(derivnames);
147         if(res!=null) return res;
148         
149         // Deriv not found. Calculate from lower derivative
150
int origlen = derivnames.length;
151         Node lowereqn; // equation for lower derivative (or root equation)
152
if(origlen < 1)
153             throw new ParseException("findDerivativeSorted: Empty Array of names");
154         else if(origlen == 1)
155             lowereqn = getEquation();
156         else
157         {
158             String JavaDoc newnames[] = new String JavaDoc[origlen-1];
159             for(int i=0;i<origlen-1;++i)
160                 newnames[i]=derivnames[i];
161             lowereqn = findDerivativeSorted(newnames,jep).getEquation();
162         }
163         if(lowereqn==null)
164         {
165             return null;
166         }
167         Node deriv = (Node) jep.differentiate(lowereqn,derivnames[origlen-1]);
168         Node simp = (Node) jep.simplify(deriv);
169         res = createDerivative(derivnames,simp);
170         setDerivative(derivnames,res);
171         return res;
172     }
173
174     public PartialDerivative findDerivative(String JavaDoc derivnames[],DJep jep)
175         throws ParseException
176     {
177         String JavaDoc newnames[] = sortedNames(derivnames);
178         return findDerivativeSorted(newnames,jep);
179     }
180
181     public PartialDerivative findDerivative(String JavaDoc derivname,DJep jep)
182         throws ParseException
183     {
184         String JavaDoc newnames[] = new String JavaDoc[1];
185         newnames[0]=derivname;
186         return findDerivativeSorted(newnames,jep);
187     }
188
189     public PartialDerivative findDerivative(PartialDerivative deriv,String JavaDoc name,DJep jep)
190         throws ParseException
191     {
192         int len = deriv.getDnames().length;
193         String JavaDoc newnames[] = new String JavaDoc[len+1];
194         System.arraycopy(deriv.getDnames(),0,newnames,0,len);
195         newnames[len]=name;
196         return findDerivative(newnames,jep);
197     }
198     
199     public void print(PrintVisitor bpv)
200     {
201         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(name);
202         sb.append(": ");
203         if(hasValidValue()) sb.append(" val "+getValue() );
204         else sb.append(" val invalid");
205         sb.append(" ");
206         if(getEquation()!=null) sb.append(bpv.toString(getEquation()));
207         sb.append("\n");
208         for(Enumeration e = derivatives.elements(); e.hasMoreElements(); )
209         {
210             PartialDerivative var = (PartialDerivative) e.nextElement();
211             sb.append("\t"+var.toString()+": ");
212             if(var.hasValidValue()) sb.append(" val "+var.getValue() );
213             else sb.append(" val invalid");
214             sb.append(" ");
215             sb.append(bpv.toString(var.getEquation()));
216             sb.append("\n");
217         }
218         System.out.print(sb.toString());
219     }
220
221     /**
222      * Sets the value of the variable. Constant values cannot be changed.
223      * @return false if tried to change a constant value.
224      */

225 /*
226  * Should not be needed as functionality now caried out using java.util.observer/observable model.
227  
228     public boolean setValueRaw(Object object) {
229         for(Enumeration en = derivatives.elements();en.hasMoreElements();)
230         {
231             PartialDerivative pd = (PartialDerivative) en.nextElement();
232             pd.setValidValue(false);
233         }
234         return super.setValueRaw(object);
235     }
236 */

237 }
238
Popular Tags