how to use multiply in constraint

This forum is for posts that specifically focus on Ngene.

Moderators: Andrew Collins, Michiel Bliemer, johnr

how to use multiply in constraint

Postby wxy008 » Sun Jan 16, 2022 7:53 am

Dear Michiel,

I am trying to add two constraints in my design. I would like that cost in alternative 1 is larger than cost in alternative 2 when the value of attribute survival multiplying attribute tree in alternative 1 is larger than the value in alternative 2. I use the codes below to set up constraints, but I get an error message that alt1. survival* is not found. How should I fix this issue? Thanks.
Code: Select all
;cond:
if(alt1.survival * alt1.tree > alt2.survival * alt2.tree, alt1.cost > alt2.cost),
if(alt1.survival * alt1.tree = alt2.survival * alt2.tree, alt1.cost = alt2.cost)
wxy008
 
Posts: 33
Joined: Wed Mar 04, 2020 3:22 am

Re: how to use multiply in constraint

Postby Michiel Bliemer » Sun Jan 16, 2022 2:35 pm

On page 231 in the Ngene manual you can find that multiplications in the logical expression are not supported in conditional constraints.
Often it is possible to rewrite the constraints in another way such that it fits in Ngene. I can perhaps assist if you can share your full Ngene syntax.

Michiel
Michiel Bliemer
 
Posts: 1727
Joined: Tue Mar 31, 2009 4:13 pm

Re: how to use multiply in constraint

Postby wxy008 » Mon Jan 17, 2022 12:13 am

Thanks so much Michiel. Please see full Ngene syntax below:
Code: Select all
Design;
;alts = alt1*,alt2*,base
;rows = 12
;block = 2
;eff = (mnl,d)
;alg = mfederov
;cond:
if(alt1.survival * alt1.tree > alt2.survival * alt2.tree, alt1.cost > alt2.cost),
?if(alt1.survival * alt1.tree = alt2.survival * alt2.tree, alt1.cost = alt2.cost)
;model:
U(alt1) = asc + b1* survival[0.6, 0.75, 0.9] + b2.dummy[0|0]*vigor[1,2,0]  +
                b3*tree[150,200,250]  + b4[-0.001]*cost[6,8,10]
 /
U(alt2) = asc + b1* survival + b2*vigor + b3*tree + b4*cost/

U(base) = b1*survival1[0.6] + b3*tree1[150] + b4*cost1[6]

$
wxy008
 
Posts: 33
Joined: Wed Mar 04, 2020 3:22 am

Re: how to use multiply in constraint

Postby Michiel Bliemer » Mon Jan 17, 2022 7:21 am

I believe that the syntax below will do what you want.

Note that conditional constraints are not compatible with the modified Federov algorithm, only with the default swapping algorithm. I have translated your conditional constraints into reject constraints.

Further note that the modified Federov algorithm does not guarantee attribute level balance. I have added attribute level balance constraints (3-5,3-5,3-5) for each attribute.

Finally, you may want to include a small positive or negative priors for the other attributes (if known) to avoid dominant alternatives, e.g. use 0.000001 or -0.000001 as priors. You now only specified a non-negative prior for cost.

Code: Select all
Design
;alts = alt1*,alt2*,base
;rows = 12
;block = 2
;eff = (mnl,d)
;alg = mfederov

;reject:

? the constraints below replace: if(alt1.survival * alt1.tree > alt2.survival * alt2.tree, alt1.cost > alt2.cost)

alt1.survival = 0.75 and alt1.tree = 150 and alt2.survival = 0.6 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 150 and alt2.survival = 0.6 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.6 and alt1.tree = 200 and alt2.survival = 0.6 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.75 and alt1.tree = 200 and alt2.survival = 0.6 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 200 and alt2.survival = 0.6 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.6 and alt1.tree = 250 and alt2.survival = 0.6 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.75 and alt1.tree = 250 and alt2.survival = 0.6 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 250 and alt2.survival = 0.6 and alt2.tree = 150 and alt1.cost <= alt2.cost,

