Eigen MatrixXi to VectorXi conversion - c++

I have a MatrixXi, say
[0, 1, 2]
[0, 2, 3]
[4, 7, 6]
[4, 6, 5]
[0, 4, 5]
[0, 5, 1]
[1, 5, 6]
I get a part of it by doing:
MatrixXi MR = F.middleRows(first, last);
with first and last at will. Now I'd like to turn those n rows into a column VectorXi, like:
[0,
1,
2,
0,
2,
3]
possibly without using a for loop. I've tried:
VectorXi VRT(MR.rows() * MR.cols());
VRT.tail(MR.rows() * MR.cols()) = MR.array();
But I get:
Assertion failed: (rows == this->rows() && cols == this->cols() && "DenseBase::resize() does not actually allow to resize."), function resize, file /Users/max/Developer/Stage/Workspace/AutoTools3D/dep/libigl/external/eigen/Eigen/src/Core/DenseBase.h, line 257.
How do I get that? I'm using Eigen before v4 so I cannot use reshape...
Thank you

As pointed out by chtz, this works:
Eigen::VectorXi VR(MR.size());
Eigen::MatrixXi::Map(VR.data(), MR.cols(), MR.rows()) =
MR.transpose();

Related

How to choose specific row and column indices in C++ Eigen Array?

I wonder how it is possible to choose specific elements in Eigen Array given lists of indices for rows and columns. For example:
array = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
rowIndices = [0, 1, 2]
colIndices = [0, 1, 2]
expectedResult = [1, 5, 9]
I tried something similar to this but didn't get the expected result.
std::vector<int> indices = {0, 1, 2};
array(indices, indices);

Writting in sub-ndarray of a ndarray in the most pythonian way. Python 2

I have a ndarray like this one:
number_of_rows = 3
number_of_columns = 3
a = np.arange(number_of_rows*number_of_columns).reshape(number_of_rows,number_of_columns)
a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
But I want something like this:
array([[0, 100, 101],
[3, 102, 103],
[6, 7, 8]])
To do that I want to avoid to do it one by one, I rather prefer to do it in arrays or matrices, because later I want to extend the code.
Nothe I have change a submatrix of the initial matrix (in mathematical terms, in terms of this example ndarray). In the example the columns considered are [1,2] and the rows [0,1].
columns_to_keep = [1,2]
rows_to_keep = [0,1]
My first try was to do:
a[rows_to_keep,:][:,columns_to_keep] = np.asarray([[100,101],[102,103]])
However this doesn't modify the initial a, I am not having any error, so a=
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
So I have implemented a piece of code that goes do the job:
b = [[100, 101],[102, 103]]
for i in range(len(rows_to_keep)):
a[i,columns_to_keep] = b[i]
Al thought the previous lines do the job I am wondering how to do it slicing and in a faster fashion. Also in a way that with:
columns_to_keep = [0,2]
rows_to_keep = [0,2]
the desired output is
array([[100, 1, 101],
[3, 4, 5],
[102, 7, 103]]).
Many thanks!
Indexing with lists like [1,2] is called advanced indexing. By itself it produces a copy, not a view. You have to use one indexing expression, not two to assign or change values. That is a[[1,2],:] is a copy, a[[1,2],:][:,[1,2]] += 100 modifies that copy, not the original a.
In [68]: arr = np.arange(12).reshape(3,4)
Indexing with slices; this is basic indexing:
In [69]: arr[1:,2:]
Out[69]:
array([[ 6, 7],
[10, 11]])
In [70]: arr[1:,2:] += 100
In [71]: arr
Out[71]:
array([[ 0, 1, 2, 3],
[ 4, 5, 106, 107],
[ 8, 9, 110, 111]])
Doing the same indexing with lists requires arrays that 'broadcast' against each other. ix_ is a handy way of generating these:
In [73]: arr[np.ix_([1,2],[2,3])]
Out[73]:
array([[106, 107],
[110, 111]])
In [74]: arr[np.ix_([1,2],[2,3])] -= 100
In [75]: arr
Out[75]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
Here's what ix_ produces - a tuple of arrays, one is (2,1) in shape, the other (1,2). Together they index a (2,2) block:
In [76]: np.ix_([1,2],[2,3])
Out[76]:
(array([[1],
[2]]), array([[2, 3]]))
For the continuous rows and columns case, you can use basic slicing like this:
In [634]: a
Out[634]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [635]: b = np.asarray([[100, 101],[102, 103]])
In [636]: a[:rows_to_keep[1]+1, columns_to_keep[0]:] = b
In [637]: a
Out[637]:
array([[ 0, 100, 101],
[ 3, 102, 103],
[ 6, 7, 8]])

Prolog: Head of a variable list is not instantated

