Wolfram
Mathematica
8의 신기능: 통합된 C 작업 흐름
◄
이전
|
다음
►
소프트웨어 개발
컴파일된 함수를 이용한 독립 실행 파일 제작
독립 실행 파일을 생성하고 배포할 수 있습니다.
In[3]:=
X
lopassmainSrc = " #include \"stdio.h\" #include \"stdlib.h\" #include \"lopass.h\" #include \"WolframRTL.h\" static WolframLibraryData libData = 0; int main() { int err = 0; mint i, type, rank, nelems, *dims; double *data; MTensor x, y; double dt; double RC; libData = WolframLibraryData_new(WolframLibraryVersion); /* read x */ type = MType_Real; rank = 1; dims = (mint*)malloc(rank * sizeof(mint)); scanf(\" %d\", &nelems); dims[0] = nelems; err = (*(libData->MTensor_new))(type, rank, dims, &x); if (err) return 1; free(dims); data = (*(libData->MTensor_getRealData))(x); for(i = 0; i < nelems; i++) { scanf(\" %lf\", &(data[i])); } /* read dt */ scanf(\" %lf\", &dt); /* read RC */ scanf(\" %lf\", &RC); err = Initialize_lopass(libData); y = 0; err = lopass(libData, x, dt, RC, &y); printf(\"%d\\n\", err); if(0 == err){ dims = libData->MTensor_getDimensions(y); nelems = dims[0]; data = (*(libData->MTensor_getRealData))(y); printf(\"%d\\n\", nelems); for(i = 0; i < nelems; i++) printf(\"%f\\n\", data[i]); } Uninitialize_lopass(libData); return 0; } ";
먼저 관심있는 함수를 정의합니다.
In[1]:=
X
lopass = Compile[{{x, _Real, 1}, dt, RC}, Module[{a = dt/(RC + dt), yprev = First[x], yi}, Table[yi = a*x[[i]] + (1 - a)*yprev; yprev = yi; yi, {i, 1, Length[x]}]]];
C 코드와 헤더 파일을 생성합니다.
In[2]:=
X
targetDir = CreateDirectory[] fnSource = FileNameJoin[{targetDir, "lopass.c"}]; Export[fnSource, lopass];
Out[2]=
생성된 코드를 호출하기 위한 C main 함수를 작성합니다.
In[4]:=
X
lopassmainSrcFile = FileNameJoin[{targetDir, "lopassMain.c"}]; Export[lopassmainSrcFile, lopassmainSrc, "Text"]
Out[4]=
Wolfram Runtime Library를 이용하여 실행 파일을 컴파일합니다.
In[5]:=
X
Needs["CCompilerDriver`"]; lopassExe = CreateExecutable[{fnSource, lopassmainSrcFile}, "lowpass", "TargetDirectory" -> targetDir, "Libraries" -> "WolframRTL_Static_Minimal"]
Out[5]=
이제 프로그램을 배포하고
Mathematica
밖에서 실행시킬 수 있습니다. 또한 검증 및 시범을 위해 Mathematica에서도 실행할 수 있습니다. 그리고 여러가지 주파수 성분으로 구성된 입력 신호를 만들어 본 것입니다.
In[6]:=
X
input = Table[Sin[x] + Sin[x*10] + Sin[x*50], {x, 0, 10, 0.01}]; ListPlot[input, Joined -> True]
Out[6]=
입력 신호를 실행에 사용할 파일 형식으로 변환합니다.
In[7]:=
X
inputText = StringJoin[ToString[Length[input]], "\n", Riffle[ToString /@ input, "\n"],(* dt*)"0.01",(*RC *)"0.3"]; inputFile = FileNameJoin[{targetDir, "input.txt"}]; Export[inputFile, inputText, "Text"]
Out[7]=
실행 파일을 실행하고 출력을 해석하여 원래의 신호 (파란색)과 저역 통과 필터 처리된 신호 (빨간색)의 그래프를 함께 플롯합니다.
In[8]:=
X
SetDirectory[targetDir]; outputLines = Import["!" <> lopassExe <> " < " <> inputFile, "Lines"]; ResetDirectory[]; output = ToExpression /@ outputLines; output = If[ Length[output] > 1 && First[output] === 0 && output[[2]] === Length[output] - 2, Drop[output, 2], $Failed ]; ListPlot[{input, output}, Joined -> True]
Out[8]=