I wrote an optimization model of a paper with imaginary data in AMPL but there is some problem in running in terms of one of constraints about Years - ampl

All you need explain in question title. The mentioned Optimization model belong to a paper with same content but I tried to write the code and analyze what happen exactly through that. I will add the codes to have access to data and find out what is the problem when you are running that. I added the three segment of AMPL code down. Please help me with this.
MOD:
set O;
set J;
set Q;
set R; #use R instead of K because we have K in line 11 as parameter
set T;
param D {q in Q, t in T};
param K {o in O, q in Q};
param C {q in Q, j in J};
param S {r in R, q in Q};
param H {r in R, q in Q};
param F {q in Q};
param G {q in Q};
param B {q in Q};
param Delta;
param Omega;
param I;
param A;
param M;
var X {o in O, q in Q, j in J, t in T} binary;
var Z {o in O, q in Q, t in T} binary;
var P {q in Q, t in T} binary;
var Y {q in Q, t in T} binary;
var z {q in Q, t in T} binary;
var n {q in Q, t in T} integer >=0;
var m {q in Q, t in T} integer >=0;
var N {q in Q, t in T} integer >=0;
var Teta {q in Q, t in T} integer >=0;
var a {r in R, q in Q, t in T} integer >=0;
var b {r in R, q in Q, t in T} integer >=0;
var u binary;
var v binary;
var w binary;
minimize OF: sum {q in Q, j in J, o in O, t in T} C[q, j] * D[q, t] * X[o, q, j, t]
+ sum {o in O, q in Q, t in T} K[o, q] * Z[o, q, t]
+ sum {q in Q , t in T} N[q, t] * Delta
+ sum {t in T, q in Q} Omega * Teta[q, t]
+ sum {t in T, r in R, q in Q} S[r, q] * a[r, q, t]
+ sum {t in T, r in R, q in Q} H[r, q] * b[r, q, t]
+ sum {t in T, q in Q} F[q] * z[q, t]
+ sum {t in T, q in Q} G[q] * Y[q, t]
+ sum {t in T, q in Q} B[q] * P[q, t]
+ I * v + A * u;
subject to c1{q in Q , t in T}: sum {o in O} Z[o, q, t] = D[q, t];
subject to c2{o in O , q in Q , t in T}: sum {j in J} X[o, q, j, t] >= Z[o, q, t];
subject to c3{q in Q , t in T}: n[q, t]= n[q, t-1] + sum {r in R} a[r, q, t-1] + N[q, t] - sum {r in R} a[q, r, t-1];
subject to c4{q in Q , t in T}: m[q, t]= m[q, t-1] + sum {r in R} b[r, q, t-1] + Teta[q, t] - sum {r in R} b[q, r, t-1];
subject to c5{o in O , q in Q , t in T}: Z[o, q, t]<= n[q, t];
subject to c6{q in Q , t in T}: sum {o in O} X[o, q, 1, t]<= m[q, t];
subject to c7{t in T, r in R}: sum {q in Q} a[q, r, t]<= sum{q in Q} n[q, t-1]+ a[r, r, t];
subject to c8{r in R , t in T}: sum {q in Q} b[q, r, t]<= sum{q in Q} m[q, t-1]+ b[r, r, t];
subject to c91{o in O , q in Q , t in T}: X[o, q, 2, t-1]<= X[o, q, 2, t];
subject to c92{o in O , q in Q , t in T}: X[o, q, 3, t-1]<= X[o, q, 3, t];
subject to c10{q in Q , t in T}: sum {o in O} X[o, q, 2, t]- sum {o in O} X[o, q, 2, t-1]<= z[q, t];
subject to c11{q in Q , t in T}: sum {o in O} X[o, q, 3, t]- sum {o in O} X[o, q, 3, t-1]<= P[q, t];
subject to c12{q in Q , t in T , j in J}: X[3, q, j, t]- X[3, q, j, t-1]<= Y[q, t];
subject to c13: sum {t in T, q in Q} Z[4, q, t]<= M * u;
subject to c14: sum {t in T, q in Q} Z[5, q, t]<= M * v;
subject to c15{o in O , q in Q , t in T}: X[o, q, 1, t]<= M * (w-1);
subject to c16{q in Q , t in T}: Z[3, q, t]<= M * w;
subject to c17{q in Q , t in T}: Z[2, q, t]<= X[2, q, 1, t];
DATA:
set O := Treat1 Treat2 Treat3 Treat4 Treat5;
set J := Dewater1 Dewater2 Dewater3;
set Q := ArcticBay Arviat CambridgeBay CapeDorse ClydeRiver GjoaHaven;
set R := ArcticBay Arviat CambridgeBay CapeDorse ClydeRiver GjoaHaven; #use R instead of K because we have K in line 15 as parameter
set T := Year1 Year2 Year3 Year4 Year5;
param D :
Year1 Year2 Year3 Year4 Year5 :=
ArcticBay 0 1 0 1 0
Arviat 1 0 0 1 1
CambridgeBay 1 0 0 1 1
CapeDorse 1 0 1 1 1
ClydeRiver 1 1 0 1 0
GjoaHaven 0 0 1 0 1 ;
param K :
ArcticBay Arviat CambridgeBay CapeDorse ClydeRiver GjoaHaven :=
Treat1 4051 4221 6477 5205 6443 4088
Treat2 6758 4012 4994 5437 6215 6267
Treat3 5162 4051 6755 6742 6589 4139
Treat4 6556 5094 5963 6043 5745 5428
Treat5 5289 6050 5144 4456 6474 4432 ;
param C :
Dewater1 Dewater2 Dewater3 :=
ArcticBay 56299 32825 11894
Arviat 5977 15550 5958
CambridgeBay 20654 28654 19782
CapeDorse 3073 35237 33822
ClydeRiver 19218 48466 34032
GjoaHaven 23650 23304 42540 ;
param S :
ArcticBay Arviat CambridgeBay CapeDorse ClydeRiver GjoaHaven :=
ArcticBay 0 1359 1480 1458 1728 849
Arviat 2863 0 1229 1873 2353 2731
CambridgeBay 1821 1972 0 1772 1680 2726
CapeDorse 2754 2219 1817 0 1266 2814
ClydeRiver 1216 2632 2527 2782 0 949
GjoaHaven 1229 1238 2605 1060 2673 0;
param H :
ArcticBay Arviat CambridgeBay CapeDorse ClydeRiver GjoaHaven :=
ArcticBay 0 2269 1497 1218 2290 2344
Arviat 1424 0 1123 2494 2107 1114
CambridgeBay 2452 2365 0 1924 1292 1722
CapeDorse 1799 2003 2071 0 1216 1150
ClydeRiver 1322 1097 1827 1259 0 1191
GjoaHaven 1163 1444 2085 2398 1308 0;
param F :=
ArcticBay 1981
Arviat 1845
CambridgeBay 1529
CapeDorse 1721
ClydeRiver 1778
GjoaHaven 1802;
param G :=
ArcticBay 8639
Arviat 8829
CambridgeBay 11737
CapeDorse 8167
ClydeRiver 8573
GjoaHaven 10890;
param B :=
ArcticBay 6427
Arviat 9508
CambridgeBay 6661
CapeDorse 8016
ClydeRiver 6196
GjoaHaven 8359;
param Delta := 15000;
param Omega := 12000;
param I := 20000;
param A := 17000;
param M := 100000000;
RUN:
reset;
option solver CPLEX;
model SM.mod;
data SM.dat;
solve;
display X, Z, P, Y, z, n, m, N, Teta, a, b, u, v, w>b.out;

