2015-03-31 4 views
3

мне нужно, чтобы соответствовать функциямдвухмерные подходит с питоном

z(u,v) = C u v^p 

То есть, у меня есть двумерный набор данных, и я должен найти два параметр, С и р. Есть что-то в numpy или scipy, которые могут сделать это прямолинейно? Я взглянул на scipy.optimize.leastsq, но мне непонятно, как я буду использовать его здесь.

ответ

4
def f(x,u,v,z_data): 
    C = x[0] 
    p = x[1] 
    modelled_z = C*u*v**p 
    diffs = modelled_z - z_data 
    return diffs.flatten() # it expects a 1D array out. 
     # it doesn't matter that it's conceptually 2D, provided flatten it consistently 

result = scipy.optimize.leastsq(f,[1.0,1.0], # initial guess at starting point 
         args = (u,v,z_data) # alternatively you can do this with closure variables in f if you like 
          ) 
# result is the best fit point 

Для конкретной функции, которую вы могли бы быть в состоянии сделать это лучше - например, для любого заданного значения p есть одна лучшая стоимость C, которая может быть определена с помощью простой линейной алгебры.

+0

Пара вопросов: 1) u, ​​v делает 2D сетку. У меня есть точка данных для каждой пары u, v. Мне не нужно что-то вроде np.outer (u, v ** p)? 2) Я удивлен, что «modelled_z» является третьим аргументом в «args». Разве мне не нужно «observ_z» или что-то в этом роде? Благодарю. –

+0

С np.outer() он работал нормально, поэтому я принимаю это как ответ. –

+1

'modelled_z' vs' z_data' было ошибкой с моей стороны - я исправил это. 'np.outer' действительно зависит от того, как вы храните' u' и 'v'. Вероятно, я бы определил 'u' как' m by 1' и 'v' и' 1 by n', и он будет работать так, как я его написал. Я предполагаю, что вы определили их как 1D-массивы, поэтому в этом случае 'np.outer' хорош. – DavidW

1

Вы можете преобразовать проблему в простую линейную задачу наименьших квадратов, а затем вам не нужно leastsq().

z[i] == C * u[i] * v[i]**p 

становится

z[i]/u[i] == C * v[i]**p 

а затем

log(z[i]/u[i]) == log(C) + p * log(v[i]) 

Изменить переменные, и вы можете решить, как простой линейной задачи:

Z[i] == L + p * V[i] 

Использование numpy и предполагающей у вас есть данные в массивах z, u и v, это выглядит так:

Z = log(z/u) 
V = log(v) 
p, L = np.polyfit(V, Z, 1) 
C = exp(L) 

Вы, вероятно, следует положить try: и except: вокруг него в случае, если некоторые из u значений равны нулю или есть отрицательные значения.

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