Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes random number generator on windows. Fixes #103 #140

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions svm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include <stdarg.h>
#include <limits.h>
#include <locale.h>
#ifdef _WIN32
#include <climits>
#endif
#include "svm.h"
int libsvm_version = LIBSVM_VERSION;
typedef float Qfloat;
Expand Down Expand Up @@ -38,6 +41,33 @@ static inline double powi(double base, int times)
#define TAU 1e-12
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))

// New function to ensure the same behaviour for random number generation on windows and linux
inline int myrand() {
// In MS Visual Studio (2012) RAND_MAX = 0x7FFF (15bit) = 32767
// In Linux GCC (4.6) 32bits RAND_MAX = 0x7FFFFFFF (31bit) = 2147483647
// In Linux GCC (4.6) 64bits RAND_MAX = 0x7FFFFFFFFFFFFFFF (63 bits) = 9223372036854775807
// so in MS Visual Studio we need to call rand() several times to always ensure the same random number range than in Linux GCC
#if RAND_MAX != INT_MAX
#if INT_MAX == 0x7FFFFFFF
// make a 31bit random number by using several 15bit rand()
// info("Fixing random number generator for 32 bits ints. RAND_MAX=%d INT_MAX=%d\n", RAND_MAX, INT_MAX);
return ( (__int32)rand() << 16) + ( (__int32)rand() << 1) + ( (__int32)rand() >> 14);
#elif INT_MAX == 0x7FFFFFFFFFFFFFFF
// make a 63bit random number by using several 15bit rand()
// info("Fixing random number generator for 64 bits ints. RAND_MAX=%d INT_MAX=%d\n", RAND_MAX, INT_MAX);
return ( ( (__int64)rand() << 48) + ( (__int64)rand() << 33) + ( (__int64)rand() << 18) + ( (__int64)rand() << 3) + ( (__int64)rand() >> 12) );
#else
//fallback - should never happen on 32 or 64 bits windows systems
info("Random number generator is not fixed for this system. Please report issue. RAND_MAX=%d INT_MAX=%d\n", RAND_MAX, INT_MAX);
exit(1);
#endif
#else
// In Linux GCC (4.6) 32bits RAND_MAX = 0x7FFFFFFF (31bit) or 64bits RAND_MAX = 0x7FFFFFFFFFFFFFFF (63 bits)
// nothing special to do
return rand();
#endif
}

static void print_string_stdout(const char *s)
{
fputs(s,stdout);
Expand Down Expand Up @@ -1903,7 +1933,7 @@ static void svm_binary_svc_probability(
for(i=0;i<prob->l;i++) perm[i]=i;
for(i=0;i<prob->l;i++)
{
int j = i+rand()%(prob->l-i);
int j = i+myrand()%(prob->l-i);
swap(perm[i],perm[j]);
}
for(i=0;i<nr_fold;i++)
Expand Down Expand Up @@ -2368,7 +2398,7 @@ void svm_cross_validation(const svm_problem *prob, const svm_parameter *param, i
for (c=0; c<nr_class; c++)
for(i=0;i<count[c];i++)
{
int j = i+rand()%(count[c]-i);
int j = i+myrand()%(count[c]-i);
swap(index[start[c]+j],index[start[c]+i]);
}
for(i=0;i<nr_fold;i++)
Expand Down Expand Up @@ -2405,7 +2435,7 @@ void svm_cross_validation(const svm_problem *prob, const svm_parameter *param, i
for(i=0;i<l;i++) perm[i]=i;
for(i=0;i<l;i++)
{
int j = i+rand()%(l-i);
int j = i+myrand()%(l-i);
swap(perm[i],perm[j]);
}
for(i=0;i<=nr_fold;i++)
Expand Down
Binary file modified windows/libsvm.dll
Binary file not shown.
Binary file modified windows/libsvmread.mexw64
Binary file not shown.
Binary file modified windows/libsvmwrite.mexw64
Binary file not shown.
Binary file modified windows/svm-predict.exe
Binary file not shown.
Binary file modified windows/svm-scale.exe
Binary file not shown.
Binary file modified windows/svm-toy.exe
Binary file not shown.
Binary file modified windows/svm-train.exe
Binary file not shown.
Binary file modified windows/svmpredict.mexw64
Binary file not shown.
Binary file modified windows/svmtrain.mexw64
Binary file not shown.