2014-02-06 2 views
1

У меня есть скрипт, который импортирует модуль geometry, и этот модуль замедляет мой скрипт до экстремального уровня. Мой сценарий генерирует растровое изображение и на 16 миллионов пикселей, что потребуется более 100 часовДиагностика и улучшение скорости вычислений

здесь проблематичный модуль:

''' 
Created on 2 fevr. 2014 

@author: gary 
''' 
#module name is: geometry.py 

import numpy as np 
import numpy.linalg as la 
import tetgen 

def barycentric_coords(vertices, point): 
    T = (np.array(vertices[:-1])-vertices[-1]).T 
    v = np.dot(la.inv(T), np.array(point)-vertices[-1]) 
    v.resize(len(vertices)) 
    v[-1] = 1-v.sum() 
    #print vertices 
    return v 

def tetgen_of_hull(points): 
    tg_all = tetgen.TetGen(points) 

    hull_i = set().union(*tg_all.hull) 
    hull_points = [points[i] for i in hull_i] 

    tg_hull = tetgen.TetGen(hull_points) 
    return tg_hull, hull_i 

def containing_tet(tg, point): 
    for tet in tg.tets: 
     verts = [tg.points[j] for j in tet] 
     bcoords = barycentric_coords(verts, point) 
     if (bcoords >= 0).all(): 
      return bcoords 
    return None, None 

это статистика Cprofile дает на мой сценарии, который использует функции выше, очевидно, вот где время провел:

ncalls tottime percall cumtime percall filename:lineno(function) 
    1291716 45.576 0.000 171.672 0.000 geometry.py:10(barycentric_coords) 

    6460649 31.617 0.000 31.617 0.000 {numpy.core.multiarray.array} 
    2583432 15.979 0.000 15.979 0.000 {method 'reduce' of 'numpy.ufunc' 
objects} 
    2031 12.032 0.006 193.333 0.095 geometry.py:26(containing_tet) 
    1291716 10.944 0.000 58.323 0.000 linalg.py:244(solve) 
    1291716 7.075 0.000 7.075 0.000 {numpy.linalg.lapack_lite.dgesv} 
    1291716 5.750 0.000 9.865 0.000 linalg.py:99(_commonType) 
    2583432 5.659 0.000 5.659 0.000 {numpy.core.multiarray._fastCopyAn 
dTranspose} 
    1291716 5.526 0.000 7.299 0.000 twodim_base.py:169(eye) 
    1291716 5.492 0.000 12.791 0.000 numeric.py:1884(identity) 

Так вот мой вопрос:

numpy, по-видимому, довольно медленно справляется с вычислением барицентрических координат здесь, стоило бы это сделать в c++? Или можно ли каким-либо образом оптимизировать это по-другому (в python)?

+0

@VladimirF жаль, что я ошибочно нажал «сообщение» до окончания ... –

+1

Вы тратите много времени на преобразование списков python в массивы numpy. Есть ли какой-либо способ, который вы можете сразу создать в виде массивов numpy? (Не слишком хорошо знакомы с numpy, поэтому я, вероятно, говорю из моего отступающего волоса ...) – molbdnilo

+0

Не могли бы ли вы удалить из него какой-нибудь numpy и запустить его через pypy? –

ответ

1

реального времени раковина, вероятно, будет матрица инверсии вы делаете в barycentric_coords:

v = np.dot(la.inv(T), np.array(point)-vertices[-1]) 

Помните, что в значительной степени во всех случаях: Don't invert that matrix!

Вы можете заменить эту строку с:

v = np.linalg.lstsq(T, np.array(point)-vertices[-1])[0] 

Чтобы получить тот же результат с гораздо более быстрым решением наименьших квадратов.

Смежные вопросы