```python

```

In this example, exact analytical trajectory of a charged particle moving in a uniform electric field is compared with results of numerical simulation.

In uniform electric field charged particle moves with uniform acceleration, directed along the field.

\begin{align}
& \mathbf{v} = \mathbf{v}_0 + \frac{q}{m} \mathbf{E}_0 t
\\
& \mathbf{r} = \mathbf{r}_0 + \mathbf{v}_0 t + \frac{1}{2} \frac{q}{m} \mathbf{E}_0 t^2
\end{align}

Part of a config file, regarding single particle, is similar to
['singe particle in free space'](https://github.com/epicf/ef/wiki/Ex1:-Single-Particle-In-Free-Space).

```python
from ef.config.components import *
timegrid = TimeGridConf(total=6e-09, save_step=6e-11, step=6e-12)
mesh = SpatialMeshConf((5, 5, 15), (.5, .5, 1.5))
source = ParticleSourceConf("emit_single_particle", Box((.1, .1, .1), (.01, .01, .01)), 1, 0,
                           (6e-19, 6e-19, 1.77e-18), 0., 4.8e-10, 9.8e-28)
file_config = OutputFileConf("single_particle_electric_field_")
field = ExternalElectricFieldUniformConf("uniform_z_field", (0, 0, 6))

```

```python
from ef.config.config import Config
from ef.config.visualizer import Visualizer3d
conf = Config(time_grid=timegrid, spatial_mesh=mesh, sources=[source],
              external_fields=[field], output_file=file_config)
conf.visualize_all(Visualizer3d())
```

    <Figure size 640x480 with 1 Axes>

```python
from ef.runner import Runner
Runner(conf.make(), output_writer=file_config.make()).start()
```

    Writing initial fields to file
    Writing to file single_particle_electric_field_fieldsWithoutParticles_new.h5
    Writing to file single_particle_electric_field_fieldsWithoutParticles.h5
    Writing step 0 to file
    Writing to file single_particle_electric_field_0000000_new.h5
    Writing to file single_particle_electric_field_0000000.h5
    Time step from 0 to 1 of 1000
    Time step from 1 to 2 of 1000
    Time step from 2 to 3 of 1000
    Time step from 3 to 4 of 1000
    Time step from 4 to 5 of 1000
    Time step from 5 to 6 of 1000
    Time step from 6 to 7 of 1000
    Time step from 7 to 8 of 1000
    Time step from 8 to 9 of 1000
    Time step from 9 to 10 of 1000
    Writing step 10 to file
    Writing to file single_particle_electric_field_0000010_new.h5
    Writing to file single_particle_electric_field_0000010.h5
    Time step from 10 to 11 of 1000
    Time step from 11 to 12 of 1000
    Time step from 12 to 13 of 1000
    Time step from 13 to 14 of 1000
    Time step from 14 to 15 of 1000
    Time step from 15 to 16 of 1000
    Time step from 16 to 17 of 1000
    Time step from 17 to 18 of 1000
    Time step from 18 to 19 of 1000
    Time step from 19 to 20 of 1000
    Writing step 20 to file
    Writing to file single_particle_electric_field_0000020_new.h5
    Writing to file single_particle_electric_field_0000020.h5
    Time step from 20 to 21 of 1000
    Time step from 21 to 22 of 1000
    Time step from 22 to 23 of 1000
    Time step from 23 to 24 of 1000
    Time step from 24 to 25 of 1000
    Time step from 25 to 26 of 1000
    Time step from 26 to 27 of 1000
    Time step from 27 to 28 of 1000
    Time step from 28 to 29 of 1000
    Time step from 29 to 30 of 1000
    Writing step 30 to file
    Writing to file single_particle_electric_field_0000030_new.h5
    Writing to file single_particle_electric_field_0000030.h5
    Time step from 30 to 31 of 1000
    Time step from 31 to 32 of 1000
    Time step from 32 to 33 of 1000
    Time step from 33 to 34 of 1000
    Time step from 34 to 35 of 1000
    Time step from 35 to 36 of 1000
    Time step from 36 to 37 of 1000
    Time step from 37 to 38 of 1000
    Time step from 38 to 39 of 1000
    Time step from 39 to 40 of 1000
    Writing step 40 to file
    Writing to file single_particle_electric_field_0000040_new.h5
    Writing to file single_particle_electric_field_0000040.h5
    Time step from 40 to 41 of 1000
    Time step from 41 to 42 of 1000
    Time step from 42 to 43 of 1000
    Time step from 43 to 44 of 1000
    Time step from 44 to 45 of 1000
    Time step from 45 to 46 of 1000
    Time step from 46 to 47 of 1000
    Time step from 47 to 48 of 1000
    Time step from 48 to 49 of 1000
    Time step from 49 to 50 of 1000
    Writing step 50 to file
    Writing to file single_particle_electric_field_0000050_new.h5
    Writing to file single_particle_electric_field_0000050.h5
    Time step from 50 to 51 of 1000
    Time step from 51 to 52 of 1000
    Time step from 52 to 53 of 1000
    Time step from 53 to 54 of 1000
    Time step from 54 to 55 of 1000
    Time step from 55 to 56 of 1000
    Time step from 56 to 57 of 1000
    Time step from 57 to 58 of 1000
    Time step from 58 to 59 of 1000
    Time step from 59 to 60 of 1000
    Writing step 60 to file
    Writing to file single_particle_electric_field_0000060_new.h5
    Writing to file single_particle_electric_field_0000060.h5
    Time step from 60 to 61 of 1000
    Time step from 61 to 62 of 1000
    Time step from 62 to 63 of 1000
    Time step from 63 to 64 of 1000
    Time step from 64 to 65 of 1000
    Time step from 65 to 66 of 1000
    Time step from 66 to 67 of 1000
    Time step from 67 to 68 of 1000
    Time step from 68 to 69 of 1000
    Time step from 69 to 70 of 1000
    Writing step 70 to file
    Writing to file single_particle_electric_field_0000070_new.h5
    Writing to file single_particle_electric_field_0000070.h5
    Time step from 70 to 71 of 1000
    Time step from 71 to 72 of 1000
    Time step from 72 to 73 of 1000
    Time step from 73 to 74 of 1000
    Time step from 74 to 75 of 1000
    Time step from 75 to 76 of 1000
    Time step from 76 to 77 of 1000
    Time step from 77 to 78 of 1000
    Time step from 78 to 79 of 1000
    Time step from 79 to 80 of 1000
    Writing step 80 to file
    Writing to file single_particle_electric_field_0000080_new.h5
    Writing to file single_particle_electric_field_0000080.h5
    Time step from 80 to 81 of 1000
    Time step from 81 to 82 of 1000
    Time step from 82 to 83 of 1000
    Time step from 83 to 84 of 1000
    Time step from 84 to 85 of 1000
    Time step from 85 to 86 of 1000
    Time step from 86 to 87 of 1000
    Time step from 87 to 88 of 1000
    Time step from 88 to 89 of 1000
    Time step from 89 to 90 of 1000
    Writing step 90 to file
    Writing to file single_particle_electric_field_0000090_new.h5
    Writing to file single_particle_electric_field_0000090.h5
    Time step from 90 to 91 of 1000
    Time step from 91 to 92 of 1000
    Time step from 92 to 93 of 1000
    Time step from 93 to 94 of 1000
    Time step from 94 to 95 of 1000
    Time step from 95 to 96 of 1000
    Time step from 96 to 97 of 1000
    Time step from 97 to 98 of 1000
    Time step from 98 to 99 of 1000
    Time step from 99 to 100 of 1000
    Writing step 100 to file
    Writing to file single_particle_electric_field_0000100_new.h5
    Writing to file single_particle_electric_field_0000100.h5
    Time step from 100 to 101 of 1000
    Time step from 101 to 102 of 1000
    Time step from 102 to 103 of 1000
    Time step from 103 to 104 of 1000
    Time step from 104 to 105 of 1000
    Time step from 105 to 106 of 1000
    Time step from 106 to 107 of 1000
    Time step from 107 to 108 of 1000
    Time step from 108 to 109 of 1000
    Time step from 109 to 110 of 1000
    Writing step 110 to file
    Writing to file single_particle_electric_field_0000110_new.h5
    Writing to file single_particle_electric_field_0000110.h5
    Time step from 110 to 111 of 1000
    Time step from 111 to 112 of 1000
    Time step from 112 to 113 of 1000
    Time step from 113 to 114 of 1000
    Time step from 114 to 115 of 1000
    Time step from 115 to 116 of 1000
    Time step from 116 to 117 of 1000
    Time step from 117 to 118 of 1000
    Time step from 118 to 119 of 1000
    Time step from 119 to 120 of 1000
    Writing step 120 to file
    Writing to file single_particle_electric_field_0000120_new.h5
    Writing to file single_particle_electric_field_0000120.h5
    Time step from 120 to 121 of 1000
    Time step from 121 to 122 of 1000
    Time step from 122 to 123 of 1000
    Time step from 123 to 124 of 1000
    Time step from 124 to 125 of 1000
    Time step from 125 to 126 of 1000
    Time step from 126 to 127 of 1000
    Time step from 127 to 128 of 1000
    Time step from 128 to 129 of 1000
    Time step from 129 to 130 of 1000
    Writing step 130 to file
    Writing to file single_particle_electric_field_0000130_new.h5
    Writing to file single_particle_electric_field_0000130.h5
    Time step from 130 to 131 of 1000
    Time step from 131 to 132 of 1000
    Time step from 132 to 133 of 1000
    Time step from 133 to 134 of 1000
    Time step from 134 to 135 of 1000
    Time step from 135 to 136 of 1000
    Time step from 136 to 137 of 1000
    Time step from 137 to 138 of 1000
    Time step from 138 to 139 of 1000
    Time step from 139 to 140 of 1000
    Writing step 140 to file
    Writing to file single_particle_electric_field_0000140_new.h5
    Writing to file single_particle_electric_field_0000140.h5
    Time step from 140 to 141 of 1000
    Time step from 141 to 142 of 1000
    Time step from 142 to 143 of 1000
    Time step from 143 to 144 of 1000
    Time step from 144 to 145 of 1000
    Time step from 145 to 146 of 1000
    Time step from 146 to 147 of 1000
    Time step from 147 to 148 of 1000
    Time step from 148 to 149 of 1000
    Time step from 149 to 150 of 1000
    Writing step 150 to file
    Writing to file single_particle_electric_field_0000150_new.h5
    Writing to file single_particle_electric_field_0000150.h5
    Time step from 150 to 151 of 1000
    Time step from 151 to 152 of 1000
    Time step from 152 to 153 of 1000
    Time step from 153 to 154 of 1000
    Time step from 154 to 155 of 1000
    Time step from 155 to 156 of 1000
    Time step from 156 to 157 of 1000
    Time step from 157 to 158 of 1000
    Time step from 158 to 159 of 1000
    Time step from 159 to 160 of 1000
    Writing step 160 to file
    Writing to file single_particle_electric_field_0000160_new.h5
    Writing to file single_particle_electric_field_0000160.h5
    Time step from 160 to 161 of 1000
    Time step from 161 to 162 of 1000
    Time step from 162 to 163 of 1000
    Time step from 163 to 164 of 1000
    Time step from 164 to 165 of 1000
    Time step from 165 to 166 of 1000
    Time step from 166 to 167 of 1000
    Time step from 167 to 168 of 1000
    Time step from 168 to 169 of 1000
    Time step from 169 to 170 of 1000
    Writing step 170 to file
    Writing to file single_particle_electric_field_0000170_new.h5
    Writing to file single_particle_electric_field_0000170.h5
    Time step from 170 to 171 of 1000
    Time step from 171 to 172 of 1000
    Time step from 172 to 173 of 1000
    Time step from 173 to 174 of 1000
    Time step from 174 to 175 of 1000
    Time step from 175 to 176 of 1000
    Time step from 176 to 177 of 1000
    Time step from 177 to 178 of 1000
    Time step from 178 to 179 of 1000
    Time step from 179 to 180 of 1000
    Writing step 180 to file
    Writing to file single_particle_electric_field_0000180_new.h5
    Writing to file single_particle_electric_field_0000180.h5
    Time step from 180 to 181 of 1000
    Time step from 181 to 182 of 1000
    Time step from 182 to 183 of 1000
    Time step from 183 to 184 of 1000
    Time step from 184 to 185 of 1000
    Time step from 185 to 186 of 1000
    Time step from 186 to 187 of 1000
    Time step from 187 to 188 of 1000
    Time step from 188 to 189 of 1000
    Time step from 189 to 190 of 1000
    Writing step 190 to file
    Writing to file single_particle_electric_field_0000190_new.h5
    Writing to file single_particle_electric_field_0000190.h5
    Time step from 190 to 191 of 1000
    Time step from 191 to 192 of 1000
    Time step from 192 to 193 of 1000
    Time step from 193 to 194 of 1000
    Time step from 194 to 195 of 1000
    Time step from 195 to 196 of 1000
    Time step from 196 to 197 of 1000
    Time step from 197 to 198 of 1000
    Time step from 198 to 199 of 1000
    Time step from 199 to 200 of 1000
    Writing step 200 to file
    Writing to file single_particle_electric_field_0000200_new.h5
    Writing to file single_particle_electric_field_0000200.h5
    Time step from 200 to 201 of 1000
    Time step from 201 to 202 of 1000
    Time step from 202 to 203 of 1000
    Time step from 203 to 204 of 1000
    Time step from 204 to 205 of 1000
    Time step from 205 to 206 of 1000
    Time step from 206 to 207 of 1000
    Time step from 207 to 208 of 1000
    Time step from 208 to 209 of 1000
    Time step from 209 to 210 of 1000
    Writing step 210 to file
    Writing to file single_particle_electric_field_0000210_new.h5
    Writing to file single_particle_electric_field_0000210.h5
    Time step from 210 to 211 of 1000
    Time step from 211 to 212 of 1000
    Time step from 212 to 213 of 1000
    Time step from 213 to 214 of 1000
    Time step from 214 to 215 of 1000
    Time step from 215 to 216 of 1000
    Time step from 216 to 217 of 1000
    Time step from 217 to 218 of 1000
    Time step from 218 to 219 of 1000
    Time step from 219 to 220 of 1000
    Writing step 220 to file
    Writing to file single_particle_electric_field_0000220_new.h5
    Writing to file single_particle_electric_field_0000220.h5
    Time step from 220 to 221 of 1000
    Time step from 221 to 222 of 1000
    Time step from 222 to 223 of 1000
    Time step from 223 to 224 of 1000
    Time step from 224 to 225 of 1000
    Time step from 225 to 226 of 1000
    Time step from 226 to 227 of 1000
    Time step from 227 to 228 of 1000
    Time step from 228 to 229 of 1000
    Time step from 229 to 230 of 1000
    Writing step 230 to file
    Writing to file single_particle_electric_field_0000230_new.h5
    Writing to file single_particle_electric_field_0000230.h5
    Time step from 230 to 231 of 1000
    Time step from 231 to 232 of 1000
    Time step from 232 to 233 of 1000
    Time step from 233 to 234 of 1000
    Time step from 234 to 235 of 1000
    Time step from 235 to 236 of 1000
    Time step from 236 to 237 of 1000
    Time step from 237 to 238 of 1000
    Time step from 238 to 239 of 1000
    Time step from 239 to 240 of 1000
    Writing step 240 to file
    Writing to file single_particle_electric_field_0000240_new.h5
    Writing to file single_particle_electric_field_0000240.h5
    Time step from 240 to 241 of 1000
    Time step from 241 to 242 of 1000
    Time step from 242 to 243 of 1000
    Time step from 243 to 244 of 1000
    Time step from 244 to 245 of 1000
    Time step from 245 to 246 of 1000
    Time step from 246 to 247 of 1000
    Time step from 247 to 248 of 1000
    Time step from 248 to 249 of 1000
    Time step from 249 to 250 of 1000
    Writing step 250 to file
    Writing to file single_particle_electric_field_0000250_new.h5
    Writing to file single_particle_electric_field_0000250.h5
    Time step from 250 to 251 of 1000
    Time step from 251 to 252 of 1000
    Time step from 252 to 253 of 1000
    Time step from 253 to 254 of 1000
    Time step from 254 to 255 of 1000
    Time step from 255 to 256 of 1000
    Time step from 256 to 257 of 1000
    Time step from 257 to 258 of 1000
    Time step from 258 to 259 of 1000
    Time step from 259 to 260 of 1000
    Writing step 260 to file
    Writing to file single_particle_electric_field_0000260_new.h5
    Writing to file single_particle_electric_field_0000260.h5
    Time step from 260 to 261 of 1000
    Time step from 261 to 262 of 1000
    Time step from 262 to 263 of 1000
    Time step from 263 to 264 of 1000
    Time step from 264 to 265 of 1000
    Time step from 265 to 266 of 1000
    Time step from 266 to 267 of 1000
    Time step from 267 to 268 of 1000
    Time step from 268 to 269 of 1000
    Time step from 269 to 270 of 1000
    Writing step 270 to file
    Writing to file single_particle_electric_field_0000270_new.h5
    Writing to file single_particle_electric_field_0000270.h5
    Time step from 270 to 271 of 1000
    Time step from 271 to 272 of 1000
    Time step from 272 to 273 of 1000
    Time step from 273 to 274 of 1000
    Time step from 274 to 275 of 1000
    Time step from 275 to 276 of 1000
    Time step from 276 to 277 of 1000
    Time step from 277 to 278 of 1000
    Time step from 278 to 279 of 1000
    Time step from 279 to 280 of 1000
    Writing step 280 to file
    Writing to file single_particle_electric_field_0000280_new.h5
    Writing to file single_particle_electric_field_0000280.h5
    Time step from 280 to 281 of 1000
    Time step from 281 to 282 of 1000
    Time step from 282 to 283 of 1000
    Time step from 283 to 284 of 1000
    Time step from 284 to 285 of 1000
    Time step from 285 to 286 of 1000
    Time step from 286 to 287 of 1000
    Time step from 287 to 288 of 1000
    Time step from 288 to 289 of 1000
    Time step from 289 to 290 of 1000
    Writing step 290 to file
    Writing to file single_particle_electric_field_0000290_new.h5
    Writing to file single_particle_electric_field_0000290.h5
    Time step from 290 to 291 of 1000
    Time step from 291 to 292 of 1000
    Time step from 292 to 293 of 1000
    Time step from 293 to 294 of 1000
    Time step from 294 to 295 of 1000
    Time step from 295 to 296 of 1000
    Time step from 296 to 297 of 1000
    Time step from 297 to 298 of 1000
    Time step from 298 to 299 of 1000
    Time step from 299 to 300 of 1000
    Writing step 300 to file
    Writing to file single_particle_electric_field_0000300_new.h5
    Writing to file single_particle_electric_field_0000300.h5
    Time step from 300 to 301 of 1000
    Time step from 301 to 302 of 1000
    Time step from 302 to 303 of 1000
    Time step from 303 to 304 of 1000
    Time step from 304 to 305 of 1000
    Time step from 305 to 306 of 1000
    Time step from 306 to 307 of 1000
    Time step from 307 to 308 of 1000
    Time step from 308 to 309 of 1000
    Time step from 309 to 310 of 1000
    Writing step 310 to file
    Writing to file single_particle_electric_field_0000310_new.h5
    Writing to file single_particle_electric_field_0000310.h5
    Time step from 310 to 311 of 1000
    Time step from 311 to 312 of 1000
    Time step from 312 to 313 of 1000
    Time step from 313 to 314 of 1000
    Time step from 314 to 315 of 1000
    Time step from 315 to 316 of 1000
    Time step from 316 to 317 of 1000
    Time step from 317 to 318 of 1000
    Time step from 318 to 319 of 1000
    Time step from 319 to 320 of 1000
    Writing step 320 to file
    Writing to file single_particle_electric_field_0000320_new.h5
    Writing to file single_particle_electric_field_0000320.h5
    Time step from 320 to 321 of 1000
    Time step from 321 to 322 of 1000
    Time step from 322 to 323 of 1000
    Time step from 323 to 324 of 1000
    Time step from 324 to 325 of 1000
    Time step from 325 to 326 of 1000
    Time step from 326 to 327 of 1000
    Time step from 327 to 328 of 1000
    Time step from 328 to 329 of 1000
    Time step from 329 to 330 of 1000
    Writing step 330 to file
    Writing to file single_particle_electric_field_0000330_new.h5
    Writing to file single_particle_electric_field_0000330.h5
    Time step from 330 to 331 of 1000
    Time step from 331 to 332 of 1000
    Time step from 332 to 333 of 1000
    Time step from 333 to 334 of 1000
    Time step from 334 to 335 of 1000
    Time step from 335 to 336 of 1000
    Time step from 336 to 337 of 1000
    Time step from 337 to 338 of 1000
    Time step from 338 to 339 of 1000
    Time step from 339 to 340 of 1000
    Writing step 340 to file
    Writing to file single_particle_electric_field_0000340_new.h5
    Writing to file single_particle_electric_field_0000340.h5
    Time step from 340 to 341 of 1000
    Time step from 341 to 342 of 1000
    Time step from 342 to 343 of 1000
    Time step from 343 to 344 of 1000
    Time step from 344 to 345 of 1000
    Time step from 345 to 346 of 1000
    Time step from 346 to 347 of 1000
    Time step from 347 to 348 of 1000
    Time step from 348 to 349 of 1000
    Time step from 349 to 350 of 1000
    Writing step 350 to file
    Writing to file single_particle_electric_field_0000350_new.h5
    Writing to file single_particle_electric_field_0000350.h5
    Time step from 350 to 351 of 1000
    Time step from 351 to 352 of 1000
    Time step from 352 to 353 of 1000
    Time step from 353 to 354 of 1000
    Time step from 354 to 355 of 1000
    Time step from 355 to 356 of 1000
    Time step from 356 to 357 of 1000
    Time step from 357 to 358 of 1000
    Time step from 358 to 359 of 1000
    Time step from 359 to 360 of 1000
    Writing step 360 to file
    Writing to file single_particle_electric_field_0000360_new.h5
    Writing to file single_particle_electric_field_0000360.h5
    Time step from 360 to 361 of 1000
    Time step from 361 to 362 of 1000
    Time step from 362 to 363 of 1000
    Time step from 363 to 364 of 1000
    Time step from 364 to 365 of 1000
    Time step from 365 to 366 of 1000
    Time step from 366 to 367 of 1000
    Time step from 367 to 368 of 1000
    Time step from 368 to 369 of 1000
    Time step from 369 to 370 of 1000
    Writing step 370 to file
    Writing to file single_particle_electric_field_0000370_new.h5
    Writing to file single_particle_electric_field_0000370.h5
    Time step from 370 to 371 of 1000
    Time step from 371 to 372 of 1000
    Time step from 372 to 373 of 1000
    Time step from 373 to 374 of 1000
    Time step from 374 to 375 of 1000
    Time step from 375 to 376 of 1000
    Time step from 376 to 377 of 1000
    Time step from 377 to 378 of 1000
    Time step from 378 to 379 of 1000
    Time step from 379 to 380 of 1000
    Writing step 380 to file
    Writing to file single_particle_electric_field_0000380_new.h5
    Writing to file single_particle_electric_field_0000380.h5
    Time step from 380 to 381 of 1000
    Time step from 381 to 382 of 1000
    Time step from 382 to 383 of 1000
    Time step from 383 to 384 of 1000
    Time step from 384 to 385 of 1000
    Time step from 385 to 386 of 1000
    Time step from 386 to 387 of 1000
    Time step from 387 to 388 of 1000
    Time step from 388 to 389 of 1000
    Time step from 389 to 390 of 1000
    Writing step 390 to file
    Writing to file single_particle_electric_field_0000390_new.h5
    Writing to file single_particle_electric_field_0000390.h5
    Time step from 390 to 391 of 1000
    Time step from 391 to 392 of 1000
    Time step from 392 to 393 of 1000
    Time step from 393 to 394 of 1000
    Time step from 394 to 395 of 1000
    Time step from 395 to 396 of 1000
    Time step from 396 to 397 of 1000
    Time step from 397 to 398 of 1000
    Time step from 398 to 399 of 1000
    Time step from 399 to 400 of 1000
    Writing step 400 to file
    Writing to file single_particle_electric_field_0000400_new.h5
    Writing to file single_particle_electric_field_0000400.h5
    Time step from 400 to 401 of 1000
    Time step from 401 to 402 of 1000
    Time step from 402 to 403 of 1000
    Time step from 403 to 404 of 1000
    Time step from 404 to 405 of 1000
    Time step from 405 to 406 of 1000
    Time step from 406 to 407 of 1000
    Time step from 407 to 408 of 1000
    Time step from 408 to 409 of 1000
    Time step from 409 to 410 of 1000
    Writing step 410 to file
    Writing to file single_particle_electric_field_0000410_new.h5
    Writing to file single_particle_electric_field_0000410.h5
    Time step from 410 to 411 of 1000
    Time step from 411 to 412 of 1000
    Time step from 412 to 413 of 1000
    Time step from 413 to 414 of 1000
    Time step from 414 to 415 of 1000
    Time step from 415 to 416 of 1000
    Time step from 416 to 417 of 1000
    Time step from 417 to 418 of 1000
    Time step from 418 to 419 of 1000
    Time step from 419 to 420 of 1000
    Writing step 420 to file
    Writing to file single_particle_electric_field_0000420_new.h5
    Writing to file single_particle_electric_field_0000420.h5
    Time step from 420 to 421 of 1000
    Time step from 421 to 422 of 1000
    Time step from 422 to 423 of 1000
    Time step from 423 to 424 of 1000
    Time step from 424 to 425 of 1000
    Time step from 425 to 426 of 1000
    Time step from 426 to 427 of 1000
    Time step from 427 to 428 of 1000
    Time step from 428 to 429 of 1000
    Time step from 429 to 430 of 1000
    Writing step 430 to file
    Writing to file single_particle_electric_field_0000430_new.h5
    Writing to file single_particle_electric_field_0000430.h5
    Time step from 430 to 431 of 1000
    Time step from 431 to 432 of 1000
    Time step from 432 to 433 of 1000
    Time step from 433 to 434 of 1000
    Time step from 434 to 435 of 1000
    Time step from 435 to 436 of 1000
    Time step from 436 to 437 of 1000
    Time step from 437 to 438 of 1000
    Time step from 438 to 439 of 1000
    Time step from 439 to 440 of 1000
    Writing step 440 to file
    Writing to file single_particle_electric_field_0000440_new.h5
    Writing to file single_particle_electric_field_0000440.h5
    Time step from 440 to 441 of 1000
    Time step from 441 to 442 of 1000
    Time step from 442 to 443 of 1000
    Time step from 443 to 444 of 1000
    Time step from 444 to 445 of 1000
    Time step from 445 to 446 of 1000
    Time step from 446 to 447 of 1000
    Time step from 447 to 448 of 1000
    Time step from 448 to 449 of 1000
    Time step from 449 to 450 of 1000
    Writing step 450 to file
    Writing to file single_particle_electric_field_0000450_new.h5
    Writing to file single_particle_electric_field_0000450.h5
    Time step from 450 to 451 of 1000
    Time step from 451 to 452 of 1000
    Time step from 452 to 453 of 1000
    Time step from 453 to 454 of 1000
    Time step from 454 to 455 of 1000
    Time step from 455 to 456 of 1000
    Time step from 456 to 457 of 1000
    Time step from 457 to 458 of 1000
    Time step from 458 to 459 of 1000
    Time step from 459 to 460 of 1000
    Writing step 460 to file
    Writing to file single_particle_electric_field_0000460_new.h5
    Writing to file single_particle_electric_field_0000460.h5
    Time step from 460 to 461 of 1000
    Time step from 461 to 462 of 1000
    Time step from 462 to 463 of 1000
    Time step from 463 to 464 of 1000
    Time step from 464 to 465 of 1000
    Time step from 465 to 466 of 1000
    Time step from 466 to 467 of 1000
    Time step from 467 to 468 of 1000
    Time step from 468 to 469 of 1000
    Time step from 469 to 470 of 1000
    Writing step 470 to file
    Writing to file single_particle_electric_field_0000470_new.h5
    Writing to file single_particle_electric_field_0000470.h5
    Time step from 470 to 471 of 1000
    Time step from 471 to 472 of 1000
    Time step from 472 to 473 of 1000
    Time step from 473 to 474 of 1000
    Time step from 474 to 475 of 1000
    Time step from 475 to 476 of 1000
    Time step from 476 to 477 of 1000
    Time step from 477 to 478 of 1000
    Time step from 478 to 479 of 1000
    Time step from 479 to 480 of 1000
    Writing step 480 to file
    Writing to file single_particle_electric_field_0000480_new.h5
    Writing to file single_particle_electric_field_0000480.h5
    Time step from 480 to 481 of 1000
    Time step from 481 to 482 of 1000
    Time step from 482 to 483 of 1000
    Time step from 483 to 484 of 1000
    Time step from 484 to 485 of 1000
    Time step from 485 to 486 of 1000
    Time step from 486 to 487 of 1000
    Time step from 487 to 488 of 1000
    Time step from 488 to 489 of 1000
    Time step from 489 to 490 of 1000
    Writing step 490 to file
    Writing to file single_particle_electric_field_0000490_new.h5
    Writing to file single_particle_electric_field_0000490.h5
    Time step from 490 to 491 of 1000
    Time step from 491 to 492 of 1000
    Time step from 492 to 493 of 1000
    Time step from 493 to 494 of 1000
    Time step from 494 to 495 of 1000
    Time step from 495 to 496 of 1000
    Time step from 496 to 497 of 1000
    Time step from 497 to 498 of 1000
    Time step from 498 to 499 of 1000
    Time step from 499 to 500 of 1000
    Writing step 500 to file
    Writing to file single_particle_electric_field_0000500_new.h5
    Writing to file single_particle_electric_field_0000500.h5
    Time step from 500 to 501 of 1000
    Time step from 501 to 502 of 1000
    Time step from 502 to 503 of 1000
    Time step from 503 to 504 of 1000
    Time step from 504 to 505 of 1000
    Time step from 505 to 506 of 1000
    Time step from 506 to 507 of 1000
    Time step from 507 to 508 of 1000
    Time step from 508 to 509 of 1000
    Time step from 509 to 510 of 1000
    Writing step 510 to file
    Writing to file single_particle_electric_field_0000510_new.h5
    Writing to file single_particle_electric_field_0000510.h5
    Time step from 510 to 511 of 1000
    Time step from 511 to 512 of 1000
    Time step from 512 to 513 of 1000
    Time step from 513 to 514 of 1000
    Time step from 514 to 515 of 1000
    Time step from 515 to 516 of 1000
    Time step from 516 to 517 of 1000
    Time step from 517 to 518 of 1000
    Time step from 518 to 519 of 1000
    Time step from 519 to 520 of 1000
    Writing step 520 to file
    Writing to file single_particle_electric_field_0000520_new.h5
    Writing to file single_particle_electric_field_0000520.h5
    Time step from 520 to 521 of 1000
    Time step from 521 to 522 of 1000
    Time step from 522 to 523 of 1000
    Time step from 523 to 524 of 1000
    Time step from 524 to 525 of 1000
    Time step from 525 to 526 of 1000
    Time step from 526 to 527 of 1000
    Time step from 527 to 528 of 1000
    Time step from 528 to 529 of 1000
    Time step from 529 to 530 of 1000
    Writing step 530 to file
    Writing to file single_particle_electric_field_0000530_new.h5
    Writing to file single_particle_electric_field_0000530.h5
    Time step from 530 to 531 of 1000
    Time step from 531 to 532 of 1000
    Time step from 532 to 533 of 1000
    Time step from 533 to 534 of 1000
    Time step from 534 to 535 of 1000
    Time step from 535 to 536 of 1000
    Time step from 536 to 537 of 1000
    Time step from 537 to 538 of 1000
    Time step from 538 to 539 of 1000
    Time step from 539 to 540 of 1000
    Writing step 540 to file
    Writing to file single_particle_electric_field_0000540_new.h5
    Writing to file single_particle_electric_field_0000540.h5
    Time step from 540 to 541 of 1000
    Time step from 541 to 542 of 1000
    Time step from 542 to 543 of 1000
    Time step from 543 to 544 of 1000
    Time step from 544 to 545 of 1000
    Time step from 545 to 546 of 1000
    Time step from 546 to 547 of 1000
    Time step from 547 to 548 of 1000
    Time step from 548 to 549 of 1000
    Time step from 549 to 550 of 1000
    Writing step 550 to file
    Writing to file single_particle_electric_field_0000550_new.h5
    Writing to file single_particle_electric_field_0000550.h5
    Time step from 550 to 551 of 1000
    Time step from 551 to 552 of 1000
    Time step from 552 to 553 of 1000
    Time step from 553 to 554 of 1000
    Time step from 554 to 555 of 1000
    Time step from 555 to 556 of 1000
    Time step from 556 to 557 of 1000
    Time step from 557 to 558 of 1000
    Time step from 558 to 559 of 1000
    Time step from 559 to 560 of 1000
    Writing step 560 to file
    Writing to file single_particle_electric_field_0000560_new.h5
    Writing to file single_particle_electric_field_0000560.h5
    Time step from 560 to 561 of 1000
    Time step from 561 to 562 of 1000
    Time step from 562 to 563 of 1000
    Time step from 563 to 564 of 1000
    Time step from 564 to 565 of 1000
    Time step from 565 to 566 of 1000
    Time step from 566 to 567 of 1000
    Time step from 567 to 568 of 1000
    Time step from 568 to 569 of 1000
    Time step from 569 to 570 of 1000
    Writing step 570 to file
    Writing to file single_particle_electric_field_0000570_new.h5
    Writing to file single_particle_electric_field_0000570.h5
    Time step from 570 to 571 of 1000
    Time step from 571 to 572 of 1000
    Time step from 572 to 573 of 1000
    Time step from 573 to 574 of 1000
    Time step from 574 to 575 of 1000
    Time step from 575 to 576 of 1000
    Time step from 576 to 577 of 1000
    Time step from 577 to 578 of 1000
    Time step from 578 to 579 of 1000
    Time step from 579 to 580 of 1000
    Writing step 580 to file
    Writing to file single_particle_electric_field_0000580_new.h5
    Writing to file single_particle_electric_field_0000580.h5
    Time step from 580 to 581 of 1000
    Time step from 581 to 582 of 1000
    Time step from 582 to 583 of 1000
    Time step from 583 to 584 of 1000
    Time step from 584 to 585 of 1000
    Time step from 585 to 586 of 1000
    Time step from 586 to 587 of 1000
    Time step from 587 to 588 of 1000
    Time step from 588 to 589 of 1000
    Time step from 589 to 590 of 1000
    Writing step 590 to file
    Writing to file single_particle_electric_field_0000590_new.h5
    Writing to file single_particle_electric_field_0000590.h5
    Time step from 590 to 591 of 1000
    Time step from 591 to 592 of 1000
    Time step from 592 to 593 of 1000
    Time step from 593 to 594 of 1000
    Time step from 594 to 595 of 1000
    Time step from 595 to 596 of 1000
    Time step from 596 to 597 of 1000
    Time step from 597 to 598 of 1000
    Time step from 598 to 599 of 1000
    Time step from 599 to 600 of 1000
    Writing step 600 to file
    Writing to file single_particle_electric_field_0000600_new.h5
    Writing to file single_particle_electric_field_0000600.h5
    Time step from 600 to 601 of 1000
    Time step from 601 to 602 of 1000
    Time step from 602 to 603 of 1000
    Time step from 603 to 604 of 1000
    Time step from 604 to 605 of 1000
    Time step from 605 to 606 of 1000
    Time step from 606 to 607 of 1000
    Time step from 607 to 608 of 1000
    Time step from 608 to 609 of 1000
    Time step from 609 to 610 of 1000
    Writing step 610 to file
    Writing to file single_particle_electric_field_0000610_new.h5
    Writing to file single_particle_electric_field_0000610.h5
    Time step from 610 to 611 of 1000
    Time step from 611 to 612 of 1000
    Time step from 612 to 613 of 1000
    Time step from 613 to 614 of 1000
    Time step from 614 to 615 of 1000
    Time step from 615 to 616 of 1000
    Time step from 616 to 617 of 1000
    Time step from 617 to 618 of 1000
    Time step from 618 to 619 of 1000
    Time step from 619 to 620 of 1000
    Writing step 620 to file
    Writing to file single_particle_electric_field_0000620_new.h5
    Writing to file single_particle_electric_field_0000620.h5
    Time step from 620 to 621 of 1000
    Time step from 621 to 622 of 1000
    Time step from 622 to 623 of 1000
    Time step from 623 to 624 of 1000
    Time step from 624 to 625 of 1000
    Time step from 625 to 626 of 1000
    Time step from 626 to 627 of 1000
    Time step from 627 to 628 of 1000
    Time step from 628 to 629 of 1000
    Time step from 629 to 630 of 1000
    Writing step 630 to file
    Writing to file single_particle_electric_field_0000630_new.h5
    Writing to file single_particle_electric_field_0000630.h5
    Time step from 630 to 631 of 1000
    Time step from 631 to 632 of 1000
    Time step from 632 to 633 of 1000
    Time step from 633 to 634 of 1000
    Time step from 634 to 635 of 1000
    Time step from 635 to 636 of 1000
    Time step from 636 to 637 of 1000
    Time step from 637 to 638 of 1000
    Time step from 638 to 639 of 1000
    Time step from 639 to 640 of 1000
    Writing step 640 to file
    Writing to file single_particle_electric_field_0000640_new.h5
    Writing to file single_particle_electric_field_0000640.h5
    Time step from 640 to 641 of 1000
    Time step from 641 to 642 of 1000
    Time step from 642 to 643 of 1000
    Time step from 643 to 644 of 1000
    Time step from 644 to 645 of 1000
    Time step from 645 to 646 of 1000
    Time step from 646 to 647 of 1000
    Time step from 647 to 648 of 1000
    Time step from 648 to 649 of 1000
    Time step from 649 to 650 of 1000
    Writing step 650 to file
    Writing to file single_particle_electric_field_0000650_new.h5
    Writing to file single_particle_electric_field_0000650.h5
    Time step from 650 to 651 of 1000
    Time step from 651 to 652 of 1000
    Time step from 652 to 653 of 1000
    Time step from 653 to 654 of 1000
    Time step from 654 to 655 of 1000
    Time step from 655 to 656 of 1000
    Time step from 656 to 657 of 1000
    Time step from 657 to 658 of 1000
    Time step from 658 to 659 of 1000
    Time step from 659 to 660 of 1000
    Writing step 660 to file
    Writing to file single_particle_electric_field_0000660_new.h5
    Writing to file single_particle_electric_field_0000660.h5
    Time step from 660 to 661 of 1000
    Time step from 661 to 662 of 1000
    Time step from 662 to 663 of 1000
    Time step from 663 to 664 of 1000
    Time step from 664 to 665 of 1000
    Time step from 665 to 666 of 1000
    Time step from 666 to 667 of 1000
    Time step from 667 to 668 of 1000
    Time step from 668 to 669 of 1000
    Time step from 669 to 670 of 1000
    Writing step 670 to file
    Writing to file single_particle_electric_field_0000670_new.h5
    Writing to file single_particle_electric_field_0000670.h5
    Time step from 670 to 671 of 1000
    Time step from 671 to 672 of 1000
    Time step from 672 to 673 of 1000
    Time step from 673 to 674 of 1000
    Time step from 674 to 675 of 1000
    Time step from 675 to 676 of 1000
    Time step from 676 to 677 of 1000
    Time step from 677 to 678 of 1000
    Time step from 678 to 679 of 1000
    Time step from 679 to 680 of 1000
    Writing step 680 to file
    Writing to file single_particle_electric_field_0000680_new.h5
    Writing to file single_particle_electric_field_0000680.h5
    Time step from 680 to 681 of 1000
    Time step from 681 to 682 of 1000
    Time step from 682 to 683 of 1000
    Time step from 683 to 684 of 1000
    Time step from 684 to 685 of 1000
    Time step from 685 to 686 of 1000
    Time step from 686 to 687 of 1000
    Time step from 687 to 688 of 1000
    Time step from 688 to 689 of 1000
    Time step from 689 to 690 of 1000
    Writing step 690 to file
    Writing to file single_particle_electric_field_0000690_new.h5
    Writing to file single_particle_electric_field_0000690.h5
    Time step from 690 to 691 of 1000
    Time step from 691 to 692 of 1000
    Time step from 692 to 693 of 1000
    Time step from 693 to 694 of 1000
    Time step from 694 to 695 of 1000
    Time step from 695 to 696 of 1000
    Time step from 696 to 697 of 1000
    Time step from 697 to 698 of 1000
    Time step from 698 to 699 of 1000
    Time step from 699 to 700 of 1000
    Writing step 700 to file
    Writing to file single_particle_electric_field_0000700_new.h5
    Writing to file single_particle_electric_field_0000700.h5
    Time step from 700 to 701 of 1000
    Time step from 701 to 702 of 1000
    Time step from 702 to 703 of 1000
    Time step from 703 to 704 of 1000
    Time step from 704 to 705 of 1000
    Time step from 705 to 706 of 1000
    Time step from 706 to 707 of 1000
    Time step from 707 to 708 of 1000
    Time step from 708 to 709 of 1000
    Time step from 709 to 710 of 1000
    Writing step 710 to file
    Writing to file single_particle_electric_field_0000710_new.h5
    Writing to file single_particle_electric_field_0000710.h5
    Time step from 710 to 711 of 1000
    Time step from 711 to 712 of 1000
    Time step from 712 to 713 of 1000
    Time step from 713 to 714 of 1000
    Time step from 714 to 715 of 1000
    Time step from 715 to 716 of 1000
    Time step from 716 to 717 of 1000
    Time step from 717 to 718 of 1000
    Time step from 718 to 719 of 1000
    Time step from 719 to 720 of 1000
    Writing step 720 to file
    Writing to file single_particle_electric_field_0000720_new.h5
    Writing to file single_particle_electric_field_0000720.h5
    Time step from 720 to 721 of 1000
    Time step from 721 to 722 of 1000
    Time step from 722 to 723 of 1000
    Time step from 723 to 724 of 1000
    Time step from 724 to 725 of 1000
    Time step from 725 to 726 of 1000
    Time step from 726 to 727 of 1000
    Time step from 727 to 728 of 1000
    Time step from 728 to 729 of 1000
    Time step from 729 to 730 of 1000
    Writing step 730 to file
    Writing to file single_particle_electric_field_0000730_new.h5
    Writing to file single_particle_electric_field_0000730.h5
    Time step from 730 to 731 of 1000
    Time step from 731 to 732 of 1000
    Time step from 732 to 733 of 1000
    Time step from 733 to 734 of 1000
    Time step from 734 to 735 of 1000
    Time step from 735 to 736 of 1000
    Time step from 736 to 737 of 1000
    Time step from 737 to 738 of 1000
    Time step from 738 to 739 of 1000
    Time step from 739 to 740 of 1000
    Writing step 740 to file
    Writing to file single_particle_electric_field_0000740_new.h5
    Writing to file single_particle_electric_field_0000740.h5
    Time step from 740 to 741 of 1000
    Time step from 741 to 742 of 1000
    Time step from 742 to 743 of 1000
    Time step from 743 to 744 of 1000
    Time step from 744 to 745 of 1000
    Time step from 745 to 746 of 1000
    Time step from 746 to 747 of 1000
    Time step from 747 to 748 of 1000
    Time step from 748 to 749 of 1000
    Time step from 749 to 750 of 1000
    Writing step 750 to file
    Writing to file single_particle_electric_field_0000750_new.h5
    Writing to file single_particle_electric_field_0000750.h5
    Time step from 750 to 751 of 1000
    Time step from 751 to 752 of 1000
    Time step from 752 to 753 of 1000
    Time step from 753 to 754 of 1000
    Time step from 754 to 755 of 1000
    Time step from 755 to 756 of 1000
    Time step from 756 to 757 of 1000
    Time step from 757 to 758 of 1000
    Time step from 758 to 759 of 1000
    Time step from 759 to 760 of 1000
    Writing step 760 to file
    Writing to file single_particle_electric_field_0000760_new.h5
    Writing to file single_particle_electric_field_0000760.h5
    Time step from 760 to 761 of 1000
    Time step from 761 to 762 of 1000
    Time step from 762 to 763 of 1000
    Time step from 763 to 764 of 1000
    Time step from 764 to 765 of 1000
    Time step from 765 to 766 of 1000
    Time step from 766 to 767 of 1000
    Time step from 767 to 768 of 1000
    Time step from 768 to 769 of 1000
    Time step from 769 to 770 of 1000
    Writing step 770 to file
    Writing to file single_particle_electric_field_0000770_new.h5
    Writing to file single_particle_electric_field_0000770.h5
    Time step from 770 to 771 of 1000
    Time step from 771 to 772 of 1000
    Time step from 772 to 773 of 1000
    Time step from 773 to 774 of 1000
    Time step from 774 to 775 of 1000
    Time step from 775 to 776 of 1000
    Time step from 776 to 777 of 1000
    Time step from 777 to 778 of 1000
    Time step from 778 to 779 of 1000
    Time step from 779 to 780 of 1000
    Writing step 780 to file
    Writing to file single_particle_electric_field_0000780_new.h5
    Writing to file single_particle_electric_field_0000780.h5
    Time step from 780 to 781 of 1000
    Time step from 781 to 782 of 1000
    Time step from 782 to 783 of 1000
    Time step from 783 to 784 of 1000
    Time step from 784 to 785 of 1000
    Time step from 785 to 786 of 1000
    Time step from 786 to 787 of 1000
    Time step from 787 to 788 of 1000
    Time step from 788 to 789 of 1000
    Time step from 789 to 790 of 1000
    Writing step 790 to file
    Writing to file single_particle_electric_field_0000790_new.h5
    Writing to file single_particle_electric_field_0000790.h5
    Time step from 790 to 791 of 1000
    Time step from 791 to 792 of 1000
    Time step from 792 to 793 of 1000
    Time step from 793 to 794 of 1000
    Time step from 794 to 795 of 1000
    Time step from 795 to 796 of 1000
    Time step from 796 to 797 of 1000
    Time step from 797 to 798 of 1000
    Time step from 798 to 799 of 1000
    Time step from 799 to 800 of 1000
    Writing step 800 to file
    Writing to file single_particle_electric_field_0000800_new.h5
    Writing to file single_particle_electric_field_0000800.h5
    Time step from 800 to 801 of 1000
    Time step from 801 to 802 of 1000
    Time step from 802 to 803 of 1000
    Time step from 803 to 804 of 1000
    Time step from 804 to 805 of 1000
    Time step from 805 to 806 of 1000
    Time step from 806 to 807 of 1000
    Time step from 807 to 808 of 1000
    Time step from 808 to 809 of 1000
    Time step from 809 to 810 of 1000
    Writing step 810 to file
    Writing to file single_particle_electric_field_0000810_new.h5
    Writing to file single_particle_electric_field_0000810.h5
    Time step from 810 to 811 of 1000
    Time step from 811 to 812 of 1000
    Time step from 812 to 813 of 1000
    Time step from 813 to 814 of 1000
    Time step from 814 to 815 of 1000
    Time step from 815 to 816 of 1000
    Time step from 816 to 817 of 1000
    Time step from 817 to 818 of 1000
    Time step from 818 to 819 of 1000
    Time step from 819 to 820 of 1000
    Writing step 820 to file
    Writing to file single_particle_electric_field_0000820_new.h5
    Writing to file single_particle_electric_field_0000820.h5
    Time step from 820 to 821 of 1000
    Time step from 821 to 822 of 1000
    Time step from 822 to 823 of 1000
    Time step from 823 to 824 of 1000
    Time step from 824 to 825 of 1000
    Time step from 825 to 826 of 1000
    Time step from 826 to 827 of 1000
    Time step from 827 to 828 of 1000
    Time step from 828 to 829 of 1000
    Time step from 829 to 830 of 1000
    Writing step 830 to file
    Writing to file single_particle_electric_field_0000830_new.h5
    Writing to file single_particle_electric_field_0000830.h5
    Time step from 830 to 831 of 1000
    Time step from 831 to 832 of 1000
    Time step from 832 to 833 of 1000
    Time step from 833 to 834 of 1000
    Time step from 834 to 835 of 1000
    Time step from 835 to 836 of 1000
    Time step from 836 to 837 of 1000
    Time step from 837 to 838 of 1000
    Time step from 838 to 839 of 1000
    Time step from 839 to 840 of 1000
    Writing step 840 to file
    Writing to file single_particle_electric_field_0000840_new.h5
    Writing to file single_particle_electric_field_0000840.h5
    Time step from 840 to 841 of 1000
    Time step from 841 to 842 of 1000
    Time step from 842 to 843 of 1000
    Time step from 843 to 844 of 1000
    Time step from 844 to 845 of 1000
    Time step from 845 to 846 of 1000
    Time step from 846 to 847 of 1000
    Time step from 847 to 848 of 1000
    Time step from 848 to 849 of 1000
    Time step from 849 to 850 of 1000
    Writing step 850 to file
    Writing to file single_particle_electric_field_0000850_new.h5
    Writing to file single_particle_electric_field_0000850.h5
    Time step from 850 to 851 of 1000
    Time step from 851 to 852 of 1000
    Time step from 852 to 853 of 1000
    Time step from 853 to 854 of 1000
    Time step from 854 to 855 of 1000
    Time step from 855 to 856 of 1000
    Time step from 856 to 857 of 1000
    Time step from 857 to 858 of 1000
    Time step from 858 to 859 of 1000
    Time step from 859 to 860 of 1000
    Writing step 860 to file
    Writing to file single_particle_electric_field_0000860_new.h5
    Writing to file single_particle_electric_field_0000860.h5
    Time step from 860 to 861 of 1000
    Time step from 861 to 862 of 1000
    Time step from 862 to 863 of 1000
    Time step from 863 to 864 of 1000
    Time step from 864 to 865 of 1000
    Time step from 865 to 866 of 1000
    Time step from 866 to 867 of 1000
    Time step from 867 to 868 of 1000
    Time step from 868 to 869 of 1000
    Time step from 869 to 870 of 1000
    Writing step 870 to file
    Writing to file single_particle_electric_field_0000870_new.h5
    Writing to file single_particle_electric_field_0000870.h5
    Time step from 870 to 871 of 1000
    Time step from 871 to 872 of 1000
    Time step from 872 to 873 of 1000
    Time step from 873 to 874 of 1000
    Time step from 874 to 875 of 1000
    Time step from 875 to 876 of 1000
    Time step from 876 to 877 of 1000
    Time step from 877 to 878 of 1000
    Time step from 878 to 879 of 1000
    Time step from 879 to 880 of 1000
    Writing step 880 to file
    Writing to file single_particle_electric_field_0000880_new.h5
    Writing to file single_particle_electric_field_0000880.h5
    Time step from 880 to 881 of 1000
    Time step from 881 to 882 of 1000
    Time step from 882 to 883 of 1000
    Time step from 883 to 884 of 1000
    Time step from 884 to 885 of 1000
    Time step from 885 to 886 of 1000
    Time step from 886 to 887 of 1000
    Time step from 887 to 888 of 1000
    Time step from 888 to 889 of 1000
    Time step from 889 to 890 of 1000
    Writing step 890 to file
    Writing to file single_particle_electric_field_0000890_new.h5
    Writing to file single_particle_electric_field_0000890.h5
    Time step from 890 to 891 of 1000
    Time step from 891 to 892 of 1000
    Time step from 892 to 893 of 1000
    Time step from 893 to 894 of 1000
    Time step from 894 to 895 of 1000
    Time step from 895 to 896 of 1000
    Time step from 896 to 897 of 1000
    Time step from 897 to 898 of 1000
    Time step from 898 to 899 of 1000
    Time step from 899 to 900 of 1000
    Writing step 900 to file
    Writing to file single_particle_electric_field_0000900_new.h5
    Writing to file single_particle_electric_field_0000900.h5
    Time step from 900 to 901 of 1000
    Time step from 901 to 902 of 1000
    Time step from 902 to 903 of 1000
    Time step from 903 to 904 of 1000
    Time step from 904 to 905 of 1000
    Time step from 905 to 906 of 1000
    Time step from 906 to 907 of 1000
    Time step from 907 to 908 of 1000
    Time step from 908 to 909 of 1000
    Time step from 909 to 910 of 1000
    Writing step 910 to file
    Writing to file single_particle_electric_field_0000910_new.h5
    Writing to file single_particle_electric_field_0000910.h5
    Time step from 910 to 911 of 1000
    Time step from 911 to 912 of 1000
    Time step from 912 to 913 of 1000
    Time step from 913 to 914 of 1000
    Time step from 914 to 915 of 1000
    Time step from 915 to 916 of 1000
    Time step from 916 to 917 of 1000
    Time step from 917 to 918 of 1000
    Time step from 918 to 919 of 1000
    Time step from 919 to 920 of 1000
    Writing step 920 to file
    Writing to file single_particle_electric_field_0000920_new.h5
    Writing to file single_particle_electric_field_0000920.h5
    Time step from 920 to 921 of 1000
    Time step from 921 to 922 of 1000
    Time step from 922 to 923 of 1000
    Time step from 923 to 924 of 1000
    Time step from 924 to 925 of 1000
    Time step from 925 to 926 of 1000
    Time step from 926 to 927 of 1000
    Time step from 927 to 928 of 1000
    Time step from 928 to 929 of 1000
    Time step from 929 to 930 of 1000
    Writing step 930 to file
    Writing to file single_particle_electric_field_0000930_new.h5
    Writing to file single_particle_electric_field_0000930.h5
    Time step from 930 to 931 of 1000
    Time step from 931 to 932 of 1000
    Time step from 932 to 933 of 1000
    Time step from 933 to 934 of 1000
    Time step from 934 to 935 of 1000
    Time step from 935 to 936 of 1000
    Time step from 936 to 937 of 1000
    Time step from 937 to 938 of 1000
    Time step from 938 to 939 of 1000
    Time step from 939 to 940 of 1000
    Writing step 940 to file
    Writing to file single_particle_electric_field_0000940_new.h5
    Writing to file single_particle_electric_field_0000940.h5
    Time step from 940 to 941 of 1000
    Time step from 941 to 942 of 1000
    Time step from 942 to 943 of 1000
    Time step from 943 to 944 of 1000
    Time step from 944 to 945 of 1000
    Time step from 945 to 946 of 1000
    Time step from 946 to 947 of 1000
    Time step from 947 to 948 of 1000
    Time step from 948 to 949 of 1000
    Time step from 949 to 950 of 1000
    Writing step 950 to file
    Writing to file single_particle_electric_field_0000950_new.h5
    Writing to file single_particle_electric_field_0000950.h5
    Time step from 950 to 951 of 1000
    Time step from 951 to 952 of 1000
    Time step from 952 to 953 of 1000
    Time step from 953 to 954 of 1000
    Time step from 954 to 955 of 1000
    Time step from 955 to 956 of 1000
    Time step from 956 to 957 of 1000
    Time step from 957 to 958 of 1000
    Time step from 958 to 959 of 1000
    Time step from 959 to 960 of 1000
    Writing step 960 to file
    Writing to file single_particle_electric_field_0000960_new.h5
    Writing to file single_particle_electric_field_0000960.h5
    Time step from 960 to 961 of 1000
    Time step from 961 to 962 of 1000
    Time step from 962 to 963 of 1000
    Time step from 963 to 964 of 1000
    Time step from 964 to 965 of 1000
    Time step from 965 to 966 of 1000
    Time step from 966 to 967 of 1000
    Time step from 967 to 968 of 1000
    Time step from 968 to 969 of 1000
    Time step from 969 to 970 of 1000
    Writing step 970 to file
    Writing to file single_particle_electric_field_0000970_new.h5
    Writing to file single_particle_electric_field_0000970.h5
    Time step from 970 to 971 of 1000
    Time step from 971 to 972 of 1000
    Time step from 972 to 973 of 1000
    Time step from 973 to 974 of 1000
    Time step from 974 to 975 of 1000
    Time step from 975 to 976 of 1000
    Time step from 976 to 977 of 1000
    Time step from 977 to 978 of 1000
    Time step from 978 to 979 of 1000
    Time step from 979 to 980 of 1000
    Writing step 980 to file
    Writing to file single_particle_electric_field_0000980_new.h5
    Writing to file single_particle_electric_field_0000980.h5
    Time step from 980 to 981 of 1000
    Time step from 981 to 982 of 1000
    Time step from 982 to 983 of 1000
    Time step from 983 to 984 of 1000
    Time step from 984 to 985 of 1000
    Time step from 985 to 986 of 1000
    Time step from 986 to 987 of 1000
    Time step from 987 to 988 of 1000
    Time step from 988 to 989 of 1000
    Time step from 989 to 990 of 1000
    Writing step 990 to file
    Writing to file single_particle_electric_field_0000990_new.h5
    Writing to file single_particle_electric_field_0000990.h5
    Time step from 990 to 991 of 1000
    Time step from 991 to 992 of 1000
    Time step from 992 to 993 of 1000
    Time step from 993 to 994 of 1000
    Time step from 994 to 995 of 1000
    Time step from 995 to 996 of 1000
    Time step from 996 to 997 of 1000
    Time step from 997 to 998 of 1000
    Time step from 998 to 999 of 1000
    Time step from 999 to 1000 of 1000
    Writing step 1000 to file
    Writing to file single_particle_electric_field_0001000_new.h5
    Writing to file single_particle_electric_field_0001000.h5

```python
import os, glob
import h5py
import numpy as np
import matplotlib.pyplot as plt

def main():
    num = extract_num_trajectory_from_out_files()
    an = eval_an_trajectory_at_num_time_points( num )
    plot_trajectories( num , an )

def extract_num_trajectory_from_out_files():
    out_files = find_necessary_out_files()

    num_trajectory = []
    for f in out_files:
        num_trajectory.append( extract_time_pos_mom( f ) )

    num_trajectory = remove_empty_and_sort_by_time( num_trajectory )
    num_trajectory = np.array( num_trajectory,
                               dtype=[('t','float'),
                                      ('x','float'), ('y','float'), ('z','float'),
                                      ('px','float'), ('py','float'), ('pz','float') ] )
    return( num_trajectory )

def remove_empty_and_sort_by_time( num_trajectory ):
    removed_empty = [ x for x in num_trajectory if x ]
    sorted_by_time = sorted( removed_empty, key = lambda x: x[0] )
    return ( sorted_by_time )

def find_necessary_out_files():
    os.chdir("./")
    h5files = []
    for file in glob.glob("single_particle_electric_field_[0-9][0-9][0-9][0-9][0-9][0-9][0-9].h5"):
        h5files.append( file )
    return h5files

def extract_time_pos_mom( h5file ):
    h5 = h5py.File( h5file, mode="r")
    t = h5["/TimeGrid"].attrs["current_time"][0]
    t_pos_mom = ()
    if ( len(h5["/ParticleSources/emit_single_particle/particle_id"]) > 0 ):
        x = h5["/ParticleSources/emit_single_particle/position_x"][0]
        y = h5["/ParticleSources/emit_single_particle/position_y"][0]
        z = h5["/ParticleSources/emit_single_particle/position_z"][0]
        px = h5["/ParticleSources/emit_single_particle/momentum_x"][0]
        py = h5["/ParticleSources/emit_single_particle/momentum_y"][0]
        pz = h5["/ParticleSources/emit_single_particle/momentum_z"][0]
        t_pos_mom = (t, x, y, z, px, py, pz)
    h5.close()
    return( t_pos_mom )

def eval_an_trajectory_at_num_time_points( num_trajectory ):
    global mass, charge, E0
    mass, charge, x0, y0, z0, px0, py0, pz0 = get_mass_charge_and_initial_pos_and_mom()
    E0 = eval_field_amplitude()

    an_trajectory = np.empty_like( num_trajectory )
    for i, t in enumerate( num_trajectory['t'] ):
        x, y, z = coords( t, x0, y0, z0, px0, py0, pz0 )
        px, py, pz = momenta( t, px0, py0, pz0 )
        an_trajectory[i] = ( t, x, y ,z, px, py, pz )

    return( an_trajectory )

def get_mass_charge_and_initial_pos_and_mom():
    initial_out_file = "single_particle_electric_field_0000000.h5"
    h5 = h5py.File( initial_out_file, mode="r")
    m = h5["/ParticleSources/emit_single_particle"].attrs["mass"][0]
    q = h5["/ParticleSources/emit_single_particle"].attrs["charge"][0]
    x0 = h5["/ParticleSources/emit_single_particle/position_x"][0]
    y0 = h5["/ParticleSources/emit_single_particle/position_y"][0]
    z0 = h5["/ParticleSources/emit_single_particle/position_z"][0]
    px0 = h5["/ParticleSources/emit_single_particle/momentum_x"][0]
    py0 = h5["/ParticleSources/emit_single_particle/momentum_y"][0]
    pz0 = h5["/ParticleSources/emit_single_particle/momentum_z"][0]
    h5.close()
    return( m, q, x0, y0, z0, px0, py0, pz0 )

def eval_field_amplitude():
    initial_out_file = "single_particle_electric_field_0000000.h5"
    h5 = h5py.File( initial_out_file, mode="r")
    E0 = h5["ExternalFields/uniform_z_field"].attrs["electric_uniform_field_z"]
    return E0

def momenta( t, px0, py0, pz0 ):
    global mass, charge, E0
    px = px0
    py = py0
    pz = pz0 + charge * E0 * t
    return ( px, py, pz )

def coords( t, x0, y0, z0, px0, py0, pz0 ):
    global mass, charge, E0
    x = x0 + px0 / mass * t
    y = y0 + py0 / mass * t
    z = z0 + pz0 / mass * t + 1 / 2 * charge / mass * E0 * t * t
    return ( x, y, z )

def plot_trajectories( num , an ):
    plot_3d( num, an )
    plot_2d( num, an )
    plot_kin_en( num , an )

def plot_3d( num, an ):
    fig = plt.figure()
    ax = fig.gca( projection='3d' )
    ax.plot( num['x'], num['y'], num['z'], '.r', label = "Num" )
    ax.plot( an['x'], an['y'], an['z'], label = "An" )
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.legend( loc = 'upper left', title="3d" )
    plt.show()

def plot_2d( num, an ):
    plt.figure(1)
    #XY
    plt.subplot(131)
    plt.plot( num['x'], num['y'],
              linestyle='', marker='o',
              label = "Num" )
    plt.plot( an['x'], an['y'],
              linestyle='-', marker='', lw = 2,
              label = "An" )
    plt.legend( loc = 'upper right', title="XY" )
    #XZ
    plt.subplot(132)
    plt.plot( num['x'], num['z'],
        linestyle='', marker='o',
        label = "Num" )
    plt.plot( an['x'], an['z'],
              linestyle='-', marker='', lw = 2,
              label = "An" )
    plt.legend( loc = 'upper right', title="XZ" )
    #YZ
    plt.subplot(133)
    plt.plot( num['y'], num['z'],
        linestyle='', marker='o',
        label = "Num" )
    plt.plot( an['y'], an['z'],
              linestyle='-', marker='', lw = 2,
              label = "An" )
    plt.legend( loc = 'upper right', title="YZ" )
    plt.show()

def plot_kin_en( num , an ):
    global mass
    E_num = ( num['px']**2 + num['py']**2 + num['pz']**2 ) / ( 2 * mass )
    E_an = ( an['px']**2 + an['py']**2 + an['pz']**2 ) / ( 2 * mass )
    t = num['t']
    plt.figure()
    axes = plt.gca()
    axes.set_xlabel( "t [s]" )
    axes.set_ylabel( "E [erg]" )
    # axes.set_ylim( [min( E_an.min(), E_num.min() ),
    #                 max( E_an.max(), E_num.max() ) ] )
    line, = plt.plot( t, E_num, 'o' )
    line.set_label( "Num" )
    line, = plt.plot( t, E_an, ls = 'solid', lw = 3 )
    line.set_label( "An" )
    plt.legend( loc = 'upper right' )
    plt.show()

main()

```


[View in Colaboratory](https://colab.research.google.com/github/yepuv1/primality/blob/master/Prime_numbers.ipynb)

# Primality test using ANN.

The aim is to train a ANN Model on a small sample of primes from a finite prime numbers set.  In this notebook, I am generating the primes within 1M, which has 78K primes. The model is trained on a sample of 5k from this 78k prime set. What is interesting is that the model accuracy is 99.6% when testing for primality of the 78k primes. The accuracy drops rapidly for samples outside this 78k range of primes.

```
import math
import numpy as np
import h5py
import matplotlib.pyplot as plt
import tensorflow as tf
import sympy
from tensorflow.python.framework import ops
from sympy import primerange, sieve, composite, prime
import pickle
import timeit
np.random.seed(1)
from PIL import Image, ImageColor
%matplotlib inline
import os
```

```
print(tf.__version__)
device_name = tf.test.gpu_device_name()
if device_name != '/device:GPU:0':
  raise SystemError('GPU device not found')
print('Found GPU at: {}'.format(device_name))
```

    1.11.0
    Found GPU at: /device:GPU:0

```
def convert_dec2bin(num_list,feature_size):
  p_x = None
  for p in num_list:
    pb = bin(p)[2:].zfill(32)
    li = [ int(i) for i in pb]
    a1 = np.array(li).reshape((feature_size,1))
    if p_x is None:
      p_x = a1
    else:
      p_x = np.concatenate((p_x, a1), axis=1)
  return p_x
```

```
def generate_sequence_primes(between):
  start, end = between
  p_num = [i for i in primerange(start, end)]
  return p_num, len(p_num)
```

```
def generate_random_primes(size, primes):
  le = len(primes)
  p_num = [primes[i] for i in np.random.randint(le , size=size)]
  return p_num, size
```

```
def generate_composite(size, primes_set):
  c_num = np.random.randint(10000000, size=size)
  c_num = set(c_num)
  c_num = c_num - primes_set
  return list(c_num), len(c_num)

```

```
def generate_x_y(primes=None, composites=None, feature_size=32, ):
  c_examples_size = 0
  c_x = None
  c_y = None
  p_examples_size = 0
  p_x = None
  p_y = None
  X = None
  Y = None

  if primes is not None :
    p_examples_size = len(primes)
    p_x = convert_dec2bin(primes, feature_size)
    p_y = np.ones(shape=(1,p_examples_size), dtype=np.int32)

  if composites is not None:
    c_examples_size = len(composites)
    c_x = convert_dec2bin(composites, feature_size)
    c_y = np.zeros(shape=(1,c_examples_size), dtype=np.int32)

  if c_x is not None and p_x is not None:
    X = np.concatenate((c_x, p_x), axis=1)
    size = p_examples_size + c_examples_size
    Y = np.append(c_y, p_y).reshape((1, size))
  elif p_x is not None:
    X = p_x
    Y = p_y
    size = p_examples_size
  elif c_x is not None:
    X = c_x
    Y = c_y
    size = c_examples_size

  return X, Y, size

```

```
def one_hot_matrix(labels, C):
    """
    Creates a matrix where the i-th row corresponds to the ith class number and the jth column
                     corresponds to the jth training example. So if example j had a label i. Then entry (i,j)
                     will be 1.

    Arguments:
    labels -- vector containing the labels
    C -- number of classes, the depth of the one hot dimension

    Returns:
    one_hot -- one hot matrix
    """

    C = tf.constant(dtype=tf.int32, name="C", value=C)
    one_hot_matrix = tf.one_hot(labels,depth=C, axis=0)
    with tf.Session() as sess:
      one_hot = sess.run(one_hot_matrix)

    return one_hot

```

```
def create_placeholders(n_x, n_y):
    """
    Creates the placeholders for the tensorflow session.

    Arguments:
    n_x -- scalar, size of input vector
    n_y -- scalar, number of classes (from 0 to 1, so -> 2)

    Returns:
    X -- placeholder for the data input, of shape [n_x, None] and dtype "float"
    Y -- placeholder for the input labels, of shape [n_y, None] and dtype "float"

    Tips:
    - You will use None because it let's us be flexible on the number of examples you will for the placeholders.
      In fact, the number of examples during test/train is different.
    """

    X = tf.placeholder(tf.float32, shape=(n_x, None))
    Y = tf.placeholder(tf.float32, shape=(n_y, None))

    return X, Y
```

```
def initialize_parameters(dic_of_layer_sizes):
    """
    Initializes parameters to build a neural network with tensorflow. The shapes are:
                        W1 : [25, 2]
                        b1 : [25, 1]
                        W2 : [12, 25]
                        b2 : [12, 1]
                        W3 : [6, 12]
                        b3 : [6, 1]

    Returns:
    parameters -- a dictionary of tensors containing W1, b1, W2, b2, W3, b3
    """

    tf.set_random_seed(1)

    parameters ={}
    for key, value in dic_of_layer_sizes.items():
      print(key)
      print(value)
      parameters[key]=tf.get_variable(key, value, initializer = tf.contrib.layers.xavier_initializer(seed = 1))

    return parameters
```

```
def forward_propagation(X, parameters):
    """
    Implements the forward propagation for the model: LINEAR -> RELU -> LINEAR ->  SOFTMAX

    Arguments:
    X -- input dataset placeholder, of shape (input size, number of examples)
    parameters -- python dictionary containing your parameters "W1", "b1", "W2", "b2", "W3", "b3"
                  the shapes are given in initialize_parameters

    Returns:
    Z3 -- the output of the last LINEAR unit
    """

    # Retrieve the parameters from the dictionary "parameters"
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']

    Z1 = tf.add(tf.matmul(W1, X), b1)  # LINEAR
    A1 = tf.nn.relu(Z1)                # RELU
    Z2 = tf.add(tf.matmul(W2, A1), b2) # LINEAR

    return Z2
```

```
def compute_cost(Z3, Y):
    """
    Computes the cost

    Arguments:
    Z3 -- output of forward propagation (output of the last LINEAR unit), of shape (6, number of examples)
    Y -- "true" labels vector placeholder, same shape as Z3

    Returns:
    cost - Tensor of the cost function
    """

    # to fit the tensorflow requirement for tf.nn.softmax_cross_entropy_with_logits(...,...)
    logits = tf.transpose(Z3)
    labels = tf.transpose(Y)

    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits = logits, labels = labels))

    return cost
```

```
def random_mini_batches(X, Y, mini_batch_size = 64, seed = 0):
    """
    Creates a list of random minibatches from (X, Y)

    Arguments:
    X -- input data, of shape (input size, number of examples)
    Y -- true "label" vector (containing 0 if cat, 1 if non-cat), of shape (1, number of examples)
    mini_batch_size - size of the mini-batches, integer
    seed -- this is only for the purpose of grading, so that you're "random minibatches are the same as ours.

    Returns:
    mini_batches -- list of synchronous (mini_batch_X, mini_batch_Y)
    """

    m = X.shape[1]                  # number of training examples
    mini_batches = []
    np.random.seed(seed)

    # Step 1: Shuffle (X, Y)
    permutation = list(np.random.permutation(m))
    shuffled_X = X[:, permutation]
    shuffled_Y = Y[:, permutation].reshape((Y.shape[0],m))

    # Step 2: Partition (shuffled_X, shuffled_Y). Minus the end case.
    num_complete_minibatches = math.floor(m/mini_batch_size) # number of mini batches of size mini_batch_size in your partitionning
    for k in range(0, num_complete_minibatches):
        mini_batch_X = shuffled_X[:, k * mini_batch_size : k * mini_batch_size + mini_batch_size]
        mini_batch_Y = shuffled_Y[:, k * mini_batch_size : k * mini_batch_size + mini_batch_size]
        mini_batch = (mini_batch_X, mini_batch_Y)
        mini_batches.append(mini_batch)

    # Handling the end case (last mini-batch < mini_batch_size)
    if m % mini_batch_size != 0:
        mini_batch_X = shuffled_X[:, num_complete_minibatches * mini_batch_size : m]
        mini_batch_Y = shuffled_Y[:, num_complete_minibatches * mini_batch_size : m]
        mini_batch = (mini_batch_X, mini_batch_Y)
        mini_batches.append(mini_batch)

    return mini_batches
```

```
def model(X_train, Y_train, X_test, Y_test,dic_of_layer_sizes,learning_rate = 0.0001,
          num_epochs = 1024, minibatch_size = 32, print_cost = True):
    """
    Implements a three-layer tensorflow neural network: LINEAR->RELU->LINEAR->RELU->LINEAR->SOFTMAX.

    Arguments:
    X_train -- training set, of shape (input size = 12288, number of training examples = 1080)
    Y_train -- test set, of shape (output size = 6, number of training examples = 1080)
    X_test -- training set, of shape (input size = 12288, number of training examples = 120)
    Y_test -- test set, of shape (output size = 6, number of test examples = 120)
    dic_of_layer_sizes - dictionary of W<n> b<n> sizes as [x,y]
    learning_rate -- learning rate of the optimization
    num_epochs -- number of epochs of the optimization loop
    minibatch_size -- size of a minibatch
    print_cost -- True to print the cost every 100 epochs

    Returns:
    parameters -- parameters learnt by the model. They can then be used to predict.
    """
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True

    with tf.device('/gpu:0'):

      ops.reset_default_graph()                         # to be able to rerun the model without overwriting tf variables
      tf.set_random_seed(1)                             # to keep consistent results
      seed = 3                                          # to keep consistent results
      (n_x, m) = X_train.shape                          # (n_x: input size, m : number of examples in the train set)
      n_y = Y_train.shape[0]                            # n_y : output size
      costs = []                                        # To keep track of the cost

      # Create Placeholders of shape (n_x, n_y)
      X, Y = create_placeholders(n_x, n_y)

      # Initialize parameters
      parameters = initialize_parameters(dic_of_layer_sizes)

      # Forward propagation: Build the forward propagation in the tensorflow graph
      Z3 = forward_propagation(X=X, parameters=parameters)

      # Cost function: Add cost function to tensorflow graph
      cost = compute_cost(Y=Y,Z3=Z3)

      # Backpropagation: Define the tensorflow optimizer. Use an AdamOptimizer.
      optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(cost)

      # Initialize all the variables
      init = tf.global_variables_initializer()

    # Start the session to compute the tensorflow graph
    with tf.Session(config=config) as sess:

        # Run the initialization
        sess.run(init)

        # Do the training loop
        for epoch in range(num_epochs):

            epoch_cost = 0.                       # Defines a cost related to an epoch
            num_minibatches = int(m / minibatch_size) # number of minibatches of size minibatch_size in the train set
            seed = seed + 1
            minibatches = random_mini_batches(X_train, Y_train, minibatch_size, seed)

            for minibatch in minibatches:

                # Select a minibatch
                (minibatch_X, minibatch_Y) = minibatch

                # IMPORTANT: The line that runs the graph on a minibatch.
                # Run the session to execute the "optimizer" and the "cost", the feedict should contain a minibatch for (X,Y).

                _ , minibatch_cost = sess.run([optimizer, cost], feed_dict={X: minibatch_X, Y: minibatch_Y})

                epoch_cost += minibatch_cost / num_minibatches

            # Print the cost every epoch
            if print_cost == True and epoch % 100 == 0:
                print ("Cost after epoch %i: %f" % (epoch, epoch_cost))
            if print_cost == True and epoch % 5 == 0:
                costs.append(epoch_cost)

        # plot the cost

        plt.plot(np.squeeze(costs))
        plt.ylabel('cost')
        plt.xlabel('iterations (per tens)')
        plt.title("Learning rate =" + str(learning_rate))
        plt.show()

        # lets save the parameters in a variable
        parameters = sess.run(parameters)
        print ("Parameters have been trained!")

        # Calculate the correct predictions
        correct_prediction = tf.equal(tf.argmax(Z3), tf.argmax(Y))

        # Calculate accuracy on the test set
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

        print ("Train Accuracy:", accuracy.eval({X: X_train, Y: Y_train}))
        print ("Test Accuracy:", accuracy.eval({X: X_test, Y: Y_test}))

        return parameters
```

```
def test_inference(X, Y):
  config = tf.ConfigProto()
  config.gpu_options.allow_growth = True

  with tf.device('/gpu:0'):
    Y = one_hot_matrix(Y.reshape(size), 2)
    init = tf.global_variables_initializer()
  with tf.Session(config=config) as session:
    session.run(init)
    z3 = forward_propagation(np.float32(X), parameters)
    p = tf.argmax(z3)
    res = session.run(p)

    # Calculate the correct predictions
    correct_prediction = tf.equal(res, tf.argmax(Y))
    # Calculate accuracy on the test set
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

    return accuracy.eval(), res

```

```
def inference(X):
  config = tf.ConfigProto()
  config.gpu_options.allow_growth = True
  accuracies = []
  with tf.device('/gpu:0'):
    init = tf.global_variables_initializer()
  with tf.Session(config=config) as session:
    session.run(init)
    z3 = forward_propagation(np.float32(X), parameters)
    p = tf.argmax(z3)
    res = session.run(p)
    return res

```

```

def matrix_to_image(data):
  im = Image.new('RGBA', data.shape, 'red')
  for x in range(data.shape[0]):
    for y in range(data.shape[1]):
      if data[x,y] == 1:
        if x % 2 == 0:
          im.putpixel((x, y), ImageColor.getcolor('green', 'RGBA'))
        else:
          im.putpixel((x, y), ImageColor.getcolor('green', 'RGBA'))

  multiplier = 1
  xfactor = 1
  yfactor = 1
  Xsize = multiplier * xfactor* data.shape[0]
  Ysize = multiplier * yfactor* data.shape[1]
  im = im.resize((Xsize, Ysize), resample=0)
  return im

def show_pattern(image_list, titles):
  nrows = len(image_list)

  l = len(image_list)
  fig, ax = plt.subplots(nrows=nrows, ncols=1, figsize=(6, 6 * l), dpi= 96)

  if l == 1:
    ax.set_axisbelow(True)

    # Turn on the minor TICKS, which are required for the minor GRID
    ax.minorticks_on()
    ax.grid(which='minor', linestyle=':', linewidth='0.75', color='white')
    ax.set_ylabel('primes')
    ax.set_xlabel('bits (32)')
    ax.set_title(titles[0])
    #ax.grid(True)
    ax.imshow(image_list[0], aspect='auto')

  else:
    for r, im in enumerate(image_list):
      ax[r].set_axisbelow(True)

      # Turn on the minor TICKS, which are required for the minor GRID
      ax[r].minorticks_on()
      ax[r].grid(which='minor', linestyle=':', linewidth='0.75', color='white')
      #ax[r].grid(True)
      ax[r].set_ylabel('primes')
      ax[r].set_xlabel('bits (32))')
      ax[r].set_title(titles[r])
      ax[r].imshow(im, aspect='auto')

```

## Generate Primes

```

def save_primes(file, start, end):
  p_num = [i for i in primerange(start, end)]
  pickle.dump( p_num, open(file, "wb" ))
  return p_num

def load_primes(file):
 return pickle.load(open(file, "rb" ))

```

```
%%time
start = 2147483647 - 10000000
end = 2147483647
PRIMES_FILENAME = "primes1.p"
if not os.path.exists(PRIMES_FILENAME):
  PRIMES = save_primes(PRIMES_FILENAME, start, end)
else:
  PRIMES = load_primes(PRIMES_FILENAME)
print(len(PRIMES))
```

    465816
    CPU times: user 31.8 s, sys: 161 ms, total: 32 s
    Wall time: 32 s

## Model Training

1.   Sample some primes from PRIMES generated above
2.   Generate similar amount of composite numbers
3.   Sample 100 primes from PRIMES  for dev and make sure they are not in Training set.

```
def train_data(examples_size = 5000):

  primes_set = set(PRIMES)
  c, size = generate_composite(examples_size, primes_set)
  p, size = generate_random_primes(examples_size,PRIMES)
  s_p_train = set(p)
  X_train, Y_train, training_size = generate_x_y(p,c)

  examples_size = 100
  c, size = generate_composite(examples_size, primes_set)
  p, size = generate_random_primes(examples_size,PRIMES)

  # remove the primes common for both test and train
  s_p_test = set(p)
  s_p_test = s_p_test - s_p_train
  X_test, Y_test, test_size = generate_x_y(list(s_p_test),c)

  Y_train = one_hot_matrix(Y_train.reshape(training_size), 2)
  Y_test = one_hot_matrix(Y_test.reshape(test_size), 2)

  print ("number of training examples = " + str(X_train.shape[1]))
  print ("number of test examples = " + str(X_test.shape[1]))
  print ("X_train shape: " + str(X_train.shape))
  print ("Y_train shape: " + str(Y_train.shape))
  print ("X_test shape: " + str(X_test.shape))
  print ("Y_test shape: " + str(Y_test.shape))
  show_pattern([matrix_to_image(X_train), matrix_to_image(X_test)], ['X_train', 'X_test'])

  return X_train, Y_train, training_size, X_test, Y_test, test_size

def main(X_train, Y_train, training_size, X_test, Y_test, test_size ):

  dic_of_layer_sizes ={
      "W1":[64,32],
      "b1":[64,1],
      "W2":[2,64],
      "b2":[2,1]
  }

  parameters = model(
      X_train,
      Y_train,
      X_test,
      Y_test,
      dic_of_layer_sizes,
      num_epochs=1000,
      minibatch_size=64
  )
  return parameters

```

##Random sampled Inputs for both Train and Dev to the model and Visualization

```
X_train, Y_train, training_size, X_test, Y_test, test_size = train_data(5000)
```

## Training Phase

```
parameters = main(X_train, Y_train, training_size, X_test, Y_test, test_size)
```

##  Inference - Random sample test.

Test for random sample of primes  of sizes 10k to 50k from the population PRIMES

Composite Test

```

"""step_size = 1000
start = 1000
end = 10000

primes_set = set(PRIMES)

accuracies = []
for c_size in range(start, end, step_size):
  #print(start, end)
  c, size = generate_composite(c_size, primes_set)
  X, Y, size = generate_x_y(None,c)
  #print(X.shape)
  accuracy, res = test_inference(X,Y)
  #print(accuracy)
  accuracies.append(accuracy)

# plot the cost
plt.plot(np.squeeze(accuracies))
plt.ylabel('accuracies')
plt.xlabel('iterations')
plt.title("Step size =" + str(step_size))
plt.show()"""
```

```
"""%%time
start = 2
end = 100000 #len(PRIMES)
step_size = 10000

accuracies = []
for p_size in range(start, end, step_size):
  p, size = generate_random_primes(p_size, PRIMES)
  X, Y, size = generate_x_y(p,None)
  print(X.shape)
  accuracy, res = test_inference(X,Y)
  print(accuracy)
  accuracies.append(accuracy)

# plot the cost
plt.plot(np.squeeze(accuracies))
plt.ylabel('accuracies')
plt.xlabel('iterations')
plt.title("Step size =" + str(step_size))
plt.show()"""

```

## Inference - Sequence test.

Check all to see if the model can accurately test for prime for all the PRIMES

```
p = np.array(PRIMES)
print(p.shape)
size = p.shape[0]

width = 25000
for i in range(0,size,width):
  x = p[i: i+width]
  X, Y, size = generate_x_y(x,None)
  accuracy, res = test_inference(X, Y)
  failed_index = [x[i] for i in range(0, x.shape[0]) if res[i] == 0]
  print ("Accuracy:", accuracy,"Failed {}/{}".format(len(failed_index),width))

```

    (465816,)
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000
    Accuracy: 1.0 Failed 0/25000

## Inference - Accuracy outside the population

For primes out side the sample space, the accuracy drops.

```
%%time
p, size = generate_sequence_primes((end, end+100000))
X, Y, size = generate_x_y(p,None)
print(X.shape)

accuracy, res = test_inference(X, Y)
print ("Accuracy:", accuracy)

```

    (32, 5511)
    Accuracy: 1.0
    CPU times: user 1.61 s, sys: 59.7 ms, total: 1.67 s
    Wall time: 1.68 s

## Prime Numbers Visualization

```

X_train, Y_train, training_size = generate_x_y(PRIMES[0:4096])
data = X_train[:,:4096]
show_pattern([matrix_to_image(data)],['Primes'])
```


```python
# %load ../../preconfig.py
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(color_codes=True)
plt.rcParams['axes.grid'] = False

#import numpy as np
#import pandas as pd

#import sklearn

#import itertools

import logging
logger = logging.getLogger()

```

24 Single-Source Shortest Paths
=================

In a **shortest-paths problem**,
Given: a weighted, directed graph $G = (V, E)$, with weight function $w : E \to \mathcal{R}$.
path $p = < v_0, v_1, \dotsc, v_k >$, so
$$w(p) = \displaystyle \sum_{i=1}^k w(v_{i-1}, v_i)$$.

we define the **shortest-path weight** $\delta(u, v)$ from $u$ to $v$ by
\begin{equation}
    \delta(u, v) = \begin{cases}
        \min{ w(p) : u \overset{p}{\to} v } & \text{if $p$ exist}\\
        \infty & \text{otherwise}
    \end{cases}
\end{equation}

**variants**:
+ Single-destination shortest-paths problem
+ Single-pair shortest-path problem
+ All-pairs shortest-path problem

**Optimal substructure of a shortest path**:
subpath of $p$ is a shortest path between two of its internal nodes if $p$ is a shortest path.

**Negative-weight edges**: whether a negative weight cycle exists?

**Cycles**:
+ negative-weight cycle: detect and remove
+ positive-weight cycle: auto remove
+ 0-weight cycle: detect and remove

**Representing shortest paths**:
a "shortest-paths tree": a rooted tree containing a shortest path from the source $s$ to every vertex that is reachable from $s$.

**Relaxation**:
modify the node's upper bound if detect a shorter path.

```
INITIALIZE-SINGLE-SOURCE(G, s)
    for each vertex v in G.V
        v.d = infty
        v.pi = NIL
    s.d = 0

RELAX(u, v, w)
    if v.d > u.d + w(u, v)
        v.d = u.d + w(u, v)
        v.pi = u
```

**Properties of shortest paths and relaxtion**
+ Triangle inequality
+ Upper-bound property
+ No-path property
+ Convergence property
+ Path-relaxation property
+ Predecessor-subgraph property

### 24.1 The Bellman-Ford algorithm
it returns a boolean valued indicating whether or not there is a negative-weight cycle that is reachable from the source.

The algorithm relaxes edges, progressively decreasing an estimate $v.d$ on the weight of a shortest path from the source $s$ to each vertex $v \in V$ until it achieves the actual shortest-path weight $\delta(s, v)$.

The Bellman-Fold algorithm runs in time $O(VE)$.

```python
plt.imshow(plt.imread('./res/bellman_ford.png'))
```

```python
plt.imshow(plt.imread('./res/fig24_4.png'))
```

### 24.2 Single-source shortest paths in directed acyclic graphs

By relaxing the edges of a weighted dag (directed acyclic graph) $G = (V, E)$ according to a *topological sort* of its vertices, we can compute shortest paths from a single source in $O(V + E)$ time.

```python
plt.imshow(plt.imread('./res/dag.png'))
```

```python
plt.imshow(plt.imread('./res/fig24_5.png'))
```

interesting application: to determine critical paths in **PERT chart** analysis.

### 24.3 Dijkstra's algorithm (greedy strategy)
weighted, directed graph $G = (V, E)$ and all $w(u, v) \geq 0$.

Dijkstra's algorithm maintains a set $S$ of vertices whose final shortest-path weights from the source $s$ have already been determined.

we use a min-priority queue $Q$ of vertices, keyed by their $d$ values.

```python
plt.imshow(plt.imread('./res/dijkstra.png'))
```

```python
plt.imshow(plt.imread('./res/fig24_6.png'))
```

### 24.4 Difference constraints and shortest paths
#### Linear programming

#### Systems of difference constraints
In a system of difference constraints, each row of the linear-programming matrix $A$ contains one 1 and one -1, and all other entries of $A$ are 0. $\to$ the form $x_j - x_i \leq b_k$.

```python
plt.imshow(plt.imread('./res/inequ.png'))
```

#### Constraint graphs

```python
plt.imshow(plt.imread('./res/fig24_8.png'))
```

### 24.5 Proofs of shortest-paths properties

```python

```


```python
import numpy as np
import pandas as pd
import pandas_datareader
from types import SimpleNamespace
%load_ext autoreload
%autoreload 2

%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')

# Import additional libraries:
```

# 1. Regional CO$_2$ emissions

In this exercise, we will investigate the development in CO2 emissions relative to GDP across the world. For this purpose, we apply data obtained from the World Bank Indicators.

You will need to use the following data sets for the period 1990-2016:
1. **EN.ATM.CO2E.KT** : CO2 emissions in kilotons. [WB link](https://data.worldbank.org/indicator/EN.ATM.CO2E.KT)
2. **NY.GDP.MKTP.PP.KD** : GDP, PPP-corrected in constant 2017 international dollars [WB link](https://data.worldbank.org/indicator/NY.GDP.MKTP.PP.KD)
3. **SP.POP.TOTL** : total population [WB link](https://data.worldbank.org/indicator/SP.POP.TOTL)
4. **country_region.xlsx** : key between country names and world regions

Data sets 1-3 contain annual records for all the world's countries plus a large set of country aggregates. You can download each `data_set` using the following API call

```python
from pandas_datareader import wb
df = wb.download(indicator=data_set, country=[], start=1990, end=2016)
```

**Notes:**
The data set **country_region.xlsx** is available together with this notebook.
Setting `countrty=[]` implies getting all countries in a data set by the syntax of the World Bank API.
Follow the links above if there is a problem with the API call and download manually.

**Question 1:** Data cleaning.
* Download data sets 1-3. Exclude all entries in the data sets that are not a country listed in country_region.xlsx.
* Assign a world region to each country in data sets 1-3 using country_region.xlsx.
* If a data-point in one data set is `NaN` for country $x$ in year $y$, then delete it together with the corresponding data-points for country $x$ in year $y$ in the 2 other data sets.

Check that the resulting number of rows for a dataset containing GDP, population and CO2 is 4660.

**Question 2:** Regional CO2 emissions. Calculate the regional CO2 emissions per dollar GDP on an annual basis. That is, for region $R$ in year $t$ compute
$$
\frac{\sum_{j \in R} \text{CO2}_{j,t}}{\sum_{j \in R} Y_{j,t}}
$$
where $Y_{j}$ denotes the GDP of country $j$.

Plot CO2 emissions per dollar GDP for all regions in the way you find most presentable and comment.

**Question 3:** Growth rates.
* For each region $R$, calculate population weighted average $\text{CO2}_{R,t}$  and GDP pr year. See weighted average definition below.
* Calculate the annual **growth rates** of averaged GDP and CO2 for each region.
* Finally, create **one subplot** per region containing the two associated growth rates. Make a brief comment. (*tip: better use a loop for this instead of code repetition*)

The weighted averages of of GDP and CO2 for region $R$ is obtained by first calculating the weights:
$$
w_{i,t} = \frac{POP_{i,t}}{\sum \limits_{k \in R}POP_{k,t}}
$$
for each country $i \in R$.
Then get average regional GDP by
$$
\bar{Y}_{R,t} =  \sum \limits_{i \in R}w_{i,t}Y_{i,t}
$$
and similarly for CO2.

The growth rate for regional GDP per capita is then
$$
\bar{Y}^{\Delta}_{R,t} = \frac{\bar{Y}_{R,t}}{\bar{Y}_{R,t-1}} - 1
$$
and similarly for regional CO2 pr capita

# 2. Risky assets

The consumption savings model with uncertainty in both income and interest rate.

A **household** lives two periods.

In the **second period** it gets utility from **consuming** and **leaving a bequest**,

$$
\begin{aligned}
v_{2}(m_{2})&= \max_{c_{2}}\frac{c_{2}^{1-\rho}}{1-\rho}+\nu\frac{(a_2+\kappa)^{1-\rho}}{1-\rho}\\
\text{s.t.} \\
a_2 &= m_2-c_2 \\
a_2 &\geq 0
\end{aligned}
$$

* $m_2$ is cash-on-hand
* $c_2$ is consumption
* $a_2$ is end-of-period assets
* $\rho > 1$ is the risk aversion coefficient
* $\nu > 0 $ is the strength of the bequest motive
* $\kappa > 0$ is the degree of luxuriousness in the bequest motive
* $a_2\geq0$ ensures the household *cannot* die in debt

The **value function** $v_t(m_t)$ measures the household's value of having $m_t$ at the beginning of period $t$.

In the **first period**, the household gets utility from consuming and takes into account that it will also live in the next-period, where it receives a stochastic income.

We assume that the consumption decision is made at the **beginning** of the period.

We denote the interest rate on savings from period 1 to 2 by $r_{1,2}$. It is assumed to be **unknown** until the end of the period 1; ie. *after* the consumption decision is made.

$$
\begin{aligned}
	v_1(m_1) &= \max_{c_1}\frac{c_{1}^{1-\rho}}{1-\rho}+\beta\mathbb{E}_{1}\left[v_2(m_2)\right]\\&\text{s.t.}&\\
	a_1 & = m_1-c_1\\
	m_2 &= (1+r_{1,2})a_1+y_2 \\
	r_{1,2} &= \begin{cases}
	r_0 - \Delta^r & \text{with prob. }\frac{1}{2}\\
	r_0 + \Delta^r & \text{with prob. }\frac{1}{2} \\
	\end{cases}\\
	y_{2} &= \begin{cases}
	1-\Delta^y & \text{with prob. }\frac{1}{2}\\
	1+\Delta^y & \text{with prob. }\frac{1}{2}
	\end{cases}\\
	a_1 & \geq0
\end{aligned}
$$

* $m_1$ is cash-on-hand in period 1
* $c_1$ is consumption in period 1
* $a_1$ is end-of-period assets in period 1
* $\beta > 0$ is the discount factor
* $\mathbb{E}_1$ is the expectation operator conditional on information in the *beginning* of period 1
* $y_2$ is income in period 2
* $\Delta^y \in (0,1)$ is the level of income risk
* $r_0$ is the expected interest rate
* $\Delta^r \in (0,r_0)$ is the level of interest rate risk
* $a_1\geq0$ ensures the household *cannot* borrow

```python
# Parameters
rho = 8
kappa = 0.5
nu = 0.2
r0 = 0.3
Delta_r = 0.29
Delta_y = 0.5
beta = 0.98
```

Note: $r_0$ and $\Delta^r$ are somewhat extreme - that is just for exposition.

**Question 1:** Solve the model for both periods and obtain value functions $v_1(m_1), v_2(m_2)$ together with the optimal consumption functions $c^*_1(m_1), c^*_2(m_2)$.
Plot $v_1(m_1), v_2(m_2)$ in one graph and  $c^*_1(m_1), c^*_2(m_2)$ in another.

**Question 2:** Now set $\Delta^r = 0$ and solve the model once again. Plot the associated $c^*_1(m_1), c^*_2(m_2)$ and compare them with the consumption functions from the solution in Question 1.

**Question 3** Question 3 below has **2 options**. You can **freely choose** which one you want to answer. (*You can of course answer both if you like*).

**Question 3 - option 1:** Simulate the period 2 choices of $N$ households both for the case where $\Delta^r=0.29$ and where $\Delta^r=0$.
You can use the same distribution of $m_1$ for both cases as specified below.
Plot the two distributions of $c_1$ and comment.
Optionally, you can also inspect the two distributions of $c_2$ and check that you understand their shapes.

```python
np.random.seed(2021)
simN = 50000
sim_m1 = np.fmax(np.random.normal(1, 0.05, size = simN), 0)
```

**Question 3 - option 2:** Generalizing the set of possible interest rate outcomes.
We now consider the case where the interest rate has $N = 2n$ different possible realizations.
Specifically, $r$ has $n$ possible outcomes higher than $r_0$, and $n$ outcomes lower than $r_0$, which are **uniformly** distributed:
$$
\begin{aligned}
	r &= \begin{cases}
	r_0 - n\Delta^r & \text{with prob. }\frac{1}{N}\\
	r_0 - (n-1)\Delta^r & \text{with prob. }\frac{1}{N}\\
	r_0 - (n-2)\Delta^r & \text{with prob. }\frac{1}{N}\\
    \vdots & \\
	r_0 - \Delta^r & \text{with prob. }\frac{1}{N}\\
	r_0 + \Delta^r & \text{with prob. }\frac{1}{N}\\
    \vdots & \\
	r_0 + (n-1)\Delta^r & \text{with prob. }\frac{1}{N} \\
	r_0 + n\Delta^r & \text{with prob. }\frac{1}{N} \\
	\end{cases}\\
\end{aligned}
$$

Implement this generalized specification in code.
Test the model on the parameterization below and plot $c^*_1(m_1), c^*_2(m_2)$.

```python
# New parameters:
r0 = 0.3
Delta_r = 0.05
n = 5
N = 2*5
# Remaining parameters are the same as in Question 1
```

# 3. Interpolation by polynomial

We can use interpolation when dealing with some function $f$ that is very heavy to  calculate. That is, we have a large set of points $X = \{x_i\}_{i=1}^{N}$ on which we want to know the function value $f(x_i)$, but we might not have sufficiently computing power for it.

Therefore, we take out a subset $Z \subset X$ and calulate $f$ on the elements of $Z$. Whenever we want to know $f(x)$ for some $x\in X$ that is not also in our pre-computation set $Z$, we use interpolation between neighboring points to $x$ in $Z$ for which the function value has been calculated. To get an **estimate** of $f(x)$, we then interpolate between these pre-calculated neighboring points.

In lecture 11, we saw how to write up a *linear interpolation* between a set of pre-calculated function values.

In the current exercise, we will use **a polynomial** to interpolate between pre-calculated data points.

(*Note: the type of interpolation we consider below is only practical in a modified version. It is useful as an introduction, however.*)

**Polynomial interpolation**
Assume we have a set of data points $D = \{(y_i,x_i)\}_{i=1}^{n}$.

We now want to create a polynomial $p$ of degree $n-1$ such that $y_i = p(x_i)$ *exactly* for all $x_i,y_i \in D$.

We can obtain such a polynomial $p$ by the following steps:
$$
\begin{align}
	p(x) & = \sum \limits_{i = 1}^{n} y_i \times l_i(x) \\
	l_i(x) & = \prod \limits_{j \ne i} \frac{x - x_j}{x_i - x_j}
\end{align}
$$

**Example**
Say we have the function $f(x) = x^2 - 1$. We can then construct our set of data points $D$.
To do so, we evaluate $f$ in the points $\{1, 3, 5\}$:
* $f(1) = 0$
* $f(3) = 8$
* $f(5) = 24$

Thus we have $D = \{(0,1), (8,3), (24,5)\}$

Interpolating our function $f(x) = x^2 - 1$ at some $\hat{x} \in [1,5]$ is then given by

$$
p(\hat{x})  =  0 \times l_1(\hat{x}) + 3 \times l_2(\hat{x}) + 5 \times l_3 (\hat{x})
$$

$$
\begin{align}
	l_1(\hat{x}) = \frac{(\hat{x} - 3)}{(1 - 3)} \frac{(\hat{x} - 5)}{(1 - 5)}, \:\:
    l_2(\hat{x}) = \frac{(\hat{x} - 1)}{(3 - 1)} \frac{(\hat{x} - 5)}{(3 - 5)}, \:\:
    l_3(\hat{x}) = \frac{(\hat{x} - 1)}{(5 - 1)} \frac{(\hat{x} - 3)}{(5 - 3)}
\end{align}
$$

**Algorithm**
First evaluate the function $f$ on the set of points $X$ so as to obtain the associated function values $Y$. Then follow the pseudo-code below.

**Question 1:** Implement the algorithm to interpolate function values of $f$ to the point $\hat{x}$

```python
def polynomial_interpol(x, X, Y):
    pass
```

  You can test your `polynomial_interpol` on the function $f(x) = x^3$

```python
f = lambda x: x**3

X1 = np.array([1, 2, 2.5, 4])
X2 = np.array([0.5, 2.2, 7, 12.9])

Y1 = f(X1)
Y2 = f(X2)

x = 3.2

# Note: the result should be the same in both cases below
y1_interpol = polynomial_interpol(x, X1, Y1)
print(f'f(x) = {f(x): .7f}  interpolated y = {y1_interpol: .7f}')

y2_interpol = polynomial_interpol(x, X2, Y2)
print(f'f(x) = {f(x): .7f}  interpolated y = {y2_interpol: .7f}')

```