How to change the outerstride in Eigen matrices without using map function - matrix

I want to change the outerstride of Eigen matrix at compile time without using map function.
I tried to change this using OuterStrideAtCompileTime variable,but it doesn't work.Is there any way to do that ?
One more thing printing mat.Outerstride() every time gives number of rows of input matrix.How to print OuterStride of eigen matrix?
Thanks in advance.
I was defining an eigen matrix with map function like
MatrixXf mat;
float arr[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
mat = Map<Matrix<float,Dynamic,Dynamic,Eigen::RowMajor>, 0, OuterStride<Dynamic> > (arr,4,4,OuterStride<Dynamic>(5));
It's working fine, whenever I tried to change the outer stride by using
mat.OuterStrideAtCompileTime = 7;
It's not working.

Outer stride is a parameter related to the data storage. A more commonly used name is leading dimension. You could find some explaination here.
http://www.ibm.com/support/knowledgecenter/SSFHY8_5.3.0/com.ibm.cluster.essl.v5r3.essl100.doc/am5gr_leaddi.htm
Basically for an existing matrix, it can not be changed. The only way to change it without changing the elements of the matrix is to copy the matrix to a new memory space using a different outer stride setting. This usually happens when you copy a matrix into another as a sub-matrix.
For a column major matrix the minimum possible outer stride equals to the number of rows, as the number you have printed out.
When using Eigen, you don't need worry about it as Eigen usually takes care of it for you expect for Eigen::Map.
You code actually doesn't work. Setting out stride to 5 is already out of range as the existing matrix(4x4) stored in arr is of stride 4 and stride 5 x 4 columns = 20 > 16.
#include <iostream>
#include <Eigen/Eigen>
int main(void) {
using namespace Eigen;
MatrixXf mat;
float arr[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
mat = Map<Matrix<float, Dynamic, Dynamic, Eigen::RowMajor>, 0,
OuterStride<Dynamic> >(arr, 4, 4, OuterStride<Dynamic>(5));
std::cout << "mat with stride 5:\n" << mat << std::endl;
mat = Map<Matrix<float, Dynamic, Dynamic, Eigen::RowMajor>, 0,
OuterStride<Dynamic> >(arr, 4, 4, OuterStride<Dynamic>(4));
std::cout << "mat with stride 4:\n" << mat << std::endl;
return 0;
}
Please compare the output.
mat with stride 5:
1 2 3 4
6 7 8 9
11 12 13 14
16 0 0 5.01639e-14
mat with stride 4:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
If you extend the array to 20 elements
#include <iostream>
#include <Eigen/Eigen>
int main(void) {
using namespace Eigen;
MatrixXf mat;
float arr[20] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
Map<Matrix<float, Dynamic, Dynamic, Eigen::RowMajor>, 0, OuterStride<Dynamic> > map1(arr, 4, 4, OuterStride<Dynamic>(5));
mat = map1;
std::cout << "map1 outer stride: " << map1.outerStride() << std::endl << map1 << std::endl;
std::cout << "mat outer stride: " << mat.outerStride() << std::endl << mat << std::endl;
Map<Matrix<float, Dynamic, Dynamic, Eigen::RowMajor>, 0, OuterStride<Dynamic> > map2(arr, 4, 4, OuterStride<Dynamic>(4));
mat = map2;
std::cout << "map2 outer stride: " << map2.outerStride() << std::endl << map2 << std::endl;
std::cout << "mat outer stride: " << mat.outerStride() << std::endl << mat << std::endl;
return 0;
}
The output will be
map1 outer stride: 5
1 2 3 4
6 7 8 9
11 12 13 14
16 17 18 19
mat outer stride: 4
1 2 3 4
6 7 8 9
11 12 13 14
16 17 18 19
map2 outer stride: 4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
mat outer stride: 4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
You could also see the outer stride changes when copying map1 to mat.
Hope this give you a better view of what out stride is.
In fact in your original code, you are using Map in a wrong way - you shouldn't have copied Map() to Matrix mat.
That's why when you print the stride of mat, it is always 4.
What you need to do is to eliminate the unnecessary data copy and print the stride of map1/map2.

Related

gdb query xmm-registers, select representation [duplicate]

I've been using GDB for 1 day and I've accumulated a decent understanding of it.
However when I set a breakpoint at the final semicolon using GDB and print registers I can't fully interpret the meaning of the data stored into the XMM register.
I don't know if the data is in (MSB > LSB) format or vice versa.
__m128i S = _mm_load_si128((__m128i*)Array16Bytes);
}
So this is the result that I'm getting.
(gdb) print $xmm0
$1 = {
v4_float = {1.2593182e-07, -4.1251766e-18, -5.43431603e-31, -2.73406277e-14},
v2_double = {4.6236050467459811e-58, -3.7422963639201271e-245},
v16_int8 = {52, 7, 55, -32, -94, -104, 49, 49, -115, 48, 90, -120, -88, -10, 67, 50},
v8_int16 = {13319, 14304, -23912, 12593, -29392, 23176, -22282, 17202},
v4_int32 = {872888288, -1567084239, -1926210936, -1460255950},
v2_int64 = {3749026652749312305, -8273012972482837710},
uint128 = 0x340737e0a29831318d305a88a8f64332
}
So would someone kindly guide me how to interpret the data.
SSE (XMM) registers can be interpreted in various different ways. The register itself has no knowledge of the implicit data representation, it just holds 128 bits of data. An XMM register can represent:
4 x 32 bit floats __m128
2 x 64 bit doubles __m128d
16 x 8 bit ints __m128i
8 x 16 bit ints __m128i
4 x 32 bit ints __m128i
2 x 64 bit ints __m128i
128 individual bits __m128i
So when gdb displays an XMM register it gives you all possible interpretations, as seen in your example above.
If you want to display a register using a specific interpretation (e.g. 16 x 8 bit ints) then you can do it like this:
(gdb) p $xmm0.v16_int8
$1 = {0, 0, 0, 0, 0, 0, 0, 0, -113, -32, 32, -50, 0, 0, 0, 2}
As for endianness, gdb displays the register contents in natural order, i.e. left-to-right, from MS to LS.
So if you have the following code:
#include <stdio.h>
#include <stdint.h>
#include <xmmintrin.h>
int main(int argc, char *argv[])
{
int8_t buff[16] __attribute__ ((aligned(16))) = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
__m128i v = _mm_load_si128((__m128i *)buff);
printf("v = %vd\n", v);
return 0;
}
If you compile and run this you will see:
v = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
However if you step through the code in gdb and examine v you will see:
v16_int8 = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}

