私はここでいくつかのコードを最適化しようとしており、別の1つのベクトルを減算する2つの異なる単純なサブルーチンを書いています。私はこれらのサブルーチンに一対のベクトルを渡し、次に減算が実行されます。最初のサブルーチンは中間変数を使用して結果を格納し、2番目のサブルーチンは ' - ='演算子を使用してインライン演算を行います。完全なコードは、この質問の最後にあります。Math :: Complex私の配列の参照を台無しにする
純粋な実数を使用すると、プログラムは問題なく動作しますが、問題はありません。しかし、複雑なオペランドを使用している場合、オリジナルのベクトル(元々はサブルーチンに渡されたもの)が変更されます。なぜこのプログラムは純粋な実数に対してはうまくいくのですか?複素数を使用すると、この種のデータ修正を行うのはなぜですか?使用して(
- 印刷画面への主なベクトルを
- は、最初のサブルーチンの減算を実行します(コメントアウトコードに応じて、実数または複素数のいずれか)乱数ベクトルを生成します。
は私のプロセスに注意してください。サブルーチン内の3番目の変数媒介変数)
- 実ベクトルまたは複素ベクトルの使用に関係なく、それらが変更されていないことを証明するために再び主ベクトルをスクリーンに表示します。
- 2番目のサブルーチン減算を実行する(インライン計算方法を使用)
- メインベクトルを画面にもう一度表示すると、複雑なベクトルを使用すると@ main_v1が変更されたが、実際のベクトルを使用すると変更されない(@ main_v2は影響を受けない)
- プリント常に正しい答えである減算への最終的な回答を、関係なく、実数または複素数ベクトルの
問題は、(かなり高速である)は、第2のサブルーチンの場合に生じ、 @ main_v1ベクトルを変更したくありません。私は道路をさらに計算するためにそのベクトルが必要なので、同じままにする必要があります。
これを修正する方法や、間違っていることはありますか?私のコード全体は以下の通りで、機能的でなければなりません。私は以下のCLI構文を使ってプログラムを実行しています。私はすべてを読みやすいように5を選択します。
C:\> bench.pl 5 REAL
または
C:\> bench.pl 5 IMAG
#!/usr/local/bin/perl
# when debugging: add -w option above
#
use strict;
use warnings;
use Benchmark qw (:all);
use Math::Complex;
use Math::Trig;
use Time::HiRes qw (gettimeofday);
system('cls');
my $dimension = $ARGV[0];
my $type = $ARGV[1];
if(!$dimension || !$type){
print "bench.pl <n> <REAL | IMAG>\n";
print " <n> indicates the dimension of the vector to generate\n";
print " <REAL | IMAG> dictates to use real or complex vectors\n";
exit(0);
}
my @main_v1;
my @main_v2;
my @vector_sum1;
my @vector_sum2;
for($a=1;$a<=$dimension;$a++){
my $r1 = sprintf("%.0f", 9*rand)+1;
my $r2 = sprintf("%.0f", 9*rand)+1;
my $i1 = sprintf("%.0f", 9*rand)+1;
my $i2 = sprintf("%.0f", 9*rand)+1;
if(uc($type) eq "IMAG"){
# Using complex vectors has the issue
$main_v1[$a] = cplx($r1,$i1);
$main_v2[$a] = cplx($r2,$i2);
}elsif(uc($type) eq "REAL"){
# Using real vectors shows no issue
$main_v1[$a] = $r1;
$main_v2[$a] = $r2;
}else {
print "bench.pl <n> <REAL | IMAG>\n";
print " <n> indicates the dimension of the vector to generate\n";
print " <REAL | IMAG> dictates to use real or complex vectors\n";
exit(0);
}
}
# cmpthese(-5, {
# v1 => sub {@vector_sum1 = vector_subtract(\@main_v1, \@main_v2)},
# v2 => sub {@vector_sum2 = vector_subtract_v2(\@main_v1, \@main_v2)},
# });
# print "\n";
print "main vectors as defined initially\n";
print_vector_matlab(@main_v1);
print_vector_matlab(@main_v2);
print "\n";
@vector_sum1 = vector_subtract(\@main_v1, \@main_v2);
print "main vectors after the subtraction using 3rd variable\n";
print_vector_matlab(@main_v1);
print_vector_matlab(@main_v2);
print "\n";
@vector_sum2 = vector_subtract_v2(\@main_v1, \@main_v2);
print "main vectors after the inline subtraction\n";
print_vector_matlab(@main_v1);
print_vector_matlab(@main_v2);
print "\n";
print "subtracted vectors from both subroutines\n";
print_vector_matlab(@vector_sum1);
print_vector_matlab(@vector_sum2);
sub vector_subtract {
# subroutine to subtract one [n x 1] vector from another
# result = vector1 - vector2
#
my @vector1 = @{$_[0]};
my @vector2 = @{$_[1]};
my @result;
my $row = 0;
my $dim1 = @vector1 - 1;
my $dim2 = @vector2 - 1;
if($dim1 != $dim2){
syswrite STDOUT, "ERROR: attempting to subtract vectors of mismatched dimensions\n";
exit;
}
for($row=1;$row<=$dim1;$row++){$result[$row] = $vector1[$row] - $vector2[$row]}
return(@result);
}
sub vector_subtract_v2 {
# subroutine to subtract one [n x 1] vector from another
# implements the inline subtraction method for alleged speedup
# result = vector1 - vector2
#
my @vector1 = @{$_[0]};
my @vector2 = @{$_[1]};
my $row = 0;
my $dim1 = @vector1 - 1;
my $dim2 = @vector2 - 1;
if($dim1 != $dim2){
syswrite STDOUT, "ERROR: attempting to subtract vectors of mismatched dimensions\n";
exit;
}
for($row=1;$row<=$dim1;$row++){$vector1[$row] -= $vector2[$row]} # subtract inline
return(@vector1);
}
sub print_vector_matlab { # for use with outputting square matrices only
my (@junk) = (@_);
my $dimension = @junk - 1;
print "V=[";
for($b=1;$b<=$dimension;$b++){
# $temp_real = sprintf("%.3f", Re($junk[$b][$c]));
# $temp_imag = sprintf("%.3f", Im($junk[$b][$c]));
# $temp_cplx = cplx($temp_real,$temp_imag);
print "$junk[$b];";
# print "$temp_cplx,";
}
print "];\n";
}
私もしました次の行を持つように第2のサブルーチンを修正しようとしました。そして、cを使うときに@ main_v1ベクトルを変更しますomplex numbers ...私は何が起こっているかについて完全に混乱しています。
@result = @vector1;
for($row=1;$row<=$dim1;$row++){$result[$row] -= $vector2[$row]}
return(@result);
と私はあまりにもこれを試してみたが...まだオブジェクトがblessされたリファレンスで、複素数Perlで
for($row-1;$row<=$dim1;$row++){$result[$row] = $vector1[$row]}
for($row=1;$row<=$dim1;$row++){$result[$row] -= $vector2[$row]}
return(@result);
おそらく、実際の出力と予想される出力を示すことで明確にする必要があります。 – TLP