Python Forum
Thread Rating:
  • 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Triangular matrix
#1
Hi everyone

I want to fill the lower part of a matrix with an input vector but i got problems

for i in range(1,len(variable)):
    for j in range(i):
        tableau[i,j] = coef[j+i-1]
i get
[[ 0.  0.  0.  0.  0.]
 [ 1.  0.  0.  0.  0.]
 [ 2.  3.  0.  0.  0.]
 [ 3.  4.  5.  0.  0.]
 [ 4.  5.  6.  7.  0.]]
but i want to get
[[ 0  0  0  0  0]
 [ 1  0  0  0  0]
 [ 2  3  0  0  0]
 [ 4  5  6  0  0]
 [ 7  8  9 10  0]]
do you haver any idea ?

Thank you !
Reply
#2
Try this:

def make_tril(v):
    from math import sqrt
    import sys
    n = 0.5 * (1 + sqrt(1 + 8 * len(v)))
    if abs(n - int(n)) <= 2 * int(n) * sys.float_info.epsilon:
        n = int(n)
        result = [[0 for i in range(n)] for j in range(n)]
        ind = 0
        for i in range(n):
            for j in range(i):
                result[i][j] = v[ind]
                ind += 1
    else:
        raise Exception('Non-consistent length of the input vector.')
    return result

make_tril([1,2,3,4,5,6,7,8,9,10])
Output:
[[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [2, 3, 0, 0, 0], [4, 5, 6, 0, 0], [7, 8, 9, 10, 0]]
In any case, loops (as well nested loops) are quite slow in Python. So, it would be better to use
numpy package, see numpy.tril_indices for that.
Reply
#3
what's all that extra math for to fill part of a matrix?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
(Jun-14-2018, 12:20 AM)Skaperen Wrote: what's all that extra math for to fill part of a matrix?

n = 0.5 * (1 + sqrt(1 + 8 * len(v))) is solution of the equation n*(n-1)/2 = len(v), where n -- size of the matrix to be filled by elements of v.

Improvement:
It is better to use round instead of int, when performing conversion to integer type:
...
if abs(n - round(n)) <= 2 * round(n) * sys.float_info.epsilon:
        n = round(n)
        ....
Reply
#5
One gonna love itertools

Math is not my forte, but things you can do with itertools Heart and some simple logic ...
def triangle(size):
    source = itertools.count(1)
    return [[next(source) if col < row else 0 for col in range(size)] 
            for row in range(size)]
And the result is
Output:
In [3]: triangle(5) Out[3]: [[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [2, 3, 0, 0, 0], [4, 5, 6, 0, 0], [7, 8, 9, 10, 0]]
Test everything in a Python shell (iPython, Azure Notebook, etc.)
  • Someone gave you an advice you liked? Test it - maybe the advice was actually bad.
  • Someone gave you an advice you think is bad? Test it before arguing - maybe it was good.
  • You posted a claim that something you did not test works? Be prepared to eat your hat.
Reply
#6
you can't figure out the size by running an incrementor through the input vector to figure out the diagonal to add to 2x the vector and stay in integer arithmetic? oh, you wanted to avoid the loop.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020