【发布时间】:2018-07-03 21:06:38
【问题描述】:
我需要为我的实习估算 ODE 之后神经元的放电率。我一开始是用 python 编写代码,它运行得很好,但是为了获得更好的性能,我的主管告诉我用 C 编写相同的代码。但是,我从来没有用 C 编写过代码,所以我是一个非常初学者和我想要的文件射击率的值全为零...有人可以帮助我吗?
非常感谢
这是我的python代码:
import numpy as np
import matplotlib.pyplot as plt
from math import cos, sin, sqrt, pi, exp as cos, sin, sqrt, pi, exp
#parameters
eps = 0.05
f = 0.215
mu = 1.1
D = 0.001
DeltaT = 0.01
timewindow = 40
num_points = int(timewindow/DeltaT)
T = np.linspace(0, timewindow, num_points)
#signal
s = [sin(2*3.14*f*t) for t in T]
N=30000
compteur=np.zeros(num_points)
v = np.zeros((num_points,N))
samples = np.random.normal(0, 1, (num_points,N))
for i in range(1,num_points):
for j in range(N):
v[i,j] = v[i-1,j] + DeltaT *(-v[i-1,j]+ mu + eps*s[i-1]) + \
sqrt(2*D*DeltaT)*samples[i,j]
if v[i,j]>1:
v[i,j]=0
compteur[i]+=1/DeltaT/N
plt.plot(T,compteur)
plt.show()
这是我在 C 中的“翻译”:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PI 3.1415926536
float s(float x, float);
double AWGN_generator();
FILE* fopen(const char* nomDuFichier, const char* modeOuverture);
int fclose(FILE* pointeurSurFichier);
int main(int argc, char *argv[])
{
//parameters
double eps = 0.05;
float f = 0.215 ;
double mu = 1.1 ;
double D = 0.001 ;
int time_window = 90;
int num_points = 1000;
long num_neurons = 1000;
double deltaT = time_window/num_points;
int i ;
//time
double Time[num_points] ;
Time[0]= 0.0;
for (i = 1 ; i < num_points ; i++ )
{ Time[i] = Time[i-1] + deltaT;
}
//opening file for saving data
FILE* fichier = NULL;
fichier = fopen("challala.txt", "w");
if (fichier != NULL)
{
double v[num_points][num_neurons] ;
memset(v, 0, num_points*num_neurons*sizeof(long) );
long compteur[num_points];
memset( compteur, 0, num_points*sizeof(long) );
int pos_1 ;
int pos_2 ;
//Euler's method
for (pos_1 = 1 ; pos_1 < num_points ; pos_1 ++)
{
for (pos_2 = 0 ; pos_2<num_neurons ; pos_2 ++)
{
float t = Time[pos_1-1] ;
v[pos_1][pos_2] = v[pos_1-1][pos_2] + deltaT *(-v[pos_1-1]
[pos_2]+ mu + eps*s(t, f))+ sqrt(2*D*deltaT)*AWGN_generator();
if (v[pos_1][pos_2]>1)
{
v[pos_1][pos_2]=0 ;
compteur[pos_1]+=1/deltaT/num_neurons ;
}
}
fprintf(fichier, "%ld",compteur[pos_1]);
}
fclose(fichier);
printf("ca a marche test.txt");
}
else
{
// On affiche un message d'erreur si on veut
printf("Impossible d'ouvrir le fichier test.txt");
}
return 0;
}
float s(float x, float f)
{
return sin(2*M_PI*f*x);
}
double AWGN_generator()
{/* Generates additive white Gaussian Noise samples with zero mean and a
standard deviation of 1. */
double temp1;
double temp2;
double result;
int p;
p = 1;
while( p > 0 )
{
temp2 = ( rand() / ( (double)RAND_MAX ) ); /* rand() function generates an
integer between 0 and
RAND_MAX,
which is defined in
stdlib.h.
*/
if ( temp2 == 0 )
{// temp2 is >= (RAND_MAX / 2)
p = 1;
}// end if
else
{// temp2 is < (RAND_MAX / 2)
p = -1;
}// end else
}// end while()
temp1 = cos( ( 2.0 * (double)PI ) * rand() / ( (double)RAND_MAX ) );
result = sqrt( -2.0 * log( temp2 ) ) * temp1;
return result; // return the generated random sample to the caller
}
【问题讨论】:
-
如果你以前从来没有用过 C 代码,那你可能会不知所措,老师给了你不好的建议。 Python 解决方案可能足够好,这确实足够好。如果您希望能够为您的 Python 程序生成优化且运行良好的 C 版本,您需要真正了解 C 并具有编程经验。
-
第一条评论是不要把
double和float混在一起。如果您可以使用double:所有人都可以使用它。第二条评论是double deltaT = time_window/num_points;执行整数除法,因为两个操作数都是int类型,所以90 / 1000将是0。像double deltaT = (double)time_window/num_points;一样投射它 -
double v[num_points][num_neurons]; memset(v, 0, num_points * num_neurons * sizeof(long));是可疑的。建议double v[num_points][num_neurons] = {0};。或者用memset(v, 0, sizeof v);填零你真的想用memset(); -
添加到@Someprogrammerdude - 如果 Python 不够“好”,您可以使用 Java 或其他一些内存/类型/其他安全的编译语言,这将为您省去很多麻烦与 C.
-
compteur[pos_1] += 1 / deltaT / num_neurons;不清楚其 FP 数学递增整数。也许那总是compteur[pos_1] += something_less_than_1;
标签: c