├── .DS_Store ├── .gitignore ├── EncogExample ├── EncogExample.cpp ├── EncogExample.vcxproj ├── EncogExample.vcxproj.filters ├── EncogExample.vcxproj.user ├── ReadMe.txt ├── example.c └── test.csv ├── README.md ├── encog-c-cuda.sln ├── encog-c.5.1.ReSharper.user ├── encog-c.sln ├── encog-cmd ├── 3 ├── SIGMOID- ├── cuda.cpp ├── cuda_test.c ├── cuda_vecadd.cu ├── encog-cmd-cuda.vcxproj ├── encog-cmd-cuda.vcxproj.filters ├── encog-cmd-cuda.vcxproj.user ├── encog-cmd.c ├── encog-cmd.h ├── encog-cmd.vcxproj ├── encog-cmd.vcxproj.user ├── node.c ├── node_unix.c ├── node_windows.c ├── test.csv ├── test.eg ├── test.egb └── xor.eg ├── encog-core ├── activation.c ├── cuda_eval.cu ├── data.c ├── encog-c.vcxproj.filters ├── encog-c.vcxproj.user ├── encog-cmd │ └── cuda_eval.cu.deps ├── encog-core-cuda.sln ├── encog-core-cuda.vcxproj ├── encog-core-cuda.vcxproj.user ├── encog-core.vcxproj ├── encog-core.vcxproj.user ├── encog.c ├── encog.h ├── encog_cuda.cu ├── encog_cuda.h ├── errorcalc.c ├── errors.c ├── hash.c ├── network.c ├── network_io.c ├── nm.c ├── object.c ├── pso.c ├── random.c ├── rprop.c ├── train.c ├── util.c ├── util_file.c ├── util_str.c └── vector.c └── makefile /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffheaton/encog-c/d207819b86d1c2b4dba114dbc3cbd784df999e05/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.*~ 2 | *.suo 3 | *.pdb 4 | *.sdf 5 | _ReSharper* 6 | *.o 7 | *.a 8 | *.sdf 9 | *.user 10 | encog 11 | encog-core/_ReSharper* 12 | encog-core/Debug/ 13 | encog-core/Release/ 14 | encog-core/x64/ 15 | encog-cmd/_ReSharper* 16 | encog-cmd/Debug/ 17 | encog-cmd/Release/ 18 | encog-cmd/x64/ 19 | _ReSharper.encog-c/ 20 | ipch/ 21 | Debug/ 22 | Release/ 23 | x64/ 24 | obj-lib/ 25 | lib/ 26 | obj-cmd/ 27 | encog-c.sdf 28 | encog-c-cuda.sdf 29 | -------------------------------------------------------------------------------- /EncogExample/EncogExample.cpp: -------------------------------------------------------------------------------- 1 | // EncogExample.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | 7 | int _tmain(int argc, _TCHAR* argv[]) 8 | { 9 | return 0; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /EncogExample/EncogExample.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A} 23 | Win32Proj 24 | EncogExample 25 | 26 | 27 | 28 | Application 29 | true 30 | Unicode 31 | 32 | 33 | Application 34 | true 35 | Unicode 36 | 37 | 38 | Application 39 | false 40 | true 41 | Unicode 42 | 43 | 44 | Application 45 | false 46 | true 47 | Unicode 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | true 67 | 68 | 69 | true 70 | 71 | 72 | false 73 | 74 | 75 | false 76 | 77 | 78 | 79 | NotUsing 80 | Level3 81 | Disabled 82 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 83 | ..\encog-core 84 | true 85 | 86 | 87 | Console 88 | true 89 | 90 | 91 | 92 | 93 | NotUsing 94 | Level3 95 | Disabled 96 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 97 | ..\encog-core 98 | 99 | 100 | Console 101 | true 102 | 103 | 104 | 105 | 106 | Level3 107 | NotUsing 108 | MaxSpeed 109 | true 110 | true 111 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 112 | ..\encog-core 113 | true 114 | 115 | 116 | Console 117 | true 118 | true 119 | true 120 | 121 | 122 | 123 | 124 | Level3 125 | NotUsing 126 | MaxSpeed 127 | true 128 | true 129 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 130 | ..\encog-core 131 | true 132 | 133 | 134 | Console 135 | true 136 | true 137 | true 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | {3df9ceff-41ca-46b9-a659-a63c6d19d204} 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /EncogExample/EncogExample.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | -------------------------------------------------------------------------------- /EncogExample/EncogExample.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | train d:\xor.egb d:\xor.eg d:\xor.eg 5 | WindowsLocalDebugger 6 | 7 | -------------------------------------------------------------------------------- /EncogExample/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : EncogExample Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this EncogExample application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your EncogExample application. 9 | 10 | 11 | EncogExample.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | EncogExample.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | EncogExample.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named EncogExample.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /EncogExample/example.c: -------------------------------------------------------------------------------- 1 | #include "encog.h" 2 | #include 3 | 4 | char parsedOption[MAX_STR]; 5 | char parsedArgument[MAX_STR]; 6 | 7 | void Usage() { 8 | puts("\nUsage:\n"); 9 | puts("encog xor"); 10 | puts("encog benchmark"); 11 | puts("encog train [egb file]"); 12 | puts("encog egb2csv [egb file] [csv file]"); 13 | puts("encog csv2egb [csv file] [egb file]"); 14 | puts(""); 15 | puts("Options:"); 16 | puts(""); 17 | puts("/input:## The number of inputs."); 18 | puts("/ideal:## The number of ideals."); 19 | puts("/records:## The number of ideals."); 20 | puts("/iterations:## The number of ideals."); 21 | puts("/threads:## The number of threads."); 22 | }; 23 | 24 | void ParseOption(char *str) 25 | { 26 | char *ptr; 27 | 28 | if( *str=='/' || *str=='-' ) { 29 | str++; 30 | } 31 | 32 | ptr = strchr(str,':'); 33 | 34 | if( ptr!=NULL ) { 35 | strncpy(parsedOption,str,MIN(MAX_STR,ptr-str)); 36 | strncpy(parsedArgument,ptr+1,MAX_STR); 37 | } else { 38 | strncpy(parsedOption,str,MAX_STR); 39 | *parsedArgument = 0; 40 | } 41 | } 42 | 43 | void RunBenchmark(INT inputCount, INT idealCount, INT records, INT iterations ) { 44 | ENCOG_DATA *data; 45 | ENCOG_NEURAL_NETWORK *net; 46 | ENCOG_TRAIN_PSO *pso; 47 | INT i; 48 | time_t startTime; 49 | time_t endTime; 50 | int elapsed; 51 | 52 | if( inputCount==-1 ) { 53 | inputCount = 10; 54 | } 55 | 56 | if( idealCount==-1 ) { 57 | idealCount = 1; 58 | } 59 | 60 | if( records==-1 ) { 61 | records = 10000; 62 | } 63 | 64 | if( iterations==-1 ) { 65 | iterations = 100; 66 | } 67 | 68 | printf("\nPerforming benchmark\n"); 69 | printf("Input Count: %i\n",inputCount); 70 | printf("Ideal Count: %i\n",idealCount); 71 | printf("Records: %i\n",records); 72 | printf("Iterations: %i\n",iterations); 73 | 74 | data = EncogDataGenerateRandom(inputCount,idealCount,records,-1,1); 75 | 76 | net = EncogNetworkNew(); 77 | EncogErrorCheck(); 78 | EncogNetworkAddLayer(net,inputCount,&EncogActivationTANH,1); 79 | EncogNetworkAddLayer(net,50,&EncogActivationTANH,1); 80 | EncogNetworkAddLayer(net,idealCount,&EncogActivationTANH,1); 81 | EncogNetworkFinalizeStructure(net); 82 | EncogErrorCheck(); 83 | 84 | EncogNetworkRandomizeRange(net,-1,1); 85 | 86 | pso = EncogTrainPSONew(30, net, data); 87 | EncogErrorCheck(); 88 | 89 | startTime = time(NULL); 90 | 91 | for(i=0;i0.01); 154 | 155 | /* Pull the best neural network that the PSO found */ 156 | EncogTrainPSOImportBest(pso,net); 157 | EncogTrainPSODelete(pso); 158 | 159 | /* Display the results from the neural network, see if it learned anything */ 160 | printf("\nResults:\n"); 161 | for(i=0; i<4; i++) 162 | { 163 | input = EncogDataGetInput(data,i); 164 | ideal = EncogDataGetIdeal(data,i); 165 | EncogNetworkCompute(net,input,output); 166 | *line = 0; 167 | EncogStrCatStr(line,"[",MAX_STR); 168 | EncogStrCatDouble(line,input[0],8,MAX_STR); 169 | EncogStrCatStr(line," ",MAX_STR); 170 | EncogStrCatDouble(line,input[1],8,MAX_STR); 171 | EncogStrCatStr(line,"] = ",MAX_STR); 172 | EncogStrCatDouble(line,output[0],8,MAX_STR); 173 | puts(line); 174 | } 175 | 176 | /* Obtain the SSE error, display it */ 177 | error = EncogErrorSSE(net, data); 178 | *line = 0; 179 | EncogStrCatStr(line,"Error: ",MAX_STR); 180 | EncogStrCatDouble(line,(double)error,4,MAX_STR); 181 | puts(line); 182 | 183 | /* Delete the neural network */ 184 | EncogNetworkDelete(net); 185 | EncogErrorCheck(); 186 | 187 | } 188 | 189 | void train(char *egbFile, char *egFile) { 190 | ENCOG_DATA *data; 191 | ENCOG_NEURAL_NETWORK *net; 192 | ENCOG_TRAIN_PSO *pso; 193 | INT iteration; 194 | float error; 195 | char line[MAX_STR]; 196 | INT lastUpdate; 197 | 198 | data = EncogDataEGBLoad(egbFile); 199 | EncogErrorCheck(); 200 | 201 | printf("Training\n"); 202 | printf("Input Count: %i\n", data->inputCount); 203 | printf("Ideal Count: %i\n", data->idealCount); 204 | printf("Record Count: %ld\n", data->recordCount); 205 | 206 | /* Create a 3 layer neural network, with sigmoid transfer functions and bias */ 207 | 208 | net = EncogNetworkNew(); 209 | EncogErrorCheck(); 210 | EncogNetworkAddLayer(net,data->inputCount,&EncogActivationTANH,1); 211 | EncogNetworkAddLayer(net,6,&EncogActivationTANH,1); 212 | EncogNetworkAddLayer(net,data->idealCount,&EncogActivationTANH,0); 213 | EncogNetworkFinalizeStructure(net); 214 | EncogErrorCheck(); 215 | 216 | /* Randomize the neural network weights */ 217 | EncogNetworkRandomizeRange(net,-1,1); 218 | EncogErrorCheck(); 219 | 220 | /* Create a PSO trainer */ 221 | pso = EncogTrainPSONew(30, net, data); 222 | EncogErrorCheck(); 223 | 224 | /* Begin training, report progress. */ 225 | iteration = 1; 226 | lastUpdate = 0; 227 | do 228 | { 229 | error = EncogTrainPSOIterate(pso); 230 | EncogErrorCheck(); 231 | lastUpdate++; 232 | if( lastUpdate>=100 ) 233 | { 234 | lastUpdate = 0; 235 | *line = 0; 236 | EncogStrCatStr(line,"Iteration #",MAX_STR); 237 | EncogStrCatInt(line,iteration,MAX_STR); 238 | EncogStrCatStr(line,", Error: ",MAX_STR); 239 | EncogStrCatDouble(line,error,4,MAX_STR); 240 | puts(line); 241 | } 242 | iteration++; 243 | } while(error>0.01); 244 | 245 | /* Pull the best neural network that the PSO found */ 246 | EncogTrainPSOImportBest(pso,net); 247 | EncogErrorCheck(); 248 | 249 | EncogNetworkSave(egFile,net); 250 | EncogErrorCheck(); 251 | 252 | EncogTrainPSODelete(pso); 253 | EncogErrorCheck(); 254 | } 255 | 256 | void EGB2CSV(char *egbFile, char *csvFile) 257 | { 258 | ENCOG_DATA *data; 259 | 260 | data = EncogDataEGBLoad(egbFile); 261 | EncogErrorCheck(); 262 | 263 | printf("Converting EGB to CSV\n"); 264 | printf("Input Count: %i\n", data->inputCount); 265 | printf("Ideal Count: %i\n", data->idealCount); 266 | printf("Record Count: %ld\n", data->recordCount); 267 | printf("Source File: %s\n", egbFile ); 268 | printf("Target File: %s\n", csvFile ); 269 | 270 | EncogDataCSVSave(csvFile,data,10); 271 | EncogErrorCheck(); 272 | EncogDataDelete(data); 273 | EncogErrorCheck(); 274 | 275 | printf("Conversion done.\n"); 276 | } 277 | 278 | void CSV2EGB(char *csvFile, char *egbFile, int inputCount, int idealCount) 279 | { 280 | ENCOG_DATA *data; 281 | 282 | if( inputCount==-1 || idealCount==-1 ) { 283 | printf("You must specify both input and ideal counts.\n"); 284 | exit(1); 285 | } 286 | 287 | data = EncogDataCSVLoad(csvFile, inputCount, idealCount); 288 | EncogErrorCheck(); 289 | 290 | printf("Converting CSV to EGB\n"); 291 | printf("Input Count: %i\n", data->inputCount); 292 | printf("Ideal Count: %i\n", data->idealCount); 293 | printf("Record Count: %ld\n", data->recordCount); 294 | printf("Source File: %s\n", csvFile ); 295 | printf("Target File: %s\n", egbFile ); 296 | 297 | EncogDataEGBSave(egbFile,data); 298 | EncogErrorCheck(); 299 | EncogDataDelete(data); 300 | EncogErrorCheck(); 301 | 302 | printf("Conversion done.\n"); 303 | } 304 | 305 | int main(int argc, char* argv[]) 306 | { 307 | INT i; 308 | INT inputCount = -1; 309 | INT idealCount = -1; 310 | INT records = -1; 311 | INT iterations = -1; 312 | INT threads = 0; 313 | INT phase = 0; 314 | char command[MAX_STR]; 315 | char arg1[MAX_STR]; 316 | char arg2[MAX_STR]; 317 | 318 | printf("* * Encog C/C++ Command Line v0.1 * *\n"); 319 | printf("Running in: %i bit mode\n", (int)(sizeof(void*)*8)); 320 | printf("Processor/Core Count: %i\n", (int)omp_get_num_procs()); 321 | 322 | *arg1=*arg2=0; 323 | 324 | for(i=1;i<(INT)argc;i++) { 325 | if( *argv[i]=='/' || *argv[i]=='-' ) 326 | { 327 | ParseOption(argv[i]); 328 | if( !EncogUtilStrcmpi(parsedOption,"INPUT") ) { 329 | inputCount = atoi(parsedArgument); 330 | } else if( !EncogUtilStrcmpi(parsedOption,"IDEAL") ) { 331 | idealCount = atoi(parsedArgument); 332 | } else if( !EncogUtilStrcmpi(parsedOption,"RECORDS") ) { 333 | records = atoi(parsedArgument); 334 | } else if( !EncogUtilStrcmpi(parsedOption,"ITERATIONS") ) { 335 | iterations = atoi(parsedArgument); 336 | } else if( !EncogUtilStrcmpi(parsedOption,"THREADS") ) { 337 | threads = atoi(parsedArgument); 338 | omp_set_num_threads(threads); 339 | } 340 | 341 | } 342 | else 343 | { 344 | if( phase==0 ) { 345 | strncpy(command,argv[i],MAX_STR); 346 | EncogUtilStrlwr(command); 347 | } else if( phase==1 ) { 348 | strncpy(arg1,argv[i],MAX_STR); 349 | } else if( phase==2 ) { 350 | strncpy(arg2,argv[i],MAX_STR); 351 | } 352 | 353 | phase++; 354 | } 355 | } 356 | 357 | EncogUtilInitRandom(); 358 | 359 | if(!EncogUtilStrcmpi(command,"xor") ) { 360 | XORTest(); 361 | } else if (!EncogUtilStrcmpi(command,"benchmark") ) { 362 | RunBenchmark(inputCount,idealCount,records,iterations ); 363 | } else if (!EncogUtilStrcmpi(command,"train") ) { 364 | train(arg1,arg2); 365 | } else if (!EncogUtilStrcmpi(command,"egb2csv") ) { 366 | EGB2CSV(arg1,arg2); 367 | } else if (!EncogUtilStrcmpi(command,"csv2egb") ) { 368 | CSV2EGB(arg1,arg2,inputCount,idealCount); 369 | } else { 370 | Usage(); 371 | } 372 | 373 | 374 | return 0; 375 | } 376 | -------------------------------------------------------------------------------- /EncogExample/test.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffheaton/encog-c/d207819b86d1c2b4dba114dbc3cbd784df999e05/EncogExample/test.csv -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Encog Machine Learning Framework](http://www.heatonresearch.com/images/encog128.png) 2 | 3 | Encog C/C++ v1.0 (experimental) 4 | =============================== 5 | 6 | This is quick and experimental port of [Encog](http://www.encog.org) that I did for C/C++. **I am not currently developing this port, but I am putting it on GitHub incase it is useful to someone.** The primary purpose of this port was to experiment with CUDA. However, it will work either with or without CUDA. The CPU version does make use of [OpenMP](http://www.openmp.org/) for efficient processing. 7 | 8 | This file includes the complete source code for Encog for C. The header files are designed so that Encog can also be used with C++. This file includes instructions on how to compile and execute Encog for C. 9 | 10 | Visual C++ 11 | ---------- 12 | 13 | Just open the encog-c.sln file and compile as you would any Visual Studio 14 | project. 15 | 16 | UNIX 17 | ---- 18 | 19 | Simply execute the make command in the directory that includes the 20 | Encog makefile. The makefile has been tested with Linux, MAC, and 21 | Raspberry PI's Debian 7 release. 22 | 23 | There are several options you can use. 24 | 25 | To force 32 or 64 bit compile. 26 | 27 | ``` 28 | make ARCH=32 29 | make ARCH=64 30 | ``` 31 | 32 | To compile with CUDA (for GPU). 33 | 34 | ``` 35 | make CUDA=1 36 | ``` 37 | 38 | You can also combine: 39 | 40 | ``` 41 | make ARCH=64 CUDA=1 42 | ``` 43 | 44 | Clear previous builds: 45 | 46 | ``` 47 | make clean 48 | ``` 49 | 50 | Raspberry PI 51 | ------------ 52 | 53 | The gcc that comes with Raspberry PI seems to have trouble with the -m32 54 | option. The following command will compile Encog for Raspberry PI. 55 | 56 | ``` 57 | make ARCH=RPI 58 | ``` 59 | 60 | Encog CUDA Support 61 | ================== 62 | 63 | Encog for C can make use of a nVidia CUDA enabled GPU for increased performance. Even if 64 | you do not plan to program in C, you can use the Encog for C command line tool to train 65 | neural networks. Encog for C makes use of the same EG Files and EGB Files used by other 66 | Encog platforms, such as the Encog Workbench. CUDA is a very specialized architecture and 67 | will not provide a performance boost for all operations. Currently CUDA can only be used 68 | with the PSO training method. It is unlikely that RPROP will be extended to CUDA as the 69 | CUDA architecture is not particularly conducive to RPROP. RPROP, due to is "backward 70 | propagation" nature requires the activations of all neurons to be kept. Memory access is 71 | one of the most cycle-intensive aspects of GPU programming. CUDA can achieve great speeds 72 | when a SMALL amount of memory must be kept during training. CUDA also works well if a small 73 | amount of memory is kept temporarily and then overwritten as training progresses. This is 74 | the case with PSO. 75 | 76 | Using CUDA with Encog for C 77 | --------------------------- 78 | 79 | When Encog for C is compiled CUDA must be specified. The command to compile Encog with 80 | CUDA is given here. 81 | 82 |
make CUDA=1 ARCH=64
83 | The above command will compile Encog for CUDA and 64-bit CPU. This is the most advanced 84 | build of Encog for C. I provide CUDA binaries for both Mac and Windows. 85 | To find out if your version of Encog for C supports CUDA issue the following command. 86 |
encog-cmd CUDA
87 | This will perform a simple test of the CUDA system. If you are using a CUDA Encog build 88 | the version will be reported like this: 89 |
 90 | 
 91 | * * Encog C/C++ (64 bit, CUDA) Command Line v1.0 * *
 92 | 
 93 | 
