Численное решение для нелинейных уравнений в Python - PullRequest
0 голосов
/ 31 октября 2018

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

Мне удалось решить простой (одно уравнение) случай в Excel, используя Solver, но я не собирал ничего подобного в Python, поэтому буду благодарен за предложения по подходу.

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

enter image description here enter image description here

И такая же форма для второго, б, уравнения.

A является константой, переменные Z, S и x являются константами для каждой сущности i, и единственными независимыми значениями являются показатель степени a и b; два уравнения, два неизвестных, поэтому должно быть одно единственное решение.

Как я уже сказал, я настроил простой случай с одним уравнением в Excel и успешно решил для использования Солвера. Любое руководство по настройке в Python приветствуется.

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

С помощью вышесказанного удалось составить решение, оцените это. Я принял ответ Джона; Код решения ниже для справки.

import pandas as pd
import numpy as np
from scipy.optimize import fsolve

Aq = .6
Av = .6

def eqs(p):
    a, b = p    
    return(np.dot(x*(qS**a*vS**b)/np.dot(x,qS**a*vS**b),qZ)-Aq 
            , np.dot(x*(qS**a*vS**b)/np.dot(x,qS**a*vS**b),vZ)-Av)

sol = fsolve(eqs, (1,1), full_output=True)
x, y = sol[0]
0 голосов
/ 31 октября 2018

Проблема, которую вы описываете, является одной из корневых поисков . Вы хотите найти (a, b) для которого f (a, b) = 0

Простым подходом будет итерация с фиксированной точкой. Поскольку у вас есть аналитическое выражение для f (a, b), вы можете вычислить производные и использовать метод Ньютона. Чтобы настроить это с помощью fsolve, вам нужно определить функцию:

def myfunc(x):
    val1 = #evaluate your first expression here using Z and S
    val2 = #evaluate your second expression here
    return np.ndarray([val1 val2])

При желании вы можете передать свои значения для S и Z, используя аргумент * args.

Тогда решите, используя:

fsolve(myfunc,x0)

где x0 - начальное предположение.

Обратите внимание, что fsolve может не соответствовать вашему состоянию на w. Если это не удовлетворяет идентично для вашей проблемы, я бы посмотрел на метод, который поддерживает ограниченную оптимизацию, такой как fmin_slsqp . Синтаксис должен быть очень похож на тот, который я описал для fsolve в любом случае.

...