Swift 3と、Xcode 8

swift3

いまや、5つの異なるアクセスレベル、open、public、internal、fileprivate、そしてprivateが存在します。

swift4

% swift
Welcome to Apple Swift version 3.0 (swiftlang-800.0.46.2 clang-800.0.38). Type :help for assistance.
  1> var list = [10, 11, 12]
list: [Int] = 3 values {
  [0] = 10
  [1] = 11
  [2] = 12
}
  2> list.insert(99, at: 1)
  3> print(list)
[10, 99, 11, 12]
  4> public   var r = 1
r: Int = 1
  5> internal let s = 2
s: Int = 2
  6> fileprivate func myfunc() {}
  7> private     func urfunc() {}

あなたは、IBM Swift Sandboxを訪問すれば、Swift 3をインストールせずに試すことができます。

swift5

スミスチャートをROOTで描く(3)

smithroot3

smithroot4

アンテナチューナー(ICOM AH-4)を用いると、同じアンテナでVSWRの値はほぼ1.0になります。

freq1=7.02387 MHz, freq2=7.02408 MHz
amp(v2/v1)=0.985099, phase(v2/v1)=0.00860836 rad
v1=(1,0i), v2=(0.985063,0.00847999i), v3=(1.01494,-0.00847999i)
z=(0.970428,0.0164633i), z50=(48.5214,0.823164i)
gamma=(-0.0149372,0.00847999i), abs=0.0171765, arg=150.416 deg
vswr=1.03495
cable_length=20 m, velocity_factor=0.67 , phase_toward_load=143 deg

スミスチャートをROOTで描く(2)

smithroot2

もし、あなたがZ(DUT)だけでなく、あなたのアンテナの放射インピーダンスも知りたければ、あなたは、ケーブルの長さと短縮率に応じて、スミスチャート上で負荷の方向へ移動(反時計回りの回転)しなければなりません。

この図では、青色の点がZ(DUT)を、緑色のそれが放射インピーダンスを示しています。