You got an error on constraint collection c3 because you are trying to do aritmetic calculations with values of set T, when in fact set T contains only strings (Year1, Year2, etc).
For instance, you wrote n[q, t-1], where t is in T. But what is 'Year1'-1 is not a valid AMPL expression. Other constraint collections have the same problem.
You could simply change the data of set T to be 1 2 3 4 5. But then you would run into other problems, because 1-1 is 0, and n[q,0] does not exist. You have to work on your formulation.
View project on PIFOP

Related

A suspicious Isomorphism proof

So I have created two representations of integers:
data ZZ : Type where
PZ : Nat -> ZZ
Zero : ZZ
NZ : Nat -> ZZ
-- Represent an integer as a difference of two Nats.
data NatNat = NN Nat Nat
and two conversion functions:
toNatNat : ZZ -> NatNat
toNatNat (PZ k) = NN (S k) Z
toNatNat Zero = NN Z Z
toNatNat (NZ k) = NN Z (S k)
toZZ : NatNat -> ZZ
toZZ (NN pos neg) with (cmp pos neg)
toZZ (NN (n + S d) n) | CmpGT d = PZ d
toZZ (NN z z) | CmpEQ = Zero
toZZ (NN p (p + S d)) | CmpLT d = NZ d
Please note, that PZ Z represents +1, and not 0.
Now I prove that these representations are isomorphic:
import Control.Isomorphism
toNatNatToZZId : (z : NatNat) -> toNatNat (toZZ z) = z
toNatNatToZZId (NN k j) with (cmp k j)
toNatNatToZZId (NN (S d) Z) | CmpGT d = Refl
toNatNatToZZId (NN Z Z) | CmpEQ = Refl
toNatNatToZZId (NN Z (S d)) | CmpLT d = Refl
toZZToNatNatId : (z : ZZ) -> toZZ (toNatNat z) = z
toZZToNatNatId (PZ k) = Refl
toZZToNatNatId Zero = Refl
toZZToNatNatId (NZ k) = Refl
zzIsoNatNat : Iso ZZ NatNat
zzIsoNatNat = MkIso toNatNat toZZ toNatNatToZZId toZZToNatNatId
and to my astonishment Idris politely nods in agreement.
So admittedly this is exactly what I wanted, although I feel a bit uneasy with the fact that I can now prove NN 0 3 = NN 6 9:
*Data/Verified/Z> the (NN 0 3 = NN 6 9) $ toNatNatToZZId (NN 6 9)
with block in Data.Verified.Z.toNatNatToZZId 6 9 (CmpGT 2) : NN 0 3 = NN 6 9
This doesn't seem right. After all, NN 0 3 is not structurally identical to NN 6 9. So where exactly Idris got convinced that they're the same? Is this an intended behaviour (I can imagine it is) and if so, how exactly does this work?
Your proof for toNatNatToZZId is not total, you only covered some specific cases. If you put %default total in the Idris file, the typechecker rejects the definition. Of course, there is no total definition for toNatNatToZZId, because as you observed it is not true.

