```python
import sympy
import pandas as pd
import numpy as np
```

```python
N = 5
```

```python
X = pd.read_pickle('/content/drive/MyDrive/Colab Notebooks/ML/Projekt/input.pkl')
X.head()
```

      a0
      a1
      a2
      a3
      a4
      a5

      0
      0.548811
      0.576259
      0.951003
      0.989772
      0.250040
      0.725936

      1
      0.868692
      0.290476
      0.110094
      0.506379
      0.609363
      0.213803

      2
      0.768961
      0.929749
      0.749917
      0.476438
      0.213138
      0.375942

      3
      0.939739
      0.921397
      0.337292
      0.036035
      0.525527
      0.108338

      4
      0.880906
      0.443218
      0.921336
      0.978349
      0.294031
      0.250849

```python
x = sympy.symbols('x')
```

```python
data_test = X.to_numpy()

roots = []

for r, row in enumerate(data_test):
  print(r)
  poly = 0
  for i, coeff in enumerate(row):
      poly = poly + coeff * x ** i
  roots.append(sympy.solveset(poly, x))
```

    Strumieniowane dane wyjściowe obcięte do 5000 ostatnich wierszy.
    95000
    95001
    95002
    95003
    95004
    95005
    95006
    95007
    95008
    95009
    95010
    95011
    95012
    95013
    95014
    95015
    95016
    95017
    95018
    95019
    95020
    95021
    95022
    95023
    95024
    95025
    95026
    95027
    95028
    95029
    95030
    95031
    95032
    95033
    95034
    95035
    95036
    95037
    95038
    95039
    95040
    95041
    95042
    95043
    95044
    95045
    95046
    95047
    95048
    95049
    95050
    95051
    95052
    95053
    95054
    95055
    95056
    95057
    95058
    95059
    95060
    95061
    95062
    95063
    95064
    95065
    95066
    95067
    95068
    95069
    95070
    95071
    95072
    95073
    95074
    95075
    95076
    95077
    95078
    95079
    95080
    95081
    95082
    95083
    95084
    95085
    95086
    95087
    95088
    95089
    95090
    95091
    95092
    95093
    95094
    95095
    95096
    95097
    95098
    95099
    95100
    95101
    95102
    95103
    95104
    95105
    95106
    95107
    95108
    95109
    95110
    95111
    95112
    95113
    95114
    95115
    95116
    95117
    95118
    95119
    95120
    95121
    95122
    95123
    95124
    95125
    95126
    95127
    95128
    95129
    95130
    95131
    95132
    95133
    95134
    95135
    95136
    95137
    95138
    95139
    95140
    95141
    95142
    95143
    95144
    95145
    95146
    95147
    95148
    95149
    95150
    95151
    95152
    95153
    95154
    95155
    95156
    95157
    95158
    95159
    95160
    95161
    95162
    95163
    95164
    95165
    95166
    95167
    95168
    95169
    95170
    95171
    95172
    95173
    95174
    95175
    95176
    95177
    95178
    95179
    95180
    95181
    95182
    95183
    95184
    95185
    95186
    95187
    95188
    95189
    95190
    95191
    95192
    95193
    95194
    95195
    95196
    95197
    95198
    95199
    95200
    95201
    95202
    95203
    95204
    95205
    95206
    95207
    95208
    95209
    95210
    95211
    95212
    95213
    95214
    95215
    95216
    95217
    95218
    95219
    95220
    95221
    95222
    95223
    95224
    95225
    95226
    95227
    95228
    95229
    95230
    95231
    95232
    95233
    95234
    95235
    95236
    95237
    95238
    95239
    95240
    95241
    95242
    95243
    95244
    95245
    95246
    95247
    95248
    95249
    95250
    95251
    95252
    95253
    95254
    95255
    95256
    95257
    95258
    95259
    95260
    95261
    95262
    95263
    95264
    95265
    95266
    95267
    95268
    95269
    95270
    95271
    95272
    95273
    95274
    95275
    95276
    95277
    95278
    95279
    95280
    95281
    95282
    95283
    95284
    95285
    95286
    95287
    95288
    95289
    95290
    95291
    95292
    95293
    95294
    95295
    95296
    95297
    95298
    95299
    95300
    95301
    95302
    95303
    95304
    95305
    95306
    95307
    95308
    95309
    95310
    95311
    95312
    95313
    95314
    95315
    95316
    95317
    95318
    95319
    95320
    95321
    95322
    95323
    95324
    95325
    95326
    95327
    95328
    95329
    95330
    95331
    95332
    95333
    95334
    95335
    95336
    95337
    95338
    95339
    95340
    95341
    95342
    95343
    95344
    95345
    95346
    95347
    95348
    95349
    95350
    95351
    95352
    95353
    95354
    95355
    95356
    95357
    95358
    95359
    95360
    95361
    95362
    95363
    95364
    95365
    95366
    95367
    95368
    95369
    95370
    95371
    95372
    95373
    95374
    95375
    95376
    95377
    95378
    95379
    95380
    95381
    95382
    95383
    95384
    95385
    95386
    95387
    95388
    95389
    95390
    95391
    95392
    95393
    95394
    95395
    95396
    95397
    95398
    95399
    95400
    95401
    95402
    95403
    95404
    95405
    95406
    95407
    95408
    95409
    95410
    95411
    95412
    95413
    95414
    95415
    95416
    95417
    95418
    95419
    95420
    95421
    95422
    95423
    95424
    95425
    95426
    95427
    95428
    95429
    95430
    95431
    95432
    95433
    95434
    95435
    95436
    95437
    95438
    95439
    95440
    95441
    95442
    95443
    95444
    95445
    95446
    95447
    95448
    95449
    95450
    95451
    95452
    95453
    95454
    95455
    95456
    95457
    95458
    95459
    95460
    95461
    95462
    95463
    95464
    95465
    95466
    95467
    95468
    95469
    95470
    95471
    95472
    95473
    95474
    95475
    95476
    95477
    95478
    95479
    95480
    95481
    95482
    95483
    95484
    95485
    95486
    95487
    95488
    95489
    95490
    95491
    95492
    95493
    95494
    95495
    95496
    95497
    95498
    95499
    95500
    95501
    95502
    95503
    95504
    95505
    95506
    95507
    95508
    95509
    95510
    95511
    95512
    95513
    95514
    95515
    95516
    95517
    95518
    95519
    95520
    95521
    95522
    95523
    95524
    95525
    95526
    95527
    95528
    95529
    95530
    95531
    95532
    95533
    95534
    95535
    95536
    95537
    95538
    95539
    95540
    95541
    95542
    95543
    95544
    95545
    95546
    95547
    95548
    95549
    95550
    95551
    95552
    95553
    95554
    95555
    95556
    95557
    95558
    95559
    95560
    95561
    95562
    95563
    95564
    95565
    95566
    95567
    95568
    95569
    95570
    95571
    95572
    95573
    95574
    95575
    95576
    95577
    95578
    95579
    95580
    95581
    95582
    95583
    95584
    95585
    95586
    95587
    95588
    95589
    95590
    95591
    95592
    95593
    95594
    95595
    95596
    95597
    95598
    95599
    95600
    95601
    95602
    95603
    95604
    95605
    95606
    95607
    95608
    95609
    95610
    95611
    95612
    95613
    95614
    95615
    95616
    95617
    95618
    95619
    95620
    95621
    95622
    95623
    95624
    95625
    95626
    95627
    95628
    95629
    95630
    95631
    95632
    95633
    95634
    95635
    95636
    95637
    95638
    95639
    95640
    95641
    95642
    95643
    95644
    95645
    95646
    95647
    95648
    95649
    95650
    95651
    95652
    95653
    95654
    95655
    95656
    95657
    95658
    95659
    95660
    95661
    95662
    95663
    95664
    95665
    95666
    95667
    95668
    95669
    95670
    95671
    95672
    95673
    95674
    95675
    95676
    95677
    95678
    95679
    95680
    95681
    95682
    95683
    95684
    95685
    95686
    95687
    95688
    95689
    95690
    95691
    95692
    95693
    95694
    95695
    95696
    95697
    95698
    95699
    95700
    95701
    95702
    95703
    95704
    95705
    95706
    95707
    95708
    95709
    95710
    95711
    95712
    95713
    95714
    95715
    95716
    95717
    95718
    95719
    95720
    95721
    95722
    95723
    95724
    95725
    95726
    95727
    95728
    95729
    95730
    95731
    95732
    95733
    95734
    95735
    95736
    95737
    95738
    95739
    95740
    95741
    95742
    95743
    95744
    95745
    95746
    95747
    95748
    95749
    95750
    95751
    95752
    95753
    95754
    95755
    95756
    95757
    95758
    95759
    95760
    95761
    95762
    95763
    95764
    95765
    95766
    95767
    95768
    95769
    95770
    95771
    95772
    95773
    95774
    95775
    95776
    95777
    95778
    95779
    95780
    95781
    95782
    95783
    95784
    95785
    95786
    95787
    95788
    95789
    95790
    95791
    95792
    95793
    95794
    95795
    95796
    95797
    95798
    95799
    95800
    95801
    95802
    95803
    95804
    95805
    95806
    95807
    95808
    95809
    95810
    95811
    95812
    95813
    95814
    95815
    95816
    95817
    95818
    95819
    95820
    95821
    95822
    95823
    95824
    95825
    95826
    95827
    95828
    95829
    95830
    95831
    95832
    95833
    95834
    95835
    95836
    95837
    95838
    95839
    95840
    95841
    95842
    95843
    95844
    95845
    95846
    95847
    95848
    95849
    95850
    95851
    95852
    95853
    95854
    95855
    95856
    95857
    95858
    95859
    95860
    95861
    95862
    95863
    95864
    95865
    95866
    95867
    95868
    95869
    95870
    95871
    95872
    95873
    95874
    95875
    95876
    95877
    95878
    95879
    95880
    95881
    95882
    95883
    95884
    95885
    95886
    95887
    95888
    95889
    95890
    95891
    95892
    95893
    95894
    95895
    95896
    95897
    95898
    95899
    95900
    95901
    95902
    95903
    95904
    95905
    95906
    95907
    95908
    95909
    95910
    95911
    95912
    95913
    95914
    95915
    95916
    95917
    95918
    95919
    95920
    95921
    95922
    95923
    95924
    95925
    95926
    95927
    95928
    95929
    95930
    95931
    95932
    95933
    95934
    95935
    95936
    95937
    95938
    95939
    95940
    95941
    95942
    95943
    95944
    95945
    95946
    95947
    95948
    95949
    95950
    95951
    95952
    95953
    95954
    95955
    95956
    95957
    95958
    95959
    95960
    95961
    95962
    95963
    95964
    95965
    95966
    95967
    95968
    95969
    95970
    95971
    95972
    95973
    95974
    95975
    95976
    95977
    95978
    95979
    95980
    95981
    95982
    95983
    95984
    95985
    95986
    95987
    95988
    95989
    95990
    95991
    95992
    95993
    95994
    95995
    95996
    95997
    95998
    95999
    96000
    96001
    96002
    96003
    96004
    96005
    96006
    96007
    96008
    96009
    96010
    96011
    96012
    96013
    96014
    96015
    96016
    96017
    96018
    96019
    96020
    96021
    96022
    96023
    96024
    96025
    96026
    96027
    96028
    96029
    96030
    96031
    96032
    96033
    96034
    96035
    96036
    96037
    96038
    96039
    96040
    96041
    96042
    96043
    96044
    96045
    96046
    96047
    96048
    96049
    96050
    96051
    96052
    96053
    96054
    96055
    96056
    96057
    96058
    96059
    96060
    96061
    96062
    96063
    96064
    96065
    96066
    96067
    96068
    96069
    96070
    96071
    96072
    96073
    96074
    96075
    96076
    96077
    96078
    96079
    96080
    96081
    96082
    96083
    96084
    96085
    96086
    96087
    96088
    96089
    96090
    96091
    96092
    96093
    96094
    96095
    96096
    96097
    96098
    96099
    96100
    96101
    96102
    96103
    96104
    96105
    96106
    96107
    96108
    96109
    96110
    96111
    96112
    96113
    96114
    96115
    96116
    96117
    96118
    96119
    96120
    96121
    96122
    96123
    96124
    96125
    96126
    96127
    96128
    96129
    96130
    96131
    96132
    96133
    96134
    96135
    96136
    96137
    96138
    96139
    96140
    96141
    96142
    96143
    96144
    96145
    96146
    96147
    96148
    96149
    96150
    96151
    96152
    96153
    96154
    96155
    96156
    96157
    96158
    96159
    96160
    96161
    96162
    96163
    96164
    96165
    96166
    96167
    96168
    96169
    96170
    96171
    96172
    96173
    96174
    96175
    96176
    96177
    96178
    96179
    96180
    96181
    96182
    96183
    96184
    96185
    96186
    96187
    96188
    96189
    96190
    96191
    96192
    96193
    96194
    96195
    96196
    96197
    96198
    96199
    96200
    96201
    96202
    96203
    96204
    96205
    96206
    96207
    96208
    96209
    96210
    96211
    96212
    96213
    96214
    96215
    96216
    96217
    96218
    96219
    96220
    96221
    96222
    96223
    96224
    96225
    96226
    96227
    96228
    96229
    96230
    96231
    96232
    96233
    96234
    96235
    96236
    96237
    96238
    96239
    96240
    96241
    96242
    96243
    96244
    96245
    96246
    96247
    96248
    96249
    96250
    96251
    96252
    96253
    96254
    96255
    96256
    96257
    96258
    96259
    96260
    96261
    96262
    96263
    96264
    96265
    96266
    96267
    96268
    96269
    96270
    96271
    96272
    96273
    96274
    96275
    96276
    96277
    96278
    96279
    96280
    96281
    96282
    96283
    96284
    96285
    96286
    96287
    96288
    96289
    96290
    96291
    96292
    96293
    96294
    96295
    96296
    96297
    96298
    96299
    96300
    96301
    96302
    96303
    96304
    96305
    96306
    96307
    96308
    96309
    96310
    96311
    96312
    96313
    96314
    96315
    96316
    96317
    96318
    96319
    96320
    96321
    96322
    96323
    96324
    96325
    96326
    96327
    96328
    96329
    96330
    96331
    96332
    96333
    96334
    96335
    96336
    96337
    96338
    96339
    96340
    96341
    96342
    96343
    96344
    96345
    96346
    96347
    96348
    96349
    96350
    96351
    96352
    96353
    96354
    96355
    96356
    96357
    96358
    96359
    96360
    96361
    96362
    96363
    96364
    96365
    96366
    96367
    96368
    96369
    96370
    96371
    96372
    96373
    96374
    96375
    96376
    96377
    96378
    96379
    96380
    96381
    96382
    96383
    96384
    96385
    96386
    96387
    96388
    96389
    96390
    96391
    96392
    96393
    96394
    96395
    96396
    96397
    96398
    96399
    96400
    96401
    96402
    96403
    96404
    96405
    96406
    96407
    96408
    96409
    96410
    96411
    96412
    96413
    96414
    96415
    96416
    96417
    96418
    96419
    96420
    96421
    96422
    96423
    96424
    96425
    96426
    96427
    96428
    96429
    96430
    96431
    96432
    96433
    96434
    96435
    96436
    96437
    96438
    96439
    96440
    96441
    96442
    96443
    96444
    96445
    96446
    96447
    96448
    96449
    96450
    96451
    96452
    96453
    96454
    96455
    96456
    96457
    96458
    96459
    96460
    96461
    96462
    96463
    96464
    96465
    96466
    96467
    96468
    96469
    96470
    96471
    96472
    96473
    96474
    96475
    96476
    96477
    96478
    96479
    96480
    96481
    96482
    96483
    96484
    96485
    96486
    96487
    96488
    96489
    96490
    96491
    96492
    96493
    96494
    96495
    96496
    96497
    96498
    96499
    96500
    96501
    96502
    96503
    96504
    96505
    96506
    96507
    96508
    96509
    96510
    96511
    96512
    96513
    96514
    96515
    96516
    96517
    96518
    96519
    96520
    96521
    96522
    96523
    96524
    96525
    96526
    96527
    96528
    96529
    96530
    96531
    96532
    96533
    96534
    96535
    96536
    96537
    96538
    96539
    96540
    96541
    96542
    96543
    96544
    96545
    96546
    96547
    96548
    96549
    96550
    96551
    96552
    96553
    96554
    96555
    96556
    96557
    96558
    96559
    96560
    96561
    96562
    96563
    96564
    96565
    96566
    96567
    96568
    96569
    96570
    96571
    96572
    96573
    96574
    96575
    96576
    96577
    96578
    96579
    96580
    96581
    96582
    96583
    96584
    96585
    96586
    96587
    96588
    96589
    96590
    96591
    96592
    96593
    96594
    96595
    96596
    96597
    96598
    96599
    96600
    96601
    96602
    96603
    96604
    96605
    96606
    96607
    96608
    96609
    96610
    96611
    96612
    96613
    96614
    96615
    96616
    96617
    96618
    96619
    96620
    96621
    96622
    96623
    96624
    96625
    96626
    96627
    96628
    96629
    96630
    96631
    96632
    96633
    96634
    96635
    96636
    96637
    96638
    96639
    96640
    96641
    96642
    96643
    96644
    96645
    96646
    96647
    96648
    96649
    96650
    96651
    96652
    96653
    96654
    96655
    96656
    96657
    96658
    96659
    96660
    96661
    96662
    96663
    96664
    96665
    96666
    96667
    96668
    96669
    96670
    96671
    96672
    96673
    96674
    96675
    96676
    96677
    96678
    96679
    96680
    96681
    96682
    96683
    96684
    96685
    96686
    96687
    96688
    96689
    96690
    96691
    96692
    96693
    96694
    96695
    96696
    96697
    96698
    96699
    96700
    96701
    96702
    96703
    96704
    96705
    96706
    96707
    96708
    96709
    96710
    96711
    96712
    96713
    96714
    96715
    96716
    96717
    96718
    96719
    96720
    96721
    96722
    96723
    96724
    96725
    96726
    96727
    96728
    96729
    96730
    96731
    96732
    96733
    96734
    96735
    96736
    96737
    96738
    96739
    96740
    96741
    96742
    96743
    96744
    96745
    96746
    96747
    96748
    96749
    96750
    96751
    96752
    96753
    96754
    96755
    96756
    96757
    96758
    96759
    96760
    96761
    96762
    96763
    96764
    96765
    96766
    96767
    96768
    96769
    96770
    96771
    96772
    96773
    96774
    96775
    96776
    96777
    96778
    96779
    96780
    96781
    96782
    96783
    96784
    96785
    96786
    96787
    96788
    96789
    96790
    96791
    96792
    96793
    96794
    96795
    96796
    96797
    96798
    96799
    96800
    96801
    96802
    96803
    96804
    96805
    96806
    96807
    96808
    96809
    96810
    96811
    96812
    96813
    96814
    96815
    96816
    96817
    96818
    96819
    96820
    96821
    96822
    96823
    96824
    96825
    96826
    96827
    96828
    96829
    96830
    96831
    96832
    96833
    96834
    96835
    96836
    96837
    96838
    96839
    96840
    96841
    96842
    96843
    96844
    96845
    96846
    96847
    96848
    96849
    96850
    96851
    96852
    96853
    96854
    96855
    96856
    96857
    96858
    96859
    96860
    96861
    96862
    96863
    96864
    96865
    96866
    96867
    96868
    96869
    96870
    96871
    96872
    96873
    96874
    96875
    96876
    96877
    96878
    96879
    96880
    96881
    96882
    96883
    96884
    96885
    96886
    96887
    96888
    96889
    96890
    96891
    96892
    96893
    96894
    96895
    96896
    96897
    96898
    96899
    96900
    96901
    96902
    96903
    96904
    96905
    96906
    96907
    96908
    96909
    96910
    96911
    96912
    96913
    96914
    96915
    96916
    96917
    96918
    96919
    96920
    96921
    96922
    96923
    96924
    96925
    96926
    96927
    96928
    96929
    96930
    96931
    96932
    96933
    96934
    96935
    96936
    96937
    96938
    96939
    96940
    96941
    96942
    96943
    96944
    96945
    96946
    96947
    96948
    96949
    96950
    96951
    96952
    96953
    96954
    96955
    96956
    96957
    96958
    96959
    96960
    96961
    96962
    96963
    96964
    96965
    96966
    96967
    96968
    96969
    96970
    96971
    96972
    96973
    96974
    96975
    96976
    96977
    96978
    96979
    96980
    96981
    96982
    96983
    96984
    96985
    96986
    96987
    96988
    96989
    96990
    96991
    96992
    96993
    96994
    96995
    96996
    96997
    96998
    96999
    97000
    97001
    97002
    97003
    97004
    97005
    97006
    97007
    97008
    97009
    97010
    97011
    97012
    97013
    97014
    97015
    97016
    97017
    97018
    97019
    97020
    97021
    97022
    97023
    97024
    97025
    97026
    97027
    97028
    97029
    97030
    97031
    97032
    97033
    97034
    97035
    97036
    97037
    97038
    97039
    97040
    97041
    97042
    97043
    97044
    97045
    97046
    97047
    97048
    97049
    97050
    97051
    97052
    97053
    97054
    97055
    97056
    97057
    97058
    97059
    97060
    97061
    97062
    97063
    97064
    97065
    97066
    97067
    97068
    97069
    97070
    97071
    97072
    97073
    97074
    97075
    97076
    97077
    97078
    97079
    97080
    97081
    97082
    97083
    97084
    97085
    97086
    97087
    97088
    97089
    97090
    97091
    97092
    97093
    97094
    97095
    97096
    97097
    97098
    97099
    97100
    97101
    97102
    97103
    97104
    97105
    97106
    97107
    97108
    97109
    97110
    97111
    97112
    97113
    97114
    97115
    97116
    97117
    97118
    97119
    97120
    97121
    97122
    97123
    97124
    97125
    97126
    97127
    97128
    97129
    97130
    97131
    97132
    97133
    97134
    97135
    97136
    97137
    97138
    97139
    97140
    97141
    97142
    97143
    97144
    97145
    97146
    97147
    97148
    97149
    97150
    97151
    97152
    97153
    97154
    97155
    97156
    97157
    97158
    97159
    97160
    97161
    97162
    97163
    97164
    97165
    97166
    97167
    97168
    97169
    97170
    97171
    97172
    97173
    97174
    97175
    97176
    97177
    97178
    97179
    97180
    97181
    97182
    97183
    97184
    97185
    97186
    97187
    97188
    97189
    97190
    97191
    97192
    97193
    97194
    97195
    97196
    97197
    97198
    97199
    97200
    97201
    97202
    97203
    97204
    97205
    97206
    97207
    97208
    97209
    97210
    97211
    97212
    97213
    97214
    97215
    97216
    97217
    97218
    97219
    97220
    97221
    97222
    97223
    97224
    97225
    97226
    97227
    97228
    97229
    97230
    97231
    97232
    97233
    97234
    97235
    97236
    97237
    97238
    97239
    97240
    97241
    97242
    97243
    97244
    97245
    97246
    97247
    97248
    97249
    97250
    97251
    97252
    97253
    97254
    97255
    97256
    97257
    97258
    97259
    97260
    97261
    97262
    97263
    97264
    97265
    97266
    97267
    97268
    97269
    97270
    97271
    97272
    97273
    97274
    97275
    97276
    97277
    97278
    97279
    97280
    97281
    97282
    97283
    97284
    97285
    97286
    97287
    97288
    97289
    97290
    97291
    97292
    97293
    97294
    97295
    97296
    97297
    97298
    97299
    97300
    97301
    97302
    97303
    97304
    97305
    97306
    97307
    97308
    97309
    97310
    97311
    97312
    97313
    97314
    97315
    97316
    97317
    97318
    97319
    97320
    97321
    97322
    97323
    97324
    97325
    97326
    97327
    97328
    97329
    97330
    97331
    97332
    97333
    97334
    97335
    97336
    97337
    97338
    97339
    97340
    97341
    97342
    97343
    97344
    97345
    97346
    97347
    97348
    97349
    97350
    97351
    97352
    97353
    97354
    97355
    97356
    97357
    97358
    97359
    97360
    97361
    97362
    97363
    97364
    97365
    97366
    97367
    97368
    97369
    97370
    97371
    97372
    97373
    97374
    97375
    97376
    97377
    97378
    97379
    97380
    97381
    97382
    97383
    97384
    97385
    97386
    97387
    97388
    97389
    97390
    97391
    97392
    97393
    97394
    97395
    97396
    97397
    97398
    97399
    97400
    97401
    97402
    97403
    97404
    97405
    97406
    97407
    97408
    97409
    97410
    97411
    97412
    97413
    97414
    97415
    97416
    97417
    97418
    97419
    97420
    97421
    97422
    97423
    97424
    97425
    97426
    97427
    97428
    97429
    97430
    97431
    97432
    97433
    97434
    97435
    97436
    97437
    97438
    97439
    97440
    97441
    97442
    97443
    97444
    97445
    97446
    97447
    97448
    97449
    97450
    97451
    97452
    97453
    97454
    97455
    97456
    97457
    97458
    97459
    97460
    97461
    97462
    97463
    97464
    97465
    97466
    97467
    97468
    97469
    97470
    97471
    97472
    97473
    97474
    97475
    97476
    97477
    97478
    97479
    97480
    97481
    97482
    97483
    97484
    97485
    97486
    97487
    97488
    97489
    97490
    97491
    97492
    97493
    97494
    97495
    97496
    97497
    97498
    97499
    97500
    97501
    97502
    97503
    97504
    97505
    97506
    97507
    97508
    97509
    97510
    97511
    97512
    97513
    97514
    97515
    97516
    97517
    97518
    97519
    97520
    97521
    97522
    97523
    97524
    97525
    97526
    97527
    97528
    97529
    97530
    97531
    97532
    97533
    97534
    97535
    97536
    97537
    97538
    97539
    97540
    97541
    97542
    97543
    97544
    97545
    97546
    97547
    97548
    97549
    97550
    97551
    97552
    97553
    97554
    97555
    97556
    97557
    97558
    97559
    97560
    97561
    97562
    97563
    97564
    97565
    97566
    97567
    97568
    97569
    97570
    97571
    97572
    97573
    97574
    97575
    97576
    97577
    97578
    97579
    97580
    97581
    97582
    97583
    97584
    97585
    97586
    97587
    97588
    97589
    97590
    97591
    97592
    97593
    97594
    97595
    97596
    97597
    97598
    97599
    97600
    97601
    97602
    97603
    97604
    97605
    97606
    97607
    97608
    97609
    97610
    97611
    97612
    97613
    97614
    97615
    97616
    97617
    97618
    97619
    97620
    97621
    97622
    97623
    97624
    97625
    97626
    97627
    97628
    97629
    97630
    97631
    97632
    97633
    97634
    97635
    97636
    97637
    97638
    97639
    97640
    97641
    97642
    97643
    97644
    97645
    97646
    97647
    97648
    97649
    97650
    97651
    97652
    97653
    97654
    97655
    97656
    97657
    97658
    97659
    97660
    97661
    97662
    97663
    97664
    97665
    97666
    97667
    97668
    97669
    97670
    97671
    97672
    97673
    97674
    97675
    97676
    97677
    97678
    97679
    97680
    97681
    97682
    97683
    97684
    97685
    97686
    97687
    97688
    97689
    97690
    97691
    97692
    97693
    97694
    97695
    97696
    97697
    97698
    97699
    97700
    97701
    97702
    97703
    97704
    97705
    97706
    97707
    97708
    97709
    97710
    97711
    97712
    97713
    97714
    97715
    97716
    97717
    97718
    97719
    97720
    97721
    97722
    97723
    97724
    97725
    97726
    97727
    97728
    97729
    97730
    97731
    97732
    97733
    97734
    97735
    97736
    97737
    97738
    97739
    97740
    97741
    97742
    97743
    97744
    97745
    97746
    97747
    97748
    97749
    97750
    97751
    97752
    97753
    97754
    97755
    97756
    97757
    97758
    97759
    97760
    97761
    97762
    97763
    97764
    97765
    97766
    97767
    97768
    97769
    97770
    97771
    97772
    97773
    97774
    97775
    97776
    97777
    97778
    97779
    97780
    97781
    97782
    97783
    97784
    97785
    97786
    97787
    97788
    97789
    97790
    97791
    97792
    97793
    97794
    97795
    97796
    97797
    97798
    97799
    97800
    97801
    97802
    97803
    97804
    97805
    97806
    97807
    97808
    97809
    97810
    97811
    97812
    97813
    97814
    97815
    97816
    97817
    97818
    97819
    97820
    97821
    97822
    97823
    97824
    97825
    97826
    97827
    97828
    97829
    97830
    97831
    97832
    97833
    97834
    97835
    97836
    97837
    97838
    97839
    97840
    97841
    97842
    97843
    97844
    97845
    97846
    97847
    97848
    97849
    97850
    97851
    97852
    97853
    97854
    97855
    97856
    97857
    97858
    97859
    97860
    97861
    97862
    97863
    97864
    97865
    97866
    97867
    97868
    97869
    97870
    97871
    97872
    97873
    97874
    97875
    97876
    97877
    97878
    97879
    97880
    97881
    97882
    97883
    97884
    97885
    97886
    97887
    97888
    97889
    97890
    97891
    97892
    97893
    97894
    97895
    97896
    97897
    97898
    97899
    97900
    97901
    97902
    97903
    97904
    97905
    97906
    97907
    97908
    97909
    97910
    97911
    97912
    97913
    97914
    97915
    97916
    97917
    97918
    97919
    97920
    97921
    97922
    97923
    97924
    97925
    97926
    97927
    97928
    97929
    97930
    97931
    97932
    97933
    97934
    97935
    97936
    97937
    97938
    97939
    97940
    97941
    97942
    97943
    97944
    97945
    97946
    97947
    97948
    97949
    97950
    97951
    97952
    97953
    97954
    97955
    97956
    97957
    97958
    97959
    97960
    97961
    97962
    97963
    97964
    97965
    97966
    97967
    97968
    97969
    97970
    97971
    97972
    97973
    97974
    97975
    97976
    97977
    97978
    97979
    97980
    97981
    97982
    97983
    97984
    97985
    97986
    97987
    97988
    97989
    97990
    97991
    97992
    97993
    97994
    97995
    97996
    97997
    97998
    97999
    98000
    98001
    98002
    98003
    98004
    98005
    98006
    98007
    98008
    98009
    98010
    98011
    98012
    98013
    98014
    98015
    98016
    98017
    98018
    98019
    98020
    98021
    98022
    98023
    98024
    98025
    98026
    98027
    98028
    98029
    98030
    98031
    98032
    98033
    98034
    98035
    98036
    98037
    98038
    98039
    98040
    98041
    98042
    98043
    98044
    98045
    98046
    98047
    98048
    98049
    98050
    98051
    98052
    98053
    98054
    98055
    98056
    98057
    98058
    98059
    98060
    98061
    98062
    98063
    98064
    98065
    98066
    98067
    98068
    98069
    98070
    98071
    98072
    98073
    98074
    98075
    98076
    98077
    98078
    98079
    98080
    98081
    98082
    98083
    98084
    98085
    98086
    98087
    98088
    98089
    98090
    98091
    98092
    98093
    98094
    98095
    98096
    98097
    98098
    98099
    98100
    98101
    98102
    98103
    98104
    98105
    98106
    98107
    98108
    98109
    98110
    98111
    98112
    98113
    98114
    98115
    98116
    98117
    98118
    98119
    98120
    98121
    98122
    98123
    98124
    98125
    98126
    98127
    98128
    98129
    98130
    98131
    98132
    98133
    98134
    98135
    98136
    98137
    98138
    98139
    98140
    98141
    98142
    98143
    98144
    98145
    98146
    98147
    98148
    98149
    98150
    98151
    98152
    98153
    98154
    98155
    98156
    98157
    98158
    98159
    98160
    98161
    98162
    98163
    98164
    98165
    98166
    98167
    98168
    98169
    98170
    98171
    98172
    98173
    98174
    98175
    98176
    98177
    98178
    98179
    98180
    98181
    98182
    98183
    98184
    98185
    98186
    98187
    98188
    98189
    98190
    98191
    98192
    98193
    98194
    98195
    98196
    98197
    98198
    98199
    98200
    98201
    98202
    98203
    98204
    98205
    98206
    98207
    98208
    98209
    98210
    98211
    98212
    98213
    98214
    98215
    98216
    98217
    98218
    98219
    98220
    98221
    98222
    98223
    98224
    98225
    98226
    98227
    98228
    98229
    98230
    98231
    98232
    98233
    98234
    98235
    98236
    98237
    98238
    98239
    98240
    98241
    98242
    98243
    98244
    98245
    98246
    98247
    98248
    98249
    98250
    98251
    98252
    98253
    98254
    98255
    98256
    98257
    98258
    98259
    98260
    98261
    98262
    98263
    98264
    98265
    98266
    98267
    98268
    98269
    98270
    98271
    98272
    98273
    98274
    98275
    98276
    98277
    98278
    98279
    98280
    98281
    98282
    98283
    98284
    98285
    98286
    98287
    98288
    98289
    98290
    98291
    98292
    98293
    98294
    98295
    98296
    98297
    98298
    98299
    98300
    98301
    98302
    98303
    98304
    98305
    98306
    98307
    98308
    98309
    98310
    98311
    98312
    98313
    98314
    98315
    98316
    98317
    98318
    98319
    98320
    98321
    98322
    98323
    98324
    98325
    98326
    98327
    98328
    98329
    98330
    98331
    98332
    98333
    98334
    98335
    98336
    98337
    98338
    98339
    98340
    98341
    98342
    98343
    98344
    98345
    98346
    98347
    98348
    98349
    98350
    98351
    98352
    98353
    98354
    98355
    98356
    98357
    98358
    98359
    98360
    98361
    98362
    98363
    98364
    98365
    98366
    98367
    98368
    98369
    98370
    98371
    98372
    98373
    98374
    98375
    98376
    98377
    98378
    98379
    98380
    98381
    98382
    98383
    98384
    98385
    98386
    98387
    98388
    98389
    98390
    98391
    98392
    98393
    98394
    98395
    98396
    98397
    98398
    98399
    98400
    98401
    98402
    98403
    98404
    98405
    98406
    98407
    98408
    98409
    98410
    98411
    98412
    98413
    98414
    98415
    98416
    98417
    98418
    98419
    98420
    98421
    98422
    98423
    98424
    98425
    98426
    98427
    98428
    98429
    98430
    98431
    98432
    98433
    98434
    98435
    98436
    98437
    98438
    98439
    98440
    98441
    98442
    98443
    98444
    98445
    98446
    98447
    98448
    98449
    98450
    98451
    98452
    98453
    98454
    98455
    98456
    98457
    98458
    98459
    98460
    98461
    98462
    98463
    98464
    98465
    98466
    98467
    98468
    98469
    98470
    98471
    98472
    98473
    98474
    98475
    98476
    98477
    98478
    98479
    98480
    98481
    98482
    98483
    98484
    98485
    98486
    98487
    98488
    98489
    98490
    98491
    98492
    98493
    98494
    98495
    98496
    98497
    98498
    98499
    98500
    98501
    98502
    98503
    98504
    98505
    98506
    98507
    98508
    98509
    98510
    98511
    98512
    98513
    98514
    98515
    98516
    98517
    98518
    98519
    98520
    98521
    98522
    98523
    98524
    98525
    98526
    98527
    98528
    98529
    98530
    98531
    98532
    98533
    98534
    98535
    98536
    98537
    98538
    98539
    98540
    98541
    98542
    98543
    98544
    98545
    98546
    98547
    98548
    98549
    98550
    98551
    98552
    98553
    98554
    98555
    98556
    98557
    98558
    98559
    98560
    98561
    98562
    98563
    98564
    98565
    98566
    98567
    98568
    98569
    98570
    98571
    98572
    98573
    98574
    98575
    98576
    98577
    98578
    98579
    98580
    98581
    98582
    98583
    98584
    98585
    98586
    98587
    98588
    98589
    98590
    98591
    98592
    98593
    98594
    98595
    98596
    98597
    98598
    98599
    98600
    98601
    98602
    98603
    98604
    98605
    98606
    98607
    98608
    98609
    98610
    98611
    98612
    98613
    98614
    98615
    98616
    98617
    98618
    98619
    98620
    98621
    98622
    98623
    98624
    98625
    98626
    98627
    98628
    98629
    98630
    98631
    98632
    98633
    98634
    98635
    98636
    98637
    98638
    98639
    98640
    98641
    98642
    98643
    98644
    98645
    98646
    98647
    98648
    98649
    98650
    98651
    98652
    98653
    98654
    98655
    98656
    98657
    98658
    98659
    98660
    98661
    98662
    98663
    98664
    98665
    98666
    98667
    98668
    98669
    98670
    98671
    98672
    98673
    98674
    98675
    98676
    98677
    98678
    98679
    98680
    98681
    98682
    98683
    98684
    98685
    98686
    98687
    98688
    98689
    98690
    98691
    98692
    98693
    98694
    98695
    98696
    98697
    98698
    98699
    98700
    98701
    98702
    98703
    98704
    98705
    98706
    98707
    98708
    98709
    98710
    98711
    98712
    98713
    98714
    98715
    98716
    98717
    98718
    98719
    98720
    98721
    98722
    98723
    98724
    98725
    98726
    98727
    98728
    98729
    98730
    98731
    98732
    98733
    98734
    98735
    98736
    98737
    98738
    98739
    98740
    98741
    98742
    98743
    98744
    98745
    98746
    98747
    98748
    98749
    98750
    98751
    98752
    98753
    98754
    98755
    98756
    98757
    98758
    98759
    98760
    98761
    98762
    98763
    98764
    98765
    98766
    98767
    98768
    98769
    98770
    98771
    98772
    98773
    98774
    98775
    98776
    98777
    98778
    98779
    98780
    98781
    98782
    98783
    98784
    98785
    98786
    98787
    98788
    98789
    98790
    98791
    98792
    98793
    98794
    98795
    98796
    98797
    98798
    98799
    98800
    98801
    98802
    98803
    98804
    98805
    98806
    98807
    98808
    98809
    98810
    98811
    98812
    98813
    98814
    98815
    98816
    98817
    98818
    98819
    98820
    98821
    98822
    98823
    98824
    98825
    98826
    98827
    98828
    98829
    98830
    98831
    98832
    98833
    98834
    98835
    98836
    98837
    98838
    98839
    98840
    98841
    98842
    98843
    98844
    98845
    98846
    98847
    98848
    98849
    98850
    98851
    98852
    98853
    98854
    98855
    98856
    98857
    98858
    98859
    98860
    98861
    98862
    98863
    98864
    98865
    98866
    98867
    98868
    98869
    98870
    98871
    98872
    98873
    98874
    98875
    98876
    98877
    98878
    98879
    98880
    98881
    98882
    98883
    98884
    98885
    98886
    98887
    98888
    98889
    98890
    98891
    98892
    98893
    98894
    98895
    98896
    98897
    98898
    98899
    98900
    98901
    98902
    98903
    98904
    98905
    98906
    98907
    98908
    98909
    98910
    98911
    98912
    98913
    98914
    98915
    98916
    98917
    98918
    98919
    98920
    98921
    98922
    98923
    98924
    98925
    98926
    98927
    98928
    98929
    98930
    98931
    98932
    98933
    98934
    98935
    98936
    98937
    98938
    98939
    98940
    98941
    98942
    98943
    98944
    98945
    98946
    98947
    98948
    98949
    98950
    98951
    98952
    98953
    98954
    98955
    98956
    98957
    98958
    98959
    98960
    98961
    98962
    98963
    98964
    98965
    98966
    98967
    98968
    98969
    98970
    98971
    98972
    98973
    98974
    98975
    98976
    98977
    98978
    98979
    98980
    98981
    98982
    98983
    98984
    98985
    98986
    98987
    98988
    98989
    98990
    98991
    98992
    98993
    98994
    98995
    98996
    98997
    98998
    98999
    99000
    99001
    99002
    99003
    99004
    99005
    99006
    99007
    99008
    99009
    99010
    99011
    99012
    99013
    99014
    99015
    99016
    99017
    99018
    99019
    99020
    99021
    99022
    99023
    99024
    99025
    99026
    99027
    99028
    99029
    99030
    99031
    99032
    99033
    99034
    99035
    99036
    99037
    99038
    99039
    99040
    99041
    99042
    99043
    99044
    99045
    99046
    99047
    99048
    99049
    99050
    99051
    99052
    99053
    99054
    99055
    99056
    99057
    99058
    99059
    99060
    99061
    99062
    99063
    99064
    99065
    99066
    99067
    99068
    99069
    99070
    99071
    99072
    99073
    99074
    99075
    99076
    99077
    99078
    99079
    99080
    99081
    99082
    99083
    99084
    99085
    99086
    99087
    99088
    99089
    99090
    99091
    99092
    99093
    99094
    99095
    99096
    99097
    99098
    99099
    99100
    99101
    99102
    99103
    99104
    99105
    99106
    99107
    99108
    99109
    99110
    99111
    99112
    99113
    99114
    99115
    99116
    99117
    99118
    99119
    99120
    99121
    99122
    99123
    99124
    99125
    99126
    99127
    99128
    99129
    99130
    99131
    99132
    99133
    99134
    99135
    99136
    99137
    99138
    99139
    99140
    99141
    99142
    99143
    99144
    99145
    99146
    99147
    99148
    99149
    99150
    99151
    99152
    99153
    99154
    99155
    99156
    99157
    99158
    99159
    99160
    99161
    99162
    99163
    99164
    99165
    99166
    99167
    99168
    99169
    99170
    99171
    99172
    99173
    99174
    99175
    99176
    99177
    99178
    99179
    99180
    99181
    99182
    99183
    99184
    99185
    99186
    99187
    99188
    99189
    99190
    99191
    99192
    99193
    99194
    99195
    99196
    99197
    99198
    99199
    99200
    99201
    99202
    99203
    99204
    99205
    99206
    99207
    99208
    99209
    99210
    99211
    99212
    99213
    99214
    99215
    99216
    99217
    99218
    99219
    99220
    99221
    99222
    99223
    99224
    99225
    99226
    99227
    99228
    99229
    99230
    99231
    99232
    99233
    99234
    99235
    99236
    99237
    99238
    99239
    99240
    99241
    99242
    99243
    99244
    99245
    99246
    99247
    99248
    99249
    99250
    99251
    99252
    99253
    99254
    99255
    99256
    99257
    99258
    99259
    99260
    99261
    99262
    99263
    99264
    99265
    99266
    99267
    99268
    99269
    99270
    99271
    99272
    99273
    99274
    99275
    99276
    99277
    99278
    99279
    99280
    99281
    99282
    99283
    99284
    99285
    99286
    99287
    99288
    99289
    99290
    99291
    99292
    99293
    99294
    99295
    99296
    99297
    99298
    99299
    99300
    99301
    99302
    99303
    99304
    99305
    99306
    99307
    99308
    99309
    99310
    99311
    99312
    99313
    99314
    99315
    99316
    99317
    99318
    99319
    99320
    99321
    99322
    99323
    99324
    99325
    99326
    99327
    99328
    99329
    99330
    99331
    99332
    99333
    99334
    99335
    99336
    99337
    99338
    99339
    99340
    99341
    99342
    99343
    99344
    99345
    99346
    99347
    99348
    99349
    99350
    99351
    99352
    99353
    99354
    99355
    99356
    99357
    99358
    99359
    99360
    99361
    99362
    99363
    99364
    99365
    99366
    99367
    99368
    99369
    99370
    99371
    99372
    99373
    99374
    99375
    99376
    99377
    99378
    99379
    99380
    99381
    99382
    99383
    99384
    99385
    99386
    99387
    99388
    99389
    99390
    99391
    99392
    99393
    99394
    99395
    99396
    99397
    99398
    99399
    99400
    99401
    99402
    99403
    99404
    99405
    99406
    99407
    99408
    99409
    99410
    99411
    99412
    99413
    99414
    99415
    99416
    99417
    99418
    99419
    99420
    99421
    99422
    99423
    99424
    99425
    99426
    99427
    99428
    99429
    99430
    99431
    99432
    99433
    99434
    99435
    99436
    99437
    99438
    99439
    99440
    99441
    99442
    99443
    99444
    99445
    99446
    99447
    99448
    99449
    99450
    99451
    99452
    99453
    99454
    99455
    99456
    99457
    99458
    99459
    99460
    99461
    99462
    99463
    99464
    99465
    99466
    99467
    99468
    99469
    99470
    99471
    99472
    99473
    99474
    99475
    99476
    99477
    99478
    99479
    99480
    99481
    99482
    99483
    99484
    99485
    99486
    99487
    99488
    99489
    99490
    99491
    99492
    99493
    99494
    99495
    99496
    99497
    99498
    99499
    99500
    99501
    99502
    99503
    99504
    99505
    99506
    99507
    99508
    99509
    99510
    99511
    99512
    99513
    99514
    99515
    99516
    99517
    99518
    99519
    99520
    99521
    99522
    99523
    99524
    99525
    99526
    99527
    99528
    99529
    99530
    99531
    99532
    99533
    99534
    99535
    99536
    99537
    99538
    99539
    99540
    99541
    99542
    99543
    99544
    99545
    99546
    99547
    99548
    99549
    99550
    99551
    99552
    99553
    99554
    99555
    99556
    99557
    99558
    99559
    99560
    99561
    99562
    99563
    99564
    99565
    99566
    99567
    99568
    99569
    99570
    99571
    99572
    99573
    99574
    99575
    99576
    99577
    99578
    99579
    99580
    99581
    99582
    99583
    99584
    99585
    99586
    99587
    99588
    99589
    99590
    99591
    99592
    99593
    99594
    99595
    99596
    99597
    99598
    99599
    99600
    99601
    99602
    99603
    99604
    99605
    99606
    99607
    99608
    99609
    99610
    99611
    99612
    99613
    99614
    99615
    99616
    99617
    99618
    99619
    99620
    99621
    99622
    99623
    99624
    99625
    99626
    99627
    99628
    99629
    99630
    99631
    99632
    99633
    99634
    99635
    99636
    99637
    99638
    99639
    99640
    99641
    99642
    99643
    99644
    99645
    99646
    99647
    99648
    99649
    99650
    99651
    99652
    99653
    99654
    99655
    99656
    99657
    99658
    99659
    99660
    99661
    99662
    99663
    99664
    99665
    99666
    99667
    99668
    99669
    99670
    99671
    99672
    99673
    99674
    99675
    99676
    99677
    99678
    99679
    99680
    99681
    99682
    99683
    99684
    99685
    99686
    99687
    99688
    99689
    99690
    99691
    99692
    99693
    99694
    99695
    99696
    99697
    99698
    99699
    99700
    99701
    99702
    99703
    99704
    99705
    99706
    99707
    99708
    99709
    99710
    99711
    99712
    99713
    99714
    99715
    99716
    99717
    99718
    99719
    99720
    99721
    99722
    99723
    99724
    99725
    99726
    99727
    99728
    99729
    99730
    99731
    99732
    99733
    99734
    99735
    99736
    99737
    99738
    99739
    99740
    99741
    99742
    99743
    99744
    99745
    99746
    99747
    99748
    99749
    99750
    99751
    99752
    99753
    99754
    99755
    99756
    99757
    99758
    99759
    99760
    99761
    99762
    99763
    99764
    99765
    99766
    99767
    99768
    99769
    99770
    99771
    99772
    99773
    99774
    99775
    99776
    99777
    99778
    99779
    99780
    99781
    99782
    99783
    99784
    99785
    99786
    99787
    99788
    99789
    99790
    99791
    99792
    99793
    99794
    99795
    99796
    99797
    99798
    99799
    99800
    99801
    99802
    99803
    99804
    99805
    99806
    99807
    99808
    99809
    99810
    99811
    99812
    99813
    99814
    99815
    99816
    99817
    99818
    99819
    99820
    99821
    99822
    99823
    99824
    99825
    99826
    99827
    99828
    99829
    99830
    99831
    99832
    99833
    99834
    99835
    99836
    99837
    99838
    99839
    99840
    99841
    99842
    99843
    99844
    99845
    99846
    99847
    99848
    99849
    99850
    99851
    99852
    99853
    99854
    99855
    99856
    99857
    99858
    99859
    99860
    99861
    99862
    99863
    99864
    99865
    99866
    99867
    99868
    99869
    99870
    99871
    99872
    99873
    99874
    99875
    99876
    99877
    99878
    99879
    99880
    99881
    99882
    99883
    99884
    99885
    99886
    99887
    99888
    99889
    99890
    99891
    99892
    99893
    99894
    99895
    99896
    99897
    99898
    99899
    99900
    99901
    99902
    99903
    99904
    99905
    99906
    99907
    99908
    99909
    99910
    99911
    99912
    99913
    99914
    99915
    99916
    99917
    99918
    99919
    99920
    99921
    99922
    99923
    99924
    99925
    99926
    99927
    99928
    99929
    99930
    99931
    99932
    99933
    99934
    99935
    99936
    99937
    99938
    99939
    99940
    99941
    99942
    99943
    99944
    99945
    99946
    99947
    99948
    99949
    99950
    99951
    99952
    99953
    99954
    99955
    99956
    99957
    99958
    99959
    99960
    99961
    99962
    99963
    99964
    99965
    99966
    99967
    99968
    99969
    99970
    99971
    99972
    99973
    99974
    99975
    99976
    99977
    99978
    99979
    99980
    99981
    99982
    99983
    99984
    99985
    99986
    99987
    99988
    99989
    99990
    99991
    99992
    99993
    99994
    99995
    99996
    99997
    99998
    99999