freq1=7.02687 MHz, freq2=7.02978 MHz
amp(v2/v1)=0.778415, phase(v2/v1)=-0.53185 rad
v1=(1,0i), v2=(0.670893,-0.394757i), v3=(1.32911,0.394757i)
z=(0.382788,-0.410701i), z50=(19.1394,-20.535i)
gamma=(-0.329107,-0.394757i), abs=0.51395, arg=-129.818 deg
vswr=3.1148
cable_length=20 m, velocity_factor=0.67, phase_toward_load=143 deg
// file name = mytest46.cc
{
  ifstream finput("owondata.txt");
  Int_t iskip=8;
  std::string s;

  for(Int_t i=0;i<iskip;i++) {
    getline(finput, s);
  }

  const Int_t icount_max=8192;
  Int_t icount=0;
  Double_t dummy, data1[icount_max], data2[icount_max], data3[icount_max];
  while(icount < icount_max) {
    finput >> data1[icount] >> dummy >> data2[icount] >> data3[icount];
    if(finput.eof()) break;
    icount++;
  }

  TCanvas *c1 = new TCanvas("c1","Test",0,0,800,600);
  TGraph *g = new TGraph(icount, data1, data2);
  g->SetMarkerStyle( 20 ); 
  g->SetMarkerSize( 0.5 );
  g->Draw("AP");
  TF1 *f1 = new TF1("f1", "[0]*sin([1]*x+[2])-[3]");
  f1->SetParameter(0, 2000.0);
  f1->SetParameter(1, 0.022);
  f1->SetParameter(2, 0.0);
  f1->SetParameter(3, 0.0);
  f1->SetLineColor(kRed);
  g->Fit(f1);

  TGraph *h = new TGraph(icount, data1, data3);
  h->SetMarkerStyle( 24 ); 
  h->SetMarkerSize( 0.5 );
  h->Draw("P");
  TF1 *f2 = new TF1("f2", "[0]*sin([1]*x+[2])-[3]");
  f2->SetParameter(0, 2000.0);
  f2->SetParameter(1, 0.022);
  f2->SetParameter(2, 0.0);
  f2->SetParameter(3, 0.0);
  f2->SetLineColor(kYellow);
  h->Fit(f2);

  Double_t freq1, freq2;
  const Double_t fsample = 2000.0; // MHz (interpolated)
  freq1 = fsample / ( 2.0*TMath::Pi() / f1->GetParameter(1) );
  freq2 = fsample / ( 2.0*TMath::Pi() / f2->GetParameter(1) );
  std::cout << "freq1=" << freq1 << " MHz, freq2=" << freq2 << " MHz" << std::endl;

  Double_t amp, phase;
  amp   = f2->GetParameter(0) / f1->GetParameter(0);
  phase = f2->GetParameter(2) - f1->GetParameter(2);
  std::cout << "amp(v2/v1)=" << amp << ", phase(v2/v1)=" << phase << " rad" << std::endl;

  TComplex v1, v2, v3, Z, z50;
  v1  = TComplex(1.0, 0.0);
  v2  = TComplex( amp*TMath::Cos(phase), amp*TMath::Sin(phase) );
  v3  = 2.0*v1 - v2;
  z   = v2/v3;
  z50 = 50.0*z;
  std::cout << "v1=" << v1 << ", v2=" << v2 << ", v3=" << v3 << std::endl;
  std::cout << "z=" << z << ", z50=" << z50 << std::endl;

  TComplex gg;
  Double_t gg_rho, gg_theta, vswr;
  gg  = (z-1.0)/(z+1.0);
  vswr = (1.0+TComplex::Abs(gg)) / (1.0-TComplex::Abs(gg));

  std::cout << "gamma=" << gg 
            << ", abs=" << gg.Rho()
            << ", arg=" << gg.Theta()*360.0/(2.0*TMath::Pi()) << " deg" << std::endl;
  std::cout << "vswr=" << vswr << std::endl;

  TCanvas * CPol = new TCanvas("CPol", "Test", 900, 0, 600, 600);
  const Int_t ncircle = 360;

  Double_t radius[ncircle];
  Double_t theta [ncircle];
  for (Int_t i=0; i<ncircle; i++) {
    radius[i] = gg.Rho();
    theta [i] = TMath::Pi()*2.0*(Double_t)i/(Double_t)(ncircle-1);
  }

  Double_t radius_r[ncircle];
  Double_t theta_r [ncircle];
  Double_t r_center = z.Re() / (z.Re()+1.0);
  Double_t r_radius = 1.0    / (z.Re()+1.0);
  for (Int_t i=0; i<ncircle; i++) {
    Double_t th = TMath::Pi()*2.0*(Double_t)i/(Double_t)(ncircle-1);
    Double_t re = r_center + r_radius*TMath::Cos(th);
    Double_t im =            r_radius*TMath::Sin(th);
    TComplex ww = TComplex(re, im);
    radius_r[i] = ww.Rho  ();
    theta_r [i] = ww.Theta();
  }

  Double_t radius_x[ncircle];
  Double_t theta_x [ncircle];
  TComplex x_center = TComplex(1.0, 1.0/z.Im());
  Double_t x_radius = 1.0/ z.Im();
  for (Int_t i=0; i<ncircle; i++) {
    Double_t th = TMath::Pi()*2.0*(Double_t)i/(Double_t)(ncircle-1);
    Double_t re = x_center.Re() + x_radius*TMath::Cos(th);
    Double_t im = x_center.Im() + x_radius*TMath::Sin(th);
    TComplex ww = TComplex(re, im);
    radius_x[i] = ww.Rho  ();
    theta_x [i] = ww.Theta();
  }

  TGraphPolar * grP1 = new TGraphPolar(ncircle, theta, radius);
  grP1->SetTitle("Smith Chart");
  grP1->SetMarkerStyle(20);
  grP1->SetMarkerSize(2.0);
  grP1->SetMarkerColor(4);
  grP1->SetLineColor(2);
  grP1->SetLineWidth(3);
  grP1->Draw("C");
  CPol->Update();

  grP1->GetPolargram()->SetToRadian();
  grP1->GetPolargram()->SetRangeRadial(0,1);

  TGraphPolar * grP2 = new TGraphPolar(ncircle, theta_r, radius_r);
  grP2->SetMarkerStyle(20);
  grP2->SetMarkerSize(2.0);
  grP2->SetMarkerColor(4);
  grP2->SetLineColor(9);
  grP2->SetLineWidth(3);
  grP2->Draw("C");

  TGraphPolar * grP3 = new TGraphPolar(ncircle, theta_x, radius_x);
  grP3->SetMarkerStyle(20);
  grP3->SetMarkerSize(2.0);
  grP3->SetMarkerColor(4);
  grP3->SetLineColor(6);
  grP3->SetLineWidth(3);
  grP3->Draw("C");

  TMarker *m0 = new TMarker(gg.Re(), gg.Im(), 20);
  m0->SetMarkerSize(2.0);
  m0->SetMarkerColor(4);
  m0->Draw();

  Double_t freq = (freq1+freq2)/2.0; // MHz
  Double_t cable_length = 20.0; // meter
  Double_t velocity_factor = 0.67;
  Double_t wave_length = velocity_factor * (300.0 / freq);
  Double_t phase_toward_load = 2.0 * 2.0 * TMath::Pi() * (cable_length / wave_length);
  std::cout << "cable_length=" << cable_length
            << " m, velocity_factor=" << velocity_factor
            << ", phase_toward_load=" << (Int_t) ( phase_toward_load * 360.0 / (2.0*TMath::Pi()) ) % 360
            << " deg" << std::endl;

  TComplex gg_toward_load = gg * TComplex::Exp(TComplex(0.0, phase_toward_load));

  TMarker *m1 = new TMarker(gg_toward_load.Re(), gg_toward_load.Im(), 20);
  m1->SetMarkerSize(2.0);
  m1->SetMarkerColor(8);
  m1->Draw();
}