Idris Type mismatch that occurs even from template

Testing out an "easy" example of identity types, mod equality, but transitivity proof wont type check, even from the template. More than a fix, I want to know why?
Here's a snippet of the minimal problem
data ModEq : (n:Nat) -> (x:Nat) -> (y:Nat) -> Type where
{- 3 constructors
reflexive: x == x (mod n),
left-induct: x == y (mod n) => (x+n) == y (mod n)
right-induct: x == y (mod n) => x == (y+n) (mod n)
-}
Reflex : (x:Nat) -> ModEq n x x --- Needs syntatic sugar, for now prefix
LInd : (ModEq n x y) -> ModEq n (x+n) y
RInd : (ModEq n x y) -> ModEq n x (y+n)
{----- Proof of transitive property. -----}
total
isTrans : (ModEq n x y) -> (ModEq n y z) -> (ModEq n x z)
{- x=x & x=y => x=y -}
isTrans (Reflex x) v = v
isTrans u (Reflex y) = u
{- ((x=y=>(x+n)=y) & y=z) => x=y & y=z => x=z (induct) => (x+n)=z -}
isTrans (LInd u) v = LInd (isTrans u v)
isTrans u (RInd v) = RInd (isTrans u v)
{- (x=y=>x=(y+n)) & (y=z=>(y+n)=z) => x=y & y=z => x=z (induct) -}
isTrans (RInd u) (LInd v) = isTrans u v
The type mismatch is in the last line, even though from the comment line I really cannot tell why logically its wrong. Here's the error:
48 | isTrans (RInd u) (LInd v) = isTrans u v
| ~~~~~~~
When checking left hand side of isTrans:
When checking an application of Main.isTrans:
Type mismatch between
ModEq n (x + n) z (Type of LInd v)
and
ModEq n (y + n) z (Expected type)
Specifically:
Type mismatch between
plus x n
and
plus y n
Not only am I confused by how LInd v got assigned the (wrong seeming) type ModEq n (x+n) z, but I point out that when I simply try the "type-define-refine" approach with the built in template I get:
isTrans : (ModEq n x y) -> (ModEq n y z) -> (ModEq n x z)
isTrans (RInd _) (LInd _) = ?isTrans_rhs_1
And even this wont type-check, it complains:
40 | isTrans (RInd _) (LInd _) = ?isTrans_rhs_1
| ~~~~~~~
When checking left hand side of isTrans:
When checking an application of Main.isTrans:
Type mismatch between
ModEq n (x + n) z (Type of LInd _)
and
ModEq n (y + n) z (Expected type)
Specifically:
Type mismatch between
plus x n
and
plus y n
The issue is that the compiler isn't able to deduce in your last case that y = {x + n}. You can give it this hint, though:
isTrans : (ModEq n x y) -> (ModEq n y z) -> (ModEq n x z)
isTrans (Reflex _) v = v
isTrans u (Reflex _) = u
isTrans (LInd u) v = LInd $ isTrans u v
isTrans u (RInd v) = RInd $ isTrans u v
isTrans (RInd u) (LInd v) {n} {x} {y = x + n} = ?isTrans_rhs
Which gives you the following goal for isTrans_rhs:
x : Nat
n : Nat
u : ModEq n x x
z : Nat
v : ModEq n x z
--------------------------------------
isTrans_rhs : ModEq n x z
and thus, you can conclude with isTrans (RInd u) (LInd v) {n} {x} {y = x + n} = v

