/* ----------------------------------------------------------------------- *
 *                                                                         *
 *    (C) Copyright 1996 by:  aiNet                                        *
 *										Trubarjeva 42, SI-3000 Celje                 *
 *										Europe, Slovenia                             *
 *     All Rights Reserved                                                 *
 *                                                                         *
 *     Subject: C code for single vector prediction.                       *
 *     File:    t2runtim - The XOR problem with dynamic model creation     *
 *                                                                         *
 * ----------------------------------------------------------------------- */

/*--------------------------------------------------------------------------
	Here it will be shown how we can solve the XOR problem using
	aiNet C functions. The problem is the same as in DLLTST02.

	The XOR problem:
	================
		Number of model vectors: 4
			 Number of variables: 3
	 Number of input variables: 3
		 Any discrete variables: NONE

		Model vectors:  Inp,Inp,Out
				  row 1:  1,  1,  0
				  row 2:  1,  0,  1
				  row 3:  0,  1,  1
				  row 4:  0,  0,  0

	Test vectors (vectors which will be used in prediction) together with
	penalty coefficient and penalty method.

		 Prediction vectors:  Inp  Inp  Out
						  prd 1:  0.9  0.1  ??
						  prd 2:  0.1  0.9  ??
						  prd 3:  0.2  0.2  ??
						  prd 4:  0.7  0.7  ??

		 Penalty coeffcient: 1.5
		 Penalty methods:    NEAREST

	NOTE: Selected penalty coefficients are in no case optimal.
			They were selected randomly, to perform a few tests.
			The test results were compared with the results calculated by
			the main aiNet 1.14 application.

	--------------------------------------------------------------------------
	Results (rounded at fourth decimal):
	--------------------------------------------------------------------------

		 Penalty cefficient: 1.5
		 Penalty method:     NEAREST N.
												  (RESULT)
		 Prediction vectors:  Inp  Inp  (  Out )
						  prd 1:  0.9  0.1  (0.9989)
						  prd 2:  0.1  0.9  (0.9989)
						  prd 3:  0.2  0.2  (0.1054)
						  prd 4:  0.7  0.7  (0.3449)

	-------------------------------------------------------------------------*/

   /*
    * This file assumes that ainetxx.dll will be loaded at run time,
    * which is default option and no flags need to be defined.
    * ainetxx.lib must NOT be included in the linking process.
    */

#include "ainetdll.h"
#include <stdio.h>
#include <stdlib.h>

/*
 * Path and the filename of dll which will be loaded.
 */

#if defined(__WIN32__)
const char ainetDll[] = "ainet32.dll";
#else
const char ainetDll[] = "ainet16.dll";
#endif
/*
 * Pointers to ainet dll functions. They are made global - all functions
 * can use them.
 */

t_aiRegistration              paiRegistration;
t_aiGetVersion                paiGetVersion;
t_aiCreateModel               paiCreateModel;
t_aiCreateModelFromCSVFile    paiCreateModelFromCSVFile;
t_aiDeleteModel               paiDeleteModel;
t_aiNormalize                 paiNormalize;
t_aiDenormalize               paiDenormalize;
t_aiPrediction                paiPrediction;
t_aiGetNumberOfVariables      paiGetNumberOfVariables;
t_aiGetNumberOfModelVectors   paiGetNumberOfModelVectors;
t_aiGetNumberOfInputVariables paiGetNumberOfInputVariables;
t_aiSetDiscreteFlag           paiSetDiscreteFlag;
t_aiGetDiscreteFlag           paiGetDiscreteFlag;
t_aiSetVariable               paiSetVariable;
t_aiGetVariable               paiGetVariable;
t_aiGetVariableVB             paiGetVariableVB;
t_aiGetCSVFileModelSize       paiGetCSVFileModelSize;

/*
 *  ainet32.dll module variable.
 */

HINSTANCE hLib;