スミスチャートをROOTで描く

smithroot

ひとたび、あなたがZ(DUT)を、従って、反射係数を得れば、ROOTを使ってスミスチャートを描くことができます。スミスチャートとは、半径1の範囲に制限した複素平面上に極座標で反射係数をプロットしたものに過ぎないことに注意して下さい。

図では、青色の点は反射係数(-0.328107, -0.394757i)、即ち、(0.51395, -129.818 deg)を表しています。赤色の円は反射係数の絶対値が一定の円、即ち、VSWRが一定の円を表しています。

あなたのアンテナと測定回路との間にある同軸ケーブルの長さが異なれば、青色の点は異なる場所に現れますが、それらは常に同じ赤色の円上にあります。もし、ケーブル損失を無視すればですが。

// file name = mytest45.cc
{
  ifstream finput("owondata2.txt");
  Int_t iskip=8;
  std::string s;

  for(int i=0;i<iskip;i++) {
    getline(finput, s);
  }

  const Int_t icount_max=8192;
  Int_t icount=0;
  Double_t dummy, data1[icount_max], data2[icount_max], data3[icount_max];
  while(icount < icount_max) {
    finput >> data1[icount] >> dummy >> data2[icount] >> data3[icount];
    if(finput.eof()) break;
    icount++;
  }

  TCanvas *c1 = new TCanvas("c1","Test",0,0,800,600);
  TGraph *g = new TGraph(icount, data1, data2);
  g->SetMarkerStyle( 20 ); 
  g->SetMarkerSize( 0.5 );
  g->Draw("AP");
  TF1 *f1 = new TF1("f1", "[0]*sin([1]*x+[2])-[3]");
  f1->SetParameter(0, 2000.0);
  f1->SetParameter(1, 0.022);
  f1->SetParameter(2, 0.0);
  f1->SetParameter(3, 0.0);
  f1->SetLineColor(kRed);
  g->Fit(f1);

  TGraph *h = new TGraph(icount, data1, data3);
  h->SetMarkerStyle( 24 ); 
  h->SetMarkerSize( 0.5 );
  h->Draw("P");
  TF1 *f2 = new TF1("f2", "[0]*sin([1]*x+[2])-[3]");
  f2->SetParameter(0, 2000.0);
  f2->SetParameter(1, 0.022);
  f2->SetParameter(2, 0.0);
  f2->SetParameter(3, 0.0);
  f2->SetLineColor(kYellow);
  h->Fit(f2);

  double amp, phase;
  amp   = f2->GetParameter(0) / f1->GetParameter(0);
  phase = f2->GetParameter(2) - f1->GetParameter(2);
  std::cout << "amp=" << amp << ", phase=" << phase << std::endl;

  TComplex v1, v2, v3, Z, z50;
  v1  = TComplex(1.0, 0.0);
  v2  = TComplex( amp*TMath::Cos(phase), amp*TMath::Sin(phase) );
  v3  = 2.0*v1 - v2;
  z   = v2/v3;
  z50 = 50.0*z;
  std::cout << "v1=" << v1 << ", v2=" << v2 << ", v3=" << v3 << ", z=" << z << ", z50=" << z50 << std::endl;

  TComplex gg;
  double gg_rho, gg_theta, vswr;
  gg  = (z-1.0)/(z+1.0);
  vswr = (1.0+TComplex::Abs(gg)) / (1.0-TComplex::Abs(gg));

  std::cout << "gg=" << gg << ", abs=" << TComplex::Abs(gg) << std::endl;
  std::cout << "gg=" << gg.Rho() << ", " << gg.Theta()*360.0/(2.0*TMath::Pi())  << std::endl;
  std::cout << "vswr=" << vswr << std::endl;

  TCanvas * CPol = new TCanvas("CPol", "Test", 900, 0, 600, 600);
  const Int_t ncircle = 360;

  Double_t radius[ncircle];
  Double_t theta [ncircle];
  for (int i=0; i<ncircle; i++) {
    radius[i] = gg.Rho();
    theta [i] = TMath::Pi()*2.0*(double)i/(double)(ncircle-1);
  }

  Double_t radius_r[ncircle];
  Double_t theta_r [ncircle];
  Double_t r_center = z.Re() / (z.Re()+1.0);
  Double_t r_radius = 1.0    / (z.Re()+1.0);
  for (int i=0; i<ncircle; i++) {
    Double_t th = TMath::Pi()*2.0*(double)i/(double)(ncircle-1);
    Double_t re = r_center + r_radius*TMath::Cos(th);
    Double_t im =            r_radius*TMath::Sin(th);
    TComplex ww = TComplex(re, im);
    radius_r[i] = ww.Rho  ();
    theta_r [i] = ww.Theta();
  }

  Double_t radius_x[ncircle];
  Double_t theta_x [ncircle];
  TComplex x_center = TComplex(1.0, 1.0/z.Im());
  Double_t x_radius = 1.0/ z.Im();
  for (int i=0; i<ncircle; i++) {
    Double_t th = TMath::Pi()*2.0*(double)i/(double)(ncircle-1);
    Double_t re = x_center.Re() + x_radius*TMath::Cos(th);
    Double_t im = x_center.Im() + x_radius*TMath::Sin(th);
    TComplex ww = TComplex(re, im);
    radius_x[i] = ww.Rho  ();
    theta_x [i] = ww.Theta();
  }

  TGraphPolar * grP1 = new TGraphPolar(ncircle, theta, radius);
  grP1->SetTitle("Smith Chart");
  grP1->SetMarkerStyle(20);
  grP1->SetMarkerSize(2.0);
  grP1->SetMarkerColor(4);
  grP1->SetLineColor(2);
  grP1->SetLineWidth(3);
  grP1->Draw("C");
  CPol->Update();

  grP1->GetPolargram()->SetToRadian();
  grP1->GetPolargram()->SetRangeRadial(0,1);

  TGraphPolar * grP2 = new TGraphPolar(ncircle, theta_r, radius_r);
  grP2->SetMarkerStyle(20);
  grP2->SetMarkerSize(2.0);
  grP2->SetMarkerColor(4);
  grP2->SetLineColor(9);
  grP2->SetLineWidth(3);
  grP2->Draw("C");

  TGraphPolar * grP3 = new TGraphPolar(ncircle, theta_x, radius_x);
  grP3->SetMarkerStyle(20);
  grP3->SetMarkerSize(2.0);
  grP3->SetMarkerColor(4);
  grP3->SetLineColor(6);
  grP3->SetLineWidth(3);
  grP3->Draw("C");

  TMarker *m0 = new TMarker(gg.Re(), gg.Im(), 20);
  m0->SetMarkerSize(2.0);
  m0->SetMarkerColor(4);
  m0->Draw();
}
% root mytest45.cc
amp=0.778415, phase=-0.53185
v1=(1,0i), v2=(0.670893,-0.394757i), v3=(1.32911,0.394757i), z=(0.382788,-0.410701i), z50=(19.1394,-20.535i)
gg=(-0.329107,-0.394757i), abs=0.51395
gg=0.51395, -129.818
vswr=3.1148

