/*\

    nem_hlp.c

    Project NEM : display of long help

    Mon Jul 17 16:04:35 2017

\*/

#include "nem_hlp.h"  /* Exported prototypes */

void PrintHelpGeneral( FILE* F )
{
    fprintf( F , "\n" ) ;
    fprintf( F , "Goal\n" ) ;
    fprintf( F , "====\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    This program computes a partition of a given set of objects \n" ) ;
    fprintf( F , "    described by one or several numeric variables and by their \n" ) ;
    fprintf( F , "    spatial relationships, using the 'Neighborhood EM' algorithm \n" ) ;
    fprintf( F , "    (NEM). This algorithm is derived from the EM algorithm applied\n" ) ;
    fprintf( F , "    to a hidden Markov random field model. Its new feature consists in\n" ) ;
    fprintf( F , "    taking into account some spatial interdependance between the \n" ) ;
    fprintf( F , "    objects.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    It may be used for:\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - unsupervised segmentation of color or gray-level images \n" ) ;
    fprintf( F , "      (points = pixel values, geographic position = pixel coordinates) ;\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - clustering of spatial data like socio-economical activities of\n" ) ;
    fprintf( F , "      neighbouring counties, etc.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    The algorithm takes as input an objects-variables table, \n" ) ;
    fprintf( F , "    and a specification of the neighborhood relationship between \n" ) ;
    fprintf( F , "    the objects. It produces as output a fuzzy or a hard partition \n" ) ;
    fprintf( F , "    of the objects.  The main algorithm is described in the following\n" ) ;
    fprintf( F , "    paper:\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Ambroise, C., Dang, V.M. and Govaert, G. (1997). Clustering of spatial\n" ) ;
    fprintf( F , "  data by the EM algorithm, in A.~Soares, J.~G\'omez-Hernandez and\n" ) ;
    fprintf( F , "  R.~Froidevaux, eds, `geoENV I - Geostatistics for Environmental\n" ) ;
    fprintf( F , "  Applications', Vol. 9 of `Quantitative Geology and Geostatistics', \n" ) ;
    fprintf( F , "  Kluwer Academic Publisher, pp.~493--504.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Changing default parameters\n" ) ;
    fprintf( F , "===========================\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    The behaviour of this clustering algorithm can be adjusted in many\n" ) ;
    fprintf( F , "    ways to fit a particular problem. The main possibilities\n" ) ;
    fprintf( F , "    are described below.  \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - The assumed degree of spatial interdependance is controlled by\n" ) ;
    fprintf( F , "    the value of the 'beta' coefficient (option '-b beta_value'). The higher\n" ) ;
    fprintf( F , "    it is, the smoother the partition will look in the geographic\n" ) ;
    fprintf( F , "    space, but the less it will fit to the data. The default value (1.0)\n" ) ;
    fprintf( F , "    seems to work well in most image segmentation problems where the\n" ) ;
    fprintf( F , "    patches are supposed to be spatially smooth. For beta's lowest\n" ) ;
    fprintf( F , "    value (0.0), the algorithm is the same as Dempster et al's EM\n" ) ;
    fprintf( F , "    algorithm (1974), and does a 'spatially blind' segmentation.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - The algorithm 'Neighborhood Classification EM' (NCEM) can be used\n" ) ;
    fprintf( F , "    instead of NEM (option '-a ncem'). The principle of NCEM consists in\n" ) ;
    fprintf( F , "    'hardening' the classification matrix at each iteration (C-step\n" ) ;
    fprintf( F , "    after the E-step). Practically, NCEM converges faster than NEM,\n" ) ;
    fprintf( F , "    but gives a poorer segmentation on data containing a high level of\n" ) ;
    fprintf( F , "    noise.  \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - In some applications, the class may be already known for a part of\n" ) ;
    fprintf( F , "    the sample. Such a knowledge can be taken into account by the\n" ) ;
    fprintf( F , "    Neighborhood EM algorithm, and may improve considerably the resulting\n" ) ;
    fprintf( F , "    classification (option '-s l file.ck').  \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Incomplete observations are taken into account in the\n" ) ;
    fprintf( F , "    probabilistic model and the program.  It is simply assumed that\n" ) ;
    fprintf( F , "    the missingness occurs at random, i.e. it does not depend on the\n" ) ;
    fprintf( F , "    missing value itself nor on the unobserved class.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Notice\n" ) ;
    fprintf( F , "======\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    The program is only provided to make it easier to test the\n" ) ;
    fprintf( F , "    behavior of the Neighborhood EM clustering algorithm and compare\n" ) ;
    fprintf( F , "    it with other algorithms.    Although I have tried to write and \n" ) ;
    fprintf( F , "    test the program as carefully as possible, it is not guaranteed \n" ) ;
    fprintf( F , "    to be error-free.  Please contact me if you have\n" ) ;
    fprintf( F , "    any questions or problems in using it.  Please also mention its\n" ) ;
    fprintf( F , "    origin if you use it for a published work. Finally I would be\n" ) ;
    fprintf( F , "    interested to know for what kind of problem you have found\n" ) ;
    fprintf( F , "    this program to be of use.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Van Mo Dang\n" ) ;
    fprintf( F , "Van.Mo.Dang@utc.fr\n" ) ;
    fprintf( F , "http://www.hds.utc.fr/~mdang\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
} /* end of PrintHelpGeneral() */


void PrintHelpOptions( FILE* F )
{
    fprintf( F , "\n" ) ;
    fprintf( F , "Command Syntax\n" ) ;
    fprintf( F , "==============\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " Usage :    nem_exe   file  K  [ option1 option2 ... ]\n" ) ;
    fprintf( F , " ------- \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " Arguments :\n" ) ;
    fprintf( F , " -----------\n" ) ;
    fprintf( F , "   file       base name of input files ___.str and ___.dat\n" ) ;
    fprintf( F , "   K          number of classes\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " Options :   [ default  ] { possible values }\n" ) ;
    fprintf( F , " --------- \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " \n" ) ;
    fprintf( F , "  -a algo   [ nem      ]   { nem ncem gem }\n" ) ;
    fprintf( F , "     Algorithm to compute classification at E-step of each iteration : \n" ) ;
    fprintf( F , "      ncem = crisp classification by ICM procedure\n" ) ;
    fprintf( F , "      nem  = fuzzy classification by mean field approximation\n" ) ;
    fprintf( F , "      gem  = fuzzy classification by Gibbs sampling (Monte-Carlo simulations)\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -b beta   [ 1        ]   (0.0 <= beta <= 4)\n" ) ;
    fprintf( F , "     Coefficient of spatial smoothing to apply. This matches the \n" ) ;
    fprintf( F , "     Potts random field strength of interaction with 4-neighbor contexts.\n" ) ;
    fprintf( F , "     Notice that b = 0 is equivalent to EM for a mixture model.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -c wh thr [clas  0.04]   { none clas crit } and (>0)\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "       none     = no convergence test, i.e. do all specified iterations.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "       clas thr = stop the iterations when the largest difference\n" ) ;
    fprintf( F , "                  between previous and current classification matrix\n" ) ;
    fprintf( F , "                  is <= threshold. A threshold 0.04 is usually optimal.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "       crit thr = stop the iterations when \n" ) ;
    fprintf( F , "                  | (current_crit - last_crit)/current_crit | < threshold.\n" ) ;
    fprintf( F , "                  A threshold of 0.001 is usually best.  The test uses \n" ) ;
    fprintf( F , "                  the criterion selected by the option -C.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -f format [ hard     ]   { hard fuzzy }\n" ) ;
    fprintf( F , "     Format of output partition. Hard = N integers having values from\n" ) ;
    fprintf( F , "     1 to nk : for each observation, give the number of the class where\n" ) ;
    fprintf( F , "     it has highest grade of membership. Fuzzy = N x K reals between\n" ) ;
    fprintf( F , "     0 and 1 : for each observation, give its grade of membership in\n" ) ;
    fprintf( F , "     each class.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -i itmax  [ 100      ]   (>= 0)\n" ) ;
    fprintf( F , "     Maximum number of NEM iterations.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -l dolog  [ n        ]   { y n }\n" ) ;
    fprintf( F , "     Produce a log file or not to see the results of each iteration.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -m f p d  [norm p_ s__]  { norm lapl } { p_ pk } { s__ sk_ s_d skd }\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "     Mixture model assumption to use\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "      norm/lapl/bern : normal, Laplace or Bernoulli distributions\n" ) ;
    fprintf( F , "                       Bernoulli distributions are for binary data\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "      p_/pk     : clusters have equal / varying proportions\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "      s__/...   : variance model\n" ) ;
    fprintf( F , "                    s__ : same variance in all clusters and variables\n" ) ;
    fprintf( F , "                    sk_ : one variance per cluster, same in all variables\n" ) ;
    fprintf( F , "                    s_d : one variance per variable, same in all clusters\n" ) ;
    fprintf( F , "                    skd : one variance per cluster and variable\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "                  the variables are assumed independent within a cluster\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -n neigh  [ 4        ]   { 4 f }\n" ) ;
    fprintf( F , "     Neighborhood specification to use in the case of an image.\n" ) ;
    fprintf( F , "     4 = default 4-nearest neighbor system. f = specify neighborhood\n" ) ;
    fprintf( F , "     window in file.nei.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -o fout   [ file     ]\n" ) ;
    fprintf( F , "     Output files basename ___.cf, ___.mf and ___.log. Default is \n" ) ;
    fprintf( F , "     to use input file basename. Specify '-' to output the\n" ) ;
    fprintf( F , "     classification to standard output; useful to pipe the result to an \n" ) ;
    fprintf( F , "     'nem_exe -s f -' session.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -s init   [ s 1      ]   { s <v> | f <ini.uf> | r <n> | l <file> | m <file> } \n" ) ;
    fprintf( F , "     Initialization mode.\n" ) ;
    fprintf( F , "     -s s <v>   \n" ) ;
    fprintf( F , "        Sort observations by variable <v>, then divide them\n" ) ;
    fprintf( F , "        in K quantiles of equal size to get initial partition.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "     -s f <ini.uf>\n" ) ;
    fprintf( F , "        Read initial fuzzy classification from file <ini.uf>. \n" ) ;
    fprintf( F , "        '-s f -' reads from standard input.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "     -s r <n>\n" ) ;
    fprintf( F , "        Start <n> times from random parameters (means chosen at\n" ) ;
    fprintf( F , "        random among the observations), then keep result with highest\n" ) ;
    fprintf( F , "        criterion.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "     -s l <file>\n" ) ;
    fprintf( F , "        Use partially known labels given in <file> to compute initial \n" ) ;
    fprintf( F , "        parameters. Those labels remain fixed throughout the\n" ) ;
    fprintf( F , "        clustering process.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "     -s m <file> \n" ) ;
    fprintf( F , "        Use specified parameters at beginning (1) or throughout the\n" ) ;
    fprintf( F , "        clustering process (2). Parameters syntax :\n" ) ;
    fprintf( F , "        {1 2} p_1 ... p_{K-1}   m_11 .. m_1D m21 ... m_KD   s_11 ... s_KD.\n" ) ;
    fprintf( F , "        The s_kd are the standard errors for normal distributions, or\n" ) ;
    fprintf( F , "        the scale parameters for the Laplace distributions.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -t tie    [ random   ]   { random first }\n" ) ;
    fprintf( F , "     How to choose the class with highest probability when several\n" ) ;
    fprintf( F , "     classes have same maximum probability in MAP\n" ) ;
    fprintf( F , "     classification. 'random' draws uniformly between ex-aequo\n" ) ;
    fprintf( F , "     classes, 'first' chooses class with lowest index.\n" ) ;
    fprintf( F , " \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -B bmod   [ fix      ]   { fix psgrad heu_d heu_l }\n" ) ;
    fprintf( F , "     Procedure to estimate beta automatically :\n" ) ;
    fprintf( F , "      fix   = no estimation of beta, use beta given by option '-b'\n" ) ;
    fprintf( F , "      psgrad = pseudo-likelihood gradient ascent\n" ) ;
    fprintf( F , "      heu_d = heuristic using drop of fuzzy within cluster inertia\n" ) ;
    fprintf( F , "      heu_l = heuristic using drop of mixture likelihood\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -C crit   [ U        ]   local maximum criterion { U M D L }\n" ) ;
    fprintf( F , "     Criterion used to select the best local solution from random starts :\n" ) ;
    fprintf( F , "      U = fuzzy spatial clustering criterion\n" ) ;
    fprintf( F , "      M = fuzzy pseudo-likelihood\n" ) ;
    fprintf( F , "      D = fuzzy within cluster inertia\n" ) ;
    fprintf( F , "      L = likelihood of mixture parameters\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -G nit conv step rand [  1 0.001 0.0 0 ]  \n" ) ;
    fprintf( F , "     Parameters of beta gradient estimation\n" ) ;
    fprintf( F , "      nit = number of gradient iterations\n" ) ;
    fprintf( F , "      conv = threshold to test convergence (|g'|<conv*N is tested)\n" ) ;
    fprintf( F , "      step = > 0 for fixed step, <= 0 for Newton step = 1/g''\n" ) ;
    fprintf( F , "      rand = in -s r  init mode, initial beta random (1) or fixed by -b (0)\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -H bstep bmax ddrop dloss lloss [ 0.10 2.0 0.8 0.5 0.02 ]  \n" ) ;
    fprintf( F , "     Parameters of beta D and L heuristics :\n" ) ;
    fprintf( F , "      bstep = step of beta increase\n" ) ;
    fprintf( F , "      bmax  = maximal value of beta to test\n" ) ;
    fprintf( F , "      ddrop = threshold of allowed D drop (higher = less detection)\n" ) ;
    fprintf( F , "      dloss = threshold of allowed D loss (higher = less detection)\n" ) ;
    fprintf( F , "      lloss = threshold of allowed L loss (higher = less detection)\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -I eiter  [ 1        ]   (>= 1)\n" ) ;
    fprintf( F , "     Number of internal E-step iterations (nem and ncem algorithms),\n" ) ;
    fprintf( F , "     i.e. number of sweeps through whole dataset to compute\n" ) ;
    fprintf( F , "     classification at each iteration.  For gem algorithm, indicates\n" ) ;
    fprintf( F , "     number of sweeps through the dataset to compute the average\n" ) ;
    fprintf( F , "     frequency of class occurrence -> a large value is recommended\n" ) ;
    fprintf( F , "     for the gem algorithm (typically 50).\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -M miss   [ replace  ]    { replace ignore }\n" ) ;
    fprintf( F , "     How to deal with missing data.  Replace by expected value (EM) or\n" ) ;
    fprintf( F , "     ignore when computing mean (maximize fuzzy clustering criterion).\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -O order  [ direct   ]   order of site visit { direct random }\n" ) ;
    fprintf( F , "     Order in which to classify the observations at E-step.\n" ) ;
    fprintf( F , "      direct = given order 1..N\n" ) ;
    fprintf( F , "      random = random permutation of 1..N\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -S seed   [ <time>  ]    (integer)\n" ) ;
    fprintf( F , "     Specify a seed for the random number generator. Default uses\n" ) ;
    fprintf( F , "     current system clock.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -T test   [ n       ]    { y n }\n" ) ;
    fprintf( F , "     Print some debugging information or not.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -U update [ seq      ]   { seq para }\n" ) ;
    fprintf( F , "     Update the class of the sites in a sequential or parallel manner.\n" ) ;
    fprintf( F , "     'seq' works best. 'para' is more grounded, because it is EM with\n" ) ;
    fprintf( F , "     mean field approximation, but it requires a low spatial smoothing.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "You may also just type arguments : \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  -v                      versions information\n" ) ;
    fprintf( F , "  -h help_topic           longer help - help topics are\n" ) ;
    fprintf( F , "     general\n" ) ;
    fprintf( F , "     options\n" ) ;
    fprintf( F , "     examples\n" ) ;
    fprintf( F , "     filein\n" ) ;
    fprintf( F , "     fileout\n" ) ;
    fprintf( F , "     versions\n" ) ;
    fprintf( F , " \n" ) ;
    fprintf( F , " \n" ) ;
} /* end of PrintHelpOptions() */


void PrintHelpExamples( FILE* F )
{
    fprintf( F , "\n" ) ;
    fprintf( F , "    Examples :\n" ) ;
    fprintf( F , "    ----------\n" ) ;
    fprintf( F , " nem_exe  myimg  3 -b 0.5 -s r 10 -o Res/myimg3r_05 >&! Res/myimg3r_05.out &\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    This unix command clusters data set myimg (files myimg.dat, myimg.str)\n" ) ;
    fprintf( F , "    into 3 classes ; spatial coefficient is 0.5 ; do 10 random starts ;\n" ) ;
    fprintf( F , "    save results in files Res/myimg3r_05.* (___.cf ___.log ___.mf) .\n" ) ;
    fprintf( F , "    Last part of the command is unix-specific : it saves screen output\n" ) ;
    fprintf( F , "    to file Res/myimg3r_05.out and executes the program in background.\n" ) ;
    fprintf( F , "\n" ) ;
} /* end of PrintHelpExamples() */


void PrintHelpFileIn( FILE* F )
{
    fprintf( F , "\n" ) ;
    fprintf( F , "Input Files\n" ) ;
    fprintf( F , "===========\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    Input files are in ASCII format.\n" ) ;
    fprintf( F , "    2 or 3 input files are required : file.str   file.dat   [ file.nei ]\n" ) ;
    fprintf( F , "    2 optional input files :          file.u0    file.ck\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " 1) file.str\n" ) ;
    fprintf( F , " -----------\n" ) ;
    fprintf( F , "    This gives the structure of the data : \n" ) ;
    fprintf( F , "    type of spatial repartition (image, spatial or non-spatial),\n" ) ;
    fprintf( F , "    number of objects and variables. This file may start with\n" ) ;
    fprintf( F , "    comment lines to describe the dataset (lines beginning with #).\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 1 : Color image (each pixel is described by 3 variables) \n" ) ;
    fprintf( F , "             of 200 lines (height) and 300 columns (width)\n" ) ;
    fprintf( F , "    # RGB biomedical coloscopic image. Look for 3 or 4 classes.\n" ) ;
    fprintf( F , "    I 200 300 3\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 2 : Spatial dataset of 3000 objects described by 4 variables\n" ) ;
    fprintf( F , "    # Economic data on counties (region of Centre). About 5 classes.\n" ) ;
    fprintf( F , "    S 3000 4\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 3 : Non-spatial dataset of 3000 objects described by 4 variables\n" ) ;
    fprintf( F , "    # Companies characteristics for risk assessment. About 6 classes.\n" ) ;
    fprintf( F , "    N 3000 4\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " 2) file.dat\n" ) ;
    fprintf( F , " -----------\n" ) ;
    fprintf( F , "    Contains the objects-variables table (only the non-spatial\n" ) ;
    fprintf( F , "    variables).  Missing data are specified by NaN.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    If the dataset is an image, the pixels must be listed \n" ) ;
    fprintf( F , "    line-by-line first, i.e. : \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    x(1,1) x(1,2) ... x(1,nc)  \n" ) ;
    fprintf( F , "    x(2,1) x(2,2) ... x(2,nc)\n" ) ;
    fprintf( F , "    ...\n" ) ;
    fprintf( F , "    x(nl,1) x(nl,2) ... x(nl,nc)\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    where nl = number of lines, nc = number of columns, and \n" ) ;
    fprintf( F , "    x(i,j) = values of pixel at line i and column j (a set of 3\n" ) ;
    fprintf( F , "    numbers for a color image).\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 1 : Color image\n" ) ;
    fprintf( F , "    50 100 120\n" ) ;
    fprintf( F , "    51  99 122\n" ) ;
    fprintf( F , "    ...\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 2 : Spatial data (4 variables)\n" ) ;
    fprintf( F , "    0.31 200 41 1200 \n" ) ;
    fprintf( F , "    0.28 202 43 1180\n" ) ;
    fprintf( F , "    ...\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " 3) file.nei\n" ) ;
    fprintf( F , " -----------\n" ) ;
    fprintf( F , "    Specifies the spatial relationships between the objects. \n" ) ;
    fprintf( F , "    * For an image, this file is optional and allows to specify\n" ) ;
    fprintf( F , "    a particular neighborhood system ; if no file is specified,\n" ) ;
    fprintf( F , "    default neighborhood system taken is 4-nearest neighbours.\n" ) ;
    fprintf( F , "    * For other spatial data, this file is required.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    Format is different for an image and other spatial data\n" ) ;
    fprintf( F , "    (see examples below).\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 1 : 4 nearest-neighbours in an image (default)\n" ) ;
    fprintf( F , "    -1 1           /* at most 1 pixel on the left and 1 on the right */\n" ) ;
    fprintf( F , "    -1 1           /* at most 1 pixel up and 1 down */\n" ) ;
    fprintf( F , "    0 1 0          \n" ) ;
    fprintf( F , "    1 0 1          /* 4 equally weighted neighbors : */\n" ) ;
    fprintf( F , "    0 1 0	   /* up,left,right,down */            \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 2 : other spatial data, unweighted neighborhood graph\n" ) ;
    fprintf( F , "    0              /* 0 = no weight specified (use default weight = 1.0) */\n" ) ;
    fprintf( F , "    1   3   2 5 7  /* object 1 has 3 neighbors : objects 2, 5 and 7 */\n" ) ;
    fprintf( F , "    2   2   1 3\n" ) ;
    fprintf( F , "    ...\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 2 : other spatial data, weighted neighborhood graph\n" ) ;
    fprintf( F , "    1                           /* 1 = weights are specified */\n" ) ;
    fprintf( F , "    1   3   2 5 7  0.5 0.6 0.8  /* object 1 has 3 neighbors : 2, 5 and 7 */\n" ) ;
    fprintf( F , "    2   2   1 3    0.3 0.5\n" ) ;
    fprintf( F , "    ...\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " 4.a) file.ck  (option -s l file.ck)\n" ) ;
    fprintf( F , " ------------\n" ) ;
    fprintf( F , "    Gives the class of the points for which the label is already\n" ) ;
    fprintf( F , "    known. Expected format is N + 1 integers (N being the total\n" ) ;
    fprintf( F , "    number of objects in the sample) :\n" ) ;
    fprintf( F , "    - the first number is the number of classes K ;\n" ) ;
    fprintf( F , "    - the N following integers, in the same order as the\n" ) ;
    fprintf( F , "    objects in file.dat, indicate the class to which the\n" ) ;
    fprintf( F , "    corresponding object belongs.  If the value is 0 or greater than the\n" ) ;
    fprintf( F , "    number of classes, then the object is considered to have no known\n" ) ;
    fprintf( F , "    label (its label will be computed by the algorithm). \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    In the current implementation, each class must contain at least\n" ) ;
    fprintf( F , "    one observation with known label. Those pre-labeled observations\n" ) ;
    fprintf( F , "    are used to initialize the centers of the clusters.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    5     /* number of classes */\n" ) ;
    fprintf( F , "    0     /* object 1 has no known label */\n" ) ;
    fprintf( F , "    5     /* object 2 belongs to class 5 */\n" ) ;
    fprintf( F , "    1     /* object 3 belongs to class 1 */\n" ) ;
    fprintf( F , "    ...\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " 4.b) file.u0  (option -s f)\n" ) ;
    fprintf( F , " ------------\n" ) ;
    fprintf( F , "    Gives an initial fuzzy classification to start the algorithm. \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    0.9 0.1  /* object 1 : initial membership = 0.9/0.1 in class 1/2 */\n" ) ;
    fprintf( F , "    0.3 0.7  /* object 2 : initial membership = 0.3/0.7 in class 1/2 */\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " 4.c) file.m (option -s m)\n" ) ;
    fprintf( F , " -----------\n" ) ;
    fprintf( F , "    Contains the parameters (at begining or throughout the clustering process) of the mixture model separated by spaces\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    If the parameters are just initialized by this file, the file start by 1, ortherwise if the parameters are fixed throughout the clustering process the file start by 2\n" ) ;
    fprintf( F , "    Then :\n" ) ;
    fprintf( F , "    p_1 ... p_{K-1}   m_11 .. m_1D m21 ... m_KD   s_11 ... s_KD.\n" ) ;
    fprintf( F , "    The s_kd are the standard errors for normal distributions, or\n" ) ;
    fprintf( F , "    the scale parameters for the Laplace distributions.\n" ) ;
    fprintf( F , "    - Ex 1 : fixed parameters (4 variables and 2 classes)\n" ) ;
    fprintf( F , "    2 0.6 1 1 1 1 0 0 0 0 0.1 0.2 0.1 0.3 0.1 0.4 0.2 0.1 \n" ) ;
    fprintf( F , "\n" ) ;
} /* end of PrintHelpFileIn() */


void PrintHelpFileOut( FILE* F )
{
    fprintf( F , "\n" ) ;
    fprintf( F , "Output Files\n" ) ;
    fprintf( F , "============\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    Output files are in ASCII format.\n" ) ;
    fprintf( F , "    2 files are output :              file.cf    file.mf\n" ) ;
    fprintf( F , "    1 optional file is output :       file.log\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " 1) file.cf (or file.uf for fuzzy partition)\n" ) ;
    fprintf( F , " -------------------------------------------\n" ) ;
    fprintf( F , "    Gives the partition found by the algorithm.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 1 : Image segmented in 2 'hard' classes (linewise order, as the \n" ) ;
    fprintf( F , "           input data file)\n" ) ;
    fprintf( F , "    1        /* Object 1 belongs to class 1 */\n" ) ;
    fprintf( F , "    1        /* Object 2 belongs to class 1 */\n" ) ;
    fprintf( F , "    2        /* Object 3 belongs to class 2 */\n" ) ;
    fprintf( F , "    1\n" ) ;
    fprintf( F , "    2\n" ) ;
    fprintf( F , "    2\n" ) ;
    fprintf( F , "    ...\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "    - Ex 2 : Data segmented in 3 fuzzy classes\n" ) ;
    fprintf( F , "    0.2  0.7  0.1    /* Object 1 : class 1 with probability 0.2 , etc. */\n" ) ;
    fprintf( F , "    0.8  0.05 0.015\n" ) ;
    fprintf( F , "    ...\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " 2) file.mf\n" ) ;
    fprintf( F , " ----------\n" ) ;
    fprintf( F , "    \n" ) ;
    fprintf( F , "    This file gives the values of criteria optimized by the algorithm,\n" ) ;
    fprintf( F , "    and the parameters of the mixture calculated by the\n" ) ;
    fprintf( F , "    algorithm (means, proportions, scale parameter). Example: \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "~~~~~~~~~~~~~~~~~~~~~~~~~~~~ START EXAMPLE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ) ;
    fprintf( F , "Command line : \n" ) ;
    fprintf( F , " \n" ) ;
    fprintf( F , "  nem_exe intro 2 -b 1.00 -f fuzzy -R intro.cr -o intro_b10 -s r 10 -C M \n" ) ;
    fprintf( F , " \n" ) ;
    fprintf( F , "Criteria U=NEM, D=Hathaway, L=mixture, M=markov ps-like, error\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "  56.3807    -2671.73    -1788.76    -2793.36   0.335938\n" ) ;
    fprintf( F , " \n" ) ;
    fprintf( F , "Beta (fixed)\n" ) ;
    fprintf( F , "  1.0000\n" ) ;
    fprintf( F , "Mu (4), Pk, and sigma (4) of the 2 classes\n" ) ;
    fprintf( F , " \n" ) ;
    fprintf( F , "   0.947  0.00456  0.0199  0.998   0.5    1.15226  1.15226  1.15226  1.15226 \n" ) ;
    fprintf( F , "   0.0614 1.03     0.864  -0.163   0.5    1.15226  1.15226  1.15226  1.15226 \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "~~~~~~~~~~~~~~~~~~~~~~~~~~~~ END EXAMPLE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , " 3) file.log\n" ) ;
    fprintf( F , " -----------\n" ) ;
    fprintf( F , "    Details each iteration results (optimized criterion and \n" ) ;
    fprintf( F , "    class parameters).\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
} /* end of PrintHelpFileOut() */


void PrintHelpVersions( FILE* F )
{
    fprintf( F , "\n" ) ;
    fprintf( F , "History of modifications\n" ) ;
    fprintf( F , "========================\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Version 0.00  (01.02.1996)\n" ) ;
    fprintf( F , "------------\n" ) ;
    fprintf( F , "First version released on WEB. Initialization by sorting variable.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Version 1.00  (31.05.1996)  \n" ) ;
    fprintf( F , "------------\n" ) ;
    fprintf( F , "Random initializations. Image default neighborhood system. Long help.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Version 1.01  (27.06.1996)  \n" ) ;
    fprintf( F , "------------\n" ) ;
    fprintf( F , "Added an -a ncem option to implement the crisp clustering version of NEM.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Each observation is now updated sequentially in turn. The previous \n" ) ;
    fprintf( F , "parallel updating would produce chessboard-like images for high betas.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Version 1.02  (17.10.1996)\n" ) ;
    fprintf( F , "------------\n" ) ;
    fprintf( F , "Added the possibility to take into account a partial knowledge\n" ) ;
    fprintf( F , "of the classification into the clustering procedure \n" ) ;
    fprintf( F , "(option '-s l <file.ck>').\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Version 1.03  (02.10.1997)  \n" ) ;
    fprintf( F , "------------\n" ) ;
    fprintf( F , "If a partial knowledge of the classification is available, the\n" ) ;
    fprintf( F , "intial cluster centers are computed from the observations with\n" ) ;
    fprintf( F , "known labels.  \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "The log file is made optional (option '-l y').  The ___.mf file now\n" ) ;
    fprintf( F , "also contains the estimated cluster proportions, volumes and\n" ) ;
    fprintf( F , "covariance matrices and the values of the final criteria.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Version 1.04  (11.01.1998)  \n" ) ;
    fprintf( F , "------------\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Two heuristics are implemented to estimate the spatial smoothness\n" ) ;
    fprintf( F , "coefficient beta.  The first heuristic is based on detecting a sharp\n" ) ;
    fprintf( F , "drop in the fuzzy within-cluster inertia D, or a sufficient decrease\n" ) ;
    fprintf( F , "from its maximum value, when beta is slowly increased.  The second\n" ) ;
    fprintf( F , "heuristic is based on detecting a sufficient decrease of the\n" ) ;
    fprintf( F , "log-likelihood L of the mixture parameters from its maximum value.\n" ) ;
    fprintf( F , "The heuristics may be invoked with '-B heu_d' or '-B heu_l'. Their\n" ) ;
    fprintf( F , "default parameters may be changed with '-H ...'. \n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "The final partition may now be printed to standard ouput instead of to a\n" ) ;
    fprintf( F , "file (option '-o -').  The result can thus be redirected as an \n" ) ;
    fprintf( F , "initial partition to another nem_exe session's input.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "The initial partition may now be read from any file with option '-s f\n" ) ;
    fprintf( F , "foo.bar' (previously inputbasename.u0 was used).  In particular, the\n" ) ;
    fprintf( F , "partition may be read from standard input (option '-s f -').  This allows\n" ) ;
    fprintf( F , "to read the initial partition through a pipe from the result of a previous \n" ) ;
    fprintf( F , "nem_exe session.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "At each iteration, the fuzzy classification at the E-step may now be\n" ) ;
    fprintf( F , "computed by either of two methods :\n" ) ;
    fprintf( F , "- Neighborhood EM's fixed point technique (default, '-a nem')\n" ) ;
    fprintf( F , "- Gibbsian EM's Gibbs sampler technique ('-a gem').\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "A longer explanation is given for the options and successive versions\n" ) ;
    fprintf( F , "(option '-h helptopic').\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Other options have been added, to test the effect of alternative\n" ) ;
    fprintf( F , "parameter values.  Those options usually do not change considerably\n" ) ;
    fprintf( F , "the default behaviour of the algorithm :\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "- At the E-step of each iteration, the classification may now be\n" ) ;
    fprintf( F , "  updated in a random order instead of 1..N (option '-O random').\n" ) ;
    fprintf( F , "- The seed of the random number generator may now be given (option '-S seed').\n" ) ;
    fprintf( F , "- The number of E-step internal iterations may be changed (option '-I eiter').\n" ) ;
    fprintf( F , "- The convergence threshold may also be changed (option '-c cvthres').\n" ) ;
    fprintf( F , "- Another criterion than U may be chosen to select best result ('-C crit').\n" ) ;
    fprintf( F , "- Compute the classification error in two-class case ('-R refclass').\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "A few internal changes were also made to make the program portable to\n" ) ;
    fprintf( F , "the djgpp gcc compiler for MS-DOS (srand48 replaced by srandom).\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "Version 1.05  (09-APR-1998)  \n" ) ;
    fprintf( F , "------------\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "This version mainly adds the capability to deal with missing data.\n" ) ;
    fprintf( F , "This means that some of the N observation vectors may be incompletely\n" ) ;
    fprintf( F , "observed.  In the 'name.dat' file, use NaN to indicate unobserved\n" ) ;
    fprintf( F , "components of an observation vector.  Two slightly different\n" ) ;
    fprintf( F , "techniques are provided to deal with missing data.  The first and\n" ) ;
    fprintf( F , "default behaviour (invoked using switch '-M replace') roughly consists\n" ) ;
    fprintf( F , "in replacing any missing component with its expected value.  This\n" ) ;
    fprintf( F , "technique implements the EM procedure and finds parameters maximizing\n" ) ;
    fprintf( F , "the likelihood.  The alternative behaviour (invoked using switch '-M\n" ) ;
    fprintf( F , "ignore') consists in ignoring missing components.  This means that the\n" ) ;
    fprintf( F , "means are computed using only observed components.  This alternative\n" ) ;
    fprintf( F , "technique finds a classification matrix and parameters which maximize\n" ) ;
    fprintf( F , "the fuzzy classifying log-likelihood.  It appears to converge a bit\n" ) ;
    fprintf( F , "faster than the 'replace' mode.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "The iteration count is displayed in a more economic way now (all the\n" ) ;
    fprintf( F , "iteration numbers were displayed separately).\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "A new criterion is computed, the fuzzy pseudo-likelihood, named M.\n" ) ;
    fprintf( F , "Using this criterion in order to choose the best result \n" ) ;
    fprintf( F , "may prove less sensitive to the value of beta than using U.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "In the random start strategy, two initialization tactics have been\n" ) ;
    fprintf( F , "made more sensible.  The initial volumes are computed as whole volume\n" ) ;
    fprintf( F , "/ number of classes (the whole volume was used previously).  The means\n" ) ;
    fprintf( F , "are redrawn until all drawn means are different --- this avoids the\n" ) ;
    fprintf( F , "problem of artificially merging together two classes.\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "A few internal changes were also made in order to allow direct call to\n" ) ;
    fprintf( F , "the program from as a Matlab function.  This allowed to detect and\n" ) ;
    fprintf( F , "remove a few potential bugs that had gone unnoticed (a file not\n" ) ;
    fprintf( F , "closed, use of memory just after freeing it).\n" ) ;
    fprintf( F , "\n" ) ;
    fprintf( F , "\n" ) ;
} /* end of PrintHelpVersions() */


