AI-NeuralNet-FastSOM

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


0.16  Sat Jan  3 05:53:12 EST 2015
    - version bump - hasnt been tested in a while...
    - added auto-README generation to Makefile.PL
    - update copyright notice

0.15  Wed Jul 11 00:13:02 2012
	- tidy up build a bit
	- fixed warnings from CODE blocks using RETVAL without OUTPUT
	  blocks in newer perls
	- yet another typemap workaround. this time we have a 5.6.2 with
	  a new ParseXS and an old xsubpp. i wont even mention the problem
	  i found in old Test::More finding this. i hope it never becomes
	  an issue. (Note: since this is an almost 3 year old issue and
	  haven't seen any more cases, we'll assume it was isolated
	  to a single user to start with and the whole mess is fixed
	  now.)

0.14  Fri Aug 21 12:52:32 2009
	- work around some sort of ExtUtils::ParseXS bug in 5.6.2,
	  not picking up typemap files unless specifically named "typemap"

0.13  Mon Aug 17 08:42:37 2009
	- fixed perl version check in Makefile.PL

0.12  Sat Aug 15 14:24:50 2009
	- will now pass -Wall -Wextra -ansi -Wdeclaration-after-statement
	  (locally anyway)
	- wrapped newSVpvs in INT2PTR to hopefully satisfy some platforms
	- bumped perl require back up to 5.8.0 for now
	- defined PERL_MAGIC_tied for older perls
	- changed hv_fetchs() to hv_fetch() for older perls
	- hacked in defines for Newx() and friends for older perls
	- changed newSVpvs() to newSVpvn() for older perls
	- created seperate typemap for older perls, along with Makefile.PL
	  modification to use it before 5.8.0
	- added requirement for Storable which is non-core in older perls
	- moved perl require back down to 5.6.2

0.11  Sun Aug  9 10:04:19 2009
	- casting newSVpvs() to SV* to satisfy at least one platform
	- added 'const char *' to typemap for older perls
	- removed a few unneeded casts to internal types
	- moved DESTROY methods to superclass, thus fixing missing
	  Hexa::DESTROY and consolidating common code
	- consolidated neighbors code
	- general housekeeping

0.10  Fri Aug  7 09:11:39 2009
	- no longer relying on sizeof(void)
	- removed a bit of old test code
	- one more PTR2INT conversion
	- experimentally dropped perl require to 5.6.2

Changes  view on Meta::CPAN

	- removed another temp AV in _bmu_guts(), fixing another
	  memory leak
	- added pointer <-> IV conversions, hopefully fixing tons of
	  warnings on platforms where ivsize != ptrsize
	- added macros to speed up pointer conversions
	- consolidated bmu code in ::FastSOM

0.08  Fri Jul 31 16:17:32 2009
	- removed leading underscore from struct member names
	- removed all // comments, just in case...
	- changed all native type (int,double) to perl types (IV,NV)
	- fixed couple of instances of calling back to perl to get
	  stuff from c structs
	- reworked Storable support

0.07  Sat Jul 25 14:18:03 2009
	- clean up things a bit
	- now using Atol() instead of atoi()
	- now using Drand01() instead of rand()
	- now using seedDrand01() instead of srand()
	- fixed problem with not using all training vectors, or some twice

FastSOM.h  view on Meta::CPAN

 *
 * this is enough space to use the 'element' member as the base of an array
 * of Z NVs.
 *
 * the 'ref' element is a pointer to a perl RV referencing a tied array.
 * a copy of 'ref' will be returned to the perl side on request, and the
 * tied array interface can be use to access the members of this struct.
 *
 * 'Z' is of course the number of NVs in the 'element' array.
 */
typedef struct {
	SV *ref;
	IV Z;
	NV element;
} SOM_Vector;

