How to call the same index in each of 2 dimensions in a GAMS variable? - indexing

I am running a model in GAMS with a number of variables with 2 dimensions, calling the indexes i and j respectively. I have a few constraints relating to just the "diagonal" entries, so I coded them something like "d(i,i)", but GAMS gives error 171 when I do this, for example the first error comes on equation e3. How do I express this in GAMS? Code follows:
Set
i 'Origin' / 1*20 /
j 'Destination' / 1*20 /;
Table A(i,j)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 0 4 2 574 481 440 408 633 573 1066 486 1926 1537 183 334 374 107 509 378 499
2 4 0 2 573 480 438 412 632 572 1064 484 1924 1535 182 332 372 111 508 377 498
3 3 2 0 572 479 437 411 631 571 1063 484 1923 1534 181 332 371 109 507 376 497
4 574 572 572 0 93 249 135 1188 1128 1620 1040 2480 2091 737 888 928 683 498 367 488
5 481 480 479 93 0 156 228 1095 1035 1527 948 2387 1998 645 796 836 591 406 275 396
6 440 438 437 249 156 0 384 1053 993 1485 906 2345 1956 603 754 794 549 364 233 354
7 409 412 411 135 228 384 0 1044 984 1476 897 2336 1947 594 745 785 302 633 502 623
8 633 632 631 1188 1095 1053 1044 0 532 1024 623 1246 792 450 300 403 742 560 992 668
9 573 572 571 1128 1035 993 984 532 0 494 326 879 424 392 385 207 682 1063 932 1053
10 1066 1064 1063 1620 1527 1485 1476 1024 494 0 820 1979 823 885 878 699 1175 1555 1424 1545
11 486 484 484 1040 948 906 897 623 326 820 0 724 270 359 477 223 595 975 844 966
12 1926 1924 1923 2480 2387 2345 2336 1246 878 1979 724 0 454 1943 1099 846 2035 2415 2284 2405
13 1537 1535 1534 2091 1998 1956 1947 792 424 823 270 454 0 1554 645 392 1646 2026 1895 2016
14 183 182 181 738 645 603 594 450 392 884 359 1943 1554 0 151 192 292 672 542 663
15 334 332 332 888 796 754 745 300 385 878 477 1099 645 151 0 257 443 261 692 369
16 373 372 371 928 835 793 784 403 207 699 223 846 392 192 256 0 482 863 732 853
17 107 111 109 683 591 549 302 742 683 1175 595 2035 1646 292 443 483 0 618 487 608
18 509 507 507 498 406 364 633 560 1063 1555 975 2415 2026 672 261 863 618 0 134 180
19 378 377 376 367 275 233 502 992 932 1424 844 2284 1895 542 692 732 487 134 0 122
20 500 498 497 489 396 354 624 668 1053 1545 966 2405 2016 663 369 854 609 180 122 0
;
Positive variable c(i,j) 'cost direct';
Positive variable cstar(i,j) 'cost routing';
Positive variable z 'objective';
Binary variable d(i,j) 'decision direct';
Binary variable dstar(i,j) 'decision routing';
Binary variable p(i,j) 'd(i,i)*dstar(i,j)';
Binary variable q(i,j) 'd(i,j)*p(i,j)';
Binary variable x(i,j) 'd(j,j)*dstar(i,j)';
Binary variable y(i,j) 'd(i,j)*x(i,j)';
Binary variable f(i,j) 'd(i,i)*d(j,j)';
Binary variable g(i,j) 'f(i,j)*dstar(i,j)';
Integer variable h(i) 'd(i,i)*u(i)';
Integer variable k(i,j) 'd(i,i)*u(j)';
Integer variable m(i,j) 'f(i,j)*u(i)';
Integer variable u(i) 'ordering of tours';
Equation
e1
e2(i,j)
e3
e4(j)
e5(i,j)
e6(i,j)
e7(i)
e8(j)
e9(i)
e10(i,j)
e11(i,j)
e12(i,j)
e13(i,j)
e14(i,j)
e15(i,j)
e16(i,j)
e17(i,j)
e18(i,j)
e19(i,j)
e20(i,j)
e21(i,j)
e22(i,j)
e23(i,j)
e24(i,j)
e25(i,j)
e26(i,j)
e27(i,j)
e28(i)
e29(i)
e30(i)
e31(i,j)
e32(i,j)
e33(i,j)
e34(i,j)
e35(i,j)
e36(i,j)
e37(i,j)
e38(i,j)
e39(i)
e40(i)
e41(i)
e42(i)
e43(i,j)
e44(i,j)
e45(i,j)
e46(i,j)
e47(i,j)
e48(i,j)
e49(i,j)
e50(i,j)
e51(i,j);
e1 .. z =e= sum((i,j),c(i,j))+sum((i,j),cstar(i,j));
e2(i,j) .. c(i,j) =e= A(i,j)*d(i,j);
e3 .. sum((i),d(i,i)) =e= 2;
e4(j) .. sum((i),d(i,j)) =e= 1;
e5(i,j) .. d(i,j)-d(i,i) =l= 0;
e6(i,j) .. cstar(i,j) =e= A(i,j)*dstar(i,j);
e7(i) .. dstar(i,i) =e= 0;
e8(j) .. sum((i),dstar(i,j)) =e= 1;
e9(i) .. sum((j),dstar(i,j)) =e= 1;
e10(i,j) .. p(i,j) =l= d(i,i);
e11(i,j) .. p(i,j) =l= dstar(i,j);
e12(i,j) .. p(i,j) =g= d(i,i)+dstar(i,j)-1;
e13(i,j) .. p(i,j) =g= 0;
e14(i,j) .. q(i,j) =l= d(i,j);
e15(i,j) .. q(i,j) =l= p(i,j);
e16(i,j) .. q(i,j) =g= d(i,j)+p(i,j)-1;
e17(i,j) .. q(i,j) =g= 0;
e18(i,j) .. p(i,j)-q(i,j) =e= 0;
e19(i,j) .. x(i,j) =l= d(j,j);
e20(i,j) .. x(i,j) =l= dstar(i,j);
e21(i,j) .. x(i,j) =g= d(j,j)+dstar(i,j)-1;
e22(i,j) .. x(i,j) =g= 0;
e23(i,j) .. y(i,j) =l= d(i,j);
e24(i,j) .. y(i,j) =l= x(i,j);
e25(i,j) .. y(i,j) =g= d(i,j)+x(i,j)-1;
e26(i,j) .. y(i,j) =g= 0;
e27(i,j) .. x(i,j)-y(i,j) =e= 0;
e28(i) .. u(i) =l= 20;
e29(i) .. 1000*(1-d(i,i)) =g= u(i)-1;
e30(i) .. 2-d(i,i) =l= u(i);
e31(i,j) .. f(i,j) =l= d(i,i);
e32(i,j) .. f(i,j) =l= dstar(j,j);
e33(i,j) .. f(i,j) =g= d(i,i)+dstar(j,j)-1;
e34(i,j) .. f(i,j) =g= 0;
e35(i,j) .. g(i,j) =l= f(i,j);
e36(i,j) .. g(i,j) =l= dstar(i,j);
e37(i,j) .. g(i,j) =g= f(i,j)+dtar(i,j)-1;
e38(i,j) .. g(i,j) =g= 0;
e39(i) .. 0 =l= h(i);
e40(i) .. h(i) =l= 1000*d(i,i);
e41(i) .. u(i)-1000*(1-d(i,i)) =l= h(i);
e42(i) .. h(i) =l= u(i);
e43(i,j) .. 0 =l= k(i,j);
e44(i,j) .. k(i,j) =l= 1000*d(i,i);
e45(i,j) .. u(j)-1000*(1-d(i,i)) =l= k(i,j);
e46(i,j) .. k(i,j) =l= u(j);
e47(i,j) .. 0 =l= m(i,j);
e48(i,j) .. m(i,j) =l= 1000*f(i,j);
e49(i,j) .. u(i)-1000*(1-f(i,j)) =l= m(i,j);
e50(i,j) .. m(i,j) =l= u(i);
e51(i,j) .. u(i)-u(j)+1-h(i)+k(i,j)-d(i,i)-k(j,i)+h(j)-d(j,j)-m(i,j)+m(j,i)-f(i,j) =l= 19*(1-d(i,i)-d(j,j)-f(i,j)-dstar(i,j)+p(i,j)+x(i,j)+g(i,j));
Model transport / all /;
solve transport using mip minimizing z;
display d.l, dstar.l;