```python
data_roots = np.empty((10 ** 5, N * 2))

for r, row in enumerate(roots):
  for n, num in enumerate(row):
    data_roots[r, n * 2] = num.as_real_imag()[0]
    data_roots[r, n * 2 + 1] = num.as_real_imag()[1]
```

```python
columns = []

for i in range(N):
  columns.extend(['Re(alpha%d)' % (i+1), 'Im(alpha%d)' % (i+1)])

Y = pd.DataFrame(data_roots, columns=columns)
```

```python
Y
```

      Re(alpha1)
      Im(alpha1)
      Re(alpha2)
      Im(alpha2)
      Re(alpha3)
      Im(alpha3)
      Re(alpha4)
      Im(alpha4)
      Re(alpha5)
      Im(alpha5)

      0
      -0.826528
      0.0
      -0.155415
      -0.820919
      -0.155415
      0.820919
      0.396460
      -1.073836
      0.396460
      1.073836

      1
      -1.853012
      0.0
      -1.103858
      -0.987763
      -1.103858
      0.987763
      0.605308
      -0.795560
      0.605308
      0.795560

      2
      -0.972175
      0.0
      -0.490184
      -0.922207
      -0.490184
      0.922207
      0.692799
      -1.203724
      0.692799
      1.203724

      3
      -4.855659
      0.0
      -0.783015
      -0.593104
      -0.783015
      0.593104
      0.785446
      -1.111071
      0.785446
      1.111071

      4
      -1.190179
      0.0
      -0.208817
      -1.769277
      -0.208817
      1.769277
      0.217835
      -0.939238
      0.217835
      0.939238

      ...
      ...
      ...
      ...
      ...
      ...
      ...
      ...
      ...
      ...
      ...

      99995
      -1.406253
      0.0
      -0.467540
      -0.980713
      -0.467540
      0.980713
      0.527820
      -0.780883
      0.527820
      0.780883

      99996
      -0.748828
      0.0
      -0.552672
      -0.720039
      -0.552672
      0.720039
      0.493368
      -0.677414
      0.493368
      0.677414

      99997
      -0.871975
      0.0
      -0.327039
      -1.106900
      -0.327039
      1.106900
      0.363471
      -0.641750
      0.363471
      0.641750

      99998
      -15.116221
      0.0
      -0.705539
      -0.602036
      -0.705539
      0.602036
      0.702735
      -1.222892
      0.702735
      1.222892

      99999
      -0.752216
      0.0
      -0.294923
      -0.700591
      -0.294923
      0.700591
      0.114942
      -0.636086
      0.114942
      0.636086

