Другим случаем, когда NullReferenceExceptions
может случиться, является (неправильное) использование оператора as
:
class Book {
public string Name { get; set; }
}
class Car { }
Car mycar = new Car();
Book mybook = mycar as Book; // Incompatible conversion --> mybook = null
Console.WriteLine(mybook.Name); // NullReferenceException
Здесь Book
и Car
являются несовместимыми типами; a Car
не может быть преобразован / передан в Book
. Когда этот сбой завершается неудачно, as
возвращает null
. Используя mybook
после этого, вы вызываете NullReferenceException
.
В общем случае вы должны использовать cast или as
, как показано ниже:
Если вы ожидаете преобразования типа в всегда преуспевает (т. е. вы знаете, какой объект должен быть впереди времени), тогда вы должны использовать cast:
ComicBook cb = (ComicBook)specificBook;
Если вы не уверены в типе, но хотите попробовать , чтобы использовать его как определенный тип, затем используйте as
:
ComicBook cb = specificBook as ComicBook;
if (cb != null) {
// ...
}
для численного решения, вы можете использовать fsolve:
from scipy.optimize import fsolve
import math
def equations(p):
x, y = p
return (x+y**2-4, math.exp(x) + x*y - 3)
x, y = fsolve(equations, (1, 1))
print equations((x, y))
Если вы предпочитаете sympy, вы можете использовать nsolve .
>>> nsolve([x+y**2-4, exp(x)+x*y-3], [x, y], [1, 1])
[0.620344523485226]
[1.83838393066159]
Первый аргумент - это список уравнений, второй - список переменных, а третий - начальный Угадай.
Вы можете использовать пакет openopt и его метод NLP. Он имеет множество алгоритмов динамического программирования для решения нелинейных алгебраических уравнений, состоящих из: goldenSection, scipy_fminbound, scipy_bfgs, scipy_cg, scipy_ncg, amsg2p, scipy_lbfgsb, scipy_tnc, bobyqa, ralg, ipopt, scipy_slsqp, scipy_cobyla, lincher, algencan, из которых вы можете выбрать. Некоторые из последних алгоритмов могут решить проблему ограниченного нелинейного программирования. Итак, вы можете ввести свою систему уравнений в openopt.NLP () с помощью такой функции:
lambda x: x[0] + x[1]**2 - 4, np.exp(x[0]) + x[0]*x[1]
Попробуйте это, я заверяю вас, что он будет работать отлично.
import scipy.optimize as opt
from numpy import exp
import timeit
st1 = timeit.default_timer()
def f(variables) :
(x,y) = variables
first_eq = x + y**2 -4
second_eq = exp(x) + x*y - 3
return [first_eq, second_eq]
solution = opt.fsolve(f, (0.1,1) )
print(solution)
st2 = timeit.default_timer()
print("RUN TIME : {0}".format(st2-st1))
->
[ 0.62034452 1.83838393]
RUN TIME : 0.0009331008900937708
FYI. как упоминалось выше, вы также можете использовать «приближение Бройдена», заменив «fsolve» на «broyden1». Оно работает. Я сделал это.
Я не знаю точно, как работает приближение Бройдена, но потребовалось 0,02 с.
И я рекомендую вам не использовать функции Sympy & lt; - удобно, но с точки зрения скорости это довольно медленно. Ты увидишь.
from scipy.optimize import fsolve
def double_solve(f1,f2,x0,y0):
func = lambda x: [f1(x[0], x[1]), f2(x[0], x[1])]
return fsolve(func,[x0,y0])
def n_solve(functions,variables):
func = lambda x: [ f(*x) for f in functions]
return fsolve(func, variables)
f1 = lambda x,y : x**2+y**2-1
f2 = lambda x,y : x-y
res = double_solve(f1,f2,1,0)
res = n_solve([f1,f2],[1.0,0.0])
Я получил метод Бройдена для работы с связанными нелинейными уравнениями (как правило, с участием полиномов и экспонент) в IDL, но я не пробовал его в Python:
scipy.optimize.broyden1
scipy.optimize.broyden1(F, xin, iter=None, alpha=None, reduction_method='restart', max_rank=None, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)[source]
Найти корень функции, используя первое якобиевое приближение Бройдена.
Этот метод также известен как «хороший метод Бройдена».
blockquote>