/*
 * SOM_Array : holds Y ptrs to SOM_Vector thingys
 *
 * should be allocated:
 *	sizeof(SOM_Array) + sizeof(SOM_Vector*)*(Y-1)
 *
 * 'ref' and 'vector' elements similar in functionality to the 'ref' and
 * 'element' members, respectively, of the SOM_Vector struct.
 *
 * 'Y' is the number of SOM_Vector pointers in the 'vector' array.
 *
 * 'Z' is provided here only for propogation down the line in creating
 * the SOM_Vectors.
 */
typedef struct {
	SV *ref;
	IV Y;
	IV Z;
	SOM_Vector *vector;
} SOM_Array;

/*
 * SOM_Map : holds X ptrs to SOM_Array thingys
 *
 * should be allocated:
 *	sizeof(SOM_Map) + sizeof(SOM_Array*)*(X-1)
 *
 * 'ref' and 'array' are similar in functionality to the 'ref' and 'element'
 * members, respectively, of the SOM_Vector struct.
 *
 * 'X' is the number of SOM_Array pointers in the 'array' array.
 *
 * 'Y' and 'Z' are provided here only for propagation down the line in
 * creation of SOM_Array and SOM_Vector structs.
 */
typedef struct {
	SV *ref;
	IV X;
	IV Y;
	IV Z;
	SOM_Array *array;
} SOM_Map;

/*
 * SOM_Rect : holds a ptr to a single SOM_Map thingy
 *

FastSOM.h  view on Meta::CPAN

 * 'X', 'Y', and 'Z' are held here for progagation down to the structs
 * that make up our grid map.
 *
 * '_R'      = initial SOM radius
 * '_Sigma0' = ???
 * '_L0'     = initial SOM learning rate
 *
 * 'output_dim' is kept from instantiation simply because the perl interface
 * already provides access to it.
 */
typedef struct {
	SV *ref;
	IV X;
	IV Y;
	IV Z;
	NV R;
	NV Sigma0;
	NV L0;
	NV LAMBDA;
	NV T;
	int type;
	SV *output_dim;
	AV *labels;
	SOM_Map *map;
} SOM_GENERIC;

typedef SOM_GENERIC SOM_Rect;
typedef SOM_GENERIC SOM_Torus;
typedef SOM_GENERIC SOM_Hexa;

enum SOMType {
	SOMType_Hexa,
	SOMType_Rect,
	SOMType_Torus
};

typedef AV AV_SPECIAL;

#ifndef PERL_MAGIC_tied
#define PERL_MAGIC_tied 'P'
#endif

#ifndef Newx
#define Newx(ptr,nitems,type) New(0,ptr,nitems,type)
#endif

#ifndef Newxc
#define Newxc(ptr,nitems,type,cast) Newc(0,ptr,nitems,type,cast)
#endif

#ifndef Newxz
#define Newxz(ptr,nitems,type) Newz(0,ptr,nitems,type)
#endif

#ifndef PERL_UNUSED_VAR
#define PERL_UNUSED_VAR(x) ((void)x)
#endif

#define selfmg2iv(self,mg) SvIV(SvRV(SvTIED_obj((SV*)SvIV(SvRV(self)),mg)))
#define self2iv(self) SvIV(SvRV(self))

#define selfmagic(self) SvTIED_mg((SV*)SvRV(self), PERL_MAGIC_tied)