Maximum sum of values with constant sum of indices

I am looking for an efficient algorithm for the following problem:
There is an array with values, i.e. (note that index 0 is omitted on purpose)
Index 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
Value 17, 12, 5, 22, 3, 12, 6, 13, 7, 0, 2, 15
What I need to find is a subset of indices under these constraints:
The number of indices is constant (i.e. 3)
The sum of indices is constant (i.e. 20)
Each index may only appear once (so [2, 9, 9] is not a valid solution)
The sum of values is maximum.
For example if the subset length is 3 and the sum is 20, all possible solutions would be
Indices: [1, 7, 12] Sum of values: 17 + 6 + 15 = 38
Indices: [1, 8, 11] Sum of values: 17 + 13 + 2 = 32
Indices: [1, 9, 10] Sum of values: 17 + 7 + 0 = 24
Indices: [2, 6, 12] Sum of values: 12 + 12 + 15 = 39
Indices: [2, 7, 11] Sum of values: 12 + 6 + 2 = 20
Indices: [2, 8, 10] Sum of values: 12 + 13 + 0 = 25
Indices: [3, 5, 12] Sum of values: 5 + 3 + 15 = 23
Indices: [3, 6, 11] Sum of values: 5 + 12 + 2 = 19
Indices: [3, 7, 10] Sum of values: 5 + 6 + 0 = 11
Indices: [3, 8, 9] Sum of values: 5 + 13 + 7 = 25
Indices: [4, 5, 11] Sum of values: 22 + 3 + 2 = 27
Indices: [4, 6, 10] Sum of values: 22 + 12 + 0 = 34
Indices: [4, 7, 9] Sum of values: 22 + 6 + 7 = 35
Indices: [5, 6, 9] Sum of values: 3 + 12 + 7 = 22
Indices: [5, 7, 8] Sum of values: 3 + 6 + 13 = 22
of which [2, 6, 12] is the optimal solution because it has the maximum sum of values.
At the moment I run through all possible combinations using a slightly modified partition algorithm which grows exponentially as the sum of indices grows, so I wonder if there is any better way?
Solution O(I.S.K)
Let's do some naming first:
I is the greatest index (12 in your example)
S is the sum of values whose indices are selected (20 in your example)
K is the number of selected indices
V[] the array of values linked to the indices
maxsum(s, i, k) the maximal sum reachable by using k indices, all differents, whose value is less than or equal to i and whose sum is s.
Then you want to find maxsum(S, I, K)
Your problem exhibits some good properties:
optimal sub-structure
redundant sub-problems
For instance, when trying to compute maxsum(s, i, k) I can either not use index i, in which case the value is maxsum(s, i-1, k). Or I could use index i. In this case, I want to solve the sub-problem: what is the maximum sum reachable by indices less than or equal to i-1 and whose sum is s-i using k-1 such indices. This is the value: V[i] + maxsum(s-i, i-1, k-1).
As we want to reach the maximal sum we end up having: (Edit: corrected maxsum(s-i, i-1, k) to maxsum(s-i, i-1, k-1))
maxsum(s, i, k) = max{ maxsum(s, i-1, k) ; V[i] + maxsum(s-i, i-1, k-1) }
This is typical of a problem solvable by dynamic programming.
Here is an example C++ program solving the problem in O(I.S.K) (space and time).
We can improve the space complexity to O(I.S) at the price of a bigger time complexity: O(I.S.K²).
How to use the program
g++ -std=c++14 -g -Wall -O0 dp.cpp -o dp
./dp input.txt
Where input.txt is a file with the following format:
first line contains three integers: I S K
second line contains I integers, the values of the indices
Example run
---- K=1 ----
17 12 5 22 3 12 6 13 7 0 2 15
[ 1][ 2][ 3][ 4][ 5][ 6][ 7][ 8][ 9][10][11][12]
[ 1] 17 17 17 17 17 17 17 17 17 17 17 17
[ 2] 12 12 12 12 12 12 12 12 12 12 12
[ 3] 5 5 5 5 5 5 5 5 5 5
[ 4] 22 22 22 22 22 22 22 22 22
[ 5] 3 3 3 3 3 3 3 3
[ 6] 12 12 12 12 12 12 12
[ 7] 6 6 6 6 6 6
[ 8] 13 13 13 13 13
[ 9] 7 7 7 7
[10] 0 0 0
[11] 2 2
[12] 15
[13]
[14]
[15]
[16]
[17]
[18]
[19]
[20]
---- K=2 ----
17 12 5 22 3 12 6 13 7 0 2 15
[ 1][ 2][ 3][ 4][ 5][ 6][ 7][ 8][ 9][10][11][12]
[ 1]
[ 2] 12 12 12 12 12 12 12 12 12 12 12
[ 3] 29 29 29 29 29 29 29 29 29 29 29
[ 4] 22 22 22 22 22 22 22 22 22 22
[ 5] 17 39 39 39 39 39 39 39 39 39
[ 6] 34 34 34 34 34 34 34 34 34
[ 7] 27 27 29 29 29 29 29 29 29
[ 8] 8 24 24 24 24 24 24 24
[ 9] 25 25 25 30 30 30 30 30
[10] 34 34 34 34 34 34 34
[11] 15 28 28 28 28 28 28
[12] 9 35 35 35 35 35
[13] 18 18 29 29 29 32
[14] 25 25 25 25 27
[15] 19 19 19 24 24
[16] 13 13 13 37
[17] 20 20 20 20
[18] 13 13 27
[19] 7 15 21
[20] 9 28
---- K=3 ----
17 12 5 22 3 12 6 13 7 0 2 15
[ 1][ 2][ 3][ 4][ 5][ 6][ 7][ 8][ 9][10][11][12]
[ 1]
[ 2]
[ 3]
[ 4]
[ 5] 17 17 17 17 17 17 17 17 17 17
[ 6] 34 34 34 34 34 34 34 34 34 34
[ 7] 51 51 51 51 51 51 51 51 51
[ 8] 44 44 44 44 44 44 44 44 44
[ 9] 39 39 41 41 41 41 41 41 41
[10] 42 42 42 42 42 42 42 42
[11] 37 51 51 51 51 51 51 51
[12] 30 46 46 46 46 46 46 46
[13] 39 40 52 52 52 52 52
[14] 20 35 47 47 47 47 47
[15] 37 37 42 42 42 42 44
[16] 31 37 37 37 41 41
[17] 40 40 40 40 40 54
[18] 21 47 47 47 47 49
[19] 41 41 41 41 44
[20] 22 35 35 35 39
index: 12 sum: 20
index: 6 sum: 8
index: 2 sum: 2
max sum: 39
The source code
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <limits>
#include <valarray>
#include <vector>
using namespace std;
auto const INF = numeric_limits<double>::infinity();
struct matrix {
matrix(size_t rows, size_t cols, double value)
: cells(value, rows*cols)
, rows(rows)
, cols(cols)
, value(value)
{}
double& operator() (int r, int c)
{
if(r < 0 || c < 0)
return value;
return cells[r*cols+c];
}
valarray<double> cells;
size_t rows;
size_t cols;
double value;
};
int main(int argc, char* argv[]) {
if(argc > 1)
freopen(argv[1], "r", stdin);
// I: max index
// S: sum of indices
// K: number of indices in the sum S
int I, S, K;
cin >> I >> S >> K;
// load values
vector<double> V(I+1, 0);
for(int i=1; i<=I; ++i)
cin >> V[i];
// dynamic programming:
// --------------------
// maxsum(i, s, k) is the maximal sum reachable using 'k' indices, less
// than or equal to 'i', all differents, and having a sum of 's'
//
// maxsum(i, s, k) =
// -oo if i > s
//
// -oo if i < s && k == 1
//
// V[s] if i >= s && s <= I && k == 1
// -oo if (i < s || s > I) && k == 1
//
// max { V[i] + maxsum(i-1, S-i, k-1), maxsum(i-1, S, k) }
vector<matrix> maxsum(K+1, matrix(S+1, I+1, -INF));
// initialize K=1
for(int s=0; s<=I && s<=S; ++s) {
for(int i=s; i<=I; ++i) {
maxsum[1](s, i) = V[s];
}
}
// K > 1
for(int k=2; k<=K; ++k) {
for(int s=2; s<=S; ++s) {
for(int i=1; i<=I; ++i) {
auto l = V[i] + maxsum[k-1](s-i, i-1);
auto r = maxsum[k](s, i-1);
maxsum[k](s, i) = max(l, r);
}
}
}
// display the whole dynamic programming tables (optional)
for(int k=1; k<=K; ++k) {
cout << "---- K=" << k << " ----\n";
cout << " ";
for(int i=1; i<=I; ++i) {
cout << setw(3) << V[i] << ' ';
}
cout << '\n';
cout << " ";
for(int i=1; i<=I; ++i) {
cout << '[' << setw(2) << i << ']';
}
cout << '\n';
for(int s=1; s<=S; ++s) {
cout << '[' << setw(2) << s << "] ";
for(int i=1; i<=I; ++i) {
if(maxsum[k](s, i) == -INF) {
cout << " ";
} else {
cout << setw(3) << maxsum[k](s, i) << ' ';
}
}
cout << '\n';
}
}
// output the indices belonging to the solution by working backward in the
// dynamic programming tables
int t_S = S;
int t_I = I;
for(int k=K; k>=1; --k) {
if(t_I <= 0 || t_S <= 0) {
cout << "error...\n";
break;
}
auto m = maxsum[k](t_S, t_I);
int i;
for(i=t_I; i>=1; --i) {
if(maxsum[k](t_S, i) != m)
break;
}
cout << "index: " << setw(3) << (i+1) << ' ';
cout << "sum: " << setw(3) << t_S << '\n';
t_I = i;
t_S = t_S - i - 1;
}
cout << "max sum: " << maxsum[K](S, I) << '\n';
}
Take the arrays, and sort them by value instead of by index (keeping the index-value pairs preserved). Now, starting at the end of the array, take the last k numbers in the indices array, where k is the number of indices you have to have, and sum them up. If it equals the desired sum, great- you are done. If not, take note of the difference (desired sum - actual sum), and add that to the (n - k)th index. Find that index in the index array (ordered by value, mind you), now find your new sum of values (you can optimize this by subtracting out the old index's value and add the new one, instead of recomputing the sum of all k values).
You now have one valid solution, and a lower bound. You know the indices of the rest of the valid solution that can even possibly beat this score must come after the smallest index's value in the value-sorted array. That is:
Both sorted by value-
indices: | bunch of indices | index we found | more | k-1 'random' indices |
values: | bunch of values | value for ^ | more | k-1 largest values |
So we only have to search 'more' and the k-1 largest values for valid indices that satisfy the criteria and also have values that form a larger sum. To do this, we rinse and repeat, moving the smallest of the (n-k-1) elements backwards one, so we effectively try all combination of these elements, but in the order of decreasing subset-sums of our set of k elements. This allows us to continually narrow the space we search as we find larger sums, because know for certain that any sum that contains a smaller value than that of best solution will have a smaller sum (because the rest of the set is already as large as possible).
Pseudo Code:
pair_array = input() // each pair consists of index and value
sort_by_value(pair_array)
best_sum = 0
markers = [n - (k-1) .. n] // mark the k-1 indices being summed
while True:
sum_of_indices = sum_indices(pair_array[markers])
value_sum = sum_value(pair_array[markers])
if pair_array.contains(desired_sum - sum_of_indices): // this lets us effectively reduce our search by a factor of N, given contains uses a hashtable
value_sum += pair_array(pair_array.index(desired_sum - sum_of_indices)).value
if value_sum > best_sum:
best_sum = value_sum
pair_array.remove(0 .. n - (k-1)) // this greatly reduces the combinations checked
if has_next_combination(markers, pair_array):
next_greatest_combination(markers, pair_array) // pick new markers, in a reverse-binary counting fashion (most significant bit first way)
else:
print(best_sum)
break
One small trick I can think if you try to find lets say 3 indexes, is instead of iterating for the 3 indexes you can calculate the 3rd index when you know the first two indexes. For example when you know that
p1 = 1, p2 = 7 => p3 = 20 - (p1 + p2) = 12
This can be generalized when having N indexes the last one can always be inferred from the N-1 previous indexes.
I tried this in Python:
Index = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ]
Value = [17, 12, 5, 22, 3, 12, 6, 13, 7, 0, 2, 15 ]
maxSum = 0 SumInd = 20
for p1 in range(1,len(Index)+1):
for p2 in range(p1,len(Index)+1):
if (p1 + p2 < SumInd) and (p1 != p2):
p3 = SumInd - (p1 + p2) #If you know p1 and p2 calculate p3 index
if (p3 < len(Index)+1) and (p2 != p3) and (p1 != p3):
fooSum = Value[p1-1]+Value[p2-1] + Value[p3-1]
print(p1,p2,p3 , "Sum is ",fooSum)
if maxSum < fooSum:
maxSum = fooSum
print("Max Sum is ", maxSum)
Of course you need to save the indexes when you find maxSum. Also this implementation calculate many similar pairs (e.g. [1,9,10] and [9,10,1]). Perhaps a better solution could eliminate this pairs.
EDIT: Big Improvement I found a way to eliminate most unnecessary checks. Let's say you need 3 indexes. The first one checks the whole range of possible values. Let's say it is index1.
The other two indexes must sum at 20 - ind1 let's call this rest. The list of indexes is always ordered so you can have a back index showing the smallest value(first item in the list bigger than index1) and a front index that show the biggest values (last item in the list). So index2 = backIndex , index3 = frontIndex.
If the rest is smaller than the sum of index2,3 you could increase the back index (get the next bigger value) or if it is larger you decrease the front index until the two indexes meet each other where you break and increase index1. This eliminates checking (1,7,12) and (1,12,7) two times.
The code is here in Python:
maxSum = 0
SumInd = 20
for index_1 in range(1,len(Index)):
rest = SumInd - index_1
backIndex = index_1+1
frontIndex = len(Index)
while backIndex < frontIndex:
if rest > (backIndex + frontIndex):
backIndex = backIndex + 1
elif rest < (backIndex + frontIndex):
frontIndex = frontIndex - 1
else:
fooSum = Value[index_1-1]+Value[backIndex-1] + Value[frontIndex-1]
print("Checking for ",index_1,backIndex,frontIndex,' Sum of values:',fooSum)
if maxSum < fooSum:
indList = [index_1-1,backIndex,frontIndex]
maxSum = fooSum
backIndex = backIndex + 1 #To avoid Inf loop
print("Max Sum is ", maxSum,"at",indList)
and gives these results:
Checking for 1 7 12 Sum of values: 38
Checking for 1 8 11 Sum of values: 32
Checking for 1 9 10 Sum of values: 24
Checking for 2 6 12 Sum of values: 39
Checking for 2 7 11 Sum of values: 20
Checking for 2 8 10 Sum of values: 25
Checking for 3 5 12 Sum of values: 23
Checking for 3 6 11 Sum of values: 19
Checking for 3 7 10 Sum of values: 11
Checking for 3 8 9 Sum of values: 25
Checking for 4 5 11 Sum of values: 27
Checking for 4 6 10 Sum of values: 34
Checking for 4 7 9 Sum of values: 35
Checking for 5 6 9 Sum of values: 22
Checking for 5 7 8 Sum of values: 22
Max Sum is 39 at [1, 6, 12]
This can always be generalized for N indexes. The first N-2 indexes can search the whole range of the list (like index 1 in the case above, also it should be noted that all these indexes start checking from previous index value plus one until the end of the list to eliminate many duplicate checks).
The last two indexes can be calculated like I showed in my code and avoid many duplicate checks.

