0

C++ で複素数の Valarray の最高の要素を出力するにはどうすればよいですか?

このコードを試してみましたが、エラー メッセージが返されます

#include <iostream>     // std::cout
#include <valarray> 
#include <complex>// std::valarray


typedef std::complex<double> Complex;
typedef std::valarray <Complex > CArray;


int main ()
{
  CArray y[5]={{1, 2},{3, 4},{2,0},{7,0},{9,0}};

  std::cout << "The max is " << y.max() << '\n';

  return 0;
}

出力:

main.cpp: In function 'int main()':
main.cpp:15:35: error: request for member 'max' in 'y', which is of non-class type 'CArray [5] {aka std::valarray<std::complex<double> > [5]}'
   std::cout << "The max is " << y.max() << '\n';
                                   ^

私が間違っていることは何ですか?

コードを少し変更したコードの 2 番目のバージョン。今度は、Valarray の最上位の要素に対応するすべてのインデックスを取得したいと思います。この場合、要素 {9,0} に対応するすべてのインデックスを取得します。

注:「最高の要素」とは、実部が最も高い要素を意味します

新しいコード:

#include <iostream>
#include <valarray> 
#include <complex>
#include <algorithm>
#include <numeric>
typedef std::complex<double> Complex;
typedef std::valarray <Complex > CArray;

int main ()
{
    CArray y={{1, 2},{3, 4},{2,0},{9,0},{7,0},{9,0}};
    auto max_val = std::accumulate (std::begin(y), std::end(y), *std::begin(y),
        [](const Complex& a ,const Complex& b)
        {
            auto abs_a = abs(a);
            auto abs_b = abs(b);
            //if(abs_a == abs_b)
               // return std::max(arg(a), arg(b));
            return std::max(abs_a, abs_b);
        }
    );
  for (std::size_t i =std::begin(y) ; i != std::end(y) ;  i++) {
      std::cout << "The max is found on index ["<< i <<"]" << max_val<< '\n';

  }


  return 0;
}

次のエラーが表示されます: 出力:

main.cpp: In function 'int main()':
main.cpp:22:35: error: invalid conversion from 'std::complex<double>*' to 'std::size_t {aka long unsigned int}' [-fpermissive]
   for (std::size_t i =std::begin(y) ; i != std::end(y) ;  i++) {
                                   ^
main.cpp:22:54: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
   for (std::size_t i =std::begin(y) ; i != std::end(y) ;  i++) {
                                                      ^
4

3 に答える 3

3
  1. yは s の配列であるため、配列自体ではなく、その配列の各要素valarrayを呼び出す必要があります(もちろんメンバー関数はありません)。max
  2. std::complexは比較可能な型ではないので、「最高」の要素を持つとはどういう意味ですか?

更新:あなたの編集に関して、私はあなたが何を求めているのか理解していると思います...

real()max (by ) 要素の最大インデックスの場合:

std::size_t max_index(CArray const& y) {
    struct acc_t {
        double max_value;
        std::size_t max_idx, current_idx;

        constexpr acc_t next() const { return {max_value, max_idx, current_idx + 1}; }
        constexpr acc_t next_with(Complex const c) const {
            return {c.real(), current_idx, current_idx + 1};
        }
    };

    return std::accumulate(
        std::begin(y), std::end(y), acc_t{},
        [](acc_t const acc, Complex const c) {
            return c.real() < acc.max_value
              ? acc.next()
              : acc.next_with(c);
        }
    ).max_idx;
}

Online Demo

または、最大要素のすべてのインデックスに対して:

std::vector<std::size_t> max_indices(CArray const& y) {
    struct acc_t {
        std::vector<std::size_t> max_idcs;
        double max_value;
        std::size_t current_idx;

        constexpr acc_t&& next() {
            ++current_idx;
            return std::move(*this);
        }
        acc_t&& next_with_current() {
            max_idcs.push_back(current_idx++);
            return std::move(*this);
        }
        acc_t&& next_with(Complex const c) {
            max_value = c.real();
            max_idcs.clear();
            return next_with_current();
        }
    };

    return std::accumulate(
        std::begin(y), std::end(y), acc_t{},
        [](acc_t& acc, Complex const c) {
            return c.real() < acc.max_value ? acc.next()
                 : c.real() > acc.max_value ? acc.next_with(c)
                 :                            acc.next_with_current();
        }
    ).max_idcs;
}

Online Demo

Nb あなたのコードがabs関与していますが、 に基づいて比較したいだけだと言っていたので、理由はstd::complex<>::real()わかりません。そのため、省略しました...

于 2016-07-17T06:51:34.950 に答える
0

元のコードのより大きな問題は、(Ildjarn が指摘したように)その Complex の欠如でしoperator<た。

Complexもう少し複雑にする必要があると思います(言葉遊びを許可する場合)。

Complex次の解決策は、派生元でstd::complex<double>あり、友人を宣言することを提案しますoperator< ()。多くのoperator< ()可能性の1つ。

#include <iostream>
#include <valarray> 
#include <complex>

struct Complex: public std::complex<double>
 {
   template <typename ... Args>
      Complex (const Args & ... args) : std::complex<double>{args...}
    { }

   friend bool operator< (const Complex & c1, const Complex & c2)
    {
      return (c1.real() < c2.real())
         || ((c1.real() == c2.real()) && (c1.imag() < c2.imag()));
    }
 };

typedef std::valarray <Complex > CArray;

int main ()
 {
   CArray y { {1.0,2.0}, {3.0,4.0}, {2.0,0.0}, {7.0,0.0}, {9.0,0.0} };

   std::cout << "The max is " << y.max() << '\n';

   return 0;
 }

Complexテンプレート化されたクラスにすることができることを受け入れる場合(Class<double>の代わりに を使用すると、この方法でより一般的なソリューションを作成できます (これは、およびComplexに基づく複雑なものでも使用できます) 。floatlong double

#include <iostream>
#include <valarray> 
#include <complex>

template <typename T>
struct Complex: public std::complex<T>
 {
   template <typename ... Args>
      Complex (const Args & ... args) : std::complex<T>{args...}
    { }

   friend bool operator< (const Complex & c1, const Complex & c2)
    {
      return (c1.real() < c2.real())
         || ((c1.real() == c2.real()) && (c1.imag() < c2.imag()));
    }
 };

typedef std::valarray <Complex<double>> CArray;

int main ()
 {
   CArray y { {1.0,2.0}, {3.0,4.0}, {2.0,0.0}, {7.0,0.0}, {9.0,0.0} };

   std::cout << "The max is " << y.max() << '\n';

   return 0;
 }

ps: C++11 でも動作するはずです。

ps2: 下手な英語でごめんなさい。

--- max 要素のインデックスを取得するように編集 ---

#include <iostream>
#include <valarray> 
#include <complex>

template <typename T>
struct Complex: public std::complex<T>
 {
   template <typename ... Args>
      Complex (const Args & ... args) : std::complex<T>{args...}
    { }

   friend bool operator< (const Complex & c1, const Complex & c2)
    {
      return (c1.real() < c2.real())
         || ((c1.real() == c2.real()) && (c1.imag() < c2.imag()));
    }
 };

typedef std::valarray <Complex<double>> CArray;

int main ()
 {
   CArray y { {1.0,2.0}, {3.0,4.0}, {2.0,0.0}, {7.0,0.0}, {9.0,0.0} };

   auto m = 0U;

   for ( auto i = 1U ; i < y.size() ; ++i)
      if ( y[m] < y[i] )
         m = i;

   std::cout << "The max is found on index ["<< m <<"] and is " << y[m]
      << std::endl;

   return 0;
 }
于 2016-07-17T11:46:22.630 に答える