eof()は使うのに注意が必要(2)

例えば、あなたが4行からなるテキストファイルを持っていたとしましょう。

1 2.0
2 2.2
3 2.4
4 2.6

correct

// code correct
{ 
  ifstream finput("owondata3.txt");
  const Int_t icount_max=16;
  Int_t icount=0;
  Double_t data1[icount_max], data2[icount_max];
  
  while(icount < icount_max) { 
    finput >> data1[icount] >> data2[icount];
    std::cout << icount << ", " << data1[icount] << ", " << data2[icount] << std::endl;
    if(finput.eof()) break;
    icount++;
  }
  std::cout << "icount = " << icount << std::endl;

  TCanvas *c1 = new TCanvas("c1","Test",200,100,800,600);
  TGraph *g = new TGraph(icount, data1, data2);
  g->SetMarkerStyle( 20 );
  g->SetMarkerSize( 2.0 );
  g->Draw("AP");
}
% root correct.cc 
0, 1, 2
1, 2, 2.2
2, 3, 2.4
3, 4, 2.6
4, 0, 0
icount = 4
0, 1, 2
1, 2, 2.2
2, 3, 2.4
3, 4, 2.6

wrong

// code wrong
{
  ifstream finput("owondata3.txt");
  const Int_t icount_max=16;
  Int_t icount=0;
  Double_t data1[icount_max], data2[icount_max];

  while(! finput.eof() ) {
    finput >> data1[icount] >> data2[icount];
    std::cout << icount << ", " << data1[icount] << ", " << data2[icount] << std::endl;
    icount++;
  }
  std::cout << "icount = " << icount << std::endl;

  for(int i=0;i<icount;i++) {
    std::cout << i << ", " << data1[i] << ", " << data2[i] << std::endl;
  }

  TCanvas *c1 = new TCanvas("c1","Wrong",200,100,800,600);
  TGraph *g = new TGraph(icount, data1, data2);
  g->SetMarkerStyle( 20 );
  g->SetMarkerSize( 2.0 );
  g->Draw("AP");
}
% root wrong.cc 
0, 1, 2
1, 2, 2.2
2, 3, 2.4
3, 4, 2.6
4, 0, 0
icount = 5
0, 1, 2
1, 2, 2.2
2, 3, 2.4
3, 4, 2.6
4, 0, 0