Eigen: Extracting a block misses some entries

I try to take a block in Eigen:
Eigen::VectorXi v = Eigen::VectorXi::Zero(20);
v << 7, 10, 11, 14, 15, 16, 16, 1, 2, 3, 2, 3, 4, 5, 4, 5, 0, 0, 0, 0;
cout << "v = " << v << endl;
v = v.block(0, 0, 16, 1);
cout << "v = "<< v << endl;
Strangely, the first two entries in v will be zero after taking the block.
The output of the program looks as follows:
v = 7 # start original vector from here
10
11
14
15
16
16
1
2
3
2
3
4
5
4
5
0
0
0
0
v = 0 # start block out of vector, why zero here?
0
11
14
15
16
16
1
2
3
2
3
4
5
4
5
What's going wrong here? Could this be a bug in Eigen or did I missunderstand something from the documentation?
You are experiencing an aliasing problem: v gets resized before v.block(...) gets assigned to the new v. There are two solutions:
Evaluate into a temporary using .eval():
v = v.block(0,0,16,1).eval(); // or
v = v.head(16).eval(); // shorter but equivalent
Or, use conservativeResize() (but only works if you want to keep the top-left corner):
v.conservativeResize(16);
For further reference this page summarizes some common aliasing pitfalls (it also mentions the resizing alias you experienced).

