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

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

ただいまの
回答率

90.47%

  • C

    4657questions

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

  • Visual Basic 6.0

    23questions

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

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

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 2,188
退会済みユーザー

退会済みユーザー

前提・実現したいこと

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言語では配列の数がわからない時にマロック関数を使う必要があると教えていただいたのでそれを使って書き換えてみました

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

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

double **sp;
...
sp = (double**)malloc(sizeof(double *) * n);


では?

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/25 23: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);に書き換えてみます

    キャンセル

  • 2016/05/26 08:18

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

    キャンセル

  • 2016/05/26 20: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です

    キャンセル

  • 2016/05/27 13: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を、どう書き換えればよいか?」のように、質問のポイントを絞ったほうが答えを得やすい(答える方も答えやすい)と思いました。

    キャンセル

0

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/26 21:44

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

    キャンセル

  • 2016/05/27 14:09

    プログラミング経験がないのであれば
    CでFFT、IFFTを書いて、移植したと言い張るか、
    その経験を元にVBの移植作業に移るのがいいと思います。

    そして最終的にはライブラリ使ったほうがいいと思います。

    キャンセル

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

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    4657questions

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

  • Visual Basic 6.0

    23questions

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