Proving equality of types depending on (further) proofs

Suppose we'd like to have a "proper" minus on Nats, requiring m <= n for n `minus` m to make sense:
%hide minus
minus : (n, m : Nat) -> { auto prf : m `LTE` n } -> Nat
minus { prf = LTEZero } n Z = n
minus { prf = LTESucc prevPrf } (S n) (S m) = minus n m
Now let's try to prove the following lemma, stating that (n + (1 + m)) - k = ((1 + n) + m) - k, assuming both sides are valid:
minusPlusTossS : (n, m, k : Nat) ->
{ auto prf1 : k `LTE` n + S m } ->
{ auto prf2 : k `LTE` S n + m } ->
minus (n + S m) k = minus (S n + m) k
The goal suggests the following sublemma might help:
plusTossS : (n, m : Nat) -> n + S m = S n + m
plusTossS Z m = Refl
plusTossS (S n) m = cong $ plusTossS n m
so we try to use it:
minusPlusTossS n m k =
let tossPrf = plusTossS n m
in rewrite tossPrf in ?rhs
And here we fail:
When checking right hand side of minusPlusTossS with expected type
minus (n + S m) k = minus (S n + m) k
When checking argument prf to function Main.minus:
Type mismatch between
LTE k (S n + m) (Type of prf2)
and
LTE k replaced (Expected type)
Specifically:
Type mismatch between
S (plus n m)
and
replaced
If I understand this error correctly, it just means that it tries to rewrite the RHS of the target equality (which is minus { prf = prf2 } (S n + m) k) to minus { prf = prf2 } (n + S m) k and fails. Rightfully, of course, since prf is a proof for a different inequality! And while replace could be used to produce a proof of (S n + m) k (or prf1 would do as well), it does not look like it's possible to simultaneously rewrite and change the proof object so that it matches the rewrite.
How do I work around this? Or, more generally, how do I prove this lemma?
Ok, I guess I solved it. Bottom line: if you don't know what to do, do a lemma!
So we have a proof of two minuends n1, n2 being equal, and we need to produce a proof of n1 `minus` m = n2 `minus` m. Let's write this down!
minusReflLeft : { n1, n2, m : Nat } -> (prf : n1 = n2) -> (prf_n1 : m `LTE` n1) -> (prf_n2 : m `LTE` n2) -> n1 `minus` m = n2 `minus` m
minusReflLeft Refl LTEZero LTEZero = Refl
minusReflLeft Refl (LTESucc prev1) (LTESucc prev2) = minusReflLeft Refl prev1 prev2
I don't even need plusTossS anymore, which can be replaced by a more directly applicable lemma:
plusRightS : (n, m : Nat) -> n + S m = S (n + m)
plusRightS Z m = Refl
plusRightS (S n) m = cong $ plusRightS n m
After that, the original one becomes trivial:
minusPlusTossS : (n, m, k : Nat) ->
{ auto prf1 : k `LTE` n + S m } ->
{ auto prf2 : k `LTE` S n + m } ->
minus (n + S m) k = minus (S n + m) k
minusPlusTossS {prf1} {prf2} n m k = minusReflLeft (plusRightS n m) prf1 prf2

