In Technical Support, we frequently receive questions surrounding the use of factor constraints in JMP’s Design of Experiments platforms. Three options – linear constraints, the disallowed combinations filter, and the disallowed combinations script – offer the ability to restrict your design space. However, sometimes users contact us reporting that the resulting design does not respect the constraints they defined.
This blog post will specifically cover use of the disallowed combinations script, which we typically steer users towards, as it is more user-friendly than the disallowed combinations filter. The linear constraints option is fairly straightforward, but you can find guidance on it here if needed.
The disallowed combinations script option allows you to define restrictions on your design space using a JSL script. The key aspect to keep in mind is to specify which combinations of factor levels are not allowed in the design. The JSL script entered must evaluate as a Boolean expression. When the expression is true, it disallows that combination from occurring in the design. The script does not have to be linear in form, thus there is the added benefit of being able specify nonlinear constraints. You may also use functions (indicator functions can be especially useful, as illustrated in one of the examples later in this post).
A disallowed combinations script can be used in conjunction with continuous, discrete numeric, and categorical factors, but is not supported with mixture or blocking factors. Alternative ways to define restrictions in mixture scenarios are described in later examples.
In the expression, levels of continuous and discrete numeric factors are referenced by their numeric values. The levels of categorical factors can be referenced either by their associated ordinal values (1, 2, 3, etc.) or the named level values.
Consider a Custom Design with two continuous factors, one four-level discrete numeric factor, and one three-level categorical factor.
The script to reproduce the starting DOE dialog with the factors described above is:
DOE(
Custom Design,
{Add Response( Maximize, "Y", ., ., . ),
Add Factor( Continuous, -1, 1, "X1", 0 ),
Add Factor( Continuous, 100, 105, "X2", 0 ),
Add Factor( Discrete Numeric, {10, 20, 30, 40}, "X3", 0 ),
Add Factor( Categorical, {"A", "B", "C"}, "X4", 0 ),
Add Term( {1, 0} ), Add Term( {1, 1} ),
Add Term( {2, 1} ), Add Term( {3, 1} ), Add Potential Term( {3, 2} ),
Add Potential Term( {3, 3} ), Add Term( {4, 1} ),
Add Alias Term( {1, 1}, {2, 1} ), Add Alias Term( {1, 1}, {3, 1} ),
Add Alias Term( {1, 1}, {4, 1} ), Add Alias Term( {2, 1}, {3, 1} ),
Add Alias Term( {2, 1}, {4, 1} ), Add Alias Term( {3, 1}, {4, 1} ),
Set Sample Size( 12 ), Simulate Responses( 1 ), Save X Matrix( 0 )}
);
As an example, suppose no run can occur in your design where factor X1 takes a value of 1 at the same time factor X4 takes a value of A. This simple disallowed combinations script would be written as:
X1 == 1 & X4 == 1
or
X1 == 1 & X4 == "A"
The first expression uses the associated ordinal value for a value of X4 = A and the second expression simply references the character value. Either is acceptable. This expression prevents any run from having X1 = 1 and X4 = A simultaneously.
After running the script, select the radio button next to Use Disallowed Combinations Script in the Define Factor Constraints section and enter one of the expressions above.
To add additional design space restrictions to the script, use the OR (|) operator, which is necessary to separate expressions when a design cannot contain runs meeting the criteria of expression 1, or expression 2, or expression 3, etc.
Suppose that, in the same design, the sum of factors X1 and X2 cannot be greater than a value of 102 when factor X3 takes a value of 3. This disallowed combination would be written as:
((X1 + X2) > 102 & X3 == 30)
Using the | operator, the complete disallowed combinations script would be written as:
(X1 == 1 & X4 == 1) |
((X1 + X2) > 102 & X3 == 30)
After making the design, you’ll notice that JMP may reformat the script like below, representing categorical factor levels with the character value and removing unnecessary parentheses by parsing.