/*
 *  The load_aiNetLibrary() function is implemented below.
 *  This function will load ainet32.dll and define pointers to
 *  ainet functions.
 */

int load_aiNetLibrary(void);

/*
 *
 */

void main()
{

   /*
    * Working variables
    */

	int i;
	int version;

	/*
	 * vectors to be predicted
	 */

	float predict[4][3] = { { 0.9,0.1, 999 },
									{ 0.1,0.9, 999 },
									{ 0.2,0.2, 999 },
									{ 0.7,0.7, 999 } };
	/*
	 * Model variable
	 */

	aiModel* model;

   /*
    * Load DLL
    */
   if( !load_aiNetLibrary() ) {
		exit(EXIT_FAILURE);
	}

	/*
	 * Title
	 */

	version = paiGetVersion();
	printf( "\naiNetDLL version %i.%i! (C) Copyright by aiNet, 1996",
			  version/100, version%100 );
	printf( "\n---------------------------------------------------\n" );

	/*
	 * Register DLL
	 */

	paiRegistration( "Your registration name", "Your code" );

	/*
	 * Allocate the model variable and necessary memory
	 */

	model = paiCreateModel(4,   /* 4 model vectors   */
						   	  3,   /* 3 variables       */
							 	  2);  /* 2 input variables */
	if(!model) {
		printf( "\nError: Something went wrong during model creation!" );
		exit(EXIT_FAILURE);
	}

	/*
	 * Loading data into the model using aiSetVariable function
	 */

	paiSetVariable(model,1,1, 1.0); /* first model vector */
	paiSetVariable(model,1,2, 1.0); /* 1 xor 1 = 0        */
	paiSetVariable(model,1,3, 0.0);

	paiSetVariable(model,2,1, 1.0); /* second model vector */
	paiSetVariable(model,2,2, 0.0); /* 1 xor 0 = 1         */
	paiSetVariable(model,2,3, 1.0);

	paiSetVariable(model,3,1, 0.0); /* third model vector */
	paiSetVariable(model,3,2, 1.0); /* 0 xor 1 = 1        */
	paiSetVariable(model,3,3, 1.0);

	paiSetVariable(model,4,1, 0.0); /* fourth model vector */
	paiSetVariable(model,4,2, 0.0); /* 0 xor 0 = 0         */
	paiSetVariable(model,4,3, 0.0);

	/*
	 * Output the model
	 */

	printf( "\n             Model name: aiNet DLL test 2 (aiCreateModel)" );
	printf( "\nNumber of model vectors: %i", paiGetNumberOfModelVectors(model));
	printf( "\n    Number of variables: %i", paiGetNumberOfVariables(model));
	printf( "\n         Variable names: A,   B,   A xor B" );
	printf( "\n          Discrete flag: %i,   %i,   %i",
			  paiGetDiscreteFlag(model,1),
			  paiGetDiscreteFlag(model,2),
			  paiGetDiscreteFlag(model,3) );
	for( i=1; i<=paiGetNumberOfModelVectors(model); i++ ) {
		printf( "\n\t\t\t %3.1lf, %3.1lf, %3.1lf",
				  paiGetVariable(model, i,1),
				  paiGetVariable(model, i,2),
				  paiGetVariable(model, i,3) );
	}

	/*
	 * Normalize the model
	 */

	paiNormalize(model, NORMALIZE_REGULAR);

	/*
	 * Prediction
	 * This test has nearest neighbour penalty coefficient 1.50
	 */

	printf( "\n\n  Penalty coefficient: 1.50" );
	printf(   "\n       Penalty method: NEAREST N." );
	printf(   "\n\t A(inp), B(inp), A xor B(out)" );
	for ( i=0; i<4; i++ ) {
		paiPrediction(model, predict[i], 1.50, PENALTY_NEAREST);
		printf( "\n\t%7.4lf, %7.4lf, %7.4lf",
				  predict[i][0],predict[i][1],predict[i][2] );
	}

	/*
	 * Denormalize the model (in this case it is not necessary)
	 */

	paiDenormalize(model);

	/*
	 * Free alocated memory
	 */

	paiDeleteModel(model);
   FreeLibrary(hLib);

	printf( "\n\nEnd." );
	exit(EXIT_SUCCESS);
}