100000 rows × 10 columns

```python
Y.to_pickle('roots.pkl')
```


### Writing a genetic algorithm for the ARC dataset just for fun

```python
import numpy as np
import json
from PIL import Image, ImageDraw
from IPython.display import Image as Im
import matplotlib.pyplot as plt
from itertools import permutations, combinations
from sympy.utilities.iterables import multiset_permutations
```

```python
filename = "/Users/aysjajohnson/Desktop/ARC-master/data/training/0ca9ddb6.json"
with open(filename, 'r') as f:
        train1 = json.load(f)
```

```python
colorMap = {0:"black",1:"blue",2:"red", 3:"green",4:"yellow",5:"grey",6:"magenta",7:"orange",8:"cyan",9:"brown"}
```

```python
# displaying a single grid
def DisplayGrid(grid):
    grid = np.asarray(grid)
    nrows = len(grid[:,0])
    ncols = len(grid[0,:])
    height, width = nrows*50, ncols*50
    image = Image.new(size=(width,height),mode='RGB',color=(255,255,255))
    draw = ImageDraw.Draw(image)
    r = 0
    for row in grid:
        c = 0
        for col in row:
            draw.rectangle(xy=[c*50,r*50,(c+1)*50,(r+1)*50], fill=colorMap[np.abs(grid[r][c])])
            c += 1
        r += 1
    for i in range(ncols):
        draw.line([(i+1)*50,0,(i+1)*50,height],fill="grey")
    for i in range(nrows):
        draw.line([0,(i+1)*50,width,(i+1)*50],fill="grey")
    display(image)
```

