public mcpdreport(mcpd.mcpdreport obj) { _innerobj = obj; }
public mcpdreport() { _innerobj = new mcpd.mcpdreport(); }
/************************************************************************* Test bound constraints. On failure sets Err to True (leaves it unchanged otherwise) *************************************************************************/ private static void testlc(ref bool err) { int n = 0; double[,] p = new double[0,0]; double[,] c = new double[0,0]; double[,] xy = new double[0,0]; int[] ct = new int[0]; int entrystate = 0; int exitstate = 0; int entrykind = 0; int exitkind = 0; int i = 0; int j = 0; int k = 0; int t = 0; int jc = 0; double v = 0; double threshold = 0; mcpd.mcpdstate s = new mcpd.mcpdstate(); mcpd.mcpdreport rep = new mcpd.mcpdreport(); threshold = 1.0E5*math.machineepsilon; // // We try different problems with following properties: // * N is large enough - we won't have problems with inconsistent constraints // * first state is either "entry" or "normal" // * last state is either "exit" or "normal" // * we have one long random track // // We test several properties which are described in comments below // for(n=4; n<=6; n++) { for(entrykind=0; entrykind<=1; entrykind++) { for(exitkind=0; exitkind<=1; exitkind++) { // // Prepare problem // if( entrykind==0 ) { entrystate = -1; } else { entrystate = 0; } if( exitkind==0 ) { exitstate = -1; } else { exitstate = n-1; } xy = new double[2*n, n]; for(i=0; i<=ap.rows(xy)-1; i++) { for(j=0; j<=ap.cols(xy)-1; j++) { xy[i,j] = math.randomreal(); } } // // Test that single linear equality/inequality constraint // on non-entry non-exit elements of P is satisfied. // // NOTE 1: this test needs N>=4 because smaller values // can give us inconsistent constraints // NOTE 2: Constraints are generated is such a way that P=(1/N ... 1/N) // is always feasible. It guarantees that there always exists // at least one feasible point // NOTE 3: If we have inequality constraint, we "shift" right part // in order to make feasible some neighborhood of P=(1/N ... 1/N). // ap.assert(n>=4, "TestLC: expectation failed"); c = new double[1, n*n+1]; ct = new int[1]; v = 0; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { if( ((i==0 | i==n-1) | j==0) | j==n-1 ) { c[0,i*n+j] = 0; } else { c[0,i*n+j] = math.randomreal(); v = v+c[0,i*n+j]*((double)1/(double)n); } } } c[0,n*n] = v; ct[0] = math.randominteger(3)-1; if( ct[0]<0 ) { c[0,n*n] = c[0,n*n]+0.1; } if( ct[0]>0 ) { c[0,n*n] = c[0,n*n]-0.1; } createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdsetlc(s, c, ct, 1); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); if( rep.terminationtype>0 ) { v = 0; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { v = v+p[i,j]*c[0,i*n+j]; } } if( ct[0]<0 ) { err = err | (double)(v)>=(double)(c[0,n*n]+threshold); } if( ct[0]==0 ) { err = err | (double)(Math.Abs(v-c[0,n*n]))>=(double)(threshold); } if( ct[0]>0 ) { err = err | (double)(v)<=(double)(c[0,n*n]-threshold); } } else { err = true; } // // Test interaction with default "sum-to-one" constraint // on columns of P. // // We set linear constraint which has for "sum-to-X" on // on random non-exit column of P. This constraint can be // either consistent (X=1.0) or inconsistent (X<>1.0) with // this default constraint. // // Algorithm must detect inconsistency. // // NOTE: // 1. this test needs N>=2 // ap.assert(n>=2, "TestLC: expectation failed"); jc = math.randominteger(n-1); c = new double[1, n*n+1]; ct = new int[1]; for(i=0; i<=n*n-1; i++) { c[0,i] = 0.0; } for(i=0; i<=n-1; i++) { c[0,n*i+jc] = 1.0; } c[0,n*n] = 1.0; ct[0] = 0; createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdsetlc(s, c, ct, 1); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype<=0; c[0,n*n] = 2.0; createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdsetlc(s, c, ct, 1); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype!=-3; // // Test interaction with constrains on entry states. // // When model has entry state, corresponding row of P // must be zero. We try to set two kinds of constraints // on elements of this row: // * sums-to-zero constraint, which must be consistent // * sums-to-one constraint, which must be inconsistent // if( entrystate>=0 ) { c = new double[1, n*n+1]; ct = new int[1]; for(i=0; i<=n*n-1; i++) { c[0,i] = 0.0; } for(j=0; j<=n-1; j++) { c[0,n*entrystate+j] = 1.0; } ct[0] = 0; c[0,n*n] = 0.0; createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdsetlc(s, c, ct, 1); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype<=0; c[0,n*n] = 1.0; createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdsetlc(s, c, ct, 1); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype!=-3; } // // Test interaction with constrains on exit states. // // When model has exit state, corresponding column of P // must be zero. We try to set two kinds of constraints // on elements of this column: // * sums-to-zero constraint, which must be consistent // * sums-to-one constraint, which must be inconsistent // if( exitstate>=0 ) { c = new double[1, n*n+1]; ct = new int[1]; for(i=0; i<=n*n-1; i++) { c[0,i] = 0.0; } for(i=0; i<=n-1; i++) { c[0,n*i+exitstate] = 1.0; } ct[0] = 0; c[0,n*n] = 0.0; createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdsetlc(s, c, ct, 1); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype<=0; c[0,n*n] = 1.0; createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdsetlc(s, c, ct, 1); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype!=-3; } } } } // // Final test - we generate several random constraints and // test SetLC() function. // // NOTES: // // 1. Constraints are generated is such a way that P=(1/N ... 1/N) // is always feasible. It guarantees that there always exists // at least one feasible point // 2. For simplicity of the test we do not use entry/exit states // in our model // for(n=1; n<=4; n++) { for(k=1; k<=2*n; k++) { // // Generate track // xy = new double[2*n, n]; for(i=0; i<=ap.rows(xy)-1; i++) { for(j=0; j<=ap.cols(xy)-1; j++) { xy[i,j] = math.randomreal(); } } // // Generate random constraints // c = new double[k, n*n+1]; ct = new int[k]; for(i=0; i<=k-1; i++) { // // Generate constraint and its right part // c[i,n*n] = 0; for(j=0; j<=n*n-1; j++) { c[i,j] = 2*math.randomreal()-1; c[i,n*n] = c[i,n*n]+c[i,j]*((double)1/(double)n); } ct[i] = math.randominteger(3)-1; // // If we have inequality constraint, we "shift" right part // in order to make feasible some neighborhood of P=(1/N ... 1/N). // if( ct[i]<0 ) { c[i,n*n] = c[i,n*n]+0.1; } if( ct[i]>0 ) { c[i,n*n] = c[i,n*n]-0.1; } } // // Test // createee(n, -1, -1, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdsetlc(s, c, ct, k); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); if( rep.terminationtype>0 ) { for(t=0; t<=k-1; t++) { v = 0; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { v = v+p[i,j]*c[t,i*n+j]; } } if( ct[t]<0 ) { err = err | (double)(v)>=(double)(c[t,n*n]+threshold); } if( ct[t]==0 ) { err = err | (double)(Math.Abs(v-c[t,n*n]))>=(double)(threshold); } if( ct[t]>0 ) { err = err | (double)(v)<=(double)(c[t,n*n]-threshold); } } } else { err = true; } } } }
/************************************************************************* Test bound constraints. On failure sets Err to True (leaves it unchanged otherwise) *************************************************************************/ private static void testbc(ref bool err) { int n = 0; double[,] p = new double[0,0]; double[,] bndl = new double[0,0]; double[,] bndu = new double[0,0]; double[,] xy = new double[0,0]; int entrystate = 0; int exitstate = 0; int entrykind = 0; int exitkind = 0; int i = 0; int j = 0; int ic = 0; int jc = 0; double vl = 0; double vu = 0; mcpd.mcpdstate s = new mcpd.mcpdstate(); mcpd.mcpdreport rep = new mcpd.mcpdreport(); // // We try different problems with following properties: // * N is large enough - we won't have problems with inconsistent constraints // * first state is either "entry" or "normal" // * last state is either "exit" or "normal" // * we have one long random track // // We test several properties which are described in comments below // for(n=4; n<=6; n++) { for(entrykind=0; entrykind<=1; entrykind++) { for(exitkind=0; exitkind<=1; exitkind++) { // // Prepare problem // if( entrykind==0 ) { entrystate = -1; } else { entrystate = 0; } if( exitkind==0 ) { exitstate = -1; } else { exitstate = n-1; } xy = new double[2*n, n]; for(i=0; i<=ap.rows(xy)-1; i++) { for(j=0; j<=ap.cols(xy)-1; j++) { xy[i,j] = math.randomreal(); } } // // Test that single bound constraint on non-entry // non-exit elements of P is satisfied. // // NOTE 1: this test needs N>=4 because smaller values // can give us inconsistent constraints // ap.assert(n>=4, "TestBC: expectation failed"); ic = 1+math.randominteger(n-2); jc = 1+math.randominteger(n-2); if( (double)(math.randomreal())>(double)(0.5) ) { vl = 0.3*math.randomreal(); } else { vl = Double.NegativeInfinity; } if( (double)(math.randomreal())>(double)(0.5) ) { vu = 0.5+0.3*math.randomreal(); } else { vu = Double.PositiveInfinity; } createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdaddbc(s, ic, jc, vl, vu); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); if( rep.terminationtype>0 ) { err = err | (double)(p[ic,jc])<(double)(vl); err = err | (double)(p[ic,jc])>(double)(vu); } else { err = true; } // // Test interaction with default "sum-to-one" constraint // on columns of P. // // We set N-1 bound constraints on random non-exit column // of P, which are inconsistent with this default constraint // (sum will be greater that 1.0). // // Algorithm must detect inconsistency. // // NOTE: // 1. we do not set constraints for the first element of // the column, because this element may be constrained by // "exit state" constraint. // 2. this test needs N>=3 // ap.assert(n>=3, "TestEC: expectation failed"); jc = math.randominteger(n-1); vl = 0.85; vu = 0.95; createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); for(i=1; i<=n-1; i++) { mcpd.mcpdaddbc(s, i, jc, vl, vu); } mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype!=-3; // // Test interaction with constrains on entry states. // // When model has entry state, corresponding row of P // must be zero. We try to set two kinds of constraints // on random element of this row: // * bound constraint with zero lower bound, which must be consistent // * bound constraint with non-zero lower bound, which must be inconsistent // if( entrystate>=0 ) { jc = math.randominteger(n); createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdaddbc(s, entrystate, jc, 0.0, 1.0); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype<=0; createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdaddbc(s, entrystate, jc, 0.5, 1.0); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype!=-3; } // // Test interaction with constrains on exit states. // // When model has exit state, corresponding column of P // must be zero. We try to set two kinds of constraints // on random element of this column: // * bound constraint with zero lower bound, which must be consistent // * bound constraint with non-zero lower bound, which must be inconsistent // if( exitstate>=0 ) { ic = math.randominteger(n); createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdaddbc(s, ic, exitstate, 0.0, 1.0); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype<=0; createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdaddbc(s, ic, exitstate, 0.5, 1.0); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); err = err | rep.terminationtype!=-3; } // // Test SetBC() call - we constrain subset of non-entry // non-exit elements and test it. // ap.assert(n>=4, "TestBC: expectation failed"); bndl = new double[n, n]; bndu = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { bndl[i,j] = Double.NegativeInfinity; bndu[i,j] = Double.PositiveInfinity; } } for(j=1; j<=n-2; j++) { i = 1+math.randominteger(n-2); bndl[i,j] = 0.5-0.1*math.randomreal(); bndu[i,j] = 0.5+0.1*math.randomreal(); } createee(n, entrystate, exitstate, s); mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); mcpd.mcpdsetbc(s, bndl, bndu); mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); if( rep.terminationtype>0 ) { for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { err = err | (double)(p[i,j])<(double)(bndl[i,j]); err = err | (double)(p[i,j])>(double)(bndu[i,j]); } } } else { err = true; } } } } }
/************************************************************************* Test for different combinations of "entry"/"exit" models On failure sets Err to True (leaves it unchanged otherwise) *************************************************************************/ private static void testentryexit(ref bool err) { int n = 0; double[,] p = new double[0,0]; double[,] pexact = new double[0,0]; double[,] xy = new double[0,0]; double threshold = 0; int entrystate = 0; int exitstate = 0; int entrykind = 0; int exitkind = 0; int popkind = 0; int i = 0; int j = 0; int k = 0; double v = 0; mcpd.mcpdstate s = new mcpd.mcpdstate(); mcpd.mcpdreport rep = new mcpd.mcpdreport(); int i_ = 0; threshold = 1.0E-3; // // // for(n=2; n<=5; n++) { for(entrykind=0; entrykind<=1; entrykind++) { for(exitkind=0; exitkind<=1; exitkind++) { for(popkind=0; popkind<=1; popkind++) { // // Generate EntryState/ExitState such that one of the following is True: // * EntryState<>ExitState // * EntryState=-1 or ExitState=-1 // do { if( entrykind==0 ) { entrystate = -1; } else { entrystate = math.randominteger(n); } if( exitkind==0 ) { exitstate = -1; } else { exitstate = math.randominteger(n); } } while( !((entrystate==-1 | exitstate==-1) | entrystate!=exitstate) ); // // Generate transition matrix P such that: // * columns corresponding to non-exit states sums to 1.0 // * columns corresponding to exit states sums to 0.0 // * rows corresponding to entry states are zero // pexact = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { pexact[i,j] = 1+math.randominteger(5); if( i==entrystate ) { pexact[i,j] = 0.0; } if( j==exitstate ) { pexact[i,j] = 0.0; } } } for(j=0; j<=n-1; j++) { v = 0.0; for(i=0; i<=n-1; i++) { v = v+pexact[i,j]; } if( (double)(v)!=(double)(0) ) { for(i=0; i<=n-1; i++) { pexact[i,j] = pexact[i,j]/v; } } } // // Create MCPD solver // if( entrystate<0 & exitstate<0 ) { mcpd.mcpdcreate(n, s); } if( entrystate>=0 & exitstate<0 ) { mcpd.mcpdcreateentry(n, entrystate, s); } if( entrystate<0 & exitstate>=0 ) { mcpd.mcpdcreateexit(n, exitstate, s); } if( entrystate>=0 & exitstate>=0 ) { mcpd.mcpdcreateentryexit(n, entrystate, exitstate, s); } // // Add N tracks. // // K-th track starts from vector with large value of // K-th component and small random noise in other components. // // Track contains from 2 to 4 elements. // // Tracks contain proportional (normalized) or // population data, depending on PopKind variable. // for(k=0; k<=n-1; k++) { // // Generate track whose length is in 2..4 // xy = new double[2+math.randominteger(3), n]; for(j=0; j<=n-1; j++) { xy[0,j] = 0.05*math.randomreal(); } xy[0,k] = 1+math.randomreal(); for(i=1; i<=ap.rows(xy)-1; i++) { for(j=0; j<=n-1; j++) { if( j!=entrystate ) { v = 0.0; for(i_=0; i_<=n-1;i_++) { v += pexact[j,i_]*xy[i-1,i_]; } xy[i,j] = v; } else { xy[i,j] = math.randomreal(); } } } // // Normalize, if needed // if( popkind==1 ) { for(i=0; i<=ap.rows(xy)-1; i++) { v = 0.0; for(j=0; j<=n-1; j++) { v = v+xy[i,j]; } if( (double)(v)>(double)(0) ) { for(j=0; j<=n-1; j++) { xy[i,j] = xy[i,j]/v; } } } } // // Add track // mcpd.mcpdaddtrack(s, xy, ap.rows(xy)); } // // Solve and test // mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); if( rep.terminationtype>0 ) { for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { err = err | (double)(Math.Abs(p[i,j]-pexact[i,j]))>(double)(threshold); } } } else { err = true; } } } } } }
/************************************************************************* Simple test with no "entry"/"exit" states On failure sets Err to True (leaves it unchanged otherwise) *************************************************************************/ private static void testsimple(ref bool err) { int n = 0; double[,] pexact = new double[0,0]; double[,] xy = new double[0,0]; double threshold = 0; int i = 0; int j = 0; double v = 0; double v0 = 0; double[,] p = new double[0,0]; mcpd.mcpdstate s = new mcpd.mcpdstate(); mcpd.mcpdreport rep = new mcpd.mcpdreport(); double offdiagonal = 0; threshold = 1.0E-2; // // First test: // * N-dimensional problem // * proportional data // * no "entry"/"exit" states // * N tracks, each includes only two states // * first record in I-th track is [0 ... 1 ... 0] with 1 is in I-th position // * all tracks are modelled using randomly generated transition matrix P // for(n=1; n<=5; n++) { // // Initialize "exact" P: // * fill by random values // * make sure that each column sums to non-zero value // * normalize // pexact = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { pexact[i,j] = math.randomreal(); } } for(j=0; j<=n-1; j++) { i = math.randominteger(n); pexact[i,j] = pexact[i,j]+0.1; } for(j=0; j<=n-1; j++) { v = 0; for(i=0; i<=n-1; i++) { v = v+pexact[i,j]; } for(i=0; i<=n-1; i++) { pexact[i,j] = pexact[i,j]/v; } } // // Initialize solver: // * create object // * add tracks // mcpd.mcpdcreate(n, s); for(i=0; i<=n-1; i++) { xy = new double[2, n]; for(j=0; j<=n-1; j++) { xy[0,j] = 0; } xy[0,i] = 1; for(j=0; j<=n-1; j++) { xy[1,j] = pexact[j,i]; } mcpd.mcpdaddtrack(s, xy, 2); } // // Solve and test // mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); if( rep.terminationtype>0 ) { for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { err = err | (double)(Math.Abs(p[i,j]-pexact[i,j]))>(double)(threshold); } } } else { err = true; } } // // Second test: // * N-dimensional problem // * proportional data // * no "entry"/"exit" states // * N tracks, each includes only two states // * first record in I-th track is [0 ...0.1 0.8 0.1 ... 0] with 0.8 is in I-th position // * all tracks are modelled using randomly generated transition matrix P // offdiagonal = 0.1; for(n=1; n<=5; n++) { // // Initialize "exact" P: // * fill by random values // * make sure that each column sums to non-zero value // * normalize // pexact = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { pexact[i,j] = math.randomreal(); } } for(j=0; j<=n-1; j++) { i = math.randominteger(n); pexact[i,j] = pexact[i,j]+0.1; } for(j=0; j<=n-1; j++) { v = 0; for(i=0; i<=n-1; i++) { v = v+pexact[i,j]; } for(i=0; i<=n-1; i++) { pexact[i,j] = pexact[i,j]/v; } } // // Initialize solver: // * create object // * add tracks // mcpd.mcpdcreate(n, s); for(i=0; i<=n-1; i++) { xy = new double[2, n]; for(j=0; j<=n-1; j++) { xy[0,j] = 0; } // // "main" element // xy[0,i] = 1.0-2*offdiagonal; for(j=0; j<=n-1; j++) { xy[1,j] = (1.0-2*offdiagonal)*pexact[j,i]; } // // off-diagonal ones // if( i>0 ) { xy[0,i-1] = offdiagonal; for(j=0; j<=n-1; j++) { xy[1,j] = xy[1,j]+offdiagonal*pexact[j,i-1]; } } if( i<n-1 ) { xy[0,i+1] = offdiagonal; for(j=0; j<=n-1; j++) { xy[1,j] = xy[1,j]+offdiagonal*pexact[j,i+1]; } } mcpd.mcpdaddtrack(s, xy, 2); } // // Solve and test // mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); if( rep.terminationtype>0 ) { for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { err = err | (double)(Math.Abs(p[i,j]-pexact[i,j]))>(double)(threshold); } } } else { err = true; } } // // Third test: // * N-dimensional problem // * population data // * no "entry"/"exit" states // * N tracks, each includes only two states // * first record in I-th track is V*[0 ...0.1 0.8 0.1 ... 0] with 0.8 is in I-th position, V in [1,10] // * all tracks are modelled using randomly generated transition matrix P // offdiagonal = 0.1; for(n=1; n<=5; n++) { // // Initialize "exact" P: // * fill by random values // * make sure that each column sums to non-zero value // * normalize // pexact = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { pexact[i,j] = math.randomreal(); } } for(j=0; j<=n-1; j++) { i = math.randominteger(n); pexact[i,j] = pexact[i,j]+0.1; } for(j=0; j<=n-1; j++) { v = 0; for(i=0; i<=n-1; i++) { v = v+pexact[i,j]; } for(i=0; i<=n-1; i++) { pexact[i,j] = pexact[i,j]/v; } } // // Initialize solver: // * create object // * add tracks // mcpd.mcpdcreate(n, s); for(i=0; i<=n-1; i++) { xy = new double[2, n]; for(j=0; j<=n-1; j++) { xy[0,j] = 0; } // // "main" element // v0 = 9*math.randomreal()+1; xy[0,i] = v0*(1.0-2*offdiagonal); for(j=0; j<=n-1; j++) { xy[1,j] = v0*(1.0-2*offdiagonal)*pexact[j,i]; } // // off-diagonal ones // if( i>0 ) { xy[0,i-1] = v0*offdiagonal; for(j=0; j<=n-1; j++) { xy[1,j] = xy[1,j]+v0*offdiagonal*pexact[j,i-1]; } } if( i<n-1 ) { xy[0,i+1] = v0*offdiagonal; for(j=0; j<=n-1; j++) { xy[1,j] = xy[1,j]+v0*offdiagonal*pexact[j,i+1]; } } mcpd.mcpdaddtrack(s, xy, 2); } // // Solve and test // mcpd.mcpdsolve(s); mcpd.mcpdresults(s, ref p, rep); if( rep.terminationtype>0 ) { for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { err = err | (double)(Math.Abs(p[i,j]-pexact[i,j]))>(double)(threshold); } } } else { err = true; } } }