質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Basic 6.0

Microsoft Visual Basic 6.0(VB6)とはCOMプログラミングのためにMicrosoftが提供したプログラミング言語とintegrated develpment enviornment(IDE)のことです。

Q&A

解決済

2回答

6650閲覧

プログラミングの書き換え Visual basic→C言語

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Basic 6.0

Microsoft Visual Basic 6.0(VB6)とはCOMプログラミングのためにMicrosoftが提供したプログラミング言語とintegrated develpment enviornment(IDE)のことです。

0グッド

1クリップ

投稿2016/05/25 07:48

###前提・実現したいこと
visual basicで書いてあるプログラムをC言語に書き換えています
高速フーリエ変換を行い数値を入力することで画像が表示されるプログラムを作ろうとしています
一通り書き換えてみましたが変な数値が表示され画像が表示されません
どこをどのように書き換えたらプログラムが動くのか教えていただきたいです
また,必要のない部分があれば教えていただきたいです
入力する数値はデータ数n=512,α=0.05,β=2,γ=0.1,走査範囲=20,ガウス乱数1(あり),異方性=0(なし)です.

###発生している問題・エラーメッセージ
画像が表示されない
おそらくスペクトル作成の部分の書き換えができていないと思われる

###該当のソースコード
visualbasicここに言語を入力
ここにご自身が実行したソースコードを書いてください
Option Explicit
Dim i As Integer, j As Integer
Dim N As Integer
Dim ParaA1 As Single, ParaB1 As Single, ParaC1 As Single
Dim A() As Single, B() As Single, Sp() As Single, Sp1() As Single
Dim AX() As Single, BY() As Single
Dim Z() As Single
Dim region As Single, QS As Single
Dim Zmax As Single, ZMin As Single

Private Sub cmdCalc_Click()
' ******************************************
' 2次元フーリエ係数を算出する
' データ数を選択後,計算開始
' ******************************************
Dim flag As Single, flag2 As Single
If optDataNum(0) = True Then
N = 512
ElseIf optDataNum(1) = True Then
N = 256
Else
N = 128
End If
ReDim A(N - 1, N - 1), B(N - 1, N - 1)
ReDim AX(N - 1, N - 1), BY(N - 1, N - 1)
ReDim Sp(N - 1, N - 1)
ReDim Z(N - 1, N - 1)

If optSR(0) = True Then region = 20 ElseIf optSR(1) = True Then region = 2 Else region = 0.5 End If

'ガウス

If chkGauss.Value Then flag = 1 Else flag = 0 End If

'異方性

If Check1.Value Then flag2 = 1 Else flag2 = 0 End If ParaA1 = CSng(txtpara(0).Text) ParaB1 = CSng(txtpara(1).Text) ParaC1 = CSng(txtpara(2).Text) QS = -1

' スペクトル作成
frmBusy.ProgressBar1.Max = 4 * N
frmBusy.ProgressBar1.Min = 0
frmBusy.lblBusy = "計算中…"
frmBusy.Show
MakeSp N, ParaA1, ParaB1, ParaC1, A(), B(), region, flag, flag2, Sp()

For i = 0 To N - 1 For j = 0 To N - 1 Sp(i, j) = (A(i, j) ^ 2 + B(i, j) ^ 2) / 0.25 AX(i, j) = A(i, j) BY(i, j) = B(i, j) Next j Next i DrawSimage frmSImage.picSImage, N, Sp() fft2DMain N, -1, AX(), BY() ZMin = AX(0, 0) For i = 0 To N - 1 For j = 0 To N - 1 If AX(i, j) < ZMin Then ZMin = AX(i, j) Next j Next i Zmax = AX(0, 0) For i = 0 To N - 1 For j = 0 To N - 1 Z(i, j) = AX(i, j) + Abs(ZMin) If Z(i, j) > Zmax Then Zmax = Z(i, j) Next j Next i DrawData frmImage.picImage, N, Z(), Zmax frmImage.Show