```python
# displaying two grids side by side
def DisplayGrids(grid1,grid2):
    # Grid 1
    grid1 = np.asarray(grid1)
    nrows = len(grid1[:,0])
    ncols = len(grid1[0,:])
    height, width = nrows*50, ncols*50
    image1 = Image.new(size=(width,height),mode='RGB',color=(255,255,255))
    draw = ImageDraw.Draw(image1)
    r = 0
    for row in grid1:
        c = 0
        for col in row:
            draw.rectangle(xy=[c*50,r*50,(c+1)*50,(r+1)*50], fill=colorMap[np.abs(grid1[r][c])])
            c += 1
        r += 1
    for i in range(ncols):
        draw.line([(i+1)*50,0,(i+1)*50,height],fill="grey")
    for i in range(nrows):
        draw.line([0,(i+1)*50,width,(i+1)*50],fill="grey")

    # Grid 2
    grid2 = np.asarray(grid2)
    nrows = len(grid2[:,0])
    ncols = len(grid2[0,:])
    height, width = nrows*50, ncols*50
    image2 = Image.new(size=(width,height),mode='RGB',color=(255,255,255))
    draw = ImageDraw.Draw(image2)
    r = 0
    for row in grid2:
        c = 0
        for col in row:
            draw.rectangle(xy=[c*50,r*50,(c+1)*50,(r+1)*50], fill=colorMap[np.abs(grid2[r][c])])
            c += 1
        r += 1
    for i in range(ncols):
        draw.line([(i+1)*50,0,(i+1)*50,height],fill="grey")
    for i in range(nrows):
        draw.line([0,(i+1)*50,width,(i+1)*50],fill="grey")

    # Displaying
    fig, ax = plt.subplots(1,2,figsize=(50,50))
    ax[0].imshow(image1)
    ax[0].axis("off")
    ax[1].imshow(image2)
    ax[1].axis("off")
```

