# 带约束的非线性系统

### 求解具有不等式约束的方程

`fsolve` 求解非线性方程组。但是，它不允许您包含任何约束，甚至是边界约束。那么，如何求解带约束的非线性方程组？

`$\begin{array}{c}{F}_{1}\left(x\right)=\left({x}_{1}+1\right)\left(10-{x}_{1}\right)\frac{1+{x}_{2}^{2}}{1+{x}_{2}^{2}+{x}_{2}}\\ {F}_{2}\left(x\right)=\left({x}_{2}+2\right)\left(20-{x}_{2}\right)\frac{1+{x}_{1}^{2}}{1+{x}_{1}^{2}+{x}_{1}},\end{array}$`

`$\begin{array}{l}x=\left(-1,-2\right)\\ x=\left(10,-2\right)\\ x=\left(-1,20\right)\\ x=\left(10,20\right).\end{array}$`

### 使用不同起点

```rng default % For reproducibility N = 10; % Try 10 random start points pts = 100*randn(N,2); % Initial points are rows in pts soln = zeros(N,2); % Allocate solution opts = optimoptions('fsolve','Display','off'); for k = 1:N soln(k,:) = fsolve(@fbnd,pts(k,:),opts); % Find solutions end```

```idx = soln(:,1) >= 0 & soln(:,2) >= 0; disp(soln(idx,:))```
``` 10.0000 20.0000 10.0000 20.0000 10.0000 20.0000 10.0000 20.0000 10.0000 20.0000 ```

### 使用不同算法

`fsolve` 有三种算法。每种算法可能得到不同的解。

```x0 = [1,9]; opts = optimoptions(@fsolve,'Display','off',... 'Algorithm','trust-region-dogleg'); x1 = fsolve(@fbnd,x0,opts)```
```x1 = 1×2 -1.0000 -2.0000 ```
```opts.Algorithm = 'trust-region'; x2 = fsolve(@fbnd,x0,opts)```
```x2 = 1×2 -1.0000 20.0000 ```
```opts.Algorithm = 'levenberg-marquardt'; x3 = fsolve(@fbnd,x0,opts)```
```x3 = 1×2 0.9523 8.9941 ```

### 使用带边界的 `lsqnonlin`

`lsqnonlin` 尝试最小化向量函数 $F\left(x\right)$ 中各分量的平方和。因此，它尝试求解方程 $F\left(x\right)=0$。此外，`lsqnonlin` 接受边界约束。

```lb = [0,0]; rng default x0 = 100*randn(2,1); [x,res] = lsqnonlin(@fbnd,x0,lb)```
```Local minimum found. Optimization completed because the size of the gradient is less than the value of the optimality tolerance. ```
```x = 2×1 10.0000 20.0000 ```
```res = 2.4783e-25 ```

### 将方程和不等式设置为 `fmincon` 约束

• 给出常数目标函数，如 `@(x)0`，该函数对每个 `x` 的计算结果为 0。

• `fsolve` 目标函数设置为 `fmincon` 中的非线性等式约束。

• 以通常的 `fmincon` 语法给出任何其他约束。

```lb = [0,0]; % Lower bound constraint rng default % Reproducible initial point x0 = 100*randn(2,1); opts = optimoptions(@fmincon,'Algorithm','interior-point','Display','off'); x = fmincon(@(x)0,x0,[],[],[],[],lb,[],@fminconstr,opts)```
```x = 2×1 10.0000 20.0000 ```

### 辅助函数

```function F = fbnd(x) F(1) = (x(1)+1)*(10-x(1))*(1+x(2)^2)/(1+x(2)^2+x(2)); F(2) = (x(2)+2)*(20-x(2))*(1+x(1)^2)/(1+x(1)^2+x(1)); end```

```function [c,ceq] = fminconstr(x) c = []; % No nonlinear inequality ceq = fbnd(x); % fsolve objective is fmincon nonlinear equality constraints end```