The problem is, that you declared d (and other symbols) with domain (i,j) but try to access it as (i,i). Therefore, you get a domain violation since you declared i and j as different sets. Is that really wanted? Or are they really the same (i.e., is each origin also a destination)? Looking at table A that seems to be the case. So, instead of declaring j as a new set, you should define it as Alias to j. The start of your model would look like this then:
Set
i 'Origin' / 1*20 /;
Alias(i,j);
The rest stays the same.

Related

Using beautifulsoup to extract information within pre, turning it into a table to csv

I am trying to extract the text from the below site shown within the code.
While I can print the list fine, I can't seem to turn it into a pandas dataframe, and print it out as a csv.
This is a site that only has the pre info.
Please let me know if there is way to do this.
import requests
from bs4 import BeautifulSoup
#url list for the new stations
url1="https://www.kyoshin.bosai.go.jp/cgi-bin/kyoshin/db/sitedat.cgi?1+NIG010+knet"
tt1="C:/temp/"
page = requests.get(url1)
soup = BeautifulSoup(page.content, 'html.parser')
print(soup)
N-Value P,S-Velocity Density Soil Column
(m/s) (g/cm^3)
----------------------------------------------------------------------------------
1m 13 1351 93 1.43 0m - 1m Fl
2m 9 1351 105 1.77 1m - 7.75m S
3m 11 1389 102 1.86 7.75m - 15.15m S
4m 7 1408 104 1.83 15.15m - 16.75m S
5m 20 1429 120 1.74 16.75m - 19.3m SF
6m 20 1481 121 1.89 19.3m - 22.75m SF
7m 24 1538 143 1.97 22.75m - 25.7m M
8m 53 1550 189 1.87 25.7m - 33.44m S
9m 52 1550 233 1.85
10m 47 1504 222 1.93
11m 43 1493 206 1.9
12m 38 1504 222 1.89
13m 27 1492 213 1.84
14m 44 1492 213 1.9
15m 62 1527 235 1.89
16m 46 1504 189 1.92
17m 22 1481 165 1.87
18m 26 1471 147 1.86
19m 24 1493 202 1.82
20m 21 1493 198 1.87
Not the most robust, but you can iterate line by line to parse the data you need:
import requests
import pandas as pd
from io import StringIO
#url list for the new stations
url1="https://www.kyoshin.bosai.go.jp/cgi-bin/kyoshin/db/sitedat.cgi?1+NIG010+knet"
tt1="C:/temp/"
page = requests.get(url1)
s=str(page.content,'utf-8')
df = pd.DataFrame()
for lineNum, line in enumerate(s.splitlines()):
if lineNum == 0:
headers = line.split()
elif lineNum == 1:
unit1, unit2 = line.split()
elif lineNum == 2:
continue
else:
row = line.split()
idx = row[0]
nval = row[1]
ps = row[2] + ' ' + row[3]
den = row[4]
try:
soil = '%s %s %s' %(row[5], row[6], row[7])
col = row[8]
except Exception as e:
print(e)
soil = ''
col = ''
temp_df = pd.DataFrame([[idx, nval, ps, den, soil, col]],
columns = ['Index',headers[0], headers[1] + ' ' + unit1, headers[2] + ' ' + unit2, headers[3], headers[4]])
df = df.append(temp_df, sort=False).reset_index(drop=True)
df.to_csv('file.csv',index=False)
Output:
print (df)
Index N-Value P,S-Velocity (m/s) Density (g/cm^3) Soil Column
0 1m 13 1351 93 1.43 0m - 1m Fl
1 2m 9 1351 105 1.77 1m - 7.75m S
2 3m 11 1389 102 1.86 7.75m - 15.15m S
3 4m 7 1408 104 1.83 15.15m - 16.75m S
4 5m 20 1429 120 1.74 16.75m - 19.3m SF
5 6m 20 1481 121 1.89 19.3m - 22.75m SF
6 7m 24 1538 143 1.97 22.75m - 25.7m M
7 8m 53 1550 189 1.87 25.7m - 33.44m S
8 9m 52 1550 233 1.85
9 10m 47 1504 222 1.93
10 11m 43 1493 206 1.9
11 12m 38 1504 222 1.89
12 13m 27 1492 213 1.84
13 14m 44 1492 213 1.9
14 15m 62 1527 235 1.89
15 16m 46 1504 189 1.92
16 17m 22 1481 165 1.87
17 18m 26 1471 147 1.86
18 19m 24 1493 202 1.82
19 20m 21 1493 198 1.87