alt1.survival = 0.9 and alt1.tree = 150 and alt2.survival = 0.75 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.6 and alt1.tree = 200 and alt2.survival = 0.75 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.75 and alt1.tree = 200 and alt2.survival = 0.75 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 200 and alt2.survival = 0.75 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.6 and alt1.tree = 250 and alt2.survival = 0.75 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.75 and alt1.tree = 250 and alt2.survival = 0.75 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 250 and alt2.survival = 0.75 and alt2.tree = 150 and alt1.cost <= alt2.cost,

alt1.survival = 0.75 and alt1.tree = 200 and alt2.survival = 0.9 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 200 and alt2.survival = 0.9 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.6 and alt1.tree = 250 and alt2.survival = 0.9 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.75 and alt1.tree = 250 and alt2.survival = 0.9 and alt2.tree = 150 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 250 and alt2.survival = 0.9 and alt2.tree = 150 and alt1.cost <= alt2.cost,

alt1.survival = 0.9 and alt1.tree = 150 and alt2.survival = 0.6 and alt2.tree = 200 and alt1.cost <= alt2.cost,
alt1.survival = 0.75 and alt1.tree = 200 and alt2.survival = 0.6 and alt2.tree = 200 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 200 and alt2.survival = 0.6 and alt2.tree = 200 and alt1.cost <= alt2.cost,
alt1.survival = 0.6 and alt1.tree = 250 and alt2.survival = 0.6 and alt2.tree = 200 and alt1.cost <= alt2.cost,
alt1.survival = 0.75 and alt1.tree = 250 and alt2.survival = 0.6 and alt2.tree = 200 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 250 and alt2.survival = 0.6 and alt2.tree = 200 and alt1.cost <= alt2.cost,

alt1.survival = 0.9 and alt1.tree = 200 and alt2.survival = 0.75 and alt2.tree = 200 and alt1.cost <= alt2.cost,
alt1.survival = 0.75 and alt1.tree = 250 and alt2.survival = 0.75 and alt2.tree = 200 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 250 and alt2.survival = 0.75 and alt2.tree = 200 and alt1.cost <= alt2.cost,

alt1.survival = 0.75 and alt1.tree = 250 and alt2.survival = 0.9 and alt2.tree = 200 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 250 and alt2.survival = 0.9 and alt2.tree = 200 and alt1.cost <= alt2.cost,

alt1.survival = 0.9 and alt1.tree = 200 and alt2.survival = 0.6 and alt2.tree = 250 and alt1.cost <= alt2.cost,
alt1.survival = 0.75 and alt1.tree = 250 and alt2.survival = 0.6 and alt2.tree = 250 and alt1.cost <= alt2.cost,
alt1.survival = 0.9 and alt1.tree = 250 and alt2.survival = 0.6 and alt2.tree = 250 and alt1.cost <= alt2.cost,

alt1.survival = 0.9 and alt1.tree = 250 and alt2.survival = 0.75 and alt2.tree = 250 and alt1.cost <= alt2.cost,

? the constraints below replace: if(alt1.survival * alt1.tree = alt2.survival * alt2.tree, alt1.cost = alt2.cost)

alt1.survival = 0.6 and alt2.survival = 0.6 and alt1.tree = 150 and alt2.tree = 150 and alt1.cost <> alt1.cost,
alt1.survival = 0.75 and alt2.survival = 0.75 and alt1.tree = 150 and alt2.tree = 150 and alt1.cost <> alt1.cost,
alt1.survival = 0.9 and alt2.survival = 0.9 and alt1.tree = 150 and alt2.tree = 150 and alt1.cost <> alt1.cost,
alt1.survival = 0.6 and alt2.survival = 0.6 and alt1.tree = 200 and alt2.tree = 200 and alt1.cost <> alt1.cost,
alt1.survival = 0.75 and alt2.survival = 0.75 and alt1.tree = 200 and alt2.tree = 200 and alt1.cost <> alt1.cost,
alt1.survival = 0.9 and alt2.survival = 0.9 and alt1.tree = 200 and alt2.tree = 200 and alt1.cost <> alt1.cost,
alt1.survival = 0.6 and alt2.survival = 0.6 and alt1.tree = 250 and alt2.tree = 250 and alt1.cost <> alt1.cost,
alt1.survival = 0.75 and alt2.survival = 0.75 and alt1.tree = 250 and alt2.tree = 250 and alt1.cost <> alt1.cost,
alt1.survival = 0.9 and alt2.survival = 0.9 and alt1.tree = 250 and alt2.tree = 250 and alt1.cost <> alt1.cost,

