Conversation
…ime error if Eigen3 not found.
…d 1x1 and 2x2 MIMO scheme.
…ng the Eigen library.
…() loops for terminated input data.
| // Iterate over tags in buffer. | ||
| for (unsigned int i = 0; i < tags.size(); ++i) { | ||
| // Calculate the number of items before the next tag. | ||
| if (i < tags.size() - 1) { |
There was a problem hiding this comment.
Why not simply split into a for loop with condition i < tags.size() - 1 and a separate i = tags.size()-1?
That'd enhance readability.
There was a problem hiding this comment.
In this case I would have to repeat the code after the if else statement in the for loop for both cases which would worsen the readability again, or am I overseeing something here?
| if (symbol_length < d_training_length){ | ||
| /* We consume the whole training sequence in the next buffer and don't consume it now | ||
| * in order to do the estimation at once. */ | ||
| break; |
There was a problem hiding this comment.
this is the last iteration of the for loop anyway, and this is the last statement in that iteration. Breaking at this point doesn't do anything, or am I mistaken?
There was a problem hiding this comment.
are we perhaps missing the case where symbol length is not smaller than training sequence length and we need to consume now?
There was a problem hiding this comment.
The for loop is not finished after the if else statement. If the symbol length is smaller than the training length, we cannot process the received training sequence right now. So we are breaking the loop (we are on the last iteration, but there would still be the copy and tag assignment operations in this iteration to be done) to skip the rest of the code in the for loop.
There was a problem hiding this comment.
Wait, I'll have to talk to you personally about this, but this is the "else" belonging to the "if(not last iteration)" clause, and that means this else is only executed on the last iteration, and right after the closing bracket of the "else" clause comes the closing bracket of the "for" clause. I'm clearly missing something here!
| uint16_t d_N; /*!< Number of receiving antennas. */ | ||
| std::vector<std::vector<gr_complex> > d_training_sequence; | ||
| /*!< Training matrix: Each subvector/row is sent through one of the M transmit antennas. */ | ||
| uint16_t d_training_length; /*!< Length of the training sequence. */ |
There was a problem hiding this comment.
just out of interest (it's unlikely we find a training sequence longer than 2¹⁶ - 1): Why the uint16_t here?
There was a problem hiding this comment.
This has no specific reason. I am changing it to uint32_t.
| // Collect all tags of the input buffer in the vector 'tags'. | ||
| get_tags_in_window(tags, 0, 0, noutput_items); | ||
|
|
||
| uint16_t symbol_length; // Number of items in the current symbol. |
There was a problem hiding this comment.
are we sure our symbols are limited to 2¹⁶ - 1 items?
| if (tags[0].offset - nitems_read(0) > 0){ | ||
| /* There are items in the input buffer, before the first tag arrives, | ||
| * which belong to the previous symbol. */ | ||
| symbol_length = (tags[0].offset - nitems_read(0))*d_num_inputs; |
There was a problem hiding this comment.
or rather, limited to (2¹⁶-1)/num_inputs? Sounds a bit of a dangerous thing, considering let's say 8×8 DAB MIMO ;)
There was a problem hiding this comment.
I am going to fix these issues in the according branch 'vblast'.
| symbol_length = noutput_items - (tags[i].offset - nitems_read(0))*d_num_inputs; | ||
| } | ||
| // Check the key of the tag. | ||
| if (pmt::symbol_to_string(tags[i].key).compare("csi") == 0) { |
There was a problem hiding this comment.
The whole idea of PMTs having symbols is that a symbol representing the same string is unique. So, instead of converting the symbol to the string and comparing the string you should just have a static pmt_t csi_key here which get initialized once; then you can compare that to the tag key with == directly.
| } | ||
| // Calculate the weighting vector for the next symbol with the received CSI. | ||
| update_mimo_equalizer(); | ||
| } else if (pmt::symbol_to_string(tags[i].key).compare("snr") == 0 && d_equalizer_type.compare("MMSE") == 0) { |
There was a problem hiding this comment.
The problem with comparing the string really is that PMT is horrific. The symbol_to_string function does a dynamic cast of the pmt_base to a pmt_symbol. That's an awful lot of indirection just to compare. Also, in a lot of cases (I think this might be one), this requires a copy of the std::string contained in that PMT to be made (did I ever mention how bad an idea that design is? Like, have "polymorphic type", but it not be properly polymorphic, and it also just inefficiently wrap std types, for communication within the same process?).
std::string copies are relatively expensive and you try to avoid them in the signal processing part, because they require allocation and deallocation of memory.
| gr_complex *out = (gr_complex *) output_items[i]; | ||
| // Write output data to current output port. | ||
| for (int j = 0; j < noutput_items; ++j) { | ||
| out[j] = in[j*d_num_outputs + i]; |
There was a problem hiding this comment.
Do we even need this, or would one of the standard deinterleaver blocks work, too?
There was a problem hiding this comment.
I think if we swap the i loop with the j loop, it becomes evident that this might be solvable more efficiently with a memcpy
| ''' | ||
| 2 tests validating the correct estimation of the channel coefficients with a random channel | ||
| and 1xN MIMO scheme. ''' | ||
| def test_001_t (self): |
There was a problem hiding this comment.
This is fine, but for your own sanity in the future: test methods need to start with test_ and can take names like test_heavier_than_duck.
| pmt.make_f32vector(num_inputs, 1e8), | ||
| pmt.from_long(0)))) | ||
|
|
||
| for i in range(0, num_tags): |
There was a problem hiding this comment.
that's simply range(num_tags) ;)
|
I get merge conflicts. Can you rebase? |
|
Thanks for the review! As discussed, I opened a new branch with the merged master. I am going to request a new pull and this pull request gets obsolete. |
This closes #17.