```python
numTrain = len(train1["train"])
```

```python
# creating action table
# np array 100,000 by 5, the columns are N, S, E, W, Current
a = [0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9]
# This will give us all the non duplicated permutations, i.e., all possible combinations of states
b = list(multiset_permutations(a,5))
```

    100000
    [[0, 0, 0, 0, 0], [0, 0, 0, 0, 1], [0, 0, 0, 0, 2], [0, 0, 0, 0, 3], [0, 0, 0, 0, 4], [0, 0, 0, 0, 5], [0, 0, 0, 0, 6], [0, 0, 0, 0, 7], [0, 0, 0, 0, 8], [0, 0, 0, 0, 9], [0, 0, 0, 1, 0], [0, 0, 0, 1, 1], [0, 0, 0, 1, 2], [0, 0, 0, 1, 3], [0, 0, 0, 1, 4], [0, 0, 0, 1, 5], [0, 0, 0, 1, 6], [0, 0, 0, 1, 7], [0, 0, 0, 1, 8], [0, 0, 0, 1, 9]]

```python
lookupTable = np.asarray(b)
print(lookupTable)
```

    [[0 0 0 0 0]
     [0 0 0 0 1]
     [0 0 0 0 2]
     ...
     [9 9 9 9 7]
     [9 9 9 9 8]
     [9 9 9 9 9]]

```python
# initialize 200 agents
agents = np.zeros((100000,200))
for i in range(200):
    agents[:,i] = np.random.randint(0,10,100000)
```

```python
print(agents[:,0])

```

    [4. 7. 6. ... 9. 4. 5.]

```python
def padding(grid):
    grid = np.asarray(grid)
    height = grid.shape[0]
    width = grid.shape[1]
    paddedGrid = np.zeros((height+2,width+2))
    paddedGrid[1:height+1,1:width+1] = grid
    return paddedGrid
```

```python
# evaluation, run the strategy on each square of the grid, with wrarp around, i.e., add one block of black around the whole thing
gridTrain = np.asarray(train1["train"][0]["input"])
gridTest = np.asarray(train1["train"][0]["output"])
DisplayGrids(gridTrain,gridTest)
```

```python
def accuracy(inputGrid,outputGrid):
    acc = 0
    if inputGrid.shape != outputGrid.shape:
        return None
    for i in range(inputGrid.shape[0]):
        for j in range(inputGrid.shape[1]):
            if inputGrid[i][j] != outputGrid[i][j]:
                acc+=1
    return acc
```

```python
def fitness(gridInput, gridOutput, agent):
    output = np.zeros((gridInput.shape[0],gridInput.shape[1]))
    grid = padding(gridInput)
    currentState = [0,0,0,0,0]
    for i in range(1,grid.shape[0]-1):
        for j in range(1,grid.shape[1]-1):
            currentState[0] = grid[i+1][j]
            currentState[1] = grid[i-1][j]
            currentState[2] = grid[i][j-1]
            currentState[3] = grid[i][j+1]
            currentState[4] = grid[i][j]
            index = np.where((lookupTable==currentState).all(axis=1))[0][0]
            action = agent[index]
            output[i-1,j-1] = action
    acc = accuracy(gridOutput,output)
    return(output,acc)
```

```python
f = fitness(gridTrain, gridTest, agents[:,0])[0]
DisplayGrid(f)
```

```python
def bestFit(gridInput,gridOutput,agents):
    numAgents = len(agents[0,:])
    fit = np.zeros((200,))
    for i in range(numAgents):
        fit[i]=(fitness(gridInput,gridOutput,agents[:,i])[1])
    return(fit)
```

```python
best = bestFit(gridTrain,gridTest,agents)
```

```python
# Pick the best 20
topAgents = agents[:,best.argsort()[:20]]
DisplayGrid(fitness(gridTrain,gridTest,topAgents[:,0])[0])
def bestAgents(a,b,n):
    return(a[:,b.argsort()[:n]])
```

```python
def newAgent(agent1,agent2):
    newAgent = np.zeros((100000,))
    if np.random.random() < 0.5:
        newAgent[:50000] = agent1[:50000].flatten()
        newAgent[50000:] = agent2[50000:].flatten()
    else:
        newAgent[:50000] = agent2[:50000].flatten()
        newAgent[50000:] = agent1[50000:].flatten()
    return newAgent
```

```python
def reproduction(agents):
    numAgents = len(agents[0,:])
    newAgents = np.zeros((100000,int(numAgents/2)))
    sample = range(numAgents)
    for i in range(int(numAgents/2)):
        agent1 = topAgents[:,np.random.choice(sample,1,replace=False)]
        agent2 = topAgents[:,np.random.choice(sample,1,replace=False)]
        new = newAgent(agent1,agent2)
        newAgents[:,i] = new
    return newAgents
```

```python
evo = reproduction(topAgents)
print(len(evo[0,:]))
```

    10

```python
for i in range(len(evo[0,:])):
    DisplayGrid(fitness(gridTrain,gridTest,evo[:,i])[0])
```

```python
# spawn 10 more mutations for each for a total of 200 and add 100 hundred random ones into the mix
```

```python
def mutation(agent):
    c = 0
    for i in range(len(agent)):
        if np.random.random() < 0.005:
            c+=1
            agent[i] = np.random.choice(range(10),1,replace=True)
    return agent
```

```python
def nextAgents(topAgents):
    agents = np.zeros((100000,200))
    for i in range(10):
        for j in range(10):
            agents[:,i] = mutation(topAgents[:,i])
    for i in range(100,200):
        agents[:,i] = np.random.randint(0,10,100000)
    return agents
```

