cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Have your say in shaping JMP's future by participating in the new JMP Wish List Prioritization Survey
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.