PageRenderTime 58ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/FScriptFramework/ArrayRepDouble.m

https://github.com/DottedGecko/F-Script
Objective C | 1295 lines | 1024 code | 241 blank | 30 comment | 214 complexity | 6245d7ea06984c9d7d039af8dded6a49 MD5 | raw file
  1. /* ArrayRepDouble.m Copyright (c) 1998-2009 Philippe Mougin. */
  2. /* This software is open source. See the license. */
  3. #import "build_config.h"
  4. #import "BlockPrivate.h"
  5. #import "BlockRep.h"
  6. #import "BlockInspector.h"
  7. #import "ArrayRepDouble.h"
  8. #import <string.h> // memcpy()
  9. #import "ArrayPrivate.h"
  10. #import "FSNumber.h"
  11. #import "NumberPrivate.h"
  12. #import "FScriptFunctions.h"
  13. #import "FSBooleanPrivate.h"
  14. #import "ArrayRepId.h"
  15. #import "FSCompiler.h"
  16. #import "FSExecEngine.h"
  17. #import "ArrayRepBoolean.h"
  18. #import <math.h>
  19. #import "FSMiscTools.h"
  20. #ifndef MAX
  21. #define MAX(a, b) \
  22. ({typeof(a) _a = (a); typeof(b) _b = (b); \
  23. _a > _b ? _a : _b; })
  24. #endif
  25. #ifndef MIN
  26. #define MIN(a, b) \
  27. ({typeof(a) _a = (a); typeof(b) _b = (b); \
  28. _a < _b ? _a : _b; })
  29. #endif
  30. struct sort_elem
  31. {
  32. NSUInteger index;
  33. double item;
  34. };
  35. static int comp(const void *a,const void *b)
  36. {
  37. if ( ((struct sort_elem *)a)->item < ((struct sort_elem *)b)->item ) return -1;
  38. else if ( ((struct sort_elem *)b)->item < ((struct sort_elem *)a)->item ) return 1;
  39. else return 0;
  40. }
  41. @implementation ArrayRepDouble
  42. ////////////////////////////// USER METHODS SUPPORT /////////////////////////////
  43. /////////////////////////////////////////////////////////////////////////////////
  44. - (FSArray *) distinctId
  45. {
  46. ArrayRepDouble *copy = [self copy];
  47. FSArray *r = [FSArray arrayWithRep:copy];
  48. [copy release];
  49. return r;
  50. }
  51. - (id)operator_backslash:(FSBlock*)bl
  52. {
  53. NSUInteger i;
  54. id res;
  55. id args[3];
  56. if ([bl isCompact])
  57. {
  58. SEL selector = [bl selector];
  59. NSString *selectorStr = [bl selectorStr];
  60. FSMsgContext *msgContext = [bl msgContext];
  61. double acu = t[0];
  62. args[1] = (id)(selector ? selector : [FSCompiler selectorFromString:selectorStr]);
  63. if (selector == @selector(operator_plus:)) { for (i = 1 ; i < count; i++) acu += t[i] ; return [FSNumber numberWithDouble:acu]; }
  64. else if (selector == @selector(max:)) { for (i = 1 ; i < count; i++) acu = MAX(acu, t[i]); return [FSNumber numberWithDouble:acu]; }
  65. else if (selector == @selector(min:)) { for (i = 1 ; i < count; i++) acu = MIN(acu, t[i]); return [FSNumber numberWithDouble:acu]; }
  66. else
  67. {
  68. @try
  69. {
  70. args[0] = [[FSNumber alloc] initWithDouble:t[0]];
  71. for (i = 1; i < count; i++)
  72. {
  73. args[2] = [[FSNumber alloc] initWithDouble:t[i]];
  74. res = [sendMsg(args[0], selector, 3, args, nil, msgContext, nil) retain];
  75. [args[0] release];
  76. args[0] = res;
  77. [args[2] release];
  78. }
  79. }
  80. @catch (id exception)
  81. {
  82. [args[0] release];
  83. [args[2] release];
  84. @throw;
  85. }
  86. } // end if
  87. }
  88. else
  89. {
  90. BlockRep *blRep = [bl blockRep];
  91. @try
  92. {
  93. args[0] = [[FSNumber alloc] initWithDouble:t[0]];
  94. for (i = 1; i < count; i++)
  95. {
  96. args[2] = [[FSNumber alloc] initWithDouble:t[i]];
  97. res = [[blRep body_notCompact_valueArgs:args count:3 block:bl] retain];
  98. [args[0] release];
  99. args[0] = res;
  100. [args[2] release];
  101. }
  102. }
  103. @catch (id exception)
  104. {
  105. [args[0] release];
  106. [args[2] release];
  107. @throw;
  108. }
  109. }
  110. return [args[0] autorelease];
  111. }
  112. - (NSUInteger)indexOfObject:(id)anObject inRange:(NSRange)range identical:(BOOL)identical
  113. {
  114. if (identical || range.length == 0 || ![anObject isKindOfClass:NSNumberClass]) return NSNotFound;
  115. double val = [anObject doubleValue];
  116. NSUInteger i = range.location;
  117. NSUInteger end = (range.location + range.length - 1);
  118. while (i <= end && t[i] != val) i++;
  119. return (i > end) ? NSNotFound : i;
  120. }
  121. - (FSArray *)reverse
  122. {
  123. NSUInteger i,j;
  124. ArrayRepDouble *resRep;
  125. FSArray *r ;
  126. double *tab = malloc(sizeof(double) * count);
  127. for(i = count-1, j = 0; j < count; i--, j++) tab[j] = t[i];
  128. resRep = [[ArrayRepDouble alloc] initWithDoublesNoCopy:tab count:count];
  129. r = [FSArray arrayWithRep:resRep];
  130. [resRep release];
  131. return r;
  132. }
  133. - (FSArray *)replicateWithArray:(FSArray *)operand
  134. {
  135. NSUInteger i,j;
  136. ArrayRepDouble *resRep;
  137. assert(![operand isProxy]);
  138. resRep = [[[ArrayRepDouble alloc] init] autorelease];
  139. switch ([operand type])
  140. {
  141. case FS_ID:
  142. {
  143. id *indexData = [operand dataPtr];
  144. for (i=0; i < count; i++)
  145. {
  146. double opElemDouble;
  147. if (![indexData[i] isKindOfClass:NSNumberClass]) FSExecError(@"argument of method \"replicate:\" must be an array of numbers");
  148. opElemDouble = [(NSNumber *)(indexData[i]) doubleValue];
  149. if (opElemDouble < 0) FSExecError(@"argument of method \"replicate:\" must not contain negative numbers");
  150. if (opElemDouble > NSUIntegerMax)
  151. FSExecError([NSString stringWithFormat:@"argument of method \"replicate:\" must contain numbers less or equal to %lu",(unsigned long)NSUIntegerMax]);
  152. for (j=0; j < opElemDouble; j++) [resRep addDouble:t[i]];
  153. }
  154. break;
  155. }
  156. case DOUBLE:
  157. {
  158. double *indexData = [(ArrayRepDouble *)[operand arrayRep] doublesPtr];
  159. for (i=0; i < count; i++)
  160. {
  161. double opElemDouble = indexData[i];
  162. if (opElemDouble < 0) FSExecError(@"argument 1 of method \"replicate:\" must not contain negative numbers");
  163. if (opElemDouble > NSUIntegerMax)
  164. FSExecError([NSString stringWithFormat:@"argument of method \"replicate:\" must contain numbers less or equal to %lu",(unsigned long)NSUIntegerMax]);
  165. for (j=0; j < opElemDouble; j++) [resRep addDouble:t[i]];
  166. }
  167. break;
  168. }
  169. case BOOLEAN:
  170. if ([operand count] != 0) FSExecError(@"argument of method \"replicate:\" is an array of Booleans. An array of numbers was expected");
  171. break;
  172. case EMPTY: break;
  173. case FETCH_REQUEST:
  174. [operand becomeArrayOfId];
  175. return [self replicateWithArray:operand];
  176. } // end switch
  177. return [FSArray arrayWithRep:resRep];
  178. }
  179. - (FSArray *)sort
  180. {
  181. NSUInteger i;
  182. double *resTab;
  183. struct sort_elem * tab;
  184. @try
  185. {
  186. tab = malloc(count*sizeof(struct sort_elem));
  187. if (count == 0) return [FSArray array]; // mergesort() crash if passed an empty array
  188. for (i = 0; i < count; i++)
  189. {
  190. tab[i].index = i;
  191. tab[i].item = t[i];
  192. }
  193. if (mergesort(tab,count,sizeof(struct sort_elem),comp) != 0)
  194. {
  195. if (errno == ENOMEM) FSExecError(@"not enough memory");
  196. else FSExecError(@"F-Script internal error in method -sort (class: ArrayRepDouble)"); // Defensive. Not supposed to happen
  197. }
  198. resTab = (double*) malloc(count * sizeof(double));
  199. for (i = 0; i < count; i++) resTab[i] = tab[i].index;
  200. }
  201. @finally
  202. {
  203. free(tab);
  204. }
  205. return [FSArray arrayWithRep:[[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count] autorelease]];
  206. }
  207. ///////////////////////////// OPTIM ////////////////////////////////////////////////////////////
  208. ////////////////////////////////////////////////////////////////////////////////////////////////
  209. ////////////////////////////////////////////////////////////////////////////////////////////////
  210. /*-------------------------------------- double loop ----------------------------------*/
  211. // note: for all the doubleLoop... methods, precondition is: [[operand arrayRep] isKindOfClass:[ArrayRepDouble class]] && ![operand isProxy]
  212. - (FSArray *)doubleLoop_operator_asterisk:(FSArray *)operand
  213. {
  214. double *resTab;
  215. NSUInteger i;
  216. NSUInteger nb = MIN(count, [operand count]);
  217. double *opData = [[operand arrayRep] doublesPtr];
  218. //NSLog(@"doubleLoop_operator_asterisk");
  219. resTab = malloc(nb*sizeof(double));
  220. for(i=0; i < nb; i++) resTab[i] = t[i]*opData[i];
  221. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:nb]] autorelease];
  222. }
  223. - (FSArray *)doubleLoop_operator_hyphen:(FSArray *)operand
  224. {
  225. double *resTab;
  226. NSUInteger i;
  227. NSUInteger nb = MIN(count, [operand count]);
  228. double *opData = [[operand arrayRep] doublesPtr];
  229. //NSLog(@"doubleLoop_operator_hyphen");
  230. resTab = malloc(nb*sizeof(double));
  231. for(i=0; i < nb; i++) resTab[i] = t[i] - opData[i];
  232. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:nb]] autorelease];
  233. }
  234. - (FSArray *)doubleLoop_operator_plus:(FSArray *)operand
  235. {
  236. double *resTab;
  237. NSUInteger i;
  238. const NSUInteger nb = MIN(count, [operand count]);
  239. double *opData = [[operand arrayRep] doublesPtr];
  240. //NSLog(@"doubleLoop_operator_plus");
  241. resTab = malloc(nb*sizeof(double));
  242. for(i=0; i < nb; i++) resTab[i] = t[i] + opData[i];
  243. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:nb]] autorelease];
  244. }
  245. - (FSArray *)doubleLoop_operator_slash:(FSArray *)operand
  246. {
  247. double *resTab;
  248. NSUInteger i;
  249. NSUInteger nb = MIN(count, [operand count]);
  250. double *opData = [[operand arrayRep] doublesPtr];
  251. //NSLog(@"doubleLoop_operator_slash");
  252. resTab = malloc(nb*sizeof(double));
  253. for(i=0; i < nb; i++)
  254. {
  255. if (!opData[i]) { free(resTab); FSExecError(@"division by zero"); }
  256. resTab[i] = t[i]/opData[i];
  257. }
  258. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:nb]] autorelease];
  259. }
  260. - (FSArray *)doubleLoop_operator_equal:(FSArray *)operand
  261. {
  262. char *resTab;
  263. NSUInteger i;
  264. NSUInteger nb = MIN(count, [operand count]);
  265. double *opData = [[operand arrayRep] doublesPtr];
  266. //NSLog(@"doubleLoop_operator_equal");
  267. resTab = malloc(nb*sizeof(char));
  268. for(i=0; i < nb; i++) resTab[i] = (t[i] == opData[i]);
  269. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:nb]] autorelease];
  270. }
  271. - (FSArray *)doubleLoop_operator_tilde_equal:(FSArray *)operand
  272. {
  273. char *resTab;
  274. NSUInteger i;
  275. NSUInteger nb = MIN(count, [operand count]);
  276. double *opData = [[operand arrayRep] doublesPtr];
  277. resTab = malloc(nb*sizeof(char));
  278. for(i=0; i < nb; i++) resTab[i] = (t[i] != opData[i]);
  279. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:nb]] autorelease];
  280. }
  281. - (FSArray *)doubleLoop_operator_greater:(FSArray *)operand
  282. {
  283. char *resTab;
  284. NSUInteger i;
  285. NSUInteger nb = MIN(count, [operand count]);
  286. double *opData = [[operand arrayRep] doublesPtr];
  287. resTab = malloc(nb*sizeof(char));
  288. for(i=0; i < nb; i++) resTab[i] = (t[i] > opData[i]);
  289. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:nb]] autorelease];
  290. }
  291. - (FSArray *)doubleLoop_operator_greater_equal:(FSArray *)operand
  292. {
  293. char *resTab;
  294. NSUInteger i;
  295. NSUInteger nb = MIN(count, [operand count]);
  296. double *opData = [[operand arrayRep] doublesPtr];
  297. resTab = malloc(nb*sizeof(char));
  298. for(i=0; i < nb; i++) resTab[i] = (t[i] >= opData[i]);
  299. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:nb]] autorelease];
  300. }
  301. - (FSArray *)doubleLoop_operator_less:(FSArray *)operand
  302. {
  303. char *resTab;
  304. NSUInteger i;
  305. NSUInteger nb = MIN(count, [operand count]);
  306. double *opData = [[operand arrayRep] doublesPtr];
  307. resTab = malloc(nb*sizeof(char));
  308. for(i=0; i < nb; i++) resTab[i] = (t[i] < opData[i]);
  309. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:nb]] autorelease];
  310. }
  311. - (FSArray *)doubleLoop_operator_less_equal:(FSArray *)operand
  312. {
  313. char *resTab;
  314. NSUInteger i;
  315. NSUInteger nb = MIN(count, [operand count]);
  316. double *opData = [[operand arrayRep] doublesPtr];
  317. resTab = malloc(nb*sizeof(char));
  318. for(i=0; i < nb; i++) resTab[i] = (t[i] <= opData[i]);
  319. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:nb]] autorelease];
  320. }
  321. /*-------------------------------------- simple loop ----------------------------------*/
  322. - (FSArray *)simpleLoop_abs
  323. {
  324. NSUInteger i;
  325. double *resTab = malloc(count*sizeof(double));
  326. for(i=0;i<count;i++) resTab[i] = fabs(t[i]);
  327. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  328. }
  329. - (FSArray *)simpleLoop_arcCos
  330. {
  331. NSUInteger i;
  332. double *resTab = malloc(count*sizeof(double));
  333. for(i=0;i<count;i++)
  334. {
  335. if((t[i] < -1.0) || (t[i] > 1.0))
  336. {
  337. free(resTab);
  338. FSExecError(@"receiver of message \"arcCos\" must be a number between -1 and 1");
  339. }
  340. resTab[i] = acos(t[i]);
  341. }
  342. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  343. }
  344. - (FSArray *)simpleLoop_arcCosh
  345. {
  346. NSUInteger i;
  347. double *resTab = malloc(count*sizeof(double));
  348. for(i=0;i<count;i++)
  349. {
  350. if (t[i] < 1.0)
  351. {
  352. free(resTab);
  353. FSExecError(@"receiver of message \"arcCosh\" must be a number equal to or greater than 1");
  354. }
  355. resTab[i] = acosh(t[i]);
  356. }
  357. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  358. }
  359. - (FSArray *)simpleLoop_arcSin
  360. {
  361. NSUInteger i;
  362. double *resTab = malloc(count*sizeof(double));
  363. for(i=0;i<count;i++)
  364. {
  365. if((t[i] < -1.0) || (t[i] > 1.0))
  366. {
  367. free(resTab);
  368. FSExecError(@"receiver of message \"arcSin\" must be a number between -1 and 1");
  369. }
  370. resTab[i] = asin(t[i]);
  371. }
  372. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  373. }
  374. - (FSArray *)simpleLoop_arcSinh
  375. {
  376. NSUInteger i;
  377. double *resTab = malloc(count*sizeof(double));
  378. for(i=0;i<count;i++) resTab[i] = asinh(t[i]);
  379. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  380. }
  381. - (FSArray *)simpleLoop_atan // obsolete
  382. {
  383. NSUInteger i;
  384. double *resTab = malloc(count*sizeof(double));
  385. for(i=0;i<count;i++) resTab[i] = atan(t[i]);
  386. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  387. }
  388. - (FSArray *)simpleLoop_arcTan
  389. {
  390. NSUInteger i;
  391. double *resTab = malloc(count*sizeof(double));
  392. for(i=0;i<count;i++) resTab[i] = atan(t[i]);
  393. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  394. }
  395. - (FSArray *)simpleLoop_arcTanh
  396. {
  397. unsigned i;
  398. double *resTab = malloc(count*sizeof(double));
  399. for(i=0;i<count;i++)
  400. {
  401. if((t[i] <= -1.0) || (t[i] >= 1.0))
  402. {
  403. free(resTab);
  404. FSExecError(@"receiver of message \"arcTanh\" must be a number greater than -1 and less than 1");
  405. }
  406. resTab[i] = atanh(t[i]);
  407. }
  408. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  409. }
  410. - (FSArray *)simpleLoop_between:(NSNumber *)a and:(NSNumber *)b
  411. {
  412. char *resTab;
  413. NSUInteger i;
  414. double inf,sup;
  415. FSVerifClassArgsNoNil(@"between:and:",2,a,NSNumberClass,b,NSNumberClass);
  416. inf = [a doubleValue]; sup = [b doubleValue];
  417. if (inf > sup) { double l = inf; inf = sup; sup = l; }
  418. resTab = malloc(count*sizeof(char));
  419. for(i=0; i < count; i++) resTab[i] = (t[i] >= inf && t[i] <= sup);
  420. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:count]] autorelease];
  421. }
  422. - (FSArray *)simpleLoop_ceiling
  423. {
  424. NSUInteger i;
  425. double *resTab = malloc(count*sizeof(double));
  426. for(i=0;i<count;i++) resTab[i] = ceil(t[i]);
  427. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  428. }
  429. - (FSArray *)simpleLoop_cos
  430. {
  431. NSUInteger i;
  432. double *resTab = malloc(count*sizeof(double));
  433. for(i=0;i<count;i++) resTab[i] = cos(t[i]);
  434. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  435. }
  436. - (FSArray *)simpleLoop_cosh
  437. {
  438. NSUInteger i;
  439. double *resTab = malloc(count*sizeof(double));
  440. for(i=0;i<count;i++) resTab[i] = cosh(t[i]);
  441. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  442. }
  443. - (FSArray *)simpleLoop_erf
  444. {
  445. NSUInteger i;
  446. double *resTab = malloc(count*sizeof(double));
  447. for(i=0;i<count;i++) resTab[i] = erf(t[i]);
  448. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  449. }
  450. - (FSArray *)simpleLoop_erfc
  451. {
  452. NSUInteger i;
  453. double *resTab = malloc(count*sizeof(double));
  454. for(i=0;i<count;i++) resTab[i] = erfc(t[i]);
  455. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  456. }
  457. - (FSArray *)simpleLoop_exp
  458. {
  459. NSUInteger i;
  460. double *resTab = malloc(count*sizeof(double));
  461. for(i=0;i<count;i++) resTab[i] = exp(t[i]);
  462. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  463. }
  464. - (FSArray *)simpleLoop_floor
  465. {
  466. NSUInteger i;
  467. double *resTab = malloc(count*sizeof(double));
  468. for(i=0;i<count;i++) resTab[i] = floor(t[i]);
  469. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  470. }
  471. - (FSArray *)simpleLoop_fractionPart
  472. {
  473. NSUInteger i;
  474. double ip;
  475. double *resTab = malloc(count*sizeof(double));
  476. for(i=0;i<count;i++) resTab[i] = modf(t[i],&ip);
  477. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  478. }
  479. - (FSArray *)simpleLoop_integerPart
  480. {
  481. NSUInteger i;
  482. double *resTab = malloc(count*sizeof(double));
  483. for(i=0;i<count;i++) modf(t[i],&(resTab[i]));
  484. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  485. }
  486. - (FSArray *)simpleLoop_ln
  487. {
  488. NSUInteger i;
  489. double *resTab = malloc(count*sizeof(double));
  490. for(i=0;i<count;i++)
  491. {
  492. if (t[i] <= 0)
  493. {
  494. free(resTab);
  495. FSExecError(@"receiver of message \"ln\" must be positive");
  496. }
  497. resTab[i] = log(t[i]);
  498. }
  499. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  500. }
  501. - (FSArray *)simpleLoop_log
  502. {
  503. NSUInteger i;
  504. double *resTab = malloc(count*sizeof(double));
  505. for(i=0;i<count;i++)
  506. {
  507. if (t[i] <= 0)
  508. {
  509. free(resTab);
  510. FSExecError(@"receiver of message \"log\" must be positive");
  511. }
  512. resTab[i] = log10(t[i]);
  513. }
  514. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  515. }
  516. - (FSArray *)simpleLoop_max:(NSNumber *)operand
  517. {
  518. double opVal;
  519. double *resTab;
  520. NSUInteger i;
  521. VERIF_OP_NSNUMBER(@"max:")
  522. opVal = [operand doubleValue];
  523. resTab = malloc(count*sizeof(double));
  524. for(i=0; i < count; i++) resTab[i] = (opVal >= t[i] ? opVal : t[i]);
  525. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  526. }
  527. - (FSArray *)simpleLoop_min:(NSNumber *)operand
  528. {
  529. double opVal;
  530. double *resTab;
  531. NSUInteger i;
  532. VERIF_OP_NSNUMBER(@"min:")
  533. opVal = [operand doubleValue];
  534. resTab = malloc(count*sizeof(double));
  535. for(i=0; i < count; i++) resTab[i] = (opVal <= t[i] ? opVal : t[i]);
  536. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  537. }
  538. - (FSArray *)simpleLoop_negated
  539. {
  540. NSUInteger i;
  541. double *resTab = malloc(count*sizeof(double));
  542. for(i=0;i<count;i++) resTab[i] = -t[i];
  543. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  544. }
  545. - (FSArray *)simpleLoop_operator_asterisk:(NSNumber *)operand
  546. {
  547. double opVal;
  548. double *resTab;
  549. NSUInteger i;
  550. VERIF_OP_NSNUMBER(@"*")
  551. opVal = [operand doubleValue];
  552. resTab = malloc(count*sizeof(double));
  553. for(i=0; i < count; i++) resTab[i] = t[i] * opVal;
  554. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  555. }
  556. - (FSArray *)simpleLoop_operator_hyphen:(NSNumber *)operand
  557. {
  558. double opVal;
  559. double *resTab;
  560. NSUInteger i;
  561. //NSLog(@"simpleLoop_operator_hyphen:");
  562. VERIF_OP_NSNUMBER(@"-")
  563. opVal = [operand doubleValue];
  564. resTab = malloc(count*sizeof(double));
  565. for(i=0; i < count; i++) resTab[i] = t[i]-opVal;
  566. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  567. }
  568. - (FSArray *)simpleLoop_operator_plus:(id)operand
  569. {
  570. double opVal;
  571. double *resTab;
  572. NSUInteger i;
  573. if (!([operand isKindOfClass:NSNumberClass] || operand == fsTrue || operand == fsFalse || [operand isKindOfClass:[FSBoolean class]]))
  574. {
  575. FSExecError(@"argument of methode \"+\" must be a number or a Boolean"); return nil; // W
  576. }
  577. opVal = [operand doubleValue];
  578. resTab = malloc(count*sizeof(double));
  579. for(i=0; i < count; i++) resTab[i] = t[i]+opVal;
  580. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  581. }
  582. - (FSArray *)simpleLoop_operator_slash:(NSNumber *)operand
  583. {
  584. double opVal;
  585. double *resTab;
  586. NSUInteger i;
  587. VERIF_OP_NSNUMBER(@"/")
  588. opVal = [operand doubleValue];
  589. if (opVal == 0.0) FSExecError(@"division by zero");
  590. resTab = malloc(count*sizeof(double));
  591. for(i=0; i < count; i++) resTab[i] = t[i] / opVal;
  592. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  593. }
  594. - (FSArray *)simpleLoop_operator_equal:(id)operand
  595. {
  596. double opVal;
  597. char *resTab;
  598. NSUInteger i;
  599. //NSLog(@"simpleLoop_operator_equal:");
  600. if ([operand isKindOfClass:NSNumberClass])
  601. {
  602. opVal = [operand doubleValue];
  603. resTab = malloc(count*sizeof(char));
  604. for(i=0; i < count; i++) resTab[i] = (t[i] == opVal) ;
  605. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:count]] autorelease];
  606. }
  607. else return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initFilledWithBoolean:NO count:count]] autorelease];
  608. }
  609. - (FSArray *)simpleLoop_operator_tilde_equal:(id)operand
  610. {
  611. double opVal;
  612. char *resTab;
  613. NSUInteger i;
  614. if ([operand isKindOfClass:NSNumberClass])
  615. {
  616. opVal = [operand doubleValue];
  617. resTab = malloc(count*sizeof(char));
  618. for(i=0; i < count; i++) resTab[i] = (t[i] != opVal) ;
  619. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:count]] autorelease];
  620. }
  621. else return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initFilledWithBoolean:YES count:count]] autorelease];
  622. }
  623. - (FSArray *)simpleLoop_operator_greater:(id)operand
  624. {
  625. double opVal;
  626. char *resTab;
  627. NSUInteger i;
  628. VERIF_OP_NSNUMBER(@">")
  629. opVal = [operand doubleValue];
  630. resTab = malloc(count*sizeof(char));
  631. for(i=0; i < count; i++) resTab[i] = (t[i] > opVal) ;
  632. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:count]] autorelease];
  633. }
  634. - (FSArray *)simpleLoop_operator_greater_equal:(id)operand
  635. {
  636. double opVal;
  637. char *resTab;
  638. NSUInteger i;
  639. VERIF_OP_NSNUMBER(@">=")
  640. opVal = [operand doubleValue];
  641. resTab = malloc(count*sizeof(char));
  642. for(i=0; i < count; i++) resTab[i] = (t[i] >= opVal) ;
  643. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:count]] autorelease];
  644. }
  645. - (FSArray *)simpleLoop_operator_less:(id)operand
  646. {
  647. double opVal;
  648. char *resTab;
  649. NSUInteger i;
  650. VERIF_OP_NSNUMBER(@"<")
  651. opVal = [operand doubleValue];
  652. resTab = malloc(count*sizeof(char));
  653. for(i=0; i < count; i++) resTab[i] = (t[i] < opVal) ;
  654. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:count]] autorelease];
  655. }
  656. - (FSArray *)simpleLoop_operator_less_equal:(id)operand
  657. {
  658. double opVal;
  659. char *resTab;
  660. NSUInteger i;
  661. VERIF_OP_NSNUMBER(@"<=")
  662. opVal = [operand doubleValue];
  663. resTab = malloc(count*sizeof(char));
  664. for(i=0; i < count; i++) resTab[i] = (t[i] <= opVal) ;
  665. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:count]] autorelease];
  666. }
  667. - (FSArray *)simpleLoop_rem:(NSNumber *)operand
  668. {
  669. double opVal;
  670. double *resTab;
  671. NSUInteger i;
  672. VERIF_OP_NSNUMBER(@"rem:")
  673. opVal = [operand doubleValue];
  674. if (opVal == 0) FSExecError(@"argument of method \"rem:\" must not be zero");
  675. resTab = malloc(count*sizeof(double));
  676. for(i=0; i < count; i++) resTab[i] = fmod(t[i],opVal);
  677. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  678. }
  679. - (FSArray *)simpleLoop_sin
  680. {
  681. NSUInteger i;
  682. double *resTab = malloc(count*sizeof(double));
  683. for(i=0;i<count;i++) resTab[i] = sin(t[i]);
  684. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  685. }
  686. - (FSArray *)simpleLoop_sinh
  687. {
  688. NSUInteger i;
  689. double *resTab = malloc(count*sizeof(double));
  690. for(i=0;i<count;i++) resTab[i] = sinh(t[i]);
  691. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  692. }
  693. - (FSArray *)simpleLoop_sqrt
  694. {
  695. NSUInteger i;
  696. double *resTab = malloc(count*sizeof(double));
  697. for(i=0;i<count;i++)
  698. {
  699. if (t[i] < 0)
  700. {
  701. free(resTab);
  702. FSExecError(@"receiver of message \"sqrt\" must not be negative");
  703. }
  704. resTab[i] = sqrt(t[i]);
  705. }
  706. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  707. }
  708. - (FSArray *)simpleLoop_tan
  709. {
  710. NSUInteger i;
  711. double *resTab = malloc(count*sizeof(double));
  712. for(i=0;i<count;i++) resTab[i] = tan(t[i]);
  713. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  714. }
  715. - (FSArray *)simpleLoop_tanh
  716. {
  717. NSUInteger i;
  718. double *resTab = malloc(count*sizeof(double));
  719. for(i=0;i<count;i++) resTab[i] = tanh(t[i]);
  720. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  721. }
  722. - (FSArray *)simpleLoop_truncated
  723. {
  724. NSUInteger i;
  725. double *resTab = malloc(count*sizeof(double));
  726. for(i=0;i<count;i++) resTab[i] = t[i] > 0 ? floor(t[i]) : ceil(t[i]);
  727. return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepDouble alloc] initWithDoublesNoCopy:resTab count:count]] autorelease];
  728. }
  729. /////////////////////////////// OTHER METHODS //////////////////////////////////
  730. ////////////////////////////////////////////////////////////////////////////////
  731. + (id)arrayRepDoubleWithCapacity:(NSUInteger)aNumItems
  732. {
  733. return [[[self alloc] initWithCapacity:aNumItems] autorelease];
  734. }
  735. - (void)addDouble:(double)aDouble
  736. {
  737. count++;
  738. if (count > capacity)
  739. {
  740. capacity = (capacity+1)*2;
  741. t = (double *)realloc(t, capacity * sizeof(double));
  742. }
  743. t[count-1] = aDouble;
  744. }
  745. - (void)addDoublesFromFSArray:(FSArray *)otherArray
  746. {
  747. NSUInteger i;
  748. NSUInteger oldCount = count;
  749. double *otherArrayData = [(ArrayRepDouble *)[otherArray arrayRep] doublesPtr];
  750. NSUInteger otherArrayCount = [otherArray count];
  751. count += otherArrayCount;
  752. if (count > capacity)
  753. {
  754. capacity = count;
  755. t = (double*)realloc(t, capacity * sizeof(double));
  756. }
  757. for (i = 0; i < otherArrayCount; i++) t[oldCount+i] = otherArrayData[i];
  758. }
  759. - (ArrayRepId *) asArrayRepId
  760. {
  761. NSUInteger i;
  762. id *tab = (id *) NSAllocateCollectable(count * sizeof(id), NSScannedOption);
  763. ArrayRepId *r = [[[ArrayRepId alloc] initWithObjectsNoCopy:tab count:count] autorelease];
  764. for (i = 0; i < count; i++) tab[i] = [[FSNumber alloc] initWithDouble:t[i]];
  765. return r;
  766. }
  767. - (id)copyWithZone:(NSZone *)zone
  768. {
  769. return [[ArrayRepDouble allocWithZone:zone] initWithDoubles:t count:count];
  770. }
  771. - (NSUInteger)count {return count;}
  772. - (void)dealloc
  773. {
  774. free(t);
  775. [super dealloc];
  776. }
  777. - (void)finalize
  778. {
  779. //NSLog(@"finalizing an ArrayRepDouble");
  780. free(t);
  781. [super finalize];
  782. }
  783. - (double *)doublesPtr {return t;}
  784. - (NSString *)descriptionLimited:(NSUInteger)nbElem
  785. {
  786. NSMutableString *str = [[@"{" mutableCopy] autorelease];
  787. NSString *elemStr = @""; // W
  788. NSUInteger i;
  789. NSUInteger lim = MIN(count,nbElem);
  790. if (lim > 0)
  791. {
  792. elemStr = [NSString stringWithFormat:@"%.11g",t[0]];
  793. [str appendString:elemStr];
  794. }
  795. for (i = 1; i < lim; i++)
  796. {
  797. [str appendString:@", "];
  798. if ([elemStr length] > 20) [str appendString:@"\n"];
  799. elemStr = [NSString stringWithFormat:@"%.11g",t[i]];
  800. [str appendString:elemStr];
  801. }
  802. if (count > nbElem ) [str appendFormat:@", ... (%lu more elements)",(unsigned long)(count-nbElem)];
  803. [str appendString:@"}"];
  804. return str;
  805. }
  806. - (id)indexWithArray:(FSArray *)index
  807. {
  808. assert(![index isProxy]);
  809. switch ([index type])
  810. {
  811. case FS_ID:
  812. {
  813. ArrayRepDouble *resRep;
  814. id *indexData;
  815. NSUInteger i = 0;
  816. NSUInteger nb = [index count];
  817. indexData = [index dataPtr];
  818. while (i < nb && !indexData[i]) i++; // ignore the nil value
  819. if (i == nb)
  820. {
  821. if (nb == count || nb == 0) return [FSArray array];
  822. else FSExecError(@"invalid index");
  823. }
  824. if (indexData[i] == fsTrue || indexData[i] == fsFalse || [indexData[i] isKindOfClass:[FSBoolean class]])
  825. {
  826. if (nb != count) FSExecError(@"indexing with an array of boolean of bad size");
  827. resRep = [[[ArrayRepDouble alloc] init] autorelease];
  828. while (i < nb)
  829. {
  830. if (indexData[i] == fsTrue) [resRep addDouble:t[i]];
  831. else if (indexData[i] != fsFalse)
  832. {
  833. if (![indexData[i] isKindOfClass:[FSBoolean class]]) FSExecError(@"indexing with a mixed array");
  834. else if ([indexData[i] isTrue]) [resRep addDouble:t[i]];
  835. }
  836. i++;
  837. while (i < nb && !indexData[i]) i++; // ignore the nil value
  838. }
  839. }
  840. else if ([indexData[i] isKindOfClass:NSNumberClass])
  841. {
  842. resRep = [ArrayRepDouble arrayRepDoubleWithCapacity:nb];
  843. while (i < nb)
  844. {
  845. double ind = [indexData[i] doubleValue];
  846. if (![indexData[i] isKindOfClass:NSNumberClass]) FSExecError(@"indexing with a mixed array");
  847. /*
  848. if (ind != (int)ind)
  849. FSExecError(@"l'indice d'un tableau doit etre un nombre sans "
  850. @"partie fractionnaire");
  851. */
  852. if (ind < 0) FSExecError(@"index of an array must be a number greater or equal to 0");
  853. if (ind >= count) FSExecError(@"index of an array must be a number less than the size of the array");
  854. [resRep addDouble:t[(NSUInteger)ind]];
  855. i++;
  856. while (i < nb && !indexData[i]) i++; // ignore the nil value
  857. }
  858. }
  859. else // indexData[i] is neither an NSNumber nor a FSBoolean
  860. {
  861. FSExecError([NSString stringWithFormat:@"array indexing by an array containing %@",descriptionForFSMessage(indexData[i])]);
  862. return nil; // W
  863. }
  864. return [FSArray arrayWithRep:resRep];
  865. }
  866. case DOUBLE:
  867. {
  868. ArrayRepDouble *resRep;
  869. double *indexData;
  870. NSUInteger i = 0;
  871. NSUInteger nb = [index count];
  872. double *tab;
  873. if (i == nb) return [FSArray array];
  874. indexData = [(ArrayRepDouble *)[index arrayRep] doublesPtr];
  875. tab = (double *) malloc(sizeof(double) * nb);
  876. resRep = [[[ArrayRepDouble alloc] initWithDoublesNoCopy:tab count:nb] autorelease];
  877. while (i < nb)
  878. {
  879. double ind = indexData[i];
  880. /*
  881. if (ind != (int)ind)
  882. FSExecError(@"l'indice d'un tableau doit etre un nombre sans "
  883. @"partie fractionnaire");
  884. */
  885. if (ind < 0) FSExecError(@"index of an array must be a number greater or equal to 0");
  886. if (ind >= count) FSExecError(@"index of an array must be a number less than the size of the array");
  887. tab[i] = t[(NSUInteger)ind];
  888. i++;
  889. }
  890. return [FSArray arrayWithRep:resRep];
  891. }
  892. case BOOLEAN:
  893. {
  894. NSUInteger i;
  895. char *indexData;
  896. ArrayRepDouble *resRep;
  897. if ([index count] == 0) return [FSArray array];
  898. if ([index count] != count) FSExecError(@"indexing with an array of booleans of bad size");
  899. resRep = [[[ArrayRepDouble alloc] init] autorelease];
  900. indexData = [(ArrayRepBoolean *)[index arrayRep] booleansPtr];
  901. for (i = 0; i < count; i++) if (indexData[i]) [resRep addDouble:t[i]];
  902. return [FSArray arrayWithRep:resRep];
  903. }
  904. case EMPTY: return [FSArray array];
  905. case FETCH_REQUEST:
  906. [index becomeArrayOfId];
  907. return [self indexWithArray:index];
  908. } // end switch
  909. return nil; //W
  910. }
  911. - (id)init { return [self initWithCapacity:0]; }
  912. - (id)initFilledWithDouble:(double)elem count:(NSUInteger)nb // contract: a return value of nil means not enough memory
  913. {
  914. if (self = [self initWithCapacity:nb])
  915. {
  916. for (count = 0; count < nb; count++) t[count] = elem;
  917. return self;
  918. }
  919. return nil;
  920. }
  921. - (id)initFrom:(NSUInteger)from to:(NSUInteger)to step:(NSUInteger)step // contract: a return value of nil means not enough memory
  922. {
  923. if (to < from) return [self init];
  924. if (self = [self initWithCapacity:1+((to-from)/step)])
  925. {
  926. double valcou = from;
  927. count = 0;
  928. do
  929. {
  930. t[count] = valcou;
  931. valcou += step;
  932. count++;
  933. }
  934. while (valcou <= to);
  935. return self;
  936. }
  937. return nil;
  938. }
  939. - (id)initWithCapacity:(NSUInteger)aNumItems // contract: a return value of nil means not enough memory
  940. {
  941. if (self = [super init])
  942. {
  943. t = malloc(aNumItems*sizeof(double));
  944. if (!t)
  945. {
  946. [super dealloc];
  947. return nil;
  948. }
  949. retainCount = 1;
  950. capacity = aNumItems;
  951. count = 0;
  952. return self;
  953. }
  954. return nil;
  955. }
  956. - (id)initWithDoubles:(double *)elems count:(NSUInteger)nb
  957. {
  958. if ((self = [self initWithCapacity:nb]))
  959. {
  960. memcpy(t,elems,nb*sizeof(double));
  961. count = nb;
  962. return self;
  963. }
  964. return nil;
  965. }
  966. - (id)initWithDoublesNoCopy:(double *)tab count:(NSUInteger)nb
  967. {
  968. if ((self = [super init]))
  969. {
  970. retainCount = 1;
  971. t = tab;
  972. capacity = nb;
  973. count = nb;
  974. return self;
  975. }
  976. return nil;
  977. }
  978. - (void)insertDouble:(double)aDouble atIndex:(NSUInteger)index
  979. {
  980. count++ ;
  981. if (count > capacity)
  982. {
  983. capacity = (capacity+1)*2;
  984. t = (double*)realloc(t, capacity * sizeof(double));
  985. }
  986. memmove( &(t[index+1]), &(t[index]), ((count-1)-index) * sizeof(double) );
  987. t[index] = aDouble;
  988. }
  989. - (void)removeLastElem
  990. {
  991. count--;
  992. if (capacity/2 >= count+100)
  993. {
  994. capacity = capacity/2;
  995. t = (double *)realloc(t, capacity * sizeof(double));
  996. }
  997. }
  998. - (void)removeElemAtIndex:(NSUInteger)index
  999. {
  1000. count--;
  1001. memmove( &(t[index]), &(t[index+1]), (count-index) * sizeof(double) );
  1002. if (capacity/2 >= count+100)
  1003. {
  1004. capacity = capacity/2;
  1005. t = (double *)realloc(t, capacity * sizeof(double));
  1006. }
  1007. }
  1008. - (void)replaceDoubleAtIndex:(NSUInteger)index withDouble:(double)aDouble
  1009. {
  1010. t[index] = aDouble;
  1011. }
  1012. - (id)retain { retainCount++; return self;}
  1013. - (NSUInteger)retainCount { return retainCount;}
  1014. - (oneway void)release { if (--retainCount == 0) [self dealloc];}
  1015. - (NSArray *)subarrayWithRange:(NSRange)range
  1016. {
  1017. ArrayRepDouble *resRep;
  1018. FSArray *r;
  1019. resRep = [[ArrayRepDouble alloc] initWithDoubles:t+range.location count:range.length];
  1020. r = [FSArray arrayWithRep:resRep];
  1021. [resRep release];
  1022. return r;
  1023. }
  1024. - (enum ArrayRepType)repType {return DOUBLE;}
  1025. - (FSArray *)where:(NSArray *)booleans // precondition: booleans is actualy an array and is of same size as the receiver
  1026. {
  1027. ArrayRepDouble *resRep = [[[ArrayRepDouble alloc] init] autorelease];
  1028. if ([booleans isKindOfClass:[FSArray class]] && [(FSArray *)booleans type] == BOOLEAN)
  1029. {
  1030. char *rawBooleans = [(ArrayRepBoolean *)[(FSArray *)booleans arrayRep] booleansPtr];
  1031. for (NSUInteger i = 0; i < count; i++) if (rawBooleans[i]) [resRep addDouble:t[i]];
  1032. }
  1033. else
  1034. {
  1035. id boolean;
  1036. for (NSUInteger i = 0; i < count; i++)
  1037. {
  1038. boolean = [booleans objectAtIndex:i];
  1039. if (boolean == fsFalse || boolean == nil)
  1040. continue;
  1041. else if (boolean == fsTrue)
  1042. [resRep addDouble:t[i]];
  1043. else if ([boolean isKindOfClass:[FSBoolean class]])
  1044. {
  1045. if ([boolean isTrue])
  1046. [resRep addDouble:t[i]];
  1047. }
  1048. else
  1049. FSExecError(@"argument of method \"where:\" must be an array of booleans");
  1050. }
  1051. }
  1052. return [FSArray arrayWithRep:resRep];
  1053. }
  1054. @end