Advertisement
Guest User

Untitled

a guest
Aug 10th, 2014
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.26 KB | None | 0 0
  1. #include "EXTERN.h"
  2. #include "perl.h"
  3. #include "XSUB.h"
  4.  
  5. #include <math.h>
  6. #include "FastSOM.h"
  7. #include "proto.h"
  8. #include "omp.h"
  9. #include <stdio.h>
  10.  
  11. /*
  12. * generic funtions
  13. *
  14. * NOT superclass functions, but usable by all
  15. */
  16.  
  17. NV _vector_distance(AV* V1, AV* V2) {
  18. NV diff,sum;
  19. I32 w_ptr;
  20.  
  21. sum = 0;
  22. for ( w_ptr=av_len(V2) ; w_ptr>=0 ; w_ptr-- ) {
  23. diff = SvNV(*av_fetch(V1, w_ptr, FALSE))
  24. - SvNV(*av_fetch(V2, w_ptr, FALSE));
  25. sum += diff * diff;
  26. }
  27. return sqrt(sum);
  28. }
  29.  
  30. void _bmuguts(SOM_GENERIC *som,AV *sample,IV *bx,IV *by,NV *bd) {
  31. IV x,y,z,X,Y,Z;
  32. NV sum,diff,distance;
  33. SOM_Map *map;
  34. SOM_Array *array;
  35. SOM_Vector *vector;
  36.  
  37. map = som->map;
  38. X = som->X;
  39. Y = som->Y;
  40. Z = som->Z;
  41.  
  42. *bx = -1;
  43. *by = 0;
  44. *bd = 0.0;
  45. for ( x=0 ; x<X ; x++ ) {
  46. array = (&map->array)[x];
  47. for ( y=0 ; y<Y ; y++ ) {
  48. vector = (&array->vector)[y];
  49.  
  50. sum = 0;
  51. for ( z=0 ; z<Z ; z++ ) {
  52. diff = SvNV(*av_fetch(sample,z,0))
  53. - (&vector->element)[z];
  54. sum += diff * diff;
  55. }
  56. distance = sqrt(sum);
  57.  
  58. if ( *bx < 0 )
  59. { *bx = 0; *by = 0; *bd = distance; }
  60. if ( distance < *bd )
  61. { *bx = x; *by = y; *bd = distance; }
  62. }
  63. }
  64. }
  65.  
  66.  
  67. /* http://www.ai-junkie.com/ann/som/som4.html */
  68. void _adjust(SV* self,NV l,NV sigma,AV* unit,AV* v) {
  69. IV x,y;
  70. I32 z,Z;
  71. NV d,theta,vold,wold;
  72. MAGIC *mg;
  73. SOM_Map *map;
  74. SOM_Array *array;
  75. SOM_Vector *vector;
  76. SOM_GENERIC *som;
  77.  
  78. x = SvIV(*av_fetch(unit, 0, FALSE));
  79. y = SvIV(*av_fetch(unit, 1, FALSE));
  80. d = SvNV(*av_fetch(unit, 2, FALSE));
  81. theta = exp( -d*d/2/sigma/sigma );
  82.  
  83. if ( !(mg = selfmagic(self)) )
  84. croak("self has no magic!\n");
  85. som = self2somptr(self,mg);
  86.  
  87. map = som->map;
  88. array = (&map->array)[x];
  89. vector = (&array->vector)[y];
  90.  
  91. /* hmm.. casting IV to I32.. is that sane? */
  92. Z = (I32)som->Z;
  93.  
  94. for ( z=0 ; z<Z ; z++ ) {
  95. wold = (&vector->element)[z];
  96. vold = SvNV(*av_fetch(v,z,FALSE));
  97. (&vector->element)[z] = (vold - wold) * l * theta + wold;
  98. }
  99. }
  100.  
  101. void _adjustn(SOM_GENERIC* som,NV l,NV sigma,NV* n,AV* v) {
  102. IV x,y,X,Y;
  103. I32 z,Z;
  104. NV d,theta,vold,wold;
  105. SOM_Map *map;
  106. SOM_Array *array;
  107. SOM_Vector *vector;
  108.  
  109. map = som->map;
  110. X = som->X;
  111. Y = som->Y;
  112.  
  113. for ( x=0 ; x<X ; x++ ) {
  114. array = (&map->array)[x];
  115. for ( y=0 ; y<Y ; y++ ) {
  116. d = n[x*Y+y];
  117. if (d < 0) continue;
  118. theta = exp( -d*d/2/sigma/sigma );
  119. vector = (&array->vector)[y];
  120.  
  121. /* hmm.. casting IV to I32.. is that sane? */
  122. Z = (I32)som->Z;
  123.  
  124.  
  125. for ( z=0 ; z<Z ; z++ ) {
  126. wold = (&vector->element)[z];
  127. vold = SvNV(*av_fetch(v,z,FALSE));
  128. (&vector->element)[z] =
  129. (vold - wold) * l * theta + wold;
  130. }
  131. }
  132. }
  133.  
  134.  
  135. }
  136.  
  137. AV* _neighbors(SV* self,NV sigma,IV X0,IV Y0,...) {
  138. IV i,x,y,X,Y;
  139. NV distance,*n;
  140. AV *tmp,*neighbors;
  141. MAGIC *mg;
  142. SOM_GENERIC *som;
  143. void (*neiguts)(SOM_GENERIC* som,NV sigma,IV X0,IV Y0,NV *n);
  144.  
  145. if ( !(mg = selfmagic(self)) )
  146. croak("self has no magic!\n");
  147. som = self2somptr(self,mg);
  148.  
  149. X = som->X;
  150. Y = som->Y;
  151.  
  152. i = X*Y;
  153. Newx(n,i,NV);
  154. for ( i-=1 ; i>=0 ; i-- )
  155. n[i] = -1;
  156.  
  157. if ( som->type == SOMType_Torus )
  158. neiguts = _torus_neiguts;
  159. else if ( som->type == SOMType_Hexa )
  160. neiguts = _hexa_neiguts;
  161. else if ( som->type == SOMType_Rect )
  162. neiguts = _rect_neiguts;
  163. else
  164. croak("unknown type");
  165.  
  166. neiguts(som,sigma,X0,Y0,n);
  167.  
  168. neighbors = newAV();
  169.  
  170. for ( x=0 ; x<X ; x++ ) {
  171. for ( y=0 ; y<Y ; y++ ) {
  172. distance = n[x*Y+y];
  173. if ( distance >= 0 ) {
  174. tmp = newAV();
  175. av_push(tmp,newSViv(x));
  176. av_push(tmp,newSViv(y));
  177. av_push(tmp,newSVnv(distance));
  178. av_push(neighbors,newRV_noinc((SV*)tmp));
  179. }
  180. }
  181. }
  182. Safefree(n);
  183. return neighbors;
  184. }
  185.  
  186. SOM_Vector* _make_vector(SOM_Array* array) {
  187. IV z,len;
  188. AV *thingy;
  189. SV *tie;
  190. HV *stash;
  191. SOM_Vector *vector;
  192.  
  193. z = array->Z;
  194.  
  195. len = sizeof(SOM_Vector)+z*sizeof(NV);
  196. Newxc(vector, len, char, SOM_Vector);
  197. Zero(vector, len, char);
  198.  
  199. vector->Z = z;
  200.  
  201. thingy = newAV();
  202. tie = newRV_noinc(newSViv(PTR2IV(vector)));
  203. stash = gv_stashpv("AI::NeuralNet::FastSOM::VECTOR", GV_ADD);
  204. sv_bless(tie, stash);
  205. hv_magic((HV*)thingy, (GV*)tie, 'P');
  206. vector->ref = newRV_noinc((SV*)thingy);
  207.  
  208. (&vector->element)[z] = 0.0;
  209. for ( z-=1 ; z>=0 ; z-- ) {
  210. (&vector->element)[z] = 0.0;
  211. }
  212.  
  213. return vector;
  214. }
  215.  
  216. SOM_Array* _make_array(SOM_Map* map) {
  217. IV y,len;
  218. AV *thingy;
  219. SV *tie;
  220. HV *stash;
  221. SOM_Array *array;
  222.  
  223. y = map->Y;
  224.  
  225. len = sizeof(SOM_Array)+y*sizeof(SOM_Vector*);
  226. Newxc(array, len, char, SOM_Array);
  227. Zero(array, len, char);
  228.  
  229. array->Y = y;
  230. array->Z = map->Z;
  231.  
  232. thingy = newAV();
  233. tie = newRV_noinc(newSViv(PTR2IV(array)));
  234. stash = gv_stashpv("AI::NeuralNet::FastSOM::ARRAY", GV_ADD);
  235. sv_bless(tie, stash);
  236. hv_magic((HV*)thingy, (GV*)tie, PERL_MAGIC_tied);
  237. array->ref = newRV_noinc((SV*)thingy);
  238.  
  239. (&array->vector)[y] = NULL;
  240. for ( y-=1 ; y>=0 ; y-- )
  241. (&array->vector)[y] = _make_vector( array );
  242.  
  243. return array;
  244. }
  245.  
  246. SOM_Map* _make_map(SOM_GENERIC *som) {
  247. IV x,len;
  248. AV *thingy;
  249. SV *tie;
  250. HV *stash;
  251. SOM_Map *map;
  252.  
  253. x = som->X;
  254.  
  255. len = sizeof(SOM_Map)+x*sizeof(SOM_Array*);
  256. Newxc(map, len, char, SOM_Map);
  257. Zero(map, len, char);
  258.  
  259. map->X = x;
  260. map->Y = som->Y;
  261. map->Z = som->Z;
  262.  
  263. thingy = newAV();
  264. tie = newRV_noinc(newSViv(PTR2IV(map)));
  265. stash = gv_stashpv("AI::NeuralNet::FastSOM::MAP", GV_ADD);
  266. sv_bless(tie, stash);
  267. hv_magic((HV*)thingy, (GV*)tie, PERL_MAGIC_tied);
  268. map->ref = newRV_noinc((SV*)thingy);
  269.  
  270. (&map->array)[x] = NULL;
  271. for ( x-=1 ; x>=0 ; x-- )
  272. (&map->array)[x] = _make_array( map );
  273.  
  274. return map;
  275. }
  276.  
  277.  
  278.  
  279. /*
  280. * som functions
  281. */
  282.  
  283. void _som_bmu(SV* self, AV* sample) {
  284. IV cx,cy;
  285. NV cd;
  286. MAGIC *mg;
  287. SOM_GENERIC *som;
  288. dXSARGS;
  289.  
  290. if ( !(mg = selfmagic(self)) )
  291. croak("self has no magic!\n");
  292. som = self2somptr(self,mg);
  293.  
  294. _bmuguts(som,sample,&cx,&cy,&cd);
  295.  
  296. PERL_UNUSED_VAR(items); /* -W */
  297. sp = mark;
  298. XPUSHs(sv_2mortal(newSViv(cx)));
  299. XPUSHs(sv_2mortal(newSViv(cy)));
  300. XPUSHs(sv_2mortal(newSVnv(cd)));
  301. PUTBACK;
  302. }
  303.  
  304. SV* _som_map(SV* self) {
  305. MAGIC *mg;
  306. SOM_GENERIC *som;
  307.  
  308. if ( !(mg = selfmagic(self)) )
  309. croak("self has no magic!\n");
  310. som = self2somptr(self,mg);
  311.  
  312. SvREFCNT_inc(som->map->ref);
  313. return som->map->ref;
  314. }
  315.  
  316. SV* _som_output_dim(SV* self) {
  317. MAGIC *mg;
  318. SOM_GENERIC *som;
  319.  
  320. if ( !(mg = selfmagic(self)) )
  321. croak("self has no magic!\n");
  322. som = self2somptr(self,mg);
  323.  
  324. SvREFCNT_inc(som->output_dim);
  325. return som->output_dim;
  326. }
  327.  
  328. void _som_train(SV* self,IV epochs) {
  329. IV i,X,Y,bx,by,epoch;
  330. NV bd,l,sigma,*n;
  331. AV **org,**veg,*sample;
  332. I32 p,pick,nitems,oitems,vitems,drnd;
  333. MAGIC *mg;
  334. SOM_GENERIC *som;
  335. bool wantarray;
  336. void (*neiguts)(SOM_GENERIC* som,NV sigma,IV X0,IV Y0,NV* n);
  337. dXSARGS;
  338.  
  339.  
  340.  
  341. int R;
  342. if ( !(mg = selfmagic(self)) )
  343. croak("self has no magic!");
  344. som = self2somptr(self,mg);
  345.  
  346. if ( epochs < 1 )
  347. epochs = 1;
  348.  
  349. if ( items < 3 )
  350. croak("no data to learn");
  351.  
  352. oitems = items - 2;
  353. Newx(org,oitems,AV*);
  354. Newx(veg,oitems,AV*);
  355.  
  356. for ( i=2 ; i<items ; i++ )
  357. if ( SvTYPE(SvRV(ST(i))) != SVt_PVAV )
  358. croak("training item %i is not an array ref", (int)i);
  359. else
  360. org[i-2] = (AV*)SvRV(ST(i));
  361.  
  362. som->LAMBDA = epochs / log( som->Sigma0 );
  363.  
  364. X = som->X;
  365. Y = som->Y;
  366.  
  367. nitems = X*Y;
  368. Newx(n,nitems,NV);
  369.  
  370. if ( som->type == SOMType_Torus )
  371. neiguts = _torus_neiguts;
  372. else if ( som->type == SOMType_Hexa )
  373. neiguts = _hexa_neiguts;
  374. else if ( som->type == SOMType_Rect )
  375. neiguts = _rect_neiguts;
  376. else
  377. croak("unknown type");
  378.  
  379. wantarray = GIMME_V == G_ARRAY ? TRUE : FALSE;
  380.  
  381. /* should this be moved somewhere more global? */
  382. if ( !PL_srand_called ) {
  383. seedDrand01((Rand_seed_t)(time(NULL)+PerlProc_getpid()));
  384. PL_srand_called = TRUE;
  385. }
  386.  
  387. sp = mark;
  388.  
  389. int dd=0;
  390. #pragma omp parallel default(shared)
  391. {
  392. #pragma omp for
  393. for ( epoch=1 ; epoch<=epochs ; epoch++ ) {
  394.  
  395. dd++;
  396. printf("epoch: %d \n", dd);
  397. som->T = epoch;
  398. sigma = som->Sigma0 * exp(-epoch / som->LAMBDA);
  399. l = som->L0 * exp(-epoch / epochs);
  400.  
  401. Copy(org,veg,oitems,AV*);
  402. vitems = oitems;
  403.  
  404. /*
  405. while ( vitems > 0 ) {
  406. */
  407.  
  408. for(vitems=oitems; vitems>0; vitems--) {
  409.  
  410.  
  411. /*
  412. pick = (I32)(Drand01() * vitems);
  413. */
  414.  
  415. drnd = Drand01();
  416. pick = drnd * vitems;
  417.  
  418. sample = (AV*)veg[pick];
  419.  
  420. /* optimze me! */
  421. for ( p=pick+1 ; p<vitems ; p++ ){
  422. R=p-1;
  423. veg[R] = veg[p];
  424. }
  425.  
  426. /*
  427. vitems--;
  428. */
  429. _bmuguts(som,sample,&bx,&by,&bd);
  430.  
  431. if ( wantarray ) XPUSHs(newSVnv(bd));
  432.  
  433. for ( i=0 ; i<nitems ; i++ ) n[i] = -1;
  434. neiguts(som,sigma,bx,by,n);
  435.  
  436. _adjustn(som,l,sigma,n,sample);
  437. }
  438.  
  439. }
  440. }
  441.  
  442.  
  443. Safefree(n);
  444. Safefree(org);
  445. Safefree(veg);
  446.  
  447. PUTBACK;
  448. }
  449.  
  450. void _som_FREEZE(SV* self,SV* cloning) {
  451. IV x,y,z;
  452. MAGIC *mg;
  453. SOM_Map *m;
  454. SOM_Array *a;
  455. SOM_Vector *v;
  456. SOM_GENERIC *som;
  457. dXSARGS;
  458.  
  459. PERL_UNUSED_VAR(items); /* -W */
  460. sp = mark;
  461.  
  462. if ( !SvTRUE(cloning) ) {
  463.  
  464. if ( (mg = selfmagic(self)) != NULL) {
  465.  
  466. /*
  467. * we should get here on the first pass. this is where we
  468. * serialize the hash seen from perl.
  469. */
  470.  
  471. XPUSHs(INT2PTR(SV*,newSVpvn("i wanna be a cowboy",19)));
  472.  
  473. }
  474. else if ( SvTYPE(SvRV(self)) == SVt_PVMG ) {
  475.  
  476. /*
  477. * this should be the second pass. here we need to serialize
  478. * the tied part not seen from the perl side.
  479. */
  480.  
  481. som = INT2PTR(SOM_GENERIC*,self2iv(self));
  482.  
  483. XPUSHs( INT2PTR(SV*,newSVpvn(
  484. "beat me whip me make me code badly",34)) );
  485. XPUSHs( newRV_noinc(newSViv(som->type)) );
  486. XPUSHs( newRV_noinc(newSViv(som->X)) );
  487. XPUSHs( newRV_noinc(newSViv(som->Y)) );
  488. XPUSHs( newRV_noinc(newSViv(som->Z)) );
  489. XPUSHs( newRV_noinc(newSVnv(som->R)) );
  490. XPUSHs( newRV_noinc(newSVnv(som->Sigma0)) );
  491. XPUSHs( newRV_noinc(newSVnv(som->L0)) );
  492. XPUSHs( newRV_noinc(newSVnv(som->LAMBDA)) );
  493. XPUSHs( newRV_noinc(newSVnv(som->T)) );
  494. XPUSHs( newRV_noinc(som->output_dim) );
  495. XPUSHs( newRV_noinc((SV*)som->labels) );
  496.  
  497. m = som->map;
  498. for ( x=som->X-1 ; x>=0 ; x-- ) {
  499. a = (&m->array)[x];
  500. for ( y=som->Y-1 ; y>=0 ; y-- ) {
  501. v = (&a->vector)[y];
  502. for ( z=som->Z-1 ; z>=0 ; z-- ) {
  503. XPUSHs(newRV_noinc(newSVnv(
  504. (&v->element)[z])));
  505. }
  506. }
  507. }
  508. }
  509. else {
  510. croak("i wanna run with scissors!");
  511. }
  512. } /* cloning */
  513. PUTBACK;
  514. }
  515.  
  516. void _som_THAW(SV* self,SV* cloning,SV* serialized) {
  517. IV x,y,z,i;
  518. SV *rrr;
  519. HV *stash;
  520. SOM_Map *m;
  521. SOM_Array *a;
  522. SOM_Vector *v;
  523. SOM_GENERIC *som;
  524. dXSARGS;
  525.  
  526. PERL_UNUSED_VAR(serialized); /* -W */
  527.  
  528. if (!SvTRUE(cloning)) {
  529.  
  530. if ( SvTYPE(SvRV(self)) == SVt_PVMG ) {
  531. Newxz(som,1,SOM_GENERIC);
  532.  
  533. som->type = SvIV(SvRV(ST(3)));
  534. som->X = SvIV(SvRV(ST(4)));
  535. som->Y = SvIV(SvRV(ST(5)));
  536. som->Z = SvIV(SvRV(ST(6)));
  537. som->R = SvNV(SvRV(ST(7)));
  538. som->Sigma0 = SvNV(SvRV(ST(8)));
  539. som->L0 = SvNV(SvRV(ST(9)));
  540. som->LAMBDA = SvNV(SvRV(ST(10)));
  541. som->T = SvNV(SvRV(ST(11)));
  542. som->output_dim = newSVsv(SvRV(ST(12)));
  543. som->labels = (AV*)SvRV(ST(13));
  544.  
  545. som->map = _make_map( som );
  546.  
  547. i = 14;
  548. m = som->map;
  549. for ( x=som->X-1 ; x>=0 ; x-- ) {
  550. a = (&m->array)[x];
  551. for ( y=som->Y-1 ; y>=0 ; y-- ) {
  552. v = (&a->vector)[y];
  553. for ( z=som->Z-1 ; z>=0 ; z-- ) {
  554. /*
  555. (&v->element)[z] =
  556. SvNV(SvRV(ST(i++)));
  557. */
  558. rrr = SvRV(ST(i++));
  559. (&v->element)[z] = SvNV(rrr);
  560. }
  561. }
  562. }
  563.  
  564. SvSetSV( SvRV(self), sv_2mortal(newSViv((IV)PTR2IV(som))) );
  565.  
  566. stash = SvSTASH(SvRV(self));
  567. som->ref = sv_bless(newRV_inc((SV*)self),stash);
  568.  
  569. }
  570.  
  571. else if ( SvTYPE(SvRV(self)) != SVt_PVHV )
  572. croak("you'll put an eye out!");
  573.  
  574. } /* cloning */
  575.  
  576. PERL_UNUSED_VAR(items); /* -W */
  577. sp = mark;
  578. PUTBACK;
  579. }
  580.  
  581. SV* _som_FETCH(SV* self,SV* key) {
  582. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("map",3) ) ) ) {
  583. SOM_GENERIC *som = INT2PTR(SOM_Rect*,self2iv(self));
  584. SvREFCNT_inc(som->map->ref);
  585. return som->map->ref;
  586. }
  587. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_X",2) ) ) )
  588. return newSViv(tied2ptr(self)->X);
  589. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_Y",2) ) ) )
  590. return newSViv(tied2ptr(self)->Y);
  591. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_Z",2) ) ) )
  592. return newSViv(tied2ptr(self)->Z);
  593. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_R",2) ) ) )
  594. return newSVnv(tied2ptr(self)->R);
  595. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_L0",3) ) ) )
  596. return newSVnv(tied2ptr(self)->L0);
  597. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_Sigma0",7) ) ) )
  598. return newSVnv(tied2ptr(self)->Sigma0);
  599. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("output_dim",10) ) ) )
  600. return newSVsv(tied2ptr(self)->output_dim);
  601. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("LAMBDA",6) ) ) )
  602. return newSVnv(tied2ptr(self)->LAMBDA);
  603. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("T",1) ) ) )
  604. return newSVnv(tied2ptr(self)->T);
  605. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("labels",6) ) ) )
  606. return newRV_inc((SV*)(tied2ptr(self)->labels));
  607. croak("%s not accessible for read", SvPV_nolen(key));
  608. }
  609.  
  610. SV* _som_STORE(SV* self,SV* key,SV* val) {
  611. if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_X",2) ) ) )
  612. tied2ptr(self)->X = SvIV(val);
  613. else if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_Y",2) ) ) )
  614. tied2ptr(self)->Y = SvIV(val);
  615. else if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_Z",2) ) ) )
  616. tied2ptr(self)->Z = SvIV(val);
  617. else if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_R",2) ) ) )
  618. tied2ptr(self)->R = SvNV(val);
  619. else if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_L0",3) ) ) )
  620. tied2ptr(self)->L0 = SvNV(val);
  621. else if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("_Sigma0",7) ) ) )
  622. tied2ptr(self)->Sigma0 = SvNV(val);
  623. else if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("output_dim",10) ) ) )
  624. tied2ptr(self)->output_dim = newSVsv(val);
  625. else if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("LAMBDA",6) ) ) )
  626. tied2ptr(self)->LAMBDA = SvNV(val);
  627. else if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("T",1) ) ) )
  628. tied2ptr(self)->T = SvNV(val);
  629. else if ( !sv_cmp( key, INT2PTR(SV*,newSVpvn("map",3) ) ) )
  630. croak("cant assign to map");
  631. else
  632. croak("%s not accessible for write", SvPV_nolen(key));
  633. return val;
  634. }
  635.  
  636. SV* _som_FIRSTKEY() {
  637. return INT2PTR(SV*,newSVpvn("_X",2));
  638. }
  639.  
  640. SV* _som_NEXTKEY(SV* prev) {
  641. if ( strEQ( SvPVX(prev), "_X" ) )
  642. return INT2PTR(SV*,newSVpvn("_Y",2));
  643. else if ( strEQ( SvPVX(prev), "_Y" ) )
  644. return INT2PTR(SV*,newSVpvn("_Z",2));
  645. else if ( strEQ( SvPVX(prev), "_Z" ) )
  646. return INT2PTR(SV*,newSVpvn("_R",2));
  647. else if ( strEQ( SvPVX(prev), "_R" ) )
  648. return INT2PTR(SV*,newSVpvn("_Sigma0",7));
  649. else if ( strEQ( SvPVX(prev), "_Sigma0" ) )
  650. return INT2PTR(SV*,newSVpvn("_L0",3));
  651. else if ( strEQ( SvPVX(prev), "_L0" ) )
  652. return INT2PTR(SV*,newSVpvn("LAMBDA",6));
  653. else if ( strEQ( SvPVX(prev), "LAMBDA" ) )
  654. return INT2PTR(SV*,newSVpvn("T",1));
  655. else if ( strEQ( SvPVX(prev), "T" ) )
  656. return INT2PTR(SV*,newSVpvn("labels",6));
  657. else if ( strEQ( SvPVX(prev), "labels" ) )
  658. return INT2PTR(SV*,newSVpvn("map",3));
  659. return &PL_sv_undef;
  660. }
  661.  
  662. void _som_DESTROY(SV* self) {
  663. IV iv;
  664. SV *ref;
  665. SOM_Map *map;
  666. SOM_GENERIC *som;
  667.  
  668. if ( !SvROK(self) )
  669. return;
  670. ref = SvRV(self);
  671. if ( !SvIOK(ref) )
  672. return;
  673. iv = SvIV(ref);
  674. som = INT2PTR(SOM_GENERIC*,iv);
  675. if ( !som )
  676. return;
  677. map = som->map;
  678. /* more to do here ? */
  679. }
  680.  
  681.  
  682.  
  683. /*
  684. * rect functions
  685. */
  686.  
  687. void _rect_neiguts(SOM_Rect* som,NV sigma,IV X0,IV Y0,NV* n) {
  688. IV x,y,X,Y;
  689. NV d2,s2;
  690.  
  691. X = som->X;
  692. Y = som->Y;
  693.  
  694. s2 = sigma * sigma;
  695.  
  696. for ( x=0 ; x<X ; x++ ) {
  697. for ( y=0 ; y<Y ; y++ ) {
  698. d2 = (x-X0)*(x-X0)+(y-Y0)*(y-Y0);
  699. if (d2 <= s2) n[x*Y+y] = sqrt(d2);
  700. }
  701. }
  702. }
  703.  
  704. void _rect_new(const char* class,...) {
  705. IV i;
  706. NV sigma0,rate;
  707. SV *tie,*rv,*key,*val,*od,*sclass;
  708. HV *options,*hash,*stash;
  709. char *begptr,*endptr,*xstart,*ystart,*yend;
  710. STRLEN len;
  711. SOM_GENERIC *som;
  712. dXSARGS;
  713.  
  714. if ( (items & 1) ^ 1 )
  715. croak( "Weird number of arguments\n" );
  716.  
  717. options = newHV();
  718. for ( i=1 ; i<items ; i+=2 ) {
  719. key = ST(i);
  720. val = ST(i+1);
  721. len = sv_len(key);
  722. hv_store( options, SvPV_nolen(key), len, val, 0 );
  723. }
  724.  
  725. if ( !hv_exists( options, "input_dim", 9 ) )
  726. croak( "no input_dim argument" );
  727. if ( !hv_exists( options, "output_dim", 10 ) )
  728. croak( "no output_dim argument" );
  729.  
  730. Newxz(som,1,SOM_GENERIC);
  731.  
  732. od = newSVsv(*hv_fetch(options,"output_dim",10,FALSE));
  733. som->output_dim = od;
  734.  
  735. begptr = SvPV_force(od,SvLEN(od));
  736. endptr = SvEND(od) - 1; /* allow for terminating character */
  737. if ( endptr < begptr )
  738. croak("brain damage!!!");
  739.  
  740. xstart = begptr;
  741. if ( !isDIGIT((char)*xstart) )
  742. croak("no x-dimension found");
  743. som->X = Atol(xstart);
  744.  
  745. ystart = yend = endptr;
  746. if ( !isDIGIT((char)*ystart) )
  747. croak("no y-dimension found");
  748. while (--ystart >= begptr)
  749. if ( !isDIGIT((char)*ystart) )
  750. break;
  751. som->Y = Atol(++ystart);
  752.  
  753. som->Z = SvIV(*hv_fetch(options,"input_dim",9,FALSE));
  754.  
  755. som->R = som->X > som->Y
  756. ? som->Y / 2.0
  757. : som->X / 2.0;
  758.  
  759. if ( hv_exists( options, "sigma0", 6 ) ) {
  760. sigma0 = SvNV(*hv_fetch(options,"sigma0",6,0));
  761. if ( sigma0 )
  762. som->Sigma0 = sigma0;
  763. else
  764. som->Sigma0 = som->R;
  765. }
  766. else
  767. som->Sigma0 = som->R;
  768.  
  769. if ( hv_exists( options, "learning_rate", 13 ) ) {
  770. rate = SvNV(*hv_fetch(options,"learning_rate",13,0));
  771. if ( rate )
  772. som->L0 = rate;
  773. else
  774. som->L0 = 0.1;
  775. }
  776. else
  777. som->L0 = 0.1;
  778.  
  779. som->map = _make_map(som);
  780. som->labels = newAV();
  781.  
  782. sclass = sv_2mortal(newSVpvf("%s",class));
  783. if (!sv_cmp(sclass,INT2PTR(
  784. SV*,newSVpvn("AI::NeuralNet::FastSOM::Rect",28))))
  785. som->type = SOMType_Rect;
  786. /*
  787. else if (!sv_cmp(sclass,INT2PTR(
  788. SV*,newSVpvn("AI::NeuralNet::FastSOM::Hexa",28))))
  789. som->type = SOMType_Hexa;
  790. */
  791. else if (!sv_cmp(sclass,INT2PTR(
  792. SV*,newSVpvn("AI::NeuralNet::FastSOM::Torus",29))))
  793. som->type = SOMType_Torus;
  794. else
  795. croak("unknown type");
  796.  
  797. hash = (HV*)sv_2mortal((SV*)newHV());
  798. tie = newRV_noinc(newSViv(PTR2IV(som)));
  799. stash = gv_stashpv(class, GV_ADD);
  800. sv_bless(tie, stash);
  801. hv_magic(hash, (GV*)tie, PERL_MAGIC_tied);
  802. rv = sv_bless(newRV_noinc((SV*)hash),stash);
  803.  
  804. som->ref = rv;
  805.  
  806. /*
  807. * here 'hash' is the object seen from the perl side.
  808. * 'tie' is what we see from the c side when accessing the tied
  809. * functionality.
  810. */
  811.  
  812. sp = mark;
  813. XPUSHs(rv);
  814. PUTBACK;
  815. }
  816.  
  817. SV* _rect_radius(SV* self) {
  818. MAGIC *mg;
  819. SOM_GENERIC *som;
  820.  
  821. if ( !(mg = selfmagic(self)) )
  822. croak("self has no magic!\n");
  823. som = self2somptr(self,mg);
  824.  
  825. return newSVnv(som->R);
  826. }
  827.  
  828.  
  829.  
  830. /*
  831. * torus functions
  832. */
  833.  
  834. void _torus_neiguts(SOM_Torus* som,NV sigma,IV X0,IV Y0,NV* n) {
  835. IV x,y,X,Y;
  836. NV d2,s2;
  837.  
  838. X = som->X;
  839. Y = som->Y;
  840.  
  841. s2 = sigma * sigma;
  842.  
  843. for ( x=0 ; x<X ; x++ ) {
  844. for ( y=0 ; y<Y ; y++ ) {
  845.  
  846. /*
  847. * which one of these should "win"?
  848. */
  849.  
  850. d2 = (x-X0)*(x-X0) + (y-Y0)*(y-Y0);
  851. if (d2 <= s2) n[x*Y+y] = sqrt(d2);
  852.  
  853. d2 = (x-X-X0)*(x-X-X0) + (y-Y0)*(y-Y0);
  854. if (d2 <= s2) n[x*Y+y] = sqrt(d2);
  855.  
  856. d2 = (x+X-X0)*(x+X-X0) + (y-Y0)*(y-Y0);
  857. if (d2 <= s2) n[x*Y+y] = sqrt(d2);
  858.  
  859. d2 = (x-X0)*(x-X0) + (y-Y-Y0)*(y-Y-Y0);
  860. if (d2 <= s2) n[x*Y+y] = sqrt(d2);
  861.  
  862. d2 = (x-X0)*(x-X0) + (y+Y-Y0)*(y+Y-Y0);
  863. if (d2 <= s2) n[x*Y+y] = sqrt(d2);
  864. }
  865. }
  866. }
  867.  
  868. /* http://www.ai-junkie.com/ann/som/som3.html */
  869.  
  870.  
  871.  
  872. /*
  873. * hexa functions
  874. */
  875.  
  876. void _hexa_new(const char* class) {
  877. IV i;
  878. SV *key,*val,*od,*tie,*rv;
  879. NV sigma0,rate;
  880. HV *options,*hash,*stash;
  881. STRLEN len;
  882. SOM_Hexa *hexa;
  883. dXSARGS;
  884.  
  885. if ( (items & 1) ^ 1 )
  886. croak( "Weird number of arguments\n" );
  887.  
  888. options = newHV();
  889. for ( i=1 ; i<items ; i+=2 ) {
  890. key = ST(i);
  891. val = ST(i+1);
  892. len = sv_len(key);
  893. hv_store( options, SvPV_nolen(key), len, val, 0 );
  894. }
  895.  
  896. if ( !hv_exists( options, "input_dim", 9 ) )
  897. croak( "no input_dim argument" );
  898. if ( !hv_exists( options, "output_dim", 10 ) )
  899. croak( "no ouput_dim argument" );
  900.  
  901. Newxz(hexa,1,SOM_Hexa);
  902.  
  903. od = newSVsv(*hv_fetch(options,"output_dim",10,FALSE));
  904. hexa->output_dim = od;
  905.  
  906. hexa->X=SvIV(*hv_fetch(options,"output_dim",10,FALSE));
  907. hexa->Z=SvIV(*hv_fetch(options,"input_dim",9,FALSE));
  908.  
  909. hexa->Y = hexa->X;
  910. hexa->R = hexa->X / 2.0;
  911.  
  912. if ( hv_exists( options, "sigma0", 6 ) ) {
  913. sigma0 = SvNV(*hv_fetch(options,"sigma0",6,0));
  914. if ( sigma0 )
  915. hexa->Sigma0 = sigma0;
  916. else
  917. hexa->Sigma0 = hexa->R;
  918. }
  919. else
  920. hexa->Sigma0 = hexa->R;
  921.  
  922. if ( hv_exists( options, "learning_rate", 13 ) ) {
  923. rate = SvNV(*hv_fetch(options,"learning_rate",13,0));
  924. if ( rate )
  925. hexa->L0 = rate;
  926. else
  927. hexa->L0 = 0.1;
  928. }
  929. else
  930. hexa->L0 = 0.1;
  931.  
  932. hexa->map = _make_map( hexa );
  933. hexa->labels = newAV();
  934.  
  935. hexa->type = SOMType_Hexa;
  936.  
  937. hash = (HV*)sv_2mortal((SV*)newHV());
  938. tie = newRV_noinc(newSViv(PTR2IV(hexa)));
  939. stash = gv_stashpv(class, GV_ADD);
  940. sv_bless(tie, stash);
  941. hv_magic(hash, (GV*)tie, PERL_MAGIC_tied);
  942. rv = sv_bless(newRV_noinc((SV*)hash),stash);
  943.  
  944. hexa->ref = rv;
  945.  
  946. sp = mark;
  947. XPUSHs(rv);
  948. PUTBACK;
  949. }
  950.  
  951. NV _hexa_distance(NV x1,NV y1,NV x2,NV y2) {
  952. NV tmp,dx,dy;
  953.  
  954. if ( x1+y1 > x2+y2 ) {
  955. tmp=x1; x1=x2; x2=tmp;
  956. tmp=y1; y1=y2; y2=tmp;
  957. }
  958.  
  959. dx = x2 - x1;
  960. dy = y2 - y1;
  961.  
  962. if ( dx<0 || dy<0 )
  963. return abs(dx) + abs(dy);
  964. else
  965. return dx<dy ? dy : dx;
  966. }
  967.  
  968. void _hexa_neiguts(SOM_Hexa* som,NV sigma,IV X0,IV Y0,NV* n) {
  969. IV x,y,X,Y;
  970. NV d;
  971.  
  972. X = som->X;
  973. Y = som->Y;
  974.  
  975. for ( x=0 ; x<X ; x++ ) {
  976. for ( y=0 ; y<Y ; y++ ) {
  977. d = _hexa_distance(X0,Y0,x,y);
  978. if (d <= sigma) n[x*Y+y] = d;
  979. }
  980. }
  981. }
  982.  
  983.  
  984.  
  985. /*
  986. * map functions
  987. */
  988.  
  989. SV* _map_FETCH(SV* self,I32 x) {
  990. SOM_Map *map;
  991. SOM_Array *array;
  992.  
  993. map = INT2PTR(SOM_Map*,self2iv(self));
  994. array = (&map->array)[x];
  995. SvREFCNT_inc(array->ref);
  996. return array->ref;
  997. }
  998.  
  999. void _map_DESTROY(SV* self) {
  1000. SOM_Map *map;
  1001.  
  1002. map = INT2PTR(SOM_Map*,self2iv(self));
  1003. /* need more done here ? */
  1004. Safefree( map );
  1005. }
  1006.  
  1007.  
  1008.  
  1009. /*
  1010. * array functions
  1011. */
  1012.  
  1013. void _array_STORE(SV* self,IV y,SV* aref) {
  1014. I32 len;
  1015. NV tmp;
  1016. AV *src;
  1017. SV **ptr;
  1018. SOM_Array *array;
  1019. SOM_Vector *dst;
  1020.  
  1021. if ( SvTYPE( SvRV(aref) ) != SVt_PVAV )
  1022. croak("value to store is not a reference to an array\n");
  1023. src = (AV*)SvRV( aref );
  1024.  
  1025. array = INT2PTR(SOM_Array*,self2iv(self));
  1026. dst = (&array->vector)[y];
  1027.  
  1028. if ( y < 0 )
  1029. croak("storing y-index < 0 not supported\n");
  1030. if ( y >= array->Y )
  1031. croak("storing y-index > y-dimension of SOM\n");
  1032.  
  1033. len = av_len( src );
  1034. if ( len < 0 )
  1035. croak("cant store empty vector\n");
  1036. if ( len+1 > array->Z )
  1037. croak("vector too long\n");
  1038. if ( len+1 < array->Z )
  1039. croak("vector too short\n");
  1040.  
  1041. for ( ; len >= 0 ; len-- ) {
  1042. ptr = av_fetch( src, len, 0 );
  1043. if ( ptr == NULL )
  1044. croak("NULL ptr!\n");
  1045. tmp = SvNV(*ptr);
  1046. (&dst->element)[len] = tmp;
  1047. }
  1048. }
  1049.  
  1050. SV* _array_FETCH(SV* self,I32 y) {
  1051. SOM_Array *array;
  1052. SOM_Vector *vector;
  1053.  
  1054. array = INT2PTR(SOM_Array*,self2iv(self));
  1055. vector = (&array->vector)[y];
  1056. SvREFCNT_inc(vector->ref);
  1057. return vector->ref;
  1058. }
  1059.  
  1060. void _array_DESTROY(SV* self) {
  1061. SOM_Array *array;
  1062.  
  1063. array = INT2PTR(SOM_Array*,self2iv(self));
  1064. /* need more done here ? */
  1065. Safefree( array );
  1066. }
  1067.  
  1068.  
  1069.  
  1070. /*
  1071. * vector functions
  1072. */
  1073.  
  1074. void _vector_STORE(SV* self,I32 z,NV val) {
  1075. SOM_Vector *vector;
  1076.  
  1077. vector = INT2PTR(SOM_Vector*,self2iv(self));
  1078. if ( z < 0 )
  1079. croak("negative z-index not supported\n");
  1080. if ( z >= vector->Z )
  1081. croak("z-index larger than vector dimension\n");
  1082. (&vector->element)[z] = val;
  1083. }
  1084.  
  1085. SV* _vector_FETCH(SV* self,I32 z) {
  1086. SOM_Vector *vector;
  1087.  
  1088. vector = INT2PTR(SOM_Vector*,self2iv(self));
  1089. return newSVnv((&vector->element)[z]);
  1090. }
  1091.  
  1092. void _vector_DESTROY(SV* self) {
  1093. SOM_Vector *vector;
  1094.  
  1095. vector = INT2PTR(SOM_Vector*,self2iv(self));
  1096. /* need more done here ? */
  1097. Safefree( vector );
  1098. }
  1099.  
  1100.  
  1101.  
  1102. /*
  1103. *
  1104. * End of C code. Begin XS.
  1105. *
  1106. */
  1107.  
  1108.  
  1109.  
  1110. MODULE = AI::NeuralNet::FastSOM PACKAGE = AI::NeuralNet::FastSOM
  1111.  
  1112. PROTOTYPES: DISABLE
  1113.  
  1114.  
  1115. void
  1116. train (self, epochs, ...)
  1117. SV * self
  1118. IV epochs
  1119. PREINIT:
  1120. I32* temp;
  1121. temp = PL_markstack_ptr++;
  1122. _som_train(self,epochs);
  1123. if (PL_markstack_ptr != temp) {
  1124. PL_markstack_ptr = temp;
  1125. XSRETURN_EMPTY;
  1126. }
  1127. return;
  1128.  
  1129. void
  1130. bmu (self, sample)
  1131. SV * self
  1132. AV * sample
  1133. PREINIT:
  1134. I32* temp;
  1135. PPCODE:
  1136. temp = PL_markstack_ptr++;
  1137. _som_bmu(self,sample);
  1138. if (PL_markstack_ptr != temp) {
  1139. PL_markstack_ptr = temp;
  1140. XSRETURN_EMPTY;
  1141. }
  1142. return;
  1143.  
  1144. SV *
  1145. map (self)
  1146. SV * self
  1147. PREINIT:
  1148. SV* rv;
  1149. CODE:
  1150. rv = _som_map(self);
  1151. ST(0) = rv;
  1152. sv_2mortal(ST(0));
  1153.  
  1154. SV *
  1155. output_dim (self)
  1156. SV * self
  1157. PREINIT:
  1158. SV* rv;
  1159. CODE:
  1160. rv = _som_output_dim(self);
  1161. ST(0) = rv;
  1162. sv_2mortal(ST(0));
  1163.  
  1164. void
  1165. _adjust (self, l, sigma, unit, v)
  1166. SV * self
  1167. NV l
  1168. NV sigma
  1169. AV * unit
  1170. AV * v
  1171. PREINIT:
  1172. I32* temp;
  1173. PPCODE:
  1174. temp = PL_markstack_ptr++;
  1175. _adjust(self, l, sigma, unit, v);
  1176. if (PL_markstack_ptr != temp) {
  1177. PL_markstack_ptr = temp;
  1178. XSRETURN_EMPTY;
  1179. }
  1180. return;
  1181.  
  1182. void
  1183. STORABLE_freeze (self, cloning)
  1184. SV * self
  1185. SV * cloning
  1186. PREINIT:
  1187. I32* temp;
  1188. PPCODE:
  1189. temp = PL_markstack_ptr++;
  1190. _som_FREEZE(self,cloning);
  1191. if (PL_markstack_ptr != temp) {
  1192. PL_markstack_ptr = temp;
  1193. XSRETURN_EMPTY;
  1194. }
  1195. return;
  1196.  
  1197. void
  1198. STORABLE_thaw (self, cloning, serialized, ...)
  1199. SV * self
  1200. SV * cloning
  1201. SV * serialized
  1202. PREINIT:
  1203. I32* temp;
  1204. PPCODE:
  1205. temp = PL_markstack_ptr++;
  1206. _som_THAW(self,cloning,serialized);
  1207. if (PL_markstack_ptr != temp) {
  1208. PL_markstack_ptr = temp;
  1209. XSRETURN_UNDEF;
  1210. }
  1211. return;
  1212.  
  1213. SV *
  1214. FETCH (self, key)
  1215. SV * self
  1216. SV * key
  1217. PREINIT:
  1218. SV* rv;
  1219. CODE:
  1220. rv = _som_FETCH(self, key);
  1221. ST(0) = rv;
  1222. sv_2mortal(ST(0));
  1223.  
  1224. void
  1225. STORE (self, key, val)
  1226. SV * self
  1227. SV * key
  1228. SV * val
  1229. PREINIT:
  1230. I32* temp;
  1231. PPCODE:
  1232. temp = PL_markstack_ptr++;
  1233. _som_STORE(self, key, val);
  1234. if (PL_markstack_ptr != temp) {
  1235. PL_markstack_ptr = temp;
  1236. XSRETURN_EMPTY;
  1237. }
  1238. return;
  1239.  
  1240. SV *
  1241. FIRSTKEY (self)
  1242. SV * self
  1243. PREINIT:
  1244. SV* rv;
  1245. CODE:
  1246. if (!self) croak("avoiding -Wextra");
  1247. rv = _som_FIRSTKEY();
  1248. ST(0) = rv;
  1249. sv_2mortal(ST(0));
  1250.  
  1251. SV *
  1252. NEXTKEY (self,prev)
  1253. SV * self
  1254. SV * prev
  1255. PREINIT:
  1256. SV* rv;
  1257. CODE:
  1258. if (!self) croak("avoiding -Wextra");
  1259. rv = _som_NEXTKEY(prev);
  1260. ST(0) = rv;
  1261. sv_2mortal(ST(0));
  1262.  
  1263. void
  1264. DESTROY (obj)
  1265. SV * obj
  1266. PREINIT:
  1267. I32* temp;
  1268. PPCODE:
  1269. temp = PL_markstack_ptr++;
  1270. _som_DESTROY(obj);
  1271. if (PL_markstack_ptr != temp) {
  1272. PL_markstack_ptr = temp;
  1273. XSRETURN_EMPTY;
  1274. }
  1275. return;
  1276.  
  1277.  
  1278.  
  1279. MODULE = AI::NeuralNet::FastSOM PACKAGE = AI::NeuralNet::FastSOM::Rect
  1280.  
  1281. PROTOTYPES: DISABLE
  1282.  
  1283.  
  1284. void
  1285. new (class, ...)
  1286. const char * class
  1287. PREINIT:
  1288. I32* temp;
  1289. PPCODE:
  1290. temp = PL_markstack_ptr++;
  1291. _rect_new(class);
  1292. if (PL_markstack_ptr != temp) {
  1293. PL_markstack_ptr = temp;
  1294. XSRETURN_EMPTY;
  1295. }
  1296. return;
  1297.  
  1298. AV *
  1299. neighbors (self, sigma, X, Y, ...)
  1300. SV * self
  1301. NV sigma
  1302. IV X
  1303. IV Y
  1304. PREINIT:
  1305. I32* temp;
  1306. CODE:
  1307. temp = PL_markstack_ptr++;
  1308. RETVAL = _neighbors(self, sigma, X, Y);
  1309. PL_markstack_ptr = temp;
  1310. OUTPUT:
  1311. RETVAL
  1312.  
  1313. SV *
  1314. radius (self)
  1315. SV * self
  1316. PREINIT:
  1317. SV* rv;
  1318. CODE:
  1319. rv = _rect_radius(self);
  1320. ST(0) = rv;
  1321. sv_2mortal(ST(0));
  1322.  
  1323.  
  1324.  
  1325.  
  1326. MODULE = AI::NeuralNet::FastSOM PACKAGE = AI::NeuralNet::FastSOM::Torus
  1327.  
  1328. PROTOTYPES: DISABLE
  1329.  
  1330.  
  1331. AV *
  1332. neighbors (self, sigma, X, Y, ...)
  1333. SV * self
  1334. NV sigma
  1335. IV X
  1336. IV Y
  1337. PREINIT:
  1338. I32* temp;
  1339. CODE:
  1340. temp = PL_markstack_ptr++;
  1341. RETVAL = _neighbors(self, sigma, X, Y);
  1342. PL_markstack_ptr = temp;
  1343. OUTPUT:
  1344. RETVAL
  1345.  
  1346.  
  1347.  
  1348. MODULE = AI::NeuralNet::FastSOM PACKAGE = AI::NeuralNet::FastSOM::Hexa
  1349.  
  1350. PROTOTYPES: DISABLE
  1351.  
  1352.  
  1353. void
  1354. new (class, ...)
  1355. const char * class
  1356. PREINIT:
  1357. I32* temp;
  1358. PPCODE:
  1359. temp = PL_markstack_ptr++;
  1360. _hexa_new(class);
  1361. if (PL_markstack_ptr != temp) {
  1362. PL_markstack_ptr = temp;
  1363. XSRETURN_EMPTY;
  1364. }
  1365. return;
  1366.  
  1367. AV *
  1368. neighbors (self, sigma, X, Y, ...)
  1369. SV * self
  1370. NV sigma
  1371. IV X
  1372. IV Y
  1373. PREINIT:
  1374. I32* temp;
  1375. CODE:
  1376. temp = PL_markstack_ptr++;
  1377. RETVAL = _neighbors(self, sigma, X, Y);
  1378. PL_markstack_ptr = temp;
  1379. OUTPUT:
  1380. RETVAL
  1381.  
  1382.  
  1383.  
  1384. MODULE = AI::NeuralNet::FastSOM PACKAGE = AI::NeuralNet::FastSOM::Utils
  1385.  
  1386. PROTOTYPES: DISABLE
  1387.  
  1388.  
  1389. NV
  1390. vector_distance (V1, V2)
  1391. AV_SPECIAL* V1;
  1392. AV_SPECIAL* V2;
  1393. PREINIT:
  1394. NV rv;
  1395. CODE:
  1396. rv = _vector_distance((AV*)V1, (AV*)V2);
  1397. XSprePUSH; PUSHn((NV)rv);
  1398.  
  1399.  
  1400.  
  1401. MODULE = AI::NeuralNet::FastSOM PACKAGE = AI::NeuralNet::FastSOM::MAP
  1402.  
  1403. PROTOTYPES: DISABLE
  1404.  
  1405.  
  1406. SV *
  1407. FETCH (self, x)
  1408. SV * self
  1409. I32 x
  1410. PREINIT:
  1411. SV* rv;
  1412. CODE:
  1413. rv = _map_FETCH(self, x);
  1414. ST(0) = rv;
  1415. sv_2mortal(ST(0));
  1416.  
  1417. IV
  1418. FETCHSIZE (self)
  1419. SV * self
  1420. PREINIT:
  1421. IV rv;
  1422. CODE:
  1423. rv = (INT2PTR(SOM_Map*,self2iv(self)))->X;
  1424. XSprePUSH; PUSHi((IV)rv);
  1425.  
  1426. void
  1427. DESTROY (obj)
  1428. SV * obj
  1429. PREINIT:
  1430. I32* temp;
  1431. PPCODE:
  1432. temp = PL_markstack_ptr++;
  1433. _map_DESTROY(obj);
  1434. if (PL_markstack_ptr != temp) {
  1435. PL_markstack_ptr = temp;
  1436. XSRETURN_EMPTY;
  1437. }
  1438. return;
  1439.  
  1440.  
  1441.  
  1442. MODULE = AI::NeuralNet::FastSOM PACKAGE = AI::NeuralNet::FastSOM::ARRAY
  1443.  
  1444. PROTOTYPES: DISABLE
  1445.  
  1446.  
  1447. void
  1448. STORE (self, y, aref)
  1449. SV * self
  1450. IV y
  1451. SV * aref
  1452. PREINIT:
  1453. I32* temp;
  1454. PPCODE:
  1455. temp = PL_markstack_ptr++;
  1456. _array_STORE(self, y, aref);
  1457. if (PL_markstack_ptr != temp) {
  1458. PL_markstack_ptr = temp;
  1459. XSRETURN_EMPTY;
  1460. }
  1461. return;
  1462.  
  1463. SV *
  1464. FETCH (self, y)
  1465. SV * self
  1466. I32 y
  1467. PREINIT:
  1468. SV* rv;
  1469. CODE:
  1470. rv = _array_FETCH(self, y);
  1471. ST(0) = rv;
  1472. sv_2mortal(ST(0));
  1473.  
  1474. IV
  1475. FETCHSIZE (self)
  1476. SV * self
  1477. PREINIT:
  1478. IV rv;
  1479. CODE:
  1480. rv = (INT2PTR(SOM_Array*,self2iv(self)))->Y;
  1481. XSprePUSH; PUSHi((IV)rv);
  1482.  
  1483. void
  1484. DESTROY (obj)
  1485. SV * obj
  1486. PREINIT:
  1487. I32* temp;
  1488. PPCODE:
  1489. temp = PL_markstack_ptr++;
  1490. _array_DESTROY(obj);
  1491. if (PL_markstack_ptr != temp) {
  1492. PL_markstack_ptr = temp;
  1493. XSRETURN_EMPTY;
  1494. }
  1495. return;
  1496.  
  1497.  
  1498.  
  1499. MODULE = AI::NeuralNet::FastSOM PACKAGE = AI::NeuralNet::FastSOM::VECTOR
  1500.  
  1501. PROTOTYPES: DISABLE
  1502.  
  1503.  
  1504. void
  1505. STORE (self, z, val)
  1506. SV * self
  1507. I32 z
  1508. NV val
  1509. PREINIT:
  1510. I32* temp;
  1511. PPCODE:
  1512. temp = PL_markstack_ptr++;
  1513. _vector_STORE(self, z, val);
  1514. if (PL_markstack_ptr != temp) {
  1515. PL_markstack_ptr = temp;
  1516. XSRETURN_EMPTY;
  1517. }
  1518. return;
  1519.  
  1520. SV *
  1521. FETCH (self, z)
  1522. SV * self
  1523. I32 z
  1524. PREINIT:
  1525. SV* rv;
  1526. CODE:
  1527. rv = _vector_FETCH(self, z);
  1528. ST(0) = rv;
  1529. sv_2mortal(ST(0));
  1530.  
  1531. IV
  1532. FETCHSIZE (self)
  1533. SV * self
  1534. PREINIT:
  1535. IV rv;
  1536. CODE:
  1537. rv = (INT2PTR(SOM_Vector*,self2iv(self)))->Z;
  1538. XSprePUSH; PUSHi((IV)rv);
  1539.  
  1540. void
  1541. DESTROY (obj)
  1542. SV * obj
  1543. PREINIT:
  1544. I32* temp;
  1545. PPCODE:
  1546. temp = PL_markstack_ptr++;
  1547. _vector_DESTROY(obj);
  1548. if (PL_markstack_ptr != temp) {
  1549. PL_markstack_ptr = temp;
  1550. XSRETURN_EMPTY;
  1551. }
  1552. return;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement