cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Register for our Discovery Summit 2024 conference, Oct. 21-24, where you’ll learn, connect, and be inspired.
Choose Language Hide Translation Bar
dp30
Level IV

Mixture design point type (extrem vertices)

Hello,

Is there a way to know whether a mixture design point is a vertice or a centroid (of degree 1, or 2, or 3, ...) when creating an Extrem Vertices Design?

Ideally, I wish it could be indicated in an additional column in the "Make Design" Table.

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
louv
Staff (Retired)

Re: Mixture design point type (extrem vertices)

Check out this script to see if it is what you were looking for?

 

 

Names Default To Here( 1 );

Ntables = N Table();
tableList = {};
For( i = 1, i <= Ntables, i++,
	tableList[i] = Data Table( i )
);
//show(tableList);

desTable = {};
conTable = {};

sameTableAlert = Expr(
	Dialog(
		"Choose different data tables for each selection.",
		Text Box( " " ),
		Button( "OK" )
	)
);

noTableAlert = Expr(
	Dialog(
		"A design data table must be open.",
		Text Box( " " ),
		Button( "OK" )
	)
);

noMixtureFacAlert = Expr(
	Dialog(
		"The Design Table has no mixture factors.",
		Text Box( " " ),
		Button( "OK" )
	)
);

doWork = Expr(
//Assess the Design Table
	numCols = N Col( desTable );
	numRows = N Row( desTable );
	numMixFac = 0;
	XMatrix = [];
	mixLower = [];
	mixUpper = [];
	mixSum = [];
	mixCon = [];
//show(numCols);
	//show(numRows);
	Current Data Table( desTable );
	For( i = 1, i <= numCols, i++,
		col = Column( i );
		prop = col << get property( "Mixture" );
//show(prop);
		If( Is List( prop ),
			numMixFac++;
			tmp = col << get as matrix;
//show(tmp);
			XMatrix ||= tmp;
//show(XMatrix);
			mixLower ||= {prop[1]};
			mixUpper ||= {prop[2]};
			mixSum ||= {prop[3]};
//show(numMixFac);
		);
	);
	If( numMixFac == 0,
		noMixtureFacAlert,
		satCon = J( numRows, 1, 0 );
//show(satCon);

		//Set up Simple Constraint Matrix
		numConstraintsOld = 2 * numMixFac + 1;
		conMatrix = J( 1, numMixFac, 1 );
		conMatrix = conMatrix |/ Identity( numMixFac ) |/
		Identity( numMixFac );
//show(conMatrix);

		mixSumVal = mixSum[1];
		mixCon = mixCon || {mixSumVal} || mixLower || mixUpper;
//show(mixCon);

		//Get linear inequality constraints if there is a constraint table
		If( conVal == 1,
			numConstraintsNew = numConstraintsOld;
			Current Data Table( conTable );
			numIneqRow = N Row( conTable );
//look for duplicate constraints
			FullConMat = conMatrix || mixCon`;
			For( i = 1, i <= numIneqCon, i++,
				con = Column( i );
				prop = con << get property( "ConstraintState" );
				charprop = Char( Name Expr( prop ) );
				If( numIneqRow != numMixFac + 1,
					Throw(
						"Can only use constraints with pure mixture designs."
					)
				);
				ineqConMat = con << get as matrix;
//show(ineqConMat);
				overallTest = 0;
				For( j = 1, (j <= numConstraintsOld), j++,  
//find the first nonzero element
					For( k = 1, k <= numMixFac + 1, k++,
						If( FullConMat[j, k] != 0,
							piv = FullConMat[j, k];
							ind = k;
							k = numMixFac + 2;
						)
					);
					test = 0;
					If( ineqConMat[ind] != 0,
						mult = piv / ineqConMat[ind];
						newRow = ineqConMat * mult;
						newRow = newRow` - FullConMat[j, 0];
						For( k = 1, k <= numMixFac + 1, k++,
							If( Abs( newRow[k] ) > 1e-10,
								test
								++)
						);
					,
						test
						++);
					If( test == 0,
						overallTest++;
						j = numConstraintsOld + 1;
					);
				);

//show(overallTest);
				If( overallTest == 0,
					tmp = ineqConMat[1 :: numMixFac];
					conMatrix = conMatrix |/ tmp`;
					numConstraintsNew++;
					tmp = ineqConMat[numMixFac + 1 :: numMixFac + 1];
					mixCon = mixCon || tmp;
				);
//show(mixCon);
			);
		,
			numConstraintsNew = numConstraintsOld
		);
//show(conMatrix);

		//Check how the rows satisfy the constraints
		resultMat = conMatrix * XMatrix`;
//show(resultMat);
		For( j = 1, j <= numRows, j++,
			For( i = 1, i <= numConstraintsNew, i++,
				If( Abs( resultMat[i, j] - mixCon[i] ) < .00000001,
					satCon[j, 1]
					++)
			)
		);
//show(satCon);

		//label the points
		Current Data Table( desTable );
		pointCol = desTable << New Column( "Point Type", Character, Nominal );
		For( i = 1, i <= numRows, i++,
			If(
				(satCon[i] >= numMixFac),
					pointCol[i] = "Vertex";
					Row State( i ) = Color State( 3 );,
				(satCon[i] == numMixFac - 1),
					pointCol[i] = "Edge";
					Row State( i ) = Color State( 4 );,
				(satCon[i] == 1),
					pointCol[i] = "Interior";
					Row State( i ) = Color State( 5 );,
				numFace = numMixFac - satCon[i];
				pointCol[i] = Char( numFace ) || "D-Face";
				Row State( i ) = Color State( numMixFac - satCon[i] + 6 );
			)
		);
		pointCol << label( 1 );
//Create Ternary Plot Script
		xString = "";
		For( i = 1, i <= numCols, i++,
			col = Column( i );
			prop = col << get property( "Mixture" );
			If( Is List( prop ),
				colname = Char( Column Name( i ) );
//show(colname);
				xString = xString || Expr( " :" ) || colname || Expr( "," );
			);
		);
		len = Length( xString );
		xString2 = Substr( xString, 1, len - 1 );
//show(xString2);

		If( numMixFac > 2,
			frameString = "";
			If( numMixFac == 3,
				frameString = frameString || "report(obj)[framebox(" ||
				Char( 1 ) || ")]<<marker size(4);",
				numPlots = (numMixFac * (numMixFac - 1)) / 2;
				For( i = 1, i < numPlots, i++,
					frameString = frameString || "report(obj)[framebox(" ||
					Char( i ) || ")]<<marker size(4);\!N"
				);
				frameString = frameString || "report(obj)[framebox(" ||
				Char( i ) || ")]<<marker size(4);";
			);

			d1 = "obj=Ternary Plot(Y(" || xString2 || "));\!N" || frameString;
			d2 = Eval( Expr( Parse( d1 ) ) );
			d3 = Expr(
				desTable << New Table Property( "Ternary Plot", a )
			);
			Eval( Substitute( Name Expr( d3 ), Expr( a ), Name Expr( d2 ) ) );
		);
		If( NTables > 1,
			dlg << close window
		);
	);
);

initState = 0;
If(
	(Ntables == 0), noTableAlert,
	(Ntables == 1),
		conVal = 0;
		desTable = tableList[1];
		doWork;,
	dlg = New Window( "Identify Mixture Points",
		Border Box( Left( 3 ), bottom( 3 ), Right( 2 ), sides( 28 ), top( 3 ),
			V List Box(
				Panel Box( "Table Settings",
					checkObj = Check Box(
						{"Use Constraint Table"},
						If( initState == 0,
							pbox << append(
								pbox2 =
								Panel Box( "Select Constraint Data Table",
									comboObj3 = Combo Box( tableList )
								)
							);
							pbox << reshow;
						,
							pbox2 << delete;
							pbox << reshow;
						);
						If( initState == 0,
							initState = 1,
							initState = 0
						);
					)
				),
				pbox = Panel Box( "Select Data Tables",
					Panel Box( "Select Design Data Table",
						comboObj1 = Combo Box( tableList )
					), 

				),
				Button Box( "OK",
					desTableNum = comboObj1 << get;
//show(desTableNum);
					desTable = Data Table( Eval( desTableNum ) );
//show(desTable);
					conVal = checkObj << get( 1 );
					If( (conVal == 1) & (Ntables == 1),
						Throw(
							"Both a design and constraint table must be open."
						)
					);
					If( conVal == 1,
						conTableNum = comboObj3 << get;
//show(conTableNum);
						conTable = Data Table( Eval( conTableNum ) );
//show(conTable);
					);
					If( (conVal == 1) & (desTableNum == conTableNum),
						sameTableAlert,
						If( conVal == 1,
							Current Data Table( conTable );
							numIneqCon = N Col( conTable );
							For( i = 1, i <= numIneqCon, i++,
								con = Column( i );
								prop = con <<
								get property( "ConstraintState" );
								charprop = Char( Name Expr( prop ) );
								If(
									(charprop != "ConstraintState(less than)")
									 & (charprop !=
									"ConstraintState(greater than)"),
									Throw( "Need to use a constraint table." )
								);

							);
						);
						doWork;
					);
				)
			)
		)
	)
);

 

View solution in original post

3 REPLIES 3
louv
Staff (Retired)

Re: Mixture design point type (extrem vertices)

Check out this script to see if it is what you were looking for?

 

 

Names Default To Here( 1 );

Ntables = N Table();
tableList = {};
For( i = 1, i <= Ntables, i++,
	tableList[i] = Data Table( i )
);
//show(tableList);

desTable = {};
conTable = {};

sameTableAlert = Expr(
	Dialog(
		"Choose different data tables for each selection.",
		Text Box( " " ),
		Button( "OK" )
	)
);

noTableAlert = Expr(
	Dialog(
		"A design data table must be open.",
		Text Box( " " ),
		Button( "OK" )
	)
);

noMixtureFacAlert = Expr(
	Dialog(
		"The Design Table has no mixture factors.",
		Text Box( " " ),
		Button( "OK" )
	)
);

doWork = Expr(
//Assess the Design Table
	numCols = N Col( desTable );
	numRows = N Row( desTable );
	numMixFac = 0;
	XMatrix = [];
	mixLower = [];
	mixUpper = [];
	mixSum = [];
	mixCon = [];
//show(numCols);
	//show(numRows);
	Current Data Table( desTable );
	For( i = 1, i <= numCols, i++,
		col = Column( i );
		prop = col << get property( "Mixture" );
//show(prop);
		If( Is List( prop ),
			numMixFac++;
			tmp = col << get as matrix;
//show(tmp);
			XMatrix ||= tmp;
//show(XMatrix);
			mixLower ||= {prop[1]};
			mixUpper ||= {prop[2]};
			mixSum ||= {prop[3]};
//show(numMixFac);
		);
	);
	If( numMixFac == 0,
		noMixtureFacAlert,
		satCon = J( numRows, 1, 0 );
//show(satCon);

		//Set up Simple Constraint Matrix
		numConstraintsOld = 2 * numMixFac + 1;
		conMatrix = J( 1, numMixFac, 1 );
		conMatrix = conMatrix |/ Identity( numMixFac ) |/
		Identity( numMixFac );
//show(conMatrix);

		mixSumVal = mixSum[1];
		mixCon = mixCon || {mixSumVal} || mixLower || mixUpper;
//show(mixCon);

		//Get linear inequality constraints if there is a constraint table
		If( conVal == 1,
			numConstraintsNew = numConstraintsOld;
			Current Data Table( conTable );
			numIneqRow = N Row( conTable );
//look for duplicate constraints
			FullConMat = conMatrix || mixCon`;
			For( i = 1, i <= numIneqCon, i++,
				con = Column( i );
				prop = con << get property( "ConstraintState" );
				charprop = Char( Name Expr( prop ) );
				If( numIneqRow != numMixFac + 1,
					Throw(
						"Can only use constraints with pure mixture designs."
					)
				);
				ineqConMat = con << get as matrix;
//show(ineqConMat);
				overallTest = 0;
				For( j = 1, (j <= numConstraintsOld), j++,  
//find the first nonzero element
					For( k = 1, k <= numMixFac + 1, k++,
						If( FullConMat[j, k] != 0,
							piv = FullConMat[j, k];
							ind = k;
							k = numMixFac + 2;
						)
					);
					test = 0;
					If( ineqConMat[ind] != 0,
						mult = piv / ineqConMat[ind];
						newRow = ineqConMat * mult;
						newRow = newRow` - FullConMat[j, 0];
						For( k = 1, k <= numMixFac + 1, k++,
							If( Abs( newRow[k] ) > 1e-10,
								test
								++)
						);
					,
						test
						++);
					If( test == 0,
						overallTest++;
						j = numConstraintsOld + 1;
					);
				);

//show(overallTest);
				If( overallTest == 0,
					tmp = ineqConMat[1 :: numMixFac];
					conMatrix = conMatrix |/ tmp`;
					numConstraintsNew++;
					tmp = ineqConMat[numMixFac + 1 :: numMixFac + 1];
					mixCon = mixCon || tmp;
				);
//show(mixCon);
			);
		,
			numConstraintsNew = numConstraintsOld
		);
//show(conMatrix);

		//Check how the rows satisfy the constraints
		resultMat = conMatrix * XMatrix`;
//show(resultMat);
		For( j = 1, j <= numRows, j++,
			For( i = 1, i <= numConstraintsNew, i++,
				If( Abs( resultMat[i, j] - mixCon[i] ) < .00000001,
					satCon[j, 1]
					++)
			)
		);
//show(satCon);

		//label the points
		Current Data Table( desTable );
		pointCol = desTable << New Column( "Point Type", Character, Nominal );
		For( i = 1, i <= numRows, i++,
			If(
				(satCon[i] >= numMixFac),
					pointCol[i] = "Vertex";
					Row State( i ) = Color State( 3 );,
				(satCon[i] == numMixFac - 1),
					pointCol[i] = "Edge";
					Row State( i ) = Color State( 4 );,
				(satCon[i] == 1),
					pointCol[i] = "Interior";
					Row State( i ) = Color State( 5 );,
				numFace = numMixFac - satCon[i];
				pointCol[i] = Char( numFace ) || "D-Face";
				Row State( i ) = Color State( numMixFac - satCon[i] + 6 );
			)
		);
		pointCol << label( 1 );
//Create Ternary Plot Script
		xString = "";
		For( i = 1, i <= numCols, i++,
			col = Column( i );
			prop = col << get property( "Mixture" );
			If( Is List( prop ),
				colname = Char( Column Name( i ) );
//show(colname);
				xString = xString || Expr( " :" ) || colname || Expr( "," );
			);
		);
		len = Length( xString );
		xString2 = Substr( xString, 1, len - 1 );
//show(xString2);

		If( numMixFac > 2,
			frameString = "";
			If( numMixFac == 3,
				frameString = frameString || "report(obj)[framebox(" ||
				Char( 1 ) || ")]<<marker size(4);",
				numPlots = (numMixFac * (numMixFac - 1)) / 2;
				For( i = 1, i < numPlots, i++,
					frameString = frameString || "report(obj)[framebox(" ||
					Char( i ) || ")]<<marker size(4);\!N"
				);
				frameString = frameString || "report(obj)[framebox(" ||
				Char( i ) || ")]<<marker size(4);";
			);

			d1 = "obj=Ternary Plot(Y(" || xString2 || "));\!N" || frameString;
			d2 = Eval( Expr( Parse( d1 ) ) );
			d3 = Expr(
				desTable << New Table Property( "Ternary Plot", a )
			);
			Eval( Substitute( Name Expr( d3 ), Expr( a ), Name Expr( d2 ) ) );
		);
		If( NTables > 1,
			dlg << close window
		);
	);
);

initState = 0;
If(
	(Ntables == 0), noTableAlert,
	(Ntables == 1),
		conVal = 0;
		desTable = tableList[1];
		doWork;,
	dlg = New Window( "Identify Mixture Points",
		Border Box( Left( 3 ), bottom( 3 ), Right( 2 ), sides( 28 ), top( 3 ),
			V List Box(
				Panel Box( "Table Settings",
					checkObj = Check Box(
						{"Use Constraint Table"},
						If( initState == 0,
							pbox << append(
								pbox2 =
								Panel Box( "Select Constraint Data Table",
									comboObj3 = Combo Box( tableList )
								)
							);
							pbox << reshow;
						,
							pbox2 << delete;
							pbox << reshow;
						);
						If( initState == 0,
							initState = 1,
							initState = 0
						);
					)
				),
				pbox = Panel Box( "Select Data Tables",
					Panel Box( "Select Design Data Table",
						comboObj1 = Combo Box( tableList )
					), 

				),
				Button Box( "OK",
					desTableNum = comboObj1 << get;
//show(desTableNum);
					desTable = Data Table( Eval( desTableNum ) );
//show(desTable);
					conVal = checkObj << get( 1 );
					If( (conVal == 1) & (Ntables == 1),
						Throw(
							"Both a design and constraint table must be open."
						)
					);
					If( conVal == 1,
						conTableNum = comboObj3 << get;
//show(conTableNum);
						conTable = Data Table( Eval( conTableNum ) );
//show(conTable);
					);
					If( (conVal == 1) & (desTableNum == conTableNum),
						sameTableAlert,
						If( conVal == 1,
							Current Data Table( conTable );
							numIneqCon = N Col( conTable );
							For( i = 1, i <= numIneqCon, i++,
								con = Column( i );
								prop = con <<
								get property( "ConstraintState" );
								charprop = Char( Name Expr( prop ) );
								If(
									(charprop != "ConstraintState(less than)")
									 & (charprop !=
									"ConstraintState(greater than)"),
									Throw( "Need to use a constraint table." )
								);

							);
						);
						doWork;
					);
				)
			)
		)
	)
);

 

dp30
Level IV

Re: Mixture design point type (extrem vertices)

Wow ! Exactly what I was looking for, thanks a lot !

It works perfectly, that's a great script. 

Thanks again

louv
Staff (Retired)

Re: Mixture design point type (extrem vertices)

No problem. I can't take credit for writing the script but recall it being shared with me quite a few years ago. I believe it was embedded in the JMP course notes on Mixture Designs and could have been Mark Bailey.