```python
newBatch = nextAgents(evo)
print(newBatch)
```

    [[0. 4. 0. ... 5. 9. 1.]
     [9. 1. 1. ... 0. 8. 0.]
     [6. 3. 4. ... 4. 3. 1.]
     ...
     [7. 9. 3. ... 3. 3. 0.]
     [9. 7. 7. ... 0. 6. 7.]
     [6. 1. 1. ... 5. 4. 3.]]

```python
# second through n run
bFit = bestFit(gridTrain,gridTest,newBatch)
bAgents = bestAgents(newBatch,bFit,20)
evo = reproduction(bAgents)
for i in range(len(evo[0,:])):
    DisplayGrid(fitness(gridTrain,gridTest,evo[:,i])[0])
newBatch = nextAgents(evo)
```

```python
def evolution(gridInput,gridOutput,agents):
    bFit = bestFit(gridInput,gridOutput,agents)
    bAgents = bestAgents(newBatch,bFit,20)
    evo = reproduction(bAgents)
    for i in range(len(evo[0,:])):
        DisplayGrid(fitness(gridInput,gridOutput,evo[:,i])[0])
    newBatch = nextAgents(evo)
    return(newBatch)
```

```python
def evolutionRecursive(gridInput,gridOutput,bAgents,n):
    if n==1:
        return bAgents
    else:
        bFit = bestFit(gridInput,gridOutput,bAgents)
        bAgents = bestAgents(bAgents,bFit,20)
        evo = reproduction(bAgents)
        for i in range(len(evo[0,:])):
            DisplayGrid(fitness(gridInput,gridOutput,evo[:,i])[0])
        newBatch = nextAgents(evo)
        evolutionRecursive(gridInput,gridOutput,newBatch,n-1)
```

```python
evolutionRecursive(gridTrain,gridTest,newBatch,3)
```

```python

```


```python
import sympy as sp
import numpy as np
import matplotlib.pyplot as mpl
from scipy.optimize import fsolve, fmin, minimize_scalar, curve_fit
```

```python
import pathlib
if not pathlib.Path("mpl_utils.py").exists():
  !curl -O https://raw.githubusercontent.com/joaochenriques/MCTE_2022/main/libs/mpl_utils.py &> /dev/null

import mpl_utils as mut
mut.config_plots()

%config InlineBackend.figure_formats = ['svg']
```

# **Warning**

Before running this notebook, the locus of optimal values of $C_P$ as function of $C_T$ and $\mathrm{Fr}_1$ are described in the notebook:

https://github.com/joaochenriques/MCTE_2022/blob/main/DiskActuator/Sensitivity_Analysis.ipynb

```python
def CardanoRoots( aa, bb ):
  # Cardano algorithm to solve our polynomial, see:
  # https://www.shsu.edu/kws006/professional/Concepts_files/SolvingCubics.pdf
  P = -2.0*aa
  Q = -2.0*bb
  Δ = (P/3.0)**3 + (Q/2)**2
  if Δ < 0.0: Δ = Δ + 0J
  β = ( -Q/2.0 - np.sqrt(Δ) )**(1.0/3.0)
  α = P/(3.0*β)
  ω = ( -1.0 + np.sqrt(3.0)*1J) / 2.0

  x1 = α - β
  x2 = (α*ω - β)*ω
  x3 = (α - β*ω)*ω

  if np.imag(x1) < 1E-15: x1 = np.real( x1 )
  if np.imag(x2) < 1E-15: x2 = np.real( x2 )
  if np.imag(x3) < 1E-15: x3 = np.real( x3 )

  # applies only for this solution
  assert( np.imag( x1 ) == 0 )
  assert( np.imag( x2 ) == 0 )
  assert( np.imag( x3 ) == 0 )
  assert( x1 <= 0.0 )
  assert( x2 <= x3 )

  return (x2, x3)
```

```python
def compute_CT_CP_Frs( Fr4b, Fr1, B ):

    # These Eqs. are described in
    # https://github.com/joaochenriques/MCTE_2020_2021/blob/main/DiskActuator/DiskActuator.ipynb

    ζ4 = (1.0/2.0)*Fr1**2 - 1.0/2.0*Fr4b**2 + 1.0

    C1 = Fr1 - Fr4b*ζ4
    C2 = B**2*Fr4b**2 - 2*B*Fr1**2 + 2*B*Fr1*Fr4b \
            + B*ζ4**2 - B + Fr1**2 - 2*Fr1*Fr4b*ζ4 + Fr4b**2*ζ4**2

    Fr4t = ( C1 + np.sqrt(C2) ) / B
    ζ4t = ( Fr4b*ζ4 - Fr1 ) / ( Fr4b - Fr4t )
    ζ4b = ζ4 - ζ4t

    Fr2t = Fr4t*ζ4t/B
    C_T = (Fr4b**2 - Fr4t**2)/Fr1**2
    C_P = C_T*Fr2t/Fr1

    mb = Fr4b*ζ4b + Fr4t*ζ4t
    bb = mb**2
    aa = (Fr4b**2*ζ4b + Fr4t**2*ζ4t + 1/2*ζ4**2)

    ζs = CardanoRoots( aa, bb )
    ζ5 = ζs[1]
    Fr5 = mb / ζ5

    return C_T, C_P, Fr2t, Fr4t, Fr5
```

```python
def find_minus_C_P( Fr4b, Fr1, B ):
    # function created to discard the C_T when calling "compute_C_T_and_C_P"
    _, C_P, _, _, _ = compute_CT_CP_Frs( Fr4b, Fr1, B )
    return -C_P # Minus C_P to allow minimization
```

```python
fig, (ax1, ax2) = mpl.subplots(1,2, figsize=(12, 4.5) )
fig.subplots_adjust( wspace = 0.15 )

# Blockage factor
B = 0.3
sub_fig = ( 'e)', 'f)')

# define Fr1 interval and number of points
Fr1_min = 1E-3
Fr1_max = 0.3
Fr1_num = 50

Fr1_opt_vec = np.linspace( Fr1_min, Fr1_max, Fr1_num )

C_P_opt_vec  = np.zeros( Fr1_num )
C_T_opt_vec  = np.zeros( Fr1_num )
Fr2t_opt_vec  = np.zeros( Fr1_num )
Fr4b_opt_vec = np.zeros( Fr1_num )
Fr4t_opt_vec = np.zeros( Fr1_num )
Fr5_opt_vec  = np.zeros( Fr1_num )

for i, Fr1 in enumerate( Fr1_opt_vec ):

  res = minimize_scalar( find_minus_C_P, args=(Fr1, B), bounds=[0,1], method='bounded',
                         options={ 'xatol': 1e-08, 'maxiter': 500, 'disp': 1 } )
  Fr4b = res.x # optimal value

  C_T, C_P, Fr2t, Fr4t, Fr5 = compute_CT_CP_Frs( Fr4b, Fr1, B )

  C_T_opt_vec[i]  = C_T
  C_P_opt_vec[i]  = C_P
  Fr2t_opt_vec[i] = Fr2t
  Fr4b_opt_vec[i] = Fr4b
  Fr4t_opt_vec[i] = Fr4t
  Fr5_opt_vec[i]  = Fr5

ax1.plot( Fr1_opt_vec, C_P_opt_vec, label='$C_P^\mathrm{opt}$' )
ax1.plot( Fr1_opt_vec, C_T_opt_vec, dashes = (6,2), label='$C_T^\mathrm{opt}$' )
ax1.set_title( "B = %.2f" % B )
ax1.legend(loc='upper left', fontsize=14, handlelength=2.9, ncol=3)
ax1.set_xlabel("$\mathrm{Fr}_1\ [-]$")
ax1.grid()
ax1.set_ylim( (0.5,3) )
ax1.text(-0.12, 1.05, sub_fig[0], transform=ax1.transAxes, size=16, weight='semibold')

ax2.plot( Fr1_opt_vec, Fr1_opt_vec,  '-', label='$\mathrm{Fr}_{1}^\mathrm{opt}$' )
ax2.plot( Fr1_opt_vec, Fr2t_opt_vec, '-', dashes = (6,2), label='$\mathrm{Fr}_{2t}^\mathrm{opt}$' )
ax2.plot( Fr1_opt_vec, Fr4t_opt_vec, '-', dashes = (6,1.5,1.5,1.5), label='$\mathrm{Fr}_{4t}^\mathrm{opt}$' )
ax2.plot( Fr1_opt_vec, Fr4b_opt_vec, '-', dashes = (11,3), label='$\mathrm{Fr}_{4b}^\mathrm{opt}$' )
ax2.plot( Fr1_opt_vec, Fr5_opt_vec,  '-', dashes = (2,2), label='$\mathrm{Fr}_5^\mathrm{opt}$' )
ax2.set_title( "B = %.2f" % B )
ax2.legend(loc='upper left', fontsize=14, handlelength=2.9, ncol=3)
ax2.set_xlabel("$\mathrm{Fr}_1\ [-]$")
ax2.grid()
ax2.set_ylim( (0,0.5) )
ax2.text(-0.12, 1.05, sub_fig[1], transform=ax2.transAxes, size=16, weight='semibold');
mpl.savefig( 'ChannelFlow_B%4.2f.pdf' % B, bbox_inches='tight', pad_inches=0.02);
```

## **Polynomial fitting**

Fit a polynomial of the type

$$ a x^6 + b x^4 + c x^2 + d$$

to the optimal $C_T$ and $C_P$. This polynomial has only even monomial to avoid double curvature.

```python
def fitting_func( x, a, b, c, d ):
    x2 = x*x
    return ( ( ( a * x2 + b ) * x2 + c ) * x2 ) + d

C_P_popt, C_P_pcov = curve_fit( fitting_func, Fr1_opt_vec, C_P_opt_vec )
C_T_popt, C_P_pcov = curve_fit( fitting_func, Fr1_opt_vec, C_T_opt_vec )
```

## **Optimal $C_T$ and $C_P$**

```python
sFr_1, sC_P, sC_T = sp.symbols( "\mathrm{Fr}_1, C_\mathrm{P}, C_\mathrm{T}" )
eqCP = sp.Eq( sC_P, fitting_func( sFr_1, *C_P_popt ) )
sp.expand( eqCP )
```

$\displaystyle C_\mathrm{P} = 124.610074372161 \mathrm{Fr}_1^{6} - 0.0563726690419734 \mathrm{Fr}_1^{4} + 1.84400253463544 \mathrm{Fr}_1^{2} + 1.20901299576112$

```python
eqCT = sp.Eq( sC_T, fitting_func( sFr_1, *C_T_popt ) )
sp.expand( eqCT )
```

$\displaystyle C_\mathrm{T} = 880.217556741866 \mathrm{Fr}_1^{6} - 29.9116488878394 \mathrm{Fr}_1^{4} + 6.24988738923356 \mathrm{Fr}_1^{2} + 2.35514240201942$

## **Plot results of the optimization and interpolation of the maxima**

```python
fit_C_P = fitting_func( Fr1_opt_vec, *C_P_popt )
fit_C_T = fitting_func( Fr1_opt_vec, *C_T_popt )
```

```python
mpl.plot( Fr1_opt_vec, C_P_opt_vec, 'ro', label="Optimal values" )
mpl.plot( Fr1_opt_vec, fit_C_P, label="$(ax^6+bx^4+cx^2+d)$ fitting" )

mpl.title( "B = %.2f" % B )
mpl.xlabel("$\mathrm{Fr}_1$")
mpl.ylabel("$C_P^\mathrm{opt}$")
mpl.legend(loc='upper left')
mpl.grid()
```

```python
mpl.plot( Fr1_opt_vec, C_T_opt_vec, 'ro', label="Optimal values" )
mpl.plot( Fr1_opt_vec, fit_C_T, label="$(ax^6+bx^4+cx^2+d)$ fitting" )

mpl.title( "B = %.2f" % B )
mpl.xlabel("$\mathrm{Fr}_1$")
mpl.ylabel("$C_T^\mathrm{opt}$")
mpl.legend(loc='upper left')
mpl.grid()
```

```python

```


#Using python
Python is an interpreted language. This means that there is a "python program" that reads your input and excecutes it. If you open your ipython interpreter, you'll see the following message (or something very similar):

    Python 2.7.6 (default, Mar 22 2014, 22:59:56)
    Type "copyright", "credits" or "license" for more information.

    IPython 3.1.0 -- An enhanced Interactive Python.
    ?         -> Introduction and overview of IPython's features.
    %quickref -> Quick reference.
    help      -> Python's own help system.
    object?   -> Details about 'object', use 'object??' for extra details.

    In [1]:

where In [1]: is a command prompt. Whenever I write

```python
1 + 1
```

    2

I mean that the command is written in the ipython command prompt (or in the ipython notebook if you prefer to use that). There are some lines above the command prompt. These are information on the current python and ipython version and tips on how to get help. But first, let us look at some of the basic operations, addition, subtraction, multiplication, division and exponentiation. In python, these would have the symbols +, -, \*, / and \*\*. If we would like to calculate
\begin{align}
\frac{3.6\cdot 5 + (3 - 2)^{3}}{2}
\end{align}
we would write

```python
(3.6*5 + (3 - 2)**3)/2
```

    9.5

These are the most basic operation and there are several more. We wont bother about them in this text though.

## Variables
Python, as most programming languages relies on the fact that you can create something called a variable in it. This is similar to what in mathematics is called a variable and a constant. For example, we can define a variable with the name $a$ in python and let it have the value $5$ by typing

```python
a = 5
```

Python now knows that there is such a thing as $a$ which you can use to do further operations. For example, instead of writing

```python
5 + 3
```

    8

We can write

```python
a + 3
```

    8

and we get the same result. This might seem as it is not that useful, but we can use it the same way as we use constants and variables in mathematics to shorten what we have to write. For example, we may want to calculate averages of averages.

```python
b = (2.5 + 6.3)/2
c = (5.3 + 8.7)/2

(b + c)/2
```

    5.7

Without variables this would get messy and very, very soon extremely difficult.

## Objects
Just as there are different kind of objects in mathematics such as integers, reals and matrices, there are different kind of objects in python. The basic ones are integers, floats, lists, tuples and strings which will be introduced here.

### Integers

Integers behave very much like the integers in mathematics. Any operation between two integers will result in an integer, for example $5 + 2$ will result in $7$, which is an integer. Notice though that division might not always lead to a new integer, for example $\frac{5}{2}$ is not an integer. In python operations between integers always results in a new integer. Because of this, division between integers in python will drop the remainder.

```python
a = 12
a / 5
```

    2

Often, this is not what you wanted. This leads us to the next object.

### Floats
A float, or a floating point number, works very much like a real number in mathematics. The set of floats is closed under all the operations we have introduced just as the reals are. To declare a float we simply have to add a dot to the number we wish to have, like this

```python
a = 12.
```

and now, $a$ is a float instead of am integer. If we do the same operation as before, but with floats we get

```python
a / 5.
```

    2.4

Now it seems as if we only should use floats and not use integers at all because of this property. But as we will se soon the integers will play a central role in loops.

## Lists and tuples

Just as integers and floats are similar, so are lists and tuples. We will begin with lists. A list is an ordered collection of objects. The objects can be of any type, it can even contain itself! (But that is usually not very useful). A list is initiated with matching square brackets \[ and \].

```python
a = [1, 3.5, [3, 5, []], 'this is a string']
a
```

    [1, 3.5, [3, 5, []], 'this is a string']

Because a list is ordered, the objects in the list can be accessed by stating at which place they are. To access an object in the list we use the square brackets again. In python (and most otehr programming languages) counts from $0$, which means that the first object in the list has index $0$, the second has index $1$ and so on. So to access an object in a list we simply type

```python
a[2] # Accessing the third element in the list. (This is acomment and is ignored by the interpreter.)
```

    [3, 5, []]

```python
a[2][1] # We can access an objects in a list which is in a list
```

    5

```python
a[1] = 13.2 # We can change values of the objects in the list
```

```python
a[0] + a[1] + a[2][1]
```

    19.2

You can also access parts of a list like this:

```python
a[0:2] # Return a list containing the first element up to but not including the third (index 2) element
```

    [1, 13.2]

```python
a[0:2] + a[0:2] # You can put two lists together with addition.
```

    [1, 13.2, 1, 13.2]

The lengt hof a list is not fixed in python and objects can be added and removed. To do this we will use append and del.

```python
a = [] # Creating an empty list
a
```

    []

```python
a.append('bleen')
a.append([2,4.1,'grue'])
a.append(4.3)
a
```

    ['bleen', [2, 4.1, 'grue'], 4.3]

```python
del a[-1] # We can also index from the end of the list. -1 indicates the last element
a
```

    ['bleen', [2, 4.1, 'grue']]

Tuples are initialized similarly as lists and they can contain most objects the list can contain. The main difference is that the tuple does not support item assignment. What this means is that when the tuple is created its objects can not change later. Tuples are initiated with matching parentheses ( and ).

```python
a = (2, 'e', (3.4, 6.8))
a
```

    (2, 'e', (3.4, 6.8))

```python
a[0]
```

    2

```python
a[-1][-1]
```

    6.8

```python
a[1] = 0
```

Because tuples does not support item assignment, you cannot use append or del with it. Tuples ar good to use if you want to make sure that certain values stay unchanged in a program, for example a group of physical constants.

###Strings
Strings are lines of text or symbols and are initiated with doubble or single quotes. If you wish for the string to span several lines you can use triple double quotes

```python
a = 'here is a string'
a
```

    'here is a string'

```python
a = "Here's another" # Notice that we included a single quote in the string.
a
```

    "Here's another"

```python
a = """
This string
spans
several lines.
"""
a # \n means new line. They can be manually included with \n.
```

    '\nThis string\nspans\nseveral lines.\n'

```python
print a # To see \n as an actual new line we need to use print a.
```

    This string
    spans
    several lines.

Here, you saw the first occurrence of the print statement. It's functionality is much greater than prettifying string output as it can print text to the command or terminal window. One omportant functionality of the string is the format function. This function lets us create a string without knowing what it will contain beforehand.

```python
a = [1,2,3,4,5]
```

```python
str = "The sum of {} is {}".format(a, sum(a))
str
```

    'The sum of [1, 2, 3, 4, 5] is 15'

It uses curly brackets \{ and \} as placeholders for the objects in the format part. There are many other things you can do with strings, to find out use the question mark, ?, in the interpreter after the variable you want more information about. Notice that this does not work in the regular python interpreter, you have to use ipython. You can also use the help function to get help about functions and variables. It works both in the regular interpreter and in ipython.

```python
a?
```

```python
help(sum)
```

    Help on built-in function sum in module __builtin__:

    sum(...)
        sum(sequence[, start]) -> value

        Return the sum of a sequence of numbers (NOT strings) plus the value
        of parameter 'start' (which defaults to 0).  When the sequence is
        empty, return start.


```python
from IPython.core.display import display_html
from urllib.request import urlopen

display_html(urlopen('http://bit.ly/1HflmO9').read(), raw=True)
```

<link href='http://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=EB+Garamond' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Lato:100,100italic' rel='stylesheet' type='text/css'>

