KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lsmp > djep > vectorJep > function > MMultiply


1 /* @author rich
2  * Created on 27-Jul-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.vectorJep.function;
9 import org.lsmp.djep.vectorJep.*;
10 import org.lsmp.djep.vectorJep.values.*;
11 import org.nfunk.jep.*;
12 import org.nfunk.jep.function.*;
13 import java.util.*;
14
15 /**
16  * An extension of the Multiply to with vectors and matricies.
17  * Must faster (1/3) if used with MatrixJep and calcValue routines.
18  * Note vector * vector treated as col_vec * row_vec -> matrix.
19  *
20  * @author Rich Morris
21  * Created on 27-Jul-2003
22  * TODO add handeling of tensors
23  * @since 2.3.2 Improved error reporting
24  */

25 public class MMultiply extends Multiply implements BinaryOperatorI {
26     
27     protected Add add = new Add();
28     protected Subtract sub = new Subtract();
29     
30     public MMultiply()
31     {
32         //add = (Add) Operator.OP_ADD.getPFMC();
33
//sub = (Subtract) Operator.OP_SUBTRACT.getPFMC();
34
numberOfParameters = 2;
35     }
36
37
38
39
40     /**
41      * need to redo this as the standard jep version assumes commutivity.
42      */

43     public void run(Stack stack) throws ParseException
44     {
45         checkStack(stack); // check the stack
46
//if(this.curNumberOfParameters!=2) throw new ParseException("Multiply: should have two children its got "+stack.size());
47
Object JavaDoc param2 = stack.pop();
48         Object JavaDoc param1 = stack.pop();
49         Object JavaDoc product = mul(param1, param2);
50         stack.push(product);
51         return;
52     }
53
54     /**
55      * Multiply two objects.
56      */

57
58     public Object JavaDoc mul(Object JavaDoc param1, Object JavaDoc param2) throws ParseException
59     {
60         if(param1 instanceof MatrixValueI && param2 instanceof MatrixValueI)
61         {
62             return mul((MatrixValueI) param1,(MatrixValueI) param2);
63         }
64         else if(param1 instanceof MatrixValueI)
65         {
66             MatrixValueI l = (MatrixValueI) param1;
67             MatrixValueI res = Tensor.getInstance(l.getDim());
68             for(int i=0;i<res.getNumEles();++i)
69                 res.setEle(i,super.mul(l.getEle(i),param2));
70             return res;
71         }
72         else if(param2 instanceof MatrixValueI)
73         {
74             MatrixValueI r = (MatrixValueI) param2;
75             MatrixValueI res = Tensor.getInstance(r.getDim());
76             for(int i=0;i<res.getNumEles();++i)
77                 res.setEle(i,super.mul(param1,r.getEle(i)));
78             return res;
79         }
80         return super.mul(param1,param2);
81     }
82         
83     /**
84      * Multiply two objects.
85      */

86
87     public Object JavaDoc mul(MatrixValueI param1, MatrixValueI param2) throws ParseException
88     {
89         Dimensions dims = this.calcDim(param1.getDim(),param2.getDim());
90         MatrixValueI res = Tensor.getInstance(dims);
91         return this.calcValue(res,param1,param2);
92     }
93
94     public Dimensions calcDim(Dimensions l,Dimensions r) throws ParseException
95     {
96         int lrank = l.rank();
97         int rrank = r.rank();
98         
99         switch(lrank)
100         {
101         case 0: // Scaler res
102
return r;
103         case 1: // Vector * ?
104
switch(rrank)
105             {
106             case 0: // Vector * Scaler -> Vector
107
return l;
108             case 1: // Vector * Vector -> Matrix
109
return Dimensions.valueOf(l.getFirstDim(),r.getFirstDim());
110             case 2: // Vector * Matrix -> Vector
111
if(l.getLastDim() == r.getFirstDim())
112                      return Dimensions.valueOf(r.getLastDim());
113                 break;
114             default: // Tensor res
115
throw new ParseException("Sorry I don't know how to multiply a vector by a tensor");
116             }
117             break;
118         case 2: // Matrix * ?
119
switch(rrank)
120             {
121             case 0: // Matrix * Scaler -> Matrix
122
return l;
123             case 1: // Matrix * Vector -> Vector
124
if(l.getLastDim() == r.getFirstDim())
125                      return Dimensions.valueOf(l.getFirstDim());
126                 break;
127             case 2: // Matrix * Matrix -> Matrix
128
if(l.getLastDim() == r.getFirstDim()) return Dimensions.valueOf(l.getFirstDim(),r.getLastDim());
129                 break;
130             default: // Tensor res
131
//throw new ParseException("Sorry I don't know how to multiply a matrix by a tensor");
132

133             }
134             break;
135         default: // Tensor res
136
switch(rrank)
137             {
138             case 0: // Scaler res
139
return l;
140 // case 1: // Vector res
141
// throw new ParseException("Sorry I don't know how to multiply a tensor by a vector");
142
// case 2: // Matrix res
143
// throw new ParseException("Sorry I don't know how to multiply a tensor by a matrix");
144
// default: // Tensor res
145
// throw new ParseException("Sorry I don't know how to multiply a tensor by a tensor");
146
}
147         }
148         throw new ParseException("Dimensions for multiply do not match: "+l+" "+r);
149     }
150
151     public MatrixValueI calcValue(MatrixValueI res,MatrixValueI param1,MatrixValueI param2) throws ParseException
152     {
153         if(param1 instanceof Scaler)
154         {
155             if(param2 instanceof Scaler)
156             { // Scaler * Scaler -> Scaler
157
res.setEle(0,super.mul(param1.getEle(0),param2.getEle(0)));
158             }
159             else if(param2 instanceof MVector)
160             {
161              // Scaler * Vector -> Vector
162
for(int i=0;i<param2.getDim().getFirstDim();++i)
163                     res.setEle(i,super.mul(param1.getEle(0),param2.getEle(i)));
164             }
165             else if(param2 instanceof Matrix) // Scaler * Matrix -> Matrix
166
{
167                 Matrix r = (Matrix) param2;
168                 Matrix mres = (Matrix) res;
169                 for(int i=0;i<r.getNumRows();++i)
170                     for(int j=0;j<r.getNumCols();++j)
171                     mres.setEle(i,j,super.mul(param1.getEle(0),r.getEle(i,j)));
172             }
173             else
174             { // Tensor res
175
for(int i=0;i<param2.getDim().numEles();++i)
176                     res.setEle(i,super.mul(param1.getEle(0),param2.getEle(i)));
177             }
178         }
179         else if(param1 instanceof MVector)
180         {
181             if(param2 instanceof Scaler) // Vector * Scaler -> Vector
182
{
183                 for(int i=0;i<param1.getDim().getFirstDim();++i)
184                     res.setEle(i,super.mul(param1.getEle(i),param2.getEle(0)));
185             }
186             else if(param2 instanceof MVector) // Vector * Vector -> Matrix
187
{
188                 Matrix mat = (Matrix) res;
189                 for(int i=0;i<param1.getDim().getFirstDim();++i)
190                     for(int j=0;j<param2.getDim().getFirstDim();++j)
191                         mat.setEle(i,j,super.mul(param1.getEle(i),param2.getEle(j)));
192             }
193             else if(param2 instanceof Matrix) // Vector * Matrix -> Vector
194
{
195                 MVector lhs = (MVector) param1;
196                 Matrix rhs = (Matrix) param2;
197                 if(lhs.getNumEles() != rhs.getNumRows()) throw new ParseException("Multiply Matrix , Vector: Miss match in sizes ("+lhs.getNumEles()+","+rhs.getNumRows()+")!");
198                 for(int i=0;i<rhs.getNumCols();++i)
199                 {
200                     Object JavaDoc val = super.mul(lhs.getEle(0),rhs.getEle(0,i));
201                     for(int j=1;j<rhs.getNumRows();++j)
202                         val = add.add(val,
203                                 super.mul(lhs.getEle(j),rhs.getEle(j,i)));
204                     res.setEle(i,val);
205                 }
206             }
207             else
208             {
209                 throw new ParseException("Sorry I don't know how to multiply a vector by a tensor");
210             }
211         }
212         else if(param1 instanceof Matrix)
213         {
214             if(param2 instanceof Scaler) // Matrix * Scaler -> Matrix
215
{
216                 Matrix l = (Matrix) param1;
217                 Matrix mres = (Matrix) res;
218                 for(int i=0;i<l.getNumRows();++i)
219                     for(int j=0;j<l.getNumCols();++j)
220                     mres.setEle(i,j,super.mul(l.getEle(i,j),param2.getEle(0)));
221             }
222             else if(param2 instanceof MVector) // Matrix * Vector -> Vector
223
{
224                 Matrix lhs = (Matrix) param1;
225                 MVector rhs = (MVector) param2;
226                 if(lhs.getNumCols() != rhs.getNumEles()) throw new ParseException("Mat * Vec: Miss match in sizes ("+lhs.getNumCols()+","+rhs.getNumEles()+") when trying to add vectors!");
227                 for(int i=0;i<lhs.getNumRows();++i)
228                 {
229                     Object JavaDoc val = super.mul(lhs.getEle(i,0),rhs.getEle(0));
230                     for(int j=1;j<lhs.getNumCols();++j)
231                         val = add.add(val,super.mul(lhs.getEle(i,j),rhs.getEle(j)));
232                     res.setEle(i,val);
233                 }
234             }
235             else if(param2 instanceof Matrix) // Matrix * Matrix -> Matrix
236
{
237                 Matrix lhs = (Matrix) param1;
238                 Matrix rhs = (Matrix) param2;
239                 Matrix mres = (Matrix) res;
240                 if(lhs.getNumCols() != rhs.getNumRows()) throw new ParseException("Multiply matrix,matrix: Miss match in number of dims ("+lhs.getNumCols()+","+rhs.getNumRows()+")!");
241                 int lnr = lhs.getNumRows();
242                 int lnc = lhs.getNumCols();
243                 int rnc = rhs.getNumCols();
244                 Object JavaDoc ldata[][] = lhs.getEles();
245                 Object JavaDoc rdata[][] = rhs.getEles();
246                 Object JavaDoc resdata[][] = mres.getEles();
247                 for(int i=0;i<lnr;++i)
248                     for(int j=0;j<rnc;++j)
249                     {
250                         Object JavaDoc val = mul(ldata[i][0],rdata[0][j]);
251                         for(int k=1;k<lnc;++k)
252                             val = add.add(val,
253                                 mul(ldata[i][k],rdata[k][j]));
254                         resdata[i][j] = val;
255                     }
256             }
257             else // Tensor res
258
throw new ParseException("Sorry I don't know how to multiply a matrix by a tensor");
259         }
260         else
261         {
262             if(param2 instanceof Scaler)
263             {
264                 for(int i=0;i<param2.getDim().numEles();++i)
265                     res.setEle(i,super.mul(param1.getEle(i),param2.getEle(0)));
266             }
267             else
268                 throw new ParseException("Sorry I don't know how to multiply a tensor by a vector");
269         }
270         return res;
271     }
272 }
273
Popular Tags