2010-03-19 16 views
6

Tôi có một mảng 1d chứa dữ liệu Nd, tôi muốn đi qua hiệu quả trên nó với std :: transform hoặc std :: for_each.C++/STL: std :: chuyển đổi với bước tiến nhất định?

unigned int nelems; 
unsigned int stride=3;// we are going to have 3D points 
float *pP;// this will keep xyzxyzxyz... 
Load(pP); 
std::transform(pP, pP+nelems, strMover<float>(pP, stride));//How to define the strMover?? 
+0

Bạn muốn 'strMover' (hoặc toàn bộ' biến đổi ') làm gì? – jpalecek

+0

Xin chào, tôi cần một biến đổi hoàn toàn. Các strMover tôi đã viết chỉ để minh hoạ ... – Arman

Trả lời

1

Vâng, tôi đã quyết định sử dụng for_each thay vì chuyển đổi bất kỳ quyết định khác được chào đón:

generator<unsigned int> gen(0, 1); 
      vector<unsigned int> idx(m_nelem);//make an index 
      std::generate(idx.begin(), idx.end(),gen); 
      std::for_each(idx.begin(), idx.end(), strMover<float>(&pPOS[0],&m_COM[0],stride)); 

nơi

template<class T> T op_sum (T i, T j) { return i+j; } 
template<class T> 
class strMover 
    { 
    T *pP_; 
    T *pMove_; 
    unsigned int stride_; 
    public: 
     strMover(T *pP,T *pMove, unsigned int stride):pP_(pP), pMove_(pMove),stride_(stride) 
      {} 
     void operator() (const unsigned int ip) 
      { 
      std::transform(&pP_[ip*stride_], &pP_[ip*stride_]+stride_, 
       pMove_, &pP_[ip*stride_], op_sum<T>); 
      } 
    }; 

Từ lần đầu tiên nhìn này là một giải pháp an toàn chủ đề.

3

Câu trả lời không thay đổi strMover, nhưng để thay đổi trình lặp của bạn. Xác định một lớp lặp mới kết thúc tốt đẹp float * nhưng di chuyển về phía trước 3 vị trí khi gọi operator++. .

Bạn có thể sử dụng tăng của Permutation Iterator và sử dụng một hoán vị nonstrict mà chỉ bao gồm các phạm vi bạn quan tâm đến

Nếu bạn cố gắng để cuộn iterator của riêng bạn, có một số gotchas: duy trì nghiêm ngặt tiêu chuẩn, bạn cần phải suy nghĩ cẩn thận về những gì "cuối cùng" iterator cho một vòng lặp stride như vậy là, kể từ khi thực hiện ngây thơ sẽ vui vẻ sải chân hơn và vượt quá cho phép "một-qua-the-end" đến khu vực âm u xa quá cuối mảng mà con trỏ không bao giờ nên nhập, vì sợ nasal demons.

Nhưng tôi phải hỏi: tại sao bạn lưu trữ một mảng các điểm 3d như một mảng của float s ở địa điểm đầu tiên? Chỉ cần xác định kiểu dữ liệu Point3D và tạo một mảng thay thế. Đơn giản hơn nhiều.

+0

Tôi muốn +1 nhưng tôi ra, nhưng đây là những gì tôi sẽ nói. Nếu có nhu cầu, tôi sẵn sàng cố gắng viết các trình vòng lặp vào lần tới tôi có thời gian rảnh. – GManNickG

+0

Tôi cho rằng tôi nên lưu ý rằng bởi vì một Iterator Permutation lưu trữ hoán vị của nó như là một danh sách, các Iterator Permutation sẽ không là một iterator truy cập ngẫu nhiên. Tôi không biết nếu điều này sẽ là một vấn đề cho song song 'std :: transform' –

1

Điều này thật kinh khủng, mọi người bảo bạn sử dụng trình vòng lặp xâu chuỗi thay thế. Ngoài việc không thể sử dụng các đối tượng chức năng từ thư viện chuẩn với cách tiếp cận này, bạn làm cho nó rất, rất phức tạp đối với trình biên dịch để tạo ra tối ưu hóa đa lõi hoặc sse bằng cách sử dụng các nạng như thế này. Hãy tìm "stride iterator" cho giải pháp thích hợp, ví dụ trong C++ cookbook.

Và quay lại câu hỏi ban đầu ... sử dụng valarray và sải chân để mô phỏng các mảng đa chiều.

0

sử dụng bộ điều hợp tăng tốc. bạn có thể nhận được vòng lặp của chúng. bất lợi duy nhất là thời gian biên dịch.

vector<float> pp = vector_load(pP); 
boost::for_each(pp|stride(3)|transformed(dosmtn())); 
Các vấn đề liên quan