End Sub

Private Sub cmdQuit_Click()
End
End Sub

Private Sub mnuSavea_Click()


' 2次元複素フーリエ係数作成
' ******************************************
Dim i As Integer, j As Integer
Dim PI As Single, phase As Single, rad As Single, phaseS As Single
Dim kx As Single, ky As Single, K As Single
Dim Spec As Single, gauss As Single, lim As Single, Spec2 As Single, Rnd1 As Single, Rnd2 As Single

'波長をカットする領域
If region = 2 Then
lim = 50
ElseIf region = 0.5 Then
lim = 50
Else
lim = 50
End If

'SP面を創成
Randomize 4
PI = 4 * Atn(1)
For i = 1 To N / 2 - 1
For j = 1 To N / 2 - 1

If i <> 0 Or j <> 0 Then kx = i / (region) ky = j / (region) K = Sqr(kx ^ 2 + ky ^ 2) Rnd1 = Rnd Rnd2 = Rnd gauss = Abs(Sqr(-2 * Log(Rnd1)) * Cos(2 * PI * Rnd2)) '**************************** 'gaussの上限,下限 (04.6.20) If gauss < 0.001 Then gauss = 0.001 ElseIf gauss > 10 Then gauss = 10 End If '**************************** Spec = ParaA1 * (K ^ (-ParaB1)) Spec2 = Spec * (gauss ^ flag) rad = Sqr(Spec2 * 0.25) If Sqr(kx ^ 2 + ky ^ 2) >= lim Then phase = PI / 2 Else phase = 2 * PI * Rnd End If A(i, j) = rad * Cos(phase) B(i, j) = rad * Sin(phase) A(N - i - 1, N - j - 1) = rad * Cos(phase) B(N - i - 1, N - j - 1) = rad * Sin(phase) A(i, N - j - 1) = rad * Cos(phase) B(i, N - j - 1) = rad * Sin(phase) A(N - i - 1, j) = rad * Cos(phase) B(N - i - 1, j) = rad * Sin(phase) End If Next j: DoEvents: frmBusy.ProgressBar1.Value = i Next i '壁の創成0°方向 0 For i = 0 To N / 2 - 1 If i <> 0 Then kx = i / (region) K = Sqr(kx ^ 2) gauss = Abs(Sqr(-2 * Log(Rnd)) * Cos(2 * PI * Rnd)) '**************************** 'gaussの上限,下限 (04.6.20) If gauss < 0.001 Then gauss = 0.001 ElseIf gauss > 10 Then gauss = 10 End If '**************************** Spec = ParaC1 * ParaA1 * (K ^ (-ParaB1)) Spec2 = Spec * (gauss ^ flag) rad = Sqr(Spec2 * 0.25) If Sqr(kx ^ 2) >= lim Then phase = PI / 2 Else phase = 2 * PI * Rnd End If A(i, 0) = rad * Cos(phase) B(i, 0) = rad * Sin(phase) A(N - i - 1, 0) = rad * Cos(phase) B(N - i - 1, 0) = rad * Sin(phase) End If Next i '壁の創成0°方向 511 For i = 0 To N / 2 - 1 If i <> 0 Then kx = i / (region) K = Sqr(kx ^ 2) gauss = Abs(Sqr(-2 * Log(Rnd)) * Cos(2 * PI * Rnd))

以下はC言語に書き換えてみたプログラムです

#include <stdio.h>
#include <math.h>
#include <process.h>
#include <stdlib.h>