Replacing part of std::vector by smaller std::vector

I wonder what would be the correct way to replace (overwriting) a part of a given std::vector "input" by another, smaller std::vector?
I do neet to keep the rest of the original vector unchanged.
Also I do not need to bother what has been in the original vector and
I don't need to keep the smaller vector afterwards anymore.
Say I have this:
std::vector<int> input = { 0, 0, 1, 1, 2, 22, 3, 33, 99 };
std::vector<int> a = { 1, 2, 3 };
std::vector<int> b = { 4, 5, 6, 7, 8 };
And I want to achieve that:
input = { 1, 2, 3, 4, 5, 6, 7, 8, 99}
What is the right way to do it? I thought of something like
input.replace(input.beginn(), input.beginn()+a.size(), a);
// intermediate input would look like that: input = { 1, 2, 3, 1, 2, 22, 3, 33, 99 };
input.replace(input.beginn()+a.size(), input.beginn()+a.size()+b.size(), b);
There should be a standard way to do it, shouldn't it?
My thoughts on this so far are the following:
I can not use std::vector::assign for it destroys all elements of input
std::vector::push_back would not replace but enlarge the input --> not what I want
std::vector::insert also creates new elements and enlages the input vector but I know for sure that the vectors a.size() + b.size() <= input.size()
std::vector::swap would not work since there is some content of input that needs to remain there ( in the example the last element) also it would not work to add b that way
std::vector::emplace also increases the input.size -> seems wrong as well
Also I would prefer if the solution would not waste performance by unnecessary clears or writing back values into the vectors a or b. My vectors will be very large for real and this is about performance in the end.
Any competent help would be appreciated very much.
You seem to be after std::copy(). This is how you would use it in your example (live demo on Coliru):
#include <algorithm> // Necessary for `std::copy`...
// ...
std::vector<int> input = { 0, 0, 1, 1, 2, 22, 3, 33, 99 };
std::vector<int> a = { 1, 2, 3 };
std::vector<int> b = { 4, 5, 6, 7, 8 };
std::copy(std::begin(a), std::end(a), std::begin(input));
std::copy(std::begin(b), std::end(b), std::begin(input) + a.size());
As Zyx2000 notes in the comments, in this case you can also use the iterator returned by the first call to std::copy() as the insertion point for the next copy:
auto last = std::copy(std::begin(a), std::end(a), std::begin(input));
std::copy(std::begin(b), std::end(b), last);
This way, random-access iterators are no longer required - that was the case when we had the expression std::begin(input) + a.size().
The first two arguments to std::copy() denote the source range of elements you want to copy. The third argument is an iterator to the first element you want to overwrite in the destination container.
When using std::copy(), make sure that the destination container is large enough to accommodate the number of elements you intend to copy.
Also, the source and the target range should not interleave.
Try this:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> input = { 0, 0, 1, 1, 2, 22, 3, 33, 99 };
std::vector<int> a = { 1, 2, 3 };
std::vector<int> b = { 4, 5, 6, 7, 8 };
std::set_union( a.begin(), a.end(), b.begin(), b.end(), input.begin() );
for ( std::vector<int>::const_iterator iter = input.begin();
iter != input.end();
++iter )
{
std::cout << *iter << " ";
}
return 0;
}
It outputs:
1 2 3 4 5 6 7 8 99

