2 |
26 Feb 07 |
jari |
1 |
package org.tigr.microarray.mev.r; |
2 |
26 Feb 07 |
jari |
2 |
|
2 |
26 Feb 07 |
jari |
3 |
import java.util.*; |
2 |
26 Feb 07 |
jari |
4 |
|
2 |
26 Feb 07 |
jari |
/** representation of R-eXpressions in Java |
2 |
26 Feb 07 |
jari |
6 |
|
2 |
26 Feb 07 |
jari |
@version $Id$ |
2 |
26 Feb 07 |
jari |
8 |
*/ |
2 |
26 Feb 07 |
jari |
9 |
public class REXP extends Object { |
2 |
26 Feb 07 |
jari |
/** xpression type: NULL */ |
2 |
26 Feb 07 |
jari |
11 |
public static final int XT_NULL=0; |
2 |
26 Feb 07 |
jari |
/** xpression type: integer */ |
2 |
26 Feb 07 |
jari |
13 |
public static final int XT_INT=1; |
2 |
26 Feb 07 |
jari |
/** xpression type: double */ |
2 |
26 Feb 07 |
jari |
15 |
public static final int XT_DOUBLE=2; |
2 |
26 Feb 07 |
jari |
/** xpression type: String */ |
2 |
26 Feb 07 |
jari |
17 |
public static final int XT_STR=3; |
2 |
26 Feb 07 |
jari |
/** xpression type: language construct (currently content is same as list) */ |
2 |
26 Feb 07 |
jari |
19 |
public static final int XT_LANG=4; |
2 |
26 Feb 07 |
jari |
/** xpression type: symbol (content is symbol name: String) */ |
2 |
26 Feb 07 |
jari |
21 |
public static final int XT_SYM=5; |
2 |
26 Feb 07 |
jari |
/** xpression type: RBool */ |
2 |
26 Feb 07 |
jari |
23 |
public static final int XT_BOOL=6; |
2 |
26 Feb 07 |
jari |
/** xpression type: Vector */ |
2 |
26 Feb 07 |
jari |
25 |
public static final int XT_VECTOR=16; |
2 |
26 Feb 07 |
jari |
/** xpression type: RList */ |
2 |
26 Feb 07 |
jari |
27 |
public static final int XT_LIST=17; |
2 |
26 Feb 07 |
jari |
/** xpression type: closure (there is no java class for that type (yet?). currently the body of the closure is stored in the content part of the REXP. Please note that this may change in the future!) */ |
2 |
26 Feb 07 |
jari |
29 |
public static final int XT_CLOS=18; |
2 |
26 Feb 07 |
jari |
/** xpression type: int[] */ |
2 |
26 Feb 07 |
jari |
31 |
public static final int XT_ARRAY_INT=32; |
2 |
26 Feb 07 |
jari |
/** xpression type: double[] */ |
2 |
26 Feb 07 |
jari |
33 |
public static final int XT_ARRAY_DOUBLE=33; |
2 |
26 Feb 07 |
jari |
/** xpression type: String[] (currently not used, Vector is used instead) */ |
2 |
26 Feb 07 |
jari |
35 |
public static final int XT_ARRAY_STR=34; |
2 |
26 Feb 07 |
jari |
/** internal use only! this constant should never appear in a REXP */ |
2 |
26 Feb 07 |
jari |
37 |
public static final int XT_ARRAY_BOOL_UA=35; |
2 |
26 Feb 07 |
jari |
/** xpression type: RBool[] */ |
2 |
26 Feb 07 |
jari |
39 |
public static final int XT_ARRAY_BOOL=36; |
2 |
26 Feb 07 |
jari |
/** xpression type: unknown; no assumptions can be made about the content */ |
2 |
26 Feb 07 |
jari |
41 |
public static final int XT_UNKNOWN=48; |
2 |
26 Feb 07 |
jari |
42 |
|
2 |
26 Feb 07 |
jari |
/** xpression type: RFactor; this XT is internally generated (ergo is does not come from Rsrv.h) to support RFactor class which is built from XT_ARRAY_INT */ |
2 |
26 Feb 07 |
jari |
44 |
public static final int XT_FACTOR=127; |
2 |
26 Feb 07 |
jari |
45 |
|
2 |
26 Feb 07 |
jari |
/** xpression type */ |
2 |
26 Feb 07 |
jari |
47 |
int Xt; |
2 |
26 Feb 07 |
jari |
/** attribute xpression or <code>null</code> if none */ |
2 |
26 Feb 07 |
jari |
49 |
REXP attr; |
2 |
26 Feb 07 |
jari |
/** content of the xpression - its object type is dependent of {@link #Xt} */ |
2 |
26 Feb 07 |
jari |
51 |
Object cont; |
2 |
26 Feb 07 |
jari |
52 |
|
2 |
26 Feb 07 |
jari |
/** cached binary length; valid only if positive */ |
2 |
26 Feb 07 |
jari |
54 |
long cachedBinaryLength=-1; |
2 |
26 Feb 07 |
jari |
55 |
|
2 |
26 Feb 07 |
jari |
/** construct a new, empty (NULL) expression w/o attribute */ |
2 |
26 Feb 07 |
jari |
57 |
public REXP() { Xt=0; attr=null; cont=null; } |
2 |
26 Feb 07 |
jari |
58 |
|
2 |
26 Feb 07 |
jari |
/** construct a new xpression of type t and content o, but no attribute |
2 |
26 Feb 07 |
jari |
@param t xpression type (XT_...) |
2 |
26 Feb 07 |
jari |
@param o content */ |
2 |
26 Feb 07 |
jari |
62 |
public REXP(int t, Object o) { |
2 |
26 Feb 07 |
jari |
63 |
Xt=t; cont=o; attr=null; |
2 |
26 Feb 07 |
jari |
64 |
} |
2 |
26 Feb 07 |
jari |
65 |
|
2 |
26 Feb 07 |
jari |
/** construct a new xpression of type t, content o and attribute at |
2 |
26 Feb 07 |
jari |
@param t xpression type |
2 |
26 Feb 07 |
jari |
@param o content |
2 |
26 Feb 07 |
jari |
@param at attribute */ |
2 |
26 Feb 07 |
jari |
70 |
public REXP(int t, Object o, REXP at) { |
2 |
26 Feb 07 |
jari |
71 |
Xt=t; cont=o; attr=at; |
2 |
26 Feb 07 |
jari |
72 |
} |
2 |
26 Feb 07 |
jari |
73 |
|
2 |
26 Feb 07 |
jari |
/** construct a new xpression of type XT_ARRAY_DOUBLE and content val |
2 |
26 Feb 07 |
jari |
@param val array of doubles to store in the REXP */ |
2 |
26 Feb 07 |
jari |
76 |
public REXP(double[] val) { |
2 |
26 Feb 07 |
jari |
77 |
this(XT_ARRAY_DOUBLE,val); |
2 |
26 Feb 07 |
jari |
78 |
} |
2 |
26 Feb 07 |
jari |
79 |
|
2 |
26 Feb 07 |
jari |
/** construct a new xpression of type XT_ARRAY_INT and content val |
2 |
26 Feb 07 |
jari |
@param val array of integers to store in the REXP */ |
2 |
26 Feb 07 |
jari |
82 |
public REXP(int[] val) { |
2 |
26 Feb 07 |
jari |
83 |
this(XT_ARRAY_INT,val); |
2 |
26 Feb 07 |
jari |
84 |
} |
2 |
26 Feb 07 |
jari |
85 |
|
2 |
26 Feb 07 |
jari |
/** construct a new xpression of type XT_ARRAY_INT and content val |
2 |
26 Feb 07 |
jari |
@param val array of integers to store in the REXP */ |
2 |
26 Feb 07 |
jari |
88 |
public REXP(String[] val) { |
2 |
26 Feb 07 |
jari |
89 |
this(XT_ARRAY_STR,val); |
2 |
26 Feb 07 |
jari |
90 |
} |
2 |
26 Feb 07 |
jari |
91 |
|
2 |
26 Feb 07 |
jari |
/** get attribute of the REXP. In R every object can have attached attribute xpression. Some more complex structures such as classes are built that way. |
2 |
26 Feb 07 |
jari |
@return attribute xpression or <code>null</code> if there is none associated */ |
2 |
26 Feb 07 |
jari |
94 |
public REXP getAttribute() { |
2 |
26 Feb 07 |
jari |
95 |
return attr; |
2 |
26 Feb 07 |
jari |
96 |
} |
2 |
26 Feb 07 |
jari |
97 |
|
2 |
26 Feb 07 |
jari |
/** get raw content. Use as... methods to retrieve contents of known type. |
2 |
26 Feb 07 |
jari |
@return content of the REXP */ |
2 |
26 Feb 07 |
jari |
100 |
public Object getContent() { |
2 |
26 Feb 07 |
jari |
101 |
return cont; |
2 |
26 Feb 07 |
jari |
102 |
} |
2 |
26 Feb 07 |
jari |
103 |
|
2 |
26 Feb 07 |
jari |
/** get xpression type (see XT_.. constants) of the content. It defines the type of the content object. |
2 |
26 Feb 07 |
jari |
@return xpression type */ |
2 |
26 Feb 07 |
jari |
106 |
public int getType() { |
2 |
26 Feb 07 |
jari |
107 |
return Xt; |
2 |
26 Feb 07 |
jari |
108 |
} |
2 |
26 Feb 07 |
jari |
109 |
|
2 |
26 Feb 07 |
jari |
/** parses byte buffer for binary representation of xpressions - read one xpression slot (descends recursively for aggregated xpressions such as lists, vectors etc.) |
2 |
26 Feb 07 |
jari |
@param x xpression object to store the parsed xpression in |
2 |
26 Feb 07 |
jari |
@param buf buffer containing the binary representation |
2 |
26 Feb 07 |
jari |
@param o offset in the buffer to start at |
2 |
26 Feb 07 |
jari |
@return position just behind the parsed xpression. Can be use for successive calls to {@link #parseREXP} if more than one expression is stored in the binary array. */ |
2 |
26 Feb 07 |
jari |
115 |
public static int parseREXP(REXP x, byte[] buf, int o) { |
2 |
26 Feb 07 |
jari |
116 |
int xl=Rtalk.getLen(buf,o); |
2 |
26 Feb 07 |
jari |
117 |
boolean hasAtt=((buf[o]&128)!=0); |
2 |
26 Feb 07 |
jari |
118 |
boolean isLong=((buf[o]&64)!=0); |
2 |
26 Feb 07 |
jari |
119 |
int xt=(int)(buf[o]&63); |
2 |
26 Feb 07 |
jari |
//System.out.println("parseREXP: type="+xt+", len="+xl+", hasAtt="+hasAtt+", isLong="+isLong); |
2 |
26 Feb 07 |
jari |
121 |
if (isLong) o+=4; |
2 |
26 Feb 07 |
jari |
122 |
o+=4; |
2 |
26 Feb 07 |
jari |
123 |
int eox=o+xl; |
2 |
26 Feb 07 |
jari |
124 |
|
2 |
26 Feb 07 |
jari |
125 |
x.Xt=xt; x.attr=null; |
2 |
26 Feb 07 |
jari |
126 |
if (hasAtt) o=parseREXP(x.attr=new REXP(),buf,o); |
2 |
26 Feb 07 |
jari |
127 |
if (xt==XT_NULL) { |
2 |
26 Feb 07 |
jari |
128 |
x.cont=null; return o; |
2 |
26 Feb 07 |
jari |
129 |
}; |
2 |
26 Feb 07 |
jari |
130 |
if (xt==XT_DOUBLE) { |
2 |
26 Feb 07 |
jari |
131 |
long lr=Rtalk.getLong(buf,o); |
2 |
26 Feb 07 |
jari |
132 |
x.cont=new Double(Double.longBitsToDouble(lr)); |
2 |
26 Feb 07 |
jari |
133 |
o+=8; |
2 |
26 Feb 07 |
jari |
134 |
if (o!=eox) { |
2 |
26 Feb 07 |
jari |
135 |
System.out.println("Warning: double SEXP size mismatch\n"); |
2 |
26 Feb 07 |
jari |
136 |
o=eox; |
2 |
26 Feb 07 |
jari |
137 |
}; |
2 |
26 Feb 07 |
jari |
138 |
return o; |
2 |
26 Feb 07 |
jari |
139 |
} |
2 |
26 Feb 07 |
jari |
140 |
if (xt==XT_ARRAY_DOUBLE) { |
2 |
26 Feb 07 |
jari |
141 |
int as=(eox-o)/8,i=0; |
2 |
26 Feb 07 |
jari |
142 |
double[] d=new double[as]; |
2 |
26 Feb 07 |
jari |
143 |
while (o<eox) { |
2 |
26 Feb 07 |
jari |
144 |
d[i]=Double.longBitsToDouble(Rtalk.getLong(buf,o)); |
2 |
26 Feb 07 |
jari |
145 |
o+=8; |
2 |
26 Feb 07 |
jari |
146 |
i++; |
2 |
26 Feb 07 |
jari |
147 |
}; |
2 |
26 Feb 07 |
jari |
148 |
if (o!=eox) { |
2 |
26 Feb 07 |
jari |
149 |
System.out.println("Warning: double array SEXP size mismatch\n"); |
2 |
26 Feb 07 |
jari |
150 |
o=eox; |
2 |
26 Feb 07 |
jari |
151 |
}; |
2 |
26 Feb 07 |
jari |
152 |
x.cont=d; |
2 |
26 Feb 07 |
jari |
153 |
return o; |
2 |
26 Feb 07 |
jari |
154 |
}; |
2 |
26 Feb 07 |
jari |
155 |
if (xt==XT_BOOL) { |
2 |
26 Feb 07 |
jari |
156 |
x.cont=new RBool(buf[o]); o++; |
2 |
26 Feb 07 |
jari |
157 |
if (o!=eox) { |
2 |
26 Feb 07 |
jari |
158 |
if (eox!=o+3) // o+3 could happen if the result was aligned (1 byte data + 3 bytes padding) |
2 |
26 Feb 07 |
jari |
159 |
System.out.println("Warning: bool SEXP size mismatch\n"); |
2 |
26 Feb 07 |
jari |
160 |
o=eox; |
2 |
26 Feb 07 |
jari |
161 |
}; |
2 |
26 Feb 07 |
jari |
162 |
return o; |
2 |
26 Feb 07 |
jari |
163 |
}; |
2 |
26 Feb 07 |
jari |
164 |
if (xt==XT_ARRAY_BOOL_UA) { |
2 |
26 Feb 07 |
jari |
165 |
int as=(eox-o), i=0; |
2 |
26 Feb 07 |
jari |
166 |
x.Xt=XT_ARRAY_BOOL; // XT_ARRAY_BOOL_UA is only old transport type for XT_ARRAY_BOOL |
2 |
26 Feb 07 |
jari |
167 |
RBool[] d=new RBool[as]; |
2 |
26 Feb 07 |
jari |
168 |
while(o<eox) { |
2 |
26 Feb 07 |
jari |
169 |
d[i]=new RBool(buf[o]); |
2 |
26 Feb 07 |
jari |
170 |
i++; o++; |
2 |
26 Feb 07 |
jari |
171 |
}; |
2 |
26 Feb 07 |
jari |
172 |
x.cont=d; |
2 |
26 Feb 07 |
jari |
173 |
return o; |
2 |
26 Feb 07 |
jari |
174 |
}; |
2 |
26 Feb 07 |
jari |
175 |
if (xt==XT_ARRAY_BOOL) { |
2 |
26 Feb 07 |
jari |
176 |
int as=Rtalk.getInt(buf,o); |
2 |
26 Feb 07 |
jari |
177 |
o+=4; |
2 |
26 Feb 07 |
jari |
178 |
int i=0; |
2 |
26 Feb 07 |
jari |
179 |
RBool[] d=new RBool[as]; |
2 |
26 Feb 07 |
jari |
180 |
while(o<eox && i<as) { |
2 |
26 Feb 07 |
jari |
181 |
d[i]=new RBool(buf[o]); |
2 |
26 Feb 07 |
jari |
182 |
i++; o++; |
2 |
26 Feb 07 |
jari |
183 |
} |
2 |
26 Feb 07 |
jari |
// skip the padding |
2 |
26 Feb 07 |
jari |
185 |
while ((i&3)!=0) { i++; o++; }; |
2 |
26 Feb 07 |
jari |
186 |
x.cont=d; |
2 |
26 Feb 07 |
jari |
187 |
return o; |
2 |
26 Feb 07 |
jari |
188 |
}; |
2 |
26 Feb 07 |
jari |
189 |
if (xt==XT_INT) { |
2 |
26 Feb 07 |
jari |
190 |
x.cont=new Integer(Rtalk.getInt(buf,o)); |
2 |
26 Feb 07 |
jari |
191 |
o+=4; |
2 |
26 Feb 07 |
jari |
192 |
if (o!=eox) { |
2 |
26 Feb 07 |
jari |
193 |
System.out.println("Warning: int SEXP size mismatch\n"); |
2 |
26 Feb 07 |
jari |
194 |
o=eox; |
2 |
26 Feb 07 |
jari |
195 |
}; |
2 |
26 Feb 07 |
jari |
196 |
return o; |
2 |
26 Feb 07 |
jari |
197 |
} |
2 |
26 Feb 07 |
jari |
198 |
if (xt==XT_ARRAY_INT) { |
2 |
26 Feb 07 |
jari |
199 |
int as=(eox-o)/4,i=0; |
2 |
26 Feb 07 |
jari |
200 |
int[] d=new int[as]; |
2 |
26 Feb 07 |
jari |
201 |
while (o<eox) { |
2 |
26 Feb 07 |
jari |
202 |
d[i]=Rtalk.getInt(buf,o); |
2 |
26 Feb 07 |
jari |
203 |
o+=4; |
2 |
26 Feb 07 |
jari |
204 |
i++; |
2 |
26 Feb 07 |
jari |
205 |
}; |
2 |
26 Feb 07 |
jari |
206 |
if (o!=eox) { |
2 |
26 Feb 07 |
jari |
207 |
System.out.println("Warning: int array SEXP size mismatch\n"); |
2 |
26 Feb 07 |
jari |
208 |
o=eox; |
2 |
26 Feb 07 |
jari |
209 |
}; |
2 |
26 Feb 07 |
jari |
210 |
x.cont=d; |
2 |
26 Feb 07 |
jari |
// hack for lists - special lists attached to int are factors |
2 |
26 Feb 07 |
jari |
212 |
if (x.attr!=null && x.attr.Xt==XT_LIST && x.attr.cont!=null && |
2 |
26 Feb 07 |
jari |
213 |
((RList)x.attr.cont).head!=null && |
2 |
26 Feb 07 |
jari |
214 |
((RList)x.attr.cont).body!=null && |
2 |
26 Feb 07 |
jari |
215 |
((RList)x.attr.cont).head.cont!=null && |
2 |
26 Feb 07 |
jari |
216 |
((RList)x.attr.cont).body.cont!=null && |
2 |
26 Feb 07 |
jari |
217 |
((RList)x.attr.cont).head.Xt==XT_VECTOR && |
2 |
26 Feb 07 |
jari |
218 |
((RList)x.attr.cont).body.Xt==XT_LIST && |
2 |
26 Feb 07 |
jari |
219 |
((RList)((RList)x.attr.cont).body.cont).head!=null && |
2 |
26 Feb 07 |
jari |
220 |
((RList)((RList)x.attr.cont).body.cont).head.Xt==XT_STR && |
2 |
26 Feb 07 |
jari |
221 |
((String)((RList)((RList)x.attr.cont).body.cont).head.cont).compareTo("factor")==0) { |
2 |
26 Feb 07 |
jari |
222 |
RFactor f=new RFactor(d,(Vector)((RList)x.attr.cont).head.cont); |
2 |
26 Feb 07 |
jari |
223 |
x.cont=f; |
2 |
26 Feb 07 |
jari |
224 |
x.Xt=XT_FACTOR; |
2 |
26 Feb 07 |
jari |
225 |
x.attr=null; |
2 |
26 Feb 07 |
jari |
226 |
}; |
2 |
26 Feb 07 |
jari |
227 |
return o; |
2 |
26 Feb 07 |
jari |
228 |
}; |
2 |
26 Feb 07 |
jari |
229 |
if (xt==XT_VECTOR) { |
2 |
26 Feb 07 |
jari |
230 |
Vector v=new Vector(); |
2 |
26 Feb 07 |
jari |
231 |
while(o<eox) { |
2 |
26 Feb 07 |
jari |
232 |
REXP xx=new REXP(); |
2 |
26 Feb 07 |
jari |
233 |
o=parseREXP(xx,buf,o); |
2 |
26 Feb 07 |
jari |
234 |
v.addElement(xx); |
2 |
26 Feb 07 |
jari |
235 |
}; |
2 |
26 Feb 07 |
jari |
236 |
if (o!=eox) { |
2 |
26 Feb 07 |
jari |
237 |
System.out.println("Warning: int vector SEXP size mismatch\n"); |
2 |
26 Feb 07 |
jari |
238 |
o=eox; |
2 |
26 Feb 07 |
jari |
239 |
}; |
2 |
26 Feb 07 |
jari |
240 |
x.cont=v; |
2 |
26 Feb 07 |
jari |
// fixup for lists since they're stored as attributes of vectors |
2 |
26 Feb 07 |
jari |
242 |
if (x.attr!=null && x.attr.Xt==XT_LIST && x.attr.cont!=null) { |
2 |
26 Feb 07 |
jari |
243 |
RList l=new RList(); |
2 |
26 Feb 07 |
jari |
244 |
l.head=((RList)x.attr.cont).head; |
2 |
26 Feb 07 |
jari |
245 |
l.body=new REXP(XT_VECTOR,v); |
2 |
26 Feb 07 |
jari |
246 |
x.cont=l; |
2 |
26 Feb 07 |
jari |
247 |
x.Xt=XT_LIST; x.attr=x.attr.attr; |
2 |
26 Feb 07 |
jari |
// one more hack: we're de-vectorizing strings if alone |
2 |
26 Feb 07 |
jari |
// so we should invert that in case of list heads |
2 |
26 Feb 07 |
jari |
250 |
if (l.head.Xt==XT_STR) { |
2 |
26 Feb 07 |
jari |
251 |
Vector sv=new Vector(); |
2 |
26 Feb 07 |
jari |
252 |
sv.addElement(l.head); |
2 |
26 Feb 07 |
jari |
253 |
l.head=new REXP(XT_VECTOR,sv,l.head.attr); |
2 |
26 Feb 07 |
jari |
254 |
l.head.attr=null; |
2 |
26 Feb 07 |
jari |
255 |
}; |
2 |
26 Feb 07 |
jari |
256 |
}; |
2 |
26 Feb 07 |
jari |
257 |
return o; |
2 |
26 Feb 07 |
jari |
258 |
}; |
2 |
26 Feb 07 |
jari |
259 |
if (xt==XT_STR) { |
2 |
26 Feb 07 |
jari |
260 |
int i=o; |
2 |
26 Feb 07 |
jari |
261 |
while (buf[i]!=0 && i<eox) i++; |
2 |
26 Feb 07 |
jari |
262 |
try { |
2 |
26 Feb 07 |
jari |
263 |
x.cont=new String(buf,o,i-o,Rconnection.transferCharset); |
2 |
26 Feb 07 |
jari |
264 |
} catch(Exception e) { |
2 |
26 Feb 07 |
jari |
265 |
System.out.println("unable to convert string\n"); |
2 |
26 Feb 07 |
jari |
266 |
x.cont=null; |
2 |
26 Feb 07 |
jari |
267 |
}; |
2 |
26 Feb 07 |
jari |
268 |
o=eox; |
2 |
26 Feb 07 |
jari |
269 |
return o; |
2 |
26 Feb 07 |
jari |
270 |
}; |
2 |
26 Feb 07 |
jari |
271 |
if (xt==XT_LIST || xt==XT_LANG) { |
2 |
26 Feb 07 |
jari |
272 |
RList rl=new RList(); |
2 |
26 Feb 07 |
jari |
273 |
rl.head=new REXP(); |
2 |
26 Feb 07 |
jari |
274 |
rl.body=new REXP(); |
2 |
26 Feb 07 |
jari |
275 |
rl.tag=null; |
2 |
26 Feb 07 |
jari |
276 |
o=parseREXP(rl.head,buf,o); // CAR |
2 |
26 Feb 07 |
jari |
277 |
o=parseREXP(rl.body,buf,o); // CDR |
2 |
26 Feb 07 |
jari |
278 |
if (o!=eox) { |
2 |
26 Feb 07 |
jari |
// if there is more data then it's presumably the TAG entry |
2 |
26 Feb 07 |
jari |
280 |
rl.tag=new REXP(); |
2 |
26 Feb 07 |
jari |
281 |
o=parseREXP(rl.tag,buf,o); |
2 |
26 Feb 07 |
jari |
282 |
if (o!=eox) { |
2 |
26 Feb 07 |
jari |
283 |
System.out.println("Warning: list SEXP size mismatch\n"); |
2 |
26 Feb 07 |
jari |
284 |
o=eox; |
2 |
26 Feb 07 |
jari |
285 |
} |
2 |
26 Feb 07 |
jari |
286 |
}; |
2 |
26 Feb 07 |
jari |
287 |
x.cont=rl; |
2 |
26 Feb 07 |
jari |
288 |
return o; |
2 |
26 Feb 07 |
jari |
289 |
}; |
2 |
26 Feb 07 |
jari |
290 |
|
2 |
26 Feb 07 |
jari |
291 |
if (xt==XT_SYM) { |
2 |
26 Feb 07 |
jari |
292 |
REXP sym=new REXP(); |
2 |
26 Feb 07 |
jari |
293 |
o=parseREXP(sym,buf,o); // PRINTNAME that's all we will use |
2 |
26 Feb 07 |
jari |
294 |
String s=null; |
2 |
26 Feb 07 |
jari |
295 |
if (sym.Xt==XT_STR) s=(String)sym.cont; else s=sym.toString(); |
2 |
26 Feb 07 |
jari |
296 |
x.cont=s; // content of a symbol is its printname string (so far) |
2 |
26 Feb 07 |
jari |
297 |
o=eox; |
2 |
26 Feb 07 |
jari |
298 |
return o; |
2 |
26 Feb 07 |
jari |
299 |
} |
2 |
26 Feb 07 |
jari |
300 |
|
2 |
26 Feb 07 |
jari |
301 |
if (xt==XT_CLOS) { |
2 |
26 Feb 07 |
jari |
302 |
REXP form=new REXP(); |
2 |
26 Feb 07 |
jari |
303 |
REXP body=new REXP(); |
2 |
26 Feb 07 |
jari |
304 |
o=parseREXP(form,buf,o); |
2 |
26 Feb 07 |
jari |
305 |
o=parseREXP(body,buf,o); |
2 |
26 Feb 07 |
jari |
306 |
if (o!=eox) { |
2 |
26 Feb 07 |
jari |
307 |
System.out.println("Warning: closure SEXP size mismatch\n"); |
2 |
26 Feb 07 |
jari |
308 |
o=eox; |
2 |
26 Feb 07 |
jari |
309 |
} |
2 |
26 Feb 07 |
jari |
/* curently closures are not coded into their own objects, basically due to lack of demand. */ |
2 |
26 Feb 07 |
jari |
311 |
x.cont=body; |
2 |
26 Feb 07 |
jari |
312 |
return o; |
2 |
26 Feb 07 |
jari |
313 |
} |
2 |
26 Feb 07 |
jari |
314 |
|
2 |
26 Feb 07 |
jari |
315 |
if (xt==XT_UNKNOWN) { |
2 |
26 Feb 07 |
jari |
316 |
x.cont=new Integer(Rtalk.getInt(buf,o)); |
2 |
26 Feb 07 |
jari |
317 |
o=eox; |
2 |
26 Feb 07 |
jari |
318 |
return o; |
2 |
26 Feb 07 |
jari |
319 |
} |
2 |
26 Feb 07 |
jari |
320 |
|
2 |
26 Feb 07 |
jari |
321 |
x.cont=null; |
2 |
26 Feb 07 |
jari |
322 |
o=eox; |
2 |
26 Feb 07 |
jari |
323 |
System.out.println("unhandled type: "+xt); |
2 |
26 Feb 07 |
jari |
324 |
return o; |
2 |
26 Feb 07 |
jari |
325 |
} |
2 |
26 Feb 07 |
jari |
326 |
|
2 |
26 Feb 07 |
jari |
/** Calculates the length of the binary representation of the REXP including all headers. This is the amount of memory necessary to store the REXP via {@link #getBinaryRepresentation}. |
2 |
26 Feb 07 |
jari |
<p>Please note that currently only XT_[ARRAY_]INT, XT_[ARRAY_]DOUBLE and XT_[ARRAY_]STR are supported! All other types will return 4 which is the size of the header. |
2 |
26 Feb 07 |
jari |
@return length of the REXP including headers (4 or 8 bytes)*/ |
2 |
26 Feb 07 |
jari |
330 |
public int getBinaryLength() { |
2 |
26 Feb 07 |
jari |
331 |
int l=0; |
2 |
26 Feb 07 |
jari |
332 |
switch (Xt) { |
2 |
26 Feb 07 |
jari |
333 |
case XT_INT: l=4; break; |
2 |
26 Feb 07 |
jari |
334 |
case XT_DOUBLE: l=8; break; |
2 |
26 Feb 07 |
jari |
335 |
case XT_STR: l=(cont==null)?1:((String)cont).length()+1; break; |
2 |
26 Feb 07 |
jari |
336 |
case XT_ARRAY_INT: l=(cont==null)?0:((int[])cont).length*4; break; |
2 |
26 Feb 07 |
jari |
337 |
case XT_ARRAY_DOUBLE: l=(cont==null)?0:((double[])cont).length*8; break; |
2 |
26 Feb 07 |
jari |
338 |
case XT_ARRAY_STR: |
2 |
26 Feb 07 |
jari |
339 |
if (cachedBinaryLength<0) { // if there's no cache, we have to count.. |
2 |
26 Feb 07 |
jari |
340 |
if (cont==null) cachedBinaryLength=4; else { |
2 |
26 Feb 07 |
jari |
341 |
String sa[]=(String[])cont; |
2 |
26 Feb 07 |
jari |
342 |
int i=0, io=0; |
2 |
26 Feb 07 |
jari |
343 |
while (i<sa.length) { |
2 |
26 Feb 07 |
jari |
344 |
if (sa[i]!=null) { |
2 |
26 Feb 07 |
jari |
345 |
try { |
2 |
26 Feb 07 |
jari |
346 |
byte b[]=sa[i].getBytes(Rconnection.transferCharset); |
2 |
26 Feb 07 |
jari |
347 |
io+=b.length; |
2 |
26 Feb 07 |
jari |
348 |
b=null; |
2 |
26 Feb 07 |
jari |
349 |
} catch (java.io.UnsupportedEncodingException uex) { |
2 |
26 Feb 07 |
jari |
// FIXME: we should so something ... so far we hope noone's gonna mess with the encoding |
2 |
26 Feb 07 |
jari |
351 |
} |
2 |
26 Feb 07 |
jari |
352 |
} |
2 |
26 Feb 07 |
jari |
353 |
io++; |
2 |
26 Feb 07 |
jari |
354 |
i++; |
2 |
26 Feb 07 |
jari |
355 |
} |
2 |
26 Feb 07 |
jari |
356 |
while ((io&3)!=0) io++; |
2 |
26 Feb 07 |
jari |
357 |
cachedBinaryLength=io+4; |
2 |
26 Feb 07 |
jari |
358 |
if (cachedBinaryLength>0xfffff0) |
2 |
26 Feb 07 |
jari |
359 |
cachedBinaryLength+=4; |
2 |
26 Feb 07 |
jari |
360 |
} |
2 |
26 Feb 07 |
jari |
361 |
} |
2 |
26 Feb 07 |
jari |
362 |
return (int)cachedBinaryLength; |
2 |
26 Feb 07 |
jari |
363 |
} // switch |
2 |
26 Feb 07 |
jari |
364 |
if (l>0xfffff0) l+=4; // large data need 4 more bytes |
2 |
26 Feb 07 |
jari |
365 |
return l+4; |
2 |
26 Feb 07 |
jari |
366 |
} |
2 |
26 Feb 07 |
jari |
367 |
|
2 |
26 Feb 07 |
jari |
/** Stores the REXP in its binary (ready-to-send) representation including header into a buffer and returns the index of the byte behind the REXP. |
2 |
26 Feb 07 |
jari |
<p>Please note that currently only XT_[ARRAY_]INT, XT_[ARRAY_]DOUBLE and XT_[ARRAY_]STR are supported! All other types will be stored as SEXP of the length 0 without any contents. |
2 |
26 Feb 07 |
jari |
@param buf buffer to store the REXP binary into |
2 |
26 Feb 07 |
jari |
@param off offset of the first byte where to store the REXP |
2 |
26 Feb 07 |
jari |
@return the offset of the first byte behind the stored REXP */ |
2 |
26 Feb 07 |
jari |
373 |
public int getBinaryRepresentation(byte[] buf, int off) { |
2 |
26 Feb 07 |
jari |
374 |
int myl=getBinaryLength(); |
2 |
26 Feb 07 |
jari |
375 |
boolean isLarge=(myl>0xfffff0); |
2 |
26 Feb 07 |
jari |
376 |
Rtalk.setHdr(Xt,myl-(isLarge?8:4),buf,off); |
2 |
26 Feb 07 |
jari |
377 |
off+=(isLarge?8:4); |
2 |
26 Feb 07 |
jari |
378 |
switch (Xt) { |
2 |
26 Feb 07 |
jari |
379 |
case XT_INT: Rtalk.setInt(asInt(),buf,off); break; |
2 |
26 Feb 07 |
jari |
380 |
case XT_DOUBLE: Rtalk.setLong(Double.doubleToLongBits(asDouble()),buf,off); break; |
2 |
26 Feb 07 |
jari |
381 |
case XT_ARRAY_INT: |
2 |
26 Feb 07 |
jari |
382 |
if (cont!=null) { |
2 |
26 Feb 07 |
jari |
383 |
int ia[]=(int[])cont; |
2 |
26 Feb 07 |
jari |
384 |
int i=0, io=off; |
2 |
26 Feb 07 |
jari |
385 |
while(i<ia.length) { |
2 |
26 Feb 07 |
jari |
386 |
Rtalk.setInt(ia[i++],buf,io); io+=4; |
2 |
26 Feb 07 |
jari |
387 |
} |
2 |
26 Feb 07 |
jari |
388 |
} |
2 |
26 Feb 07 |
jari |
389 |
break; |
2 |
26 Feb 07 |
jari |
390 |
case XT_ARRAY_DOUBLE: |
2 |
26 Feb 07 |
jari |
391 |
if (cont!=null) { |
2 |
26 Feb 07 |
jari |
392 |
double da[]=(double[])cont; |
2 |
26 Feb 07 |
jari |
393 |
int i=0, io=off; |
2 |
26 Feb 07 |
jari |
394 |
while(i<da.length) { |
2 |
26 Feb 07 |
jari |
395 |
Rtalk.setLong(Double.doubleToLongBits(da[i++]),buf,io); io+=8; |
2 |
26 Feb 07 |
jari |
396 |
} |
2 |
26 Feb 07 |
jari |
397 |
} |
2 |
26 Feb 07 |
jari |
398 |
break; |
2 |
26 Feb 07 |
jari |
399 |
case XT_ARRAY_STR: |
2 |
26 Feb 07 |
jari |
400 |
if (cont!=null) { |
2 |
26 Feb 07 |
jari |
401 |
String sa[]=(String[])cont; |
2 |
26 Feb 07 |
jari |
402 |
int i=0, io=off; |
2 |
26 Feb 07 |
jari |
403 |
while (i<sa.length) { |
2 |
26 Feb 07 |
jari |
404 |
if (sa[i]!=null) { |
2 |
26 Feb 07 |
jari |
405 |
try { |
2 |
26 Feb 07 |
jari |
406 |
byte b[]=sa[i].getBytes(Rconnection.transferCharset); |
2 |
26 Feb 07 |
jari |
407 |
System.arraycopy(b,0,buf,io,b.length); |
2 |
26 Feb 07 |
jari |
408 |
io+=b.length; |
2 |
26 Feb 07 |
jari |
409 |
b=null; |
2 |
26 Feb 07 |
jari |
410 |
} catch (java.io.UnsupportedEncodingException uex) { |
2 |
26 Feb 07 |
jari |
// FIXME: we should so something ... so far we hope noone's gonna mess with the encoding |
2 |
26 Feb 07 |
jari |
412 |
} |
2 |
26 Feb 07 |
jari |
413 |
} |
2 |
26 Feb 07 |
jari |
414 |
buf[io++]=0; |
2 |
26 Feb 07 |
jari |
415 |
i++; |
2 |
26 Feb 07 |
jari |
416 |
} |
2 |
26 Feb 07 |
jari |
417 |
i=io-off; |
2 |
26 Feb 07 |
jari |
418 |
while ((i&3)!=0) { buf[io++]=1; i++; } // padding if necessary.. |
2 |
26 Feb 07 |
jari |
419 |
} |
2 |
26 Feb 07 |
jari |
420 |
} |
2 |
26 Feb 07 |
jari |
421 |
return off+myl; |
2 |
26 Feb 07 |
jari |
422 |
} |
2 |
26 Feb 07 |
jari |
423 |
|
2 |
26 Feb 07 |
jari |
/** returns human-readable name of the xpression type as string. Arrays are denoted by a trailing asterisk (*). |
2 |
26 Feb 07 |
jari |
@param xt xpression type |
2 |
26 Feb 07 |
jari |
@return name of the xpression type */ |
2 |
26 Feb 07 |
jari |
427 |
public static String xtName(int xt) { |
2 |
26 Feb 07 |
jari |
428 |
if (xt==XT_NULL) return "NULL"; |
2 |
26 Feb 07 |
jari |
429 |
if (xt==XT_INT) return "INT"; |
2 |
26 Feb 07 |
jari |
430 |
if (xt==XT_STR) return "STRING"; |
2 |
26 Feb 07 |
jari |
431 |
if (xt==XT_DOUBLE) return "REAL"; |
2 |
26 Feb 07 |
jari |
432 |
if (xt==XT_BOOL) return "BOOL"; |
2 |
26 Feb 07 |
jari |
433 |
if (xt==XT_ARRAY_INT) return "INT*"; |
2 |
26 Feb 07 |
jari |
434 |
if (xt==XT_ARRAY_STR) return "STRING*"; |
2 |
26 Feb 07 |
jari |
435 |
if (xt==XT_ARRAY_DOUBLE) return "REAL*"; |
2 |
26 Feb 07 |
jari |
436 |
if (xt==XT_ARRAY_BOOL) return "BOOL*"; |
2 |
26 Feb 07 |
jari |
437 |
if (xt==XT_SYM) return "SYMBOL"; |
2 |
26 Feb 07 |
jari |
438 |
if (xt==XT_LANG) return "LANG"; |
2 |
26 Feb 07 |
jari |
439 |
if (xt==XT_LIST) return "LIST"; |
2 |
26 Feb 07 |
jari |
440 |
if (xt==XT_CLOS) return "CLOS"; |
2 |
26 Feb 07 |
jari |
441 |
if (xt==XT_VECTOR) return "VECTOR"; |
2 |
26 Feb 07 |
jari |
442 |
if (xt==XT_FACTOR) return "FACTOR"; |
2 |
26 Feb 07 |
jari |
443 |
if (xt==XT_UNKNOWN) return "UNKNOWN"; |
2 |
26 Feb 07 |
jari |
444 |
return "<unknown "+xt+">"; |
2 |
26 Feb 07 |
jari |
445 |
} |
2 |
26 Feb 07 |
jari |
446 |
|
2 |
26 Feb 07 |
jari |
/** get content of the REXP as string (if it is one) |
2 |
26 Feb 07 |
jari |
@return string content or <code>null</code> if the REXP is no string */ |
2 |
26 Feb 07 |
jari |
449 |
public String asString() { |
2 |
26 Feb 07 |
jari |
450 |
return (Xt==XT_STR)?(String)cont:null; |
2 |
26 Feb 07 |
jari |
451 |
} |
2 |
26 Feb 07 |
jari |
452 |
|
2 |
26 Feb 07 |
jari |
/** get content of the REXP as int (if it is one) |
2 |
26 Feb 07 |
jari |
@return int content or 0 if the REXP is no integer */ |
2 |
26 Feb 07 |
jari |
455 |
public int asInt() { |
2 |
26 Feb 07 |
jari |
456 |
if (Xt==XT_ARRAY_INT) { |
2 |
26 Feb 07 |
jari |
457 |
int i[]=(int[])cont; |
2 |
26 Feb 07 |
jari |
458 |
if (i!=null && i.length>0) return i[0]; |
2 |
26 Feb 07 |
jari |
459 |
} |
2 |
26 Feb 07 |
jari |
460 |
return (Xt==XT_INT)?((Integer)cont).intValue():0; |
2 |
26 Feb 07 |
jari |
461 |
} |
2 |
26 Feb 07 |
jari |
462 |
|
2 |
26 Feb 07 |
jari |
/** get content of the REXP as double (if it is one) |
2 |
26 Feb 07 |
jari |
@return double content or 0.0 if the REXP is no double */ |
2 |
26 Feb 07 |
jari |
465 |
public double asDouble() { |
2 |
26 Feb 07 |
jari |
466 |
if (Xt==XT_ARRAY_DOUBLE) { |
2 |
26 Feb 07 |
jari |
467 |
double d[]=(double[])cont; |
2 |
26 Feb 07 |
jari |
468 |
if (d!=null && d.length>0) return d[0]; |
2 |
26 Feb 07 |
jari |
469 |
} |
2 |
26 Feb 07 |
jari |
470 |
return (Xt==XT_DOUBLE)?((Double)cont).doubleValue():0.0; |
2 |
26 Feb 07 |
jari |
471 |
} |
2 |
26 Feb 07 |
jari |
472 |
|
2 |
26 Feb 07 |
jari |
/** get content of the REXP as {@link Vector} (if it is one) |
2 |
26 Feb 07 |
jari |
@return Vector content or <code>null</code> if the REXP is no Vector */ |
2 |
26 Feb 07 |
jari |
475 |
public Vector asVector() { |
2 |
26 Feb 07 |
jari |
476 |
return (Xt==XT_VECTOR)?(Vector)cont:null; |
2 |
26 Feb 07 |
jari |
477 |
} |
2 |
26 Feb 07 |
jari |
478 |
|
2 |
26 Feb 07 |
jari |
/** get content of the REXP as {@link RFactor} (if it is one) |
2 |
26 Feb 07 |
jari |
@return {@link RFactor} content or <code>null</code> if the REXP is no factor */ |
2 |
26 Feb 07 |
jari |
481 |
public RFactor asFactor() { |
2 |
26 Feb 07 |
jari |
482 |
return (Xt==XT_FACTOR)?(RFactor)cont:null; |
2 |
26 Feb 07 |
jari |
483 |
} |
2 |
26 Feb 07 |
jari |
484 |
|
2 |
26 Feb 07 |
jari |
/** get content of the REXP as {@link RList} (if it is one) |
2 |
26 Feb 07 |
jari |
@return {@link RList} content or <code>null</code> if the REXP is no list */ |
2 |
26 Feb 07 |
jari |
487 |
public RList asList() { |
2 |
26 Feb 07 |
jari |
488 |
return (Xt==XT_LIST)?(RList)cont:null; |
2 |
26 Feb 07 |
jari |
489 |
} |
2 |
26 Feb 07 |
jari |
490 |
|
2 |
26 Feb 07 |
jari |
/** get content of the REXP as {@link RBool} (if it is one) |
2 |
26 Feb 07 |
jari |
@return {@link RBool} content or <code>null</code> if the REXP is no logical value */ |
2 |
26 Feb 07 |
jari |
493 |
public RBool asBool() { |
2 |
26 Feb 07 |
jari |
494 |
return (Xt==XT_BOOL)?(RBool)cont:null; |
2 |
26 Feb 07 |
jari |
495 |
} |
2 |
26 Feb 07 |
jari |
496 |
|
2 |
26 Feb 07 |
jari |
/** get content of the REXP as an array of doubles. Array of integers, single double and single integer are automatically converted into such an array if necessary. |
2 |
26 Feb 07 |
jari |
@return double[] content or <code>null</code> if the REXP is not a array of doubles or integers */ |
2 |
26 Feb 07 |
jari |
499 |
public double[] asDoubleArray() { |
2 |
26 Feb 07 |
jari |
500 |
if (Xt==XT_ARRAY_DOUBLE) return (double[])cont; |
2 |
26 Feb 07 |
jari |
501 |
if (Xt==XT_DOUBLE) { |
2 |
26 Feb 07 |
jari |
502 |
double[] d=new double[1]; d[0]=asDouble(); return d; |
2 |
26 Feb 07 |
jari |
503 |
} |
2 |
26 Feb 07 |
jari |
504 |
if (Xt==XT_INT) { |
2 |
26 Feb 07 |
jari |
505 |
double[] d=new double[1]; d[0]=((Integer)cont).doubleValue(); return d; |
2 |
26 Feb 07 |
jari |
506 |
} |
2 |
26 Feb 07 |
jari |
507 |
if (Xt==XT_ARRAY_INT) { |
2 |
26 Feb 07 |
jari |
508 |
int[] i=asIntArray(); |
2 |
26 Feb 07 |
jari |
509 |
if (i==null) return null; |
2 |
26 Feb 07 |
jari |
510 |
double[] d=new double[i.length]; |
2 |
26 Feb 07 |
jari |
511 |
int j=0; |
2 |
26 Feb 07 |
jari |
512 |
while (j<i.length) { |
2 |
26 Feb 07 |
jari |
513 |
d[j]=(double)i[j]; j++; |
2 |
26 Feb 07 |
jari |
514 |
} |
2 |
26 Feb 07 |
jari |
515 |
return d; |
2 |
26 Feb 07 |
jari |
516 |
} |
2 |
26 Feb 07 |
jari |
517 |
return null; |
2 |
26 Feb 07 |
jari |
518 |
} |
2 |
26 Feb 07 |
jari |
519 |
|
2 |
26 Feb 07 |
jari |
/** get content of the REXP as an array of integers. Unlike {@link #asDoubleArray} <u>NO</u> automatic conversion is done if the content is not an array of the correct type, because there is no canonical representation of doubles as integers. A single integer is returned as an array of the length 1. |
2 |
26 Feb 07 |
jari |
@return double[] content or <code>null</code> if the REXP is not a array of integers */ |
2 |
26 Feb 07 |
jari |
522 |
public int[] asIntArray() { |
2 |
26 Feb 07 |
jari |
523 |
if (Xt==XT_ARRAY_INT) return (int[])cont; |
2 |
26 Feb 07 |
jari |
524 |
if (Xt==XT_INT) { |
2 |
26 Feb 07 |
jari |
525 |
int[] i=new int[1]; i[0]=asInt(); return i; |
2 |
26 Feb 07 |
jari |
526 |
} |
2 |
26 Feb 07 |
jari |
527 |
return null; |
2 |
26 Feb 07 |
jari |
528 |
} |
2 |
26 Feb 07 |
jari |
529 |
|
2 |
26 Feb 07 |
jari |
/** returns the content of the REXP as a matrix of doubles (2D-array: m[rows][cols]). This is the same form as used by popular math packages for Java, such as JAMA. This means that following leads to desired results:<br> |
2 |
26 Feb 07 |
jari |
<code>Matrix m=new Matrix(c.eval("matrix(c(1,2,3,4,5,6),2,3)").asDoubleMatrix());</code> |
2 |
26 Feb 07 |
jari |
@return 2D array of doubles in the form double[rows][cols] or <code>null</code> if the contents is no 2-dimensional matrix of doubles */ |
2 |
26 Feb 07 |
jari |
533 |
public double[][] asDoubleMatrix() { |
2 |
26 Feb 07 |
jari |
534 |
if (Xt!=XT_ARRAY_DOUBLE || attr==null || attr.Xt!=XT_LIST) return null; |
2 |
26 Feb 07 |
jari |
535 |
REXP dim=attr.asList().getHead(); |
2 |
26 Feb 07 |
jari |
536 |
if (dim==null || dim.Xt!=XT_ARRAY_INT) return null; // we need dimension attr |
2 |
26 Feb 07 |
jari |
537 |
int[] ds=dim.asIntArray(); |
2 |
26 Feb 07 |
jari |
538 |
if (ds==null || ds.length!=2) return null; // matrix must be 2-dimensional |
2 |
26 Feb 07 |
jari |
539 |
int m=ds[0], n=ds[1]; |
2 |
26 Feb 07 |
jari |
540 |
double[][] r=new double[m][n]; |
2 |
26 Feb 07 |
jari |
541 |
double[] ct=asDoubleArray(); |
2 |
26 Feb 07 |
jari |
542 |
if (ct==null) return null; |
2 |
26 Feb 07 |
jari |
// R stores matrices as matrix(c(1,2,3,4),2,2) = col1:(1,2), col2:(3,4) |
2 |
26 Feb 07 |
jari |
// we need to copy everything, since we create 2d array from 1d array |
2 |
26 Feb 07 |
jari |
545 |
int i=0,k=0; |
2 |
26 Feb 07 |
jari |
546 |
while (i<n) { |
2 |
26 Feb 07 |
jari |
547 |
int j=0; |
2 |
26 Feb 07 |
jari |
548 |
while (j<m) { |
2 |
26 Feb 07 |
jari |
549 |
r[j++][i]=ct[k++]; |
2 |
26 Feb 07 |
jari |
550 |
} |
2 |
26 Feb 07 |
jari |
551 |
i++; |
2 |
26 Feb 07 |
jari |
552 |
} |
2 |
26 Feb 07 |
jari |
553 |
return r; |
2 |
26 Feb 07 |
jari |
554 |
} |
2 |
26 Feb 07 |
jari |
555 |
|
2 |
26 Feb 07 |
jari |
/** this is just an alias for {@link #asDoubleMatrix()}. */ |
2 |
26 Feb 07 |
jari |
557 |
public double[][] asMatrix() { |
2 |
26 Feb 07 |
jari |
558 |
return asDoubleMatrix(); |
2 |
26 Feb 07 |
jari |
559 |
} |
2 |
26 Feb 07 |
jari |
560 |
|
2 |
26 Feb 07 |
jari |
/** displayable contents of the expression. The expression is traversed recursively if aggregation types are used (Vector, List, etc.) |
2 |
26 Feb 07 |
jari |
@return String descriptive representation of the xpression */ |
2 |
26 Feb 07 |
jari |
563 |
public String toString() { |
2 |
26 Feb 07 |
jari |
564 |
StringBuffer sb= |
2 |
26 Feb 07 |
jari |
565 |
new StringBuffer("["+xtName(Xt)+" "); |
2 |
26 Feb 07 |
jari |
566 |
if (attr!=null) sb.append("\nattr="+attr+"\n "); |
2 |
26 Feb 07 |
jari |
567 |
if (Xt==XT_DOUBLE) sb.append((Double)cont); |
2 |
26 Feb 07 |
jari |
568 |
if (Xt==XT_INT) sb.append((Integer)cont); |
2 |
26 Feb 07 |
jari |
569 |
if (Xt==XT_BOOL) sb.append((RBool)cont); |
2 |
26 Feb 07 |
jari |
570 |
if (Xt==XT_FACTOR) sb.append((RFactor)cont); |
2 |
26 Feb 07 |
jari |
571 |
if (Xt==XT_ARRAY_DOUBLE) { |
2 |
26 Feb 07 |
jari |
572 |
double[] d=(double[])cont; |
2 |
26 Feb 07 |
jari |
573 |
sb.append("("); |
2 |
26 Feb 07 |
jari |
574 |
for(int i=0; i<d.length; i++) { |
2 |
26 Feb 07 |
jari |
575 |
sb.append(d[i]); |
2 |
26 Feb 07 |
jari |
576 |
if (i<d.length-1) sb.append(", "); |
2 |
26 Feb 07 |
jari |
577 |
if (i==99) { |
2 |
26 Feb 07 |
jari |
578 |
sb.append("... ("+(d.length-100)+" more values follow)"); |
2 |
26 Feb 07 |
jari |
579 |
break; |
2 |
26 Feb 07 |
jari |
580 |
} |
2 |
26 Feb 07 |
jari |
581 |
}; |
2 |
26 Feb 07 |
jari |
582 |
sb.append(")"); |
2 |
26 Feb 07 |
jari |
583 |
}; |
2 |
26 Feb 07 |
jari |
584 |
if (Xt==XT_ARRAY_INT) { |
2 |
26 Feb 07 |
jari |
585 |
int[] d=(int[])cont; |
2 |
26 Feb 07 |
jari |
586 |
sb.append("("); |
2 |
26 Feb 07 |
jari |
587 |
for(int i=0; i<d.length; i++) { |
2 |
26 Feb 07 |
jari |
588 |
sb.append(d[i]); |
2 |
26 Feb 07 |
jari |
589 |
if (i<d.length-1) sb.append(", "); |
2 |
26 Feb 07 |
jari |
590 |
if (i==99) { |
2 |
26 Feb 07 |
jari |
591 |
sb.append("... ("+(d.length-100)+" more values follow)"); |
2 |
26 Feb 07 |
jari |
592 |
break; |
2 |
26 Feb 07 |
jari |
593 |
} |
2 |
26 Feb 07 |
jari |
594 |
}; |
2 |
26 Feb 07 |
jari |
595 |
sb.append(")"); |
2 |
26 Feb 07 |
jari |
596 |
}; |
2 |
26 Feb 07 |
jari |
597 |
if (Xt==XT_ARRAY_BOOL) { |
2 |
26 Feb 07 |
jari |
598 |
RBool[] d=(RBool[])cont; |
2 |
26 Feb 07 |
jari |
599 |
sb.append("("); |
2 |
26 Feb 07 |
jari |
600 |
for(int i=0; i<d.length; i++) { |
2 |
26 Feb 07 |
jari |
601 |
sb.append(d[i]); |
2 |
26 Feb 07 |
jari |
602 |
if (i<d.length-1) sb.append(", "); |
2 |
26 Feb 07 |
jari |
603 |
}; |
2 |
26 Feb 07 |
jari |
604 |
sb.append(")"); |
2 |
26 Feb 07 |
jari |
605 |
}; |
2 |
26 Feb 07 |
jari |
606 |
if (Xt==XT_VECTOR) { |
2 |
26 Feb 07 |
jari |
607 |
Vector v=(Vector)cont; |
2 |
26 Feb 07 |
jari |
608 |
sb.append("("); |
2 |
26 Feb 07 |
jari |
609 |
for(int i=0; i<v.size(); i++) { |
2 |
26 Feb 07 |
jari |
610 |
sb.append(((REXP)v.elementAt(i)).toString()); |
2 |
26 Feb 07 |
jari |
611 |
if (i<v.size()-1) sb.append(", "); |
2 |
26 Feb 07 |
jari |
612 |
}; |
2 |
26 Feb 07 |
jari |
613 |
sb.append(")"); |
2 |
26 Feb 07 |
jari |
614 |
}; |
2 |
26 Feb 07 |
jari |
615 |
if (Xt==XT_STR) { |
2 |
26 Feb 07 |
jari |
616 |
sb.append("\""); |
2 |
26 Feb 07 |
jari |
617 |
sb.append((String)cont); |
2 |
26 Feb 07 |
jari |
618 |
sb.append("\""); |
2 |
26 Feb 07 |
jari |
619 |
}; |
2 |
26 Feb 07 |
jari |
620 |
if (Xt==XT_SYM) { |
2 |
26 Feb 07 |
jari |
621 |
sb.append((String)cont); |
2 |
26 Feb 07 |
jari |
622 |
}; |
2 |
26 Feb 07 |
jari |
623 |
if (Xt==XT_LIST || Xt==XT_LANG) { |
2 |
26 Feb 07 |
jari |
624 |
RList l=(RList)cont; |
2 |
26 Feb 07 |
jari |
625 |
sb.append(l.head); sb.append(" <-> "); |
2 |
26 Feb 07 |
jari |
626 |
sb.append(l.body); |
2 |
26 Feb 07 |
jari |
627 |
}; |
2 |
26 Feb 07 |
jari |
628 |
if (Xt==XT_UNKNOWN) sb.append((Integer)cont); |
2 |
26 Feb 07 |
jari |
629 |
sb.append("]"); |
2 |
26 Feb 07 |
jari |
630 |
return sb.toString(); |
2 |
26 Feb 07 |
jari |
631 |
}; |
2 |
26 Feb 07 |
jari |
632 |
} |