eof()は使うのに注意が必要

もしも、あなたがAWKの1行プログラムを使わずに、ROOTのマクロで同じことをしようと思えば、コードは以下のようになります。

% cat owondata.txt | awk 'NR>8 {print $1, $3}' >owondata_ch1.txt
% cat owondata.txt | awk 'NR>8 {print $1, $4}' >owondata_ch2.txt
{
  ifstream finput("owondata.txt"); // read the original file without using AWK one-liners
  Int_t nskip=8;
  std::string s;

  for(int i=0;i<nskip;i++) { // skip the first eight lines
    getline(finput, s);
  }

  const Int_t icount_max=8192;
  Int_t icount=0;
  Double_t dummy, data1[icount_max], data2[icount_max], data3[icount_max]; // save $1, $3, and $4
  while(icount < icount_max) {
    finput >> data1[icount] >> dummy >> data2[icount] >> data3[icount];
    if(finput.eof()) break;
    icount++;
  }

  TCanvas *c1 = new TCanvas("c1","Test",200,100,800,600);
  TGraph *g = new TGraph(icount, data1, data2); // ch1 data
  g->SetMarkerStyle( 20 ); 
  g->SetMarkerSize( 0.5 );
  g->Draw("AP");
  TF1 *f1 = new TF1("f1", "[0]*sin([1]*x+[2])-[3]");
  f1->SetParameter(0, 2000.0);
  f1->SetParameter(1, 0.022);
  f1->SetParameter(2, 0.0);
  f1->SetParameter(3, 0.0);
  f1->SetLineColor(kRed);
  g->Fit(f1);

  TGraph *h = new TGraph(icount, data1, data3); // ch2 data
  h->SetMarkerStyle( 24 ); 
  h->SetMarkerSize( 0.5 );
  h->Draw("P");
  TF1 *f2 = new TF1("f2", "[0]*sin([1]*x+[2])-[3]");
  f2->SetParameter(0, 2000.0);
  f2->SetParameter(1, 0.022);
  f2->SetParameter(2, 0.0);
  f2->SetParameter(3, 0.0);
  f2->SetLineColor(kYellow);
  h->Fit(f2);

  double amp, phase;
  amp   = f2->GetParameter(0) / f1->GetParameter(0);
  phase = f2->GetParameter(2) - f1->GetParameter(2);
  std::cout << amp << ", " << phase << std::endl;

  TComplex v1, v2, v3, Z, z50;
  v1  = TComplex(1.0, 0.0);
  v2  = TComplex( amp*TMath::Cos(phase), amp*TMath::Sin(phase) );
  v3  = 2.0*v1 - v2;
  z   = v2/v3;
  z50 = 50.0*z;
  std::cout << v1 << ", " << v2 << ", " << v3 << ", " << z << ", " << z50 << std::endl;

  TComplex rho;
  double vswr;
  rho  = (z-1.0)/(z+1.0);
  vswr = (1.0+TComplex::Abs(rho)) / (1.0-TComplex::Abs(rho));
  std::cout << rho << ", " << vswr << std::endl;
}

