第 11 回 Gnuplot, 文字列

本日の内容


このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。

11-1. Gnuplot

gnuplot はグラフを作成するためのツールです。 名前は gnu とついていますが、GNU とは配布ライセンスは異なる形態です。

Mupad light 2.5.2 はバグがあって、対数軸のグラフがうまく書けません。 電気系のグラフを書く際に、 gnuplot が必要になります。

基本操作

二次元のグラフを書くには plot を使用します。 変数は x を使用して、関数をそのまま書きます。 複数のグラフを重ねるには関数を「,(カンマ)」で区切ります。 また、 x 軸の範囲、 y 軸の範囲を設定するには [ ] の中に範囲を「:(コロ ン)」で区切って書きます。

演習11-1

次のグラフを書きなさい

  1. plot sin(x)
  2. plot sin(x),cos(x)
  3. plot [0:2*pi] sin(x)
  4. plot [0:2*pi][0:1] sin(x)
  5. plot [][:0] sin(x)

応用

gnuplot は複素数なども扱うことができます。 また、対数軸のグラフもきちんと書けます。 例えば次の回路の周波数特性を考えます。

low pass filter

抵抗値を R, コンデンサの容量を C とした時、入力電圧に対する出力電圧の 比は、それぞれのインピーダンス R, 1/jωC の比に電圧を分けたものになり ますから次式で得られます。但し、 j = √(-1)、ωは入力信号の角周波数で す。


frac{frac{1}{j omega C}}{R + frac{1}{j omega C}} = frac{1}{1+ j omega
C}

ここで、 CR=1 の時、ωに関する周波数特性を示す式をグラフにしてみましょ う。 つまり、 1/(1+ j x) というグラフを書くということです。 gnuplot では j= √(-1) を {0,1} で表します( 0+ 1*j の意味です)。 従って、周波数特性のうち電圧の大きさの比は abs(1/(1+{0,1}*x)) と書けます。 一般に、周波数特性を調べる時は横軸、縦軸とも対数目盛を使用します。 また、求める周波数の範囲ですが、今回は 10-5 から 105 まで求めましょう。 gnuplot で巾乗は ** で表します。 求める周波数特性のグラフは次のようになります。

set logscale xy
plot [10**-5:10**5] abs(1/(1+{0,1}*x))

一方、偏角を求めるには arg 関数を使用します。 偏角の場合縦軸は対数目盛ではないので、 logscale を解除します。

set nologscale y
plot [10**-5:10**5] arg(1/(1+{0,1}*x))

対数目盛を全て解除するには set nologscale xy として下さい。

演習11-2

次の回路において入出力電圧の比と偏角の周波数特性をグラフに表しなさい。 なお、複素数で表した場合の入出力電圧比は 
frac{j omega C R}{1 + j omega C R}
になります。 但し、グラフを書く際、コンデンサの容量と抵抗値の積は 1 とします。

low pass filter

演習11-3

次の回路においてインピーダンスの大きさと偏角の周波数特性をグラフに表し なさい。 なお、複素数で表した場合のインピーダンスは次のようになります。


frac{1}{frac{1}{R} + j omega C + frac{1}{j omega L}}
=
frac{R}{1 + j Q LRparen{ frac{omega}{omega_0} - frac{omega_0}{omega}}}

omega_0 = frac{1}{sqrt{L C}}, Q = R sqrt{frac{C}{L}}

但し、グラフを書く際、LC = 1, R = 1 として、 Q= 0.1, 1, 10 のそれぞれ に関してグラフの形を調べなさい。

LCR

数値入力