create new column from divided columns over iteration

I am working with the following code:
url = 'https://raw.githubusercontent.com/dothemathonthatone/maps/master/fertility.csv'
df = pd.read_csv(url)
year regional_schlüssel Aus15 Deu15 Aus16 Deu16 Aus17 Deu17 Aus18 Deu18 ... aus36 aus37 aus38 aus39 aus40 aus41 aus42 aus43 aus44 aus45
0 2000 5111000 0 4 8 25 20 45 56 89 ... 935 862 746 732 792 660 687 663 623 722
1 2000 5113000 1 1 4 14 13 33 19 48 ... 614 602 498 461 521 470 393 411 397 400
2 2000 5114000 0 11 0 5 2 13 7 20 ... 317 278 265 235 259 228 204 173 213 192
3 2000 5116000 0 2 2 7 3 28 13 26 ... 264 217 206 207 197 177 171 146 181 169
4 2000 5117000 0 0 3 1 2 4 4 7 ... 135 129 118 116 128 148 89 110 124 83
I would like to create a new set of columns fertility_deu15, ..., fertility_deu45 and fertility_aus15, ..., fertility_aus45 such that aus15 / Aus15 = fertiltiy_aus15 and deu15/ Deu15 = fertility_deu15 for each ausi and Ausj where j == i \n [15-45] and deui:Deuj where j == i \n [15-45]
I'm not sure what is up with that data but we need to fix it to make it numeric. I'll end up doing that while filtering
numerator = df.filter(regex='^[a-z]+\d+$') # Lower case ones
numerator = numerator.apply(pd.to_numeric, errors='coerce') # Fix numbers
denominator = df.filter(regex='^[A-Z][a-z]+\d+$').rename(columns=str.lower)
denominator = denominator.apply(pd.to_numeric, errors='coerce')
numerator.div(denominator).add_prefix('fertility_')