以下のようなコードは、icountをwhile loopの外で1だけ減らさない限り、うまく動作しないことに留意して下さい。

while(! finput.eof() ) }
  finput >> ...
  icount++;
}

インピーダンス測定とカーブフィッティング(5)

従って、もし全てを1つのマクロで記述するとすれば、以下のようになります。

// file name = myetst41.cc
{
  TGraph *g = new TGraph("myfile3.dat");
  g->SetMarkerStyle( 20 ); 
  g->SetMarkerSize( 0.5 );
  g->Draw("AP");
  TF1 *f1 = new TF1("f1", "[0]*sin([1]*x+[2])-[3]");
  f1->SetParameter(0, 2000.0);
  f1->SetParameter(1, 0.022);
  f1->SetParameter(2, 0.0);
  f1->SetParameter(3, 0.0);
  f1->SetLineColor(kRed);
  g->Fit(f1);

  TGraph *h = new TGraph("myfile4.dat");
  h->SetMarkerStyle( 24 ); 
  h->SetMarkerSize( 0.5 );
  h->Draw("P");
  TF1 *f2 = new TF1("f2", "[0]*sin([1]*x+[2])-[3]");
  f2->SetParameter(0, 2000.0);
  f2->SetParameter(1, 0.022);
  f2->SetParameter(2, 0.0);
  f2->SetParameter(3, 0.0);
  f2->SetLineColor(kYellow);
  h->Fit(f2);

  double amp, phase;
  amp   = f2->GetParameter(0) / f1->GetParameter(0);
  phase = f2->GetParameter(2) - f1->GetParameter(2);
  std::cout << amp << ", " << phase << std::endl;

  TComplex v1, v2, v3, Z, z50;
  v1  = TComplex(1.0, 0.0);
  v2  = TComplex( amp*TMath::Cos(phase), amp*TMath::Sin(phase) );
  v3  = 2.0*v1 - v2;
  z   = v2/v3;
  z50 = 50.0*z;
  std::cout << v1 << ", " << v2 << ", " << v3 << ", " << z << ", " << z50 << std::endl;

  TComplex rho;
  double vswr;
  rho  = (z-1.0)/(z+1.0);
  vswr = (1.0+TComplex::Abs(rho)) / (1.0-TComplex::Abs(rho));
  std::cout << rho << ", " << vswr << std::endl;
}
% root mytest41.cc
0.778415, -0.53185
(1,0i), (0.670893,-0.394757i), (1.32911,0.394757i), (0.382788,-0.410701i), (19.1394,-20.535i)
(-0.329107,-0.394757i), 3.1148

ROOT、インタープリテーションかコンパイレーションか

ROOTには、ClingというC++インタープリターが内蔵されています。Clingを用いた1つの例は:

root6

% root
root [0] TF1 f1("f1", "sin(x)/x", -10.0, 10.0)
root [1] f1.Draw()

各行の最後に終端の”;”が不要なことに注意して下さい。

もしくは、あなたはROOTのmacro、これは行の集合ですが、を書くことができます。

// file name = myprog1.C
void myprog1(){
   TCanvas *c1 = new TCanvas("c1" ,"Test" ,0 ,0 ,600 ,400) ;
   c1->SetGrid( ) ;
   TF1 *f1 = new TF1("f1", "sin(x)/x", -10.0, 10.0);
   f1->Draw();
   c1->Update();
}

あなたは、あなたのマクロを以下のいずれかの方法で実行することができます。

% root myprog1.C
// or
% root
root [0] .x myprog1.C

root7

あなたのマクロは、いくらかの”dressing code”を付加することにより、コンパイルすることもできます。

https://root.cern.ch/root/htmldoc/guides/primer/ROOTPrimer.html#interpretation-and-compilation

// file name = myprog2.C

//include some header files, not necessary for Cling.
#include "TApplication.h"
#include "TROOT.h"
#include "TCanvas.h"
#include "TF1.h"
using namespace std;

void myprog2() {
  TCanvas *c1 = new TCanvas("c1", "Test", 0, 0, 600, 400);
  c1->SetGrid();
  TF1 *f1 = new TF1("f1", "sin(x)/x", -10.0, 10.0);
  f1->Draw();
  c1->Update();
}

void StandaloneApplication(int argc, char** argv) {
  myprog2();
}

int main (int argc, char** argv) {
  TApplication app("ROOT Application", &argc, argv);
  StandaloneApplication(app.Argc(), app.Argv());
  app.Run();
  return 0;
}
% g++ -o myprog2 myprog2.C `root-config --cflags --libs`
./myprog2

最後に、あなたはバインディングの集合PyROOTを用いてPythonにインターフェースすることもできます。

# file name = myprog3.py
from ROOT import TCanvas, TF1
c1=TCanvas("c1" ,"Test" ,0 ,0 ,600 ,400) 
c1.SetGrid ()
f1=TF1("f1", "sin(x)/x", -10.0, 10.0)
f1.Draw()
c1.Update()
raw_input('Press <ret> to end -> ')
% python myprog3.py

インピーダンス測定とカーブフィッティング(4)

vectors2

先ほど求めたパラメータp0とp2を用いれば、数値的には以下のようになります。

vector(red)    = 1.0*cexp(i*0.0) = (1.0, 0.0)
vector(green)  = vector(red) = (1.0, 0.0)
vector(yellow) = 0.778415*vector(red)*cexp(i*-0.531850) = (0.670893, -0.394757)
vector(purple) = 2*vector(red)-vector(yellow) = (1.32911, 0.394757)

これで、DUTのインピーダンスを計算する準備ができました。

Z(DUT) = 50 ohm * vector(yellow) / vector(purple)   <-- because the current is the same.
       = 50 ohm * (0.670893, -0.394757) / (1.32911, 0.394757)
       = 50 ohm * (0.382787,-0.4107)
       = (19.1394,-20.535) ohm

VSWRを計算するための短いプログラムです。

#include <complex>
#include <iostream>
using namespace std;
int main() {
 complex<double> x(0.670893, -0.394757);
 complex<double> y(1.32911 ,  0.394757);
 complex<double> rho;
 double vswr;
 cout << x << y << x/y << 50.0*x/y << endl;
 rho  = (x/y-1.0)/(x/y+1.0);
 vswr = (1.0+abs(rho))/(1.0-abs(rho));
 cout << rho << vswr << endl;
 return 0;
}

このプログラムの出力は:

% ./a.out
(0.670893,-0.394757)(1.32911,0.394757)(0.382787,-0.4107)(19.1394,-20.535)
(-0.329108,-0.394756)3.1148

Z(DUT)からVSWRを求めるのには、スミスチャートを用いることもできます。

smith1

インピーダンス測定とカーブフィッティング(3)

root4

vectors

図では、2つの信号がベクトルとして表現されています。赤色の方は基準信号で、黄色の方はDUTに掛かる信号です。実際には、2つのベクトルは信号源の周波数7026kHzで反時計回り(そう決めたのです)に回転していますが、私たちはベクトルの相対的な関係にしか興味がありません。

さて、どのようにしてDUTのインピーダンスを知ることができるでしょうか?測定回路のことを思い出せば、私たちは図中にさらに2つのベクトルを加えることができます。

directionalbridge2

vectors2

ここで、赤色と緑色のベクトルは同一であることに注意して下さい。なぜならば、2つの50オーム抵抗は直列に接続されているからです。紫色のベクトルは、赤色のベクトルを2倍したものと、黄色のベクトルとの差分として求めることができます。