<style>
	@font-face{
   		font-family: "Computer Modern";
        	src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');}

	h1 {
        	font-family: 'Lato', sans-serif;}

	h2 {
        	font-family: 'Lato', serif;}

	h3{
		font-family:   'Lato', serif;
        	margin-top:    12px;
		margin-bottom: 3px;}

        h4{
		font-family: 'Lato', serif;}

	h5 {
        	font-family: 'Lato', serif;}

	div.text_cell_render{
        	font-family:  'EB Garamond', 'Computer Modern', 'Helvetica Neue', Arial, Helvetica, Geneva, sans-serif;
	        line-height:  140%;
	        font-size:    14pt;}

	.CodeMirror{
        	font-family: 'Inconsolata';}

	.text_cell_render h1 {
	        font-weight:   100;
	        font-size:     50pt;
		line-height:   100%;
	        color:         #CD2305;
	        margin-bottom: 0.5em;
	        margin-top:    0.5em;
	        display:       block;}

	.text_cell_render h2 {
        	font-weight:   100;
        	font-size:     30pt;}

	.text_cell_render h3 {
        	font-weight:   100;
        	font-size:     20pt;}

	.text_cell_render h4 {
        	font-weight:   100;
        	font-size:     16pt;}

	.text_cell_render h5 {
	        font-weight:   100;
	        font-size:     16pt;
	        color:         #CD2305;
	        font-style:    italic;
	        margin-bottom: 0.5em;
	        margin-top:    0.5em;
	        display:       block;}

	.text_cell_render h6 {
	        font-weight:   100;
	        font-size:     14pt;
	        color:         #CD2305;
	        font-style:    italic;
	        margin-bottom: 0.5em;
	        margin-top:    0.5em;
	        display:       block;}

	.warning{
	    	background-color: #fcf2f2;
	    	border-color: #dFb5b4;
	    	border-left: 5px solid #dfb5b4;
	    	padding: 0.5em;}
</style>

# Dinámica del Robot Manipulador SCARA

Se tiene un robot manipulador tipo SCARA, como el de la siguiente figura, del cual se quiere obtener sus ecuaciones de movimiento, asi como una simulación bajo cierta ley de  control.

Empezaremos obteniendo una representación simple de las posiciones de los centros de masa para los eslabones del robot.

Primero tenemos que importar las librerias de computo simbolico:

```python
from sympy import var, sin, cos, Matrix, Integer, eye, Function, Rational, exp, Symbol, I, solve, pi, trigsimp, dsolve, sinh, cosh, simplify
from sympy.physics.mechanics import mechanics_printing
mechanics_printing()
```

Y declaramos todas las constantes involucradas en este calculo simbolico:

```python
var("m1 m2 m3 J1 J2 J3 l1 l2 L1 L2 L0 t g")
```

Asi como algunas de las variables de nuestro problema:

```python
q1 = Function("q1")(t)
q2 = Function("q2")(t)
q3 = Function("q3")(t)
```

Y empezamos con el calculo de la posicion de los centros de masa de los eslabones, asi como su derivada y el cuadrado de la velocidad lineal de cada eslabon:

```python
x1 = l1*cos(q1)
y1 = l1*sin(q1)
z1 = L0
v1 = x1.diff("t")**2 + y1.diff("t")**2 + z1.diff("t")**2
v1.trigsimp()
```

```python
x2 = L1*cos(q1) + l2*cos(q1 + q2)
y2 = L1*sin(q1) + l2*sin(q1 + q2)
z2 = L0
v2 = x2.diff("t")**2 + y2.diff("t")**2 + z2.diff("t")**2
v2.trigsimp()
```

```python
x3 = L1*cos(q1) + L2*cos(q1 + q2)
y3 = L1*sin(q1) + L2*sin(q1 + q2)
z3 = L0 - q3
v3 = x3.diff("t")**2 + y3.diff("t")**2 + z3.diff("t")**2
v3.trigsimp()
```

Declaramos $\omega_i$ como la velocidad angular de cada eslabon:

```python
ω1 = q1.diff("t")
ω2 = q2.diff("t")
ω3 = 0
```

Y procedemos al calculo de la energía cinética de cada eslabon:

```python
K1 = Rational(1, 2)*m1*v1 + Rational(1, 2)*J1*ω1**2
K1
```

```python
K2 = Rational(1, 2)*m1*v2 + Rational(1, 2)*J2*ω2**2
K2
```

```python
K3 = Rational(1, 2)*m1*v3 + Rational(1, 2)*J3*ω3**2
K3
```

Calculamos tambien la energía potencial de cada eslabon:

```python
U1 = m1*g*z1
U1
```

```python
U2 = m2*g*z2
U2
```

```python
U3 = m3*g*z3
U3
```

Por lo que ya podemos calcular tanto la energía cinética de nuestro sistema como la potencial:

```python
K = K1 + K2 + K3
K
```

```python
U = U1 + U2 + U3
U
```

y el Lagrangiano queda:

```python
L = (K - U).expand().simplify()
L
```

Por lo que ahora solo tenemos que aplicar la ecuación de Euler-Lagrange para obtener las ecuaciones de movimiento del sistema:

```python
τ1 = (L.diff(q1.diff(t)).diff(t) - L.diff(q1)).simplify().expand().collect(q1.diff(t).diff(t)).collect(q2.diff(t).diff(t))
```

```python
τ2 = (L.diff(q2.diff(t)).diff(t) - L.diff(q2)).simplify().expand().collect(q1.diff(t).diff(t)).collect(q2.diff(t).diff(t))
```

```python
τ3 = (L.diff(q3.diff(t)).diff(t) - L.diff(q3)).simplify().expand().collect(q1.diff(t).diff(t)).collect(q2.diff(t).diff(t))
```

```python
τ1
```

```python
τ2
```

```python
τ3
```

Una vez que tenemos las ecuaciones de movimiento, debemos simular el comportamiento del sistema por medio de la función ```odeint```, y obtener una gráfica de la trayectoria del sistema:

```python
from scipy.integrate import odeint
from numpy import linspace
```

Para utilizar la función ```odeint```, debemos crear una función, que describa la dinámica del sistema:

```python
def scara(estado, tiempo):
    # Se importan funciones necesarias
    from numpy import sin, cos, matrix
    # Se desenvuelven variables del estado y tiempo
    q1, q2, q3, q̇1, q̇2, q̇3 = estado
    t = tiempo

    # Se declaran constantes del sistema
    m1, m2, m3 = 1, 1, 1
    J1, J2, J3 = 1, 1, 1
    l1, l2 = 0.5, 0.5
    L1, L2 = 1, 1
    L = 1
    g = 9.81

    # Se declaran constantes del control
    kp1, kp2, kp3 = -30, -60, -60
    kv1, kv2, kv3 = -20, -20, -18

    # Señales de control nulas
    #tau1, tau2, tau3 = 0, 0, 0

    # Posiciones a alcanzar
    qd1, qd2, qd3 = 1, 1, 1

    # Se declaran señales de control del sistema
    tau1 = kp1*(q1 - qd1) + kv1*q̇1
    tau2 = kp2*(q2 - qd2) + kv2*q̇2
    tau3 = kp3*(q3 - qd3) + kv3*q̇3- m3*g

    # Se calculan algunos terminos comunes
    λ1 = m1*L1*(l2 + L2)
    λ2 = m1*(l2**2 + L2**2)
    λ3 = m1*(l1**2 + L1**2)

    # Se calculan las matrices de masas, Coriolis,
    # y vectores de gravedad, control, posicion y velocidad
    M = matrix([[J1 + 2*λ1*cos(q2) + m1*L1**2 + λ2 + λ3, λ1*cos(q2) + λ2, 0],
                [λ1*cos(q2) + λ2, J2 + λ2, 0],
                [0, 0, m1]])
    C = matrix([[-2*q̇1, -q̇2, 0], [q̇1, 0, 0], [0, 0, 0]])
    G = matrix([[0], [0], [-m3*g]])
    Tau = matrix([[tau1], [tau2], [tau3]])
    q = matrix([[q1], [q2], [q3]])
    q̇ = matrix([[q̇1], [q̇2], [q̇3]])

    # Se calcula la derivada del estado del sistema
    qp1 = q̇1
    qp2 = q̇2
    qp3 = q̇3

    qpp = M.I*(Tau - C*q̇ - G)
    qpp1, qpp2, qpp3 = qpp.tolist()

    return [qp1, qp2, qp3, qpp1[0], qpp2[0], qpp3[0]]
```

Y declarar un arreglo con todos los tiempos a simular, mandar a llamar a la función ```odeint```, y listo!

```python
t = linspace(0, 10, 1000)
estados_simulados = odeint(func = scara, y0  = [0, 0, 0, 0, 0, 0], t = t)
```

Desempacamos los elementos que nos entrega ```odeint```:

```python
q1, q2, q3, q̇1, q̇2, q̇3 = list(zip(*estados_simulados.tolist()))
```

Importamos la libreria para graficar:

```python
%matplotlib notebook
from matplotlib.pyplot import plot, style, figure
from mpl_toolkits.mplot3d import Axes3D
style.use("ggplot")
```

Hacemos la grafica de las trayectorias del sistema, $q_1$, $q_2$ y $q_3$:

```python
fig1 = figure(figsize=(12, 8))

ax1 = fig1.gca()

p1, = ax1.plot(t, q1)
p2, = ax1.plot(t, q2)
p3, = ax1.plot(t, q3)
ax1.legend([p1, p2, p3],[r"$q_1$", r"$q_2$", r"$q_3$"])
ax1.set_ylim(-0.1, 1.2)
ax1.set_xlim(-0.1, 10);
```

    <IPython.core.display.Javascript object>

Realizamos la cinemática del manipulador para poder graficar en 3D:

```python
def tras_x(x):
    from numpy import matrix
    A = matrix([[1, 0, 0, x],
                [0, 1, 0, 0],
                [0, 0, 1, 0],
                [0, 0, 0, 1]])
    return A

def tras_z(z):
    from numpy import matrix
    A = matrix([[1, 0, 0, 0],
                [0, 1, 0, 0],
                [0, 0, 1, z],
                [0, 0, 0, 1]])
    return A

def rot_z(θ):
    from numpy import matrix, sin, cos
    A = matrix([[cos(θ), -sin(θ), 0, 0],
                [sin(θ), cos(θ), 0, 0],
                [0, 0, 1, 0],
                [0, 0, 0, 1]])
    return A

def cinematica_scara(q1, q2, q3, l1, l2, L):
    from numpy import matrix
    p0 = matrix([[0], [0], [0], [1]])
    p1 = tras_z(L)*p0
    p2 = rot_z(q1)*tras_x(l1)*p1
    p3 = rot_z(q2)*tras_x(l2)*p2
    p4 = tras_z(-q3)*p3

    return [[p0.tolist()[0][0], p1.tolist()[0][0], p2.tolist()[0][0], p3.tolist()[0][0], p4.tolist()[0][0]],
             [p0.tolist()[1][0], p1.tolist()[1][0], p2.tolist()[1][0], p3.tolist()[1][0], p4.tolist()[1][0]],
             [p0.tolist()[2][0], p1.tolist()[2][0], p2.tolist()[2][0], p3.tolist()[2][0], p4.tolist()[2][0]]]
```

```python
from numpy import pi
τ = 2*pi
xs, ys, zs = cinematica_scara(τ/12, τ/9, 0.5, 1, 1, 1)
```

```python
fig2 = figure(figsize=(8, 8))
ax2 = fig2.gca(projection='3d')
ax2.plot(xs, ys, zs, "-o")
ax2.set_xlim(-2, 2)
ax2.set_ylim(-2, 2)
ax2.set_zlim(0, 1.5);
```

    <IPython.core.display.Javascript object>

Cambiamos el ambiente de matplotlib, para poder graficar interactivamente, y declaramos una función que tome la cinematica del robot y grafique los puntos:

```python
%matplotlib inline
```

```python
def grafica_scara(q1, q2, q3, l1, l2, L):
    xs, ys , zs = cinematica_scara(q1, q2, q3, l1, l2, L)

    fig = figure(figsize=(8, 8))

    ax = fig.gca(projection='3d')

    ax.plot(xs, ys, zs, "-o")

    ax.set_xlim(-2, 2)
    ax.set_ylim(-2, 2)
    ax.set_zlim(0, 1.5);
```

```python
grafica_scara(τ/12, τ/9, 0.2, 1, 1, 1)
```

Importamos la libreria para interactuar con los datos y le pasamos la función que grafica:

```python
# Se importan widgets de IPython para interactuar con la funcion
from IPython.html.widgets import interact, fixed
```

    :0: FutureWarning: IPython widgets are experimental and may change in the future.

```python
# Se llama a la funcion interactiva
interact(grafica_scara, q1=(0, τ), q2=(0, τ), q3=(0, 1.0), l1=fixed(1), l2=fixed(1), L=fixed(1))
```

Para realizar una animación con los datos de la simulación primero importamos la libreria necesaria y creamos la misma grafica dentro del ambiente de animación:

```python
from matplotlib import animation
from numpy import arange
```

```python
# Se define el tamaño de la figura
fig = figure(figsize=(8, 8))

# Se define una sola grafica en la figura y se dan los limites de los ejes x y y
axi = fig.add_subplot(111, autoscale_on=False, xlim=(-2, 2), ylim=(-2, 2), projection='3d')

# Se utilizan graficas de linea para el resorte y amortiguador
robot, = axi.plot([], [], [], "-o", lw=2)

def init():
    # Esta funcion se ejecuta una sola vez y sirve para inicializar el sistema
    robot.set_data([], [])
    return robot

def animate(i):
    # Esta funcion se ejecuta para cada cuadro del GIF

    # Se obtienen las coordenadas del robot y se meten los datos en su grafica de linea
    xs, ys, zs = cinematica_scara(q1[i], q2[i], q3[i], 1, 1, 1)
    robot.set_data(xs, ys)
    robot .set_3d_properties(zs)

    return robot

# Se hace la animacion dandole el nombre de la figura definida al principio, la funcion que
# se debe ejecutar para cada cuadro, el numero de cuadros que se debe de hacer, el periodo
# de cada cuadro y la funcion inicial
ani = animation.FuncAnimation(fig, animate, arange(1, len(q1)), interval=25,
                              blit=True, init_func=init)

# Se guarda el GIF en el archivo indicado
ani.save('./imagenes/simulacion-scara.gif', writer='imagemagick');
```


# States

A Riemann Problem is specified by the state of the material to the left and right of the interface. In this hydrodynamic problem, the state is fully determined by an [equation of state](eos_defns.html) and the variables

$$
  {\bf U} = \begin{pmatrix} \rho_0 \\ v_x \\ v_t \\ \epsilon \end{pmatrix},
$$

where $\rho_0$ is the rest-mass density, $v_x$ the velocity normal to the interface, $v_t$ the velocity tangential to the interface, and $\epsilon$ the specific internal energy.

## Defining a state

In `r3d2` we define a state from an equation of state and the values of the key variables:

```python
from r3d2 import eos_defns, State
```

```python
eos = eos_defns.eos_gamma_law(5.0/3.0)
U = State(1.0, 0.1, 0.0, 2.0, eos)
```

Inside the notebook, the state will automatically display the values of the key variables:

```python
U
```

\begin{equation}\begin{pmatrix} \rho \\ v_x \\ v_t \\ \epsilon \end{pmatrix}= \begin{pmatrix} 1.0000 \\ 0.1000 \\ 0.0000 \\ 2.0000 \end{pmatrix}\end{equation}

Adding a label to the state for output purposes requires an extra keyword:

```python
U2 = State(10.0, -0.3, 0.1, 5.0, eos, label="L")
U2
```

\begin{equation}\begin{pmatrix} \rho \\ v_x \\ v_t \\ \epsilon \end{pmatrix}_{L} = \begin{pmatrix} 10.0000 \\ -0.3000 \\ 0.1000 \\ 5.0000 \end{pmatrix}\end{equation}

## Reactive states

If the state has energy available for reactions, that information is built into the equation of state. The definition of the equation of state changes: the definition of the state itself does not:

```python
q_available = 0.1
t_ignition = 10.0
Cv = 1.0
eos_reactive = eos_defns.eos_gamma_law_react(5.0/3.0, q_available, Cv, t_ignition, eos)
U_reactive = State(5.0, 0.1, 0.1, 2.0, eos_reactive, label="Reactive")
U_reactive
```

\begin{equation}\begin{pmatrix} \rho \\ v_x \\ v_t \\ \epsilon \\ q \end{pmatrix}_{Reactive} = \begin{pmatrix} 5.0000 \\ 0.1000 \\ 0.1000 \\ 2.0000 \\ 0.1000 \end{pmatrix}\end{equation}

## Additional functions

A state knows its own wavespeeds. Given a wavenumber (the left acoustic wave is `0`, the middle contact or advective wave is `1`, and the right acoustic wave is `2`), we have:

```python
print("Left wavespeed of first state is {}".format(U.wavespeed(0)))
print("Middle wavespeed of second state is {}".format(U2.wavespeed(1)))
print("Right wavespeed of reactive state is {}".format(U.wavespeed(2)))
```

    Left wavespeed of first state is -0.6636390537799616
    Middle wavespeed of second state is -0.3
    Right wavespeed of reactive state is 0.7615771981098584

A state will return the key *primitive* variables ($\rho, v_x, v_t, \epsilon$):

```python
print("Primitive variables of first state are {}".format(U.prim()))
```

    Primitive variables of first state are [1.  0.1 0.  2. ]

A state will return all the variables it computes, which is $\rho, v_x, v_t, \epsilon, p, W, h, c_s$: the primitive variables as above, the pressure $p$, Lorentz factor $W$, specific enthalpy $h$, and speed of sound $c_s$:

```python
print("All variables of second state are {}".format(U.state()))
```

    All variables of second state are [1.         0.1        0.         2.         1.33333333 1.00503782
     4.33333333 0.71611487]