Multiplying multidimensional array in python

I have two arrays:
L, M, N = 6, 31, 500
A = np.random.random((L, M, N))
B = np.random.random((L, L))
I am trying to get an array C such that:
C = B * A
C has dimension [L, M, N]
I tried answer posted at this link but it hasn't given me the desired output.
A for loop version of above code is:
L, M, N = 6, 31, 500
A = np.random.random((L, M, N))
B = np.random.random((L, L))
z1 = []
for j in range(M):
a = np.squeeze(A[:, j, :])
z1.append(np.dot(B, a))
z2 = np.stack(z1)
I think you are looking for numpy.tensordot() where you can specify along which axes to sum:
np.tensordot(B,A,axes=(1,0))

How to optimize this haskell snippet

I'm trying to create a small module for doing decimal-based calculations. A number is stored as an integer mantisse, with a precision value specified by an int:
data APNum =
{ getMantisse :: Integer
, getPrecision :: Int }
For instance:
APNum 123 0 -> 123
APNum 123 1 -> 1.23
APNum 123 2 -> 12.3
...
(negative precision is not allowed).
Now I wrote this function, which adjusts the precision automatically by stripping as many trailing zero's as possible:
autoPrecision :: APNum -> APNum
autoPrecision x#(APNum m p) = if p > maxPrecision
then autoPrecision $ setPrecision x maxPrecision
else autoPrecision' m p where
autoPrecision' m p = let (m',r) = m `divMod` 10 in
if r /= 0 || p <= 0 then APNum m p else autoPrecision' m' (pred p)
(MaxPrecision and setPrecision are obvious, I think).
The problem is, this snippet has a very bad performance, specially n numbers with more then 10000 digits. Are there any simple optimizations?
You can use binary search to find the highest power of 10 which divides m, instead of trying all consecutive values.
import Numeric.Search.Range
import Data.Maybe
data APNum = APNum{getMantisse :: Integer, getPrecission :: Int} deriving Show
setPrecision (APNum m _) x = APNum m x
maxPrecission = 200000
findDiv x = pred $ fromJust $ searchFromTo (p x) 0 maxPrecission where
p x n = x `mod` 10^n /= 0
autoPrecision :: APNum -> APNum
autoPrecision x#(APNum m p)
= if p > maxPrecission then
autoPrecision $ setPrecision x maxPrecission else APNum m' p'
where d = min (findDiv m) p
p' = p - d
m' = m `div` 10^d
I'm using the binary-search package here which provides searchFromTo :: Integral a => (a -> Bool) -> a -> a -> Maybe a. This should give you a big speedup.
Looks like even straightforward string operation is still faster:
maxPrecision = 2000000
autoPrecision (APNum m p) =
let p' = min p maxPrecision
(n',ds) = genericDropNWhile (=='0') p' $ reverse $ show m
in APNum (read $ reverse ds) n'
where
genericDropNWhile p n (x:xs) | n > 0 && p x = genericDropNWhile p (n-1) xs
genericDropNWhile _ n xs = (n,xs)
Test with this:
main = print $ autoPrecision $ APNum (10^100000) (100000-3)
EDIT: Oops, faster only for numbers with lots of zeroes. Otherwise this double conversion is definitely slower.
also x mod 10 == 0 implies x mod 2 == 0, and that is cheaper to test for