FastSOM.xs  view on Meta::CPAN

	som = self2somptr(self,mg);

	X = som->X;
	Y = som->Y;

	i = X*Y;
	Newx(n,i,NV);
	for ( i-=1 ; i>=0 ; i-- )
		n[i] = -1;

	if ( som->type == SOMType_Torus )
		neiguts = _torus_neiguts;
	else if ( som->type == SOMType_Hexa )
		neiguts = _hexa_neiguts;
	else if ( som->type == SOMType_Rect )
		neiguts = _rect_neiguts;
	else
		croak("unknown type");

	neiguts(som,sigma,X0,Y0,n);

	neighbors = newAV();

	for ( x=0 ; x<X ; x++ ) {
		for ( y=0 ; y<Y ; y++ ) {
			distance = n[x*Y+y];
			if ( distance >= 0 ) {
				tmp = newAV();

FastSOM.xs  view on Meta::CPAN

			org[i-2] = (AV*)SvRV(ST(i));

	som->LAMBDA = epochs / log( som->Sigma0 );

	X = som->X;
	Y = som->Y;

	nitems = X*Y;
	Newx(n,nitems,NV);

	if ( som->type == SOMType_Torus )
		neiguts = _torus_neiguts;
	else if ( som->type == SOMType_Hexa )
		neiguts = _hexa_neiguts;
	else if ( som->type == SOMType_Rect )
		neiguts = _rect_neiguts;
	else
		croak("unknown type");

	wantarray = GIMME_V == G_ARRAY ? TRUE : FALSE;

	/* should this be moved somewhere more global? */
	if ( !PL_srand_called ) {
		seedDrand01((Rand_seed_t)(time(NULL)+PerlProc_getpid()));
		PL_srand_called = TRUE;
	}

	sp = mark;

FastSOM.xs  view on Meta::CPAN


		/*
		 * this should be the second pass. here we need to serialize
		 * the tied part not seen from the perl side.
		 */

		som = INT2PTR(SOM_GENERIC*,self2iv(self));

		XPUSHs( INT2PTR(SV*,newSVpvn(
				"beat me whip me make me code badly",34)) );
		XPUSHs( newRV_noinc(newSViv(som->type)) );
		XPUSHs( newRV_noinc(newSViv(som->X)) );
		XPUSHs( newRV_noinc(newSViv(som->Y)) );
		XPUSHs( newRV_noinc(newSViv(som->Z)) );
		XPUSHs( newRV_noinc(newSVnv(som->R)) );
		XPUSHs( newRV_noinc(newSVnv(som->Sigma0)) );
		XPUSHs( newRV_noinc(newSVnv(som->L0)) );
		XPUSHs( newRV_noinc(newSVnv(som->LAMBDA)) );
		XPUSHs( newRV_noinc(newSVnv(som->T)) );
		XPUSHs( newRV_noinc(som->output_dim) );
		XPUSHs( newRV_noinc((SV*)som->labels) );

FastSOM.xs  view on Meta::CPAN

	SOM_GENERIC	*som;
	dXSARGS;

	PERL_UNUSED_VAR(serialized); /* -W */

	if (!SvTRUE(cloning)) {

	if ( SvTYPE(SvRV(self)) == SVt_PVMG ) {
		Newxz(som,1,SOM_GENERIC);

		som->type = SvIV(SvRV(ST(3)));
		som->X = SvIV(SvRV(ST(4)));
		som->Y = SvIV(SvRV(ST(5)));
		som->Z = SvIV(SvRV(ST(6)));
		som->R = SvNV(SvRV(ST(7)));
		som->Sigma0 = SvNV(SvRV(ST(8)));
		som->L0 = SvNV(SvRV(ST(9)));
		som->LAMBDA = SvNV(SvRV(ST(10)));
		som->T = SvNV(SvRV(ST(11)));
		som->output_dim = newSVsv(SvRV(ST(12)));
		som->labels = (AV*)SvRV(ST(13));

FastSOM.xs  view on Meta::CPAN

	}
	else
		som->L0 = 0.1;

	som->map = _make_map(som);
	som->labels = newAV();

	sclass = sv_2mortal(newSVpvf("%s",class));
	if (!sv_cmp(sclass,INT2PTR(
			SV*,newSVpvn("AI::NeuralNet::FastSOM::Rect",28))))
		som->type = SOMType_Rect;
	/*
	else if (!sv_cmp(sclass,INT2PTR(
			SV*,newSVpvn("AI::NeuralNet::FastSOM::Hexa",28))))
		som->type = SOMType_Hexa;
	*/
	else if (!sv_cmp(sclass,INT2PTR(
			SV*,newSVpvn("AI::NeuralNet::FastSOM::Torus",29))))
		som->type = SOMType_Torus;
	else
		croak("unknown type");

	hash = (HV*)sv_2mortal((SV*)newHV());
	tie = newRV_noinc(newSViv(PTR2IV(som)));
	stash = gv_stashpv(class, GV_ADD);
	sv_bless(tie, stash);
	hv_magic(hash, (GV*)tie, PERL_MAGIC_tied);
	rv = sv_bless(newRV_noinc((SV*)hash),stash);

	som->ref = rv;

FastSOM.xs  view on Meta::CPAN

                        hexa->L0 = rate;
                else
                        hexa->L0 = 0.1;
        }
        else
                hexa->L0 = 0.1;

	hexa->map = _make_map( hexa );
	hexa->labels = newAV();

	hexa->type = SOMType_Hexa;

	hash = (HV*)sv_2mortal((SV*)newHV());
	tie = newRV_noinc(newSViv(PTR2IV(hexa)));
	stash = gv_stashpv(class, GV_ADD);
	sv_bless(tie, stash);
	hv_magic(hash, (GV*)tie, PERL_MAGIC_tied);
	rv = sv_bless(newRV_noinc((SV*)hash),stash);

	hexa->ref = rv;

MANIFEST  view on Meta::CPAN

t/orig/rect.t
t/orig/som.t
t/orig/torus.t
t/pods.t
t/rect.t
t/rect_retrieve.t
t/som.t
t/torus.t
t/torus_retrieve.t
TODO
typemap.v1
typemap.v2
META.json                                Module JSON meta-data (added by MakeMaker)

Makefile.PL  view on Meta::CPAN

use 5.006002;
use ExtUtils::MakeMaker;

WriteMakefile(
    NAME          => 'AI::NeuralNet::FastSOM',
    VERSION_FROM  => 'lib/AI/NeuralNet/FastSOM.pm',
    ABSTRACT_FROM => 'lib/AI/NeuralNet/FastSOM.pm',
    AUTHOR        => 'Rick Myers <jrm@cpan.org>',
    LICENSE       => 'perl',
    PREREQ_PM     => { Storable => 0 },
    TYPEMAPS      => [ $] < 5.008000 ? 'typemap.v1' : 'typemap.v2' ],
    test          => { TESTS => 't/*.t t/orig/*.t' },
    clean         => { FILES => 't/*.bin typemap' },
);

#
# everything below is a work-around for some sort of bug in ExtUtils::ParseXS
# not picking up typemap files unless named "typemap" in perl5.6.2
#
# note however that the TYPEMAPS entry above is still needed for 5.6.2's still
# using the old xsubpp
#

package MY;

sub xs_c {
    my $t = shift->SUPER::xs_c(@_);
    $t =~ s/:/:\n	\$(MAKE) typemap/;
    $t;
}

sub test {
    my $t = shift->SUPER::test(@_);
    $t =~ s/(PERL_DL_NONLAZY=)/HARNESS_OPTIONS=j1 $1/g;
    $t;
}

sub postamble {
    my $out = <<'README';
readme:
	pod2text lib/AI/NeuralNet/FastSOM.pm README
	perl -i -pe's{\\*(\\S+)\\*}{\\1}g' README

README

    if ( $] < 5.008000 ) {
        $out .= <<'EOP';
typemap:
	$(CP) typemap.v1 typemap
EOP
    }

    else {
        $out .= <<'EOP';
typemap:
	$(CP) typemap.v2 typemap
EOP
    }

    return $out;
}

exit 0;

TODO  view on Meta::CPAN

- skip some tests if Storable not found (for old perls).
  versions ok: 2.21, 2.20, 2.19, 2.18
  perls found in: 5.11.0, 5.10.1, 5.10.0, 5.8.8, 5.8.9p35104, 5.8.9, 5.8.8, 5.6.2

- "passing argument 3 of 'Perl_newXS' discards qualifiers
   from pointer target type". is this still a problem?

- clean up!

- figure out how to call perl's exp(), log() and getpid() functions.



( run in 3.154 seconds using v1.01-cache-2.11-cpan-df04353d9ac )