If you want to create some self-organizing maps on a Mac you’re going to need to compile some source code yourself. Assuming you have Apple’s Developer Tools installed, it should be fairly painless.
cd ~/Downloads wget http://www.cis.hut.fi/research/som_pak/som_pak-3.1.tar wget http://mike.eire.ca/wp-content/uploads/2012/02/som_pak.txt tar xvf som_pak-3.1.tar patch -bp0 < som_pak.txt cd som_pak-3.1 cp makefile.unix makefile make make example sudo make install wget http://www.cis.hut.fi/research/som_pak/som_doc.ps open som_doc.ps |
cd ~/Downloads wget http://www.cis.hut.fi/research/som_pak/som_pak-3.1.tar wget http://mike.eire.ca/wp-content/uploads/2012/02/som_pak.txt tar xvf som_pak-3.1.tar patch -bp0 < som_pak.txt cd som_pak-3.1 cp makefile.unix makefile make make example sudo make install wget http://www.cis.hut.fi/research/som_pak/som_doc.ps open som_doc.ps
That’s it. You should have these files in ~/Downloads/som_pak-3.1/
ready to crunch data:
lininit
mapinit
planes
qerror
randinit
sammon
umat
vcal
vfind
visual
vsom
This diff file – which is downloaded in the steps above – changes a couple of function names so they don’t conflict with existing function names (getline
, getprogname
, and setprogname
.) It also changes the makefile to give us a usable build environment, places binaries into a subdirectory (bin/
), and lets you make clean
, make distclean
, or make install
.
--- som_pak-3.1/datafile.c 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/datafile.c 2012-01-31 22:26:41.000000000 -0800 @@ -122,7 +122,7 @@ do { - iline = getline(fi); + iline = getline_som(fi); row++; if (iline == NULL) { fprintf(stderr, "Can't read file %s", fi->name); @@ -157,7 +157,7 @@ /* Currently all header information is on the first non-comment line, so we just skip it. */ - while ((iline = getline(fi)) != NULL) + while ((iline = getline_som(fi)) != NULL) if (iline[0] != '#') break; @@ -608,7 +608,7 @@ while (!line) { /* get line from file */ - line = getline(fi); + line = getline_som(fi); /* The caller should check the entr->fi->error for errors or end of file */ --- som_pak-3.1/fileio.c 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/fileio.c 2012-01-31 22:26:46.000000000 -0800 @@ -276,10 +276,10 @@ } -/* getline - get a line from file. Returns a char * to the line (a +/* getline_som - get a line from file. Returns a char * to the line (a static buffer), NULL on error. */ -char *getline(struct file_info *fi) +char *getline_som(struct file_info *fi) { static char *stre = NULL; static long strl = 0; @@ -298,7 +298,7 @@ stre = (char *) malloc(sizeof(char) * strl); if (stre == NULL) { - perror("getline"); + perror("getline_som"); fi->error = ERR_NOMEM; return NULL; } @@ -319,14 +319,14 @@ tstr = stre = realloc(stre, sizeof(char) * strl); if (stre == NULL) { - perror("getline"); + perror("getline_som"); fi->error = ERR_NOMEM; return NULL; } if (strl > ABS_STR_LNG) { - fprintf(stderr, "getline: Too long lines in file %s (max %d)\n", + fprintf(stderr, "getline_som: Too long lines in file %s (max %d)\n", fi->name, ABS_STR_LNG); fi->error = ERR_LINETOOLONG; return NULL; @@ -361,8 +361,8 @@ /* read error */ tstr = NULL; fi->error = ERR_FILEERR; - fprintf(stderr, "getline: read error on line %d of file %s\n", fi->lineno, fi->name); - perror("getline"); + fprintf(stderr, "getline_som: read error on line %d of file %s\n", fi->lineno, fi->name); + perror("getline_som"); } break; } @@ -377,7 +377,7 @@ static char progname_real[512]; -char *setprogname(char *argv0) +char *setprogname_som(char *argv0) { char *s, *s2; static char *progname = NULL; --- som_pak-3.1/fileio.h 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/fileio.h 2012-01-31 22:26:52.000000000 -0800 @@ -66,10 +66,10 @@ struct file_info *open_file(char *name, char *fmode); int close_file(struct file_info *fi); -char *getline(struct file_info *fi); +char *getline_som(struct file_info *fi); /* for getting the program name */ -char *setprogname(char *argv0); -#define getprogname() setprogname(NULL); +char *setprogname_som(char *argv0); +#define getprogname_som() setprogname_som(NULL); #endif /* SOMPAK_FILEIO_H */ --- som_pak-3.1/lvq_pak.c 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/lvq_pak.c 2012-01-31 22:25:59.000000000 -0800 @@ -470,7 +470,7 @@ char *s; /* set program name */ - setprogname(argv[0]); + setprogname_som(argv[0]); #ifndef NO_PIPED_COMMANDS /* command for compressing */ --- som_pak-3.1/makefile.unix 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/makefile.unix 2012-02-29 16:39:52.000000000 -0800 @@ -1,10 +1,18 @@ - -# -CC=cc -CFLAGS=-O -LDFLAGS=-s +## Darwin (tested on OS X 10.7) +## +CC=gcc +CFLAGS=-O3 +LDFLAGS= LDLIBS=-lm LD=$(CC) +BINDIR=bin/ +OUTDIR=output/ +# +#CC=cc +#CFLAGS=-O +#LDFLAGS=-s +#LDLIBS=-lm +#LD=$(CC) ## NetBSD-1.0 (tested on Amiga) ## @@ -59,46 +67,50 @@ UMATOBJS=umat.o map.o median.o header.o OTHERFILES=header.ps -all: vcal mapinit vsom qerror randinit lininit visual sammon planes vfind umat +all: mkdirs vcal mapinit vsom qerror randinit lininit visual sammon planes vfind umat + +mkdirs: + mkdir -p $(BINDIR) + mkdir -p $(OUTDIR) vsom: vsom.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ vsom.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ vsom.o $(OBJS) $(LDLIBS) vsomtest: vsomtest.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ vsomtest.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ vsomtest.o $(OBJS) $(LDLIBS) qerror: qerror.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ qerror.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ qerror.o $(OBJS) $(LDLIBS) mapinit: mapinit.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ mapinit.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ mapinit.o $(OBJS) $(LDLIBS) randinit: mapinit rm -f $@ - ln mapinit $@ + ln $(BINDIR)mapinit $(BINDIR)$@ lininit: mapinit rm -f $@ - ln mapinit $@ + ln $(BINDIR)mapinit $(BINDIR)$@ vcal: vcal.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ vcal.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ vcal.o $(OBJS) $(LDLIBS) visual: visual.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ visual.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ visual.o $(OBJS) $(LDLIBS) sammon: sammon.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ sammon.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ sammon.o $(OBJS) $(LDLIBS) planes: planes.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ planes.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ planes.o $(OBJS) $(LDLIBS) vfind: vfind.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ vfind.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ vfind.o $(OBJS) $(LDLIBS) # Umat umat: $(UMATOBJS) $(OBJS) - $(LD) $(LDFLAGS) -o $@ $(UMATOBJS) $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ $(UMATOBJS) $(OBJS) $(LDLIBS) map.o umat.o: umat.h fileio.h datafile.o lvq_pak.h labels.h median.o: umat.h @@ -117,16 +129,16 @@ #BUFFER=-buffer 500 example : - ./randinit -din ex.dat -cout ex.cod -xdim 12 -ydim 8 -topol hexa \ + ./$(BINDIR)randinit -din ex.dat -cout $(OUTDIR)ex.cod -xdim 12 -ydim 8 -topol hexa \ -neigh bubble -rand 123 - ./vsom -din ex.dat -cin ex.cod -cout ex.cod -rlen 1000 \ + ./$(BINDIR)vsom -din ex.dat -cin $(OUTDIR)ex.cod -cout $(OUTDIR)ex.cod -rlen 1000 \ -alpha 0.05 -radius 10 $(TRAND) $(ALPHA_TYPE) $(BUFFER) - ./vsom -din ex.dat -cin ex.cod -cout ex.cod -rlen 10000 \ + ./$(BINDIR)vsom -din ex.dat -cin $(OUTDIR)ex.cod -cout $(OUTDIR)ex.cod -rlen 10000 \ -alpha 0.02 -radius 3 $(TRAND) $(ALPHA_TYPE) $(BUFFER) - ./qerror -din ex.dat -cin ex.cod - ./vcal -din ex_fts.dat -cin ex.cod -cout ex.cod - ./visual -din ex_ndy.dat -cin ex.cod -dout ex.nvs - ./visual -din ex_fdy.dat -cin ex.cod -dout ex.fvs + ./$(BINDIR)qerror -din ex.dat -cin $(OUTDIR)ex.cod + ./$(BINDIR)vcal -din ex_fts.dat -cin $(OUTDIR)ex.cod -cout $(OUTDIR)ex.cod + ./$(BINDIR)visual -din ex_ndy.dat -cin $(OUTDIR)ex.cod -dout $(OUTDIR)ex.nvs + ./$(BINDIR)visual -din ex_fdy.dat -cin $(OUTDIR)ex.cod -dout $(OUTDIR)ex.fvs fileio.o: fileio.h datafile.o: lvq_pak.h datafile.h fileio.h @@ -137,3 +149,11 @@ vcal.o mapinit.o vsom.o qerror.o visual.o sammon.o:\ lvq_pak.h datafile.h fileio.h labels.h som_rout.h +clean: + rm -f *.o + +distclean: + rm -rf *.o $(BINDIR) + +install: + cp $(BINDIR)* /usr/local/bin/ --- som_pak-3.1/map.c 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/map.c 2012-01-31 22:27:01.000000000 -0800 @@ -1095,7 +1095,7 @@ lask = -1; row = 1; - getline(in,s,maxline); + getline_som(in,s,maxline); do { ++lask; @@ -1103,7 +1103,7 @@ do { ++row; - getline(in,s,maxline); + getline_som(in,s,maxline); /* if the row in the input file starts with # or with newline, skip it */ if (strcmp(s,"")==NULL || s[0]=='#') --- mapinit.c 1995-04-06 17:01:00.000000000 -0700 +++ mapinit.c 2012-04-16 20:18:28.000000000 -0700 @@ -68,7 +68,7 @@ exit(0); } - progname = getprogname(); + progname = getprogname_som(); if (strcasecmp(progname, "lininit") == 0) init_type = IT_LIN; |
--- som_pak-3.1/datafile.c 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/datafile.c 2012-01-31 22:26:41.000000000 -0800 @@ -122,7 +122,7 @@ do { - iline = getline(fi); + iline = getline_som(fi); row++; if (iline == NULL) { fprintf(stderr, "Can't read file %s", fi->name); @@ -157,7 +157,7 @@ /* Currently all header information is on the first non-comment line, so we just skip it. */ - while ((iline = getline(fi)) != NULL) + while ((iline = getline_som(fi)) != NULL) if (iline[0] != '#') break; @@ -608,7 +608,7 @@ while (!line) { /* get line from file */ - line = getline(fi); + line = getline_som(fi); /* The caller should check the entr->fi->error for errors or end of file */ --- som_pak-3.1/fileio.c 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/fileio.c 2012-01-31 22:26:46.000000000 -0800 @@ -276,10 +276,10 @@ } -/* getline - get a line from file. Returns a char * to the line (a +/* getline_som - get a line from file. Returns a char * to the line (a static buffer), NULL on error. */ -char *getline(struct file_info *fi) +char *getline_som(struct file_info *fi) { static char *stre = NULL; static long strl = 0; @@ -298,7 +298,7 @@ stre = (char *) malloc(sizeof(char) * strl); if (stre == NULL) { - perror("getline"); + perror("getline_som"); fi->error = ERR_NOMEM; return NULL; } @@ -319,14 +319,14 @@ tstr = stre = realloc(stre, sizeof(char) * strl); if (stre == NULL) { - perror("getline"); + perror("getline_som"); fi->error = ERR_NOMEM; return NULL; } if (strl > ABS_STR_LNG) { - fprintf(stderr, "getline: Too long lines in file %s (max %d)\n", + fprintf(stderr, "getline_som: Too long lines in file %s (max %d)\n", fi->name, ABS_STR_LNG); fi->error = ERR_LINETOOLONG; return NULL; @@ -361,8 +361,8 @@ /* read error */ tstr = NULL; fi->error = ERR_FILEERR; - fprintf(stderr, "getline: read error on line %d of file %s\n", fi->lineno, fi->name); - perror("getline"); + fprintf(stderr, "getline_som: read error on line %d of file %s\n", fi->lineno, fi->name); + perror("getline_som"); } break; } @@ -377,7 +377,7 @@ static char progname_real[512]; -char *setprogname(char *argv0) +char *setprogname_som(char *argv0) { char *s, *s2; static char *progname = NULL; --- som_pak-3.1/fileio.h 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/fileio.h 2012-01-31 22:26:52.000000000 -0800 @@ -66,10 +66,10 @@ struct file_info *open_file(char *name, char *fmode); int close_file(struct file_info *fi); -char *getline(struct file_info *fi); +char *getline_som(struct file_info *fi); /* for getting the program name */ -char *setprogname(char *argv0); -#define getprogname() setprogname(NULL); +char *setprogname_som(char *argv0); +#define getprogname_som() setprogname_som(NULL); #endif /* SOMPAK_FILEIO_H */ --- som_pak-3.1/lvq_pak.c 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/lvq_pak.c 2012-01-31 22:25:59.000000000 -0800 @@ -470,7 +470,7 @@ char *s; /* set program name */ - setprogname(argv[0]); + setprogname_som(argv[0]); #ifndef NO_PIPED_COMMANDS /* command for compressing */ --- som_pak-3.1/makefile.unix 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/makefile.unix 2012-02-29 16:39:52.000000000 -0800 @@ -1,10 +1,18 @@ - -# -CC=cc -CFLAGS=-O -LDFLAGS=-s +## Darwin (tested on OS X 10.7) +## +CC=gcc +CFLAGS=-O3 +LDFLAGS= LDLIBS=-lm LD=$(CC) +BINDIR=bin/ +OUTDIR=output/ +# +#CC=cc +#CFLAGS=-O +#LDFLAGS=-s +#LDLIBS=-lm +#LD=$(CC) ## NetBSD-1.0 (tested on Amiga) ## @@ -59,46 +67,50 @@ UMATOBJS=umat.o map.o median.o header.o OTHERFILES=header.ps -all: vcal mapinit vsom qerror randinit lininit visual sammon planes vfind umat +all: mkdirs vcal mapinit vsom qerror randinit lininit visual sammon planes vfind umat + +mkdirs: + mkdir -p $(BINDIR) + mkdir -p $(OUTDIR) vsom: vsom.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ vsom.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ vsom.o $(OBJS) $(LDLIBS) vsomtest: vsomtest.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ vsomtest.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ vsomtest.o $(OBJS) $(LDLIBS) qerror: qerror.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ qerror.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ qerror.o $(OBJS) $(LDLIBS) mapinit: mapinit.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ mapinit.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ mapinit.o $(OBJS) $(LDLIBS) randinit: mapinit rm -f $@ - ln mapinit $@ + ln $(BINDIR)mapinit $(BINDIR)$@ lininit: mapinit rm -f $@ - ln mapinit $@ + ln $(BINDIR)mapinit $(BINDIR)$@ vcal: vcal.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ vcal.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ vcal.o $(OBJS) $(LDLIBS) visual: visual.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ visual.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ visual.o $(OBJS) $(LDLIBS) sammon: sammon.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ sammon.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ sammon.o $(OBJS) $(LDLIBS) planes: planes.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ planes.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ planes.o $(OBJS) $(LDLIBS) vfind: vfind.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ vfind.o $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ vfind.o $(OBJS) $(LDLIBS) # Umat umat: $(UMATOBJS) $(OBJS) - $(LD) $(LDFLAGS) -o $@ $(UMATOBJS) $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -o $(BINDIR)$@ $(UMATOBJS) $(OBJS) $(LDLIBS) map.o umat.o: umat.h fileio.h datafile.o lvq_pak.h labels.h median.o: umat.h @@ -117,16 +129,16 @@ #BUFFER=-buffer 500 example : - ./randinit -din ex.dat -cout ex.cod -xdim 12 -ydim 8 -topol hexa \ + ./$(BINDIR)randinit -din ex.dat -cout $(OUTDIR)ex.cod -xdim 12 -ydim 8 -topol hexa \ -neigh bubble -rand 123 - ./vsom -din ex.dat -cin ex.cod -cout ex.cod -rlen 1000 \ + ./$(BINDIR)vsom -din ex.dat -cin $(OUTDIR)ex.cod -cout $(OUTDIR)ex.cod -rlen 1000 \ -alpha 0.05 -radius 10 $(TRAND) $(ALPHA_TYPE) $(BUFFER) - ./vsom -din ex.dat -cin ex.cod -cout ex.cod -rlen 10000 \ + ./$(BINDIR)vsom -din ex.dat -cin $(OUTDIR)ex.cod -cout $(OUTDIR)ex.cod -rlen 10000 \ -alpha 0.02 -radius 3 $(TRAND) $(ALPHA_TYPE) $(BUFFER) - ./qerror -din ex.dat -cin ex.cod - ./vcal -din ex_fts.dat -cin ex.cod -cout ex.cod - ./visual -din ex_ndy.dat -cin ex.cod -dout ex.nvs - ./visual -din ex_fdy.dat -cin ex.cod -dout ex.fvs + ./$(BINDIR)qerror -din ex.dat -cin $(OUTDIR)ex.cod + ./$(BINDIR)vcal -din ex_fts.dat -cin $(OUTDIR)ex.cod -cout $(OUTDIR)ex.cod + ./$(BINDIR)visual -din ex_ndy.dat -cin $(OUTDIR)ex.cod -dout $(OUTDIR)ex.nvs + ./$(BINDIR)visual -din ex_fdy.dat -cin $(OUTDIR)ex.cod -dout $(OUTDIR)ex.fvs fileio.o: fileio.h datafile.o: lvq_pak.h datafile.h fileio.h @@ -137,3 +149,11 @@ vcal.o mapinit.o vsom.o qerror.o visual.o sammon.o:\ lvq_pak.h datafile.h fileio.h labels.h som_rout.h +clean: + rm -f *.o + +distclean: + rm -rf *.o $(BINDIR) + +install: + cp $(BINDIR)* /usr/local/bin/ --- som_pak-3.1/map.c 1995-04-06 17:01:00.000000000 -0700 +++ som_pak-3.1/map.c 2012-01-31 22:27:01.000000000 -0800 @@ -1095,7 +1095,7 @@ lask = -1; row = 1; - getline(in,s,maxline); + getline_som(in,s,maxline); do { ++lask; @@ -1103,7 +1103,7 @@ do { ++row; - getline(in,s,maxline); + getline_som(in,s,maxline); /* if the row in the input file starts with # or with newline, skip it */ if (strcmp(s,"")==NULL || s[0]=='#') --- mapinit.c 1995-04-06 17:01:00.000000000 -0700 +++ mapinit.c 2012-04-16 20:18:28.000000000 -0700 @@ -68,7 +68,7 @@ exit(0); } - progname = getprogname(); + progname = getprogname_som(); if (strcasecmp(progname, "lininit") == 0) init_type = IT_LIN;
Cheers for this Mike,
it saved me a bit of time because I was having trouble with the redefinition of getline(), and there is not much else in the way of comments on the internet. In addition to your modifications I also had to modify the instance of getprogname() -> getprogname_som() in mapinit.c before running make, it threw an error otherwise.
I also made a modification to fileio.h and extended the variable ABS_STR_LNG to 300000
Cheers,
Glad to be of some help; I’ve made the update to the diff file to correct the omission in mapinit.c.
I had to add the “som_pak-3.1/” path to mapinit.c on lines 266-267, but other than that, it ran like a charm!
Thanks for creating this and making it available, you’ve saved me a lot of time and frustration!
Best