728x90
비주얼 스튜디오 2019 커뮤니티 버전을 받았습니다.
그리고 Gnuplot 빌드를 도전해 보기로 합니다.
우선 소스를 다음 사이트에서 받았습니다.
그리고 git 명령어가 없으면 다음 사이트에서 받아서 Path 에 넣어 주도록 합니다.
저는 포터블을 받았습니다.
마지막으로 gnuplot git 사이트에서 현재 버전을 다음과 같이 다운로드 받습니다.
git clone https://github.com/gnuplot/gnuplot.git
그리고 나서, .git 폴더를 다음과 같이 옮겨 주었습니다.
현재 버전은 오류가 납니다. 수정 버전인 파일을
아래 위치에 복사해 넣어 줍니다.
~\gnuplot-6.0.0\term
준비과정을 끝난 것 같으니, cmd 창을 열고서 다음 디렉토리를 검색 해 봅시다.
앞서 말했지만 비주얼스튜디오 2019를 설치 했습니다(커뮤니티버전)
dir "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\"
위의 명령을 다음과 같이 실행 해 보면
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat"
다음과 같은 리스트가 나타 날 것입니다.
요즘은 64비트가 대세니 음... 아래서 두번째꺼로
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 8.1
환경이 좀 안 맞나 보네요.. 그냥 첫번째 걸로 하겠습니다.
다 되었으니, 빌드를 수행 해 보도록 하겠습니다.
nmake -f Makefile clean && nmake -f Makefile
그리고 다시 빌드를 수행 해 봅니다.
마지막 링크 시에 다음과 같은 오류를 만납니다.
filters.obj : error LNK2019: bisect_hitsharpen 함수에서 참조되는 확인할 수 없는 외부 기호
wgnuplot.exe : fatal error LNK1120: 1개의 확인할 수 없는 외부 참조입니다.
NMAKE : fatal error U1077: '"~\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.EXE"' : '0x460' 반환 코드입니다.
Stop.
일단 filters.c 파일에 있는 sharpen 함수를 다음과 같이 처리 해 줄 수 있습니다.
void
sharpen(struct curve_points *plot)
{
struct axis *y_axis = &axis_array[plot->y_axis];
int newcount = plot->p_count;
struct coordinate *p;
/* Restrictions */
if (parametric || polar)
return;
/* Make more than enough room for new points */
cp_extend(plot, 1.5 * plot->p_count);
p = plot->points;
/* We expect that sharpened peaks may go to +/- Infinity
* and in fact the plot may already contain such points.
* Because these were tagged UNDEFINED in store_and_update_range()
* they will be lost when the points are sorted.
* As a work-around we look for these and flag them OUTRANGE instead.
* If there are other UNDEFINED points we set y to 0 so that they
* do not cause the f'' approximation to blow up.
*/
for (int i = 0; i < plot->p_count; i++) {
if (p[i].type == UNDEFINED) {
if (p[i].y >= VERYLARGE) {
p[i].type = OUTRANGE;
p[i].y = VERYLARGE;
} else if (p[i].y <= -VERYLARGE) {
p[i].type = OUTRANGE;
p[i].y = -VERYLARGE;
} else
p[i].y = 0;
}
}
/* Look for minima in a sliding window */
/* This is a very simple test; it may not be sufficient
* f(i) is lower than its neighbors
* f''(x) is negative on at least one side
*/
for (int i = 4; i < plot->p_count-4; i++) {
TBOOLEAN criterion = FALSE;
criterion = (fpp_SG5(&p[i-2]) < 0 || fpp_SG5(&p[i+2]) < 0);
if (p[i].y <= p[i-1].y && p[i].y <= p[i+1].y
&& p[i].y <= p[i-2].y && p[i].y <= p[i+2].y
&& criterion)
{
double hit_x = p[i].x;
double hit_y = p[i].y;
=========> 아래 꺼 주석 처리
//bisect_hit( plot, BISECT_MINIMIZE, &hit_x, &hit_y, p[i-1].x, p[i+1].x );
p[newcount] = p[i]; /* copy any other properties */
p[newcount].x = hit_x;
p[newcount].y = hit_y;
/* Use sharpened peak for autoscaling only if it approaches zero,
* not if it's heading towards +/- Infinity!
*/
if (fabs(hit_y) < 1.e-7 && !y_axis->log)
autoscale_one_point(y_axis, hit_y);
if (!inrange(hit_y, y_axis->min, y_axis->max))
p[newcount].type = OUTRANGE;
else
p[newcount].type = INRANGE;
if (debug)
FPRINTF((stderr, "\tbisect min [%4g %g]\tto [%4g %4g]\n",
p[i].x, p[i].y, hit_x, hit_y));
newcount++;
}
}
/* Equivalent search for maxima */
for (int i = 4; i < plot->p_count-4; i++) {
TBOOLEAN criterion = FALSE;
if (p[i].type == UNDEFINED || p[i-1].type == UNDEFINED || p[i+1].type == UNDEFINED)
continue;
criterion = (fpp_SG5(&p[i-2]) > 0 || fpp_SG5(&p[i+2]) > 0);
if (p[i].y >= p[i-1].y && p[i].y >= p[i+1].y
&& p[i].y >= p[i-2].y && p[i].y >= p[i+2].y
&& criterion)
{
double hit_x = p[i].x;
double hit_y = p[i].y;
=========> 아래 꺼 주석 처리
//bisect_hit( plot, BISECT_MAXIMIZE, &hit_x, &hit_y, p[i-1].x, p[i+1].x );
p[newcount] = p[i]; /* copy any other properties */
p[newcount].x = hit_x;
p[newcount].y = hit_y;
if (fabs(hit_y) < 1.e-7 && !y_axis->log)
autoscale_one_point(y_axis, hit_y);
if (!inrange(hit_y, y_axis->min, y_axis->max))
p[newcount].type = OUTRANGE;
else
p[newcount].type = INRANGE;
if (debug)
FPRINTF((stderr, "\tbisect max [%4g %g]\tto [%4g %4g]\n",
p[i].x, p[i].y, hit_x, hit_y));
newcount++;
}
}
/* Move new points into proper order */
if (newcount > plot->p_count) {
plot->p_count = newcount;
gp_qsort(plot->points, newcount, sizeof(struct coordinate), compare_x);
}
}
아니면 다음과 같이 정의 되지 않을 함수를 넣어 주도록 했습니다.
#define PHIM1 0.618034
#define EPS 3.0E-8
static void
bisect_hit(struct curve_points *plot, t_bisection_target target,
double *xhit, double *yhit, double xlow, double xhigh)
{
double x0, x1, x2, x3;
double f1, f2; /* f1 = f(x1), f2 = f(x2) */
struct value a;
TBOOLEAN left;
double epsilon = (target == BISECT_MATCH) ? EPS : 1.e-14;
x0 = xlow;
x3 = xhigh;
if (fabs(xhigh - *xhit) > fabs(*xhit - xlow)) {
x1 = *xhit;
x2 = *xhit + (1.0-PHIM1) * (xhigh - *xhit);
} else {
x2 = *xhit;
x1 = *xhit - (1.0-PHIM1) * (*xhit - xlow);
}
Gcomplex( &(plot->plot_function.dummy_values[0]), x1, 0 );
evaluate_at(plot->plot_function.at, &a);
f1 = real(&a);
Gcomplex( &(plot->plot_function.dummy_values[0]), x2, 0 );
evaluate_at(plot->plot_function.at, &a);
f2 = real(&a);
/* Iterate until convergence of estimated xhit */
while (fabs(x3-x0) > epsilon * (fabs(x1) + fabs(x2))) {
if (target == BISECT_MINIMIZE)
left = (f2 < f1);
else if (target == BISECT_MAXIMIZE)
left = (f2 > f1);
else /* minimize difference of f(x) from *yhit */
left = (fabs(f2 - *yhit) < fabs(f1 - *yhit));
if (left) {
x0 = x1;
x1 = x2;
x2 = PHIM1*x2 + (1.0-PHIM1)*x3;
f1 = f2;
Gcomplex( &(plot->plot_function.dummy_values[0]), x2, 0 );
evaluate_at(plot->plot_function.at, &a);
f2 = real(&a);
} else {
x3 = x2;
x2 = x1;
x1 = PHIM1*x1 + (1.0-PHIM1)*x0;
f2 = f1;
Gcomplex( &(plot->plot_function.dummy_values[0]), x1, 0 );
evaluate_at(plot->plot_function.at, &a);
f1 = real(&a);
}
if ((fabs(x1) + fabs(x2)) < epsilon)
break;
}
/* Update and return hit coordinates */
if (target == BISECT_MINIMIZE)
left = (f2 < f1);
else if (target == BISECT_MAXIMIZE)
left = (f2 > f1);
else /* minimize difference of f(x) from *yhit */
left = (fabs(f2 - *yhit) < fabs(f1 - *yhit));
if (left) {
*xhit = x2;
*yhit = f2;
} else {
*xhit = x1;
*yhit = f1;
}
}
빌드가 다 되면 다음과 같이 실행 파일이 생성 된 것을 확인 할 수 있습니다.
버그리포트를 썼는 데.. 고쳐지겠죠?
이상.
728x90
'프로그래밍' 카테고리의 다른 글
C# app.config ? web.config? 두 파일의 호환성 (0) | 2024.02.08 |
---|---|
Getter, Setter와 리플렉션 (0) | 2024.02.02 |
디자인패턴 커닝지 (0) | 2023.04.21 |
[자바] 사용자의 터치로 완벽한 원 그리기 (0) | 2023.04.20 |
MinGW 정적 동적 라이브러리 (0) | 2023.04.19 |