演習11-4

  • 次のような値を入れたファイルを作り、c:\work\testdata という名前で 保存しなさい。
    0 3
    4 5
    10 7
    
    そして、 gnuplot で、
    1. cd 'c:\work'
    2. plot "testdata"
    としなさい。

    ファイル出力

    なお、TeX のドキュメントに入れる画像を作るには、 EPS ファイルで出力し ます。次のようにすると detafile というファイルからデータを読んでプロッ トしたグラフを graph.eps というファイル名で白黒の EPS ファイルに保存し ます(カラーの出力にする場合は monochrome を color に変更します)。

    set terminal postscript eps monochrome
    set output "graph.eps"
    cd 'c:\work'
    plot [0:][0:] "datafile", 0.5*x+1
    

    パラメータ

    set parametric とすると、媒介表示モードになります。 set noparametric とすると元に戻ります 媒介表示モードでは、t の関数を二つ書くことにより、 t の値により座標を 定めグラフを書きます。

    演習11-5

    次の媒介変数による関数のグラフを書きなさい。

    1. t , t
    2. cos(t),sin(t)
    3. cos(6*t),sin(5*t)

    三次元グラフィック

    gnuplot では三次元グラフィックを表示させるのに、 splot 命令を使用しま す。

    演習11-6

    次の関数のグラフを書きなさい。

    1. x2+y2
    2. sin(√(x2+y2))

    また set parametric とすると、 u, v を媒介変数とした関数のグラフを書く ことができます。

    1. cos(u),sin(u)*cos(v),sin(u)*sin(v)
    2. (3+cos(u))*cos(v),(3+cos(u))*sin(v),sin(u)

    11-2. 文字列

    C 言語で文字列を扱うには、文字型の配列を使います。 ただし、配列の終りには配列の終りを示す(番兵)特別な文字\0を入 れます。従って、配列にあらかじめ文字列を入れるには次のようにします。

    char x[]={'a','b','c','\0'};
    

    ただし、文字列の扱いを簡単にするために、これを次のように書くことが可能 です。

    char x[]="abc";
    

    このように書くと配列変数 x の値は次のようになります。

    x[0]='a', x[1]='b', x[2]='c', x[3]='\0'
    

    二重引用符で括られた文字列を並べると一つの文字列として扱われます。 長い文字列を記述する場合、つぎのようにします。

    char x[]="abc"
             "def"
             "ghi";
    

    この宣言は char x[]="abcdefghi"; と同じになります。 なお、このような文字列の一括の代入はあくまでも宣言文の中でのみ有効で、 プログラムの実行中はできません。 プログラム中はひと文字ずつしか取り扱えません。 文字配列 x, y に対し、 x=y はできません(エラーにならず誤動作します)。

    文字を画面に表示するには printf("%c",x[0]); などと書きますが、文字配列 を一括して画面に表示するには %s を使用します。 printf("%s",x); と %s に対して文字配列名を指定します。 これは、次のプログラムと同じ処理が行なわれます。

    int i=0;
    while(x[i]!='\0'){
      printf("%c",x[i++]);
    }
    

    演習11-7

    文字列が与えられた時、縦書きに表示するプログラムを書きなさい。 そして "abcdefg" を縦書きにしなさい。


    演習11-8

    次のプログラムを完成させなさい。 また、文字列を "ABCDEF" に替えて実行しなさい。

    #include <stdio.h>
    main(){
      char x[]="abcdefgh";
      int y=0;
      while(x[y]!='\0'){
        printf("文字列 %s の %d 文字目は %c\n",?,?,?);
        y=y+1;
      }
      printf("全部で %d 文字\n",?);
    }
    

    演習11-9

    文字列の長さを出力するプログラムを書きなさい。 文字列 "abcdefg" などで試しなさい。


    演習11-10

    次のプログラムを完成させなさい。 また、文字列を "ABC" と "DEF" に替えて実行しなさい。

    #include <stdio.h>
    main(){
      char x[]="abcdef", y[]="ghijkl", z[100];
      int i,j;
      printf("文字列 %s と文字列 %s をくっつけると",x,y);
      /* まず z に x をひと文字ずつコピーする */
      j=0;
      while(y[j]!='\0'){
        z[i]=y[j];
        i=i+1;
        j=j+1;
      }
      z[i]='\0';
      printf("%s\n",z);
    }
    

    演習11-11

    文字列が与えられた時、先頭の 3 文字だけを表示するプログラムを書きなさ い。 作ったプログラムを文字列 "abcde", "ABC", "X" などで試しなさい。

    ヒント

    「文字が \0 かまたは 3 文字を越えた時」終了させるには次のように論理演算を 使います。

      while((文字が '\0' でない)&&(3 文字以内))
    

    演習11-12

    文字列が与えられた時、先頭の空白の文字数を数えるプログラムを書きなさい。 "a○b○c" なら 0, "○○def" なら 2 が出力されるようにしなさい(○は空白 を表す)。


    演習11-13

    文字配列 x 中に含まれている文字変数 y の文字の使用頻度を求めるプログラ ムを書きなさい。 例えば、 x[]="This is a pen.", y='i' ならば、 2 を表示しなさい。


    演習11-14

    文字列が与えられた時、二文字出力しては改行するように表示するプログラム を書きなさい。 そして、次の文字列で試しなさい。

    1. "a"
    2. "abcd"
    3. "abcde"

    演習11-15

    文字列が与えられた時、最初の文字から一文字おきに表示するプログラムを書 きなさい。 "abcde" なら出力は ace になります。 そして、次の文字列で試しなさい。

    1. "a"
    2. "abcd"
    3. "abcde"

    演習11-16

    文字列が与えられた時、逆向きに表示するプログラムを書きなさい。 "abcdefg" が与えられた時、「gfedcba」と表示されるようにしなさい。


    坂本直志 <[email protected]>
    東京電機大学工学部情報通信工学科