 <?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.analytica.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rhoro</id>
	<title>Analytica Docs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.analytica.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rhoro"/>
	<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php/Special:Contributions/Rhoro"/>
	<updated>2026-05-21T21:58:25Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.9</generator>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Modelling_Guide&amp;diff=23162</id>
		<title>Modelling Guide</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Modelling_Guide&amp;diff=23162"/>
		<updated>2013-02-15T22:46:11Z</updated>

		<summary type="html">&lt;p&gt;Rhoro: /* Suggested Topics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This section give tips and guidelines from the experts on how to model with Analytica.&lt;br /&gt;
&lt;br /&gt;
* [[Managing Memory and CPU Time for large models]]&lt;br /&gt;
&lt;br /&gt;
* [[Array Manipulation Examples and Challenge Problems]]&lt;br /&gt;
&lt;br /&gt;
* [[Excel to Analytica Mappings|How to translate Excel spreadsheets into Analytica]]&lt;br /&gt;
&lt;br /&gt;
* [[Debugging Hints]]&lt;br /&gt;
&lt;br /&gt;
* [[Articles that refer to Analytica]]&lt;br /&gt;
&lt;br /&gt;
* [[Writing Array-Abstractable Definitions]]&lt;br /&gt;
&lt;br /&gt;
* [[Formulations that Preserve Linearity for Optimization]] -- for builders of Structured Optimization models&lt;br /&gt;
&lt;br /&gt;
* Integrating with other software&lt;br /&gt;
** [[Integrating with Excel]]&lt;br /&gt;
** [[Integrating with R|Integrating with R: A Programming Environment for Data Analysis and Graphics]]&lt;br /&gt;
&lt;br /&gt;
= [[:category:Concepts|Concepts]]  =&lt;br /&gt;
&lt;br /&gt;
*[[Array Abstraction]] &lt;br /&gt;
** [[Expressions that don't array-abstract]]&lt;br /&gt;
*[[Evaluation Modes]] &lt;br /&gt;
*[[Modules and Libraries]]&amp;amp;nbsp;: Organizing models, storing in separate files for collaboration or reuse. &lt;br /&gt;
*[[Expressing Uncertainty]]&amp;amp;nbsp;: Distributions, sampling methods, the Run index, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
*[[Associative vs. Positional Indexing]] &lt;br /&gt;
*[[Self-Indexed Arrays]] &lt;br /&gt;
*[[Implicit Dimensions]] (aka Lists, null-indexed arrays, unnamed dimensions) &lt;br /&gt;
*[[User-Defined Functions]] &lt;br /&gt;
*[[Using References]] &lt;br /&gt;
*[[Modeling Changes over Time]] &lt;br /&gt;
*[[Parametric Analysis]] &lt;br /&gt;
*Optimization &lt;br /&gt;
**[[Linear and Quadratic Programming]] &lt;br /&gt;
**[[Non-linear Programming]] &lt;br /&gt;
*[[Scripting]]&amp;amp;nbsp;: Button scripts, typescript &lt;br /&gt;
*Special Values [[INF, NAN, Null, and Undefined]] &lt;br /&gt;
*[[Local Indexes]] &lt;br /&gt;
*[[Table Splicing]] - edit tables based on computed indexes &lt;br /&gt;
*[[OLE Linking]] &lt;br /&gt;
*[[Model building by mouse]] Enabling modelers to build models by copying nodes and drawing arrows &lt;br /&gt;
*[[Class|Analytica Object Classes]] &lt;br /&gt;
*[[Controlling When Result Are Cached]] &lt;br /&gt;
*[[Encoding Decision Trees]] as influence diagrams &lt;br /&gt;
*[[Proactive Evaluation]] &lt;br /&gt;
*Structured Optimization &lt;br /&gt;
**[[DefineOptimization]] &lt;br /&gt;
**[[Formulations that Preserve Linearity for Optimization]]&lt;br /&gt;
* [[Description_balloons#Customizing_Balloon_Content|Customizing Balloon Help]]&lt;br /&gt;
* [[CloudPlayerStyles_Attribute_Values|Customizing the model interface styles for Cloud Player presentation]]&lt;br /&gt;
&lt;br /&gt;
= Mini-Tutorials =&lt;br /&gt;
&lt;br /&gt;
Currently, the ones here are focused on features new to 4.0.  But more will be coming.  For more material along these lines, see the list of past Analytica User Group webinars at [[Analytica User Group]].&lt;br /&gt;
&lt;br /&gt;
* Graphing&lt;br /&gt;
** [[Introduction to the Coordinate Index]]&lt;br /&gt;
*** [[Graphing a Probability Density]]&lt;br /&gt;
*** [[Making a Multi-D Scatter Plot]]&lt;br /&gt;
** [[Tornado Plots]]&lt;br /&gt;
** [[Gantt Charts]]&lt;br /&gt;
** [[Waterfall Charts]]&lt;br /&gt;
** [[Contour/Region Charts]]&lt;br /&gt;
** Substitutes for Tukey-style [[Box Plots]]&lt;br /&gt;
&lt;br /&gt;
* Edit Tables&lt;br /&gt;
** [[Inserting Choice Controls in Edit Table Cells]]&lt;br /&gt;
** [[Introduction to SubTables]]&lt;br /&gt;
&lt;br /&gt;
* Integration with External Programs and Data.&lt;br /&gt;
** [[Retrieving Content From the Web]]&lt;br /&gt;
** [[DbQuery/Step-by-Step_querying_Microsoft_Access|Querying an ODBC data source]]&lt;br /&gt;
&lt;br /&gt;
= Suggested Topics =&lt;br /&gt;
&lt;br /&gt;
Please list other areas for which you would like tips or guidelines, or add your own: &lt;br /&gt;
&lt;br /&gt;
* Choosing the Sample Size&lt;br /&gt;
&lt;br /&gt;
* Dynamic simulation&lt;br /&gt;
&lt;br /&gt;
* Programs that do things with and to models&lt;br /&gt;
&lt;br /&gt;
* How to make models transparent and easy to understand&lt;br /&gt;
&lt;br /&gt;
* OLE links from individual Excel cells to non-table variables&lt;/div&gt;</summary>
		<author><name>Rhoro</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Formulations_that_Preserve_Linearity_for_Optimization&amp;diff=23160</id>
		<title>Formulations that Preserve Linearity for Optimization</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Formulations_that_Preserve_Linearity_for_Optimization&amp;diff=23160"/>
		<updated>2013-02-14T22:46:40Z</updated>

		<summary type="html">&lt;p&gt;Rhoro: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concepts]]&lt;br /&gt;
When creating an optimization model, there are advantages to formulating your model as a linear program (LP), avoiding non-linear relationships.  Linear programs solve more robustly than non-linear programs, and usually solve faster than their non-linear counterparts even when there are mixed-integer decision variables.&lt;br /&gt;
&lt;br /&gt;
Many problems that seem non-linear at the outset can be converted into a linear formulation with sufficient ingenuity, often by changing the set of decision variables used to represent the problem and its search space, and by introducing auxilliary integer and boolean variables and auxilliary constraints.  In general, this transformation is not easy and requires substantial creativity and analytical skills.&lt;br /&gt;
&lt;br /&gt;
This page is devoted to cataloging various cases that come up with solutions for how these can be encoded in a linear fashion.&lt;br /&gt;
&lt;br /&gt;
== Piecewise linear relationships ==&lt;br /&gt;
&lt;br /&gt;
Income tax is a function of taxable income, but in the US is determined according to a piecewise-linear specification (with the slope changing at different tax brackets).  In other cases, a non-linear relationship between two scalar variables can be approximated by a piecewise linear curve, as in this example:&lt;br /&gt;
&lt;br /&gt;
[[image:pwl_relationship.png]]&lt;br /&gt;
&lt;br /&gt;
Structured optimization in Analytica processes piecewise-linear relationships automatically for you when these appear within your model through the use of the [[LinearInterp]] function.  A PWL curve is specified by a set of points, ''(d,r)'', containing the break points in the curve.  In Analytica, these would be arrays ''d'' and ''r'' sharing a common index ''i''.  The result, ''y'' is then computed as &amp;lt;code&amp;gt;[[LinearInterp]](d,r,x,i)&amp;lt;/code&amp;gt;.  To be linear, the arrays ''d'' and ''r'' cannot depend on decision variables of the optimization.&lt;br /&gt;
&lt;br /&gt;
Calls to [[LinearInterp]] can appear anywhere in your model.  [[DefineOptimization]] processes these automatically and adds several binary and continuous auxilliary variables to the underlying optimization problem while preserving linearity.&lt;br /&gt;
&lt;br /&gt;
== Semi-continuous Domains ==&lt;br /&gt;
&lt;br /&gt;
A certain power plant can either be ''off'', or its power output is bounded 100MW and 500MW.  &lt;br /&gt;
&lt;br /&gt;
 Decision PowerPlantOutput&lt;br /&gt;
 Domain: [[Continuous]](100M,500M,orZero:true)&lt;br /&gt;
&lt;br /&gt;
== Static Conditional Constraints ==&lt;br /&gt;
&lt;br /&gt;
A constraint with one or more intrinsic indexes specifies an array of scalar constraints.  Conditions arise where only a subset of that array should be enforced.  When the condition that defines which elements of the array should be enforced does not depend on any decision variables, then we say the conditional is ''static'' - it will remain the same through the optimization search.&lt;br /&gt;
&lt;br /&gt;
Let's assume the constraint with intrinsic indexes ''I'' and ''J'' is of the form:&lt;br /&gt;
:&amp;lt;code&amp;gt;F(x,y)&amp;lt;=0&amp;lt;/code&amp;gt;     only when ''B'' is true&lt;br /&gt;
where ''F(x,y)'' and ''B'' are array-valued, but ''B'' does not depend on decision variables.  &lt;br /&gt;
&lt;br /&gt;
To accomplish this, you can force the non-active constraints to be vacuous, or you can cause their constaint part to be [[Null]], or you can transform the constraint to include only the active components.  Each will be demonstrated here.&lt;br /&gt;
&lt;br /&gt;
* Make the constraint vacuous when ''B'' is false&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;F(x,y) &amp;lt;= ([[If]] B [[Then]] 0 [[Else]] [[INF]]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Make the constant be [[Null]] when ''B'' is false&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;F(x,y) &amp;lt;= ([[If]] B [[Then]] 0 [[Else]] [[Null]])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Transform to include only the active constraints.&lt;br /&gt;
&lt;br /&gt;
:Index K := 1..[[Sum]](B,I,J)&lt;br /&gt;
:Index L := ['I','J','F']&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[[MdArrayToTable]]([[If]] B [[Then]] F(x,y) [[Else]] [[Null]],K,L)[L='F'] &amp;lt;= 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The transformation approach minimizes the number of scalar constraints in the LP formulation, so is essentially the most efficient of these.&lt;br /&gt;
&lt;br /&gt;
== Varying Conditional Constraints ==&lt;br /&gt;
&lt;br /&gt;
When a constraint should be enforced only under certain conditions, and those conditions vary with the value of decision variables, this is referred to as a ''varying conditional constraint''.  &lt;br /&gt;
&lt;br /&gt;
In psuedo-code (but not actual Analytica syntax), a varying conditional constraint is like:&lt;br /&gt;
:If B(x,y) Then ( F(x,y) &amp;lt;= 0 )&lt;br /&gt;
&lt;br /&gt;
where ''B'' is a boolean 0,1 condition that is linear in the decision variables (usually involving boolean decision variables).  We write B and F in function call notation to emphasize the dependence on decision variables.&lt;br /&gt;
&lt;br /&gt;
In a non-linear formulation, this can be easily captured using a vacuous constraint method:&lt;br /&gt;
:F(x,y) &amp;lt;= [[If]] B(x,y) [[Then]] 0 else [[INF]]&lt;br /&gt;
&lt;br /&gt;
This formulation, however, is not linear.  A solution is to write&lt;br /&gt;
&lt;br /&gt;
:F(x,y) &amp;lt;= (1-B(x,y)) * 10M&lt;br /&gt;
&lt;br /&gt;
This formulation preserves linearity and works as long as it can be guaranteed that ''F(x,y)'' would never exceed 10M.  (You would adjust the big number appropriately for your problem, of course).  You cannot use [[INF]] as the big number since 0*[[INF]] is [[NAN]] (not 0).  It is best to keep the big number as small as possible since this has an impact on the numeric stability of the solution process.&lt;br /&gt;
&lt;br /&gt;
Using this technique, a varying conditional equality constraint must be broken into two inequality constraints.  &lt;br /&gt;
:If B(x,y) Then (F(x,y) = 0)&lt;br /&gt;
is encoded with these two linear constraints:&lt;br /&gt;
:F(x,y) &amp;lt;= (1-B(x,y)) * 10M&lt;br /&gt;
:(B(x,y)-1) * 10M &amp;lt;= F(x,y)&lt;br /&gt;
&lt;br /&gt;
== Leave &amp;quot;On&amp;quot; for a minimum number of periods ==&lt;br /&gt;
&lt;br /&gt;
If a power plant is turned on, it must remain on for a minimum of the following three time periods (i.e., is on for at least 4 consecutive time periods).  This can be encoded by introducing an auxilliary boolean variable, ''PlantCommit'', when is true when we are committed to at least 3 more periods of being on.  &lt;br /&gt;
&lt;br /&gt;
:Decision PlantOn&lt;br /&gt;
:Domain: [[Boolean]]()&lt;br /&gt;
:Intrinsic Index: Time&lt;br /&gt;
&lt;br /&gt;
:Decision PlantCommit&lt;br /&gt;
:Domain: [[Boolean]]()&lt;br /&gt;
:Intrinsic Index:Time&lt;br /&gt;
&lt;br /&gt;
:Index Steps := 0..3&lt;br /&gt;
&lt;br /&gt;
:Constraint: Stay_on_for_3&lt;br /&gt;
:Intrinsic Index: Time&lt;br /&gt;
:Definition: sum(PlantOn[@Time=@Time+Steps],Steps) &amp;gt;= 4*PlantCommit&lt;br /&gt;
&lt;br /&gt;
:Constraint On_During_Commit&lt;br /&gt;
:Intrinsic Index:Time&lt;br /&gt;
:Definition: PlantCommit &amp;lt;= PlantOn&lt;br /&gt;
&lt;br /&gt;
== Penalty for a change from a nominal value ==&lt;br /&gt;
&lt;br /&gt;
You want to incur a penalty if the decision variable differs from some nominal value.  For example, if you were to rebalance your portfolio, you would incur a sales commission.&lt;br /&gt;
&lt;br /&gt;
:Index Holding&lt;br /&gt;
&lt;br /&gt;
:Decision Allocation&lt;br /&gt;
:Domain: [[Continuous]](0,max_allocation)&lt;br /&gt;
:Intrinsic: Holding&lt;br /&gt;
&lt;br /&gt;
:Variable CurAllocation&lt;br /&gt;
:Definition: Table(Holding)&lt;br /&gt;
&lt;br /&gt;
:Decision Change&lt;br /&gt;
:Domain: [[Boolean]]()&lt;br /&gt;
:Intrinsic: Holding&lt;br /&gt;
&lt;br /&gt;
:Constant Penalty_for_change := 10&lt;br /&gt;
&lt;br /&gt;
:Variable Penalty&lt;br /&gt;
:Definition: Sum( Penalty_for_change * Change, Holding )&lt;br /&gt;
&lt;br /&gt;
:Constraint Enforce_change&lt;br /&gt;
:Definition: -Max_allocation * Change &amp;lt;= Allocation-CurAllocation &amp;lt;= Max_allocation * Change&lt;br /&gt;
:Intrinsic: Holding&lt;br /&gt;
&lt;br /&gt;
To see this idea encoded (in a car-dealer context), see the following example model:&lt;br /&gt;
[[media:Penalize_Change_in_LP.ana|Penalize_Change_in_LP.ana]]&lt;br /&gt;
&lt;br /&gt;
== Mixed Complementarity, #1 ==&lt;br /&gt;
&lt;br /&gt;
A simple form of mixed complementarity is the following:&lt;br /&gt;
::&amp;lt;math&amp;gt;x=0 \mbox{ and } 0&amp;lt;=F(x)\mbox{, or } 0&amp;lt;=x \mbox{ and } F(x)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Geometrically, on a plot where x is on the horizontal, and the constraint is the vertical axis, this mixed complementarity constraint specifies that the solution must lie on either the positive x axis or on the positive y axis.&lt;br /&gt;
&lt;br /&gt;
The above is equivalent to the following non-linear formulation:&lt;br /&gt;
::&amp;lt;math&amp;gt;x&amp;gt;=0, F(x)&amp;gt;=0 \mbox{ and } x\cdot F(x)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This representation of complementarity cannot be captured exactly in a linear form (with F(x) being linear) using the mixed-integer mechanisms in Structured Optimization, but an approximation to it can be, where the approximation is:&lt;br /&gt;
::&amp;lt;math&amp;gt;0&amp;lt;=x&amp;lt;=U, 0&amp;lt;=F(x)&amp;lt;=U\mbox{, and } x\cdot F(x)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
or equivalently:&lt;br /&gt;
::&amp;lt;math&amp;gt;x=0 \mbox{ and } 0&amp;lt;=F(x)&amp;lt;=U\mbox{, or } 0&amp;lt;=x&amp;lt;=U \mbox{ and } F(x)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In other words, we've artificially imposed an upper bound.  If the constant U is made very large, then the approximation approaches the desired formulation (but for numeric stability, it is preferable to keep U as small as reasonable).&lt;br /&gt;
&lt;br /&gt;
The formulation is captured with linear constraints by introducing an auxilliary boolean variable, '''''b''''':&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
:0 &amp;lt;= x &amp;lt;= (1-b) * U&lt;br /&gt;
:0 &amp;lt;= F(x) &amp;lt;= b * U&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mixed Complementarity, #3 ==&lt;br /&gt;
&lt;br /&gt;
Another general form of mixed complementarity is where one of the following must hold:&lt;br /&gt;
::&amp;lt;math&amp;gt;\begin{array}{ccc}&lt;br /&gt;
L=x &amp;amp; \mbox{and} &amp;amp; F(x)&amp;lt;=0 \\&lt;br /&gt;
L&amp;lt;=x&amp;lt;=U &amp;amp; \mbox{and} &amp;amp; F(x)=0 \\&lt;br /&gt;
x=U &amp;amp; \mbox{and} &amp;amp; F(x)&amp;gt;=0&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again, an approximation must be employed which adds an artificial constraint:&lt;br /&gt;
::&amp;lt;math&amp;gt;-K &amp;lt;= F(x) &amp;lt;= K&amp;lt;/math&amp;gt;&lt;br /&gt;
where &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is sufficiently large constant.  With the addition of the artificial constraint, the MCP is encoded by introducing three boolean variables, &amp;lt;code&amp;gt;b1, b2,&amp;lt;/code&amp;gt; and &amp;lt;/code&amp;gt;b3&amp;lt;code&amp;gt;, and encoding as&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
:b1+b2+b3=1&lt;br /&gt;
:L+(U-L)*b3 &amp;lt;= x &amp;lt;= U-(U-L)*b1&lt;br /&gt;
:-K+K*b2 &amp;lt;= F(x) &amp;lt;= K-K*b2&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Please Contribute =&lt;br /&gt;
&lt;br /&gt;
If you encounter cases like these that may be of general interest, then please add them here along with the method you found for expressing them in a linear fashion.&lt;br /&gt;
&lt;br /&gt;
= See Also =&lt;br /&gt;
&lt;br /&gt;
* [[DefineOptimization]]&lt;/div&gt;</summary>
		<author><name>Rhoro</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Talk:Modeling_Depreciation&amp;diff=23159</id>
		<title>Talk:Modeling Depreciation</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Talk:Modeling_Depreciation&amp;diff=23159"/>
		<updated>2013-02-14T22:32:51Z</updated>

		<summary type="html">&lt;p&gt;Rhoro: How does the Dynamic version of this work?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Can we have some explanation of how exactly the Dynamic version works?  It has important advantages to it, in that it can handle the correct amortization of multiple additions to the balance, but the definition logic is quite opaque and does not lend itself to self-documentation.&lt;/div&gt;</summary>
		<author><name>Rhoro</name></author>
	</entry>
</feed>