📄 common.c
字号:
/* Contents: Functions used by all somsd modules (sominit, somsd, somtest). Author: Markus Hagenbuchner Comments and questions concerning this program package may be sent to 'markus@artificial-neural.net' *//************//* Includes *//************/#include <ctype.h>#include <float.h>#include <limits.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "common.h"#include "train.h"#include "utils.h"/* Begin functions... *//******************************************************************************Description: Convert network topology from a string pointed to by cptr to an ID number. Store ID number in uval. uval remains unchanged if cptr does not hold data. Return value: 1 if ID number of a recognized topology was assigned, or 0 otherwise.******************************************************************************/UNSIGNED GetTopologyID(char *cptr, UNSIGNED *uval){ if (cptr == NULL) /* No data given, return UNKNOWN */ return (UNSIGNED)UNKNOWN; if (!strncasecmp(cptr, "hex", 3)){ /* Hexagonal topology */ if (uval) *uval = (UNSIGNED)TOPOL_HEXA; return TOPOL_HEXA; } else if (!strncasecmp(cptr, "rect", 4)){ /* Rectangular topology */ if (uval) *uval = (UNSIGNED)TOPOL_RECT; return TOPOL_RECT; } else if (!strncasecmp(cptr, "oct", 3)){ /* Octagonal topology */ if (uval) *uval = (UNSIGNED)TOPOL_OCT; return TOPOL_OCT; } else if (!strncasecmp(cptr, "vq", 2)){ /*Vector quantization (no topology)*/ if (uval) *uval = (UNSIGNED)TOPOL_VQ; return TOPOL_VQ; } else if (!strncasecmp(cptr, "none", 2)){/*Vector quantization (no topology)*/ if (uval) *uval = (UNSIGNED)TOPOL_VQ; return TOPOL_VQ; } else if (uval) *uval = (UNSIGNED)UNKNOWN; return (UNSIGNED)UNKNOWN; /* Topology not recognized */}/******************************************************************************Description: Convert network neighborhood from a string pointed to by cptr to an ID number. If uval is not NULL, then store the ID number in uval. uval remains unchanged if cptr does not hold data. Return value: The value UNKNOWN is returned if ID number of a recognized topology was not found, otherwise the ID number is returned.******************************************************************************/UNSIGNED GetNeighborhoodID(char *cptr, UNSIGNED *uval){ if (cptr == NULL) /* No data given, return UNKNOWN */ return UNKNOWN; if (!strncasecmp(cptr, "bubble", 6)){ /* Bubble neighborhood */ if (uval) *uval = NEIGH_BUBBLE; return NEIGH_BUBBLE; } else if (!strncasecmp(cptr, "gauss", 5)){ /* Gaussian neighborhood */ if (uval) *uval = NEIGH_GAUSSIAN; return NEIGH_GAUSSIAN; } else if (!strncasecmp(cptr, "none", 4)){ /* No neighborhood (VQ mode) */ if (uval) *uval = NEIGH_NONE; return NEIGH_NONE; } else if (uval) *uval = UNKNOWN; return UNKNOWN; /* Neighborhood not recognized */}/******************************************************************************Description: Converts a string which is assumed to specify the type of alpha value decrease to a numerical identifier.Return value: A numerical identifier which indicates the alpha type, or UNKNOWN if the string did not hold a recognized keyword.******************************************************************************/UNSIGNED GetAlphaType(char *atype){ if (atype == NULL) AddError("No parameter for option alpha_type specified\n"); else if (!strncasecmp(atype, "sigmoid", 7)) /* Sigmoidal decreasing alpha */ return ALPHA_SIGMOIDAL; else if (!strncasecmp(atype, "linear", 6)) /* Linearly decreasing alpha */ return ALPHA_LINEAR; else if (!strncasecmp(atype, "exponent", 8)) /* Exponential decrease alpha */ return ALPHA_EXPONENTIAL; else if (!strncasecmp(atype, "const", 5)) /* Constant alpha value */ return ALPHA_CONSTANT; else AddError("Unknown type for option alpha_type specified\n"); return UNKNOWN;}/******************************************************************************Description: Convert a network topology ID to a corresponding string (i.e. an ID value of TOPOL_HEXA will be converted to "hexagonal").Return value: Pointer to the corresponding topology name, or NULL if the ID could not be resolved to a known name.******************************************************************************/char* GetTopologyName(UNSIGNED ID){ if (ID == TOPOL_HEXA) /* Hexagonal topology */ return "hexagonal"; else if (ID == TOPOL_RECT) /* Rectangular topology */ return "rectagonal"; else if (ID == TOPOL_OCT) /* Octangular topology */ return "octagonal"; else if (ID == TOPOL_VQ) /* VQ mode (no topology) */ return "vq"; else return NULL; /* ID unknown */}/******************************************************************************Description: Convert a network neighborhood ID to a corresponding string (i.e. an ID value of NEIGH_BUBBLE will be converted to "bubble").Return value: Pointer to the corresponding neighborhood name, or NULL if the ID could not be resolved to a known name.******************************************************************************/char* GetNeighborhoodName(UNSIGNED ID){ if (ID == NEIGH_BUBBLE) /* Bubble neighborhood */ return "bubble"; else if (ID == NEIGH_GAUSSIAN) /* Gaussian neighborhood */ return "gaussian"; else if (ID == NEIGH_NONE) /* No neighborhood (VQ mode)*/ return "none"; else return NULL; /* ID unknown */}/*****************************************************************************Description: Create a new map for the SOM, and initialize all codebook vectors with random values chosen from within a range of values observed in a given dataset. Initialization can occur in two different modes: mode=INIT_LINEAR: Initialize codebooks such that those codebooks which are located closest to the origin of the map receive the smallest values from within a computed range of valid values, and codebooks located furthest from the origin receive the largest values. The increase of values between the two corners is linear. mode=INIT_RANDOM: Randomly initialize all codebooks (this is the default behaviour).Return value: 1 on success, 0 otherwise (an error is set which can be checked using PrintErrors() ).*****************************************************************************/UNSIGNED InitCodes(struct Map *map, struct Graph *data, UNSIGNED mode){ UNSIGNED dim, sdim, noc; UNSIGNED offset, offset2; int nc; UNSIGNED i, x, y; FLOAT *maval, *mival; FLOAT dist, maxdist; struct Graph *gptr; struct Node *node; FLOAT (*ComputeDistance)(int bx, int by, int tx, int ty); noc = map->xdim * map->ydim; /* Total number of codebooks */ if (noc == 0u){ AddError("Network dimension is zero!"); return 0u; } map->codes = (struct Codebook*)MyCalloc(noc, sizeof(struct Codebook)); /* Find maximum dimension of codebook entries */ dim = 0u; for (gptr = data; gptr != NULL; gptr = gptr->next){ if (gptr->dimension > dim) dim = data->dimension; } if (dim == 0u){ AddError("Dimension of all node vectors in the dataset is zero!"); return 0u; } if (map->topology == TOPOL_VQ) dim = data->ldim + (data->FanOut + data->FanIn) * noc + data->tdim; map->dim = dim; /* allocate codebook vectors */ i = 0u; for (y = 0u; y < map->ydim; y++){ for (x = 0u; x < map->xdim; x++){ map->codes[i].points = (FLOAT*)MyMalloc(map->dim * sizeof(FLOAT)); map->codes[i].x = x; map->codes[i].y = y; map->codes[i].label = MAX_UNSIGNED; i++; } } /* Find the maximum and minimum values of data */ maval = (FLOAT*)MyMalloc(dim * sizeof(FLOAT)); mival = (FLOAT*)MyMalloc(dim * sizeof(FLOAT)); for (i = 0; i < dim; i++) { maval[i] = MIN_FLOAT; mival[i] = MAX_FLOAT; } if (map->topology == TOPOL_VQ){ for (gptr = data; gptr != NULL; gptr = gptr->next){ for (i = 0; i < gptr->numnodes; i++){ node = gptr->nodes[i]; for (x = 0; x < gptr->ldim; x++){ maval[x] = max(node->points[x], maval[x]); mival[x] = min(node->points[x], mival[x]); } for (x = 0; x < data->FanOut + data->FanIn; x++){ offset = gptr->ldim + x*noc; offset2 = gptr->ldim + x*2; for (nc = 0; nc < noc; nc++){ if (nc == (int)node->points[offset2]){ maval[offset+nc] = max(1.0, maval[offset+nc]); mival[offset+nc] = min(1.0, mival[offset+nc]); } else{ maval[offset+nc] = max(0.0, maval[offset+nc]); mival[offset+nc] = min(0.0, mival[offset+nc]); } } } for (x = 0; x < gptr->tdim; x++){ offset = gptr->ldim + (data->FanOut + data->FanIn) * noc; offset2 = gptr->ldim + (data->FanOut + data->FanIn) * 2; maval[offset+x] = max(node->points[offset2+x], maval[offset+x]); mival[offset+x] = min(node->points[offset2+x], mival[offset+x]); } } } } else{ /* Normal SOM-SD mode (not in VQ mode) */ for (gptr = data; gptr != NULL; gptr = gptr->next){ for (i = 0; i < gptr->numnodes; i++){ node = gptr->nodes[i]; for (x = 0; x < dim; x++){ maval[x] = max(node->points[x], maval[x]); mival[x] = min(node->points[x], mival[x]); } } } } /* Check if info about the mapping of data was available */ sdim = data->ldim + (data->FanOut + data->FanIn) * 2; for (x = data->ldim; x < sdim; x++){ if (maval[x] != -1 || mival[x] != -1) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -