## Passivity: Test, visualize, and enforce passivity of rationalfit output

This example shows how to test, visualize, and enforce the passivity of output from the rationalfit function.

### Section 1 S-parameter data passivity

Time-domain analysis and simulation depends critically on being able to convert frequency-domain S-parameter data into causal, stable, and passive time-domain representations. Because the rationalfit function guarantees that all poles are in the left half plane, rationalfit output is both stable and causal by construction. The problem is passivity.

N-port S-parameter data represents a frequency-dependent transfer function H(f). An sparameter object can be created in RF Toolbox by reading a Touchstone file, such as passive.s2p, into the sparameter function. The ispassive function can be used to check the passivity of the S-parameter data, and the passivity function can be used to plot the 2-norm of the NxN matrices H(f) at each data frequency.

```S = sparameters('passive.s2p'); ispassive(S)```
```ans = logical 1 ```
`passivity(S)`

### Section 2 Testing and visualizing rationalfit output passivity

The rationalfit function converts N-port sparameter data S into an NxN matrix of rfmodel.rational objects.

Using the ispassive function on the NxN fit output reports that despite the fact that the input data S is passive, the output fit is not passive. In other words, the norm H(f) is greater than one at some frequency in the range [0,Inf].

The passivity function takes an NxN fit as input and plots its passivity. This is a plot of the upper bound of the norm(H(f)) on [0,Inf], also known as the H-infinity norm.

```fit = rationalfit(S); ispassive(fit)```
```ans = logical 0 ```
`passivity(fit)`

### Section 3 Testing and visualizing rationalfit output passivity

The makepassive function takes as input an NxN array of fit objects and also the original S-parameter data, and produces a passive fit by using convex optimization techniques to optimally match the data of the S-parameter input S while satisfying passivity constraints. The residues C and feedthrough matrix D of the output pfit are modified, but the poles A of the output pfit are identical to the poles A of the input fit.

`pfit = makepassive(fit,S,'Display','on');`
```ITER H-INFTY NORM FREQUENCY ERRDB CONSTRAINTS 0 1 + 1.791e-02 17.6816 GHz -40.4702 1 1 + 2.878e-04 275.317 MHz -40.9167 5 2 1 + 9.201e-05 366.051 MHz -40.9092 7 3 1 - 3.806e-07 367.977 MHz -40.906 9 ```
`ispassive(pfit)`
```ans = logical 1 ```
`passivity(pfit)`

`all(vertcat(pfit(:).A) == vertcat(fit(:).A))`
```ans = logical 1 ```

### Section 4 Starting makepassive with prescribed poles and zero C and D

To demonstrate that only C and D are modified by makepassive, one can zero out C and D and re-run makepassive. The output pfit still has the same poles as the input fit. The differences between pfit and pfit2 arise because of the different starting points of the convex optimizations.

One can use this feature of the makepassive function to produce a passive fit from a prescribed set of poles without any idea of starting C and D.

```for k = 1:numel(fit) fit(k).C(:) = 0; fit(k).D(:) = 0; end pfit2 = makepassive(fit,S); passivity(pfit2)```

`all(vertcat(pfit2(:).A) == vertcat(fit(:).A))`
```ans = logical 1 ```

### Section 5 Generating an equivalent SPICE circuit from a passive fit

The generateSPICE function takes a passive fit and generates an equivalent circuit as a SPICE subckt file. The input fit is an NxN array of rfmodel.rational objects as returned by rationalfit with an sparameters object as input. The generated file is a SPICE model constructed solely of passive R, L, C elements and controlled source elements E, F, G, and H.

```generateSPICE(pfit2,'mypassive.ckt') type mypassive.ckt```
```* Equivalent circuit model for mypassive.ckt .SUBCKT mypassive po1 po2 Vsp1 po1 p1 0 Eu1 u1 um1 p1 0 1 Hu1 um1 0 Vsp1 50 Ru1 u1 0 1 Vsp2 po2 p2 0 Eu2 u2 um2 p2 0 1 Hu2 um2 0 Vsp2 50 Ru2 u2 0 1 Rx1 x1 0 1 Cx1 x1 xm1 2.73023882777141e-12 Vx1 xm1 0 0 Gx1_1 x1 0 u1 0 -1.17333664417854 Rx2 x2 0 1 Cx2 x2 xm2 7.77758881964484e-12 Vx2 xm2 0 0 Gx2_1 x2 0 u1 0 -1.49024204069386 Rx3 x3 0 1 Cx3 x3 xm3 2.29141630537012e-11 Vx3 xm3 0 0 Gx3_1 x3 0 u1 0 -0.517084431404101 Rx4 x4 0 1 Cx4 x4 xm4 9.31845201916597e-11 Vx4 xm4 0 0 Gx4_1 x4 0 u1 0 -0.653520147723875 Rx5 x5 0 1 Cx5 x5 xm5 4.89917763955558e-10 Vx5 xm5 0 0 Gx5_1 x5 0 u1 0 -0.0808078265280028 Rx6 x6 0 1 Cx6 x6 xm6 3.95175907081288e-09 Vx6 xm6 0 0 Fxc6_7 x6 0 Vx7 19.0874397715705 Gx6_1 x6 0 u1 0 -0.0921092455473917 Rx7 x7 0 1 Cx7 x7 xm7 3.95175907081288e-09 Vx7 xm7 0 0 Fxc7_6 x7 0 Vx6 -0.0822778593169319 Gx7_1 x7 0 u1 0 0.00757855154693703 Rx8 x8 0 1 Cx8 x8 xm8 1.25490425523105e-08 Vx8 xm8 0 0 Gx8_1 x8 0 u1 0 -0.947555572588829 Rx9 x9 0 1 Cx9 x9 xm9 2.73023882777141e-12 Vx9 xm9 0 0 Gx9_2 x9 0 u2 0 -1.31894663415646 Rx10 x10 0 1 Cx10 x10 xm10 7.77758881964484e-12 Vx10 xm10 0 0 Gx10_2 x10 0 u2 0 -1.56398731385394 Rx11 x11 0 1 Cx11 x11 xm11 2.29141630537012e-11 Vx11 xm11 0 0 Gx11_2 x11 0 u2 0 -0.549814077793872 Rx12 x12 0 1 Cx12 x12 xm12 9.31845201916597e-11 Vx12 xm12 0 0 Gx12_2 x12 0 u2 0 -0.672510569169281 Rx13 x13 0 1 Cx13 x13 xm13 4.89917763955558e-10 Vx13 xm13 0 0 Gx13_2 x13 0 u2 0 -0.0832947353614212 Rx14 x14 0 1 Cx14 x14 xm14 3.95175907081288e-09 Vx14 xm14 0 0 Fxc14_15 x14 0 Vx15 18.7066754329505 Gx14_2 x14 0 u2 0 -0.0926801244265795 Rx15 x15 0 1 Cx15 x15 xm15 3.95175907081288e-09 Vx15 xm15 0 0 Fxc15_14 x15 0 Vx14 -0.083952580985043 Gx15_2 x15 0 u2 0 0.00778073565162628 Rx16 x16 0 1 Cx16 x16 xm16 1.25490425523105e-08 Vx16 xm16 0 0 Gx16_2 x16 0 u2 0 -0.948025705229776 Ry1 y1 0 1 Gyc1_1 y1 0 x1 0 -0.246410744003341 Gyc1_2 y1 0 x2 0 -0.0436184268277901 Gyc1_3 y1 0 x3 0 -1.05288221338797 Gyc1_4 y1 0 x4 0 -1.00146202269516 Gyc1_5 y1 0 x5 0 1.0042109486198 Gyc1_6 y1 0 x6 0 -1.00125204779405 Gyc1_7 y1 0 x7 0 -1.02014178683822 Gyc1_8 y1 0 x8 0 0.999887929709963 Gyc1_9 y1 0 x9 0 1.57805076340554 Gyc1_10 y1 0 x10 0 -1.87067996482439 Gyc1_11 y1 0 x11 0 0.894346097879497 Gyc1_12 y1 0 x12 0 0.970092575228679 Gyc1_13 y1 0 x13 0 -0.966457276803446 Gyc1_14 y1 0 x14 0 0.994333095156155 Gyc1_15 y1 0 x15 0 0.975750719558783 Gyc1_16 y1 0 x16 0 -1.00002751679248 Gyd1_1 y1 0 u1 0 0.604432234734033 Gyd1_2 y1 0 u2 0 -0.351057196689152 Ry2 y2 0 1 Gyc2_1 y2 0 x1 0 1.75358925599666 Gyc2_2 y2 0 x2 0 -1.95638157317221 Gyc2_3 y2 0 x3 0 0.947117786612026 Gyc2_4 y2 0 x4 0 0.998537977304836 Gyc2_5 y2 0 x5 0 -0.995789051380204 Gyc2_6 y2 0 x6 0 0.998747952205951 Gyc2_7 y2 0 x7 0 0.979858213161784 Gyc2_8 y2 0 x8 0 -1.00011207029004 Gyc2_9 y2 0 x9 0 -0.421949236594461 Gyc2_10 y2 0 x10 0 0.129320035175611 Gyc2_11 y2 0 x11 0 -1.1056539021205 Gyc2_12 y2 0 x12 0 -1.02990742477132 Gyc2_13 y2 0 x13 0 1.03354272319655 Gyc2_14 y2 0 x14 0 -1.00566690484384 Gyc2_15 y2 0 x15 0 -1.02424928044122 Gyc2_16 y2 0 x16 0 0.999972483207518 Gyd2_1 y2 0 u1 0 -0.335778539856147 Gyd2_2 y2 0 u2 0 0.701641692695201 Ey1 p1 0 y1 ym1 1 Hy1 ym1 0 Vsp1 -50 Ey2 p2 0 y2 ym2 1 Hy2 ym2 0 Vsp2 -50 .ENDS ```