How to verify if a word has valid syllables or not?

I need to be able to process one word or words and verify that it has valid syllables. There are some syllabification rules that could be used:
V CV VC CVC CCV CCCV CVCC
where V is a vowel and C is a consonant. e.g.,
pronunciation (5 Pro-nun-ci-a-tion; CCV-CVC-CV-V-CVC)
Or is there a simple code that can be used, or a library in c++? In class we're talking about binary search trees, hash tables, etc, but i can't really see the relation. Any help would appreciated, thanks.
Whenever we have collected a full pattern-string, we can either discard it and begin collecting to a new pattern-string, or keep it and try to get a longer pattern-string. We don't know in advance (without examining the rest of the input-string), whether we should keep or discard the current string, so we need to keep both possibilities in mind.
We can build a state machine that can keep track of this for us. The base-states are identified by the sequence of characters we have examined so far:
State C V
"" {"C"} {"V",""}
"C" {"CC"} {"CV",""}
"CC" {"CCC"} {""}
"CCC" {} {""}
"CV" {"CVC",""} {}
"CVC" {""} {}
"V" {""} {}
Since we don't always know which action to take, we can be in several possible states at once. Those sets of possible states form super-states:
Index Super-state C V
0 {} 0 0 Fail
1 {""} 2 9 Accept
2 {"C"} 3 8
3 {"CC"} 4 1
4 {"CCC"} 0 1
5 {"","C"} 6 13 Accept
6 {"C","CC"} 7 8
7 {"CC","CCC"} 4 1
8 {"","CV"} 12 9 Accept
9 {"","V"} 5 9 Accept
10 {"","C","CC"} 11 13 Accept
11 {"C","CC","CCC"} 7 8
12 {"","C","CVC"} 10 13 Accept
13 {"","CV","V"} 12 9 Accept
The transitions are between super-states. Each member of the super-state is advanced with the same symbol. All members without such transition are discarded. If a member has two possible destinations, both are added to the new super-state.
You might notice that some rows are very similar. Super-state 3 and 7 have the same transitions. As are 6 and 11, and 8 and 13. You could collapse those into one state each, and update the indices. I'm not going to demonstrate that here.
This could easily be encoded into a programming language:
// index = 0 1 2 3 4 5 6 7 8 9 10 11 12 13
int[] consonant = new int[] { 0, 2, 3, 4, 0, 6, 7, 4, 12, 5, 11, 7, 10, 12 };
int[] vocal = new int[] { 0, 9, 8, 1, 1, 13, 8, 1, 9, 9, 13, 8, 13, 9 };
int[] accept = new int[] { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1 };
int startState = 1;
int failState = 0;
bool CheckWord(string word)
{
int state = startState;
foreach (char c in word)
{
if (IsVocal(c))
{
state = vocal[state];
}
else if (IsConsonant(c))
{
state = consonant[state];
}
if (state == failState) return false;
}
return accept[state] != 0;
}
Example:
> CheckWord("pronunciation")
true
> CheckWord("pronunciationn")
false

Resources