94 | If you are using a CUDA build, but your system does not have CUDA drivers or a CUDA GPU, 95 | you will receive a system dependent error message. For more information, see the 96 | troubleshooting section of Encog for C. 97 | 98 | The CUDA build of Encog will always use the GPU if the training method supports it. To 99 | disable the GPU, use the option /gpu:0. You can also specify /gpu:1 to enable the GPU; 100 | however, this is redundant, given that the default operation is to use the GPU. The GPU 101 | will only be used with PSO training. 102 | 103 | A Simple Benchmark 104 | ------------------ 105 | 106 | The Encog command line utility contains a simple benchmark. This benchmark can be used to compare training results between GPU/CPU and CPU only. When the GPU is enabled, Encog is still making full use of your CPU cores. The GPU is simply brought in to assist with certain calculations. The following shows the output from a simple benchmark run. The benchmark is 10,000 data items of 10 inputs and one output, and 100 iterations of PSO. The following time is achieved using GPU and CPU. 107 | 108 |
heaton:encog-c jheaton$ ./encog benchmark /gpu:1
109 | 
110 | * * Encog C/C++ (64 bit, CUDA) Command Line v1.0 * *
111 | Processor/Core Count: 8
112 | Basic Data Type: double (64 bits)
113 | GPU: enabled
114 | Input Count: 10
115 | Ideal Count: 1
116 | Records: 10000
117 | Iterations: 100
118 | 
119 | Performing benchmark...please wait
120 | Benchmark time(seconds): 4.2172
121 | Benchmark time includes only training time.
122 | 
123 | Encog Finished.  Run time 00:00:04.4040
124 | heaton:encog-c jheaton$
125 | As you can see from above, the benchmark was completed in 4.2 seconds. Now we will try the same benchmark, but disable the GPU.
126 | heaton:encog-c jheaton$ ./encog benchmark /gpu:0
127 | 
128 | * * Encog C/C++ (64 bit, CUDA) Command Line v1.0 * *
129 | Processor/Core Count: 8
130 | Basic Data Type: double (64 bits)
131 | GPU: disabled
132 | Input Count: 10
133 | Ideal Count: 1
134 | Records: 10000
135 | Iterations: 100
136 | 
137 | Performing benchmark...please wait
138 | Benchmark time(seconds): 5.3727
139 | Benchmark time includes only training time.
140 | 
141 | Encog Finished.  Run time 00:00:05.3749
142 | heaton:encog-c jheaton$ 
143 | 144 | As you can see, the benchmark was completed in one less second. 145 | As you increase the amount of training data the gap tends to increase. 146 | On small training sets, the overhead of involving the GPU may actually slow training. 147 | You would not want to use the GPU on a simple XOR train. 148 | 149 | The above benchmark was performed on a MacBook Pro with an Intel i7 CPU and a nVidia 150 | 650M GPU. For more information on the computer see the article on Jeff's Computers. 151 | Results will be better with more advanced GPU's. The M on the 650 also means that this is 152 | a "mobile" edition of the GPU. Mobile GPU's tend to perform worse than desktop GPUs. 153 | -------------------------------------------------------------------------------- /encog-c-cuda.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encog-cmd-cuda", "encog-cmd\encog-cmd-cuda.vcxproj", "{CE50443B-9615-4C66-B9BE-57CD2A99F62A}" 5 | ProjectSection(ProjectDependencies) = postProject 6 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204} = {3DF9CEFF-41CA-46B9-A659-A63C6D19D204} 7 | EndProjectSection 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encog-core-cuda", "encog-core\encog-core-cuda.vcxproj", "{3DF9CEFF-41CA-46B9-A659-A63C6D19D204}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Win32 = Debug|Win32 14 | Debug|x64 = Debug|x64 15 | Release|Win32 = Release|Win32 16 | Release|x64 = Release|x64 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Debug|Win32.ActiveCfg = Debug|Win32 20 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Debug|Win32.Build.0 = Debug|Win32 21 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Debug|x64.ActiveCfg = Debug|Win32 22 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Release|Win32.ActiveCfg = Release|Win32 23 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Release|Win32.Build.0 = Release|Win32 24 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Release|x64.ActiveCfg = Release|x64 25 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Release|x64.Build.0 = Release|x64 26 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|Win32.ActiveCfg = Debug|Win32 27 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|Win32.Build.0 = Debug|Win32 28 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|x64.ActiveCfg = Debug|x64 29 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|x64.Build.0 = Debug|x64 30 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|Win32.ActiveCfg = Release|Win32 31 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|Win32.Build.0 = Release|Win32 32 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|x64.ActiveCfg = Release|x64 33 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|x64.Build.0 = Release|x64 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /encog-c.5.1.ReSharper.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | C:\Program Files (x86)\NUnit 2.5.3\bin\net-2.0\ 74 | Never 75 | 76 | -------------------------------------------------------------------------------- /encog-c.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encog-core", "encog-core\encog-core.vcxproj", "{3DF9CEFF-41CA-46B9-A659-A63C6D19D204}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encog-cmd", "encog-cmd\encog-cmd.vcxproj", "{CE50443B-9615-4C66-B9BE-57CD2A99F62A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Debug|x64 = Debug|x64 12 | Release|Win32 = Release|Win32 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|Win32.Build.0 = Debug|Win32 18 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|x64.ActiveCfg = Debug|x64 19 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|x64.Build.0 = Debug|x64 20 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|Win32.ActiveCfg = Release|Win32 21 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|Win32.Build.0 = Release|Win32 22 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|x64.ActiveCfg = Release|x64 23 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|x64.Build.0 = Release|x64 24 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Debug|Win32.Build.0 = Debug|Win32 26 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Debug|x64.ActiveCfg = Debug|x64 27 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Release|Win32.ActiveCfg = Release|Win32 28 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Release|Win32.Build.0 = Release|Win32 29 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Release|x64.ActiveCfg = Release|x64 30 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A}.Release|x64.Build.0 = Release|x64 31 | EndGlobalSection 32 | GlobalSection(SolutionProperties) = preSolution 33 | HideSolutionNode = FALSE 34 | EndGlobalSection 35 | EndGlobal 36 | -------------------------------------------------------------------------------- /encog-cmd/3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffheaton/encog-c/d207819b86d1c2b4dba114dbc3cbd784df999e05/encog-cmd/3 -------------------------------------------------------------------------------- /encog-cmd/SIGMOID-: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffheaton/encog-c/d207819b86d1c2b4dba114dbc3cbd784df999e05/encog-cmd/SIGMOID- -------------------------------------------------------------------------------- /encog-cmd/cuda.cpp: -------------------------------------------------------------------------------- 1 | int TestVectorAdd(); 2 | 3 | extern "C" void BridgeVectorAdd() { 4 | //TestVectorAdd(); 5 | } -------------------------------------------------------------------------------- /encog-cmd/cuda_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog-cmd.h" 25 | #ifdef ENCOG_CUDA 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | const char *sComputeMode[] = { 32 | "Default (multiple host threads can use ::cudaSetDevice() with device simultaneously)", 33 | "Exclusive (only one host thread in one process is able to use ::cudaSetDevice() with this device)", 34 | "Prohibited (no host thread can use ::cudaSetDevice() with this device)", 35 | "Exclusive Process (many threads in one process is able to use ::cudaSetDevice() with this device)", 36 | "Unknown", 37 | NULL 38 | }; 39 | 40 | void BridgeVectorAdd(); 41 | 42 | int ConvertSMVer2Cores(int major, int minor) 43 | { 44 | // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM 45 | typedef struct { 46 | int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version 47 | int Cores; 48 | } sSMtoCores; 49 | 50 | sSMtoCores nGpuArchCoresPerSM[] = 51 | { { 0x10, 8 }, // Tesla Generation (SM 1.0) G80 class 52 | { 0x11, 8 }, // Tesla Generation (SM 1.1) G8x class 53 | { 0x12, 8 }, // Tesla Generation (SM 1.2) G9x class 54 | { 0x13, 8 }, // Tesla Generation (SM 1.3) GT200 class 55 | { 0x20, 32 }, // Fermi Generation (SM 2.0) GF100 class 56 | { 0x21, 48 }, // Fermi Generation (SM 2.1) GF10x class 57 | { 0x30, 192}, // Fermi Generation (SM 3.0) GK10x class 58 | { -1, -1 } 59 | }; 60 | 61 | int index = 0; 62 | while (nGpuArchCoresPerSM[index].SM != -1) { 63 | if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor) ) { 64 | return nGpuArchCoresPerSM[index].Cores; 65 | } 66 | index++; 67 | } 68 | printf("MapSMtoCores SM %d.%d is undefined (please update to the latest SDK)!\n", major, minor); 69 | return -1; 70 | } 71 | 72 | 73 | 74 | void TestCUDA() 75 | { 76 | struct cudaDeviceProp deviceProp; 77 | int count; 78 | int dev, driverVersion = 0, runtimeVersion = 0; 79 | char msg[256]; 80 | int error; 81 | 82 | 83 | memset(&deviceProp,0,sizeof(struct cudaDeviceProp)); 84 | deviceProp.major = 1; 85 | deviceProp.minor = 3; 86 | 87 | error = (int)cudaGetDeviceCount(&count); 88 | if( error!= CUDA_SUCCESS ) 89 | { 90 | printf("CUDA Error: cudaGetDeviceCount, returned %i.\n",error); 91 | exit(1); 92 | } 93 | else if( count==0 ) 94 | { 95 | printf("No CUDA devices detectd.\n"); 96 | exit(1); 97 | } 98 | 99 | for(dev=0;dev= 2020 105 | cudaDriverGetVersion(&driverVersion); 106 | cudaRuntimeGetVersion(&runtimeVersion); 107 | printf(" CUDA Driver Version / Runtime Version %d.%d / %d.%d\n", driverVersion/1000, (driverVersion%100)/10, runtimeVersion/1000, (runtimeVersion%100)/10); 108 | 109 | printf(" CUDA Capability Major/Minor version number: %d.%d\n", deviceProp.major, deviceProp.minor); 110 | #endif 111 | sprintf(msg, " Total amount of global memory: %.0f MBytes (%llu bytes)\n", 112 | (float)deviceProp.totalGlobalMem/1048576.0f, (unsigned long long) deviceProp.totalGlobalMem); 113 | puts(msg); 114 | #if CUDART_VERSION >= 2000 115 | printf(" (%2d) Multiprocessors x (%2d) CUDA Cores/MP: %d CUDA Cores\n", 116 | deviceProp.multiProcessorCount, 117 | ConvertSMVer2Cores(deviceProp.major, deviceProp.minor), 118 | ConvertSMVer2Cores(deviceProp.major, deviceProp.minor) * deviceProp.multiProcessorCount); 119 | #endif 120 | printf(" GPU Clock Speed: %.2f GHz\n", deviceProp.clockRate * 1e-6f); 121 | 122 | 123 | printf(" Total amount of constant memory: %u bytes\n", (unsigned int)deviceProp.totalConstMem); 124 | printf(" Total amount of shared memory per block: %u bytes\n", (unsigned int)deviceProp.sharedMemPerBlock); 125 | printf(" Total number of registers available per block: %d\n", deviceProp.regsPerBlock); 126 | printf(" Warp size: %d\n", deviceProp.warpSize); 127 | printf(" Maximum number of threads per block: %d\n", deviceProp.maxThreadsPerBlock); 128 | printf(" Maximum sizes of each dimension of a block: %d x %d x %d\n", 129 | deviceProp.maxThreadsDim[0], 130 | deviceProp.maxThreadsDim[1], 131 | deviceProp.maxThreadsDim[2]); 132 | printf(" Maximum sizes of each dimension of a grid: %d x %d x %d\n", 133 | deviceProp.maxGridSize[0], 134 | deviceProp.maxGridSize[1], 135 | deviceProp.maxGridSize[2]); 136 | printf(" Maximum memory pitch: %u bytes\n", (unsigned int)deviceProp.memPitch); 137 | printf(" Texture alignment: %u bytes\n", (unsigned int)deviceProp.textureAlignment); 138 | } 139 | printf("Performing CUDA test.\n"); 140 | TestVectorAdd(); 141 | } 142 | 143 | #else 144 | void TestCUDA() 145 | { 146 | puts("CUDA is not supported in this build of Encog."); 147 | } 148 | #endif 149 | -------------------------------------------------------------------------------- /encog-cmd/cuda_vecadd.cu: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Functions 4 | void RandomInit(float*, int); 5 | 6 | // Device code 7 | __global__ void VecAddKernel(const float* A, const float* B, float* C, int N) 8 | { 9 | int i = blockDim.x * blockIdx.x + threadIdx.x; 10 | if (i < N) 11 | C[i] = A[i] + B[i]; 12 | } 13 | 14 | // Host code 15 | extern "C" int TestVectorAdd() 16 | { 17 | float* h_A; 18 | float* h_B; 19 | float* h_C; 20 | float* d_A; 21 | float* d_B; 22 | float* d_C; 23 | 24 | printf("Vector Addition\n"); 25 | int N = 50000; 26 | size_t size = N * sizeof(float); 27 | 28 | // Allocate input vectors h_A and h_B in host memory 29 | h_A = (float*)EncogUtilAlloc(N,sizeof(float)); 30 | h_B = (float*)EncogUtilAlloc(N,sizeof(float)); 31 | h_C = (float*)EncogUtilAlloc(N,sizeof(float)); 32 | 33 | // Initialize input vectors 34 | RandomInit(h_A, N); 35 | RandomInit(h_B, N); 36 | 37 | // Allocate vectors in device memory 38 | checkCudaErrors( cudaMalloc((void**)&d_A, size) ); 39 | checkCudaErrors( cudaMalloc((void**)&d_B, size) ); 40 | checkCudaErrors( cudaMalloc((void**)&d_C, size) ); 41 | 42 | // Copy vectors from host memory to device memory 43 | checkCudaErrors( cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice) ); 44 | checkCudaErrors( cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice) ); 45 | 46 | // Invoke kernel 47 | int threadsPerBlock = 256; 48 | int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock; 49 | VecAddKernel<<>>(d_A, d_B, d_C, N); 50 | 51 | getLastCudaError("kernel launch failure"); 52 | #ifdef _DEBUG 53 | checkCudaErrors( cudaDeviceSynchronize() ); 54 | #endif 55 | 56 | // Copy result from device memory to host memory 57 | // h_C contains the result in host memory 58 | checkCudaErrors( cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost) ); 59 | 60 | // Verify result 61 | int i; 62 | int error = 0; 63 | for (i = 0; i < N; ++i) { 64 | float sum = h_A[i] + h_B[i]; 65 | if (fabs(h_C[i] - sum) > 1e-5) { 66 | error = 1; 67 | break; 68 | } 69 | } 70 | 71 | // cleanup resources 72 | // Free device memory 73 | if (d_A) 74 | cudaFree(d_A); 75 | if (d_B) 76 | cudaFree(d_B); 77 | if (d_C) 78 | cudaFree(d_C); 79 | 80 | // Free host memory 81 | if (h_A) 82 | free(h_A); 83 | if (h_B) 84 | free(h_B); 85 | if (h_C) 86 | free(h_C); 87 | #if (CUDA_VERSION > 4010 ) 88 | cudaDeviceReset(); 89 | #endif 90 | 91 | // display error 92 | if( error ) { 93 | printf("CUDA Vector Add Test failed.\n"); 94 | } else { 95 | printf("CUDA Vector Add Test was successful.\n"); 96 | } 97 | return 0; 98 | } 99 | 100 | // Allocates an array with random float entries. 101 | void RandomInit(float* data, int n) 102 | { 103 | for (int i = 0; i < n; ++i) 104 | data[i] = rand() / (float)RAND_MAX; 105 | } 106 | 107 | -------------------------------------------------------------------------------- /encog-cmd/encog-cmd-cuda.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A} 23 | Win32Proj 24 | EncogExample 25 | encog-cmd-cuda 26 | 27 | 28 | 29 | Application 30 | true 31 | Unicode 32 | 33 | 34 | Application 35 | true 36 | Unicode 37 | 38 | 39 | Application 40 | false 41 | true 42 | Unicode 43 | 44 | 45 | Application 46 | false 47 | true 48 | Unicode 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | true 69 | 70 | 71 | true 72 | 73 | 74 | false 75 | 76 | 77 | false 78 | 79 | 80 | 81 | NotUsing 82 | Level3 83 | Disabled 84 | ENCOG_CUDA;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 85 | ..\encog-core;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\include 86 | true 87 | 88 | 89 | Console 90 | true 91 | cuda.lib;cudart.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 92 | 93 | 94 | ..\encog-core 95 | 96 | 97 | 98 | 99 | NotUsing 100 | Level3 101 | Disabled 102 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 103 | ..\encog-core 104 | 105 | 106 | Console 107 | true 108 | 109 | 110 | 111 | 112 | Level3 113 | NotUsing 114 | MaxSpeed 115 | true 116 | true 117 | ENCOG_CUDA;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | ..\encog-core;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\include 119 | true 120 | 121 | 122 | Console 123 | true 124 | true 125 | true 126 | cuda.lib;cudart.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 127 | 128 | 129 | ..\encog-core 130 | 131 | 132 | 133 | 134 | Level3 135 | NotUsing 136 | MaxSpeed 137 | true 138 | true 139 | ENCOG_CUDA;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 140 | ..\encog-core;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\include 141 | true 142 | 143 | 144 | Console 145 | true 146 | true 147 | true 148 | cuda.lib;cudart.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 149 | 150 | 151 | ..\encog-core 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | {3df9ceff-41ca-46b9-a659-a63c6d19d204} 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /encog-cmd/encog-cmd-cuda.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | 40 | 41 | Source Files 42 | 43 | 44 | -------------------------------------------------------------------------------- /encog-cmd/encog-cmd-cuda.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | cuda 5 | WindowsLocalDebugger 6 | 7 | -------------------------------------------------------------------------------- /encog-cmd/encog-cmd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #ifndef __ENCOG_CMD_H 25 | #define __ENCOG_CMD_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include "encog.h" 32 | 33 | int TestVectorAdd(); 34 | void TestCUDA(); 35 | 36 | void EncogNodeMain(int port); 37 | void EncogNodeRecv(unsigned char b); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /encog-cmd/encog-cmd.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {CE50443B-9615-4C66-B9BE-57CD2A99F62A} 23 | Win32Proj 24 | EncogExample 25 | encog-cmd 26 | 27 | 28 | 29 | Application 30 | true 31 | Unicode 32 | 33 | 34 | Application 35 | true 36 | Unicode 37 | 38 | 39 | Application 40 | false 41 | true 42 | Unicode 43 | 44 | 45 | Application 46 | false 47 | true 48 | Unicode 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | true 67 | 68 | 69 | true 70 | 71 | 72 | false 73 | 74 | 75 | false 76 | 77 | 78 | 79 | NotUsing 80 | Level3 81 | Disabled 82 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 83 | ..\encog-core;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.1\include 84 | true 85 | 86 | 87 | Console 88 | true 89 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 90 | 91 | 92 | 93 | 94 | NotUsing 95 | Level3 96 | Disabled 97 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 98 | ..\encog-core 99 | 100 | 101 | Console 102 | true 103 | 104 | 105 | 106 | 107 | Level3 108 | NotUsing 109 | MaxSpeed 110 | true 111 | true 112 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 113 | ..\encog-core 114 | true 115 | 116 | 117 | Console 118 | true 119 | true 120 | true 121 | 122 | 123 | 124 | 125 | Level3 126 | NotUsing 127 | MaxSpeed 128 | true 129 | true 130 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 131 | ..\encog-core 132 | true 133 | 134 | 135 | Console 136 | true 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | {3df9ceff-41ca-46b9-a659-a63c6d19d204} 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /encog-cmd/encog-cmd.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | csv2egb iris.csv iris.egb /input:4 /ideal:2 5 | WindowsLocalDebugger 6 | 7 | -------------------------------------------------------------------------------- /encog-cmd/node.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog-cmd.h" 25 | 26 | void EncogNodeRecv(unsigned char b) 27 | { 28 | printf("Char: %i - %c\n",(int)b,(char)b); 29 | } -------------------------------------------------------------------------------- /encog-cmd/node_unix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #ifndef _MSC_VER 25 | #include "encog-cmd.h" 26 | 27 | void EncogNodeMain(int port) 28 | { 29 | } 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /encog-cmd/node_windows.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #ifdef _MSC_VER 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "encog-cmd.h" 33 | 34 | #pragma comment(lib, "Ws2_32.lib") 35 | 36 | DWORD WINAPI SocketHandler(void*); 37 | 38 | void EncogNodeMain(int port) 39 | { 40 | unsigned short wVersionRequested; 41 | WSADATA wsaData; 42 | int err; 43 | int hsock; 44 | int * p_int ; 45 | struct sockaddr_in my_addr; 46 | int* csock; 47 | struct sockaddr_in sadr; 48 | int addr_size; 49 | 50 | wVersionRequested = MAKEWORD( 2, 2 ); 51 | err = WSAStartup( wVersionRequested, &wsaData ); 52 | if ( err != 0 || ( LOBYTE( wsaData.wVersion ) != 2 || 53 | HIBYTE( wsaData.wVersion ) != 2 )) { 54 | fprintf(stderr, "Could not find useable sock dll %d\n",WSAGetLastError()); 55 | goto FINISH; 56 | } 57 | 58 | hsock = socket(AF_INET, SOCK_STREAM, 0); 59 | if(hsock == -1){ 60 | printf("Error initializing socket %d\n",WSAGetLastError()); 61 | goto FINISH; 62 | } 63 | 64 | p_int = (int*)malloc(sizeof(int)); 65 | *p_int = 1; 66 | if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )|| 67 | (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){ 68 | printf("Error setting options %d\n", WSAGetLastError()); 69 | free(p_int); 70 | goto FINISH; 71 | } 72 | free(p_int); 73 | 74 | my_addr.sin_family = AF_INET ; 75 | my_addr.sin_port = htons(port); 76 | 77 | memset(&(my_addr.sin_zero), 0, 8); 78 | my_addr.sin_addr.s_addr = INADDR_ANY ; 79 | 80 | if( bind( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){ 81 | fprintf(stderr,"Error binding to socket, make sure nothing else is listening on this port %d\n",WSAGetLastError()); 82 | goto FINISH; 83 | } 84 | if(listen( hsock, 10) == -1 ){ 85 | fprintf(stderr, "Error listening %d\n",WSAGetLastError()); 86 | goto FINISH; 87 | } 88 | 89 | //Now lets to the server stuff 90 | 91 | addr_size = sizeof(SOCKADDR); 92 | 93 | while(1){ 94 | printf("waiting for a connection\n"); 95 | csock = (int*)malloc(sizeof(int)); 96 | 97 | if((*csock = accept( hsock, (SOCKADDR*)&sadr, &addr_size))!= INVALID_SOCKET ){ 98 | printf("Received connection from %s",inet_ntoa(sadr.sin_addr)); 99 | CreateThread(0,0,&SocketHandler, (void*)csock , 0,0); 100 | } 101 | else{ 102 | fprintf(stderr, "Error accepting %d\n",WSAGetLastError()); 103 | } 104 | } 105 | 106 | FINISH: 107 | ; 108 | } 109 | 110 | DWORD WINAPI SocketHandler(void* lp){ 111 | int *csock = (int*)lp; 112 | char buffer[1024]; 113 | int buffer_len = 1024; 114 | int bytecount; 115 | int i; 116 | 117 | memset(buffer, 0, buffer_len); 118 | if((bytecount = recv(*csock, buffer, buffer_len, 0))==SOCKET_ERROR){ 119 | fprintf(stderr, "Error receiving data %d\n", WSAGetLastError()); 120 | goto FINISH; 121 | } 122 | printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer); 123 | strcat(buffer, " SERVER ECHO"); 124 | 125 | for(i=0;iweights[index++] * *(iptr++); 56 | } 57 | 58 | if( hasBias ) { 59 | sum += dnet->weights[index++]; 60 | } 61 | 62 | switch(cnet.activationFunctionIDs[currentLayer - 1]) 63 | { 64 | case AF_LINEAR: 65 | *(output++) = EncogGPUActivationLinear(sum); 66 | break; 67 | case AF_SIGMOID: 68 | *(output++) = EncogGPUActivationSigmoid(sum); 69 | break; 70 | case AF_TANH: 71 | *(output++) = EncogGPUActivationTANH(sum); 72 | break; 73 | } 74 | //dnet->layerSums[x] = sum; 75 | } 76 | } 77 | 78 | __device__ float _ComputeOutputError(GPU_DYNAMIC_NETWORK *dnet, int currentLayer, REAL *input, REAL *ideal) 79 | { 80 | int y; 81 | int inputSize = cnet.layerFeedCounts[currentLayer]; 82 | int outputSize = cnet.layerFeedCounts[currentLayer - 1]; 83 | REAL *iptr; 84 | REAL delta; 85 | float result; 86 | 87 | int index = cnet.weightIndex[currentLayer - 1]; 88 | int hasBias = (cnet.layerContextCount[currentLayer] + cnet.layerFeedCounts[currentLayer]) != cnet.layerCounts[currentLayer]; 89 | 90 | result = 0; 91 | 92 | // weight values 93 | while(outputSize--) 94 | { 95 | REAL sum = 0; 96 | iptr = input; 97 | for (y = 0; y < inputSize; y++) 98 | { 99 | sum += dnet->weights[index++] * *(iptr++); 100 | } 101 | 102 | if( hasBias ) { 103 | sum += dnet->weights[index++]; 104 | } 105 | 106 | switch(cnet.activationFunctionIDs[currentLayer - 1]) 107 | { 108 | case AF_LINEAR: 109 | delta = EncogGPUActivationLinear(sum); 110 | break; 111 | case AF_SIGMOID: 112 | delta = EncogGPUActivationSigmoid(sum); 113 | break; 114 | case AF_TANH: 115 | delta = EncogGPUActivationTANH(sum); 116 | break; 117 | } 118 | 119 | delta-=*(ideal++); 120 | result+=delta*delta; 121 | } 122 | 123 | return result; 124 | } 125 | 126 | __device__ float EncogGPUNetworkCompute(GPU_DYNAMIC_NETWORK *dnet,REAL *input, REAL *ideal) 127 | { 128 | int i; 129 | REAL l1[1024]; 130 | REAL l2[1024]; 131 | REAL *inputPtr = l1; 132 | REAL *outputPtr = l2; 133 | REAL *temp; 134 | 135 | // compute the input layer to first hidden layer (h1) 136 | i = cnet.layerCount-1; 137 | _ComputeLayer(dnet,i,input,outputPtr); 138 | i--; 139 | 140 | // compute h2 to hx (if they even exist) 141 | while(i>1) 142 | { 143 | // swap the input ptr and output ptr 144 | temp = inputPtr; 145 | inputPtr = outputPtr; 146 | outputPtr = temp; 147 | // compute the layer 148 | _ComputeLayer(dnet,i,inputPtr,outputPtr); 149 | i--; 150 | } 151 | 152 | // compute hx to output 153 | // use outputPtr even though we want inputPtr, we are just being efficient and not performing a final "swap" 154 | return _ComputeOutputError(dnet,i,outputPtr, ideal); 155 | 156 | } 157 | 158 | 159 | __global__ void EncogGPUEval(REAL *data, REAL *weights, float *errors) 160 | { 161 | __shared__ float cache[THREADS_PER_BLOCK]; 162 | int tid = blockDim.x * blockIdx.x + threadIdx.x; 163 | int cacheIndex = threadIdx.x; 164 | float temp = 0; 165 | 166 | GPU_DYNAMIC_NETWORK dnet; 167 | 168 | while (tid < cnet.recordCount) 169 | { 170 | dnet.weights = weights; 171 | REAL *input = EncogGPUDataGetInput(data,tid); 172 | REAL *ideal = EncogGPUDataGetIdeal(data,tid); 173 | //errors = cnet.dynamicSize; 174 | temp += EncogGPUNetworkCompute(&dnet,input,ideal); 175 | tid+=blockDim.x*gridDim.x; 176 | } 177 | 178 | cache[cacheIndex] = temp; 179 | 180 | __syncthreads(); 181 | 182 | int i = blockDim.x/2; 183 | while(i!=0) { 184 | if( cacheIndexlayerCount; 203 | tempConstNet.neuronCount = net->neuronCount; 204 | tempConstNet.weightCount = net->weightCount; 205 | tempConstNet.inputCount = net->inputCount; 206 | tempConstNet.beginTraining = net->beginTraining; 207 | tempConstNet.connectionLimit = net->connectionLimit; 208 | tempConstNet.endTraining = net->endTraining; 209 | tempConstNet.hasContext = net->hasContext; 210 | tempConstNet.recordCount = data->recordCount; 211 | tempConstNet.outputCount = net->outputCount; 212 | tempConstNet.dynamicSize = (net->neuronCount*2); 213 | 214 | for(int i=0;ilayerCount ) { 216 | tempConstNet.contextTargetOffset[i] = net->contextTargetOffset[i]; 217 | tempConstNet.contextTargetSize[i] = net->contextTargetSize[i]; 218 | tempConstNet.layerCounts[i] = net->layerCounts[i]; 219 | tempConstNet.layerContextCount[i] = net->layerContextCount[i]; 220 | tempConstNet.layerFeedCounts[i] = net->layerFeedCounts[i]; 221 | tempConstNet.layerIndex[i] = net->layerIndex[i]; 222 | tempConstNet.weightIndex[i] = net->weightIndex[i]; 223 | tempConstNet.activationFunctionIDs[i] = net->activationFunctionIDs[i]; 224 | tempConstNet.biasActivation[i] = net->biasActivation[i]; 225 | } else { 226 | tempConstNet.contextTargetOffset[i] = 0; 227 | tempConstNet.contextTargetSize[i] = 0; 228 | tempConstNet.layerCounts[i] = 0; 229 | tempConstNet.layerContextCount[i] = 0; 230 | tempConstNet.layerFeedCounts[i] = 0; 231 | tempConstNet.layerIndex[i] = 0; 232 | tempConstNet.weightIndex[i] = 0; 233 | tempConstNet.activationFunctionIDs[i] = 0; 234 | tempConstNet.biasActivation[i] = 0; 235 | } 236 | } 237 | 238 | cudaMemcpyToSymbol(cnet, &tempConstNet, sizeof(GPU_CONST_NETWORK)); 239 | 240 | result = (GPU_DEVICE*)EncogUtilAlloc(1,sizeof(GPU_DEVICE)); 241 | 242 | result->blocksPerGrid = MIN(32,(data->recordCount + THREADS_PER_BLOCK - 1) / THREADS_PER_BLOCK); 243 | 244 | int dataSize = (data->inputCount + data->idealCount + 1) * data->recordCount; 245 | 246 | // Allocate vectors in device memory 247 | checkCudaErrors( cudaMalloc((void**)&result->deviceData, dataSize*sizeof(REAL)) ); 248 | checkCudaErrors( cudaMalloc((void**)&result->deviceErrors, result->blocksPerGrid * sizeof(float)) ); 249 | checkCudaErrors( cudaMalloc((void**)&result->deviceWeights, net->weightCount*sizeof(REAL)) ); 250 | result->errors = (float*)EncogUtilAlloc(data->recordCount,sizeof(float)); 251 | result->recordCount = data->recordCount; 252 | 253 | // Copy vectors from host memory to device memory 254 | // 255 | checkCudaErrors( cudaMemcpy(result->deviceData, data->data, dataSize*sizeof(REAL), cudaMemcpyHostToDevice) ); 256 | 257 | return result; 258 | } 259 | 260 | extern "C" void EncogGPUDeviceDelete(GPU_DEVICE *device) { 261 | cudaFree(device->deviceData); 262 | cudaFree(device->deviceErrors); 263 | cudaFree(device->deviceWeights); 264 | EncogUtilFree(device->errors); 265 | EncogUtilFree(device); 266 | #if (CUDA_VERSION > 4010 ) 267 | cudaDeviceReset(); 268 | #endif 269 | 270 | } 271 | 272 | // Host code 273 | extern "C" float EncogCUDAErrorSSE(GPU_DEVICE *device, ENCOG_NEURAL_NETWORK *net) 274 | { 275 | cudaEvent_t start,stop; 276 | float elapsed; 277 | checkCudaErrors( cudaMemcpy(device->deviceWeights, net->weights, net->weightCount * sizeof(REAL), cudaMemcpyHostToDevice) ); 278 | 279 | cudaEventCreate(&start); 280 | cudaEventCreate(&stop); 281 | 282 | checkCudaErrors( cudaEventRecord(start,0) ); 283 | EncogGPUEval<<blocksPerGrid, THREADS_PER_BLOCK>>>(device->deviceData, device->deviceWeights, device->deviceErrors); 284 | checkCudaErrors( cudaEventRecord(stop,0) ); 285 | 286 | getLastCudaError("kernel launch failure"); 287 | checkCudaErrors( cudaEventSynchronize(stop) ); 288 | 289 | // Copy result from device memory to host memory 290 | // h_C contains the result in host memory 291 | checkCudaErrors( cudaMemcpy(device->errors, device->deviceErrors, device->blocksPerGrid * sizeof(float), cudaMemcpyDeviceToHost) ); 292 | 293 | checkCudaErrors( cudaEventElapsedTime( &elapsed, start, stop ) ); 294 | 295 | device->perfCount++; 296 | device->perfKernelTime+=elapsed; 297 | 298 | float sum = 0; 299 | for(int i=0;iblocksPerGrid;i++) { 300 | sum+=device->errors[i]; 301 | } 302 | 303 | checkCudaErrors( cudaEventDestroy( start ) ); 304 | checkCudaErrors( cudaEventDestroy( stop ) ); 305 | 306 | return sum/(device->recordCount*net->outputCount); 307 | } 308 | 309 | 310 | extern "C" float EncogCUDAPSOIterate(ENCOG_TRAIN_PSO *pso) { 311 | return 0; 312 | } 313 | -------------------------------------------------------------------------------- /encog-core/data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | static const char *HEADER = "ENCOG-00"; 27 | 28 | ENCOG_DATA *EncogDataCreate(unsigned int inputCount, unsigned int idealCount, unsigned long records) 29 | { 30 | ENCOG_DATA *data; 31 | 32 | /* Clear out any previous errors */ 33 | EncogErrorClear(); 34 | 35 | data = (ENCOG_DATA*)EncogUtilAlloc(1,sizeof(ENCOG_DATA)); 36 | data->inputCount = inputCount; 37 | data->idealCount = idealCount; 38 | data->recordCount = records; 39 | data->data = (REAL*)EncogUtilAlloc(records*(inputCount+idealCount+1),sizeof(REAL)); 40 | data->cursor = data->data; 41 | 42 | EncogObjectRegister(data, ENCOG_TYPE_DATA); 43 | 44 | return data; 45 | } 46 | 47 | void EncogDataAdd(ENCOG_DATA *data,char *str) 48 | { 49 | char ch, *ptr; 50 | char temp[MAX_STR]; 51 | REAL d; 52 | 53 | /* Clear out any previous errors */ 54 | EncogErrorClear(); 55 | 56 | *temp = 0; 57 | ptr = str; 58 | 59 | while(*ptr) 60 | { 61 | ch = *ptr; 62 | if( ch==',' ) 63 | { 64 | d = (REAL)atof(temp); 65 | *(data->cursor++) = d; 66 | *temp = 0; 67 | } 68 | else if( isdigit((int)ch) || ch=='-' || ch=='.' ) 69 | { 70 | EncogStrCatChar(temp,ch,MAX_STR); 71 | } 72 | ptr++; 73 | } 74 | 75 | if(*temp) 76 | { 77 | d = (REAL)atof(temp); 78 | *(data->cursor++) = d; 79 | } 80 | } 81 | 82 | void EncogDataAddVar(ENCOG_DATA *data, ...) 83 | { 84 | int i,total; 85 | REAL d = 0.0; 86 | va_list arguments; 87 | 88 | /* Clear out any previous errors */ 89 | EncogErrorClear(); 90 | 91 | va_start ( arguments, data ); 92 | total = data->inputCount + data->idealCount; 93 | 94 | for(i=0; icursor++) = d; 98 | } 99 | 100 | va_end( arguments ); 101 | } 102 | 103 | REAL *EncogDataGetInput(ENCOG_DATA *data, unsigned int index) 104 | { 105 | int i; 106 | 107 | /* Clear out any previous errors */ 108 | EncogErrorClear(); 109 | 110 | i = index*(data->inputCount+data->idealCount); 111 | return &data->data[i]; 112 | } 113 | 114 | REAL *EncogDataGetIdeal(ENCOG_DATA *data, unsigned int index) 115 | { 116 | int i; 117 | 118 | /* Clear out any previous errors */ 119 | EncogErrorClear(); 120 | 121 | i = index*(data->inputCount+data->idealCount); 122 | return &data->data[i+data->inputCount]; 123 | } 124 | 125 | void EncogDataCSVSave(char *filename, ENCOG_DATA *data, int decimals) 126 | { 127 | char temp[MAX_STR]; 128 | INT i,j; 129 | REAL *input, *ideal; 130 | FILE *fp; 131 | 132 | /* Clear out any previous errors */ 133 | EncogErrorClear(); 134 | 135 | fp = fopen(filename,"w"); 136 | 137 | if( fp==NULL ) { 138 | EncogErrorSet(ENCOG_ERROR_FILE_NOT_FOUND); 139 | EncogErrorSetArg(filename); 140 | return; 141 | } 142 | 143 | 144 | for(i=0; irecordCount; i++) 145 | { 146 | input = EncogDataGetInput(data,i); 147 | ideal = EncogDataGetIdeal(data,i); 148 | 149 | for(j=0; jinputCount; j++) 150 | { 151 | if(j>0) 152 | { 153 | fprintf(fp,","); 154 | } 155 | *temp=0; 156 | EncogStrCatDouble(temp,input[j],decimals,MAX_STR); 157 | fputs(temp,fp); 158 | } 159 | 160 | for(j=0; jidealCount; j++) 161 | { 162 | fprintf(fp,","); 163 | *temp = 0; 164 | EncogStrCatDouble(temp,ideal[j],decimals,MAX_STR); 165 | fputs(temp,fp); 166 | } 167 | fputs("\n",fp); 168 | } 169 | fclose(fp); 170 | } 171 | 172 | ENCOG_DATA *EncogDataGenerateRandom(INT inputCount, INT idealCount, INT records, REAL low, REAL high) 173 | { 174 | ENCOG_DATA *data; 175 | REAL *ptr; 176 | int i,size; 177 | 178 | /* Clear out any previous errors */ 179 | EncogErrorClear(); 180 | 181 | data = EncogDataCreate(inputCount,idealCount,records); 182 | size = (inputCount+idealCount)*records; 183 | 184 | ptr = data->data; 185 | for(i=0;idata; 231 | for(i=0;iinputCount;j++) { 242 | d = record[k++]; 243 | *(ptr++) = (REAL)d; 244 | } 245 | for(j=0;jidealCount;j++) { 246 | d = record[k++]; 247 | *(ptr++) = (REAL)d; 248 | } 249 | } 250 | 251 | EncogUtilFree(record); 252 | 253 | fclose(fp); 254 | return result; 255 | } 256 | 257 | ENCOG_DATA *EncogDataCSVLoad(char *csvFile, INT inputCount, INT idealCount) 258 | { 259 | FILE *fp; 260 | char numBuffer[ MAX_STR ], ch; 261 | int records,lineCount,lineSize; 262 | ENCOG_DATA *result; 263 | REAL *optr; 264 | int lastCR; 265 | int lastError; 266 | int currentLine; 267 | 268 | lineSize = inputCount+idealCount; 269 | 270 | /* Clear out any previous errors */ 271 | EncogErrorClear(); 272 | 273 | /* Open the file */ 274 | fp = fopen ( csvFile, "rb" ); 275 | 276 | if( fp==NULL ) { 277 | EncogErrorSet(ENCOG_ERROR_FILE_NOT_FOUND); 278 | EncogErrorSetArg(csvFile); 279 | return NULL; 280 | } 281 | 282 | lastError = 0; 283 | 284 | /* initially count the lines (pass 1) */ 285 | records = 0; 286 | lastCR = 0; 287 | while ( (ch=fgetc(fp)) !=EOF ) 288 | { 289 | if( ch==13 || (ch==10&&!lastCR) ) { 290 | records++; 291 | } 292 | 293 | lastCR = (ch==13); 294 | } 295 | 296 | /* allocate space to hold data */ 297 | result = EncogDataCreate(inputCount,idealCount,records); 298 | if( EncogErrorGet() ) { 299 | return NULL; 300 | } 301 | 302 | /* return to beginning and parse the file (pass 2) */ 303 | fseek(fp,0,SEEK_SET); 304 | optr = result->data; 305 | 306 | 307 | lastCR = 0; 308 | *numBuffer = 0; 309 | lineCount = 0; 310 | 311 | currentLine = 1; 312 | while ( (ch=fgetc(fp)) !=EOF ) 313 | { 314 | if( ch==13 || (ch==10&&!lastCR) ) { 315 | if( lineCount ) { 316 | *(optr++) = (REAL)atof(numBuffer); 317 | *numBuffer = 0; 318 | lineCount++; 319 | 320 | /* too much data for the line? */ 321 | if( ( lineCount>lineSize ) || ( lineCount=lineSize ) { 332 | lastError = ENCOG_ERROR_SIZE_MISMATCH; 333 | break; 334 | } 335 | 336 | *(optr++) = (REAL)atof(numBuffer); 337 | *numBuffer = 0; 338 | lineCount++; 339 | } 340 | else { 341 | EncogStrCatChar(numBuffer, ch, sizeof(numBuffer)); 342 | } 343 | 344 | lastCR = (ch==13); 345 | } 346 | 347 | fclose(fp); 348 | 349 | if( lastError ) { 350 | *numBuffer = 0; 351 | EncogStrCatStr(numBuffer,"While processling line #",sizeof(numBuffer)); 352 | EncogStrCatInt(numBuffer,currentLine,sizeof(numBuffer)); 353 | EncogStrCatStr(numBuffer,", was expecting ",sizeof(numBuffer)); 354 | EncogStrCatInt(numBuffer,lineSize,sizeof(numBuffer)); 355 | EncogStrCatStr(numBuffer," columns.",sizeof(numBuffer)); 356 | 357 | EncogObjectFree(result); 358 | EncogErrorSet(ENCOG_ERROR_SIZE_MISMATCH); 359 | EncogErrorSetArg(numBuffer); 360 | return NULL; 361 | } 362 | 363 | 364 | return result; 365 | } 366 | 367 | void EncogDataEGBSave(char *egbFile,ENCOG_DATA *data) 368 | { 369 | FILE *fp; 370 | double *line; 371 | EGB_HEADER hdr; 372 | INT i,j,lineSize; 373 | REAL *ptr; 374 | 375 | /* Clear out any previous errors */ 376 | EncogErrorClear(); 377 | 378 | /* Open the file */ 379 | if( (fp=fopen(egbFile,"wb"))==NULL ) { 380 | EncogErrorSet(ENCOG_ERROR_FILE_NOT_FOUND); 381 | EncogErrorSetArg(egbFile); 382 | return; 383 | } 384 | 385 | /* Write the header */ 386 | memcpy(hdr.ident,HEADER,8); 387 | hdr.ideal = data->idealCount; 388 | hdr.input = data->inputCount; 389 | fwrite(&hdr,sizeof(EGB_HEADER),1,fp); 390 | 391 | /* write the data */ 392 | lineSize = data->idealCount + data->inputCount + 1; 393 | line = (double*)EncogUtilAlloc(lineSize,sizeof(double)); 394 | ptr = data->data; 395 | 396 | for(i=0;irecordCount;i++) { 397 | for(j=0;j 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | -------------------------------------------------------------------------------- /encog-core/encog-c.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /encog-core/encog-core-cuda.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encog-core-cuda", "encog-core-cuda.vcxproj", "{3DF9CEFF-41CA-46B9-A659-A63C6D19D204}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|Win32.Build.0 = Debug|Win32 16 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|x64.ActiveCfg = Debug|x64 17 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Debug|x64.Build.0 = Debug|x64 18 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|Win32.ActiveCfg = Release|Win32 19 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|Win32.Build.0 = Release|Win32 20 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|x64.ActiveCfg = Release|x64 21 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /encog-core/encog-core-cuda.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204} 23 | Win32Proj 24 | encogc 25 | encog-core-cuda 26 | 27 | 28 | 29 | StaticLibrary 30 | true 31 | Unicode 32 | 33 | 34 | StaticLibrary 35 | true 36 | Unicode 37 | 38 | 39 | StaticLibrary 40 | false 41 | true 42 | Unicode 43 | 44 | 45 | StaticLibrary 46 | false 47 | true 48 | Unicode 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | NotUsing 71 | Level3 72 | Disabled 73 | ENCOG_CUDA;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 74 | true 75 | C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\include 76 | 77 | 78 | Windows 79 | true 80 | 81 | 82 | ..\encog-core 83 | compute_20,sm_20 84 | 85 | 86 | 87 | 88 | NotUsing 89 | Level3 90 | Disabled 91 | WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 92 | 93 | 94 | Windows 95 | true 96 | 97 | 98 | ..\encog-core 99 | 100 | 101 | 102 | 103 | Level3 104 | NotUsing 105 | MaxSpeed 106 | true 107 | true 108 | ENCOG_CUDA;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 109 | true 110 | %(AdditionalIncludeDirectories);$(CudaToolkitIncludeDir);C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\include 111 | 112 | 113 | Windows 114 | true 115 | true 116 | true 117 | 118 | 119 | ..\encog-core 120 | 121 | 122 | 123 | 124 | Level3 125 | NotUsing 126 | MaxSpeed 127 | true 128 | true 129 | ENCOG_CUDA;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 130 | true 131 | ..\encog-core;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\include 132 | 133 | 134 | Windows 135 | true 136 | true 137 | true 138 | 139 | 140 | ..\encog-core 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | compute_20,sm_20 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /encog-core/encog-core-cuda.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /encog-core/encog-core.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {3DF9CEFF-41CA-46B9-A659-A63C6D19D204} 23 | Win32Proj 24 | encogc 25 | encog-core 26 | 27 | 28 | 29 | StaticLibrary 30 | true 31 | Unicode 32 | 33 | 34 | StaticLibrary 35 | true 36 | Unicode 37 | 38 | 39 | StaticLibrary 40 | false 41 | true 42 | Unicode 43 | 44 | 45 | StaticLibrary 46 | false 47 | true 48 | Unicode 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | NotUsing 69 | Level3 70 | Disabled 71 | WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 72 | true 73 | C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.1\include 74 | 75 | 76 | Windows 77 | true 78 | 79 | 80 | c:\projects\encog-c 81 | 82 | 83 | 84 | 85 | NotUsing 86 | Level3 87 | Disabled 88 | WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 89 | 90 | 91 | Windows 92 | true 93 | 94 | 95 | 96 | 97 | Level3 98 | NotUsing 99 | MaxSpeed 100 | true 101 | true 102 | WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 103 | true 104 | 105 | 106 | Windows 107 | true 108 | true 109 | true 110 | 111 | 112 | 113 | 114 | Level3 115 | NotUsing 116 | MaxSpeed 117 | true 118 | true 119 | WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 120 | true 121 | 122 | 123 | Windows 124 | true 125 | true 126 | true 127 | 128 | 129 | 130 | 131 | Document 132 | c:\projects\encog-c\encog-core 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /encog-core/encog-core.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | WindowsLocalDebugger 7 | 8 | -------------------------------------------------------------------------------- /encog-core/encog.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | ENCOG_CONTEXT encogContext; 27 | 28 | void EncogInit() { 29 | memset(&encogContext,0,sizeof(ENCOG_CONTEXT)); 30 | encogContext.config = EncogHashNew(5,1); 31 | 32 | #ifdef ENCOG_CUDA 33 | encogContext.gpuEnabled = 1; 34 | #endif 35 | 36 | encogContext.versionMajor = 0; 37 | encogContext.versionMajor = 1; 38 | strncpy(encogContext.version,"1.0",sizeof(encogContext.version)); 39 | 40 | EncogUtilInitRandom(); 41 | } 42 | 43 | void EncogShutdown() { 44 | } 45 | 46 | void EncogTrainMinimalCallback(ENCOG_TRAINING_REPORT *report) { 47 | if( report->error < report->maxError ) { 48 | report->stopRequested = 1; 49 | } 50 | 51 | if( report->maxIterations!=0 && (report->iterations>=report->maxIterations) ) { 52 | report->stopRequested = 1; 53 | } 54 | 55 | //printf("%i\n",report->iterations); 56 | 57 | } 58 | 59 | void EncogTrainStandardCallback(ENCOG_TRAINING_REPORT *report) { 60 | char line[MAX_STR]; 61 | time_t currentTime; 62 | time_t sinceLastUpdate; 63 | 64 | EncogTrainMinimalCallback(report); 65 | 66 | currentTime = time(NULL); 67 | sinceLastUpdate = currentTime-report->lastUpdate; 68 | 69 | if( report->iterations==1 ) { 70 | printf("Beginning training (%s).\n", EncogObjectType(report->trainer)); 71 | } 72 | 73 | /* display every updateSeconds seconds, plus first and last iterations */ 74 | if( report->stopRequested || sinceLastUpdate>=report->updateSeconds || report->iterations==1 ) 75 | { 76 | report->lastUpdate = time(NULL); 77 | *line = 0; 78 | EncogStrCatStr(line,"Iteration #",MAX_STR); 79 | EncogStrCatInt(line,report->iterations,MAX_STR); 80 | EncogStrCatStr(line,", Error: ",MAX_STR); 81 | EncogStrCatDouble(line,report->error*100.0,4,MAX_STR); 82 | EncogStrCatChar(line,'%',MAX_STR); 83 | EncogStrCatStr(line,", press [Enter] to quit and save.", MAX_STR); 84 | puts(line); 85 | 86 | if( kbhit() ) 87 | { 88 | puts("Stopping at user request."); 89 | report->stopRequested = 1; 90 | } 91 | } 92 | 93 | if( report->stopRequested ) { 94 | printf("Training complete.\n"); 95 | } 96 | 97 | } 98 | 99 | -------------------------------------------------------------------------------- /encog-core/encog_cuda.cu: -------------------------------------------------------------------------------- 1 | #include "encog_cuda.h" 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // These are CUDA Helper functions 5 | 6 | 7 | 8 | 9 | // end of CUDA Helper Functions 10 | 11 | -------------------------------------------------------------------------------- /encog-core/encog_cuda.h: -------------------------------------------------------------------------------- 1 | #ifndef __ENCOG_CUDA_H 2 | #define __ENCOG_CUDA_H 3 | 4 | #include "encog.h" 5 | #include 6 | 7 | #define MAX_CUDA_LAYERS 10 8 | 9 | typedef struct GPU_CONST_NETWORK 10 | { 11 | INT layerCount; 12 | INT neuronCount; 13 | INT weightCount; 14 | INT inputCount; 15 | INT layerCounts[MAX_CUDA_LAYERS]; 16 | INT layerContextCount[MAX_CUDA_LAYERS]; 17 | INT layerFeedCounts[MAX_CUDA_LAYERS]; 18 | INT layerIndex[MAX_CUDA_LAYERS]; 19 | INT outputCount; 20 | INT weightIndex[MAX_CUDA_LAYERS]; 21 | INT activationFunctionIDs[MAX_CUDA_LAYERS]; 22 | REAL biasActivation[MAX_CUDA_LAYERS]; 23 | INT beginTraining; 24 | REAL connectionLimit; 25 | INT contextTargetOffset[MAX_CUDA_LAYERS]; 26 | INT contextTargetSize[MAX_CUDA_LAYERS]; 27 | INT endTraining; 28 | INT hasContext; 29 | INT recordCount; 30 | INT dynamicSize; 31 | } GPU_CONST_NETWORK; 32 | 33 | typedef struct GPU_DYNAMIC_NETWORK 34 | { 35 | REAL *weights; 36 | } GPU_DYNAMIC_NETWORK; 37 | 38 | 39 | // This will output the proper CUDA error strings in the event that a CUDA host call returns an error 40 | #define checkCudaErrors(err) __checkCudaErrors (err, __FILE__, __LINE__) 41 | 42 | // This will output the proper error string when calling cudaGetLastError 43 | #define getLastCudaError(msg) __getLastCudaError (msg, __FILE__, __LINE__) 44 | 45 | inline void __checkCudaErrors(cudaError err, const char *file, const int line ) 46 | { 47 | if(cudaSuccess != err) 48 | { 49 | fprintf(stderr, "%s(%i) : CUDA Runtime API error %d: %s.\n",file, line, (int)err, cudaGetErrorString( err ) ); 50 | exit(-1); 51 | } 52 | } 53 | 54 | inline void __getLastCudaError(const char *errorMessage, const char *file, const int line ) 55 | { 56 | cudaError_t err = cudaGetLastError(); 57 | if (cudaSuccess != err) 58 | { 59 | fprintf(stderr, "%s(%i) : getLastCudaError() CUDA error : %s : (%d) %s.\n", 60 | file, line, errorMessage, (int)err, cudaGetErrorString( err ) ); 61 | exit(-1); 62 | } 63 | } 64 | 65 | 66 | 67 | 68 | #endif -------------------------------------------------------------------------------- /encog-core/errorcalc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | 27 | float EncogErrorSSE(ENCOG_NEURAL_NETWORK *net, ENCOG_DATA *data) 28 | { 29 | #ifndef ENCOG_CUDA 30 | return EncogCPUErrorSSE(net,data); 31 | #else 32 | GPU_DEVICE *device; 33 | float result; 34 | 35 | if( encogContext.gpuEnabled ) { 36 | device = EncogGPUDeviceNew(0, net, data); 37 | result = EncogCUDAErrorSSE(device, net); 38 | EncogGPUDeviceDelete(device); 39 | return result; 40 | } 41 | else { 42 | return EncogCPUErrorSSE(net,data); 43 | } 44 | #endif 45 | } 46 | 47 | float EncogCPUErrorSSE(ENCOG_NEURAL_NETWORK *net, ENCOG_DATA *data) 48 | { 49 | INT i,j; 50 | REAL *input,*ideal,delta,sum; 51 | 52 | /* Clear out any previous errors */ 53 | EncogErrorClear(); 54 | 55 | sum = 0; 56 | for(i=0; irecordCount; i++) 57 | { 58 | input = EncogDataGetInput(data,i); 59 | ideal = EncogDataGetIdeal(data,i); 60 | 61 | EncogNetworkCompute(net,input,NULL); 62 | for(j=0; joutputCount; j++) 63 | { 64 | delta = net->layerOutput[j] - ideal[j]; 65 | sum+=delta*delta; 66 | } 67 | } 68 | 69 | return (float)(sum/(data->recordCount*data->idealCount)); 70 | } 71 | -------------------------------------------------------------------------------- /encog-core/errors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | static char _arg[MAX_STR]; 27 | static int _currentError = ENCOG_ERROR_OK; 28 | static char *_errorMessages[] = 29 | { 30 | "Success", /* 0 */ 31 | "File not found", /* 1 */ 32 | "IO Error", /* 2 */ 33 | "Size mismatch", /* 3 */ 34 | "Invalid EG File", /* 4 */ 35 | "Invalid EGB File", /* 5 */ 36 | "Invalid EGA File", /* 6 */ 37 | "Network has not been finalized", /* 7 */ 38 | "Network has already been finalized", /* 8 */ 39 | "Network must have at least two layers", /* 9 */ 40 | "Invalid activation function name", /* 10 */ 41 | "Expected a bias (b) to follow the :", /* 11 */ 42 | "Invalid layer conditional (?), must have only two", /* 12 */ 43 | "Encog object error", /* 13 */ 44 | "Encog object type error", /* 14 */ 45 | "Unknown training type error", /* 15 */ 46 | 47 | }; 48 | 49 | void EncogErrorClear() { 50 | EncogErrorSet(ENCOG_ERROR_OK); 51 | } 52 | 53 | void EncogErrorSet(int e) { 54 | _currentError = e; 55 | } 56 | 57 | void EncogErrorSetArg(char *arg) { 58 | strncpy(_arg,arg,sizeof(_arg)); 59 | } 60 | 61 | char *EncogErrorArgument() { 62 | return _arg; 63 | } 64 | 65 | int EncogErrorGet() { 66 | return _currentError; 67 | } 68 | 69 | void EncogErrorCheck() { 70 | if( EncogErrorGet() !=ENCOG_ERROR_OK ) { 71 | printf("** Encog function failure **\n"); 72 | printf("Error Code: %i, Error Message: %s\n%s\n", 73 | EncogErrorGet(), 74 | EncogErrorMessage(), 75 | EncogErrorArgument()); 76 | exit(1); 77 | } 78 | } 79 | 80 | char *EncogErrorMessage() { 81 | return _errorMessages[EncogErrorGet()]; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /encog-core/hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | #include 26 | 27 | ENCOG_HASH *EncogHashNew(INT tableSize, INT ignoreCase) 28 | { 29 | ENCOG_HASH *result = (ENCOG_HASH *)EncogUtilAlloc(1,sizeof(ENCOG_HASH)); 30 | 31 | result->tableSize = tableSize; 32 | result->ignoreCase = ignoreCase; 33 | result->table = (ENCOG_HASH_NODE **)EncogUtilAlloc(tableSize,sizeof(ENCOG_HASH_NODE*)); 34 | 35 | return result; 36 | } 37 | 38 | void EncogHashPut(ENCOG_HASH *hashTable, char *key, void *obj) 39 | { 40 | char *key2; 41 | int hashCode; 42 | ENCOG_HASH_NODE *newNode,*current, *prev; 43 | 44 | prev = NULL; 45 | 46 | key2 = strdup(key); 47 | if( hashTable->ignoreCase ) 48 | { 49 | EncogUtilStrlwr(key2); 50 | } 51 | 52 | hashCode = EncogUtilHash((unsigned char*)key2) % hashTable->tableSize; 53 | 54 | newNode = (ENCOG_HASH_NODE*)EncogUtilAlloc(1,sizeof(ENCOG_HASH_NODE)); 55 | newNode->key = key2; 56 | newNode->hashCode = hashCode; 57 | newNode->value = obj; 58 | 59 | current = hashTable->table[hashCode]; 60 | 61 | while( current!=NULL && strcmp(current->key,key2)<0 ) 62 | { 63 | prev = current; 64 | current=current->next; 65 | } 66 | 67 | if( current == hashTable->table[hashCode] ) 68 | { 69 | newNode->next = current; 70 | hashTable->table[hashCode] = newNode; 71 | } 72 | else if( prev!=NULL ) 73 | { 74 | newNode->next = prev->next; 75 | prev->next = newNode; 76 | } 77 | } 78 | 79 | void *EncogHashGet(ENCOG_HASH *hashTable, char *key, void *defaultValue) 80 | { 81 | char *key2; 82 | int hashCode, cp; 83 | ENCOG_HASH_NODE *current; 84 | 85 | key2 = strdup(key); 86 | if( hashTable->ignoreCase ) 87 | { 88 | EncogUtilStrlwr(key2); 89 | } 90 | 91 | hashCode = EncogUtilHash((unsigned char*)key2) % hashTable->tableSize; 92 | 93 | current = hashTable->table[hashCode]; 94 | 95 | while(current!=NULL) 96 | { 97 | cp = strcmp(key2,current->key); 98 | if( !cp ) 99 | { 100 | free(key2); 101 | return current->value; 102 | } 103 | else if( cp<0 ) 104 | { 105 | break; 106 | } 107 | current = current->next; 108 | } 109 | 110 | free(key2); 111 | return defaultValue; 112 | } 113 | 114 | int EncogHashContains(ENCOG_HASH *hashTable, char *key) 115 | { 116 | return EncogHashGet(hashTable, key, NULL)!=NULL; 117 | } 118 | 119 | void EncogHashDump(ENCOG_HASH *hashTable) 120 | { 121 | INT i; 122 | ENCOG_HASH_NODE *current; 123 | 124 | for(i=0;itableSize;i++) 125 | { 126 | if( hashTable->table[i] ) 127 | { 128 | printf("Table entry #%i\n",i); 129 | 130 | current = hashTable->table[i]; 131 | 132 | while(current) 133 | { 134 | printf("%s = %s\n", current->key, (char*)current->value); 135 | current = current->next; 136 | } 137 | } 138 | } 139 | } 140 | 141 | int EncogHashGetInteger(ENCOG_HASH *hashTable, char *key, int defaultValue) 142 | { 143 | char *v; 144 | 145 | v = (char*)EncogHashGet(hashTable,key,NULL); 146 | if( v==NULL ) 147 | return defaultValue; 148 | else 149 | return atoi(v); 150 | } 151 | 152 | float EncogHashGetFloat(ENCOG_HASH *hashTable, char *key, float defaultValue) 153 | { 154 | char *v; 155 | 156 | v = (char*)EncogHashGet(hashTable,key,NULL); 157 | 158 | if( v==NULL) 159 | return defaultValue; 160 | else 161 | return (float)atof(v); 162 | } 163 | 164 | -------------------------------------------------------------------------------- /encog-core/network_io.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | typedef struct { 27 | char *line; 28 | ENCOG_NEURAL_NETWORK *network; 29 | FILE *fp; 30 | } _PARSED_NETWORK; 31 | 32 | typedef struct _ARRAY_SEGMENT { 33 | double array[2048]; 34 | int length; 35 | struct _ARRAY_SEGMENT *next; 36 | } _ARRAY_SEGMENT; 37 | 38 | static REAL *_ParseLargeDoubleList(_PARSED_NETWORK *parse,char *firstline, INT *size) 39 | { 40 | INT index, i, len; 41 | REAL *result; 42 | char arg[MAX_STR],*ptr; 43 | REAL *dptr; 44 | 45 | if( firstline[0]=='#' && firstline[1]=='#' ) { 46 | if( fgets(parse->line,SIZE_MEGABYTE,parse->fp) == NULL ) { 47 | *(parse->line) = 0; 48 | } 49 | 50 | /* first, strip the length off the end */ 51 | ptr = parse->line+strlen(parse->line)-1; 52 | while(*(ptr-1)!='#' && ptr>firstline ) { 53 | ptr--; 54 | } 55 | *size = atoi(ptr); 56 | 57 | /* allocate enough space */ 58 | result = (REAL*)malloc((*size)*sizeof(double)); 59 | dptr = result; 60 | len = 0; 61 | 62 | while( fgets(parse->line,SIZE_MEGABYTE,parse->fp) ) 63 | { 64 | EncogStrStripCRLF(parse->line); 65 | 66 | index = 0; 67 | 68 | if( *parse->line=='#' ) { 69 | break; 70 | } 71 | 72 | do { 73 | index = EncogStrPopLine(parse->line, arg, index, sizeof(arg)); 74 | if( *arg || parse->line[index] ) { 75 | *(dptr++) = (REAL)atof(arg); 76 | len++; 77 | } 78 | } while(parse->line[index] && len<*size); 79 | } 80 | 81 | } else { 82 | *size = EncogStrCountValues(firstline); 83 | result = (REAL*)malloc((*size)*sizeof(double)); 84 | 85 | index = 0; 86 | for(i = 0; i<(*size); i++ ) 87 | { 88 | index = EncogStrPopLine(firstline, arg, index, sizeof(arg)); 89 | result[i] = (REAL)atof(arg); 90 | } 91 | } 92 | return result; 93 | } 94 | 95 | 96 | static int _CheckNetwork(FILE *fp) 97 | { 98 | int index, v; 99 | char line[MAX_STR]; 100 | char arg[MAX_STR]; 101 | 102 | if( fgets(line,sizeof(line),fp)==NULL ) { 103 | *line = 0; 104 | } 105 | 106 | index = 0; 107 | 108 | /* Make sure this is an Encog file */ 109 | index = EncogStrPopLine(line,arg,index,sizeof(arg)); 110 | if( strcmp(arg,"encog") ) 111 | { 112 | return -1; 113 | } 114 | 115 | /* Make sure this is a BasicNetwork */ 116 | index = EncogStrPopLine(line,arg,index,sizeof(arg)); 117 | if( strcmp(arg,"BasicNetwork") ) 118 | { 119 | return -1; 120 | } 121 | 122 | /* Encog platform */ 123 | index = EncogStrPopLine(line,arg,index,sizeof(arg)); 124 | 125 | /* Encog version */ 126 | index = EncogStrPopLine(line,arg,index,sizeof(arg)); 127 | 128 | /* File version */ 129 | index = EncogStrPopLine(line,arg,index,sizeof(arg)); 130 | v = atoi(arg); 131 | 132 | if( v>1 ) 133 | { 134 | return -1; 135 | } 136 | 137 | return 0; 138 | } 139 | 140 | 141 | static void _LoadBasic(_PARSED_NETWORK *parse) 142 | { 143 | char name[MAX_STR],*value; 144 | 145 | EncogStrStripCRLF(parse->line); 146 | value = EncogStrParseNV(parse->line,name,MAX_STR); 147 | 148 | if(!strcmp(name,"beginTraining") ) 149 | { 150 | parse->network->beginTraining = atoi(value); 151 | } 152 | else if(!strcmp(name,"connectionLimit") ) 153 | { 154 | parse->network->connectionLimit = (REAL)atof(value); 155 | } 156 | else if(!strcmp(name,"contextTargetOffset") ) 157 | { 158 | parse->network->contextTargetOffset = EncogStrParseIntList(value); 159 | } 160 | else if(!strcmp(name,"contextTargetSize") ) 161 | { 162 | parse->network->contextTargetSize = EncogStrParseIntList(value); 163 | } 164 | else if(!strcmp(name,"endTraining") ) 165 | { 166 | parse->network->endTraining = atoi(value); 167 | } 168 | else if(!strcmp(name,"hasContext") ) 169 | { 170 | parse->network->hasContext = EncogStrParseBoolean(value); 171 | } 172 | else if(!strcmp(name,"inputCount") ) 173 | { 174 | parse->network->inputCount = atoi(value); 175 | } 176 | else if(!strcmp(name,"layerCounts") ) 177 | { 178 | parse->network->layerCount = EncogStrCountValues(value); 179 | parse->network->layerCounts = EncogStrParseIntList(value); 180 | parse->network->activationFunctions = (ACTIVATION_FUNCTION*)EncogUtilAlloc(parse->network->layerCount,sizeof(ACTIVATION_FUNCTION)); 181 | parse->network->derivativeFunctions = (DERIVATIVE_FUNCTION*)EncogUtilAlloc(parse->network->layerCount,sizeof(DERIVATIVE_FUNCTION)); 182 | parse->network->activationFunctionIDs = (INT*)EncogUtilAlloc(parse->network->layerCount,sizeof(INT)); 183 | } 184 | else if(!strcmp(name,"layerFeedCounts") ) 185 | { 186 | parse->network->layerFeedCounts = EncogStrParseIntList(value); 187 | } 188 | else if(!strcmp(name,"layerContextCount") ) 189 | { 190 | parse->network->layerContextCount = EncogStrParseIntList(value); 191 | } 192 | else if(!strcmp(name,"layerIndex") ) 193 | { 194 | parse->network->layerIndex = EncogStrParseIntList(value); 195 | } 196 | else if(!strcmp(name,"output") ) 197 | { 198 | parse->network->layerOutput = _ParseLargeDoubleList(parse,value,&parse->network->neuronCount); 199 | } 200 | else if(!strcmp(name,"outputCount") ) 201 | { 202 | parse->network->outputCount = atoi(value); 203 | } 204 | else if(!strcmp(name,"weightIndex") ) 205 | { 206 | parse->network->weightIndex = EncogStrParseIntList(value); 207 | } 208 | else if(!strcmp(name,"weights") ) 209 | { 210 | parse->network->weights = _ParseLargeDoubleList(parse,value,&parse->network->weightCount); 211 | } 212 | else if(!strcmp(name,"biasActivation") ) 213 | { 214 | parse->network->biasActivation = EncogStrParseDoubleList(value); 215 | } 216 | } 217 | 218 | static void _LoadActivation(char *line, _PARSED_NETWORK *parse, int currentActivation) 219 | { 220 | EncogStrStripQuotes(line); 221 | if( !strcmp(line,"ActivationLinear") ) 222 | { 223 | parse->network->activationFunctions[currentActivation] = &EncogActivationLinear; 224 | parse->network->derivativeFunctions[currentActivation] = &EncogDerivativeLinear; 225 | parse->network->activationFunctionIDs[currentActivation] = AF_LINEAR; 226 | } 227 | else if( !strcmp(line,"ActivationSigmoid") ) 228 | { 229 | parse->network->activationFunctions[currentActivation] = &EncogActivationSigmoid; 230 | parse->network->derivativeFunctions[currentActivation] = &EncogDerivativeSigmoid; 231 | parse->network->activationFunctionIDs[currentActivation] = AF_SIGMOID; 232 | } 233 | else if( !strcmp(line,"ActivationTANH") ) 234 | { 235 | parse->network->activationFunctions[currentActivation] = EncogActivationTANH; 236 | parse->network->derivativeFunctions[currentActivation] = &EncogDerivativeTANH; 237 | parse->network->activationFunctionIDs[currentActivation] = AF_TANH; 238 | } 239 | } 240 | 241 | 242 | ENCOG_NEURAL_NETWORK *EncogNetworkLoad(char *name) 243 | { 244 | int mode, currentActivation; 245 | _PARSED_NETWORK parse; 246 | 247 | parse.fp = fopen(name,"r"); 248 | 249 | if( parse.fp==NULL ) 250 | { 251 | EncogErrorSet(ENCOG_ERROR_FILE_NOT_FOUND); 252 | EncogErrorSetArg(name); 253 | return NULL; 254 | } 255 | 256 | if( _CheckNetwork(parse.fp) == -1 ) 257 | { 258 | return NULL; 259 | } 260 | 261 | parse.line = (char*)EncogUtilAlloc(SIZE_MEGABYTE,sizeof(char)); 262 | parse.network = EncogNetworkNew(); 263 | 264 | mode = 0; 265 | currentActivation = 0; 266 | 267 | while( fgets(parse.line,SIZE_MEGABYTE,parse.fp) ) 268 | { 269 | EncogStrStripCRLF(parse.line); 270 | 271 | if(!strcmp(parse.line,"[BASIC:NETWORK]") ) 272 | { 273 | mode = 1; 274 | } 275 | else if(!strcmp(parse.line,"[BASIC:ACTIVATION]") ) 276 | { 277 | mode = 2; 278 | } 279 | else 280 | { 281 | switch(mode) 282 | { 283 | case 1: 284 | _LoadBasic(&parse); 285 | break; 286 | case 2: 287 | _LoadActivation(parse.line,&parse,currentActivation++); 288 | break; 289 | } 290 | } 291 | } 292 | 293 | fclose(parse.fp); 294 | EncogUtilFree(parse.line); 295 | 296 | parse.network->layerSums = (REAL*)EncogUtilAlloc(parse.network->neuronCount,sizeof(REAL)); 297 | 298 | return parse.network; 299 | } 300 | 301 | void EncogNetworkSave(char *name, ENCOG_NEURAL_NETWORK *network) 302 | { 303 | char line[MAX_STR]; 304 | INT i; 305 | FILE *fp; 306 | time_t t; 307 | 308 | /* Write the header line */ 309 | fp = fopen(name,"w"); 310 | if( fp==NULL ) { 311 | EncogErrorSet(ENCOG_ERROR_FILE_NOT_FOUND); 312 | return; 313 | } 314 | 315 | *line=0; 316 | strcat(line,"encog"); 317 | strcat(line,","); 318 | strcat(line,"BasicNetwork"); 319 | strcat(line,","); 320 | strcat(line,"c++"); 321 | strcat(line,","); 322 | strcat(line,"3.0"); 323 | strcat(line,","); 324 | strcat(line,"1"); 325 | strcat(line,","); 326 | 327 | time(&t); 328 | EncogStrCatLong(line,(long)t,MAX_STR); 329 | fputs(line,fp); 330 | fputs("\n[BASIC]\n",fp); 331 | fputs("[BASIC:PARAMS]\n",fp); 332 | fputs("[BASIC:NETWORK]\n",fp); 333 | EncogFileWriteValueInt(fp,"beginTraining",network->beginTraining); 334 | EncogFileWriteValueDouble(fp,"connectionLimit",network->connectionLimit); 335 | EncogFileWriteValueIntArray(fp,"contextTargetOffset",network->contextTargetOffset,network->layerCount); 336 | EncogFileWriteValueIntArray(fp,"contextTargetSize",network->contextTargetSize,network->layerCount); 337 | EncogFileWriteValueInt(fp,"endTraining",network->endTraining); 338 | EncogFileWriteValueBoolean(fp,"hasContext",network->hasContext); 339 | EncogFileWriteValueInt(fp,"inputCount",network->inputCount); 340 | EncogFileWriteValueIntArray(fp,"layerCounts",network->layerCounts,network->layerCount); 341 | EncogFileWriteValueIntArray(fp,"layerFeedCounts",network->layerFeedCounts,network->layerCount); 342 | EncogFileWriteValueIntArray(fp,"layerContextCount",network->layerContextCount,network->layerCount); 343 | EncogFileWriteValueIntArray(fp,"layerIndex",network->layerIndex,network->layerCount); 344 | EncogFileWriteValueDoubleArray(fp,"output",network->layerOutput,network->neuronCount); 345 | EncogFileWriteValueInt(fp,"outputCount",network->outputCount); 346 | EncogFileWriteValueIntArray(fp,"weightIndex",network->weightIndex,network->layerCount); 347 | EncogFileWriteValueDoubleArray(fp,"weights",network->weights,network->weightCount); 348 | EncogFileWriteValueDoubleArray(fp,"biasActivation",network->biasActivation,network->layerCount); 349 | fputs("[BASIC:ACTIVATION]\n",fp); 350 | for(i=0;ilayerCount;i++) 351 | { 352 | fputc('\"',fp); 353 | if( network->activationFunctions[i]==&EncogActivationLinear ) { 354 | fputs("ActivationLinear",fp); 355 | } else if( network->activationFunctions[i]==&EncogActivationTANH ) { 356 | fputs("ActivationTANH",fp); 357 | } else if( network->activationFunctions[i]==&EncogActivationSigmoid ) { 358 | fputs("ActivationSigmoid",fp); 359 | } 360 | 361 | fputs("\"\n",fp); 362 | } 363 | 364 | /* Write the basic info */ 365 | 366 | /* Write the activation functions */ 367 | 368 | fclose(fp); 369 | } 370 | 371 | -------------------------------------------------------------------------------- /encog-core/nm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | 27 | static double _evaluate (ENCOG_TRAIN_NM *nm, int thread, double x[] ) 28 | { 29 | int i, tid; 30 | float result; 31 | ENCOG_DATA *data; 32 | REAL *input, *ideal; 33 | REAL delta; 34 | unsigned int j; 35 | double errorSum; 36 | 37 | EncogNetworkImportWeights(nm->targetNetwork, x); 38 | data = nm->data; 39 | 40 | errorSum = 0; 41 | 42 | #pragma omp parallel for private(i,j,input,ideal, tid, delta) reduction(+:errorSum) default(shared) 43 | for(i=0; i<(int)nm->data->recordCount; i++) 44 | { 45 | tid = omp_get_thread_num(); 46 | 47 | input = EncogDataGetInput(data,i); 48 | ideal = EncogDataGetIdeal(data,i); 49 | 50 | EncogNetworkCompute(nm->network[tid],input,NULL); 51 | for(j=0; jtargetNetwork->outputCount; j++) 52 | { 53 | delta = nm->network[tid]->layerOutput[j] - ideal[j]; 54 | errorSum+=delta*delta; 55 | } 56 | } 57 | 58 | result = (float)(errorSum/(data->recordCount*data->idealCount)); 59 | 60 | nm->error = nm->error; 61 | 62 | if( !nm->currentReport.stopRequested ) 63 | { 64 | nm->currentReport.error = nm->error; 65 | nm->currentReport.iterations++; 66 | nm->reportTarget(&nm->currentReport); 67 | } 68 | return result; 69 | } 70 | 71 | static void _nelmin ( ENCOG_TRAIN_NM *nm, int thread, double start[], double xmin[] ) 72 | { 73 | REAL ccoeff = 0.5; 74 | REAL del; 75 | REAL dn; 76 | REAL dnn; 77 | REAL ecoeff = 2.0; 78 | REAL eps = 0.001; 79 | int i; 80 | int ihi; 81 | int ilo; 82 | int j; 83 | int jcount; 84 | int l; 85 | int nn; 86 | int n; 87 | REAL *p; 88 | REAL *p2star; 89 | REAL *pbar; 90 | REAL *pstar; 91 | REAL rcoeff = 1.0; 92 | REAL rq; 93 | REAL x; 94 | REAL *y; 95 | REAL y2star; 96 | REAL ylo; 97 | REAL ystar; 98 | REAL z; 99 | 100 | n = nm->n; 101 | /* 102 | Check the input parameters. 103 | */ 104 | if ( nm->reqmin <= 0.0 ) 105 | { 106 | nm->ifault = 1; 107 | return; 108 | } 109 | 110 | if ( n < 1 ) 111 | { 112 | nm->ifault = 1; 113 | return; 114 | } 115 | 116 | if ( nm->konvge < 1 ) 117 | { 118 | nm->ifault = 1; 119 | return; 120 | } 121 | 122 | p = ( double * ) malloc ( n * ( n + 1 ) * sizeof ( double ) ); 123 | pstar = ( double * ) malloc ( n * sizeof ( double ) ); 124 | p2star = ( double * ) malloc ( n * sizeof ( double ) ); 125 | pbar = ( double * ) malloc ( n * sizeof ( double ) ); 126 | y = ( double * ) malloc ( ( n + 1 ) * sizeof ( double ) ); 127 | 128 | nm->numres = 0; 129 | 130 | jcount = nm->konvge; 131 | dn = ( double ) ( n ); 132 | nn = n + 1; 133 | dnn = ( double ) ( nn ); 134 | del = 1.0; 135 | rq = nm->reqmin * dn; 136 | /* 137 | Initial or restarted loop. 138 | */ 139 | for ( ; ; ) 140 | { 141 | for ( i = 0; i < n; i++ ) 142 | { 143 | p[i+n*n] = start[i]; 144 | } 145 | y[n] = _evaluate ( nm, thread, start ); 146 | 147 | for ( j = 0; j < n; j++ ) 148 | { 149 | x = start[j]; 150 | start[j] = start[j] + nm->step * del; 151 | for ( i = 0; i < n; i++ ) 152 | { 153 | p[i+j*n] = start[i]; 154 | } 155 | y[j] = _evaluate ( nm, thread, start ); 156 | start[j] = x; 157 | } 158 | /* 159 | The simplex construction is complete. 160 | 161 | Find highest and lowest Y values. YNEWLO = Y(IHI) indicates 162 | the vertex of the simplex to be replaced. 163 | */ 164 | ylo = y[0]; 165 | ilo = 0; 166 | 167 | for ( i = 1; i < nn; i++ ) 168 | { 169 | if ( y[i] < ylo ) 170 | { 171 | ylo = y[i]; 172 | ilo = i; 173 | } 174 | } 175 | /* 176 | Inner loop. 177 | */ 178 | for ( ; ; ) 179 | { 180 | if ( nm->currentReport.stopRequested ) 181 | { 182 | break; 183 | } 184 | nm->error = (float)y[0]; 185 | ihi = 0; 186 | 187 | for ( i = 1; i < nn; i++ ) 188 | { 189 | if ( nm->error < y[i] ) 190 | { 191 | nm->error = (float)y[i]; 192 | ihi = i; 193 | } 194 | } 195 | /* 196 | Calculate PBAR, the centroid of the simplex vertices 197 | excepting the vertex with Y value YNEWLO. 198 | */ 199 | for ( i = 0; i < n; i++ ) 200 | { 201 | z = 0.0; 202 | for ( j = 0; j < nn; j++ ) 203 | { 204 | z = z + p[i+j*n]; 205 | } 206 | z = z - p[i+ihi*n]; 207 | pbar[i] = z / dn; 208 | } 209 | /* 210 | Reflection through the centroid. 211 | */ 212 | for ( i = 0; i < n; i++ ) 213 | { 214 | pstar[i] = pbar[i] + rcoeff * ( pbar[i] - p[i+ihi*n] ); 215 | } 216 | ystar = _evaluate ( nm, thread, pstar ); 217 | /* 218 | Successful reflection, so extension. 219 | */ 220 | if ( ystar < ylo ) 221 | { 222 | for ( i = 0; i < n; i++ ) 223 | { 224 | p2star[i] = pbar[i] + ecoeff * ( pstar[i] - pbar[i] ); 225 | } 226 | y2star = _evaluate ( nm, thread, p2star ); 227 | /* 228 | Check extension. 229 | */ 230 | if ( ystar < y2star ) 231 | { 232 | for ( i = 0; i < n; i++ ) 233 | { 234 | p[i+ihi*n] = pstar[i]; 235 | } 236 | y[ihi] = ystar; 237 | } 238 | /* 239 | Retain extension or contraction. 240 | */ 241 | else 242 | { 243 | for ( i = 0; i < n; i++ ) 244 | { 245 | p[i+ihi*n] = p2star[i]; 246 | } 247 | y[ihi] = y2star; 248 | } 249 | } 250 | /* 251 | No extension. 252 | */ 253 | else 254 | { 255 | l = 0; 256 | for ( i = 0; i < nn; i++ ) 257 | { 258 | if ( ystar < y[i] ) 259 | { 260 | l = l + 1; 261 | } 262 | } 263 | 264 | if ( 1 < l ) 265 | { 266 | for ( i = 0; i < n; i++ ) 267 | { 268 | p[i+ihi*n] = pstar[i]; 269 | } 270 | y[ihi] = ystar; 271 | } 272 | /* 273 | Contraction on the Y(IHI) side of the centroid. 274 | */ 275 | else if ( l == 0 ) 276 | { 277 | for ( i = 0; i < n; i++ ) 278 | { 279 | p2star[i] = pbar[i] + ccoeff * ( p[i+ihi*n] - pbar[i] ); 280 | } 281 | y2star = _evaluate ( nm, thread, p2star ); 282 | /* 283 | Contract the whole simplex. 284 | */ 285 | if ( y[ihi] < y2star ) 286 | { 287 | for ( j = 0; j < nn; j++ ) 288 | { 289 | for ( i = 0; i < n; i++ ) 290 | { 291 | p[i+j*n] = ( p[i+j*n] + p[i+ilo*n] ) * 0.5; 292 | xmin[i] = p[i+j*n]; 293 | } 294 | y[j] = _evaluate ( nm, thread, xmin ); 295 | } 296 | ylo = y[0]; 297 | ilo = 0; 298 | 299 | for ( i = 1; i < nn; i++ ) 300 | { 301 | if ( y[i] < ylo ) 302 | { 303 | ylo = y[i]; 304 | ilo = i; 305 | } 306 | } 307 | continue; 308 | } 309 | /* 310 | Retain contraction. 311 | */ 312 | else 313 | { 314 | for ( i = 0; i < n; i++ ) 315 | { 316 | p[i+ihi*n] = p2star[i]; 317 | } 318 | y[ihi] = y2star; 319 | } 320 | } 321 | /* 322 | Contraction on the reflection side of the centroid. 323 | */ 324 | else if ( l == 1 ) 325 | { 326 | for ( i = 0; i < n; i++ ) 327 | { 328 | p2star[i] = pbar[i] + ccoeff * ( pstar[i] - pbar[i] ); 329 | } 330 | y2star = _evaluate ( nm, thread, p2star ); 331 | /* 332 | Retain reflection? 333 | */ 334 | if ( y2star <= ystar ) 335 | { 336 | for ( i = 0; i < n; i++ ) 337 | { 338 | p[i+ihi*n] = p2star[i]; 339 | } 340 | y[ihi] = y2star; 341 | } 342 | else 343 | { 344 | for ( i = 0; i < n; i++ ) 345 | { 346 | p[i+ihi*n] = pstar[i]; 347 | } 348 | y[ihi] = ystar; 349 | } 350 | } 351 | } 352 | /* 353 | Check if YLO improved. 354 | */ 355 | if ( y[ihi] < ylo ) 356 | { 357 | ylo = y[ihi]; 358 | ilo = ihi; 359 | } 360 | jcount = jcount - 1; 361 | 362 | if ( 0 < jcount ) 363 | { 364 | continue; 365 | } 366 | /* 367 | Check to see if minimum reached. 368 | */ 369 | if ( !nm->currentReport.stopRequested ) 370 | { 371 | jcount = nm->konvge; 372 | 373 | z = 0.0; 374 | for ( i = 0; i < nn; i++ ) 375 | { 376 | z = z + y[i]; 377 | } 378 | x = z / dnn; 379 | 380 | z = 0.0; 381 | for ( i = 0; i < nn; i++ ) 382 | { 383 | z = z + pow ( y[i] - x, 2 ); 384 | } 385 | 386 | if ( z <= rq ) 387 | { 388 | break; 389 | } 390 | } 391 | } 392 | /* 393 | Factorial tests to check that YNEWLO is a local minimum. 394 | */ 395 | for ( i = 0; i < n; i++ ) 396 | { 397 | xmin[i] = p[i+ilo*n]; 398 | } 399 | 400 | if ( nm->currentReport.stopRequested ) 401 | { 402 | nm->ifault = 2; 403 | break; 404 | } 405 | 406 | nm->ifault = 0; 407 | 408 | for ( i = 0; i < n; i++ ) 409 | { 410 | del = nm->step * eps; 411 | xmin[i] = xmin[i] + del; 412 | z = _evaluate ( nm,thread, xmin ); 413 | if ( z < nm->error ) 414 | { 415 | nm->ifault = 2; 416 | break; 417 | } 418 | xmin[i] = xmin[i] - del - del; 419 | z = _evaluate ( nm,thread, xmin ); 420 | if ( z < nm->error ) 421 | { 422 | nm->ifault = 2; 423 | break; 424 | } 425 | xmin[i] = xmin[i] + del; 426 | } 427 | 428 | if ( nm->ifault == 0 ) 429 | { 430 | break; 431 | } 432 | 433 | /* 434 | Restart the procedure. 435 | */ 436 | for ( i = 0; i < n; i++ ) 437 | { 438 | start[i] = xmin[i]; 439 | } 440 | del = eps; 441 | nm->numres++; 442 | } 443 | 444 | 445 | if( !nm->currentReport.stopRequested ) 446 | { 447 | nm->currentReport.error = nm->error; 448 | nm->currentReport.iterations++; 449 | nm->currentReport.stopRequested = 1; 450 | nm->reportTarget(&nm->currentReport); 451 | } 452 | 453 | free ( p ); 454 | free ( pstar ); 455 | free ( p2star ); 456 | free ( pbar ); 457 | free ( y ); 458 | 459 | return; 460 | } 461 | 462 | ENCOG_TRAIN_NM *EncogTrainNMNew(ENCOG_NEURAL_NETWORK *network, ENCOG_DATA *data) 463 | { 464 | ENCOG_TRAIN_NM *result; 465 | int maxThread, i; 466 | 467 | /* Clear out any previous errors */ 468 | EncogErrorClear(); 469 | 470 | maxThread = omp_get_max_threads(); 471 | 472 | result = (ENCOG_TRAIN_NM *)EncogUtilAlloc(1,sizeof(ENCOG_TRAIN_NM)); 473 | result->threadCount = maxThread; 474 | 475 | result->data = data; 476 | result->targetNetwork = network; 477 | result->reportTarget = &EncogTrainStandardCallback; 478 | result->error = 1.0; 479 | result->network = (ENCOG_NEURAL_NETWORK**)EncogUtilAlloc(maxThread,sizeof(ENCOG_NEURAL_NETWORK*)); 480 | result->step = EncogHashGetFloat(encogContext.config,PARAM_STEP,10.0); 481 | result->reqmin = EncogHashGetFloat(encogContext.config,PARAM_REQMIN, 1.0e-16f); 482 | result->konvge = EncogHashGetInteger(encogContext.config,PARAM_KONVERGE,100); 483 | result->ifault = 0; 484 | memset(&result->currentReport,0,sizeof(ENCOG_TRAINING_REPORT)); 485 | 486 | result->n = result->targetNetwork->weightCount; 487 | result->step = 1; 488 | 489 | for(i=0;inetwork[i] = (ENCOG_NEURAL_NETWORK*)EncogNetworkTransactionClone(network); 492 | } 493 | 494 | EncogObjectRegister(result, ENCOG_TYPE_NM); 495 | result->currentReport.trainer = (ENCOG_OBJECT*)result; 496 | 497 | return result; 498 | } 499 | 500 | float EncogTrainNMRun(ENCOG_TRAIN_NM *nm) 501 | { 502 | int n; 503 | double *start; 504 | double *xmin; 505 | 506 | 507 | /* Clear out any previous errors */ 508 | EncogErrorClear(); 509 | 510 | nm->currentReport.iterations = 0; 511 | nm->currentReport.lastUpdate = 0; 512 | nm->currentReport.stopRequested = 0; 513 | nm->currentReport.trainingStarted = time(NULL); 514 | 515 | n = nm->targetNetwork->weightCount; 516 | start = (double*)EncogUtilDuplicateMemory(nm->targetNetwork->weights,n,sizeof(REAL)); 517 | xmin = (double*)EncogUtilAlloc(n,sizeof(double)); 518 | 519 | _nelmin ( nm, 0, start, xmin ); 520 | 521 | nm->currentReport.error = nm->error; 522 | 523 | return nm->currentReport.error; 524 | } 525 | 526 | -------------------------------------------------------------------------------- /encog-core/object.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | static void _freeNeuralNetwork(ENCOG_NEURAL_NETWORK *net) 27 | { 28 | EncogUtilFree(net->layerCounts); 29 | EncogUtilFree(net->biasActivation); 30 | EncogUtilFree(net->activationFunctions); 31 | EncogUtilFree(net->activationFunctionIDs); 32 | EncogUtilFree(net->layerContextCount); 33 | EncogUtilFree(net->weightIndex); 34 | EncogUtilFree(net->layerIndex); 35 | EncogUtilFree(net->layerFeedCounts); 36 | EncogUtilFree(net->contextTargetOffset); 37 | EncogUtilFree(net->contextTargetSize); 38 | 39 | EncogUtilFree(net); 40 | } 41 | 42 | static void _freeData(ENCOG_DATA *data) 43 | { 44 | EncogUtilFree(data->data); 45 | EncogUtilFree(data); 46 | } 47 | 48 | static void _freePSO(ENCOG_TRAIN_PSO *pso) 49 | { 50 | int i; 51 | ENCOG_PARTICLE *particle; 52 | 53 | /* Clear out any previous errors */ 54 | EncogErrorClear(); 55 | 56 | /* first delete the particles */ 57 | for(i=0;ipopulationSize;i++) { 58 | particle = &pso->particles[i]; 59 | EncogObjectFree(particle->network); 60 | EncogUtilFree(particle->velocities); 61 | EncogUtilFree(particle->bestVector); 62 | EncogUtilFree(particle->vtemp); 63 | } 64 | 65 | /* delete anything on the PSO, including particle structure */ 66 | EncogUtilFree(pso->particles); 67 | EncogUtilFree(pso->bestVector); 68 | 69 | /* finally, delete the PSO */ 70 | EncogUtilFree(pso); 71 | } 72 | 73 | static void _freeHash(ENCOG_HASH *hash) 74 | { 75 | unsigned int i; 76 | ENCOG_HASH_NODE *node,*temp; 77 | 78 | for(i=0;itableSize;i++) 79 | { 80 | node = hash->table[i]; 81 | while( node!=NULL ) 82 | { 83 | EncogUtilFree(node->value); 84 | EncogUtilFree(node->key); 85 | temp = node->next; 86 | EncogUtilFree(temp); 87 | node = temp; 88 | } 89 | } 90 | 91 | EncogUtilFree(hash); 92 | } 93 | 94 | 95 | static void _freeRPROP(ENCOG_TRAIN_RPROP *rprop) 96 | { 97 | int i = 0; 98 | 99 | EncogUtilFree(rprop->gradients); 100 | EncogUtilFree(rprop->lastGradient); 101 | EncogUtilFree(rprop->lastWeightChange); 102 | EncogUtilFree(rprop->updateValues); 103 | 104 | for(i=0;ithreadCount;i++) 105 | { 106 | EncogUtilFree(rprop->layerDelta[i]); 107 | EncogUtilFree(rprop->network[i]); 108 | 109 | } 110 | 111 | EncogUtilFree(rprop); 112 | } 113 | 114 | void EncogObjectRegister(void *obj, int type) 115 | { 116 | ENCOG_OBJECT *encogObject; 117 | 118 | encogObject = (ENCOG_OBJECT *)obj; 119 | encogObject->id[0] = 'E'; 120 | encogObject->id[1] = 'G'; 121 | encogObject->type = type; 122 | } 123 | 124 | void EncogObjectValidate(void *obj, int type) 125 | { 126 | ENCOG_OBJECT *encogObject; 127 | EncogErrorClear(); 128 | 129 | encogObject = (ENCOG_OBJECT *)obj; 130 | 131 | if( encogObject->id[0]!='E' || encogObject->id[1]!='G' ) 132 | { 133 | EncogErrorSet(ENCOG_ERROR_OBJECT); 134 | return; 135 | } 136 | 137 | if( encogObject->type != type) 138 | { 139 | EncogErrorSet(ENCOG_ERROR_OBJECT_TYPE); 140 | return; 141 | } 142 | } 143 | 144 | void EncogObjectFree(void *obj) 145 | { 146 | ENCOG_OBJECT *encogObject; 147 | encogObject = (ENCOG_OBJECT *)obj; 148 | 149 | EncogErrorClear(); 150 | 151 | if( encogObject->id[0]!='E' || encogObject->id[1]!='G' ) 152 | { 153 | EncogErrorSet(ENCOG_ERROR_OBJECT); 154 | return; 155 | } 156 | 157 | switch(encogObject->type) 158 | { 159 | case ENCOG_TYPE_NEURAL_NETWORK: 160 | _freeNeuralNetwork((ENCOG_NEURAL_NETWORK*)obj); 161 | break; 162 | case ENCOG_TYPE_DATA: 163 | _freeData((ENCOG_DATA*)obj); 164 | break; 165 | case ENCOG_TYPE_PSO: 166 | _freePSO((ENCOG_TRAIN_PSO*)obj); 167 | break; 168 | case ENCOG_TYPE_RPROP: 169 | _freeRPROP((ENCOG_TRAIN_RPROP*)obj); 170 | break; 171 | case ENCOG_TYPE_HASH: 172 | _freeHash((ENCOG_HASH*)obj); 173 | break; 174 | } 175 | } 176 | 177 | int EncogObjectGetType(ENCOG_OBJECT *encogObject) 178 | { 179 | if( encogObject->id[0]!='E' || encogObject->id[1]!='G' ) 180 | { 181 | EncogErrorSet(ENCOG_ERROR_OBJECT); 182 | return -1; 183 | } 184 | 185 | return encogObject->type; 186 | } 187 | 188 | char *EncogObjectType(ENCOG_OBJECT *encogObject) 189 | { 190 | switch(encogObject->type) 191 | { 192 | case ENCOG_TYPE_NEURAL_NETWORK: 193 | return "NEURAL_NETWORK"; 194 | case ENCOG_TYPE_DATA: 195 | return "ENCOG_DATA"; 196 | case ENCOG_TYPE_PSO: 197 | return "ENCOG_TRAIN_PSO"; 198 | case ENCOG_TYPE_RPROP: 199 | return "ENCOG_TRAIN_RPROP"; 200 | case ENCOG_TYPE_HASH: 201 | return "ENCOG_HASH"; 202 | case ENCOG_TYPE_NM: 203 | return "ENCOG_TRAIN_NM"; 204 | default: 205 | return "unknown"; 206 | } 207 | } 208 | 209 | 210 | -------------------------------------------------------------------------------- /encog-core/pso.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | 27 | 28 | static float _CalculatePSOError(ENCOG_TRAIN_PSO *pso, ENCOG_NEURAL_NETWORK *network) 29 | { 30 | float result; 31 | float start,stop; 32 | 33 | #ifdef ENCOG_CUDA 34 | if( encogContext.gpuEnabled && omp_get_thread_num()==0 ) 35 | { 36 | result = EncogCUDAErrorSSE(pso->device, network); 37 | } 38 | else 39 | { 40 | start = omp_get_wtime(); 41 | result = EncogCPUErrorSSE( network, pso->data); 42 | stop = omp_get_wtime(); 43 | 44 | #pragma omp critical 45 | { 46 | pso->cpuWorkUnitTime+=(stop-start); 47 | pso->cpuWorkUnitCalls++; 48 | } 49 | return result; 50 | } 51 | return result; 52 | #else 53 | start = (float)omp_get_wtime(); 54 | result = EncogErrorSSE( network, pso->data); 55 | stop = (float)omp_get_wtime(); 56 | #pragma omp critical 57 | { 58 | pso->cpuWorkUnitTime+=(stop-start); 59 | pso->cpuWorkUnitCalls++; 60 | } 61 | 62 | return result; 63 | #endif 64 | } 65 | 66 | 67 | /* Internal functions */ 68 | 69 | 70 | static void _UpdateGlobalBestPosition(ENCOG_TRAIN_PSO *pso) 71 | { 72 | int bestUpdated = 0, i; 73 | ENCOG_PARTICLE *best,*particle; 74 | 75 | if( pso->bestParticle!=-1 ) 76 | { 77 | best = &pso->particles[pso->bestParticle]; 78 | } 79 | else 80 | { 81 | best = NULL; 82 | } 83 | 84 | 85 | for (i = 0; i < pso->populationSize; i++) 86 | { 87 | particle = &pso->particles[i]; 88 | if ((best==NULL) || particle->bestErrorbestError ) 89 | { 90 | pso->bestParticle = i; 91 | best = particle; 92 | bestUpdated = 1; 93 | } 94 | } 95 | if (bestUpdated) 96 | { 97 | EncogVectorCopy(pso->bestVector, best->network->weights,pso->dimensions); 98 | pso->bestError = best->bestError; 99 | } 100 | } 101 | 102 | /* API functions */ 103 | 104 | ENCOG_TRAIN_PSO *EncogTrainPSONew(int populationSize, ENCOG_NEURAL_NETWORK *model, ENCOG_DATA *data) 105 | { 106 | int i; 107 | ENCOG_PARTICLE *particle; 108 | ENCOG_TRAIN_PSO *pso; 109 | ENCOG_NEURAL_NETWORK *clone; 110 | 111 | /* Clear out any previous errors */ 112 | EncogErrorClear(); 113 | 114 | pso = (ENCOG_TRAIN_PSO*)EncogUtilAlloc(1,sizeof(ENCOG_TRAIN_PSO)); 115 | pso->inertiaWeight = EncogHashGetFloat(encogContext.config,PARAM_INERTIA,(float)0.4); 116 | pso->c1 = EncogHashGetFloat(encogContext.config,PARAM_C1,2.0); 117 | pso->c2 = EncogHashGetFloat(encogContext.config,PARAM_C2,2.0); 118 | pso->populationSize = populationSize; 119 | pso->maxPosition = EncogHashGetFloat(encogContext.config,PARAM_MAXPOS,(float)-1); 120 | pso->maxVelocity = EncogHashGetFloat(encogContext.config,PARAM_MAXVEL,(float)2); 121 | pso->bestParticle = -1; 122 | pso->dimensions = model->weightCount; 123 | pso->data = data; 124 | pso->bestVector = (REAL*)EncogUtilAlloc(model->weightCount,sizeof(REAL)); 125 | pso->reportTarget = &EncogTrainStandardCallback; 126 | 127 | memset(&pso->currentReport,0,sizeof(ENCOG_TRAINING_REPORT)); 128 | 129 | /* construct the arrays */ 130 | 131 | pso->particles = (ENCOG_PARTICLE*)EncogUtilAlloc(populationSize,sizeof(ENCOG_PARTICLE)); 132 | 133 | #ifdef ENCOG_CUDA 134 | if( encogContext.gpuEnabled ) { 135 | pso->device = EncogGPUDeviceNew(0, model, data); 136 | } 137 | #endif 138 | 139 | for(i=0; iparticles[i]; 142 | clone = EncogNetworkClone(model); 143 | particle->index = i; 144 | particle->pso = (struct ENCOG_TRAIN_PSO*)pso; 145 | particle->network = clone; 146 | particle->velocities = (REAL*)EncogUtilAlloc(clone->weightCount,sizeof(REAL)); 147 | particle->vtemp = (REAL*)EncogUtilAlloc(clone->weightCount,sizeof(REAL)); 148 | particle->bestVector = (REAL*)EncogUtilAlloc(clone->weightCount,sizeof(REAL)); 149 | particle->bestError = 1.0; 150 | particle->particleState = PARTICLE_STATE_CALC; 151 | if( i>0 ) { 152 | EncogNetworkRandomizeRange(particle->network,-1,1); 153 | } 154 | EncogNetworkExportWeights(particle->network,particle->bestVector); 155 | EncogVectorRandomise(particle->velocities, pso->maxVelocity, clone->weightCount); 156 | } 157 | 158 | EncogObjectRegister(pso, ENCOG_TYPE_PSO); 159 | pso->currentReport.trainer = (ENCOG_OBJECT*)pso; 160 | 161 | _UpdateGlobalBestPosition(pso); 162 | return pso; 163 | } 164 | 165 | /** 166 | * Update the personal best position of a particle. 167 | * 168 | * @param particleIndex index of the particle in the swarm 169 | * @param particlePosition the particle current position vector 170 | */ 171 | static void _PSOPerformCalc(ENCOG_PARTICLE *particle) 172 | { 173 | float score; 174 | 175 | // set the network weights and biases from the vector 176 | score = _CalculatePSOError( particle->pso, particle->network); 177 | 178 | // update the best vectors (g and i) 179 | if ( (particle->bestError == 0) || scorebestError) 180 | { 181 | particle->bestError = score; 182 | EncogVectorCopy(particle->bestVector, particle->network->weights, particle->pso->dimensions); 183 | 184 | #pragma omp critical 185 | { 186 | if( particle->pso->bestError == 0 || scorepso->bestError ) { 187 | EncogVectorCopy(particle->pso->bestVector, particle->network->weights,particle->pso->dimensions); 188 | particle->pso->bestError = score; 189 | particle->pso->bestParticle = particle->index; 190 | } 191 | } 192 | } 193 | 194 | particle->particleState = PARTICLE_STATE_ITERATION; 195 | } 196 | 197 | static void _PSOPerformMove(ENCOG_PARTICLE *particle) 198 | { 199 | ENCOG_TRAIN_PSO *pso; 200 | INT i; 201 | 202 | pso = (ENCOG_TRAIN_PSO *)particle->pso; 203 | 204 | for(i=0;i<(INT)pso->dimensions;i++) { 205 | // update velocity 206 | particle->velocities[i] *= pso->inertiaWeight; 207 | 208 | // cognitive term 209 | particle->velocities[i]+=(particle->bestVector[i]-particle->network->weights[i]) * pso->c1 * ((REAL)rand()/(REAL)RAND_MAX); 210 | 211 | // social term 212 | if (particle->index != pso->bestParticle) 213 | { 214 | particle->velocities[i]+=(pso->bestVector[i]-particle->network->weights[i]) * pso->c2 * ((REAL)rand()/(REAL)RAND_MAX); 215 | } 216 | 217 | // clamp 218 | if( pso->maxVelocity!=-1 ) { 219 | particle->velocities[i] = MAX(particle->velocities[i],-pso->maxVelocity); 220 | particle->velocities[i] = MIN(particle->velocities[i],pso->maxVelocity); 221 | } 222 | 223 | 224 | // update weights 225 | particle->network->weights[i]+=particle->velocities[i]; 226 | if( pso->maxPosition!=-1 ) { 227 | particle->network->weights[i] = MAX(particle->network->weights[i],-pso->maxPosition); 228 | particle->network->weights[i] = MIN(particle->network->weights[i],pso->maxPosition); 229 | } 230 | } 231 | 232 | particle->particleState = PARTICLE_STATE_CALC; 233 | } 234 | 235 | ENCOG_PARTICLE *_getNextParticle(ENCOG_TRAIN_PSO *pso) 236 | { 237 | ENCOG_PARTICLE *result = NULL; 238 | int i; 239 | 240 | /* First preference is to move */ 241 | 242 | for(i=0;ipopulationSize;i++) { 243 | result = &pso->particles[i]; 244 | if( result->particleState == PARTICLE_STATE_MOVE ) { 245 | result->particleState = PARTICLE_STATE_MOVING; 246 | return result; 247 | } 248 | } 249 | 250 | /* Second preference is to recalculate */ 251 | 252 | for(i=0;ipopulationSize;i++) { 253 | result = &pso->particles[i]; 254 | if( result->particleState == PARTICLE_STATE_CALC ) { 255 | result->particleState = PARTICLE_STATE_CALCING; 256 | return result; 257 | } 258 | } 259 | 260 | /* Third, we set everyone back to move, and return the last particle */ 261 | for(i=0;ipopulationSize;i++) { 262 | result = &pso->particles[i]; 263 | result->particleState = PARTICLE_STATE_MOVE; 264 | } 265 | 266 | pso->currentReport.iterations++; 267 | pso->currentReport.error = pso->bestError; 268 | pso->reportTarget(&pso->currentReport); 269 | 270 | return result; 271 | } 272 | 273 | float EncogTrainPSORun(ENCOG_TRAIN_PSO *pso) 274 | { 275 | ENCOG_PARTICLE *particle; 276 | 277 | /* Clear out any previous errors */ 278 | EncogErrorClear(); 279 | 280 | pso->currentReport.iterations = 0; 281 | pso->currentReport.lastUpdate = 0; 282 | pso->currentReport.stopRequested = 0; 283 | pso->currentReport.trainingStarted = time(NULL); 284 | 285 | #pragma omp parallel private(particle) 286 | { 287 | while( !pso->currentReport.stopRequested ) 288 | { 289 | #pragma omp critical 290 | { 291 | particle = _getNextParticle(pso); 292 | } 293 | 294 | if( particle->particleState == PARTICLE_STATE_CALCING ) 295 | { 296 | //printf("##Calc: %i\n",particle->index); 297 | _PSOPerformCalc(particle); 298 | } else if( particle->particleState == PARTICLE_STATE_MOVING ) 299 | { 300 | //printf("##Move: %i\n",particle->index); 301 | _PSOPerformMove(particle); 302 | } 303 | } 304 | } 305 | 306 | return pso->bestError; 307 | } 308 | 309 | void EncogTrainPSOImportBest(ENCOG_TRAIN_PSO *pso, ENCOG_NEURAL_NETWORK *net) 310 | { 311 | ENCOG_PARTICLE *particle; 312 | 313 | /* Clear out any previous errors */ 314 | EncogErrorClear(); 315 | 316 | particle = &pso->particles[pso->bestParticle]; 317 | EncogNetworkImportWeights(net,particle->bestVector); 318 | } 319 | 320 | void EncogTrainPSOFinish(ENCOG_TRAIN_PSO *pso) { 321 | #ifdef ENCOG_CUDA 322 | if( encogContext.gpuEnabled ) { 323 | pso->cudaKernelTime=pso->device->perfKernelTime/pso->device->perfCount; 324 | pso->cudaKernelCalls=pso->device->perfCount; 325 | } 326 | #endif 327 | } 328 | -------------------------------------------------------------------------------- /encog-core/random.c: -------------------------------------------------------------------------------- 1 | #include "encog.h" 2 | 3 | static int _randomAlgorithm = RANDOM_RTL; 4 | static unsigned long _x=123456789, _y=362436069, _z=521288629; 5 | 6 | static unsigned long xorshf96(void) { //period 2^96-1 7 | unsigned long t; 8 | _x ^= _x << 16; 9 | _x ^= _x >> 5; 10 | _x ^= _x << 1; 11 | 12 | t = _x; 13 | _x = _y; 14 | _y = _z; 15 | _z = t ^ _x ^ _y; 16 | 17 | return _z; 18 | } 19 | 20 | void EncogRandomChooseAlgorithm(int a) 21 | { 22 | _randomAlgorithm = a; 23 | } 24 | 25 | void EncogRandomSeed() 26 | { 27 | unsigned int iseed; 28 | iseed = (unsigned int)time(NULL); 29 | EncogRandomSeedSpecific(iseed); 30 | } 31 | 32 | void EncogRandomSeedSpecific(unsigned int iseed) 33 | { 34 | switch(_randomAlgorithm) 35 | { 36 | case RANDOM_RTL: 37 | srand (iseed); 38 | break; 39 | case RANDOM_XORSHIFT: 40 | break; 41 | } 42 | } 43 | 44 | double EncogRandomDouble() 45 | { 46 | double result; 47 | 48 | #pragma omp critical 49 | { 50 | 51 | switch(_randomAlgorithm) 52 | { 53 | case RANDOM_RTL: 54 | result = ((REAL)rand()/(REAL)RAND_MAX); 55 | break; 56 | case RANDOM_XORSHIFT: 57 | result = ((REAL)xorshf96()/(REAL)RAND_MAX); 58 | break; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /encog-core/rprop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | /** 27 | * The default zero tolerance. 28 | */ 29 | const double DEFAULT_ZERO_TOLERANCE = 0.00000000000000001; 30 | 31 | /** 32 | * The POSITIVE ETA value. This is specified by the resilient propagation 33 | * algorithm. This is the percentage by which the deltas are increased by if 34 | * the partial derivative is greater than zero. 35 | */ 36 | const double POSITIVE_ETA = 1.2; 37 | 38 | /** 39 | * The NEGATIVE ETA value. This is specified by the resilient propagation 40 | * algorithm. This is the percentage by which the deltas are increased by if 41 | * the partial derivative is less than zero. 42 | */ 43 | const double NEGATIVE_ETA = 0.5; 44 | 45 | /** 46 | * The minimum delta value for a weight matrix value. 47 | */ 48 | const double DELTA_MIN = 1e-6; 49 | 50 | /** 51 | * The starting update for a delta. 52 | */ 53 | const double DEFAULT_INITIAL_UPDATE = 0.1; 54 | 55 | /** 56 | * The maximum amount a delta can reach. 57 | */ 58 | const double DEFAULT_MAX_STEP = 50; 59 | 60 | ENCOG_TRAIN_RPROP *EncogTrainRPROPNew(ENCOG_NEURAL_NETWORK *network, ENCOG_DATA *data) 61 | { 62 | ENCOG_TRAIN_RPROP *result; 63 | INT i,maxThread; 64 | 65 | /* Clear out any previous errors */ 66 | EncogErrorClear(); 67 | 68 | maxThread = omp_get_max_threads(); 69 | 70 | result = (ENCOG_TRAIN_RPROP *)EncogUtilAlloc(1,sizeof(ENCOG_TRAIN_RPROP)); 71 | result->threadCount = maxThread; 72 | result->data = data; 73 | result->targetNetwork = network; 74 | result->reportTarget = &EncogTrainStandardCallback; 75 | result->lastWeightChange = (REAL*)EncogUtilAlloc(network->weightCount,sizeof(REAL)); 76 | result->updateValues = (REAL*)EncogUtilAlloc(network->weightCount,sizeof(REAL)); 77 | result->gradients = (REAL*)EncogUtilAlloc(network->weightCount,sizeof(REAL)); 78 | result->lastGradient = (REAL*)EncogUtilAlloc(network->weightCount,sizeof(REAL)); 79 | result->layerDelta = (REAL**)EncogUtilAlloc(maxThread,sizeof(REAL*)); 80 | result->network = (ENCOG_NEURAL_NETWORK**)EncogUtilAlloc(maxThread,sizeof(ENCOG_NEURAL_NETWORK*)); 81 | memset(&result->currentReport,0,sizeof(ENCOG_TRAINING_REPORT)); 82 | 83 | for(i=0;iweightCount;i++) 84 | { 85 | result->updateValues[i] = DEFAULT_INITIAL_UPDATE; 86 | result->lastWeightChange[i] = 0; 87 | result->lastGradient[i] = 0; 88 | } 89 | 90 | for(i=0;ilayerDelta[i] = (REAL*)EncogUtilAlloc(network->neuronCount,sizeof(REAL)); 93 | result->network[i] = (ENCOG_NEURAL_NETWORK*)EncogNetworkTransactionClone(network); 94 | } 95 | 96 | EncogObjectRegister(result, ENCOG_TYPE_RPROP); 97 | result->currentReport.trainer = (ENCOG_OBJECT*)result; 98 | 99 | return result; 100 | } 101 | 102 | static void _ProcessLevel(INT currentLevel,ENCOG_NEURAL_NETWORK *net, ENCOG_TRAIN_RPROP *rprop, REAL *layerDelta ) 103 | { 104 | int fromLayerIndex; 105 | int toLayerIndex; 106 | int fromLayerSize; 107 | int toLayerSize; 108 | int index; 109 | DERIVATIVE_FUNCTION df; 110 | REAL output,sum; 111 | int yi; 112 | int xi; 113 | int wi; 114 | int x,y; 115 | 116 | fromLayerIndex = net->layerIndex[currentLevel + 1]; 117 | toLayerIndex = net->layerIndex[currentLevel]; 118 | fromLayerSize = net->layerCounts[currentLevel + 1]; 119 | toLayerSize = net->layerFeedCounts[currentLevel]; 120 | 121 | index = net->weightIndex[currentLevel]; 122 | 123 | df = net->derivativeFunctions[currentLevel+1]; 124 | 125 | // handle weights 126 | yi = fromLayerIndex; 127 | for (y = 0; y < fromLayerSize; y++) { 128 | output = net->layerOutput[yi]; 129 | sum = 0; 130 | xi = toLayerIndex; 131 | wi = index + y; 132 | for (x = 0; x < toLayerSize; x++) { 133 | 134 | #pragma omp critical 135 | { 136 | rprop->gradients[wi] += output * layerDelta[xi]; 137 | } 138 | sum += net->weights[wi] * layerDelta[xi]; 139 | wi += fromLayerSize; 140 | xi++; 141 | } 142 | 143 | layerDelta[yi] = sum 144 | * ((*df)(net->layerSums[yi],net->layerOutput[yi])); 145 | yi++; 146 | } 147 | } 148 | 149 | float _Process(ENCOG_TRAIN_RPROP *rprop, 150 | ENCOG_NEURAL_NETWORK *net, 151 | REAL *layerDelta, REAL *input, REAL *ideal, double s) 152 | { 153 | REAL delta; 154 | INT i; 155 | float errorSum; 156 | 157 | EncogNetworkCompute(net,input,NULL); 158 | 159 | errorSum = 0; 160 | for(i=0; ioutputCount; i++) 161 | { 162 | delta = ideal[i] - net->layerOutput[i]; 163 | errorSum += (float)(delta*delta); 164 | layerDelta[i] = (*net->derivativeFunctions)(net->layerSums[i],net->layerOutput[i])*delta; 165 | } 166 | 167 | for(i=0;ilayerCount;i++) 168 | { 169 | _ProcessLevel(i,net,rprop,layerDelta); 170 | } 171 | 172 | return errorSum; 173 | } 174 | 175 | /** 176 | * Determine the sign of the value. 177 | * 178 | * @param value 179 | * The value to check. 180 | * @return -1 if less than zero, 1 if greater, or 0 if zero. 181 | */ 182 | int sign(double value) { 183 | if (fabs(value) < 0.000000001) { 184 | return 0; 185 | } else if (value > 0) { 186 | return 1; 187 | } else { 188 | return -1; 189 | } 190 | } 191 | 192 | void _UpdateRPROPWeight(int index, ENCOG_TRAIN_RPROP *rprop) 193 | { 194 | int change; 195 | REAL delta; 196 | REAL *gradients; 197 | REAL *lastGradient; 198 | REAL *updateValues; 199 | REAL weightChange; 200 | REAL *lastWeightChange; 201 | ENCOG_NEURAL_NETWORK *net; 202 | 203 | net = rprop->targetNetwork; 204 | gradients = rprop->gradients; 205 | lastGradient = rprop->lastGradient; 206 | updateValues = rprop->updateValues; 207 | lastWeightChange = rprop->lastWeightChange; 208 | 209 | // multiply the current and previous gradient, and take the 210 | // sign. We want to see if the gradient has changed its sign. 211 | change = sign(gradients[index] * lastGradient[index]); 212 | weightChange = 0; 213 | 214 | // if the gradient has retained its sign, then we increase the 215 | // delta so that it will converge faster 216 | if (change > 0) { 217 | double delta = updateValues[index] 218 | * POSITIVE_ETA; 219 | delta = MIN(delta, DEFAULT_MAX_STEP); 220 | weightChange = sign(gradients[index]) * delta; 221 | updateValues[index] = delta; 222 | lastGradient[index] = gradients[index]; 223 | } else if (change < 0) { 224 | // if change<0, then the sign has changed, and the last 225 | // delta was too big 226 | double delta = updateValues[index] 227 | * NEGATIVE_ETA; 228 | delta = MAX(delta, DELTA_MIN); 229 | updateValues[index] = delta; 230 | weightChange = -lastWeightChange[index]; 231 | // set the previous gradent to zero so that there will be no 232 | // adjustment the next iteration 233 | lastGradient[index] = 0; 234 | } else if (change == 0) { 235 | // if change==0 then there is no change to the delta 236 | delta = updateValues[index]; 237 | weightChange = sign(gradients[index]) * delta; 238 | lastGradient[index] = gradients[index]; 239 | } 240 | 241 | // apply the weight change, if any 242 | net->weights[index]+=weightChange; 243 | } 244 | 245 | float EncogTrainRPROPRun(ENCOG_TRAIN_RPROP *rprop) 246 | { 247 | int i, tid; 248 | REAL *input,*ideal; 249 | float errorSum; 250 | ENCOG_DATA *data; 251 | 252 | /* Clear out any previous errors */ 253 | EncogErrorClear(); 254 | 255 | rprop->currentReport.iterations = 0; 256 | rprop->currentReport.lastUpdate = 0; 257 | rprop->currentReport.stopRequested = 0; 258 | rprop->currentReport.trainingStarted = time(NULL); 259 | 260 | data = rprop->data; 261 | 262 | while( !rprop->currentReport.stopRequested ) 263 | { 264 | errorSum = 0; 265 | memset(rprop->gradients,0, sizeof(REAL)*rprop->targetNetwork->weightCount); 266 | 267 | #pragma omp parallel for private(i,input,ideal, tid) reduction(+:errorSum) default(shared) 268 | for(i=0; i<(int)data->recordCount; i++) 269 | { 270 | tid = omp_get_thread_num(); 271 | input = EncogDataGetInput(data,i); 272 | ideal = EncogDataGetIdeal(data,i); 273 | 274 | errorSum = errorSum + _Process(rprop, 275 | rprop->network[tid], 276 | rprop->layerDelta[tid], input, ideal, 1.0); 277 | } 278 | 279 | // now learn! 280 | 281 | for(i=0;i<(int)rprop->targetNetwork->weightCount;i++) { 282 | _UpdateRPROPWeight(i,rprop); 283 | //net->weights[i]+=rprop->gradients[i]*0.7; 284 | } 285 | 286 | rprop->currentReport.error = (float)(errorSum/(data->recordCount*data->idealCount)); 287 | rprop->currentReport.iterations++; 288 | rprop->reportTarget(&rprop->currentReport); 289 | } 290 | 291 | return rprop->currentReport.error; 292 | } 293 | -------------------------------------------------------------------------------- /encog-core/train.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | ENCOG_OBJECT *EncogTrainNew(ENCOG_NEURAL_NETWORK *net, ENCOG_DATA *data) 27 | { 28 | char *ttype; 29 | ENCOG_TRAIN_PSO *pso; 30 | ENCOG_TRAIN_RPROP *rprop; 31 | ENCOG_TRAIN_NM *nm; 32 | int particles; 33 | 34 | ttype = (char*)EncogHashGet(encogContext.config,PARAM_TRAIN, "PSO"); 35 | 36 | if( !EncogUtilStrcmpi(ttype,TRAIN_TYPE_RPROP) ) 37 | { 38 | rprop = EncogTrainRPROPNew(net,data); 39 | return &rprop->encog; 40 | } 41 | else if( !EncogUtilStrcmpi(ttype,TRAIN_TYPE_PSO) ) 42 | { 43 | particles = EncogHashGetInteger(encogContext.config,PARAM_PARTICLES,30); 44 | pso = EncogTrainPSONew(particles, net, data); 45 | EncogErrorCheck(); 46 | pso->reportTarget = EncogTrainStandardCallback; 47 | return &pso->encog; 48 | } 49 | else if( !EncogUtilStrcmpi(ttype,TRAIN_TYPE_NM) ) 50 | { 51 | nm = EncogTrainNMNew(net,data); 52 | return &nm->encog; 53 | } 54 | else { 55 | EncogErrorSet(ENCOG_ERROR_UNKNOWN_TRAINING); 56 | return NULL; 57 | } 58 | } 59 | 60 | ENCOG_TRAINING_REPORT *EncogTrainReport(ENCOG_OBJECT *train) 61 | { 62 | int t; 63 | 64 | if( (t = EncogObjectGetType(train)) == -1 ) 65 | return NULL; 66 | 67 | if( t==ENCOG_TYPE_PSO ) 68 | { 69 | return &((ENCOG_TRAIN_PSO*)train)->currentReport; 70 | } 71 | else if( t==ENCOG_TYPE_RPROP ) 72 | { 73 | return &((ENCOG_TRAIN_RPROP*)train)->currentReport; 74 | } 75 | else if( t==ENCOG_TYPE_NM ) 76 | { 77 | return &((ENCOG_TRAIN_NM*)train)->currentReport; 78 | } 79 | else 80 | { 81 | EncogErrorSet(ENCOG_ERROR_OBJECT_TYPE); 82 | return NULL; 83 | } 84 | } 85 | 86 | void EncogTrainRun(ENCOG_OBJECT *train, ENCOG_NEURAL_NETWORK *net) 87 | { 88 | int t; 89 | 90 | if( (t = EncogObjectGetType(train)) == -1 ) 91 | return; 92 | 93 | if( t==ENCOG_TYPE_PSO ) 94 | { 95 | EncogTrainPSORun((ENCOG_TRAIN_PSO*)train); 96 | EncogTrainPSOFinish((ENCOG_TRAIN_PSO*)train); 97 | EncogTrainPSOImportBest((ENCOG_TRAIN_PSO*)train,net); 98 | } 99 | else if( t==ENCOG_TYPE_RPROP ) 100 | { 101 | EncogTrainRPROPRun((ENCOG_TRAIN_RPROP*)train); 102 | } 103 | else if( t==ENCOG_TYPE_NM ) 104 | { 105 | EncogTrainNMRun((ENCOG_TRAIN_NM*)train); 106 | } 107 | else { 108 | EncogErrorSet(ENCOG_ERROR_OBJECT_TYPE); 109 | } 110 | } 111 | 112 | void EncogTrainSetCallback(ENCOG_OBJECT *train, ENCOG_REPORT_FUNCTION callback) 113 | { 114 | int t; 115 | 116 | if( (t = EncogObjectGetType(train)) == -1 ) 117 | return; 118 | 119 | if( t==ENCOG_TYPE_PSO ) 120 | { 121 | ((ENCOG_TRAIN_PSO*)train)->reportTarget = callback; 122 | } 123 | else if( t==ENCOG_TYPE_RPROP ) 124 | { 125 | ((ENCOG_TRAIN_RPROP*)train)->reportTarget = callback; 126 | } 127 | else if( t==ENCOG_TYPE_NM ) 128 | { 129 | ((ENCOG_TRAIN_NM*)train)->reportTarget = callback; 130 | } 131 | else { 132 | EncogErrorSet(ENCOG_ERROR_OBJECT_TYPE); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /encog-core/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #ifndef _MSC_VER 25 | #include 26 | #include 27 | #include 28 | #include 29 | #endif 30 | 31 | #include "encog.h" 32 | 33 | #ifndef _MSC_VER 34 | static struct termios oldterm, newterm; 35 | #endif 36 | 37 | 38 | #ifdef _MSC_VER 39 | int isnan(double x) 40 | { 41 | return x != x; 42 | } 43 | 44 | int isinf(double x) 45 | { 46 | return !isnan(x) && isnan(x - x); 47 | } 48 | #endif 49 | 50 | void EncogUtilInitRandom() 51 | { 52 | unsigned int iseed; 53 | 54 | /* Clear out any previous errors */ 55 | EncogErrorClear(); 56 | 57 | iseed = (unsigned int)time(NULL); 58 | srand (iseed); 59 | } 60 | 61 | REAL EncogUtilRandomRange(REAL low, REAL high) 62 | { 63 | REAL d; 64 | d = (REAL)rand()/(REAL)RAND_MAX; 65 | d = (d*(high-low))+low; 66 | return d; 67 | } 68 | 69 | void EncogUtilOutputRealArray(char *tag, REAL *array, INT len) 70 | { 71 | INT i; 72 | char temp[MAX_STR]; 73 | 74 | puts(tag); 75 | for(i=0; i= 14 || (neg && m >= 9) || m <= -9); 156 | if (neg) 157 | *(c++) = '-'; 158 | // set up for scientific notation 159 | if (useExp) 160 | { 161 | if (m < 0) 162 | m -= 1; 163 | n = n / pow(10.0, m); 164 | m1 = m; 165 | m = 0; 166 | } 167 | if (m < 1.0) 168 | { 169 | m = 0; 170 | } 171 | // convert the number 172 | while (n > percision || m >= 0) 173 | { 174 | weight = pow(10.0, m); 175 | if (weight > 0 && !isinf(weight)) 176 | { 177 | digit = (int)(floor(n / weight)); 178 | n -= (digit * weight); 179 | *(c++) = '0' + digit; 180 | } 181 | if (m == 0 && n > 0) 182 | *(c++) = '.'; 183 | m--; 184 | } 185 | if (useExp) 186 | { 187 | // convert the exponent 188 | *(c++) = 'e'; 189 | if (m1 > 0) 190 | { 191 | *(c++) = '+'; 192 | } 193 | else 194 | { 195 | *(c++) = '-'; 196 | m1 = -m1; 197 | } 198 | m = 0; 199 | while (m1 > 0) 200 | { 201 | *(c++) = '0' + m1 % 10; 202 | m1 /= 10; 203 | m++; 204 | } 205 | c -= m; 206 | for (i = 0, j = m-1; i 0) 292 | 293 | ret = 1 ; 294 | 295 | return ret; 296 | } 297 | 298 | void EncogStrCatRuntime(char *base, double t,size_t len) 299 | { 300 | INT minutes, hours; 301 | double seconds; 302 | seconds = t; 303 | hours = (INT)(seconds/3600); 304 | seconds -= hours*3600; 305 | minutes = (INT)seconds/60; 306 | seconds -= minutes*60; 307 | sprintf(base+strlen(base),"%02i:%02i:",hours,minutes); 308 | if( seconds<10 ) { 309 | EncogStrCatChar(base,'0',len); 310 | } 311 | sprintf(base+strlen(base),"%2.4f",seconds); 312 | } 313 | 314 | unsigned long EncogUtilHash(unsigned char *str) 315 | { 316 | unsigned long hash = 5381; 317 | int c; 318 | 319 | while ( (c = (*(str++))) ) 320 | { 321 | hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ 322 | } 323 | 324 | return hash; 325 | } 326 | 327 | #ifndef _MSC_VER 328 | static void set_unbuffered ( void ) 329 | { 330 | tcgetattr( STDIN_FILENO, &oldterm ); 331 | newterm = oldterm; 332 | newterm.c_lflag &= ~( ICANON | ECHO ); 333 | tcsetattr( STDIN_FILENO, TCSANOW, &newterm ); 334 | } 335 | 336 | static void set_buffered ( void ) 337 | { 338 | tcsetattr( STDIN_FILENO, TCSANOW, &oldterm ); 339 | } 340 | 341 | int kbhit ( void ) 342 | { 343 | int result; 344 | fd_set set; 345 | struct timeval tv; 346 | 347 | FD_ZERO(&set); 348 | FD_SET(STDIN_FILENO,&set); /* watch stdin */ 349 | tv.tv_sec = 0; 350 | tv.tv_usec = 0; /* don't wait */ 351 | 352 | /* quick peek at the input, to see if anything is there */ 353 | set_unbuffered(); 354 | result = select( STDIN_FILENO+1,&set,NULL,NULL,&tv); 355 | set_buffered(); 356 | 357 | return result == 1; 358 | } 359 | #endif 360 | 361 | -------------------------------------------------------------------------------- /encog-core/util_file.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | void EncogFileWriteValueInt(FILE *fp, char *name, INT value) 27 | { 28 | char buffer[MAX_STR]; 29 | *buffer = 0; 30 | EncogStrCatInt(buffer,value,MAX_STR); 31 | fputs(name,fp); 32 | fputc('=',fp); 33 | fputs(buffer,fp); 34 | fputs("\n",fp); 35 | } 36 | 37 | void EncogFileWriteValueBoolean(FILE *fp, char *name, INT value) 38 | { 39 | fputs(name,fp); 40 | fputc('=',fp); 41 | fputc(value?'T':'F',fp); 42 | fputs("\n",fp); 43 | } 44 | 45 | void EncogFileWriteValueIntArray(FILE *fp, char *name, INT *a, INT count) 46 | { 47 | char buffer[MAX_STR]; 48 | INT i; 49 | 50 | fputs(name,fp); 51 | fputc('=',fp); 52 | for(i=0;i0 ) 55 | { 56 | fputc(',',fp); 57 | } 58 | *buffer = 0; 59 | EncogStrCatInt(buffer,a[i],MAX_STR); 60 | fputs(buffer,fp); 61 | } 62 | fputs("\n",fp); 63 | } 64 | 65 | void EncogFileWriteValueDouble(FILE *fp, char *name, REAL value) 66 | { 67 | fputs(name,fp); 68 | fputc('=',fp); 69 | fprintf(fp,"%.20g",value); 70 | fputs("\n",fp); 71 | } 72 | 73 | void EncogFileWriteValueDoubleArray(FILE *fp, char *name, REAL *a, INT count) 74 | { 75 | INT i, lineCount; 76 | 77 | fputs(name,fp); 78 | fputc('=',fp); 79 | 80 | if( count>2048 ) { 81 | fprintf(fp,"##%i\n##double#%i\n",0,count); 82 | lineCount = 0; 83 | 84 | for(i=0;i0 ) 87 | { 88 | fputc(',',fp); 89 | } 90 | fprintf(fp,"%.20g",a[i]); 91 | lineCount++; 92 | if( lineCount>2048 ) { 93 | lineCount = 0; 94 | fprintf(fp,"\n"); 95 | } 96 | } 97 | fputs("\n##end\n",fp); 98 | } else { 99 | for(i=0;i0 ) 102 | { 103 | fputc(',',fp); 104 | } 105 | fprintf(fp,"%.20g",a[i]); 106 | } 107 | fputs("\n",fp); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /encog-core/util_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Encog(tm) Core v1.0 - ANSI C Version 3 | * http://www.heatonresearch.com/encog/ 4 | * http://code.google.com/p/encog-java/ 5 | 6 | * Copyright 2008-2012 Heaton Research, Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For more information on Heaton Research copyrights, licenses 21 | * and trademarks visit: 22 | * http://www.heatonresearch.com/copyright 23 | */ 24 | #include "encog.h" 25 | 26 | int EncogStrPopLine(char *line, char *arg, int start, int len) 27 | { 28 | char *argPtr,*linePtr; 29 | int stop; 30 | 31 | argPtr = arg; 32 | linePtr = line + start; 33 | stop = len-1; 34 | 35 | while( *linePtr && (argPtr-arg) maxValue) v[i] = maxValue; 165 | if (v[i] < -maxValue) v[i] = -maxValue; 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # detect OS 2 | OSUPPER = $(shell uname -s 2>/dev/null | tr [:lower:] [:upper:]) 3 | OSLOWER = $(shell uname -s 2>/dev/null | tr [:upper:] [:lower:]) 4 | 5 | # 'linux' is output for Linux system, 'darwin' for OS X 6 | DARWIN = $(strip $(findstring DARWIN, $(OSUPPER))) 7 | ifneq ($(DARWIN),) 8 | SNOWLEOPARD = $(strip $(findstring 10.6, $(shell egrep "10\.6" /System/Library/CoreServices/SystemVersion.plist))) 9 | LION = $(strip $(findstring 10.7, $(shell egrep "10\.7" /System/Library/CoreServices/SystemVersion.plist))) 10 | endif 11 | 12 | # Define arch to use 13 | ARCH := $(shell getconf LONG_BIT) 14 | 15 | RPI_FLAGS := 16 | CPP_FLAGS_32 := -m32 17 | CPP_FLAGS_64 := -m64 18 | #use CUDA? 19 | ifeq ($(CUDA),1) 20 | 21 | endif 22 | 23 | # Encog Paths 24 | LIB_IDIR =./encog-core/ 25 | CMD_IDIR =./encog-cmd/ 26 | LIB_ODIR=./obj-lib 27 | CMD_ODIR=./obj-cmd 28 | LDIR =./lib 29 | 30 | # CUDA Paths 31 | ifeq ($(CUDA),1) 32 | CUDA_INSTALL_PATH ?= /usr/local/cuda 33 | ifdef cuda-install 34 | CUDA_INSTALL_PATH := $(cuda-install) 35 | endif 36 | endif 37 | 38 | _LIB_DEPS = encog.h 39 | LIB_DEPS = $(patsubst %,$(LIB_IDIR)/%,$(_LIB_DEPS)) 40 | 41 | _LIB_OBJ = activation.o errorcalc.o network_io.o util.o util_str.o data.o errors.o network.o pso.o util_file.o vector.o encog.o nm.o object.o rprop.o hash.o train.o 42 | LIB_OBJ = $(patsubst %,$(LIB_ODIR)/%,$(_LIB_OBJ)) 43 | 44 | _CMD_DEPS = encog-cmd.h 45 | CMD_DEPS = $(patsubst %,$(CMD_IDIR)/%,$(_CMD_DEPS)) 46 | 47 | _CMD_OBJ = encog-cmd.o cuda_test.o node_unix.o 48 | CMD_OBJ = $(patsubst %,$(CMD_ODIR)/%,$(_CMD_OBJ)) 49 | 50 | ifeq ($(CUDA),1) 51 | _CMD_CUOBJ = cuda_vecadd.cu.o 52 | _LIB_CUOBJ = encog_cuda.cu.o cuda_eval.cu.o 53 | CMD_CUOBJ = $(patsubst %,$(CMD_ODIR)/%,$(_CMD_CUOBJ)) 54 | LIB_CUOBJ = $(patsubst %,$(LIB_ODIR)/%,$(_LIB_CUOBJ)) 55 | endif 56 | 57 | ENCOG_LIB = $(LDIR)/encog.a 58 | 59 | CC=gcc 60 | NVCC := $(CUDA_INSTALL_PATH)/bin/nvcc 61 | CFLAGS=-I$(LIB_IDIR) -fopenmp -std=gnu99 -pedantic -O3 -Wall $(CPP_FLAGS_$(ARCH)) 62 | NVCCFLAGS = -I$(LIB_IDIR) $(CPP_FLAGS_$(ARCH)) 63 | MKDIR_P = mkdir -p 64 | LIBS=-lm 65 | 66 | ifeq ($(CUDA),1) 67 | CFLAGS+= -DENCOG_CUDA=1 68 | CFLAGS+= -I$(CUDA_INSTALL_PATH)/include 69 | endif 70 | 71 | # Libs 72 | ifeq ($(CUDA),1) 73 | ifneq ($(DARWIN),) 74 | LIB := -L$(CUDA_INSTALL_PATH)/lib 75 | else 76 | ifeq ($(ARCH),64) 77 | LIB := -L$(CUDA_INSTALL_PATH)/lib64 78 | else 79 | LIB := -L$(CUDA_INSTALL_PATH)/lib 80 | endif 81 | endif 82 | 83 | LIB+= -lcudart 84 | endif 85 | 86 | $(CMD_ODIR)/%.cu.o : ./encog-cmd/%.cu $(CMD_DEPS) 87 | ${MKDIR_P} $(CMD_ODIR) 88 | $(NVCC) -o $@ -c $< $(NVCCFLAGS) 89 | 90 | $(LIB_ODIR)/%.cu.o : ./encog-core/%.cu $(LIB_DEPS) 91 | ${MKDIR_P} $(LIB_ODIR) 92 | $(NVCC) -o $@ -c $< $(NVCCFLAGS) 93 | 94 | $(LIB_ODIR)/%.o: ./encog-core/%.c $(LIB_DEPS) 95 | ${MKDIR_P} $(LIB_ODIR) 96 | $(CC) -c -o $@ $< $(CFLAGS) 97 | 98 | $(CMD_ODIR)/%.o: ./encog-cmd/%.c $(CMD_DEPS) 99 | ${MKDIR_P} $(CMD_ODIR) 100 | $(CC) -c -o $@ $< $(CFLAGS) 101 | 102 | encog: $(CMD_OBJ) $(CMD_CUOBJ) $(ENCOG_LIB) 103 | $(CC) -o $@ $^ $(CFLAGS) -lm $(ENCOG_LIB) $(LIB) 104 | 105 | $(ENCOG_LIB): $(LIB_OBJ) $(LIB_CUOBJ) 106 | ${MKDIR_P} $(LDIR) 107 | ar rcs $(ENCOG_LIB) $(LIB_OBJ) $(LIB_CUOBJ) 108 | 109 | .PHONY: clean 110 | clean: 111 | rm -f $(LIB_ODIR)/*.o 112 | rm -f $(CMD_ODIR)/*.o 113 | rm -f $(LDIR)/*.a 114 | --------------------------------------------------------------------------------