alt1.survival = 0.75 and alt2.survival = 0.6 and alt1.tree = 200 and alt2.tree = 250 and alt1.cost <> alt1.cost,
alt1.survival = 0.6 and alt2.survival = 0.75 and alt1.tree = 250 and alt2.tree = 200 and alt1.cost <> alt1.cost

;model:
U(alt1) = asc
        + b1            * survival[0.6, 0.75, 0.9](3-5,3-5,3-5)
        + b2.dummy[0|0] * vigor[1,2,0](3-5,3-5,3-5) 
        + b3            * tree[150,200,250](3-5,3-5,3-5) 
        + b4            * cost[6,8,10](3-5,3-5,3-5)
        /
U(alt2) = asc + b1 * survival + b2 * vigor + b3 * tree + b4 * cost /
U(base) = b1*survival1[0.6] + b3*tree1[150] + b4*cost1[6]
$


Michiel
Michiel Bliemer
 
Posts: 1727
Joined: Tue Mar 31, 2009 4:13 pm

Re: how to use multiply in constraint

Postby wxy008 » Mon Jan 17, 2022 7:58 am

Michiel,
Thanks so much for your help.
The follow up questions:
1. Is default swapping algorithm better than modified Federov since swapping will give balance design?
2. You suggest add 3-5 to get level balance. Do you think 3 will better than a range eg. 3-5? Should I use a single number (eg. 3) or use a range (eg. 3-5)?

Wei
wxy008
 
Posts: 33
Joined: Wed Mar 04, 2020 3:22 am

Re: how to use multiply in constraint

Postby Michiel Bliemer » Mon Jan 17, 2022 9:08 am

The default swapping algorithm maintains attribute level balance, but cannot handle many constraints (imposing constraints makes it nearly impossible to satisfy attribute level balance). The modified Federov algorithm is a column based algorithm that can deal with a heavily constrained design (like yours), so in this case you do not have much choice I think.

You can try using (4,4,4) as exact levels, note that they need to add up to 12 (rows), but that imposes a very heavy constrained on the design and also the modified Federov algorithm may struggle to find a design that satisfies all constraints. It is worth trying though.

Note that attribute level balance is not required in a design, but having sufficient attribute level balance is a nice feature to have. A range of 3-5 offers sufficient attribute level balance.

Michiel
Michiel Bliemer
 
Posts: 1727
Joined: Tue Mar 31, 2009 4:13 pm

Re: how to use multiply in constraint

Postby wxy008 » Mon Jan 17, 2022 10:01 am

Michiel,

Thanks for quick response, and I really appreciate your detail explanation. Could you also share how do you set up the level range? exact level +/- 1( eg. (4-1, 4+1)? Is there any criterion for sufficient attribute level?

Wei
wxy008
 
Posts: 33
Joined: Wed Mar 04, 2020 3:22 am

Re: how to use multiply in constraint

Postby Michiel Bliemer » Mon Jan 17, 2022 11:13 am

How you specify the attribute level range is personal preference, but I generally indeed to at (1) what is the number of levels to get exact attribute level balance, in this case 4, and (2) use -1 and +1 to see if Ngene can find a design within this range, (3) if Ngene cannot find a design, increase the range using -2 and +2, etc. Note that you can have different ranges for different attributes, so you could use (4,4,4) for cost and (2-6,2-6,2-6) for survival. Or you can simply specify a lower bound, e.g. (2-12,2-12,2-12) for all attribute levels to appear at least two times.

There are no rules for attribute level balance and some people do not care about it at all, but I generally start setting the ranges relatively tight and only widen them if Ngene struggles to find designs.

Michiel
Michiel Bliemer
 
Posts: 1727
Joined: Tue Mar 31, 2009 4:13 pm

Re: how to use multiply in constraint

Postby wxy008 » Mon Jan 17, 2022 11:54 am

Thanks so much, Michiel!!!!!!!!!!
wxy008
 
Posts: 33
Joined: Wed Mar 04, 2020 3:22 am


Return to Choice experiments - Ngene

Who is online

Users browsing this forum: No registered users and 7 guests

cron