I'm writing a simple code generating a simple list with 5 numbers whose first variable should be positive and I'm trying to understand why this code fails
test([H|T]) :- H > 0, length(T,4).
when I call with
length(X,5), test(X).
it shows me the following error:
ERROR: Arguments are not sufficiently instantiated
When I debug the code, the H variable in test isn't instantiated.
Anyone know why?
The issue here is that your rule for test([H|T]) doesn't describe in Prolog that H is a positive integer. It only tests if H > 0, which fails since H has not instantiation. Just attempting to compare an uninstantiated variable with a number (H > 0 in this case) doesn't cause Prolog to assume you intended H to be a number, and further, doesn't instantiate H.
Further, your rule for test/1 doesn't describe the rest of the list (T) other than to force that it be length 4. Since you're query establishes the rule that the length of the original list be 5, this stipulation is redundant.
You appear to be wanting to define test(L) such that it means L is an arbitrary list of positive integers. This is generally done using CLP(FD):
:- use_module(library(clpfd)).
test(X) :- X ins 1..10000.
This rule says that X is a list whose values are in the range 1 to 10000. The appropriate query to generate the lists of length 5 would then be:
?- length(X, 5), test(X), label(X).
X = [1, 1, 1, 1, 1] ;
X = [1, 1, 1, 1, 2] ;
X = [1, 1, 1, 1, 3] ;
X = [1, 1, 1, 1, 4] ;
X = [1, 1, 1, 1, 5] ;
...
If you want to restrict it further and say that elements need to be unique, you can use all_different/1:
test(X) :- X ins 1..10000, all_different(X).
?- length(X, 5), test(X), label(X).
X = [1, 2, 3, 4, 5] ;
X = [1, 2, 3, 4, 6] ;
X = [1, 2, 3, 4, 7] ;
X = [1, 2, 3, 4, 8] ;
X = [1, 2, 3, 4, 9] ;
X = [1, 2, 3, 4, 10] ;
...

finding how many times a sequence repeats in a data frame using python

Is there a way to find how many times a sequence repeats in a dataframe?
Lets say I have a dataframe with a large number of 1 and 3's and I wanted to see how much this sequence [3,1,3,3,1] repeats.
here's an example list. 3,1,3,3,1,3,3,1,3,3,1,3,1,1,1,1,3,1,3,1,1,3,3,3
Here's an example of what I'm trying to do
this first part would be true 3,1,3,3,1,3,3,1,3,3,1,3,1,1,1,1,3,1,3,1,1,3,3,3
this second part would be false 3,1,3,3,1,3,3,1,3,3,1,3,1,1,1,1,3,1,3,1,1,3,3,3
and the third part would be false
3,1,3,3,1,3,3,1,3,3,1,3,1,1,1,1,3,1,3,1,1,3,3,3
I want to analyze sections at a time according to the length of the sequence I'm trying to find. In numeric order of the data frame.
My data Is in a dateandtime format. But I can change that.
Thanks for all your help I really appreciate it everything everybody does on this site.
my_list = np.array([3, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 3, 1, 1, 1, 1, 3, 1, 3, 1, 1, 3, 3, 3])
target = np.array([3, 1, 3, 3, 1])
(my_list.reshape(-1, len(sequence)) == sequence[None, :]).all(axis=1)
This converts a list of numbers into a comma separated string, and then compares each sequential chunk to the target.
from itertools import izip_longest
my_list = [3, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 3, 1, 1, 1, 1, 3, 1, 3, 1, 1, 3, 3, 3]
target = [3, 1, 3, 3, 1]
n = len(target)
>>> sum(all(a == b for a, b in izip_longest(target, my_list[(i * n):((i + 1) * n)]))
for i in range(len(my_list) // n))
1
Below is an alternative method that converts the integers to strings and then compares the strings.
target = ",".join(str(number) for number in target)
>>> target
'3,1,3,3,1'
>>> sum(",".join(str(number) for number in my_list[(i * n):(i * n + n)]) == target
for i in range(len(my_list) / n))
1
To give some more intuition on what is going on, the list is chunked five elements at a time and then those elements are joined as a string. These strings are then compared to the target string which was similarly converted, and the number of matches are then summed.
>>> [",".join(str(number) for number in my_list[(i * n):(i * n + n)])
for i in range(len(my_list) / n)]
['3,1,3,3,1', '3,3,1,3,3', '1,3,1,1,1', '1,3,1,3,1']
Step1
Convert list of integers into string.
Step2
Use findall() function of regex module to find all occurences of target_string in my_list_string.
import re
my_list = [3, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 3, 1, 1, 1, 1, 3, 1, 3, 1, 1, 3, 3, 3]
target = [3, 1, 3, 3, 1]
my_list_string = ''.join(str(e) for e in my_list)
target_string = ''.join(str(e) for e in target)
print(len(re.findall(target_string, my_list_string)))

Remove adjacent element in a list in python

I am trying to do a simple python program that removes all the adjacent elements in a list
def main():
a = [1, 5, 2, 3, 3, 1, 2, 3, 5, 6]
c = len(a)
for i in range (0, c-2):
if a[i] == a[i+1]:
del a[i]
c = len(a)
print a
if __name__ == '__main__':
main()
and the output is
[1, 5, 2, 3, 3, 2, 3, 5, 6] which is all fine!
If change the a list to a = [1, 5, 2, 3, 3, 1, 2, 2, 5, 6]
then it gives an error
index list out of range
**if a[i] == a[i+1]**
It shouldn't be complaining about the index out of range as I am calculating the len(a) every time it deletes an element in the list. What am I missing here?
for i in range (0, c-2):
This is not like a for loop in some other languages; it’s iterating over a list returned (once) by range. When you change c later, it does not affect this loop.
You can use while instead:
c = len(a)
while i < c - 2:
if a[i] == a[i + 1]:
del a[i]
c = len(a)
else:
i += 1
There’s also itertools.groupby:
import itertools
def remove_consecutive(l):
return (k for k, v in itertools.groupby(l))
Here's a slightly different approach:
origlist=[1, 5, 2, 3, 3, 1, 2, 3, 5, 6]
newlist=[origlist[0]]
for elem in origlist[1:]:
if (elem != newlist[-1]):
newlist.append(elem)
The itertools answer above may be preferred, though, for brevity and clarity...