int load_aiNetLibrary()
{
   /*
    * Load the Dynamic Link Library AINET32.DLL
    */

   hLib = LoadLibrary(ainetDll);
   if((unsigned)hLib<=HINSTANCE_ERROR){
      char bfr[40];
      wsprintf(bfr, "Failure loading library: %s", ainetDll);
      MessageBox(NULL, bfr, "Error", MB_OK|MB_APPLMODAL);
      return 0;
   }

   /*
    * Get all the entry points for the functions in ainet32.dll
    */

	paiRegistration              = (t_aiRegistration)              GetProcAddress(hLib, "aiRegistration");
   paiGetVersion                = (t_aiGetVersion)                GetProcAddress(hLib, "aiGetVersion");
   paiCreateModel               = (t_aiCreateModel)               GetProcAddress(hLib, "aiCreateModel");
   paiCreateModelFromCSVFile    = (t_aiCreateModelFromCSVFile)    GetProcAddress(hLib, "aiCreateModelFromCSVFile");
   paiDeleteModel               = (t_aiDeleteModel)               GetProcAddress(hLib, "aiDeleteModel");
   paiNormalize                 = (t_aiNormalize)                 GetProcAddress(hLib, "aiNormalize");
   paiDenormalize               = (t_aiDenormalize)               GetProcAddress(hLib, "aiDenormalize");
   paiPrediction                = (t_aiPrediction)                GetProcAddress(hLib, "aiPrediction");
   paiGetNumberOfVariables      = (t_aiGetNumberOfVariables)      GetProcAddress(hLib, "aiGetNumberOfVariables");
   paiGetNumberOfModelVectors   = (t_aiGetNumberOfModelVectors)   GetProcAddress(hLib, "aiGetNumberOfModelVectors");
   paiGetNumberOfInputVariables = (t_aiGetNumberOfInputVariables) GetProcAddress(hLib, "aiGetNumberOfInputVariables");
   paiSetDiscreteFlag           = (t_aiSetDiscreteFlag)           GetProcAddress(hLib, "aiSetDiscreteFlag");
   paiGetDiscreteFlag           = (t_aiGetDiscreteFlag)           GetProcAddress(hLib, "aiGetDiscreteFlag");
   paiSetVariable               = (t_aiSetVariable)               GetProcAddress(hLib, "aiSetVariable");
   paiGetVariable               = (t_aiGetVariable)               GetProcAddress(hLib, "aiGetVariable");
   paiGetVariableVB             = (t_aiGetVariableVB)             GetProcAddress(hLib, "aiGetVariableVB");
   paiGetCSVFileModelSize       = (t_aiGetCSVFileModelSize)       GetProcAddress(hLib, "aiGetCSVFileModelSize");

   /*
    * GetProcAddress returns null on failure
    */
   if( paiRegistration == NULL
       || paiGetVersion == NULL
       || paiCreateModel == NULL
       || paiCreateModelFromCSVFile == NULL
       || paiDeleteModel == NULL
       || paiNormalize == NULL
       || paiDenormalize == NULL
       || paiPrediction == NULL
       || paiGetNumberOfVariables == NULL
       || paiGetNumberOfModelVectors == NULL
       || paiGetNumberOfInputVariables == NULL
       || paiSetDiscreteFlag == NULL
       || paiGetDiscreteFlag == NULL
       || paiSetVariable == NULL
       || paiGetVariable == NULL
       || paiGetVariableVB == NULL
       || paiGetCSVFileModelSize == NULL ) {
		MessageBox(NULL, "Failure locating procedures.", "Error",
            MB_OK|MB_APPLMODAL);
      return 0;
	}
   return 1;
}

/* THE END */