Taking the last two rows' minimum value

I have this data frame:
ID Date X 123_Var 456_Var 789_Var
A 16-07-19 3 777 250 810
A 17-07-19 9 637 121 529
A 18-07-19 7 878 786 406
A 19-07-19 4 656 140 204
A 20-07-19 2 295 272 490
A 21-07-19 3 778 600 544
A 22-07-19 6 741 792 907
B 01-07-19 4 509 690 406
B 02-07-19 2 732 915 199
B 03-07-19 2 413 725 414
B 04-07-19 2 170 702 912
B 09-08-19 3 851 616 477
B 10-08-19 9 475 447 555
B 11-08-19 1 412 403 708
B 12-08-19 2 299 537 321
B 13-08-19 4 310 119 125
C 01-12-18 4 912 755 657
C 02-12-18 4 586 771 394
C 04-12-18 9 498 122 193
C 05-12-18 2 500 528 764
C 06-12-18 1 982 383 654
C 07-12-18 1 299 496 488
C 08-12-18 3 336 691 496
C 09-12-18 3 206 433 263
C 10-12-18 2 373 319 111
I want to show the minimum value between current row and previous row values, for each column in 123_Var 456_Var 789_Var set.
That should be applied separately for each ID. (Groupby.)
The first row of each ID, will show the current value. (Since there's no "previous" value to compare.)
Expected result:
ID Date X 123_Var 456_Var 789_Var 123_Min2 456_Min2 789_Min2
A 16-07-19 3 777 250 810 777 250 810
A 17-07-19 9 637 121 529 637 121 529
A 18-07-19 7 878 786 406 637 121 406
A 19-07-19 4 656 140 204 656 140 204
A 20-07-19 2 295 272 490 295 140 204
A 21-07-19 3 778 600 544 295 272 490
A 22-07-19 6 741 792 907 741 600 544
B 01-07-19 4 509 690 406 509 690 406
B 02-07-19 2 732 915 199 509 690 199
B 03-07-19 2 413 725 414 413 725 199
B 04-07-19 2 170 702 912 170 702 414
B 09-08-19 3 851 616 477 170 616 477
B 10-08-19 9 475 447 555 475 447 477
B 11-08-19 1 412 403 708 412 403 555
B 12-08-19 2 299 537 321 299 403 321
B 13-08-19 4 310 119 125 299 119 125
C 01-12-18 4 912 755 657 912 755 657
C 02-12-18 4 586 771 394 586 755 394
C 04-12-18 9 498 122 193 498 122 193
C 05-12-18 2 500 528 764 498 122 193
C 06-12-18 1 982 383 654 500 383 654
C 07-12-18 1 299 496 488 299 383 488
C 08-12-18 3 336 691 496 299 496 488
C 09-12-18 3 206 433 263 206 433 263
C 10-12-18 2 373 319 111 206 319 111
IIUC, We use groupby.shift to select the previous var for each ID, then we can use DataFrame.where
to leave only the cells where the previous value is lower than the current value and fill with the current value in the rest. We use DataFrame.add_suffix to add _Min2 and we join with df with DataFrame.join
df_vars = df[['123_Var','456_Var','789_Var']]
df = df.join(df.groupby('ID')['123_Var','456_Var','789_Var']
.shift()
.fillna(df_vars)
.where(lambda x: x.le(df_vars),df_vars)
.add_suffix('_Min2')
)
print(df)
Output
ID Date X 123_Var 456_Var 789_Var 123_Var_Min2 456_Var_Min2 789_Var_Min2
0 A 16-07-19 3 777 250 810 777.0 250.0 810.0
1 A 17-07-19 9 637 121 529 637.0 121.0 529.0
2 A 18-07-19 7 878 786 406 637.0 121.0 406.0
3 A 19-07-19 4 656 140 204 656.0 140.0 204.0
4 A 20-07-19 2 295 272 490 295.0 140.0 204.0
5 A 21-07-19 3 778 600 544 295.0 272.0 490.0
6 A 22-07-19 6 741 792 907 741.0 600.0 544.0
7 B 01-07-19 4 509 690 406 509.0 690.0 406.0
8 B 02-07-19 2 732 915 199 509.0 690.0 199.0
9 B 03-07-19 2 413 725 414 413.0 725.0 199.0
10 B 04-07-19 2 170 702 912 170.0 702.0 414.0
11 B 09-08-19 3 851 616 477 170.0 616.0 477.0
12 B 10-08-19 9 475 447 555 475.0 447.0 477.0
13 B 11-08-19 1 412 403 708 412.0 403.0 555.0
14 B 12-08-19 2 299 537 321 299.0 403.0 321.0
15 B 13-08-19 4 310 119 125 299.0 119.0 125.0
16 C 01-12-18 4 912 755 657 912.0 755.0 657.0
17 C 02-12-18 4 586 771 394 586.0 755.0 394.0
18 C 04-12-18 9 498 122 193 498.0 122.0 193.0
19 C 05-12-18 2 500 528 764 498.0 122.0 193.0
20 C 06-12-18 1 982 383 654 500.0 383.0 654.0
21 C 07-12-18 1 299 496 488 299.0 383.0 488.0
22 C 08-12-18 3 336 691 496 299.0 496.0 488.0
23 C 09-12-18 3 206 433 263 206.0 433.0 263.0
24 C 10-12-18 2 373 319 111 206.0 319.0 111.0
Case 2: If you want check the n previous use groupby.rolling
df_vars = df[['123_Var','456_Var','789_Var']]
n = 3
df = df.join(df.groupby('ID')['123_Var','456_Var','789_Var']
.rolling(n,min_periods = 1).min()
.reset_index(drop=True)
.add_suffix(f'_Min{n}')
)
print(df)
ID Date X 123_Var 456_Var 789_Var 123_Var_Min3 456_Var_Min3 789_Var_Min3
0 A 16-07-19 3 777 250 810 777.0 250.0 810.0
1 A 17-07-19 9 637 121 529 637.0 121.0 529.0
2 A 18-07-19 7 878 786 406 637.0 121.0 406.0
3 A 19-07-19 4 656 140 204 637.0 121.0 204.0
4 A 20-07-19 2 295 272 490 295.0 121.0 204.0
5 A 21-07-19 3 778 600 544 295.0 140.0 204.0
6 A 22-07-19 6 741 792 907 295.0 140.0 204.0
7 B 01-07-19 4 509 690 406 509.0 690.0 406.0
8 B 02-07-19 2 732 915 199 509.0 690.0 199.0
9 B 03-07-19 2 413 725 414 413.0 690.0 199.0
10 B 04-07-19 2 170 702 912 170.0 690.0 199.0
11 B 09-08-19 3 851 616 477 170.0 616.0 199.0
12 B 10-08-19 9 475 447 555 170.0 447.0 414.0
13 B 11-08-19 1 412 403 708 170.0 403.0 477.0
14 B 12-08-19 2 299 537 321 299.0 403.0 321.0
15 B 13-08-19 4 310 119 125 299.0 119.0 125.0
16 C 01-12-18 4 912 755 657 912.0 755.0 657.0
17 C 02-12-18 4 586 771 394 586.0 755.0 394.0
18 C 04-12-18 9 498 122 193 498.0 122.0 193.0
19 C 05-12-18 2 500 528 764 498.0 122.0 193.0
20 C 06-12-18 1 982 383 654 498.0 122.0 193.0
21 C 07-12-18 1 299 496 488 299.0 122.0 193.0
22 C 08-12-18 3 336 691 496 299.0 383.0 488.0
23 C 09-12-18 3 206 433 263 206.0 383.0 263.0
24 C 10-12-18 2 373 319 111 206.0 319.0 111.0
A quite elegant solution is to apply rolling(2).min() to each group,
but to avoid the first row of NaN in each group, this first row
should be "replicated" from the source group.
To do your task, start from defining the following function:
def fnMin2(grp):
rv = pd.concat([pd.DataFrame([grp.iloc[0, -3:]]),
grp[['123_Var', '456_Var', '789_Var']].rolling(2).min().iloc[1:]])\
.astype('int')
rv.columns = [ it.replace('Var', 'Min2') for it in rv.columns ]
return grp.join(rv)
Then apply it to each group:
df.groupby('ID').apply(fnMin2)
Note that column names assigned to new columns in my solution are
just as you wish, contrary to the solution you accepted.
#this compares the next row to the previous row
ext = df.iloc[:,3:].gt(df.iloc[:,3:].shift(1))
#simply renamed the columns here
ext.columns=['123_min','456_min','789_min']
#join the two dataframes by columns
M = pd.concat([df,ext],axis=1)
#based on the conditions, if it is False,
#use value from current row,
#else use value from previous row
M['123_min']=np.where(M['123_min']==0,
M['123_Var'],
M['123_Var'].shift(1)
)
M['456_min']=np.where(M['456_min']==0,
M['456_Var'],
M['456_Var'].shift(1)
)
M['789_min']=np.where(M['789_min']==0,
M['789_Var'],
M['789_Var'].shift(1)
)

MPI_sendrecv changes loop index with -O1 flag [duplicate]

This question already has an answer here:
MPI_Recv overwrites parts of memory it should not access
(1 answer)
Closed 7 years ago.
Despite having written long, heavily parallelized codes with complicated send/receives over three dimensional arrays, this simple code with a two dimensional array of integers has got me at my wits end. I combed stackoverflow for possible solutions and found one that resembled slightly with the issue I am having:
Boost.MPI: What's received isn't what was sent!
However the solutions seem to point the looping segment of code as the culprit for overwriting sections of the memory. But this one seems to act even stranger. Maybe it is a careless oversight of some simple detail on my part. The problem is with the below code:
program main
implicit none
include 'mpif.h'
integer :: i, j
integer :: counter, offset
integer :: rank, ierr, stVal
integer, dimension(10, 10) :: passMat, prntMat !! passMat CONTAINS VALUES TO BE PASSED TO prntMat
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
counter = 0
offset = (rank + 1)*300
do j = 1, 10
do i = 1, 10
prntMat(i, j) = 10 !! prntMat OF BOTH RANKS CONTAIN 10
passMat(i, j) = offset + counter !! passMat OF rank=0 CONTAINS 300..399 AND rank=1 CONTAINS 600..699
counter = counter + 1
end do
end do
if (rank == 1) then
call MPI_SEND(passMat(1:10, 1:10), 100, MPI_INTEGER, 0, 1, MPI_COMM_WORLD, ierr) !! SEND passMat OF rank=1 to rank=0
else
call MPI_RECV(prntMat(1:10, 1:10), 100, MPI_INTEGER, 1, 1, MPI_COMM_WORLD, stVal, ierr)
do i = 1, 10
print *, prntMat(:, i)
end do
end if
call MPI_FINALIZE(ierr)
end program main
When I compile the code with mpif90 with no flags and run it on my machine with mpirun -np 2, I get the following output with wrong values in the first four indices of the array:
0 0 400 0 604 605 606 607 608 609
610 611 612 613 614 615 616 617 618 619
620 621 622 623 624 625 626 627 628 629
630 631 632 633 634 635 636 637 638 639
640 641 642 643 644 645 646 647 648 649
650 651 652 653 654 655 656 657 658 659
660 661 662 663 664 665 666 667 668 669
670 671 672 673 674 675 676 677 678 679
680 681 682 683 684 685 686 687 688 689
690 691 692 693 694 695 696 697 698 699
However, when I compile it with the same compiler but with the -O3 flag on, I get the correct output:
600 601 602 603 604 605 606 607 608 609
610 611 612 613 614 615 616 617 618 619
620 621 622 623 624 625 626 627 628 629
630 631 632 633 634 635 636 637 638 639
640 641 642 643 644 645 646 647 648 649
650 651 652 653 654 655 656 657 658 659
660 661 662 663 664 665 666 667 668 669
670 671 672 673 674 675 676 677 678 679
680 681 682 683 684 685 686 687 688 689
690 691 692 693 694 695 696 697 698 699
This error is machine dependent. This issue turns up only on my system running Ubuntu 14.04.2, using OpenMPI 1.6.5
I tried this on other systems running RedHat and CentOS and the code ran well with and without the -O3 flag. Curiously those machines use an older version of OpenMPI - 1.4
I am guessing that the -O3 flag is performing some odd optimization that is modifying the manner in which arrays are being passed between the processes.
I also tried other versions of array allocation. The above code uses explicit shape arrays. With assumed shape and allocated arrays I am receiving equally, if not more bizarre results, with some of them seg-faulting. I tried using Valgrind to trace the origin of these seg-faults, but I still haven't gotten the hang of getting Valgrind to not give false positives when running with MPI programs.
I believe that resolving the difference in performance of the above code will help me understand the tantrums of my other codes as well.
Any help would be greatly appreciated! This code has really gotten me questioning if all the other MPI codes I wrote are sound at all.
Using the Fortran 90 interface to MPI reveals a mismatch in your call to MPI_RECV
call MPI_RECV(prntMat(1:10, 1:10), 100, MPI_INTEGER, 1, 1, MPI_COMM_WORLD, stVal, ierr)
1
Error: There is no specific subroutine for the generic ‘mpi_recv’ at (1)
This is because the status variable stVal is an integer scalar, rather than an array of MPI_STATUS_SIZE. The F77 interface (include 'mpif.h') to MPI_RECV is:
INCLUDE ’mpif.h’
MPI_RECV(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, STATUS, IERROR)
<type> BUF(*)
INTEGER COUNT, DATATYPE, SOURCE, TAG, COMM
INTEGER STATUS(MPI_STATUS_SIZE), IERROR
Changing
integer :: rank, ierr, stVal
to
integer :: rank, ierr, stVal(mpi_status_size)
produces a program that works as expected, tested with gfortran 5.1 and OpenMPI 1.8.5.
Using the F90 interface (use mpi vs include "mpif.h") lets the compiler detect the mismatched arguments at compile time rather than producing confusing runtime problems.

Syntax error with AMPL

I get syntax error while running this script in AMPL. Can someone help me to solve this?
param K;
param N;
param PT;
param beta_lower{1..K};
param beta_upper{1..K};
set KSET := {1 . . K};
set NSET := {1 . . N};
param Channel {KSET,NSET};
var V
var C {KSET, NSET} binary;
#==================================
data;
param K:=2;
param N:=64;
param PT:= 1;
param beta_lower:= 1 1.99 2 3.99;
param beta_upper:= 1 2.01 2 4.01;
param Channel : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 :=
1 1366 1474 1583 1690 1790 1881 1963 2036 2101 2161 2217 2268 2315 2355 2385 2402 2403 2386 2350 2295 2223 2137 2041 1939 1835 1734 1639 1553 1479 1419 1375 1347 1335 1339 1357 1386 1421 1459 1494 1523 1542 1548 1540 1520 1490 1451 1409 1364 1321 1279 1239 1201 1164 1127 1092 1060 1034 1016 1012 1024 1055 1107 1178 1265
2 1297 1281 1250 1201 1135 1055 963 867 772 685 611 555 519 504 510 536 579 636 702 775 851 928 1002 1074 1143 1209 1276 1345 1420 1503 1596 1698 1808 1921 2033 2137 2225 2290 2327 2333 2309 2256 2180 2089 1989 1890 1796 1712 1641 1582 1533 1493 1458 1425 1393 1364 1337 1314 1298 1289 1288 1292 1297 1301;
I write this piece of code in tex file (.rtf) and upload this to neos-server
The output from the solver is:
amplin, line 7 (offset 54):
syntax error
context: >>> {\ <<< rtf1\ansi\ansicpg1252\cocoartf12processing commands.
Executing on neos-2.neos-server.org
Error (2) in /opt/ampl/ampl -R amplin
The problem is that you mix syntax for AMPL model and data in your code. In particular, you should first declare parameter beta_lower in the model:
param beta_lower{1..K}; # you may want a different indexing expression here
and then provide data for it in the data section:
data;
param beta_lower:= 1 1.99 2 3.99;
Your updated formulation looks correct, but the error indicates that it is in RTF format. To make it work you should convert it into plain text.