//qs変更
//保存部分変更
// α,β,γのに変更中
//parab1
void main(void)
{
int ka,kb,ix,i,j,r,l,m,n,il1,it1,it2,it3,mf,nf,ib,lff,ir,ic,z,aa,bb;
double qs,ig,q,pi,tr,tj,swap,swop,**sp,**xx,**yy,*x,*y,*il,*ik,*d,*s;
double paraa1,paraa2,paraa3,parab1,parab2,parab3,flag,flag2,parac1,region;
double phase,rad,phaseS,kx,ky,k,spec,gauss,lim,spec2,**a,**b,rnd,zmin1,*zmin,*zmax,**zz;

//double *xは1次元配列 double **spは2次元配列の要素数未定の指定の仕方

FILE *fr,*fw;
char infilename[50],outfilename[50];

printf("ファイルのデータ数を入力して下さい!(AFMなら512)\n");
scanf("%d",&n);
printf("n=%d\n", n);

printf("αを入力して下さい!(0.05くらい)\n");
scanf("%lf",&paraa1);
printf("%lf\n", paraa1);

printf("βを入力して下さい!(2くらい)\n");
scanf("%lf",&parab1);
printf("parab1=%lf\n ", parab1);

printf("γを入力して下さい!(0.1くらい)\n");
scanf("%lf",&parac1);
printf("%lf\n", parac1);

printf("走査範囲を入力して下さい!(基本20)\n");
scanf("%lf",&region);
printf("region=%lf\n", region);

printf("ガウス乱数 0:なし 1:あり(逆かも基本1?)\n");
scanf("%lf",&flag);
printf("%lf\n", flag);

printf("異方性 0:なし 1:あり(0?)\n");
scanf("%lf",&flag2);
printf("%lf\n", flag2);

//-----------------------------------------------------
d = (double *)malloc(sizeof(double) * n);
if (d==NULL) exit(1);
s = (double *)malloc(sizeof(double) * n);
if (s==NULL) exit(1);

x = (double *)malloc(sizeof(double) * n);
if (x==NULL) exit(1);
y = (double *)malloc(sizeof(double) * n);
if (y==NULL) exit(1);

sp = (double **)malloc(sizeof(double *) * n);
if (sp==NULL) exit(1);
for (i=0; i<n; i++) {
sp[i] = (double *)malloc(sizeof(double) * n);
if (sp[i]==NULL) exit(1);
}
a = (double **)malloc(sizeof(double *) * n);
if (a==NULL) exit(1);
for (i=0; i<n; i++) {
a[i] = (double *)malloc(sizeof(double) * n);
if (a[i]==NULL) exit(1);
}
b = (double **)malloc(sizeof(double *) * n);
if (b==NULL) exit(1);
for (i=0; i<n; i++) {
b[i] = (double *)malloc(sizeof(double) * n);
if (b[i]==NULL) exit(1);
}

pi=4*atan(1);
qs=-1;
ig=log(n)/log(2);

###試したこと
C言語では配列の数がわからない時にマロック関数を使う必要があると教えていただいたのでそれを使って書き換えてみました

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

とりあえずDFTのプログラムを書いてからFFTを作ったほうがいいと思うよ。計算の確認ができるし、FFTの部品にも使えるよ。ついでに、元のプログラムのパラメタの多さが気になります。二次元にしてもなんかおかしい。そもそも、パラメタの解釈によって意味が変わるはず。

FFT(原信号)
原信号長が偶数ならば
→原信号奇数部と偶数部をそれぞれ再帰的にFFT。この結果で計算結果を組み立てる。
原信号長が奇数ならば
→原信号をそのままDFT

投稿2016/05/26 12:17

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/05/26 12:44

回答ありがとうございます 一応1次元のFFT,逆FFT2次元のFFTのプログラミングは先輩方が作ってくれていてある事にはあるんです。ただ、今回はすでに作られていた2次元の逆FFTをVisual basicでの文章をC言語に書き換える事を言い渡され困っています。 私は、プログラミングを経験したことがなく先輩方も卒業されてしまったので調べながら書き換えをしているのですが何分わからない所が多すぎて進むペースが遅いのが現状です。
ozwk

2016/05/27 05:09

プログラミング経験がないのであれば CでFFT、IFFTを書いて、移植したと言い張るか、 その経験を元にVBの移植作業に移るのがいいと思います。 そして最終的にはライブラリ使ったほうがいいと思います。
guest

0

ベストアンサー

ざっと流し読みしましたが、とりあえず
spなどがdoubleとして宣言されている割には
sp = (double )malloc(sizeof(double *) * n);
double*n個分の領域を確保しているので、
多分、意図するところは

C

1double **sp; 2... 3sp = (double**)malloc(sizeof(double *) * n);

では?

もっと言えば多分二次元配列の動的確保をしたいのでしょうから
このあたりを参考にどうぞ。

投稿2016/05/25 08:00

編集2016/05/27 04:57
ozwk

総合スコア13512

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/05/25 14:54

回答ありがとうございます sp = (double )malloc(sizeof(double *) * n); if (sp==NULL) exit(1); for (i=0; i<n; i++) { sp[i] = (double *)malloc(sizeof(double) * n); if (sp[i]==NULL) exit(1); } 上記の部分のsp = (double )malloc(sizeof(double *) * n); を sp = (double**)malloc(sizeof(double *) * n);に書き換えてみます
ozwk

2016/05/25 23:18

他にも似たような箇所あるので合わせて直してみてください
退会済みユーザー

退会済みユーザー

2016/05/26 11:53

直す箇所の前の部分の visual basicの ReDim A(N - 1, N - 1), B(N - 1, N - 1) ReDim AX(N - 1, N - 1), BY(N - 1, N - 1) ReDim Sp(N - 1, N - 1) ReDim Z(N - 1, N - 1) をC言語にどのように書き換える方法がわからないのですが この部分は省略しても大丈夫ですか? 省略してはいけないのなら書き換え方を教えていただきたいです ちなみにN=512です
rubato6809

2016/05/27 04:52

ReDim は、配列変数の領域を再割当てする、即ち配列のサイズを変更するのだから、 C言語では realloc() ライブラリ関数の呼出しに相当します。 「再」割当てですから、普通、既に割当済みの(Dim してある)ものを ReDimするので、例えば Dim DP(256) As Double だったものを、 ReDim DP(512) とするなら、 double *dp; /* 一次元配列を指すポインタ変数 dp を宣言しておき */ : dp = malloc(sizeof(double) * 256); /* 1回目、要素数256個分の配列を確保する */ : dp = realloc(dp, sizeof(double) * 512); /* 2回目、512個分に割当てなおす */ が相当するCのコードとなると思います(あくまで一般的には、ということで)。 ただし、まだ配列を割当ておらず、ReDim で初めてメモリを割当てるなら、それは即ち1回目のメモリ割当てなので malloc() で構わないし、不要なトラブルを避けることになります。即ち dp = malloc(sizeof(double) * 512); P.S.1. コード中に「double **spは2次元配列の要素数未定の指定の仕方」とコメントがありましたが、それだけの認識ではトラブルになりそうです。C言語で二次元配列をmalloc()で割当てるのは単純ではありません。割り当てた後のアクセス方法ともあわせて、複数の方法が考えられるので、注意が要ります。 例えば次のページを参考にして、どのようなデータ構造にすればよいか・配列のアクセス方法をどうするのがよいか、検討されると良いと思います(なので、上の私の回答は簡単な一次元配列を例にした)。 C言語で2次元配列を動的に割り当てる4つの方法 http://tondol.hatenablog.jp/entry/20090713/1247426321 P.S.2 VBからCへの書き換えをするなら、本来、両方の言語に通じている必要があります。「私は、プログラミングを経験したことがな」いなら、両方に通じている方を探して、直接助言を受けるのが理想です(どちらかと言えば、少なくともC言語の経験者が望ましい)。 そのうえで、このサイトで助言を受けたければ、プログラム全体を質問の対象にするのではなく、ここの「ReDimを、どう書き換えればよいか?」のように、質問のポイントを絞ったほうが答えを得やすい(答える方も答えやすい)と思いました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問