Some common scenarios users present to us are:
1) How do I specify restrictions on the design space in a mixture design, since disallowed combinations are not supported with mixture factors?
Using discrete numeric and/or continuous factors in place of mixture factors, there are a couple of different ways to handle this. First, we could impose an equality constraint in the disallowed combinations script (and add any other necessary constraints). JMP likely won’t be able to find a feasible design using a strict equality constraint (e.g. using the != operator, or using < and > strict inequalities in one condition). Thus, we must use an expression specifying the sum of factor values is close to 1.
Suppose we have three mixture factors and the mixture sum is one. We know one of the factors (X1) can only take discrete levels of 0, 0.25, 0.5, 0.75, and 1. The other two factors (X2 and X3) can take any value between 0 and 1, inclusive. Thus, it makes most sense to define the first as a five-level discrete numeric factor and the other two as continuous factors. For the three factors to sum approximately to one, we can specify the pseudo-equality constraint as:
X1 + X2 + X3 > 1.001 | X1 + X2 + X3 < 0.999
which restricts the sum to be within one thousandth of one. Considering that the driving force for this question is to be able to specify factor constraints in the context of a mixture design, suppose we also want to prevent the value of X3 from being greater than the value of X2 in the design. The complete expression to enter in the disallowed combinations script field in this case would be:
X1 + X2 + X3 > 1.001 | X1 + X2 + X3 < 0.999 | X3 > X2
Run the below JSL script to create an example of this design.
DOE(
Custom Design,
{Add Response( Maximize, "Y", ., ., . ),
Add Factor( Discrete Numeric, {0, 0.25, 0.5, 0.75, 1}, "X1", 0 ),
Add Factor( Continuous, 0, 1, "X2", 0 ), Add Factor( Continuous, 0, 1, "X3", 0 ),
Set Random Seed( 12345 ), Number of Starts( 1000 ), Add Term( {1, 1} ),
Add Term( {1, 2} ), Add Term( {1, 3} ), Add Term( {1, 4} ), Add Term( {2, 1} ),
Add Term( {3, 1} ), Add Alias Term( {1, 1}, {2, 1} ), Add Alias Term( {1, 1}, {3, 1} ),
Add Alias Term( {2, 1}, {3, 1} ), Set Sample Size( 20 ),
Disallowed Combinations( X1 + X2 + X3 > 1.001 | X1 + X2 + X3 < 0.999 | X3 > X2 ),
Make Design}
);
Because the three factors’ values will not sum exactly to one, you’ll have to slightly adjust one of the continuous factors’ values in the resulting design table.
A second, cleaner approach to the original question is to enter only factors X1 (the five-level discrete numeric factor) and X2 (continuous factor ranging from 0 to 1) in the initial Custom Design dialog. The values for X3 can easily be generated in the design table using the formula 1 - X1 - X2. In the initial design setup with just factors X1 and X2, we’ll use a disallowed combinations script to ensure that the sum of X1 and X2 is neither less than zero nor greater than 1. Also, again we’ll add the restriction that X3 cannot be greater than X2. Since X3 = 1 - X1 - X2, we can rewrite the X3 > X2 restriction as 2*X2 + X1 < 1 and include it in the expression with an OR operator.
In this scenario, the complete disallowed combinations script would be:
X1 + X2 > 1 | X1 + X2 < 0 | 2 * X2 + X1 < 1
A full script to create this example design is:
DOE(
Custom Design,
{Add Response( Maximize, "Y", ., ., . ), Add Factor(
Discrete Numeric,
{0, 0.25, 0.5, 0.75, 1},
"X1",
0
), Add Factor( Continuous, 0, 1, "X2", 0 ),
Number of Starts( 1000 ), Add Term( {1, 0} ), Add Term( {1, 1} ), Add Potential Term( {1, 2} ),
Add Potential Term( {1, 3} ), Add Potential Term( {1, 4} ), Add Term( {2, 1} ),
Add Alias Term( {1, 1}, {2, 1} ), Set Sample Size( 20 ),
Disallowed Combinations( X1 + X2 > 1 | X1 + X2 < 0 | 2 * X2 + X1 < 1 ),
Simulate Responses( 1 ), Save X Matrix( 0 ), Make Design}
);
In both approaches above, the column properties of the factors in the design table need to be modified at the end to reflect the true mixture characteristics of the design. You can manually add the properties based on the guidance here in our documentation. However, a quicker method is to create another Custom Design using actual mixture factors (no need for disallowed combinations), and make the table (as a template). Then, copy your design into that “template” table. Doing so ensures the appropriate column properties for mixture factors are present.
2) How can I specify that a maximum number of factors can be “active” in a single experiment? Suppose there are six factors, but at most three of them can take a value greater than zero in any experimental run. We choose to define six discrete numeric factors (X1 - X6) with varying numbers of levels.
An essential tool to remember is that the disallowed combinations script accepts functions. Indicator functions are key in this scenario. For instance, the indicator function (X1 > 0) resolves to 1 if X1 is greater than zero and resolves to 0 if it is not. Thus, summing the indicator functions for all six factors, then excluding cases where the sum is greater than 3 will restrict the design space so that no more than three factors are active in a single run. The disallowed combinations script is written as:
(X1 > 0) + (X2 > 0) + (X3 > 0) + (X4 > 0) + (X5 > 0) + (X6 > 0) > 3
And, this example design can be created with the following JSL script:
DOE(
Custom Design,
{Add Response( Maximize, "Y", ., ., . ), Add Factor( Discrete Numeric, {0, 1, 2, 3}, "X1", 0 ),
Add Factor( Discrete Numeric, {0, 1, 2, 3}, "X2", 0 ), Add Factor( Discrete Numeric, {0, 1}, "X3", 0 ),
Add Factor( Discrete Numeric, {0, 1, 2, 3}, "X4", 0 ), Add Factor( Discrete Numeric, {0, 1, 5}, "X5", 0 ),
Add Factor( Discrete Numeric, {0, 1, 2, 3}, "X6", 0 ), Add Term( {1, 0} ), Add Term( {1, 1} ), Add Potential Term( {1, 2} ),
Add Potential Term( {1, 3} ), Add Term( {2, 1} ), Add Potential Term( {2, 2} ), Add Potential Term( {2, 3} ),
Add Term( {3, 1} ), Add Term( {4, 1} ), Add Potential Term( {4, 2} ), Add Potential Term( {4, 3} ), Add Term( {5, 1} ),
Add Potential Term( {5, 2} ), Add Term( {6, 1} ), Add Potential Term( {6, 2} ), Add Potential Term( {6, 3} ),
Add Alias Term( {1, 1}, {2, 1} ), Add Alias Term( {1, 1}, {3, 1} ), Add Alias Term( {1, 1}, {4, 1} ),
Add Alias Term( {1, 1}, {5, 1} ), Add Alias Term( {1, 1}, {6, 1} ), Add Alias Term( {2, 1}, {3, 1} ),
Add Alias Term( {2, 1}, {4, 1} ), Add Alias Term( {2, 1}, {5, 1} ), Add Alias Term( {2, 1}, {6, 1} ),
Add Alias Term( {3, 1}, {4, 1} ), Add Alias Term( {3, 1}, {5, 1} ), Add Alias Term( {3, 1}, {6, 1} ),
Add Alias Term( {4, 1}, {5, 1} ), Add Alias Term( {4, 1}, {6, 1} ), Add Alias Term( {5, 1}, {6, 1} ), Set Sample Size( 16 ),
Disallowed Combinations( (X1 > 0) + (X2 > 0) + (X3 > 0) + (X4 > 0) + (X5 > 0) + (X6 > 0) > 3 ),
Save X Matrix( 0 ), Make Design}
);
After running the script, note that at least three factors take a value of zero for every run in the design.
In any of these scenarios, if the JMP Alert “Optimal designer failed to converge” appears, your constraints may be too restrictive. If possible, relax the constraints to give the coordinate-exchange algorithm a better chance of finding a design. Also, you could try increasing the number of starts and/or changing the estimability of terms in your assumed model to If Possible instead of Necessary to see if convergence can be achieved.
As always, please feel free to reach out to Technical Support if you have questions about using the design space restriction options in JMP, or if your design is producing runs that are not sensible given your intended constraints.