Я пытаюсь оптимизировать некоторый код здесь и написал две разные простые подпрограммы, которые будут вычитать один вектор из другого. Я передаю этим подпрограммам пару векторов, и затем выполняется вычитание. Первая подпрограмма использует промежуточную переменную для хранения результата, тогда как вторая выполняет встроенную операцию с использованием оператора '- ='. Полный код находится внизу этого вопроса.
Когда я использую чисто реальные числа, программа работает нормально и проблем нет. Однако, если я использую сложные операнды, то исходные векторы (те, которые изначально были переданы подпрограммам) изменяются! Почему эта программа отлично работает с чисто действительными числами, но выполняет подобную модификацию данных при использовании комплексных чисел?
Обратите внимание на мой процесс:
- Генерация случайных векторов (реальных или сложных в зависимости от закомментированного кода)
- Вывести основные векторы на экран
- Выполните первое вычитание подпрограммы (используя третью переменную посредника в подпрограмме)
- Снова выведите основные векторы на экран, чтобы убедиться, что они не изменились, независимо от того, используются ли действительные или комплексные векторы.
- Выполните второе вычитание подпрограммы (используя метод встроенных вычислений)
- Снова выведите основные векторы на экран, показывая, что @ main_v1 изменилась при использовании сложных векторов, но не изменится при использовании реальных векторов (@ main_v2 не изменится)
- Выведите окончательные ответы на вычитание, которые всегда являются правильными, независимо от действительных или комплексных векторов.
Проблема возникает из-за того, что в случае второй подпрограммы (которая работает немного быстрее) я не хочу, чтобы вектор @ main_v1 изменялся. Мне нужен этот вектор для дальнейших вычислений в будущем, так что мне нужно, чтобы он оставался прежним.
Есть идеи, как это исправить, или что я делаю не так? Весь мой код приведен ниже и должен быть работоспособным. Я использовал синтаксис CLI, показанный ниже, для запуска программы. Я выбираю 5, чтобы мне все было легко читать.
c: \> bench.pl 5 НАСТОЯЩИЙ
or
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";
}
Я даже попытался изменить вторую подпрограмму так, чтобы в ней были следующие строки, и она ВСЕ ЕЩЕ изменяет вектор @ main_v1 при использовании комплексных чисел ... Я совершенно не понимаю, что происходит.
@result = @vector1;
for($row=1;$row<=$dim1;$row++){$result[$row] -= $vector2[$row]}
return(@result);
и я тоже пробовал ... все еще изменяет @ main_V1 комплексными числами
for($row-1;$row<=$dim1;$row++){$result[$row] = $vector1[$row]}
for($row=1;$row<=$dim1;$row++){$result[$row] -= $vector2[$row]}
return(@result);