 <?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=Jhernandez3</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=Jhernandez3"/>
	<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php/Special:Contributions/Jhernandez3"/>
	<updated>2026-06-08T19:30:17Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.9</generator>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Introduction_to_Optimizer&amp;diff=39046</id>
		<title>Introduction to Optimizer</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Introduction_to_Optimizer&amp;diff=39046"/>
		<updated>2016-01-03T16:35:27Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* To Validate the Activation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;This introduction explains what  the Analytica Optimizer is and how you can obtain a copy of the software. It also details how you can activate and validate your copy of as well as activate high-end, add-on engines for the Optimizer.&lt;br /&gt;
==What is the Analytica Optimizer?==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer enhances Analytica with powerful functions for finding optimal decisions and solving difficult equations. Most Analytica Optimizer models aim to find a decision strategy — values for ''decision'' variables — to maximize or minimize a quantified objective subject to a set of equality or inequality constraints. Some models seek a feasible solution that satisfies a set of constraints without regard to an objective.&lt;br /&gt;
&lt;br /&gt;
===Types of Optimization ===&lt;br /&gt;
&lt;br /&gt;
A ''linear program'' (LP) requires the objective function and constraints to be linear functions of decision variables. LPs are solvable using straightforward algorithms that yield unique (global) maximizing or minimizing solutions. Although LP algorithms are well understood, large-scale optimizations can be computationally complex.&lt;br /&gt;
&lt;br /&gt;
When pairs of decision variables are multiplied together, including squared decision variables, quadratic terms result. A ''quadratic problem'' (QP) has quadratic terms in the objective and linear constraints. A generalization of a QP, in which one or more constraints contains quadratic terms, is called a ''Quadratically Constrained Program'' (QCP). If the objective and constraint functions satisfy a mathematical property known as convexity, QP solutions are always unique (global). Non-convex formulations can result in “local” solutions that may or may not represent the global optimum.&lt;br /&gt;
&lt;br /&gt;
''Nonlinear Programming'' (NLP) does not impose restrictions on the mathematical properties of objectives and constraints. A wide variety of computational algorithms can be applied to NLPs. Strategies include gradient tracking and genetic algorithms that allow potential solutions to compete within the computation.&lt;br /&gt;
&lt;br /&gt;
With all classes of optimization, Analytica supports variables that are continuous, discrete (integer, Boolean, grouped), or a mixture of continuous and discrete decision variables.&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer analyzes your objective functions and constraints automatically to discover the type of optimization and select the appropriate solver engine.&amp;lt;!--See the section on the Type parameter of DefineOptimization() for more details on these types of Optimization.--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Premium Solver Specifications===&lt;br /&gt;
&lt;br /&gt;
The standard edition of Analytica Optimizer uses the Premium Solver Platform licensed from Frontline Systems, Inc., the developer of the Optimizer/Solver in Microsoft Excel, and a world leader in spreadsheet optimization. &lt;br /&gt;
&lt;br /&gt;
The Premium Solver is the leading add-on software for spreadsheet optimization, and incorporates state-of-the-art technologies. The LP and QP solver engines that come included with Analytica Optimizer handle up to 8000 variables and 8000 constraints in addition to bounds on the decision variables. Up to 2000 of these variables may be constrained to be integer-valued for ''Mixed-Integer Programming''. Up to 2000 decision variables of any kind are supported when quadratic constraints are present. The NLP solvers offer hybrid methods using classical gradient-search and evolutionary (genetic) algorithms for smooth and discontinuous objective functions with up to 500 decision variables and 250 constraints. Large scale add-on engines that eliminate the limit on variables and constraints entirely are also available at extra cost (see [http://wiki.analytica.com/index.php?title=Introduction_to_the_Guide#Installing_Add-On_Optimizer_Engines Installing Add-On Optimizer Engines]). &lt;br /&gt;
If your problems exceed these limits, or you need a solver that is even faster, you can add any of a number of high-end solvers, LP, QP, or NLP, that include some of the most powerful solver engines available anywhere (see  the [http://wiki.analytica.com/index.php?title=DefineOptimization#Engine_Settings Engine] Settings parameter of [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() for details.&lt;br /&gt;
&lt;br /&gt;
===Optimizing with Uncertain Values and Intelligent Arrays===&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer performs optimization under uncertainty to maximize expected values and minimize loss percentiles, as well as other statistical functions of objectives and constraints. Analytica allows users to combine Intelligent ''arrays'' with all classes of optimization. Thus, you can easily create ''arrays of optimizations'' conditioned on samples from uncertain variables, for parametric analysis of effects of key assumptions, and for each time period in a dynamic model.&lt;br /&gt;
&lt;br /&gt;
===Compatibility with Other Analytica Editions===&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer is an edition of Analytica that includes all the functionalities of the Analytica Enterprise edition. After using Analytica Optimizer to create optimizing models, you can deliver them to end users on the desktop using Analytica Power Player with Optimizer, or via a web browser on a server using the Analytica Web Player (AWP) or Analytica Decision Engine (ADE) with an Optimizer license.&lt;br /&gt;
&lt;br /&gt;
==Obtaining the Analytica Optimizer==&lt;br /&gt;
&lt;br /&gt;
You can purchase a license for the Analytica Optimizer or the Analytica Power Player with Optimizer from Lumina Decision Systems. Or you can purchase an upgrade to Optimizer if you already have a license for the Analytica Enterprise or Professional editions.&lt;br /&gt;
&lt;br /&gt;
If your copy of Analytica is for release 4.2 or earlier, you need to upgrade to release 4.3 or later to obtain the newest Optimizer features as described in this Guide. Substantial discounts are available if you have a maintenance agreement for Analytica 4.2 (included free for 12 months from purchase).&lt;br /&gt;
&lt;br /&gt;
For more information: &lt;br /&gt;
&lt;br /&gt;
* Visit the [[ http://www.lumina.com/|Lumina web site]],  or &lt;br /&gt;
* Call Lumina at 650-212-1212&lt;br /&gt;
&lt;br /&gt;
==Activating your Analytica Optimizer==&lt;br /&gt;
&lt;br /&gt;
If you have purchased an individual license of Analytica Optimizer, you will be sent an Activation Key. This key allows you to retrieve a license specific to your computer and account from Lumina’s activation server. The license itself is contained in a file, usually stored in the Analytica installation directory and usually named Analytica.lic. The term activation refers to the process of obtaining this file.&lt;br /&gt;
&lt;br /&gt;
===First-Time Install===&lt;br /&gt;
&lt;br /&gt;
When installing Analytica for the first time, you will run the Analytica installer program, which you can find in [[ http://www.lumina.com/support/downloads/|Lumina Downloads]]. If you have purchased the 64-bit edition, download Ana64Setup.exe, otherwise download AnaSetup.exe. &lt;br /&gt;
&lt;br /&gt;
If you run the installer from your own end-user account (recommended), then enter the activation key when prompted, and the installer will automatically retrieve and install your license file over the internet (if you don’t have an internet connection, see “Manual Activation”). If a system administrator runs the installer from an account other than your own end-user account, leave the activation key field blank, then after it is installed, log into your own account and follow the instructions for “Previous edition already installed”.&lt;br /&gt;
&lt;br /&gt;
===Previous Edition Already Installed===&lt;br /&gt;
&lt;br /&gt;
If you already have an edition of Analytica 4.6 installed (including the Trial Edition), your installation includes the Analytica Optimizer files and there is no need to download new software. However, you need to enter a new activation key with the Optimizer option.&lt;br /&gt;
&lt;br /&gt;
To activate Analytica Optimizer while you are connected to the internet:&lt;br /&gt;
&lt;br /&gt;
# Start Analytica in the usual way, e.g., via the Windows Start menu, or by doubleclicking an Analytica model file. &lt;br /&gt;
# From Analytica’s '''Help menu''', select '''Update License''' to display the '''Analytica Licensing Information''' box. &lt;br /&gt;
# Enter the activation key into the '''License ID''' box, replacing the license name currently displayed. As soon as the key is correctly entered, an '''Activate''' button appears to the right. &lt;br /&gt;
# Click '''Activate''' to retrieve your license from the activation server. Your license name then appears in the '''License ID''' box. &lt;br /&gt;
# Click '''OK'''. &lt;br /&gt;
# Exit and restart Analytica.&lt;br /&gt;
&lt;br /&gt;
===Manual Activation===&lt;br /&gt;
&lt;br /&gt;
Automatic activation will fail if you do not have a connection to the internet, or if your firewalls and proxy servers are configured to prevent Analytica from communicating with the activation server. In this case, you can obtain a license file through manual activation. You will need your activation key and the Host ID and User ID that are displayed at the bottom of the Analytica Licensing Information dialog from Step 2 above. Enter this information into the form at http://www.lumina.com/support/activate-analytica/, and the license file will be emailed to you.&lt;br /&gt;
&lt;br /&gt;
===Floating License===&lt;br /&gt;
&lt;br /&gt;
If your organization provides you with a floating license to Analytica Optimizer, your IT department will provide you with the name (and possibly IP port) of the Reprise License Manager (RLM) server computer where your IT department will have already installed and activated a floating license.&lt;br /&gt;
&lt;br /&gt;
Run the Analytica installer as described in “First-Time Install”, but during the install, on the '''License Information''' page, select '''Centrally managed license (RLM License Server)''' and enter the ''server host name'', or '''port@host''', provided to you.&lt;br /&gt;
&lt;br /&gt;
If you already have Analytica installed, you can also enter this information into the Analytica License Information by selecting '''Update License''' from the '''Help''' menu.&lt;br /&gt;
&lt;br /&gt;
===To Validate Successful Activation ===&lt;br /&gt;
&lt;br /&gt;
To verify successful activation of Analytica Optimizer, examine the splash screen when Analytica starts up, or go to '''Help &amp;gt; About Analytica'''. The splash screen should display '''Analytica Optimizer''', as shown below. &lt;br /&gt;
&lt;br /&gt;
[[File:1-1.png|400px]]&lt;br /&gt;
&lt;br /&gt;
==Installing Add-On Optimizer Engines==&lt;br /&gt;
&lt;br /&gt;
You can add other engines for solving optimization problems to the Analytica Optimizer. Some engines provide superior performance on particular classes of optimization problems, and some engines handle larger numbers of variables or constraints. The following add-on engines are available:&lt;br /&gt;
&lt;br /&gt;
* Large Scale LP&lt;br /&gt;
* Large Scale SQP &lt;br /&gt;
* Large Scale GRG &lt;br /&gt;
* Gurobi (LP/QP)&lt;br /&gt;
* XPRESS (LP/QP)&lt;br /&gt;
* MOSEK (cQCP/NLP) &lt;br /&gt;
* KNITRO (NLP)&lt;br /&gt;
* OptQuest (NSP)&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you purchase an add-on engine license, or obtain an add-on engine trial, Lumina will provide you with the following items:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;EngineSetup.exe&amp;lt;/tt&amp;gt; (or &amp;lt;tt&amp;gt;EngineSetup64.exe&amp;lt;/tt&amp;gt; for Analytica 64-bit users), the add-on engine installer from Frontline Systems.&lt;br /&gt;
# The password required by EngineSetup.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;SolverAddons.lic&amp;lt;/tt&amp;gt; file.&lt;br /&gt;
# A Lumina activation key.&lt;br /&gt;
&lt;br /&gt;
===To Install an Add-On Engine===&lt;br /&gt;
&lt;br /&gt;
# Install Analytica Optimizer first, if you have not already done so.  &lt;br /&gt;
# Run &amp;lt;tt&amp;gt;EngineSetup.exe&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;EngineSetup64.exe&amp;lt;/tt&amp;gt;, the add-on engine installation program. Use &amp;lt;tt&amp;gt;EngineSetup64.exe&amp;lt;/tt&amp;gt; when you are using Analytica 64-bit.  &lt;br /&gt;
# The &amp;lt;tt&amp;gt;EngineSetup&amp;lt;/tt&amp;gt; program will ask for a password and activation key. Enter the password provided to you by email when you are sent the EngineSetup program. You may leave the '''activation key''' blank. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip title=&amp;quot;Note&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you're using the v14 release of EngineSetup, you will need to correct a bug that places the release's settings in the v11 registry hive instead of the v14 registry hive. &lt;br /&gt;
&lt;br /&gt;
To correct the bug: &lt;br /&gt;
&lt;br /&gt;
# From the '''Start''' menu, run &amp;lt;tt&amp;gt;RegEdit.exe&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Navigate to &amp;lt;tt&amp;gt;HKEY_LOCAL_MACHINE/Software/Lumina Decision Systems/SolverEngines&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Right-click on &amp;lt;tt&amp;gt;v11&amp;lt;/tt&amp;gt;, select '''Rename''', then change to&amp;lt;tt&amp;gt; v14&amp;lt;/tt&amp;gt;. &lt;br /&gt;
# Start up Analytica and select '''Update License''' from the Help menu. &lt;br /&gt;
# Enter the activation key provided into the '''License ID''' box, then click '''Activate'''&lt;br /&gt;
&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===To Validate the Activation===&lt;br /&gt;
&lt;br /&gt;
To test for proper installation, open Analytica, and create a variable defined as follows: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Variable Engines := OptEngineInfo(&amp;quot;All&amp;quot;,&amp;quot;TrialPeriod&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The names of available engines should appear with non-zero values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Analytica Optimizer Guide / {{PAGENAME}} / Quick Start&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39045</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39045"/>
		<updated>2016-01-03T16:33:58Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* Decisions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Decision Radius := 1&lt;br /&gt;
 Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Variable Opt := &lt;br /&gt;
 DefineOptimization(&lt;br /&gt;
      Decisions: Radius, Height, &lt;br /&gt;
      Constraints: Volume_Constraint, &lt;br /&gt;
      Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Decision: Identifier for the counterpart Decision input node&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Decision Opt_Radius := OptSolution(Opt, Radius) &lt;br /&gt;
 Decision Opt_Height := OptSolution(Opt, Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Objective Opt_Surface := OptObjective(Opt)&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Variable Status := OptStatusText(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Variable Radius := Sequence(4.5, 6.5, 0.1) &lt;br /&gt;
 Variable Height := Required_volume/(pi*Radius^2)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Decision X := 0 (or any value at all)&lt;br /&gt;
 Initial Guess of X := [-4, 2, 0, 2, 4]&lt;br /&gt;
 Objective Polynomial :=     &lt;br /&gt;
      1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&lt;br /&gt;
 Variable Opt := DefineOptimization(&lt;br /&gt;
      Decision: X,&lt;br /&gt;
      Maximize: Polynomial)&lt;br /&gt;
 Variable X_solution := OptSolution(Opt,X)&lt;br /&gt;
 Objective Max_Objective := OptObjective(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Introduction / {{PAGENAME}} / Optimization Characteristics&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39044</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39044"/>
		<updated>2016-01-03T16:32:51Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* The Initial Guess Attribute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Decision Radius := 1&lt;br /&gt;
&lt;br /&gt;
 Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Variable Opt := &lt;br /&gt;
 DefineOptimization(&lt;br /&gt;
      Decisions: Radius, Height, &lt;br /&gt;
      Constraints: Volume_Constraint, &lt;br /&gt;
      Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Decision: Identifier for the counterpart Decision input node&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Decision Opt_Radius := OptSolution(Opt, Radius) &lt;br /&gt;
 Decision Opt_Height := OptSolution(Opt, Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Objective Opt_Surface := OptObjective(Opt)&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Variable Status := OptStatusText(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Variable Radius := Sequence(4.5, 6.5, 0.1) &lt;br /&gt;
 Variable Height := Required_volume/(pi*Radius^2)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;Decision X := 0 (or any value at all)&lt;br /&gt;
 Initial Guess of X := [-4, 2, 0, 2, 4]&lt;br /&gt;
 Objective Polynomial :=     &lt;br /&gt;
      1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&lt;br /&gt;
 Variable Opt := DefineOptimization(&lt;br /&gt;
      Decision: X,&lt;br /&gt;
      Maximize: Polynomial)&lt;br /&gt;
 Variable X_solution := OptSolution(Opt,X)&lt;br /&gt;
 Objective Max_Objective := OptObjective(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Introduction / {{PAGENAME}} / Optimization Characteristics&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39043</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39043"/>
		<updated>2016-01-03T15:57:10Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* The Initial Guess Attribute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Radius := 1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Decisions: Radius, Height, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Constraints: Volume_Constraint, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Decision: Identifier for the counterpart Decision input node&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Radius := OptSolution(Opt, Radius) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Height := OptSolution(Opt, Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Opt_Surface := OptObjective(Opt)&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Status := OptStatusText(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Radius := Sequence(4.5, 6.5, 0.1) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Height := Required_volume/(pi*Radius^2)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision X := 0 (or any value at all)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Initial Guess of X := [-4, 2, 0, 2, 4] &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Polynomial := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Decision: X, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Maximize: Polynomial) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable X_solution := OptSolution(Opt,X)&amp;lt;/code&amp;gt; &lt;br /&gt;
&amp;lt;code&amp;gt;Objective Max_Objective := OptObjective(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Introduction / {{PAGENAME}} / Optimization Characteristics&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39042</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39042"/>
		<updated>2016-01-03T15:47:07Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* Chapter Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Radius := 1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Decisions: Radius, Height, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Constraints: Volume_Constraint, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Decision: Identifier for the counterpart Decision input node&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Radius := OptSolution(Opt, Radius) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Height := OptSolution(Opt, Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Opt_Surface := OptObjective(Opt)&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Status := OptStatusText(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Radius := Sequence(4.5, 6.5, 0.1) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Height := Required_volume/(pi*Radius^2)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision X := 0 (or any value at all)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Initial Guess of X := [-4, 2, 0, 2, 4] &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Polynomial := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Decision: X, &amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Maximize: Polynomial) &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Variable X_solution := OptSolution(Opt,X) &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Max_Objective := OptObjective(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Introduction / {{PAGENAME}} / Optimization Characteristics&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39041</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39041"/>
		<updated>2016-01-03T15:45:52Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* The Initial Guess Attribute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Radius := 1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Decisions: Radius, Height, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Constraints: Volume_Constraint, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Decision: Identifier for the counterpart Decision input node&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Radius := OptSolution(Opt, Radius) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Height := OptSolution(Opt, Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Opt_Surface := OptObjective(Opt)&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Status := OptStatusText(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Radius := Sequence(4.5, 6.5, 0.1) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Height := Required_volume/(pi*Radius^2)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision X := 0 (or any value at all)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Initial Guess of X := [-4, 2, 0, 2, 4] &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Polynomial := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Decision: X, &amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Maximize: Polynomial) &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Variable X_solution := OptSolution(Opt,X) &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Max_Objective := OptObjective(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&amp;lt;footer&amp;gt; Introduction / &amp;lt;/nowiki&amp;gt;{{PAGENAME}} / Optimization Characteristics&amp;lt;nowiki&amp;gt;&amp;lt;/footer&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39040</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39040"/>
		<updated>2016-01-03T15:44:45Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Radius := 1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Decisions: Radius, Height, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Constraints: Volume_Constraint, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Decision: Identifier for the counterpart Decision input node&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Radius := OptSolution(Opt, Radius) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Height := OptSolution(Opt, Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Opt_Surface := OptObjective(Opt)&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Status := OptStatusText(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Radius := Sequence(4.5, 6.5, 0.1) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Height := Required_volume/(pi*Radius^2)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision X := 0 (or any value at all)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Initial Guess of X := [-4, 2, 0, 2, 4] &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Polynomial := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;code&amp;gt;1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;code&amp;gt;Variable Opt := DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Decision: X, &amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Maximize: Polynomial) &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Variable X_solution := OptSolution(Opt,X) &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Max_Objective := OptObjective(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;tip title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&amp;lt;footer&amp;gt; Introduction / &amp;lt;/nowiki&amp;gt;{{PAGENAME}} / Optimization Characteristics&amp;lt;nowiki&amp;gt;&amp;lt;/footer&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39039</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39039"/>
		<updated>2016-01-03T15:41:44Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* Obtaining the Optimized Objective Value */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Radius := 1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Decisions: Radius, Height, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Constraints: Volume_Constraint, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Decision: Identifier for the counterpart Decision input node&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Radius := OptSolution(Opt, Radius) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Height := OptSolution(Opt, Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Opt_Surface := OptObjective(Opt)&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Status := OptStatusText(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Radius := Sequence(4.5, 6.5, 0.1) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Height := Required_volume/(pi*Radius^2)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision X := 0 (or any value at all)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Initial Guess of X := [-4, 2, 0, 2, 4]&amp;lt;/code&amp;gt; &lt;br /&gt;
&amp;lt;code&amp;gt;Objective Polynomial :=&amp;lt;/code&amp;gt; &lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;code&amp;gt;1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := DefineOptimization(&amp;lt;/code&amp;gt; &lt;br /&gt;
:&amp;lt;code&amp;gt;Decision: X, &amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Maximize: Polynomial) &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Variable X_solution := OptSolution(Opt,X) &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Max_Objective := OptObjective(Opt)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Introduction / {{PAGENAME}} / Optimization Characteristics&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39038</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39038"/>
		<updated>2016-01-03T15:37:30Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* Obtaining the Solution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Radius := 1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Decisions: Radius, Height, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Constraints: Volume_Constraint, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Decision: Identifier for the counterpart Decision input node&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Radius := OptSolution(Opt, Radius) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Height := OptSolution(Opt, Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
 Objective Opt_Surface := &amp;lt;tt&amp;gt;OptObjective(Opt)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
 Variable Status := &amp;lt;tt&amp;gt;OptStatusText(Opt)&amp;lt;/tt&amp;gt; &lt;br /&gt;
This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
 Variable Radius := Sequence(4.5, 6.5, 0.1) &lt;br /&gt;
&lt;br /&gt;
 Variable Height := Required_volume/(pi*Radius^2) &lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Decision X := 0 (or any value at all)&lt;br /&gt;
Initial Guess of X := [-4, 2, 0, 2, 4] &lt;br /&gt;
Objective Polynomial := &lt;br /&gt;
      1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&lt;br /&gt;
Variable Opt := DefineOptimization( &lt;br /&gt;
      Decision: X, &lt;br /&gt;
      Maximize: Polynomial) &lt;br /&gt;
Variable X_solution := OptSolution(Opt,X) &lt;br /&gt;
Objective Max_Objective := OptObjective(Opt)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Introduction / {{PAGENAME}} / Optimization Characteristics&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39037</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39037"/>
		<updated>2016-01-03T15:36:54Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* Obtaining the Solution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Radius := 1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Decisions: Radius, Height, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Constraints: Volume_Constraint, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Decision: Identifier for the counterpart Decision input node  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Radius := OptSolution(Opt, Radius) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Opt_Height := OptSolution(Opt, Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
 Objective Opt_Surface := &amp;lt;tt&amp;gt;OptObjective(Opt)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
 Variable Status := &amp;lt;tt&amp;gt;OptStatusText(Opt)&amp;lt;/tt&amp;gt; &lt;br /&gt;
This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
 Variable Radius := Sequence(4.5, 6.5, 0.1) &lt;br /&gt;
&lt;br /&gt;
 Variable Height := Required_volume/(pi*Radius^2) &lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Decision X := 0 (or any value at all)&lt;br /&gt;
Initial Guess of X := [-4, 2, 0, 2, 4] &lt;br /&gt;
Objective Polynomial := &lt;br /&gt;
      1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&lt;br /&gt;
Variable Opt := DefineOptimization( &lt;br /&gt;
      Decision: X, &lt;br /&gt;
      Maximize: Polynomial) &lt;br /&gt;
Variable X_solution := OptSolution(Opt,X) &lt;br /&gt;
Objective Max_Objective := OptObjective(Opt)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Introduction / {{PAGENAME}} / Optimization Characteristics&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39036</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39036"/>
		<updated>2016-01-03T15:34:36Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* Objectives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Radius := 1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Decisions: Radius, Height, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Constraints: Volume_Constraint, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
«&amp;lt;tt&amp;gt; OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt; .&lt;br /&gt;
• Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
• Decision: Identifier for the counterpart Decision input node &lt;br /&gt;
 Decision Opt_Radius := &amp;lt;tt&amp;gt;OptSolution(Opt, Radius)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
 Decision Opt_Height := &amp;lt;tt&amp;gt;OptSolution(Opt, Height)&amp;lt;/tt&amp;gt; &lt;br /&gt;
The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
 Objective Opt_Surface := &amp;lt;tt&amp;gt;OptObjective(Opt)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
 Variable Status := &amp;lt;tt&amp;gt;OptStatusText(Opt)&amp;lt;/tt&amp;gt; &lt;br /&gt;
This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
 Variable Radius := Sequence(4.5, 6.5, 0.1) &lt;br /&gt;
&lt;br /&gt;
 Variable Height := Required_volume/(pi*Radius^2) &lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Decision X := 0 (or any value at all)&lt;br /&gt;
Initial Guess of X := [-4, 2, 0, 2, 4] &lt;br /&gt;
Objective Polynomial := &lt;br /&gt;
      1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&lt;br /&gt;
Variable Opt := DefineOptimization( &lt;br /&gt;
      Decision: X, &lt;br /&gt;
      Maximize: Polynomial) &lt;br /&gt;
Variable X_solution := OptSolution(Opt,X) &lt;br /&gt;
Objective Max_Objective := OptObjective(Opt)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Introduction / {{PAGENAME}} / Optimization Characteristics&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39035</id>
		<title>Optimizer Quick Start</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Optimizer_Quick_Start&amp;diff=39035"/>
		<updated>2016-01-03T15:33:19Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* Decisions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This quick-start tutorial aims to show you how to:&lt;br /&gt;
* Set up a basic NLP optimization model using Decision, Objective, and Constraint Nodes&lt;br /&gt;
* Define the central Optimization node using the [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function&lt;br /&gt;
* Obtain solution output and status&lt;br /&gt;
* Specify domain types (i.e., integer, continuous, etc.) and bounds for decisions&lt;br /&gt;
* Combine parametric analysis with optimization&lt;br /&gt;
* Change initial guesses for non-convex solution spaces&lt;br /&gt;
&lt;br /&gt;
==Introduction to Structured Optimization==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer releases from version 4.3 onward include a set of features, collectively called Structured Optimization, designed to simplify the optimization modeling process. In Structured Optimization format, ''Linear Programming'' (LP), ''Quadratic Programming'' (QP) and ''Nonlinear Programming'' (NLP) optimizations can all be modeled in similar ways. All types of optimization are specified using the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&amp;lt;ref&amp;gt;DefineOptimization() supersedes the LPDefine(), QPDefine() and NLPDefine() function that were used to specify optimizations prior to Analytica 4.2. These functions remain available for backward compatibility, but are now deprecated.&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;function automatically analyzes your model to determine the type of optimization and selects the appropriate optimization engine, although you can still override this process if desired.&lt;br /&gt;
&lt;br /&gt;
Another significant change associated with Structured Optimization is the introduction of the Constraint  object type. Constraint  objects give users the ability to specify constraints, or arrays of constraints, in common expression format using equality or inequality operators. This intuitive interface allows users to easily integrate different types of constraints and to organize constraint arrays efficiently.&lt;br /&gt;
&lt;br /&gt;
This section includes simple NLP examples to demonstrate the roles of Decision variables, Constraint objects, Objective variables, and Decision attributes in the Structured Optimization framework. The same basic structure applies to LP and QP optimizations as well.&lt;br /&gt;
&lt;br /&gt;
== The Optimum Can Example ==&lt;br /&gt;
The Optimum Can example determines the dimensions of a cylindrical object having a minimum surface area for a given volume. Admittedly, this is not a very interesting optimization problem. In fact, the solution can be derived on paper using basic differential calculus. However, the simplicity of the example allows us to focus on the workflow and object relationships using the new Structured Optimization framework in Analytica. &lt;br /&gt;
&lt;br /&gt;
=== Decisions  ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-2.png|50px]]&lt;br /&gt;
&lt;br /&gt;
In this example, we will decide on the '''Radius''' and '''Height''' of a cylindrical vessel. We represent each of these as a Decision variable in the influence diagram. The values we define for these nodes will be used as initial guesses for optimization types that require an initial guess (''NLP'' or ''non-convex QP''). Otherwise, the definitions of these inputs are not important. We use 1cm as an initial guess for both the radius and height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Radius := 1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Decision Height := 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-3.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constants have no special interpretation in optimization definitions. They can be used as usual for values that stay constant in the model. In this example, we will use a Constant for the required volume which does not vary in the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constant Required_Volume := 1000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables&lt;br /&gt;
&lt;br /&gt;
[[File:2-4.png|50px]]&lt;br /&gt;
&lt;br /&gt;
General variables are used for intermediate values as well as for the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function described below. We also use a variable to define Volume of the cylinder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Volume := pi*Radius^2*Height&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constraints&lt;br /&gt;
&lt;br /&gt;
[[File:2-5.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Constraints contain equality or inequality conditions that restrict the range of optimized results. In this example, we use a constraint object to enforce the minimum volume requirement on our can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Constraint Volume_Constraint := (Volume &amp;gt;= Required_Volume)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
[[File:2-6.png|50px]]&lt;br /&gt;
&lt;br /&gt;
Most optimizations have an objective value to maximize or minimize. (Some problems are only concerned with feasible solutions that meet constraints.) In this example we are minimizing the surface area of our can. We define surface area using an Objective variable. The can has round disks at the top and base with surface area ('''πR2''') and a tubular side with surface area ('''2πRH''').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Objective Surface_area := 2 * (pi * Radius^2) + (2 * pi * Radius * Height)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()  Function&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() function is the key component of all Structured Optimization models. It brings all other components together, specifying the optimization to be performed. This function is typically placed in a Variable object in the center of our influence diagram. Although this function includes many optional parameters, we will only use the core parameters in this example: &lt;br /&gt;
* '''Decision:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the decision node (or a list of identifiers separated by commas if there are multiple decisions). Specify All to include all decision nodes in the model or All in module to include all desired decisions within a designated module. &lt;br /&gt;
&lt;br /&gt;
* '''Constraint:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Identifier for the constraint node (or a list of identifiers separated by commas if there are multiple constraints). Specify All to include all constraint nodes in the model or All in module to include all desired constraints within a designated module. You can also specify inequality or equality expressions directly, or omit the parameter entirely in an unconstrained optimization problem. &lt;br /&gt;
&lt;br /&gt;
* '''Maximize/Minimize:''' &amp;lt;br /&amp;gt;&lt;br /&gt;
:Use the words “Maximize” or “Minimize” depending on the type of problem. Follow this with an expression or with the identifier for the relevant objective node.&lt;br /&gt;
&lt;br /&gt;
We define our Define Optimization node as: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Opt := &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;     DefineOptimization(&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;          Decisions: Radius, Height, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;          Constraints: Volume_Constraint, &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;          Minimize: Surface_area)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Viewing the Optimization Object ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function evaluates to a special object that contains detailed information about the optimization. The object appears as a blue hyperlink that shows the type of optimization problem you have constructed. In this case we see it is NLP . You can double-click the optimization object to open a new window revealing internal details from the optimization engine. Clicking reference objects allows you to drill down to finer levels of detail. This information is also available by using the [[OptInfo]]() function.&lt;br /&gt;
&lt;br /&gt;
[[File:2-7.png|600px]]&lt;br /&gt;
&lt;br /&gt;
In this case, we have allowed Analytica to automatically determine the type of problem. Alternatively, you can specify the problem type along with the desired engine and other settings by adding optional parameters to &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;. See [[Optimizer Function Reference]] for more details about the Type and Engine parameters of &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Solution ===&lt;br /&gt;
Now that we have specified an optimization, how do we compute and view the result? You may be tempted to re-evaluate the Radius and Height decision variables to see if their values have changed. But this is not how optimization works in Analytica. Input values always retain their original definitions. (In this case, we simply used 1 as a dummy value for Radius and Height.) To obtain the solution, you need to create an output node defined with the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptSolution OptSolution]()&amp;lt;/tt&amp;gt; function. This function usually uses two parameters: &lt;br /&gt;
«&amp;lt;tt&amp;gt; OptSolution(Opt, Decision)&amp;lt;/tt&amp;gt; .&lt;br /&gt;
• Opt: Identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
• Decision: Identifier for the counterpart Decision input node &lt;br /&gt;
 Decision Opt_Radius := &amp;lt;tt&amp;gt;OptSolution(Opt, Radius)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
 Decision Opt_Height := &amp;lt;tt&amp;gt;OptSolution(Opt, Height)&amp;lt;/tt&amp;gt; &lt;br /&gt;
The Decision parameter is optional. If it is omitted, the solution will include all decisions along a local index named &amp;lt;tt&amp;gt; .DecisionVector&amp;lt;/tt&amp;gt; ..&lt;br /&gt;
&lt;br /&gt;
[[File:2-8.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Optimized Objective Value ===&lt;br /&gt;
To conveniently evaluate the optimized objective value (the surface area of the solution can) you can use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptObjective OptObjective]()&amp;lt;/tt&amp;gt;   function. The only parameter is the identifier for the Define Optimization node.&lt;br /&gt;
 Objective Opt_Surface := &amp;lt;tt&amp;gt;OptObjective(Opt)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Viewing Optimization Status ===&lt;br /&gt;
To check the status of an optimization, use the &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=OptStatusText OptStatusText]()&amp;lt;/tt&amp;gt; .. function. Enter the identifier for the node containing &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
 Variable Status := &amp;lt;tt&amp;gt;OptStatusText(Opt)&amp;lt;/tt&amp;gt; &lt;br /&gt;
This will reveal a text string describing the status of the optimization result. Status messages differ according to problem characteristics and the engine being used. In general these messages indicate whether or not a feasible solution has been found and if so, whether or not the optimizer was able to converge to a bounded solution. In this example status is: “Optimal solution has been found.”&lt;br /&gt;
&lt;br /&gt;
[[File:2-9.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Copying Optimized Results to Definitions===&lt;br /&gt;
&lt;br /&gt;
In some cases, you may wish to copy the optimized decision values into the definition of the original decisions. With this, the result for variables downstream of the decisions will reflect their optimal values as well.&lt;br /&gt;
&lt;br /&gt;
You can configure your model to copy optimized results into the original decisions by adding two buttons to your model. The first button solves for the optimal solution and copy the optimal values. The second button restores the original (non-optimized) definition. Functions provided in the '''Structured Optimization Tool.ana''' library take care of the details.&lt;br /&gt;
&lt;br /&gt;
To configure these buttons: &lt;br /&gt;
&lt;br /&gt;
# With the diagram in focus, select '''Add Library''' from the '''File''' menu. &lt;br /&gt;
# Select &amp;lt;code&amp;gt;Structured Optimization Tools.ana&amp;lt;/code&amp;gt; and click '''Open'''. &lt;br /&gt;
# Select '''Embed''', then click '''OK'''.&lt;br /&gt;
# Drag a button from the tool bar, title it &amp;quot;Set to Optimal.&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
:[[File:2-10.png|400px]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Click  [[File:expr_btn.png]] to edit the button’s Script attribute to Use_opt_decisions( opt ).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Drag a second button to the diagram, name it &amp;quot;Restore Defintions&amp;quot; and set its Script attribute to &amp;lt;code&amp;gt;Restore_Decision_Defs( opt ).&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-11.png|400px]]&lt;br /&gt;
Now we’re ready to try them out. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click [[File:expr_btn.png]] to enter browse mode. Click the '''Set to Optimal''' button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the object window for '''Radius''':&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
:[[File:2-12.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Changing Variable Types (Domain)===&lt;br /&gt;
&lt;br /&gt;
Click either '''Radius''' or '''Height''' to open the Object window for the node. You will notice a pull-down menu for '''Domain'''. This attribute specifies the variable type. It is always visible for decision nodes if you are using the Optimizer edition. &lt;br /&gt;
&lt;br /&gt;
Suppose the factory requires Radius and Height to be integer values in centimeters for tooling purposes, or because they don’t like decimals. Change the Domains of &amp;lt;tt&amp;gt;Radius&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Height&amp;lt;/tt&amp;gt; to '''Integer '''and re-evaluate the solution:&lt;br /&gt;
&lt;br /&gt;
[[File:2-13.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The new solution finds the integer values that come closest to meeting the optimization criteria.&lt;br /&gt;
&lt;br /&gt;
See [http://wiki.analytica.com/index.php?title=Optimizer_Attribute_Reference Optimizer Attribute Reference] for descriptions of all available domains.&lt;br /&gt;
&lt;br /&gt;
=== Setting Bounds on Decision Values ===&lt;br /&gt;
Suppose the cans must not exceed a 5cm radius in order to meet National Association for the Advancement of People with Small Hands (NAAPSH) guidelines. One way to set this limit would be to add another constraint. But since this restriction applies directly to one of the decision variables, it is easier to simply set an upper bound on the variable directly.&lt;br /&gt;
&lt;br /&gt;
Double-click the '''Radius''' variable and enter '''5''' as the upper bound. The updated solution will describe a thinner can that is 5cm in Radius and 13cm in Height.&lt;br /&gt;
&lt;br /&gt;
'''Bounds and Domains''' &lt;br /&gt;
&lt;br /&gt;
Some Domain types are not compatible with bounds. If one of these domains is selected ('''i.e.''' '''Boolean'''), bounds attributes will not be visible. &lt;br /&gt;
&lt;br /&gt;
'''Bounds and Feasible Solutions'''&lt;br /&gt;
&lt;br /&gt;
It is possible to have no feasible solution within the designated bounds. For example, if you restrict '''Radius''' to 5cm while restricting '''Height''' to 10cm, it will be impossible to produce a can that meets the minimum volume constraint. The [[OptStatusText]]()  function indicates whether or not a feasible solution has been found.&lt;br /&gt;
&lt;br /&gt;
===Using Parametric Analysis with Optimization ===&lt;br /&gt;
Before adding optimization to existing models, it is often useful to perform a parametric analysis to see how variations in decision inputs affect the objective value. If you have done this, your Decision and Objective variables will include parametric indexes. To demonstrate this in the ''Optimum Can'' example, we can define the '''Radius''' to be a sequence of values that vary parametrically. We then re-define '''Height''' such that the volume of the cylinder remains constant as radius varies: &lt;br /&gt;
 Variable Radius := Sequence(4.5, 6.5, 0.1) &lt;br /&gt;
&lt;br /&gt;
 Variable Height := Required_volume/(pi*Radius^2) &lt;br /&gt;
Now you can evaluate the objective '''Surface_Area''' to see how it is affected by '''Radius'''.&lt;br /&gt;
&lt;br /&gt;
[[File:2-14.png|400x400px]]&lt;br /&gt;
&lt;br /&gt;
An optimization requires a scalar-valued objective. An array-valued objective usually implies an array of optimizations, each optimizing an individual element of the objective array. But parametric indexes are an exception to this rule! If the Objective is an array over parametric indexes, the indexes are ignored by the optimization. So even though we have an array valued Objective in this example, there is still only one optimization run.&lt;br /&gt;
&lt;br /&gt;
[[File:2-15.png|500x500px]]&lt;br /&gt;
&lt;br /&gt;
Parametric analysis is a good way to gain insight into your model. The Structured Optimization framework is designed so that it will not be confused by this&lt;br /&gt;
&lt;br /&gt;
===The Initial Guess Attribute ===&lt;br /&gt;
&lt;br /&gt;
LP and convex QP problems do not rely on initial guesses and always yield globally optimal solutions. But in NLP and non-convex QP problems it is not always possible to guarantee that a solution found by the optimizer is a global optimum. It might be merely a “local” optimum within the solution space. Optimization methods for these problems use an initial guess from which to start the search for a solution. The particular solution the optimizer returns may depend on the starting point. &lt;br /&gt;
&lt;br /&gt;
Normally, Analytica uses the defined value of the Decision variables as the initial guess. In the ''Optimum Can'' example, we initially defined &amp;lt;code&amp;gt;Radius&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Height&amp;lt;/code&amp;gt; as 1. If a decision variable is defined using a parametric index, Analytica uses the first element of the parametric array as the initial guess.&lt;br /&gt;
&lt;br /&gt;
You can change the initial guess without re-defining the decision variable using the '''Initial Guess''' attribute in the Decision node. We can demonstrate this using the ''Polynomial NLP.ana'' example where the objective is a non-convex curve with local maxima.&lt;br /&gt;
&lt;br /&gt;
The Initial Guess attribute is hidden by default. To make it visible in Decision nodes: &lt;br /&gt;
* Select '''Attributes'''... from the '''Object''' menu. &lt;br /&gt;
* Check the '''Initial Guess''' box.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attribute will now be visible in the Object windows of all Decision variables.&lt;br /&gt;
&lt;br /&gt;
The polynomial curve in this model is designed to have several critical points.&lt;br /&gt;
&lt;br /&gt;
[[File:2-16.png|500x500px]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Decision X := 0 (or any value at all)&lt;br /&gt;
Initial Guess of X := [-4, 2, 0, 2, 4] &lt;br /&gt;
Objective Polynomial := &lt;br /&gt;
      1+X/6-X^2/2+X^4/24-X^6/720+X^8/40320-X^10/3628800&lt;br /&gt;
Variable Opt := DefineOptimization( &lt;br /&gt;
      Decision: X, &lt;br /&gt;
      Maximize: Polynomial) &lt;br /&gt;
Variable X_solution := OptSolution(Opt,X) &lt;br /&gt;
Objective Max_Objective := OptObjective(Opt)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The array of initial guesses will cause Analytica to abstract over the index and perform multiple optimizations.&lt;br /&gt;
&lt;br /&gt;
[[File:2-17.png|500px]]&lt;br /&gt;
&lt;br /&gt;
We see that the result depends on the initial guess for this non-convex NLP.&lt;br /&gt;
&lt;br /&gt;
If the array of guesses were entered as a ''definition'' for the decision variable instead of as an ''initial guess'' attribute, Analytica would interpret it as a parametric index and apply only one initial guess. (See subsection above.) Therefore, it is necessary to use the Initial Guess parameter if you want to perform multiple optimizations using an array of guesses.&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;Finding multiple different local extrema in this fashion can be a useful way to locate multiple solutions of interest. One often needs to combine unmodeled factors with insight and results obtained from a model, so these other solutions may turn out to be more interesting for reasons that you have not modeled.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
''&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt;When your interest is in finding just the global optima, there are additional methods for dealing with the problem of local optima. The '''Multistart''' and topological search options can be utilized with gradient-based methods (see [http://wiki.analytica.com/Coping_with_Local_Optima Coping with Local Optima]). The “Evolutionary” and “OptQuest” engines use population-based search methods that are more robust to local optima.&amp;lt;/Tip&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Chapter Summary ==&lt;br /&gt;
The ''Optimum Can'' example demonstrates the basic workflow of Structured Optimization in Analytica. It includes input Decision variables, a Constraint object, an Objective variable, intermediate Variables and the central &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;[http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]()&amp;lt;/tt&amp;gt;  function recognizes the non-linear characteristics of the Optimum Can model and classifies it as an NLP. The function evaluates as a special object containing details about the optimization.&lt;br /&gt;
&lt;br /&gt;
The Domain attributes in Decisions allow setup of variable type and bounds.&lt;br /&gt;
&lt;br /&gt;
Structured Optimization is compatible with a decision variable defined as a parametrically varying sequence.&lt;br /&gt;
&lt;br /&gt;
If the Initial Guess attribute is kept hidden or left blank, Analytica will use the defined value of the decision variable as an initial guess. Users can override this value or enter an array of initial guesses by using the Initial Guess attribute in Decision nodes. This attribute is hidden by default but can be made visible when necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Introduction / {{PAGENAME}} / Optimization Characteristics&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Introduction_to_Optimizer&amp;diff=39034</id>
		<title>Introduction to Optimizer</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Introduction_to_Optimizer&amp;diff=39034"/>
		<updated>2016-01-03T15:30:03Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* To Validate the Activation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica Optimizer Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;This introduction explains what  the Analytica Optimizer is and how you can obtain a copy of the software. It also details how you can activate and validate your copy of as well as activate high-end, add-on engines for the Optimizer.&lt;br /&gt;
==What is the Analytica Optimizer?==&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer enhances Analytica with powerful functions for finding optimal decisions and solving difficult equations. Most Analytica Optimizer models aim to find a decision strategy — values for ''decision'' variables — to maximize or minimize a quantified objective subject to a set of equality or inequality constraints. Some models seek a feasible solution that satisfies a set of constraints without regard to an objective.&lt;br /&gt;
&lt;br /&gt;
===Types of Optimization ===&lt;br /&gt;
&lt;br /&gt;
A ''linear program'' (LP) requires the objective function and constraints to be linear functions of decision variables. LPs are solvable using straightforward algorithms that yield unique (global) maximizing or minimizing solutions. Although LP algorithms are well understood, large-scale optimizations can be computationally complex.&lt;br /&gt;
&lt;br /&gt;
When pairs of decision variables are multiplied together, including squared decision variables, quadratic terms result. A ''quadratic problem'' (QP) has quadratic terms in the objective and linear constraints. A generalization of a QP, in which one or more constraints contains quadratic terms, is called a ''Quadratically Constrained Program'' (QCP). If the objective and constraint functions satisfy a mathematical property known as convexity, QP solutions are always unique (global). Non-convex formulations can result in “local” solutions that may or may not represent the global optimum.&lt;br /&gt;
&lt;br /&gt;
''Nonlinear Programming'' (NLP) does not impose restrictions on the mathematical properties of objectives and constraints. A wide variety of computational algorithms can be applied to NLPs. Strategies include gradient tracking and genetic algorithms that allow potential solutions to compete within the computation.&lt;br /&gt;
&lt;br /&gt;
With all classes of optimization, Analytica supports variables that are continuous, discrete (integer, Boolean, grouped), or a mixture of continuous and discrete decision variables.&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer analyzes your objective functions and constraints automatically to discover the type of optimization and select the appropriate solver engine.&amp;lt;!--See the section on the Type parameter of DefineOptimization() for more details on these types of Optimization.--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Premium Solver Specifications===&lt;br /&gt;
&lt;br /&gt;
The standard edition of Analytica Optimizer uses the Premium Solver Platform licensed from Frontline Systems, Inc., the developer of the Optimizer/Solver in Microsoft Excel, and a world leader in spreadsheet optimization. &lt;br /&gt;
&lt;br /&gt;
The Premium Solver is the leading add-on software for spreadsheet optimization, and incorporates state-of-the-art technologies. The LP and QP solver engines that come included with Analytica Optimizer handle up to 8000 variables and 8000 constraints in addition to bounds on the decision variables. Up to 2000 of these variables may be constrained to be integer-valued for ''Mixed-Integer Programming''. Up to 2000 decision variables of any kind are supported when quadratic constraints are present. The NLP solvers offer hybrid methods using classical gradient-search and evolutionary (genetic) algorithms for smooth and discontinuous objective functions with up to 500 decision variables and 250 constraints. Large scale add-on engines that eliminate the limit on variables and constraints entirely are also available at extra cost (see [http://wiki.analytica.com/index.php?title=Introduction_to_the_Guide#Installing_Add-On_Optimizer_Engines Installing Add-On Optimizer Engines]). &lt;br /&gt;
If your problems exceed these limits, or you need a solver that is even faster, you can add any of a number of high-end solvers, LP, QP, or NLP, that include some of the most powerful solver engines available anywhere (see  the [http://wiki.analytica.com/index.php?title=DefineOptimization#Engine_Settings Engine] Settings parameter of [http://wiki.analytica.com/index.php?title=DefineOptimization DefineOptimization]() for details.&lt;br /&gt;
&lt;br /&gt;
===Optimizing with Uncertain Values and Intelligent Arrays===&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer performs optimization under uncertainty to maximize expected values and minimize loss percentiles, as well as other statistical functions of objectives and constraints. Analytica allows users to combine Intelligent ''arrays'' with all classes of optimization. Thus, you can easily create ''arrays of optimizations'' conditioned on samples from uncertain variables, for parametric analysis of effects of key assumptions, and for each time period in a dynamic model.&lt;br /&gt;
&lt;br /&gt;
===Compatibility with Other Analytica Editions===&lt;br /&gt;
&lt;br /&gt;
The Analytica Optimizer is an edition of Analytica that includes all the functionalities of the Analytica Enterprise edition. After using Analytica Optimizer to create optimizing models, you can deliver them to end users on the desktop using Analytica Power Player with Optimizer, or via a web browser on a server using the Analytica Web Player (AWP) or Analytica Decision Engine (ADE) with an Optimizer license.&lt;br /&gt;
&lt;br /&gt;
==Obtaining the Analytica Optimizer==&lt;br /&gt;
&lt;br /&gt;
You can purchase a license for the Analytica Optimizer or the Analytica Power Player with Optimizer from Lumina Decision Systems. Or you can purchase an upgrade to Optimizer if you already have a license for the Analytica Enterprise or Professional editions.&lt;br /&gt;
&lt;br /&gt;
If your copy of Analytica is for release 4.2 or earlier, you need to upgrade to release 4.3 or later to obtain the newest Optimizer features as described in this Guide. Substantial discounts are available if you have a maintenance agreement for Analytica 4.2 (included free for 12 months from purchase).&lt;br /&gt;
&lt;br /&gt;
For more information: &lt;br /&gt;
&lt;br /&gt;
* Visit the [[ http://www.lumina.com/|Lumina web site]],  or &lt;br /&gt;
* Call Lumina at 650-212-1212&lt;br /&gt;
&lt;br /&gt;
==Activating your Analytica Optimizer==&lt;br /&gt;
&lt;br /&gt;
If you have purchased an individual license of Analytica Optimizer, you will be sent an Activation Key. This key allows you to retrieve a license specific to your computer and account from Lumina’s activation server. The license itself is contained in a file, usually stored in the Analytica installation directory and usually named Analytica.lic. The term activation refers to the process of obtaining this file.&lt;br /&gt;
&lt;br /&gt;
===First-Time Install===&lt;br /&gt;
&lt;br /&gt;
When installing Analytica for the first time, you will run the Analytica installer program, which you can find in [[ http://www.lumina.com/support/downloads/|Lumina Downloads]]. If you have purchased the 64-bit edition, download Ana64Setup.exe, otherwise download AnaSetup.exe. &lt;br /&gt;
&lt;br /&gt;
If you run the installer from your own end-user account (recommended), then enter the activation key when prompted, and the installer will automatically retrieve and install your license file over the internet (if you don’t have an internet connection, see “Manual Activation”). If a system administrator runs the installer from an account other than your own end-user account, leave the activation key field blank, then after it is installed, log into your own account and follow the instructions for “Previous edition already installed”.&lt;br /&gt;
&lt;br /&gt;
===Previous Edition Already Installed===&lt;br /&gt;
&lt;br /&gt;
If you already have an edition of Analytica 4.6 installed (including the Trial Edition), your installation includes the Analytica Optimizer files and there is no need to download new software. However, you need to enter a new activation key with the Optimizer option.&lt;br /&gt;
&lt;br /&gt;
To activate Analytica Optimizer while you are connected to the internet:&lt;br /&gt;
&lt;br /&gt;
# Start Analytica in the usual way, e.g., via the Windows Start menu, or by doubleclicking an Analytica model file. &lt;br /&gt;
# From Analytica’s '''Help menu''', select '''Update License''' to display the '''Analytica Licensing Information''' box. &lt;br /&gt;
# Enter the activation key into the '''License ID''' box, replacing the license name currently displayed. As soon as the key is correctly entered, an '''Activate''' button appears to the right. &lt;br /&gt;
# Click '''Activate''' to retrieve your license from the activation server. Your license name then appears in the '''License ID''' box. &lt;br /&gt;
# Click '''OK'''. &lt;br /&gt;
# Exit and restart Analytica.&lt;br /&gt;
&lt;br /&gt;
===Manual Activation===&lt;br /&gt;
&lt;br /&gt;
Automatic activation will fail if you do not have a connection to the internet, or if your firewalls and proxy servers are configured to prevent Analytica from communicating with the activation server. In this case, you can obtain a license file through manual activation. You will need your activation key and the Host ID and User ID that are displayed at the bottom of the Analytica Licensing Information dialog from Step 2 above. Enter this information into the form at http://www.lumina.com/support/activate-analytica/, and the license file will be emailed to you.&lt;br /&gt;
&lt;br /&gt;
===Floating License===&lt;br /&gt;
&lt;br /&gt;
If your organization provides you with a floating license to Analytica Optimizer, your IT department will provide you with the name (and possibly IP port) of the Reprise License Manager (RLM) server computer where your IT department will have already installed and activated a floating license.&lt;br /&gt;
&lt;br /&gt;
Run the Analytica installer as described in “First-Time Install”, but during the install, on the '''License Information''' page, select '''Centrally managed license (RLM License Server)''' and enter the ''server host name'', or '''port@host''', provided to you.&lt;br /&gt;
&lt;br /&gt;
If you already have Analytica installed, you can also enter this information into the Analytica License Information by selecting '''Update License''' from the '''Help''' menu.&lt;br /&gt;
&lt;br /&gt;
===To Validate Successful Activation ===&lt;br /&gt;
&lt;br /&gt;
To verify successful activation of Analytica Optimizer, examine the splash screen when Analytica starts up, or go to '''Help &amp;gt; About Analytica'''. The splash screen should display '''Analytica Optimizer''', as shown below. &lt;br /&gt;
&lt;br /&gt;
[[File:1-1.png|400px]]&lt;br /&gt;
&lt;br /&gt;
==Installing Add-On Optimizer Engines==&lt;br /&gt;
&lt;br /&gt;
You can add other engines for solving optimization problems to the Analytica Optimizer. Some engines provide superior performance on particular classes of optimization problems, and some engines handle larger numbers of variables or constraints. The following add-on engines are available:&lt;br /&gt;
&lt;br /&gt;
* Large Scale LP&lt;br /&gt;
* Large Scale SQP &lt;br /&gt;
* Large Scale GRG &lt;br /&gt;
* Gurobi (LP/QP)&lt;br /&gt;
* XPRESS (LP/QP)&lt;br /&gt;
* MOSEK (cQCP/NLP) &lt;br /&gt;
* KNITRO (NLP)&lt;br /&gt;
* OptQuest (NSP)&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you purchase an add-on engine license, or obtain an add-on engine trial, Lumina will provide you with the following items:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;EngineSetup.exe&amp;lt;/tt&amp;gt; (or &amp;lt;tt&amp;gt;EngineSetup64.exe&amp;lt;/tt&amp;gt; for Analytica 64-bit users), the add-on engine installer from Frontline Systems.&lt;br /&gt;
# The password required by EngineSetup.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;SolverAddons.lic&amp;lt;/tt&amp;gt; file.&lt;br /&gt;
# A Lumina activation key.&lt;br /&gt;
&lt;br /&gt;
===To Install an Add-On Engine===&lt;br /&gt;
&lt;br /&gt;
# Install Analytica Optimizer first, if you have not already done so.  &lt;br /&gt;
# Run &amp;lt;tt&amp;gt;EngineSetup.exe&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;EngineSetup64.exe&amp;lt;/tt&amp;gt;, the add-on engine installation program. Use &amp;lt;tt&amp;gt;EngineSetup64.exe&amp;lt;/tt&amp;gt; when you are using Analytica 64-bit.  &lt;br /&gt;
# The &amp;lt;tt&amp;gt;EngineSetup&amp;lt;/tt&amp;gt; program will ask for a password and activation key. Enter the password provided to you by email when you are sent the EngineSetup program. You may leave the '''activation key''' blank. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip title=&amp;quot;Note&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you're using the v14 release of EngineSetup, you will need to correct a bug that places the release's settings in the v11 registry hive instead of the v14 registry hive. &lt;br /&gt;
&lt;br /&gt;
To correct the bug: &lt;br /&gt;
&lt;br /&gt;
# From the '''Start''' menu, run &amp;lt;tt&amp;gt;RegEdit.exe&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Navigate to &amp;lt;tt&amp;gt;HKEY_LOCAL_MACHINE/Software/Lumina Decision Systems/SolverEngines&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Right-click on &amp;lt;tt&amp;gt;v11&amp;lt;/tt&amp;gt;, select '''Rename''', then change to&amp;lt;tt&amp;gt; v14&amp;lt;/tt&amp;gt;. &lt;br /&gt;
# Start up Analytica and select '''Update License''' from the Help menu. &lt;br /&gt;
# Enter the activation key provided into the '''License ID''' box, then click '''Activate'''&lt;br /&gt;
&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===To Validate the Activation===&lt;br /&gt;
&lt;br /&gt;
To test for proper installation, open Analytica, and create a variable defined as follows: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Variable Engines := OptEngineInfo(&amp;quot;All&amp;quot;,&amp;quot;TrialPeriod&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The names of available engines should appear with non-zero values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Analytica Optimizer Guide / {{PAGENAME}} / Quick Start&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Analytica_Optimizer_Guide&amp;diff=39033</id>
		<title>Analytica Optimizer Guide</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Analytica_Optimizer_Guide&amp;diff=39033"/>
		<updated>2016-01-03T15:28:32Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This Guide explains how to use the Analytica Optimizer. It provides a Quick Start Tutorial and an introduction to the basic concepts of optimization, including linear, quadratic, and nonlinear programming (NLP), as well as special topics in NLP. However, it is not a complete textbook on optimization. For more challenging applications, you might find it useful to consult one of the many good textbooks on optimization.[[Category: Analytica Optimizer Guide]]&lt;br /&gt;
== Sections ==&lt;br /&gt;
* [[Introduction to the Guide|Introduction]]&lt;br /&gt;
&amp;lt;!--#* Using the Analytica Optimizer Guide&lt;br /&gt;
#* Obtaining Analytica Optimizer&lt;br /&gt;
#* Activating Analytica Optimizer&lt;br /&gt;
#* Installing Add-On Engines to Analytica Optimizer--&amp;gt;&lt;br /&gt;
* [[Quick Start]]&lt;br /&gt;
&amp;lt;!--#* Intro to Structured Optimization&lt;br /&gt;
#* Notation&lt;br /&gt;
#* The Optimum Can Example&lt;br /&gt;
#** Decisions&lt;br /&gt;
#** Constants&lt;br /&gt;
#** Variables&lt;br /&gt;
#** Constraints&lt;br /&gt;
#** Objectives&lt;br /&gt;
#** The DefineOptimization() function&lt;br /&gt;
#** Viewing the Optimization Object&lt;br /&gt;
#** Obtaining the Solution&lt;br /&gt;
#** Obtaining the Optimized Objective Value&lt;br /&gt;
#** Viewing Optimization Status&lt;br /&gt;
#** Copying Optimized Results to Definitions&lt;br /&gt;
#** Changing Variable Types (Domain)&lt;br /&gt;
#** Setting Bounds on Decision Values&lt;br /&gt;
#** Using Parametric Analysis with Optimization&lt;br /&gt;
#** The Initial Guess Attribute&lt;br /&gt;
#* Summary--&amp;gt;&lt;br /&gt;
* [[Optimization Characteristics]]&lt;br /&gt;
&amp;lt;!--#* Introduction&lt;br /&gt;
#* Parts of an Optimization Problem: General Description&lt;br /&gt;
#* Identifying the Type of Optimization&lt;br /&gt;
#* Specific Optimization Characteristics&lt;br /&gt;
#* Continuous, Integer and Mixed-Integer Programs&lt;br /&gt;
#* Solving Simultaneous Equations--&amp;gt;&lt;br /&gt;
* [[Optimizing with Arrays]]&lt;br /&gt;
* [[Key Concepts: The Airline NLP Example]]&lt;br /&gt;
* [[Optimizer Attribute Reference]]&lt;br /&gt;
* [[Optimizer Function Reference]]&lt;br /&gt;
* [[Control Settings]]&lt;br /&gt;
&lt;br /&gt;
==Using this Guide==&lt;br /&gt;
&lt;br /&gt;
==== If you're new to Analytica ====&lt;br /&gt;
You will find it easier if you first learn the essentials of Analytica before learning the Analytica Optimizer described here. Start with the [http://wiki.analytica.com/index.php?title=Analytica_Tutorial Analytica Tutorial] to learn the basics of interacting with Analytica and its modeling language, especially [http://wiki.analytica.com/index.php?title=Analytica_Tutorial#Working_with_Arrays_.28Tables.29 Working with Arrays]. It's important to have a good understanding of Intelligent Arrays to make good use of the Optimizer.&lt;br /&gt;
&lt;br /&gt;
==== If you're new to the Analytica Optimizer ====&lt;br /&gt;
We suggest you start with the [http://wiki.analytica.com/index.php?title=Quick_Start Quick Start], an introductory tutorial that takes you through the key steps to create a simple optimization. The section on [http://wiki.analytica.com/index.php?title=Optimization_Characteristics Optimization Characteristics] explains the general principles of optimization and the types of optimization, including Linear Programming (LP), Quadratic Programming (QP), and Non-Linear Programming (NLP). We also recommend reading [http://wiki.analytica.com/index.php?title=Optimizing_with_Arrays Optimizing with Arrays] to master optimization with parametric analysis. [http://wiki.analytica.com/index.php?title=Key_Concepts%3A_The_Airline_NLP_Example Key Concepts: The Airline NLP Example] explains how to use optimization in models having dynamic influences and Monte Carlo-based uncertainties.&lt;br /&gt;
&lt;br /&gt;
==== If you've used Analytica Optimizer 4.2 or earlier ====&lt;br /&gt;
The 4.3 release of Analytica introduced ''Structured Optimization'', a new set of features that eliminates many difficult steps previously required for structuring optimizations in Analytica. For example, it can use a set of decision variables of varying dimensions, instead of requiring you to combine and flatten them manually. It introduces Constraints as a new object class. It can discover automatically whether your objective is linear, quadratic, or nonlinear, and apply the appropriate solver engine --and a whole lot more.&lt;br /&gt;
&lt;br /&gt;
So if you’ve used the Optimizer before, we strongly recommend that you read the [http://wiki.analytica.com/index.php?title=Quick_Start Quick Start], which introduces [http://wiki.analytica.com/index.php?title=Quick_Start#Introduction_to_Structured_Optimization Structured Optimization], and the [http://wiki.analytica.com/index.php?title=Optimizing_with_Arrays Optimizing with Arrays] section of this guide (at least). Even though Analytica 4.4 still supports functions from releases 4.2 and earlier of Optimizer for backward compatibility, you will likely want to learn and use the new functions instead.&lt;br /&gt;
&lt;br /&gt;
== Conventions Used in this Guide ==&lt;br /&gt;
Under the title of each page on this guide, the page's hierarchy and any parent pages are listed.&lt;br /&gt;
&lt;br /&gt;
The pages in this guide can be read in any order. However, if you want to read the guide sequentially, there are links to the previous and next pages at the bottom of each page which will take the reader through all of the guide's pages in order. &lt;br /&gt;
&lt;br /&gt;
Throughout this guide, we use a shorthand notation for displaying the definitions of Analytica objects. An object’s class (e.g., Variable, Decision, Constraint, etc) and identifier is followed by ''':=''', and the definition is displayed on the right. &lt;br /&gt;
&lt;br /&gt;
[[File:1-1-new.png|400px]]&lt;br /&gt;
&lt;br /&gt;
In the above example, a Constraint object class with the identifier '''Volume Constraint''' is defined as '''Volume &amp;gt;= Required Volume'''.__NOTOC__&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Reference_sections&amp;diff=38852</id>
		<title>Reference sections</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Reference_sections&amp;diff=38852"/>
		<updated>2015-12-29T04:25:57Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following appendices shows you how to select an appropriate sample size, the specifications for Analytica, the list of reserved identifiers and error message types, forward and backward compatibility information, a bibliography, and a list of all the Analytica functions.&lt;br /&gt;
&lt;br /&gt;
* [[Selecting the Sample Size]]&lt;br /&gt;
* [[Analytica Specifications]]&lt;br /&gt;
* [[Identifiers Already Used]]&lt;br /&gt;
* [[Error Message Types]]&lt;br /&gt;
* [[Forward and Backward Compatibility]]&lt;br /&gt;
* [[Bibliography]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Analytica Enterprise / {{PAGENAME}} /  functions by category&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Reference_sections&amp;diff=38851</id>
		<title>Reference sections</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Reference_sections&amp;diff=38851"/>
		<updated>2015-12-29T04:25:27Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following appendices shows you how to select an appropriate sample size, the specifications for Analytica, the list of reserved identifiers and error message types, forward and backward compatibility information, a bibliography, and a list of all the Analytica functions.&lt;br /&gt;
&lt;br /&gt;
* [[Selecting the Sample Size]]&lt;br /&gt;
* [[Analytica Specifications]]&lt;br /&gt;
* [[Identifiers Already Used]]&lt;br /&gt;
* [[Error Message Types]]&lt;br /&gt;
* [[Forward and Backward Compatibility]]&lt;br /&gt;
* [[Bibliography]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Analytica Enterprise / {{PAGENAME}} /  Functions by Category&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Bibliography&amp;diff=38850</id>
		<title>Bibliography</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Bibliography&amp;diff=38850"/>
		<updated>2015-12-29T04:21:09Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Appendices &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Morgan, M. Granger and Max Henrion. ''Uncertainty: A Guide to Dealing with Uncertainty in Quantitative Risk and Policy Analysis'', Cambridge University Press (1990,1998).&lt;br /&gt;
&lt;br /&gt;
Written by the original authors of Analytica, this text provides extensive background on how to represent and analyze uncertainty in quantitative models. It includes chapters on:&lt;br /&gt;
* Building good policy models&lt;br /&gt;
* Categorizing types and sources of uncertainty&lt;br /&gt;
* How people make judgments under uncertainty&lt;br /&gt;
* Encoding expert judgment in the form of probability distributions&lt;br /&gt;
* Choosing a computational method for propagating uncertainty in a model&lt;br /&gt;
* Analyzing uncertainty in very large models Displaying and communicating uncertainty&lt;br /&gt;
* Displaying and communicating uncertainty&lt;br /&gt;
* How to tell if representing uncertainty could make a significant difference to your conclusions, or “the value of knowing how little you know” &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We recommend the second edition, published in 1998, which contains a full chapter on Analytica (Chapter 10). If you have the first edition (1990), we recommend that you ignore Chapter 10, which describes the precursor of Analytica and is quite out of date! &lt;br /&gt;
&lt;br /&gt;
Clemen, Robert T. ''Making Hard Decisions: An Introduction to Decision Analysis''. Duxbury Press (1991).&lt;br /&gt;
&lt;br /&gt;
Howard, R., and J. Matheson. ''Influence Diagrams. In Readings on the Principles and Applications of Decision Analysis'', eds. R. Howard and J. Matheson. pp. 721-762. Menlo Park, CA: Strategic Decisions Group (1981).&lt;br /&gt;
&lt;br /&gt;
Keeney, R. ''Value–Focused Thinking: A Path to Creative Decision Making'', Cambridge, MA: Harvard University Press (1992).&lt;br /&gt;
&lt;br /&gt;
Knuth, D.E. ''Seminumerical Algorithms, 2nd ed., vol. 2 of The Art of Computer Programming'', Reading, MA: Addison-Wesley (1981). &lt;br /&gt;
&lt;br /&gt;
L’Ecuyer, P. ''Communications of the ACM'', 31, 742-774 (1988).&lt;br /&gt;
&lt;br /&gt;
Park, S.K., and K.W. Miller. ''Communications of the ACM'', 31, 1192-1201 (1988).&lt;br /&gt;
&lt;br /&gt;
Pearl, J. ''Probabilistic Reasoning in Intelligent Systems'', San Mateo, CA: Morgan Kaufmann (1988). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Forward and Backward Compatibility / {{PAGENAME}} / Function List&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Forward_and_Backward_Compatibility&amp;diff=38849</id>
		<title>Forward and Backward Compatibility</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Forward_and_Backward_Compatibility&amp;diff=38849"/>
		<updated>2015-12-29T04:20:38Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Appendices &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Backward compatibility==&lt;br /&gt;
&lt;br /&gt;
Models created in earlier releases of Analytica can be loaded, viewed, evaluated, and modified with Analytica 4.6. No file conversions are required. There are many bug fixes included with every new release of Analytica, so if your model utilizes an undocumented feature that was really a bug, a change in model behavior could result.&lt;br /&gt;
&lt;br /&gt;
===Show result warnings===&lt;br /&gt;
&lt;br /&gt;
When you are trying a model for the first time in 4.6, the first thing you should do is ensure that ''Show Result Warnings'' is checked in the '''Preferences''' box. While evaluating your model, avoid selecting ''Ignore Warnings'' if warnings do appear. If any expression in your model produces a warning that you can live with, surround the expression with '''IgnoreWarnings(...)''' to suppress the warning, so that you don’t feel compelled to select the '''Ignore Warnings''' button. When you leave warnings on while your model evaluates, most potential backward-compatibility issues are reported to you.&lt;br /&gt;
&lt;br /&gt;
===Sort (collation) order=== &lt;br /&gt;
&lt;br /&gt;
Analytica 4.5 and later uses regional sort order when comparing and sorting text, whereas Analytica 4.4 and earlier use pure ANSI (ASCII) order. Region awareness allows more intelligent handling of accented characters and other language subtleties. In the unlikely event that your model relies on ANSI ordering, you can configure it to use ANSI ordering in Analytica 4.5 or later as follows: press ''F12'' to open the T'''ypescript''' window and type: &amp;lt;code&amp;gt;TextLocale:ANSI&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Character codes===&lt;br /&gt;
&lt;br /&gt;
Every character has a numeric character code associated with it, which is used by the '''Chr()''' and '''Asc()''' functions. The characters associated with codes from 128 to 160, 173, 178 and 179 have changed to be consistent with the Unicode standard. Your model is only impacted by this if it&lt;br /&gt;
relies on the specific numeric value passed to Chr() or received from Asc(). If uses these characters in text or attributes, the conversion in handed automatically or you will see no difference.&lt;br /&gt;
&lt;br /&gt;
==Recommended Modifications==&lt;br /&gt;
&lt;br /&gt;
After you upgrade to the most recent release, there are several setting changes we recommend you make to your model, although these are optional. Analytica will initially configure these to operate a legacy mode to minimize the chance of introducing a difference when you start using your model in the new release; however, legacy modes prevent you from taking full advantage of improvements and fixes.&lt;br /&gt;
&lt;br /&gt;
===ClearType fonts===&lt;br /&gt;
&lt;br /&gt;
Analytica 4.4 and later can render influence diagram nodes using ClearType fonts, which are smooth anti-aliased fonts that look nicer than the fonts used pre-4.4. To turn on ClearType fonts in legacy models, open the '''Set Diagram Style...''' box for your top-level model diagram from edit mode and check the '''ClearType fonts''' checkbox (the checkbox will not be present for models started in Analytica 4.4 or later, which already use ClearType). Then visit each module and adjust any nodes that word wrap in an undesirable fashion. For most diagrams, you can do this by pressing ''Ctrl+A'' (select all) and then pressing ''Ctrl+T'' ('''Adjust size''') multiple times until an acceptable appearance is obtained. With ClearType support, ''Ctrl+T'' cycles through multiple criteria for adjusting node sizes.&lt;br /&gt;
&lt;br /&gt;
===Domain as self index=== &lt;br /&gt;
&lt;br /&gt;
You should turn off the '''Domain acts as self index''' preference. A small percentage of models created in Analytica 4.2 or earlier might be impacted, and only in those cases should this preference be on, at least until you update the model appropriately. The older domain treatment is inferior in many ways, and some features are only available when this preference is off.&lt;br /&gt;
&lt;br /&gt;
===Proactive evaluation===&lt;br /&gt;
&lt;br /&gt;
We recommend that you turn off the '''Proactively evaluate indexes''' preference. This will generally speed up the time it takes to load your model. This preference is on in models created initially in 4.3 or earlier.&lt;br /&gt;
&lt;br /&gt;
==Forward compatibility==&lt;br /&gt;
&lt;br /&gt;
It is also possible to run models created or edited in Release 4.6 in earlier releases of Analytica, such as Analytica 4.4, 4.0 or even 3.1, provided you don’t rely on functions, features, characters, or functionalities new to Analytica 4.6. The models load into earlier releases of Analytica, although they might encounter problems during parsing or evaluation in the places where 4.6 features are used. A few 4.6 features might be stripped out of the model if it is re-saved from an earlier Analytica User Guide 443 Appendices Appendices release, such as values for system attributes or system variables that don’t exist in the earlier version.&lt;br /&gt;
&lt;br /&gt;
===UTF-8 file format ===&lt;br /&gt;
&lt;br /&gt;
Models that contain Unicode characters (characters not present in the ASCII, or ISO-8859-1, character set, generally those with character codes above 255, including Chinese, Japanese, Korean, Cyrillic, Greek and other alphabets and esoteric mathematical and graphical symbols)&lt;br /&gt;
are saved using the UTF-8 character encoding, whereas Analytica 4.4 and earlier assume model files to be ASCII-encoded. These UTF-8 files will load into Analytica 4.4 and earlier, but extended characters (any character with an ASCII code above 127) become mangled into two or three characters. The user is warned about the problem when the model is loaded into the earlier release.&lt;br /&gt;
&lt;br /&gt;
This is not a problem if you have not used any Unicode characters in your model, since in that case, Analytica will save your model using the ASCII encoding. If your model does utilize Unicode characters, then you need to tell your users that 4.5 or later is required, since Unicode support was introduced in Release 4.5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt; Error Message Types / {{PAGENAME}} / Bibliography&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Error_Message_Types&amp;diff=38848</id>
		<title>Error Message Types</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Error_Message_Types&amp;diff=38848"/>
		<updated>2015-12-29T04:20:07Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Appendices &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several types of error messages in Analytica. Many messages are designed to inform you that something in the model needs to be corrected; some messages indicate that Analytica cannot continue or complete your request. Each error message begins with its message type, one of warning, lexical, syntax, evaluation, system, and fatal errors. In general, Analytica allows you to continue working on your model unless it cannot proceed until a problem has been corrected. When you are editing a variable definition, you can request an error message by pressing Alt-Enter or by clicking the definition warning icon .&lt;br /&gt;
&lt;br /&gt;
==Warning==&lt;br /&gt;
&lt;br /&gt;
A warning indicates that there is a possible problem. Here is an example.&lt;br /&gt;
&lt;br /&gt;
:::[[File:warning.png|400px]]&lt;br /&gt;
&lt;br /&gt;
A warning is reported during result evaluation to inform you that continuing can yield unexpected results.&lt;br /&gt;
&lt;br /&gt;
You can suppress evaluation warnings for all variables by disabling the Show result warnings preference (see [http://wiki.analytica.com/index.php?title=Preferences_dialog Preferences dialog]). When Show result warnings is unchecked, any warning conditions encountered during result evaluation is ignored. You can also suppress&lt;br /&gt;
warnings during evaluation of a single expression with the [http://wiki.analytica.com/index.php?title=IgnoreWarnings IgnoreWarnings(expr)] function. &lt;br /&gt;
&lt;br /&gt;
If an identifier in a module you are adding to a model has a name conflict with an identifier in the model, you see a warning similar to the following.&lt;br /&gt;
&lt;br /&gt;
:::[[File:warning2.png|400px]]&lt;br /&gt;
&lt;br /&gt;
==Lexical error==&lt;br /&gt;
&lt;br /&gt;
A lexical error occurs when a component of an expression was expected and is missing or is invalid. For example, if you enter a number with an invalid number suffix, you might get a message similar to the following.&lt;br /&gt;
&lt;br /&gt;
:::[[File:lexical.png|400px]][[File:lexical.png|400px]]&lt;br /&gt;
&lt;br /&gt;
==Syntax error==&lt;br /&gt;
&lt;br /&gt;
A syntax error occurs when an expression contains a syntax mistake. Analytica often reports the mistake together with the fragment of the expression that contained the error. Here is an example.&lt;br /&gt;
&lt;br /&gt;
:::[[File:syntax.png|400px]]&lt;br /&gt;
&lt;br /&gt;
The following are two common syntax errors.&lt;br /&gt;
&lt;br /&gt;
If you attempt to change the identifier for a variable, and the new identifier is assigned to another node, you see a message similar to the following.&lt;br /&gt;
&lt;br /&gt;
'''Expecting &amp;quot;,&amp;quot;''' Indicates a comma is missing, or there are too few parameters to a function.&lt;br /&gt;
'''Expecting &amp;quot;)&amp;quot;''' Indicates there are too many parameters to a function.&lt;br /&gt;
&lt;br /&gt;
If you attempt to change the identifier for a variable, and the new identifier is assigned to another node, you see a message similar to the following.&lt;br /&gt;
&lt;br /&gt;
:::[[File:syntax2.png|400px]]&lt;br /&gt;
&lt;br /&gt;
==Evaluation error== &lt;br /&gt;
&lt;br /&gt;
An evaluation error occurs when there is a problem while evaluating a variable, user-defined function, or system function. You are asked if you want to edit the definition of the variable currently being evaluated.&lt;br /&gt;
&lt;br /&gt;
:::[[File:evaluation.png|400px]]&lt;br /&gt;
&lt;br /&gt;
If a system function expects a specific kind of argument, an error message similar to the following is displayed.&lt;br /&gt;
&lt;br /&gt;
:::[[File:evaluation2.png|400px]]&lt;br /&gt;
&lt;br /&gt;
This message indicates that an argument passed to the function is of a different type or cannot be handled by that function. You might need to redefine a variable being used as an argument to the function, or change an expression being passed as an argument.&lt;br /&gt;
&lt;br /&gt;
==Invalid number==&lt;br /&gt;
&lt;br /&gt;
If a calculation tries to perform a division by zero, it displays a warning with an option to continue calculating. Three possible error codes can be returned as a result of an invalid calculation.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! '''Code'''&lt;br /&gt;
! '''Meaning'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| '''INF'''&lt;br /&gt;
|  Infinity, such as 1/0.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| '''NAN'''&lt;br /&gt;
|  Not A Number. Results from invalid functions such as Sqrt(-1), or 0/0.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| '''NULL''' (blank)&lt;br /&gt;
|  Displays as a blank cell if the result is a table, or shows the '''Compute''' button otherwise. Results from certain functions, such as SubIndex(), when a result is not available.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You can test for these results in an expression using &amp;quot;X=INF&amp;quot;, Isnan(X), or X=NULL.&lt;br /&gt;
&lt;br /&gt;
==System error==&lt;br /&gt;
&lt;br /&gt;
If you see this message type, please [mailto:support@lumina.com email us] or click [http://www.lumina.com/support/support-issue/ here] to report the error.&lt;br /&gt;
&lt;br /&gt;
==Out of memory error==&lt;br /&gt;
&lt;br /&gt;
Indicates that Analytica has used up all available memory and cannot complete the current command. If this occurs, first save your model. Before attempting to evaluate again, close some windows, use a smaller sample size, or expand the memory available to Analytica (see [[Analytica_Specifications#Memory_usage|Memory Usage]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Identifiers Already Used / {{PAGENAME}} / Forward and Backward Compatibility&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Identifiers_Already_Used&amp;diff=38847</id>
		<title>Identifiers Already Used</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Identifiers_Already_Used&amp;diff=38847"/>
		<updated>2015-12-29T04:19:43Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Appendices &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each object, whether built-in or created by you, must have a unique identifier. This identifier must start with a letter, and can be up to 20 characters including letters, digits, and underscores. If you try to create an identifier already in use, it warns you and appends a digit to make it unique.&lt;br /&gt;
&lt;br /&gt;
To see all identifiers currently in use:&lt;br /&gt;
&lt;br /&gt;
# Press ''Control+’''  (Control + single apostrophe), to open the '''Typescript''' Window&lt;br /&gt;
# Type '''List''', then press ''Enter''.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To see all identifiers starting with the prefix “Con”:&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Type List &amp;quot;^Con&amp;quot;, then press ''Enter''.&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt; Any regular expression can appear between the quotes.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Analytica Specifications / {{PAGENAME}} / Error Message Types&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Analytica_Specifications&amp;diff=38846</id>
		<title>Analytica Specifications</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Analytica_Specifications&amp;diff=38846"/>
		<updated>2015-12-29T04:18:56Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Appendices &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Hardware and Software==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| CPUs supported&lt;br /&gt;
| Pentium or higher and equivalent AMD processors recommended&lt;br /&gt;
|-&lt;br /&gt;
| System Software&lt;br /&gt;
| Windows XP, Vista, Windows 7, Server&lt;br /&gt;
|-&lt;br /&gt;
| Memory requirements&lt;br /&gt;
|128 MB (512 MB+ recommended)&lt;br /&gt;
|-&lt;br /&gt;
| Application size&lt;br /&gt;
|Approximately 6 MB&lt;br /&gt;
|-&lt;br /&gt;
| Maximum memory usable by &amp;lt;br /&amp;gt;&lt;br /&gt;
Analytica process&lt;br /&gt;
| Analytica 64-bit: 128GB (limited by max pagefile size)&lt;br /&gt;
Analytica 32-bit:&amp;lt;br /&amp;gt;&lt;br /&gt;
:4GB on Windows x64&amp;lt;br /&amp;gt;&lt;br /&gt;
:3GB if /3GB flag added in C:\boot.ini&amp;lt;br /&amp;gt;&lt;br /&gt;
:2GB without /3GB flag in C:\boot.ini&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Objects==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Number of system objects&lt;br /&gt;
| 738&lt;br /&gt;
|-&lt;br /&gt;
| Maximum user-defined objects&lt;br /&gt;
| 31,900&lt;br /&gt;
|-&lt;br /&gt;
| Maximum number of local variables&lt;br /&gt;
|No fixed limit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Uncertainty==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Probability methods&lt;br /&gt;
| Random Latin HyperCube&amp;lt;br /&amp;gt;&lt;br /&gt;
Median Latin HyperCube&amp;lt;br /&amp;gt;&lt;br /&gt;
Monte Carlo&lt;br /&gt;
|-&lt;br /&gt;
| Maximum sample size&lt;br /&gt;
| 99,999,999 for Analytica Enterprise, Optimizer, Power Player, and ADE&amp;lt;br /&amp;gt;&lt;br /&gt;
30,000 (other editions)&amp;lt;br /&amp;gt;&lt;br /&gt;
limited by available memory&lt;br /&gt;
|-&lt;br /&gt;
| Random sampling methods&lt;br /&gt;
|Minimal Standard&lt;br /&gt;
L’Ecuyer&amp;lt;br /&amp;gt;&lt;br /&gt;
Knuth&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Numbers and arrays==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Number precision&lt;br /&gt;
| 15 significant digits for floating-point numbers&lt;br /&gt;
9 digits for integers&lt;br /&gt;
|-&lt;br /&gt;
| Maximum elements in a dimension&lt;br /&gt;
| 99,999,999 (Analytica Enterprise, Optimizer, Power Player, and ADE)&amp;lt;br /&amp;gt;&lt;br /&gt;
30,000 (other editions)&lt;br /&gt;
|-&lt;br /&gt;
| Maximum dimensions in an array&lt;br /&gt;
|15&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Memory usage ==&lt;br /&gt;
The '''Memory Usage''' window displays the amount of memory available on your system, as well as the memory currently in use by all applications, including Windows itself. The memory available on your system is the sum of all physical memory installed on your system and the pagefile on &lt;br /&gt;
your hard disk, which is used to complement the physical memory.&lt;br /&gt;
&lt;br /&gt;
To display the '''Memory Usage''' window, select '''Show Memory Usage''' from the '''Window''' menu. The memory usage displays in two sizes, depending on whether you check Expanded View. The expanded view contains a large number of memory statistics.&lt;br /&gt;
&lt;br /&gt;
[[File:memory.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;gt;The above window appears automatically when Analytica runs low on memory.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:memory_2.png|800px]]&lt;br /&gt;
&lt;br /&gt;
If you require additional memory to run your model at a given sample size, you can take several steps to increase the amount of memory available to Analytica:&lt;br /&gt;
# Close other open applications. &lt;br /&gt;
::All applications require a segment of memory to operate, and this reduces the memory available to Analytica. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Increase the size of your computer’s page file. &amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Analytica is a 32-bit process, and like all 32-bit process, the Windows operating system limits the maximum amount of memory that can be used by a 32-bit process to a default limit of 2GB. In Windows XP and Vista, this limit can be increased to 3GB by editing the system file C:\boot.ini. For the line corresponding to your operating in that file, append /3GB and /USERVA options. For example, after your edit, the line may be: &amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
::: &amp;lt;code&amp;gt;multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=&amp;quot;Windows XP&amp;quot; /3GB /USERVA&amp;lt;/code&amp;gt; &lt;br /&gt;
::After making the edit, a system reboot is required for this to take effect. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;4&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Consider adding more physical memory to your computer. &amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
:: If you are limited by the 3GB per process ceiling, then adding more memory will not increase available space, although it may speed up execution when other applications are also open. Analytica 64-bit will directly benefit from any RAM you add. &lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Add a solid-state drive to your computer and locate your page file on it. &amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt; Consider ways to reorganize your model. Are there dimensions that can be removed from the model, or especially from problematic high-dimensional results. The Performance Profiler (in Analytica Enterprise) can help you pinpoint variables that consume a lot of memory.&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For additional ideas for coping with memory limitations, see [http://wiki.analytica.com/index.php?title=Managing_Memory_and_CPU_Time_for_large_models Managing Memory and CPU Time for large models].&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Selecting the Sample Size / {{PAGENAME}} / Identifiers Already Used&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Selecting_the_Sample_Size&amp;diff=38845</id>
		<title>Selecting the Sample Size</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Selecting_the_Sample_Size&amp;diff=38845"/>
		<updated>2015-12-29T04:18:28Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Appendices &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each probabilistic value is simulated by computing a random sample of values from the actual probability distribution.&lt;br /&gt;
&lt;br /&gt;
You can control the sampling method and sample size by using '''Uncertainty Setup'''. This appendix briefly discusses how to select a sample size. &lt;br /&gt;
&lt;br /&gt;
==Choosing an Appropriate Sample Size==&lt;br /&gt;
&lt;br /&gt;
There is a clear trade-off for using a larger sample size in calculating an uncertainty variable. When you set the sample size to a large value, the result is less noisy, but it takes a longer time to compute the distribution. For an initial probabilistic calculation, a sample size of 20 to 50 is usually adequate.&lt;br /&gt;
&lt;br /&gt;
How should you choose the sample size &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;? It depends both on the cost of each model run, and what you want the results for. An advantage of the Monte Carlo method is that you can apply many standard statistical techniques to estimate the precision of estimates of the output distribution. This is because the generated sample of values for each output variable is a random sample from the true probability distribution for that variable.&lt;br /&gt;
&lt;br /&gt;
==Uncertainty about the Mean==&lt;br /&gt;
&lt;br /&gt;
First, suppose you are primarily interested in the precision of the mean of your output variable &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;. Assume you have a random sample of &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; output values generated by Monte Carlo simulation:&lt;br /&gt;
&lt;br /&gt;
:(y&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, y&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;, y&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt;, …y&amp;lt;sub&amp;gt;m&amp;lt;/sub&amp;gt;) &amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(1)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can estimate the mean and standard deviation of y using the following equations:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;\vec y=\sum_{i=1}^m \frac { y_i }m&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(2)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;s^2=\sum_{i=1}^m \frac { (y_i - \vec y)^2} {m - 1}&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(3)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This leads to the following confidence interval with confidence &amp;lt;code&amp;gt;α&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; is the deviation for the unit normally enclosing probability &amp;lt;code&amp;gt;α&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;\left (\vec y-c\frac {s} {\sqrt m}, \vec y + c\frac {s} {\sqrt m}\right ) &amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(4)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suppose you wish to obtain an estimate of the mean of &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; with an α confidence interval smaller than &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt; units wide. What sample size do you need? You need to make sure that:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;w&amp;gt;2c \frac {s}{\sqrt m}&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(5)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or, rearranging the inequality:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;m&amp;gt; \left ( \frac {2cs}{w}\right ) ^2&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(6)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To use this, first make a small Monte Carlo run with, say, 10 values to get an initial estimate of the variance of y — that is, s2. You can then use equation (6) to estimate how many samples reduce the confidence interval to the requisite width w.&lt;br /&gt;
&lt;br /&gt;
For example, suppose you wish to obtain a 95% confidence interval for the mean that is less than 20 units wide. Suppose your initial sample of 10 gives s = 40. The deviation c enclosing a probability of 95% for a unit normal is about 2. Substituting these numbers into equation (6), you get:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;m&amp;gt; \left ( \frac {2 \times 2 \times 40}{20} \right )^2 = 8^2 = 64&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(7)&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, to get the required precision for the mean, you should set the sample size to about 64.&lt;br /&gt;
&lt;br /&gt;
== Estimating Confidence Intervals for Fractiles ==&lt;br /&gt;
&lt;br /&gt;
Another criterion for selecting sample size is the precision of the estimate of the median and other fractiles, or more generally, the precision of the estimated cumulative distribution. Assume that the sample m values of y are relabeled so that they are in increasing order:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt; y_1 \le, y_2 \le, ...y_m&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; is the deviation enclosing probability &amp;lt;code&amp;gt;α&amp;lt;/code&amp;gt; of the unit normal. Then the following pair of sample values constitutes the confidence interval:&lt;br /&gt;
&lt;br /&gt;
:(&amp;lt;big&amp;gt;y&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;, y&amp;lt;sub&amp;gt;k&amp;lt;/sub&amp;gt;&amp;lt;/big&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;i = \left \lfloor mp - c \sqrt {mp (1-p)} \right \rfloor&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(8)&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;i = \left \lceil mp - c \sqrt {mp (1-p)} \right \rceil&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(9)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Note&amp;quot;&amp;gt; The brackets in equations (8) and (9) above mean round up [[File:lceil.png]] and round down[[File:rfloor.png]], since they are computing numbers that need to be integers.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suppose you want to achieve sufficient precision such that the &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; confidence interval for the pth fractile Y&amp;lt;sub&amp;gt;p&amp;gt;&amp;lt;/sub&amp;gt; is given by (y&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, y&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;), where y&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt; is an estimate of '''&amp;lt;math&amp;gt;{Y_p-{_\Delta}{_p}}&amp;lt;/math&amp;gt;''', and y&amp;lt;sub&amp;gt;k&amp;lt;/sub&amp;gt; is an estimate of '''&amp;lt;math&amp;gt;{Y_p+{_\Delta}{_p}}&amp;lt;/math&amp;gt;'''. In other words, you want &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; confidence of Y&amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; being between the sample values used as estimates of the (&amp;lt;math&amp;gt;p-{_\Delta}{_p})&amp;lt;/math&amp;gt;) and (&amp;lt;math&amp;gt;p+{_\Delta}{_p})&amp;lt;/math&amp;gt;) fractiles. What sample size do you need? Ignoring the rounding, you have approximately:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;i = m(p-{\Delta}p), k = m(p+{\Delta} p)&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(10)&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;k - i = 2m{\Delta}p&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(11)&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From equations (8) and (9) above, you have:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;k - i = 2c\sqrt {mp(1-p)}&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(12)&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Equating the two expressions for k-1 , you obtain:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;2mp\Delta p = 2c \sqrt {mp(1-p)}&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(13)&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;m=p(1- p) \left (\frac {c}{\Delta p} \right )^2&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(14)&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, suppose you want to be 95% confident that the estimated fractile Y&amp;lt;sub&amp;gt;.90&amp;lt;/sub&amp;gt; is between the estimated fractiles Y&amp;lt;sub&amp;gt;.85&amp;lt;/sub&amp;gt; and Y&amp;lt;sub&amp;gt;.95&amp;lt;/sub&amp;gt;. So you have &amp;lt;math&amp;gt;\Delta p&amp;lt;/math&amp;gt;=0.05, and c≈2. Substituting the numbers into equation (14), you get:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;m = 0.90 \times  (1 - 0.90) \times \left (\frac {2}{0.05} \right )^2 = 144&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(15)&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
On the other hand, suppose you want the credible interval for the least precise estimated percentile (the 50th percentile) to have a 95% confidence interval of plus or minus one estimated percentile. Then:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;big&amp;gt;&amp;lt;math&amp;gt;m = 0.5 \times  (1 - 0.5) \times \left (\frac {2}{0.01} \right )^2 = 10,000&amp;lt;/math&amp;gt;&amp;lt;/big&amp;gt;&amp;lt;div class=&amp;quot;floatright&amp;quot;&amp;gt;(16)&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These results are completely independent of the shape of the distribution. If you find this an appropriate way to state your requirements for the precision of the estimated distribution, you can determine the sample size before doing any runs to see what sort of distribution it might be.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Appendices / {{PAGENAME}} / Analytica Specifications&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=COM_Automation_Objects&amp;diff=38844</id>
		<title>COM Automation Objects</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=COM_Automation_Objects&amp;diff=38844"/>
		<updated>2015-12-29T04:17:15Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft Component Object Model (COM) provides a framework for interprocess communication within the Windows operating system. Using the functions described in this section, you can instantiate and call other applications that expose a COM automation interface (known as the IDispatch interface). You can write your own COM servers in C++, C#, VB, and a host of other languages, and then call them, or you can use existing interfaces to call applications from other vendors.&lt;br /&gt;
&lt;br /&gt;
These functions allow your model to call other applications. This is different from having other applications call your Analytica model. The Analytica Decision Engine (ADE) product provides the latter functionality.&lt;br /&gt;
&lt;br /&gt;
If you intend to use these functions, you should refer to [http://wiki.analytica.com/index.php?title=COM_Integration Com Integration], where the topic is covered in greater depth.&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=COMCreateObject COMCreateObject](name,''server,flags,user,password'') ==&lt;br /&gt;
Instantiates a COM object. This is the first step when using COM. Only the first parameter, name, is required, which is the textual name of a registered server such as &amp;quot;'''ADE4.CAEngine&amp;quot;, &amp;quot;MSXML2.DomDocument&amp;quot; or &amp;quot;clsid:72C24DD5-D70A-438B-8A42-98424B88AFB8'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The optional server parameter is the name of the computer where the object will be run for remote invocation. Without this parameter, the object is instantiated on the same computer where Analytica is running.&lt;br /&gt;
&lt;br /&gt;
The flags parameter allows control over several esoteric flags. These may be added together. The most notable flags are:&lt;br /&gt;
* 0x1 = Allow in-process instantiation&lt;br /&gt;
* 0x2 = Allow out-of-process instantiation&lt;br /&gt;
* 0x40000 = Allow 32-bit component&lt;br /&gt;
* 0x80000 = Allow 64-bit component&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To specify the account credentials that the object will run under, you may specify the '''user''' and '''password''' parameters.&lt;br /&gt;
&lt;br /&gt;
You will usually set aside a variable as the object that is instantiated. The definition to this variable will be just a call to [http://wiki.analytica.com/index.php?title=COMCreateObject COMCreateObject](). The object itself will persist (i.e., continue running) as long as the variable remains computed. When the variable is invalidated, the object is released and the COM server will usually terminate. If you hold the result of [http://wiki.analytica.com/index.php?title=COMCreateObject COMCreateObject] in a local variable, the COM object is released when the local variable falls out of scope (more generally, when Analytica the last use of the object falls out of scope).&lt;br /&gt;
&lt;br /&gt;
==obj -&amp;gt; method()==&lt;br /&gt;
&lt;br /&gt;
After using the [http://wiki.analytica.com/COMCreateObject COMCreateObject]() or [http://wiki.analytica.com/index.php?title=SpreadsheetOpen SpreadsheetOpen]() function to instantiate an automation object, you can call method or read and write properties of the object using the -&amp;gt; operator, as show in this example which calls a method:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ade-&amp;gt;OpenModel(&amp;quot;Portfolio.ana”)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where Variable ade is defined as &amp;lt;code&amp;gt;COMCreateObject(&amp;quot;ADE4.CAEngine&amp;quot;)&amp;lt;/code&amp;gt;. Without parenthesis, properties are read, e.g.,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ade-&amp;gt;OutputBuffer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and properties can be set using assignment,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ade-&amp;gt;DefaultRenderingStyle-&amp;gt;StringQuotes := 2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The -&amp;gt; operator provides a convenient and terse syntax resembling the object syntax of many programming languages, but you should think of this operator as being an abbreviation for the [http://wiki.analytica.com/index.php?title=COMCallMethod COMCallMethod](), [http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty]() and [http://wiki.analytica.com/index.php?title=COMPutProperty COMPutProperty]() functions. Each of these functions provide additional options that are useful in some circumstances.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=COMCallMethod COMCallMethod](obj, methodName, ''parameters...,resultIndex...,concurrent'')==&lt;br /&gt;
&lt;br /&gt;
Calls the method of '''obj''' named &amp;lt;code&amp;gt;methodName&amp;lt;/code&amp;gt;, passing zero or more '''parameters''' to the method. When the method returns an array, you may want to map this to existing indexes in your model, which is done by specifying the result index or indexes in the &amp;lt;code&amp;gt;resultIndex&amp;lt;/code&amp;gt; parameter. Because '''parameters''' may have any number of specified arguments, &amp;lt;code&amp;gt;resultIndex&amp;lt;/code&amp;gt; must be specified using the named parameter calling syntax. The optional [http://wiki.analytica.com/index.php?title=COM_Integration#Concurrent_calls concurrent parameter] issues method calls asynchronously or in parallel.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;GetPriceHistory&amp;lt;/code&amp;gt; method of the &amp;lt;code&amp;gt;Reuters&amp;lt;/code&amp;gt; object returns a 2-D array of historic stock prices (this is a hypothetical app sold by a hypothetical 3rd party). The first dimension is the trading date, the second has for items: the Open, Close, High and Low. The method itself accepts three parameters: a stock symbol, a start and and end date. You wish to map the result to indexes that already exist in your model.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;COMCallMethod(reuters,”GetPriceHistory”,”AAPL”,8-Jan-2014,Today(), resultIndex:Time,DateOpenCloseHighLow)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=COMArray COMArray](x,i...)==&lt;br /&gt;
&lt;br /&gt;
When you pass Analytica arrays as parameters of a COM method, the call is iterated (invoked multiple times) for each atomic combination of parameters, and the results from each call are collected. When a method expects an array-valued parameter, you must package it using the [http://wiki.analytica.com/index.php?title=COMArray COMArray] function. The first parameter, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, in the array being passed, and the remaining parameters are the Analytica indexes of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;. The list of indexes tells it which indexes are intrinsic (any not listed are iterated) and the order of dimensions that the server expects.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;mathObj-&amp;gt;PrincipleEigenVector( COMArray(X,I,J), resultIndex:I )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The method called here expects a 2-D matrix and returns a 1-D vector.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty](obj, propertyName, ''parameters...,resultIndex...'')==&lt;br /&gt;
&lt;br /&gt;
Retrieves a property with the given name. Most properties have no parameters, so usually this call is used with only &amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;propertyName&amp;lt;/code&amp;gt;, and even more commonly the syntax &amp;lt;code&amp;gt;obj-&amp;gt;propertyName&amp;lt;/code&amp;gt; is used instead. Some COM objects have indexed properties (the parameters usually act like subscripts), and in those cases parameters may be specified. To call an indexed property, you must use [http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty](), since the obj-&amp;gt;name(x) syntax where the name is followed by parenthesis for a parameter list is interpreted as a method call. Some COM applications make a strong distriction between methods and properties, others don’t.&lt;br /&gt;
&lt;br /&gt;
When [http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty] is called, &amp;lt;code&amp;gt;propertyName&amp;lt;/code&amp;gt; is text, surrounded by quotes, or an expression that evaluates to text. The &amp;lt;code&amp;gt;resultIndex&amp;lt;/code&amp;gt; specifies the Analytica indexes for the result when the property’s value is an array.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;COMGetProperty( Wnetwork, &amp;quot;UserDomain&amp;quot; )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which is equivalent to&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Wnetwork-&amp;gt;UserDomain&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=COMPutProperty COMPutProperty](obj, propertyName, value, ''parameters...'')==&lt;br /&gt;
&lt;br /&gt;
Sets the property named &amp;lt;code&amp;gt;propertyName&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;. The call&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;COMSetProperty(renderStyle,”NumberAsText”,true)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;renderStyle-&amp;gt;NumberAsText := true&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a property is an indexed property, '''parameters''' are specified, usually indicating subscript coordinates of some kind.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Attrib_of_Obj Attrib of Obj]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=COMArray COMArray]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=COMCallMethod COMCallMethod]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=COMCreateObject COMCreateObject]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=COMPutProperty COMPutProperty]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;RunConsoleProcess - call other applications / {{PAGENAME}} /  Appendices&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=COM_Automation_Objects&amp;diff=38843</id>
		<title>COM Automation Objects</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=COM_Automation_Objects&amp;diff=38843"/>
		<updated>2015-12-29T04:15:21Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft Component Object Model (COM) provides a framework for interprocess communication within the Windows operating system. Using the functions described in this section, you can instantiate and call other applications that expose a COM automation interface (known as the IDispatch interface). You can write your own COM servers in C++, C#, VB, and a host of other languages, and then call them, or you can use existing interfaces to call applications from other vendors.&lt;br /&gt;
&lt;br /&gt;
These functions allow your model to call other applications. This is different from having other applications call your Analytica model. The Analytica Decision Engine (ADE) product provides the latter functionality.&lt;br /&gt;
&lt;br /&gt;
If you intend to use these functions, you should refer to [http://wiki.analytica.com/index.php?title=COM_Integration Com Integration], where the topic is covered in greater depth.&lt;br /&gt;
&lt;br /&gt;
== [[COMCreateObject]](name,''server,flags,user,password'') ==&lt;br /&gt;
Instantiates a COM object. This is the first step when using COM. Only the first parameter, name, is required, which is the textual name of a registered server such as &amp;quot;'''ADE4.CAEngine&amp;quot;, &amp;quot;MSXML2.DomDocument&amp;quot; or &amp;quot;clsid:72C24DD5-D70A-438B-8A42-98424B88AFB8'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The optional server parameter is the name of the computer where the object will be run for remote invocation. Without this parameter, the object is instantiated on the same computer where Analytica is running.&lt;br /&gt;
&lt;br /&gt;
The flags parameter allows control over several esoteric flags. These may be added together. The most notable flags are:&lt;br /&gt;
* 0x1 = Allow in-process instantiation&lt;br /&gt;
* 0x2 = Allow out-of-process instantiation&lt;br /&gt;
* 0x40000 = Allow 32-bit component&lt;br /&gt;
* 0x80000 = Allow 64-bit component&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To specify the account credentials that the object will run under, you may specify the '''user''' and '''password''' parameters.&lt;br /&gt;
&lt;br /&gt;
You will usually set aside a variable as the object that is instantiated. The definition to this variable will be just a call to [[COMCreateObject]](). The object itself will persist (i.e., continue running) as long as the variable remains computed. When the variable is invalidated, the object is released and the COM server will usually terminate. If you hold the result of [[COMCreateObject]] in a local variable, the COM object is released when the local variable falls out of scope (more generally, when Analytica the last use of the object falls out of scope).&lt;br /&gt;
&lt;br /&gt;
==obj -&amp;gt; method()==&lt;br /&gt;
&lt;br /&gt;
After using the [http://wiki.analytica.com/COMCreateObject COMCreateObject]() or [http://wiki.analytica.com/index.php?title=SpreadsheetOpen SpreadsheetOpen]() function to instantiate an automation object, you can call method or read and write properties of the object using the -&amp;gt; operator, as show in this example which calls a method:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ade-&amp;gt;OpenModel(&amp;quot;Portfolio.ana”)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where Variable ade is defined as COMCreateObject(&amp;quot;ADE4.CAEngine&amp;quot;). Without parenthesis, properties are read, e.g.,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ade-&amp;gt;OutputBuffer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and properties can be set using assignment,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ade-&amp;gt;DefaultRenderingStyle-&amp;gt;StringQuotes := 2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The -&amp;gt; operator provides a convenient and terse syntax resembling the object syntax of many programming languages, but you should think of this operator as being an abbreviation for the [http://wiki.analytica.com/index.php?title=COMCallMethod COMCallMethod](), [http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty]() and [http://wiki.analytica.com/index.php?title=COMPutProperty COMPutProperty]() functions. Each of these functions provide additional options that are useful in some circumstances.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=COMCallMethod COMCallMethod](obj, methodName, ''parameters...,resultIndex...,concurrent'')==&lt;br /&gt;
&lt;br /&gt;
Calls the method of '''obj''' named &amp;lt;code&amp;gt;methodName&amp;lt;/code&amp;gt;, passing zero or more '''parameters''' to the method. When the method returns an array, you may want to map this to existing indexes in your model, which is done by specifying the result index or indexes in the &amp;lt;code&amp;gt;resultIndex&amp;lt;/code&amp;gt; parameter. Because '''parameters''' may have any number of specified arguments, &amp;lt;code&amp;gt;resultIndex&amp;lt;/code&amp;gt; must be specified using the named parameter calling syntax. The optional [http://wiki.analytica.com/index.php?title=COM_Integration#Concurrent_calls concurrent parameter] issues method calls asynchronously or in parallel.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;GetPriceHistory&amp;lt;/code&amp;gt; method of the &amp;lt;code&amp;gt;Reuters&amp;lt;/code&amp;gt; object returns a 2-D array of historic stock prices (this is a hypothetical app sold by a hypothetical 3rd party). The first dimension is the trading date, the second has for items: the Open, Close, High and Low. The method itself accepts three parameters: a stock symbol, a start and and end date. You wish to map the result to indexes that already exist in your model.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;COMCallMethod(reuters,”GetPriceHistory”,”AAPL”,8-Jan-2014,Today(), resultIndex:Time,DateOpenCloseHighLow)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=COMArray COMArray](x,i...)==&lt;br /&gt;
&lt;br /&gt;
When you pass Analytica arrays as parameters of a COM method, the call is iterated (invoked multiple times) for each atomic combination of parameters, and the results from each call are collected. When a method expects an array-valued parameter, you must package it using the [http://wiki.analytica.com/index.php?title=COMArray COMArray] function. The first parameter, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, in the array being passed, and the remaining parameters are the Analytica indexes of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;. The list of indexes tells it which indexes are intrinsic (any not listed are iterated) and the order of dimensions that the server expects.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;mathObj-&amp;gt;PrincipleEigenVector( COMArray(X,I,J), resultIndex:I )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The method called here expects a 2-D matrix and returns a 1-D vector.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty](obj, propertyName, ''parameters...,resultIndex...'')==&lt;br /&gt;
&lt;br /&gt;
Retrieves a property with the given name. Most properties have no parameters, so usually this call is used with only &amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;propertyName&amp;lt;/code&amp;gt;, and even more commonly the syntax &amp;lt;code&amp;gt;obj-&amp;gt;propertyName&amp;lt;/code&amp;gt; is used instead. Some COM objects have indexed properties (the parameters usually act like subscripts), and in those cases parameters may be specified. To call an indexed property, you must use [http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty](), since the obj-&amp;gt;name(x) syntax where the name is followed by parenthesis for a parameter list is interpreted as a method call. Some COM applications make a strong distriction between methods and properties, others don’t.&lt;br /&gt;
&lt;br /&gt;
When [http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty] is called, &amp;lt;code&amp;gt;propertyName&amp;lt;/code&amp;gt; is text, surrounded by quotes, or an expression that evaluates to text. The &amp;lt;code&amp;gt;resultIndex&amp;lt;/code&amp;gt; specifies the Analytica indexes for the result when the property’s value is an array.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;COMGetProperty( Wnetwork, &amp;quot;UserDomain&amp;quot; )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which is equivalent to&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Wnetwork-&amp;gt;UserDomain&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=COMPutProperty COMPutProperty](obj, propertyName, value, ''parameters...'')==&lt;br /&gt;
&lt;br /&gt;
Sets the property named &amp;lt;code&amp;gt;propertyName&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;. The call&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;COMSetProperty(renderStyle,”NumberAsText”,true)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;renderStyle-&amp;gt;NumberAsText := true&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a property is an indexed property, '''parameters''' are specified, usually indicating subscript coordinates of some kind.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Attrib_of_Obj Attrib of Obj]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=COMArray COMArray]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=COMCallMethod COMCallMethod]&lt;br /&gt;
* [[COMCreateObject]]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=COMGetProperty COMGetProperty]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=COMPutProperty COMPutProperty]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;RunConsoleProcess - call other applications / {{PAGENAME}} /  Appendices&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=RunConsoleProcess_-_call_other_applications&amp;diff=38842</id>
		<title>RunConsoleProcess - call other applications</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=RunConsoleProcess_-_call_other_applications&amp;diff=38842"/>
		<updated>2015-12-29T04:13:58Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function lets an Analytica model run a console process, that is, start another Windows application. The application or program can be a simple one with no graphical user interface, or it can interact directly with the user. [http://wiki.analytica.com/index.php?title=RunConsoleProcess RunConsoleProcess]() can provide data as input to the program and return results generated by the application. The '''program''' parameter contains text to specify the directory path and name of the program. It can feed input to the program via command line parameters in '''cmdLine''', via the '''stdIn''' parameter, piped to the ''StdIn'' input channel of the program, or via a data file created with [http://wiki.analytica.com/index.php?title=WriteTextFile WriteTextFile](). Normally, when the program completes, [http://wiki.analytica.com/index.php?title=RunConsoleProcess RunConsoleProcess] returns a result (as text) any information the program writes to '''''stdOut'''''. Analytica can also use [http://wiki.analytica.com/index.php?title=ReadTextFile ReadTextFile]() to read any results the program has saved as a data file.&lt;br /&gt;
&lt;br /&gt;
==Required parameter==&lt;br /&gt;
&lt;br /&gt;
===program===&lt;br /&gt;
&lt;br /&gt;
Text to specify the directory path and name of the Windows application (program) to run. A relative path is interpreted relative to Analytica’s '''CurrentData-Folder'''. If it cannot find or launch the application, it gives an error message.&lt;br /&gt;
&lt;br /&gt;
==Optional parameters==&lt;br /&gt;
&lt;br /&gt;
===cmdline=== &lt;br /&gt;
&lt;br /&gt;
Text given input to the program as command line parameters. (It is separated from the '''program''' parameter to protect against a common type of virus attack.)&lt;br /&gt;
&lt;br /&gt;
===stdIn===&lt;br /&gt;
&lt;br /&gt;
Text to be piped to the '''''StdIn''''' input channel of the program.&lt;br /&gt;
&lt;br /&gt;
===block===&lt;br /&gt;
&lt;br /&gt;
If you omit '''block''' or set it to True (1), [http://wiki.analytica.com/index.php?title=RunConsoleProcess RunConsoleProcess]() ''blocks'' — that is, after calling the process, Analytica stops and waits until the console process terminates and returns a result before it resumes execution. While blocked, Analytica still notices Windows events. If you press Control+Break (or Control+.) before the process terminates, it kills the process, and ends further computation by Analytica, just as when Analytica is computing without another process.&lt;br /&gt;
&lt;br /&gt;
If you set '''block''' to False (0), [http://wiki.analytica.com/index.php?title=RunConsoleProcess RunConsoleProcess]() spawns an independent process that runs concurrently with Analytica. Within Analytica, it returns empty text. Analytica and the spawned process each continues running independently until it terminates. If you press ''Control+Break'' (or ''Control+''), it interrupts and stops further computations by Analytica, but has no effect on the spawned process. An unblocking process might continue running even after you exit Analytica. Unblocking processes are useful when you want to send data to another application for display, such as a special graphing package or GIS, or for saving selected results. It is difficult for Analytica to get any results or status back from an unblocking process. If you need results back it is usually best to use a blocking process.&lt;br /&gt;
&lt;br /&gt;
===curDir===&lt;br /&gt;
&lt;br /&gt;
The directory the process should use as its default directory to read and write  files. If omitted, it uses the application’s own directory as the default.&lt;br /&gt;
&lt;br /&gt;
===priority===&lt;br /&gt;
&lt;br /&gt;
Sets the priority that Windows should give the spawned process relative to the Analytica process. The default (0) is the same priority as the Analytica process. Setting it to +1 or +2 raises its priority, taking more of the CPU for the process. -1 or -2 lowers the priority, letting other processes (including Analytica) use more of the CPU.&lt;br /&gt;
&lt;br /&gt;
===showErr===&lt;br /&gt;
&lt;br /&gt;
Controls the display of error messages from a blocking process. By default, if the process writes anything to '''stdErr''', Analytica displays it as an error message when the process terminates. If '''showErr'''=2 it shows any text in '''stdErr''' as a warning message. If '''showErr'''=0, it ignores anything in '''stdErr'''. Analytica always ignores any error in an unblocking process, which is assumed to control the display of its own errors.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=RunConsoleProcess RunConsoleProcess]() fully supports Intelligent Arrays. If any parameter is passed an array, it runs a separate process for each element of the array. It runs multiple blocking processes sequentially. It runs multiple non-blocking processes concurrently.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
&lt;br /&gt;
=== Run a VB Script ===&lt;br /&gt;
Suppose the Visual Basic program file HelloWorld.vbs is in your model directory and contains:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;WScript.Echo &amp;quot;Hello World&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your call to [http://wiki.analytica.com/index.php?title=RunConsoleProcess RunConsoleProcess] might look like:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;RunConsoleProcess(&amp;quot;C:\Windows\System32\CScript.exe&amp;quot;, &amp;quot;CScript /Nologo HelloWorld.vbs&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
The first parameter identifies the program to be launched. You don’t need to worry about quoting any spaces in the path name. The second parameter is the command line as it might appear on a command prompt. This expression returns the text value &amp;quot;Hello World&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To send data to the '''StdIn''' of the process, include the optional parameter &amp;lt;code&amp;gt;StdIn&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;RunConsoleProcess(&amp;quot;C:\Windows\System32\CScript.exe&amp;quot;, &amp;quot;CScript /Nologo HelloWorld.vbs&amp;quot;, StdIn: MyDataToSend)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;code&amp;gt;MyDataToSend&amp;lt;/code&amp;gt; is an Analytica variable that gives a text value.&lt;br /&gt;
&lt;br /&gt;
===To run a batch file===&lt;br /&gt;
&lt;br /&gt;
Suppose the directory '''C:\Try''' contains a data file named &amp;lt;code&amp;gt;data.log&amp;lt;/code&amp;gt; and a batch file named &amp;lt;code&amp;gt;DoIt.bat&amp;lt;/code&amp;gt; containing:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;#DoIt.bat — dump the log&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Type data.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This batch file assumes it is run from the directory &amp;lt;code&amp;gt;C:\Try&amp;lt;/code&amp;gt; so does not mention the directory of &amp;lt;code&amp;gt;data.log&amp;lt;/code&amp;gt;. From Analytica, you call:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;RunConsoleProcess(&amp;quot;C:\Windows\System32\Cmd.exe&amp;quot;, &amp;quot;Cmd /C DoIt.bat&amp;quot;,CurDir: &amp;quot;C:\Try&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
Or you can run it directly:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;RunConsoleProcess(&amp;quot;DoIt.bat&amp;quot;, &amp;quot;DoIt.bat&amp;quot;, CurDir: &amp;quot;C:\Try&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=ReadTextFile ReadTextFile]()&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=RunConsoleProcess RunConsoleProcess]()&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=WriteTextFile WriteTextFile]()&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Performance Profiler library / {{PAGENAME}} /  COM Automation Objects&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Performance_Profiler_library&amp;diff=38841</id>
		<title>Performance Profiler library</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Performance_Profiler_library&amp;diff=38841"/>
		<updated>2015-12-29T04:12:59Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Performance Profiler library shows you the computation time and memory space used by each variable and function. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have a large model that takes a long time to run or uses a lot of memory, you might want to find out which variables or functions are using the Lion’s share of the time or memory. As experienced programmers know, the results are often a surprise. With the results from the Performance Profiler, you know where to focus your efforts to make the model faster or use less RAM.&lt;br /&gt;
&lt;br /&gt;
First add '''Performance Profiler.ana''' from the '''Libraries''' folder into your model.&lt;br /&gt;
&lt;br /&gt;
::[[File:performance_profiler_1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Now display the results (table or graph) for the variables whose performance you want to profile. Open the library, and click '''Performance profiles'''.&lt;br /&gt;
&lt;br /&gt;
::[[File:performance_profiler_2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
This table lists the variables and functions by row, with the class of the object, parent '''module''', '''Bytes''' of RAM (random access memory), and '''CPU msecs''' (milliseconds of time used by the central processing unit). The last column, '''msecs w ancestors''', shows the CPU milliseconds to compute each variable or function including all its ancestors — i.e., the variables and functions it uses. The Profiler shows all variables and functions that use more than 24 bytes of RAM (the minimum) or take more than 1 millisecond to compute. Use '''Sort objects by''' to sort the table by any column. &lt;br /&gt;
&lt;br /&gt;
If you want to inspect a variable or function to see why it’s taking so much time or memory, just click its title in the &amp;lt;code&amp;gt;.Objects&amp;lt;/code&amp;gt; index column to open its '''Object''' window.&lt;br /&gt;
&lt;br /&gt;
==Update profiles==&lt;br /&gt;
&lt;br /&gt;
After computing more results, click this button to update the performance profile to reflect the additional time and memory used.&lt;br /&gt;
&lt;br /&gt;
==Zero out times==&lt;br /&gt;
&lt;br /&gt;
If you want to look at the incremental time used by additional results, or another computation, first click this button to zero out the times already computed.&lt;br /&gt;
&lt;br /&gt;
==Understanding memory usage==&lt;br /&gt;
&lt;br /&gt;
For complex definitions, it might use much more RAM while it is computing than it needs to cache the final result — the Profiler reports only the latter. The Bytes show the RAM used to store the value of each variable, mid, probabilistic, or both, depending on which it has computed. Typically, an array takes about 12 bytes per number to store. For example, an uncertain dynamic array of numbers, with an index I of 20 elements, &amp;lt;code&amp;gt;Time&amp;lt;/code&amp;gt; has 30 elements, and &amp;lt;code&amp;gt;Samplesize&amp;lt;/code&amp;gt; = 1000, would use about 20 x 30 x 1000 x12 = 7,200,000 bytes or 7.2 Megabytes. Analytica uses an efficient representation for arrays with many zeroes (sparse arrays) or many repeated values. An array that is an exact or partial copy of another array can share slices. In such cases, it might actually use less memory than it reports.&lt;br /&gt;
&lt;br /&gt;
==Understanding computation time==&lt;br /&gt;
&lt;br /&gt;
The CPU time listed is the time it took to evaluate the mid and/or prob value of each variable or function, depending on which type of evaluation it did. It is zero if the results computed did not cause evaluation of the variable or function. A variable is usually only computed at most once each for its mid and prob value. Rare exceptions include when the variable is referenced directly or indirectly in a parameter to &amp;lt;code&amp;gt;Whatif&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;WhatIfall&amp;lt;/code&amp;gt;, which might cause multiple evaluations. A function can be called many times. The CPU time reported is the sum over all these evaluations.&lt;br /&gt;
&lt;br /&gt;
==Time and virtual memory==&lt;br /&gt;
&lt;br /&gt;
Like most 32-bit applications on Windows, Analytica can use up to 3 GB of memory. If your computer doesn’t have that much RAM installed, and it needs more than is available, it can use virtual memory — that is, it saves data onto the hard disk. Since reading and writing a hard disk is usually much slower than RAM, using virtual memory often causes the application to slow down substantially. In this case, finding a way to reduce memory usage below the amount of physical RAM available can speed up the application considerably. Another approach is to install more RAM, up to 4 GB.&lt;br /&gt;
&lt;br /&gt;
==Performance profiling attributes and function==&lt;br /&gt;
&lt;br /&gt;
The Performance Profiler library uses a function, two attributes, and a command, which are also available for you to write your own functions using memory or time. For an example of how to use them, you can open up the library.&lt;br /&gt;
&lt;br /&gt;
===[http://wiki.analytica.com/index.php?title=MemoryInUseBy MemoryInUseBy](v)===&lt;br /&gt;
&lt;br /&gt;
This function returns the number of bytes in use by the cached result(s) for variable v — with the same disclaimer that shared memory can be counted more than once. It includes memory used by mid and prob values if those results have been computed and cached, but it doesn’t force them to be computed if they haven’t been.&lt;br /&gt;
&lt;br /&gt;
This function includes these two special read-only attributes:&lt;br /&gt;
&lt;br /&gt;
====EvaluationTime====&lt;br /&gt;
&lt;br /&gt;
This attribute returns the time in seconds to evaluate its variable or function, not including the time to evaluate any of its inputs.&lt;br /&gt;
&lt;br /&gt;
====EvaluationTimeAll====&lt;br /&gt;
&lt;br /&gt;
This attribute returns the time in seconds to evaluate its variable or function, including the time to compute any of its inputs that needed to&lt;br /&gt;
be evaluated (and their inputs, and so on).&lt;br /&gt;
&lt;br /&gt;
===ResetElapsedTimings===&lt;br /&gt;
&lt;br /&gt;
This command sets these attributes back to zero. Like any command, you can use it in a button script, the Typescript, but not in a regular definition.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt; These features, including the Performance Profiler, are only available for Analytica Enterprise, Power Player, and ADE editions.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=MemoryInUseBy MemoryInUseBy]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Huge Arrays / {{PAGENAME}} / RunConsoleProcess - call other applications&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Making_a_browse-only_model_and_hiding_definitions&amp;diff=38839</id>
		<title>Making a browse-only model and hiding definitions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Making_a_browse-only_model_and_hiding_definitions&amp;diff=38839"/>
		<updated>2015-12-29T04:11:05Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you are ready to let others use the models you have created, you might want to save it as browse-only, so that end users can only change the variables you have designated as inputs (by making input nodes for them). You might also want to hide definitions of variables or functions to protect confidential or proprietary data or algorithms. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
With Analytica Enterprise, you can save models that are locked as browse-only and with hidden definitions, using these steps:&lt;br /&gt;
&lt;br /&gt;
# Hide selected definitions in your model, for entire model, modules, or by variable.&lt;br /&gt;
# Save your master model file (and any linked submodules) so that you can still view and modify it yourself.&lt;br /&gt;
# Select '''Save a copy''' from the '''File''' menu, and check '''Lock and encrypt''' and optionally '''Save as a browse-only model copy''' to save an '''''encrypted''''' copy — that is a file scrambled into a non-human-readable form.&lt;br /&gt;
# Distribute the encrypted copy to your end users.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The third step permanently locks your model so that hidden definitions can never again be viewed in that copy. It is therefore recommended that you save a protected copy of your model, and leave your original model as a master (unprotected) copy. Until the model is stored in an encryped form (step 3), an end user is not prevented from unhiding your definitions, or from viewing them by other means (e.g., by loading the Analytica model file into a text editor). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt; An encrypted model file cannot be decrypted, even by the original author. If it is locked as browse-only, it can never again be edited. If definitions are hidden, they can never again be viewed or edited. Always place a master copy of your model (and any sub-modules) in a safe place before making an encrypted copy.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Hiding and unhiding definitions==&lt;br /&gt;
To hide the definition of a single variable or function, select its node and select '''Hide Definition(s)'''  from the '''Object''' menu, so it becomes checked. You cannot hide multiple nodes, except by hiding all nodes in a parent module. To hide the definitions of all objects in a module:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Select the node of the module in its parent diagram, or open the module and select no nodes inside it.&lt;br /&gt;
# Select '''Hide Definition(s)''' from the '''Object''' menu, so it becomes checked.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If a variable, function, or module is hidden, when you try to view its definition, it displays:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;[Definition is Hidden]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt;The definition of a variable with an input node is always visible regardless of whether it or its parent module is marked as Hidden.&amp;lt;/Tip &amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Unhiding and inheritance of hiding==&lt;br /&gt;
&lt;br /&gt;
Definition hiding is inherited down the module hierarchy. If you hide a module, you hide the definitions of all the objects that it contains, including its submodules and all the objects that they contain — unless you explicitly unhide an object or submodule, in which it or the objects it contains are not hidden. To unhide a variable, function, or module:&lt;br /&gt;
# Select its node in its parent diagram.&lt;br /&gt;
# Select '''Unhide Definition(s)''' from the '''Object''' menu, so it becomes checked.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the module hierarchy shown below, module '''Mo1''' is hidden, and therefore so are the objects it contains, module '''Mo2''', '''Va1''', and '''Va2'''. But module '''Mo3''' is unhidden, and therefore so are the objects it contains, '''Va3''' and '''Mo4'''. However, object '''Va4''' is itself explicitly hidden.&lt;br /&gt;
&lt;br /&gt;
:[[File:browse-only_1.png|250px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt; The '''Hide Definition(s)''' and '''Unhide Definition(s)''' menu options are disabled if the current model, or any of its linked submodules, has been encrypted. In this case, encryption has locked hiding in place.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After hiding the definitions you want, you can view your model to check everything is as you want. You can still Unhide items if you want to view or edit them. But, after saving the model in encrypted form, no one, even you, can view hidden definitions or edit any variables that are not inputs, even if they open the model file in a text editor. That’s why it’s important that you save a master copy for your own use.&lt;br /&gt;
&lt;br /&gt;
==Saving an encrypted copy of your model==&lt;br /&gt;
&lt;br /&gt;
When you are ready to save an encrypted copy of your model, select '''Save a Copy''' In from the '''File''' menu.&lt;br /&gt;
&lt;br /&gt;
:[[File:browse-only_2.png|500px]]&lt;br /&gt;
&lt;br /&gt;
Enter a filename that is different than the filename of your master copy, to make sure that you retain an editable version for your self.&lt;br /&gt;
&lt;br /&gt;
Check ''Lock and encrypt the copy'' at the bottom of the dialog to save the model in an encrypted form that makes any hidden definitions unviewable, even if you try to edit the file.&lt;br /&gt;
&lt;br /&gt;
Check ''Save as a browse-only model'' if you also want to prevent users from changing any variables not designated as inputs. In that case, the model is locked in browse-only mode, even if the user runs the model with an Analytica edition that normally allows editing.&lt;br /&gt;
&lt;br /&gt;
Optionally check ''Save everything in one file by embedding linked modules'' to produce a single file that can be distributed. If your model is utilizing unlocked linked modules, the content in those may remain exposed unless you use this option (alternatively, you can link to locked copies of those modules in your main model before saving your main model in a locked form). Even if you do not lock your model, this option can provide a convenient way to distribute your model as a single file to end-users, or to bundle it for upload to the Analytica Cloud Player. '''Publish to cloud''' on the '''File''' menu saves everything in a single file automatically during the upload.&lt;br /&gt;
&lt;br /&gt;
A browse-only model is always encrypt to prevent anyone from editing the source Analytica file. Thus, it automatically checks ''Lock and encrypt the copy'' and the ''Save in XML format'' option is not available.&lt;br /&gt;
&lt;br /&gt;
If you want end users to be able to use other Enterprise features, such as database access, file reading and writing, Huge Arrays, or performance profiling, they need the Power Player — or their own Enterprise edition. Enterprise and Optimizer-level features are available to users viewing your model through the Analytica Cloud Player (ACP).&lt;br /&gt;
&lt;br /&gt;
When a browse-only model (saved as such from Enterprise) is loaded into Analytica Professional, it runs it in Power Player mode, so that database access, etc., is available.&lt;br /&gt;
&lt;br /&gt;
==Linked libraries and submodules==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Warning&amp;quot;&amp;gt; When your model utilizes linked libraries or submodules, you need to be very careful that the module files you distribute to your users are indeed encrypted or locked as you intend, while at the same time ensuring that you do not accidentally encrypt your master copies of these modules.  Because locking a model as encrypted or browse only is an irreversible operation, it is extremely&lt;br /&gt;
important that you don’t accidentally lock your master versions. If your model uses linked libraries or linked modules, to avoid inadvertently making these mistakes, it is highly recommended that you embed all modules and libraries check in your encrypted copy by checking Save everything in one file by embedding linked modules.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you save a copy of your model, without checking the ''Save everything in one file by embedding linked modules'' option, Analytica 4.2 and later will save a locked copy only of the top-level model file. The locked status of any linked modules remain in their original state, such that individual module files may remain non-encrypted or editable. If you don’t want to embed all linked modules in your encrypted copy, then you’ll need to save an encrypted copy of each submodule individually, and then use '''“Add Module...”''' with the ''Link and Merge'' options to switch your model to using the locked copy, prior to saving a copy of your top-level model.&lt;br /&gt;
&lt;br /&gt;
If you ever use a pre-4.2 release of Analytica, take extreme caution when encrypting a model containing linked modules -- release 4.1 and earlier will also encrypt the linked module files. Thus, it is imperative that you make a copy of all linked sub-modules before saving an encrypted copy.&lt;br /&gt;
&lt;br /&gt;
In Analytica 4.2 and later, you can distribute locked copies of libraries or modules, allowing other model developers to utilize those libraries without being able to view your proprietary definitions (when they are encrypted) or being able to modify the libraries (when locked as browse-only). When using locked libraries, certain operations involving objects in those modules are restricted. You cannot embed an encrypted sub-module within a non-encrypted module, but you can use it as a linked module. Embedding an encrypted module in an encrypted module is allowed. Various operations that might allow a user to gain access to your hidden definitions are disallowed, such as moving an object with a hidden definition from an encrypted module to a non-encrypted module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Warning&amp;quot;&amp;gt; If you distribute locked module files for use by others to use in their models, it is important to ensure that they are using Analytica 4.2 or later. Loading an encrypted or browse-locked module into a model from Analytica 4.1 or earlier will result in the entire model being placed in the same locked state. The ability to utilize a combination of locked and unlocked modules in the same model requires Analytica 4.2 or later.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Modules_and_Libraries Modules and Libraries]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Obfuscated_and_Browse-Only_Models Obfuscated and Browse-Only Models]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Read data from URL on internet / {{PAGENAME}} / Huge Arrays&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Read_data_from_URL_on_internet&amp;diff=38838</id>
		<title>Read data from URL on internet</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Read_data_from_URL_on_internet&amp;diff=38838"/>
		<updated>2015-12-29T04:07:37Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [http://wiki.analytica.com/index.php?title=ReadFromUrl ReadFromUrl function], on the Database menu, reads text from URL sources, such as HTTP web pages or FTP sites.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=ReadFromUrl ReadFromUrl](url, ''method, formValues, formFields, formIndex'')==&lt;br /&gt;
&lt;br /&gt;
Reads text or images from a URL (Universal Resource Locator) location on the web. In most cases, this is called with a single parameter -- the URL. When reading from a web page, the URL should begin with 'http://....'. When reading a text file from an FTP site, it should begin with 'ftp://...'. The entire text from the requested location is returned as a text value. In most cases, you will need to write Analytica expressions to parse the data. When the URL is an http request that points to an image (*.jpg, *.png, *.gif, etc), a picture object is returned that can be assigned to the pict attribute of objects. With the exception of http requests to known image types, the source data must be textual, and if not, the resulting data will be garbled.&lt;br /&gt;
&lt;br /&gt;
Some web pages and most FTP sites require user and password authentication to access. To authenticate, embed the user name and password in the URL as follows:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ReadFromUrl('http://user:password@www.site.com/dir/page.htm')&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ReadFromUrl('ftp://user:password@site.com/directory/file.txt')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional second through fourth parameters are used to submit data to web forms. There are two methods used to submit data to HTTP web forms: &amp;lt;code&amp;gt;method:'POST'&amp;lt;/code&amp;gt;or &amp;lt;code&amp;gt;method:'GET'&amp;lt;/code&amp;gt;. The field names and the values submitted for those fields are specified in &amp;lt;code&amp;gt;formValues&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;formFields&amp;lt;/code&amp;gt;, which must share a common index, and if that common index is anything other than &amp;lt;code&amp;gt;form-Fields&amp;lt;/code&amp;gt;, it should be specified in the &amp;lt;code&amp;gt;formIndex&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=ReadFromUrl ReadFromUrl]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Read and write text files / {{PAGENAME}} / Making a browse-only model and hiding definitions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Read_and_write_text_files&amp;diff=38837</id>
		<title>Read and write text files</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Read_and_write_text_files&amp;diff=38837"/>
		<updated>2015-12-29T04:06:23Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=ReadTextFile ReadTextFile](filename)==&lt;br /&gt;
&lt;br /&gt;
Reads a file &amp;lt;code&amp;gt;filename&amp;lt;/code&amp;gt; and returns its contents as a text value. If &amp;lt;code&amp;gt;filename&amp;lt;/code&amp;gt; contains no directory path, it tries to read from the current folder, usually the folder containing the current model file. If it doesn’t find the file, it opens a Windows browser dialog to prompt the user. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function LinesFromFile(filename: Atom Text)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition:&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;VAR r := SplitText(ReadTextFile(filename), Chr(10));&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Index lines :=1..Size(r);&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Array(lines, r)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function reads in the file and splits the text up at the end of each line, with the Chr(10) line feed character. It then defines a local index ''lines'', to be used as the index of the array of lines that it returns.&lt;br /&gt;
&lt;br /&gt;
The optional parameter &amp;lt;code&amp;gt;showDialog&amp;lt;/code&amp;gt; controls whether the file dialog appears. If not specified, then the dialog appears only if the file does not exist. If you set &amp;lt;code&amp;gt;showDialog&amp;lt;/code&amp;gt; to true (1), it always prompts for the file, even if it finds one by that name. This gives the user a chance to change the filename, while still providing a default name.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=WriteTextFile WriteTextFile](filename, text, ''append, warn, sep'')==&lt;br /&gt;
&lt;br /&gt;
Writes text to the file &amp;lt;code&amp;gt;filename&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;filename&amp;lt;/code&amp;gt; is relative to the current data directory. It returns the full pathname of the file if it is successful in writing or appending to it. By default, the '''append''' flag is &amp;lt;code&amp;gt;False&amp;lt;/code&amp;gt; and '''warn''' flag is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;. If the file doesn’t already exist, it creates the file in the current data directory — and if the file does exist, it asks if you want to replace it. If '''append''' is &amp;lt;code&amp;gt;True (1)&amp;lt;/code&amp;gt;, and the file already exists, it appends the text to the end of the file. If warn is &amp;lt;code&amp;gt;False (0)&amp;lt;/code&amp;gt;, it does not issue a warning before overwriting an existing file when append is &amp;lt;code&amp;gt;False&amp;lt;/code&amp;gt;, or when modifying an existing file when append is &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If text is an array, it writes each element to the file, inserting separator &amp;lt;code&amp;gt;sep&amp;lt;/code&amp;gt; between elements, if provided. If text has more than one dimension, you can control the sequence in which they are written by using function [http://wiki.analytica.com/index.php?title=JoinText JoinText]() to join the text over the index you want innermost.&lt;br /&gt;
&lt;br /&gt;
You can write or append to multiple files when &amp;lt;code&amp;gt;filename&amp;lt;/code&amp;gt; is an array of file names. If text has the same index(es), it writes the corresponding slice of text to each file — following proper array abstraction.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=ReadTextFile ReadTextFile]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=WriteTextFile WriteTextFile]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Database functions / {{PAGENAME}} / Read data from URL on internet&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Database_functions&amp;diff=38836</id>
		<title>Database functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Database_functions&amp;diff=38836"/>
		<updated>2015-12-29T04:04:52Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Database library on the Definition menu contains five functions for working with ODBC databases.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=DbLabels DBLabels](dbIndex)==&lt;br /&gt;
&lt;br /&gt;
Returns a list of the column labels for the result table. This statement can be used to define an index which can then be used as the second argument to [http://wiki.analytica.com/index.php?title=DbTable DBTable](). The first argument, '''dbIndex''', must be defined by a [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=DbQuery DBQuery](connection, sql, ''key'')==&lt;br /&gt;
&lt;br /&gt;
Used to define an index variable. The definition of the index should contain only one [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement. &amp;lt;code&amp;gt;connection&amp;lt;/code&amp;gt; specifies a data source (e.g., &amp;lt;code&amp;gt;'DSN=MyDatabase'&amp;lt;/code&amp;gt;) and sql defines an SQL query. The optional &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; parameter may specify the name of a column in the database that&lt;br /&gt;
will be used to determine the row index values returned by [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]. It is best to only use key columns that contain unique values in each row.&lt;br /&gt;
&lt;br /&gt;
When placed as the definition of an index variable, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() is evaluated as soon as the definition is complete, or immediately when the model is loaded. If you place it in a variable node, it will be evaluated when the result is requested, rather than when the model is loaded, provided there are no index nodes downstream that depend on it. When it is evaluated, the actual query is performed. The resulting result table is cached inside Analytica, to subsequently be accessed by [http://wiki.analytica.com/index.php?title=DbTable DBTable]() or [http://wiki.analytica.com/index.php?title=DbLabels DBLabels]().&lt;br /&gt;
&lt;br /&gt;
When the optional &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; parameter is not specified, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() returns a sequence 1..n, where n is the number of records (rows) in the result table. When &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; is specified, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery] returns a list consisting of the values from that column in the data source.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() should appear only once in a definition, and if it is embedded in an expression, the expression must return a list with n elements.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() processes the sql statement in read-only mode, so that the data source cannot be altered as a result of executing this statement. To alter the data source, use [http://wiki.analytica.com/index.php?title=DbWrite DBWrite]().&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTable DBTable](dbIndex, column)  ==&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTable DBTable](dbIndex, columnList)  ==&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTable DBTable](dbIndex, columnIndex) ==&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbTable DBTable]() is used to get at the data within a result table. The first argument, &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;, must be the name of a variable (normally an index) in your Analytica model that is defined with a [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement. If the second argument, &amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt;, is a text value, it identifies the name of a column label in the result table, in which case [http://wiki.analytica.com/index.php?title=DbTable DBTable]() returns a 1D array (indexed by &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;) with the data for that column. If the second argument is a list of text values (the &amp;lt;code&amp;gt;columnList&amp;lt;/code&amp;gt; form), then [http://wiki.analytica.com/index.php?title=DbTable DBTable]() returns a 2D table with records indexed by &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;, and columns implicitly indexed (i.e., self-indexed/null-indexed). If the second argument is the name of an Analytica variable (usually an index) whose value evaluates to a list of text values, those text values become the column headings for a 2D table with columns indexed by &amp;lt;code&amp;gt;columnIndex&amp;lt;/code&amp;gt;, and rows indexed by &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;. With this last form, &amp;lt;code&amp;gt;columnIndex&amp;lt;/code&amp;gt; can be defined as [http://wiki.analytica.com/index.php?title=DbLabels DBLabels](&amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTablenames DbTableNames](connection, ''catalogs, schemas, tables, tableTypes'') ==&lt;br /&gt;
Connects to an ODBC data source and returns catalog data for the data source. &amp;lt;code&amp;gt;connection&amp;lt;/code&amp;gt; specifies a data source (e.g., '&amp;lt;code&amp;gt;DSN=MyDatabase&amp;lt;/code&amp;gt;'). '''Catalogs, schemas, tables, '''and''' table-Types''' may be names or patterns (as long as the driver manager on your computer is ODBC 3-compliant). Use the percent symbol (%) as a wildcard in each field to match zero or more characters.Underscore (_) matches one character. Most drivers use backslash (\) as an escape character,so that the characters %, _, or \ as literals must be entered as \%, \_, or \\. '''tableTypes''' might be a comma-delimited list of table types. Your data source and ODBC driver might or might not support this call to varying degrees. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
To get all catalog entries (tables, views, schemas, etc) in &amp;lt;code&amp;gt;My db&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DBTableNames('DSN=My db')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get just information on tables in &amp;lt;code&amp;gt;My db&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DBTableNames('DSN=My db',tables:'%')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get all valid views:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DbTableNames('DSN=My db',tableTypes:'VIEW')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The precise value you give to tableTypes depends on which database server you are querying. If you are not sure which type names are used by your database, evaluate [http://wiki.analytica.com/index.php?title=DbTablenames DBTableNames] first with none of the parameters and you should see a column that provides the type names for existing catalog entries.&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbWrite DBWrite](connection, sql) ==&lt;br /&gt;
This function is identical to [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() except that the query is processed in read-write mode, making it possible to store data in the data source from within Analytica.&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery](connection, mdx) ==&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery] lets you read or write multidimensional data on an OLAP server database, returning or sending a multidimensional Analytica array. It uses the standard query language, MDX. MDX is analogous to SQL, but where SQL accesses any standard relational database, MDX accesses&lt;br /&gt;
multidimensional “hypercube” databases. [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery]() works with Microsoft SQL Server Analysis Services.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;connection&amp;lt;/code&amp;gt; is the standard text used to identify and connect with the database, similar to that used in other database functions, such as DBQuery(). mdx is text containing the query in the MDX language.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery]() creates a local index for each dimension. The local indexes are named &amp;lt;code&amp;gt;.Axis1&amp;lt;/code&amp;gt;,&amp;lt;code&amp;gt;.Axis2&amp;lt;/code&amp;gt;,&amp;lt;code&amp;gt; .Axis3&amp;lt;/code&amp;gt;, etc., and contain the cube member captions as elements. Some cube axes returned from MDX queries are hierarchical, and for these, [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery] concatenates member captions, separated by commas. For example, if a particular hierarchical axis included calendar year and quarter, an element of &amp;lt;code&amp;gt;.Axis1&amp;lt;/code&amp;gt; might be “2003,1”, i.e., Calendar year 2003, quarter 1. To use a separator other than comma, specify an optional parameter, &amp;lt;code&amp;gt;sep&amp;lt;/code&amp;gt;, to [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery]. &lt;br /&gt;
&lt;br /&gt;
For additional usage information and examples, please refer to [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery].&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=SqlDriverInfo SqlDriverInfo](driverName) ==&lt;br /&gt;
Returns a list of attribute-value pairs for the specified driver. If &amp;lt;code&amp;gt;driverName=&amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (an empty text value), returns a list of the names of the drivers. &amp;lt;code&amp;gt;driverName&amp;lt;/code&amp;gt; must be a text value — it cannot be a list of text values or an index that is defined as a list of text values. This statement would not&lt;br /&gt;
normally be used in a model, but might be helpful in understanding the SQL drivers that are available. &lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Category%3ADatabase_Functions Analytica Database Functions]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Database access / {{PAGENAME}} / Read and write text files&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Database_functions&amp;diff=38835</id>
		<title>Database functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Database_functions&amp;diff=38835"/>
		<updated>2015-12-29T04:04:05Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Database library on the Definition menu contains five functions for working with ODBC databases.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=DbLabels DBLabels](dbIndex)==&lt;br /&gt;
&lt;br /&gt;
Returns a list of the column labels for the result table. This statement can be used to define an index which can then be used as the second argument to [http://wiki.analytica.com/index.php?title=DbTable DBTable](). The first argument, '''dbIndex''', must be defined by a [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=DbQuery DBQuery](connection, sql, ''key'')==&lt;br /&gt;
&lt;br /&gt;
Used to define an index variable. The definition of the index should contain only one [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement. &amp;lt;code&amp;gt;connection&amp;lt;/code&amp;gt; specifies a data source (e.g., &amp;lt;code&amp;gt;'DSN=MyDatabase'&amp;lt;/code&amp;gt;) and sql defines an SQL query. The optional &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; parameter may specify the name of a column in the database that&lt;br /&gt;
will be used to determine the row index values returned by [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]. It is best to only use key columns that contain unique values in each row.&lt;br /&gt;
&lt;br /&gt;
When placed as the definition of an index variable, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() is evaluated as soon as the definition is complete, or immediately when the model is loaded. If you place it in a variable node, it will be evaluated when the result is requested, rather than when the model is loaded, provided there are no index nodes downstream that depend on it. When it is evaluated, the actual query is performed. The resulting result table is cached inside Analytica, to subsequently be accessed by [http://wiki.analytica.com/index.php?title=DbTable DBTable]() or [http://wiki.analytica.com/index.php?title=DbLabels DBLabels]().&lt;br /&gt;
&lt;br /&gt;
When the optional &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; parameter is not specified, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() returns a sequence 1..n, where n is the number of records (rows) in the result table. When &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; is specified, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery] returns a list consisting of the values from that column in the data source.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() should appear only once in a definition, and if it is embedded in an expression, the expression must return a list with n elements.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() processes the sql statement in read-only mode, so that the data source cannot be altered as a result of executing this statement. To alter the data source, use [http://wiki.analytica.com/index.php?title=DbWrite DBWrite]().&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTable DBTable](dbIndex, column)  ==&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTable DBTable](dbIndex, columnList)  ==&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTable DBTable](dbIndex, columnIndex) ==&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbTable DBTable]() is used to get at the data within a result table. The first argument, &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;, must be the name of a variable (normally an index) in your Analytica model that is defined with a [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement. If the second argument, &amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt;, is a text value, it identifies the name of a column label in the result table, in which case [http://wiki.analytica.com/index.php?title=DbTable DBTable]() returns a 1D array (indexed by &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;) with the data for that column. If the second argument is a list of text values (the &amp;lt;code&amp;gt;columnList&amp;lt;/code&amp;gt; form), then [http://wiki.analytica.com/index.php?title=DbTable DBTable]() returns a 2D table with records indexed by &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;, and columns implicitly indexed (i.e., self-indexed/null-indexed). If the second argument is the name of an Analytica variable (usually an index) whose value evaluates to a list of text values, those text values become the column headings for a 2D table with columns indexed by &amp;lt;code&amp;gt;columnIndex&amp;lt;/code&amp;gt;, and rows indexed by &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;. With this last form, &amp;lt;code&amp;gt;columnIndex&amp;lt;/code&amp;gt; can be defined as [http://wiki.analytica.com/index.php?title=DbLabels DBLabels](&amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTablenames DbTableNames](connection, ''catalogs, schemas, tables, tableTypes'') ==&lt;br /&gt;
Connects to an ODBC data source and returns catalog data for the data source. &amp;lt;code&amp;gt;connection&amp;lt;/code&amp;gt; specifies a data source (e.g., '&amp;lt;code&amp;gt;DSN=MyDatabase&amp;lt;/code&amp;gt;'). '''Catalogs, schemas, tables, '''and''' table-Types''' may be names or patterns (as long as the driver manager on your computer is ODBC 3-compliant). Use the percent symbol (%) as a wildcard in each field to match zero or more characters.Underscore (_) matches one character. Most drivers use backslash (\) as an escape character,so that the characters %, _, or \ as literals must be entered as \%, \_, or \\. '''tableTypes''' might be a comma-delimited list of table types. Your data source and ODBC driver might or might not support this call to varying degrees. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
To get all catalog entries (tables, views, schemas, etc) in &amp;lt;code&amp;gt;My db&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DBTableNames('DSN=My db')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get just information on tables in &amp;lt;code&amp;gt;My db&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DBTableNames('DSN=My db',tables:'%')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get all valid views:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DbTableNames('DSN=My db',tableTypes:'VIEW')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The precise value you give to tableTypes depends on which database server you are querying. If you are not sure which type names are used by your database, evaluate [http://wiki.analytica.com/index.php?title=DbTablenames DBTableNames] first with none of the parameters and you should see a column that provides the type names for existing catalog entries.&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbWrite DBWrite](connection, sql) ==&lt;br /&gt;
This function is identical to [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() except that the query is processed in read-write mode, making it possible to store data in the data source from within Analytica.&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery](connection, mdx) ==&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery] lets you read or write multidimensional data on an OLAP server database, returning or sending a multidimensional Analytica array. It uses the standard query language, MDX. MDX is analogous to SQL, but where SQL accesses any standard relational database, MDX accesses&lt;br /&gt;
multidimensional “hypercube” databases. [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery]() works with Microsoft SQL Server Analysis Services.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;connection&amp;lt;/code&amp;gt; is the standard text used to identify and connect with the database, similar to that used in other database functions, such as DBQuery(). mdx is text containing the query in the MDX language.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery]() creates a local index for each dimension. The local indexes are named &amp;lt;code&amp;gt;.Axis1&amp;lt;/code&amp;gt;,&amp;lt;code&amp;gt;.Axis2&amp;lt;/code&amp;gt;,&amp;lt;code&amp;gt; .Axis3&amp;lt;/code&amp;gt;, etc., and contain the cube member captions as elements. Some cube axes returned from MDX queries are hierarchical, and for these, [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery] concatenates member captions, separated by commas. For example, if a particular hierarchical axis included calendar year and quarter, an element of &amp;lt;code&amp;gt;.Axis1&amp;lt;/code&amp;gt; might be “2003,1”, i.e., Calendar year 2003, quarter 1. To use a separator other than comma, specify an optional parameter, &amp;lt;code&amp;gt;sep&amp;lt;/code&amp;gt;, to [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery]. &lt;br /&gt;
&lt;br /&gt;
For additional usage information and examples, please refer to [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery].&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=SqlDriverInfo SqlDriverInfo](driverName) ==&lt;br /&gt;
Returns a list of attribute-value pairs for the specified driver. If &amp;lt;code&amp;gt;driverName=&amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (an empty text value), returns a list of the names of the drivers. &amp;lt;code&amp;gt;driverName&amp;lt;/code&amp;gt; must be a text value — it cannot be a list of text values or an index that is defined as a list of text values. This statement would not&lt;br /&gt;
normally be used in a model, but might be helpful in understanding the SQL drivers that are available. &lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Category%3ADatabase_Functions Analytica Database Functions]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Database access / {{PAGENAME}} / Read and write text files&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Database_functions&amp;diff=38834</id>
		<title>Database functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Database_functions&amp;diff=38834"/>
		<updated>2015-12-29T04:01:57Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Database library on the Definition menu contains five functions for working with ODBC databases.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=DbLabels DBLabels](dbIndex)==&lt;br /&gt;
&lt;br /&gt;
Returns a list of the column labels for the result table. This statement can be used to define an index which can then be used as the second argument to [http://wiki.analytica.com/index.php?title=DbTable DBTable](). The first argument, '''dbIndex''', must be defined by a [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=DbQuery DBQuery](connection, sql, ''key'')==&lt;br /&gt;
&lt;br /&gt;
Used to define an index variable. The definition of the index should contain only one [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement. &amp;lt;code&amp;gt;connection&amp;lt;/code&amp;gt; specifies a data source (e.g., &amp;lt;code&amp;gt;'DSN=MyDatabase'&amp;lt;/code&amp;gt;) and sql defines an SQL query. The optional &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; parameter may specify the name of a column in the database that&lt;br /&gt;
will be used to determine the row index values returned by [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]. It is best to only use key columns that contain unique values in each row.&lt;br /&gt;
&lt;br /&gt;
When placed as the definition of an index variable, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() is evaluated as soon as the definition is complete, or immediately when the model is loaded. If you place it in a variable node, it will be evaluated when the result is requested, rather than when the model is loaded, provided there are no index nodes downstream that depend on it. When it is evaluated, the actual query is performed. The resulting result table is cached inside Analytica, to subsequently be accessed by [http://wiki.analytica.com/index.php?title=DbTable DBTable]() or [http://wiki.analytica.com/index.php?title=DbLabels DBLabels]().&lt;br /&gt;
&lt;br /&gt;
When the optional &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; parameter is not specified, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() returns a sequence 1..n, where n is the number of records (rows) in the result table. When &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; is specified, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery] returns a list consisting of the values from that column in the data source.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() should appear only once in a definition, and if it is embedded in an expression, the expression must return a list with n elements.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() processes the sql statement in read-only mode, so that the data source cannot be altered as a result of executing this statement. To alter the data source, use [http://wiki.analytica.com/index.php?title=DbWrite DBWrite]().&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTable DBTable](dbIndex, column)  ==&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTable DBTable](dbIndex, columnList)  ==&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTable DBTable](dbIndex, columnIndex) ==&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbTable DBTable]() is used to get at the data within a result table. The first argument, &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;, must be the name of a variable (normally an index) in your Analytica model that is defined with a [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement. If the second argument, &amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt;, is a text value, it identifies the name of a column label in the result table, in which case [http://wiki.analytica.com/index.php?title=DbTable DBTable]() returns a 1D array (indexed by &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;) with the data for that column. If the second argument is a list of text values (the &amp;lt;code&amp;gt;columnList&amp;lt;/code&amp;gt; form), then [http://wiki.analytica.com/index.php?title=DbTable DBTable]() returns a 2D table with records indexed by &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;, and columns implicitly indexed (i.e., self-indexed/null-indexed). If the second argument is the name of an Analytica variable (usually an index) whose value evaluates to a list of text values, those text values become the column headings for a 2D table with columns indexed by &amp;lt;code&amp;gt;columnIndex&amp;lt;/code&amp;gt;, and rows indexed by &amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;. With this last form, &amp;lt;code&amp;gt;columnIndex&amp;lt;/code&amp;gt; can be defined as [http://wiki.analytica.com/index.php?title=DbLabels DBLabels](&amp;lt;code&amp;gt;dbIndex&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbTablenames DbTableNames](connection, ''catalogs, schemas, tables, tableTypes'') ==&lt;br /&gt;
Connects to an ODBC data source and returns catalog data for the data source. &amp;lt;code&amp;gt;connection&amp;lt;/code&amp;gt; specifies a data source (e.g., '&amp;lt;code&amp;gt;DSN=MyDatabase&amp;lt;/code&amp;gt;'). '''Catalogs, schemas, tables, '''and''' table-Types''' may be names or patterns (as long as the driver manager on your computer is ODBC 3-compliant). Use the percent symbol (%) as a wildcard in each field to match zero or more characters.Underscore (_) matches one character. Most drivers use backslash (\) as an escape character,so that the characters %, _, or \ as literals must be entered as \%, \_, or \\. '''tableTypes''' might be a comma-delimited list of table types. Your data source and ODBC driver might or might not support this call to varying degrees. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
To get all catalog entries (tables, views, schemas, etc) in &amp;lt;code&amp;gt;My db&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DBTableNames('DSN=My db')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get just information on tables in &amp;lt;code&amp;gt;My db&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DBTableNames('DSN=My db',tables:'%')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get all valid views:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DbTableNames('DSN=My db',tableTypes:'VIEW')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The precise value you give to tableTypes depends on which database server you are querying. If you are not sure which type names are used by your database, evaluate [http://wiki.analytica.com/index.php?title=DbTablenames DBTableNames] first with none of the parameters and you should see a column that provides the type names for existing catalog entries.&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=DbWrite DBWrite](connection, sql) ==&lt;br /&gt;
This function is identical to [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() except that the query is processed in read-write mode, making it possible to store data in the data source from within Analytica.&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery](connection, mdx) ==&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery] lets you read or write multidimensional data on an OLAP server database, returning or sending a multidimensional Analytica array. It uses the standard query language, MDX. MDX is analogous to SQL, but where SQL accesses any standard relational database, MDX accesses&lt;br /&gt;
multidimensional “hypercube” databases. [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery]() works with Microsoft SQL Server Analysis Services.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;connection&amp;lt;/code&amp;gt; is the standard text used to identify and connect with the database, similar to that used in other database functions, such as DBQuery(). mdx is text containing the query in the MDX language.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery]() creates a local index for each dimension. The local indexes are named &amp;lt;code&amp;gt;.Axis1&amp;lt;/code&amp;gt;,&amp;lt;code&amp;gt;.Axis2&amp;lt;/code&amp;gt;,&amp;lt;code&amp;gt; .Axis3&amp;lt;/code&amp;gt;, etc., and contain the cube member captions as elements. Some cube axes returned from MDX queries are hierarchical, and for these, [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery] concatenates member captions, separated by commas. For example, if a particular hierarchical axis included calendar year and quarter, an element of &amp;lt;code&amp;gt;.Axis1&amp;lt;/code&amp;gt; might be “2003,1”, i.e., Calendar year 2003, quarter 1. To use a separator other than comma, specify an optional parameter, &amp;lt;code&amp;gt;sep&amp;lt;/code&amp;gt;, to [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery]. &lt;br /&gt;
&lt;br /&gt;
For additional usage information and examples, please refer to [http://wiki.analytica.com/index.php?title=MdxQuery MdxQuery].&lt;br /&gt;
&lt;br /&gt;
== [http://wiki.analytica.com/index.php?title=SqlDriverInfo SqlDriverInfo](driverName) ==&lt;br /&gt;
Returns a list of attribute-value pairs for the specified driver. If &amp;lt;code&amp;gt;driverName=&amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (an empty text value), returns a list of the names of the drivers. &amp;lt;code&amp;gt;driverName&amp;lt;/code&amp;gt; must be a text value — it cannot be a list of text values or an index that is defined as a list of text values. This statement would not&lt;br /&gt;
normally be used in a model, but might be helpful in understanding the SQL drivers that are available. &lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Database access / {{PAGENAME}} / Read and write text files&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Database_access&amp;diff=38832</id>
		<title>Database access</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Database_access&amp;diff=38832"/>
		<updated>2015-12-29T03:49:53Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; Analytica Enterprise &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Analytica Enterprise provides several functions for querying external databases using Open Database Connectivity (ODBC). '''''ODBC''''' is a widely used standard for connecting to relational databases, on either local or remote computers. It uses queries in Structured Query Language (SQL, pronounced “sequel,”) to read from and write to databases.&lt;br /&gt;
&lt;br /&gt;
==Overview of ODBC==&lt;br /&gt;
&lt;br /&gt;
SQL is a widely used language to read data from and write data to a relational database. A relational database organizes data in two-dimensional tables, where the columns of a table serve as fields or labels, and the rows correspond to records, entries, or instances. In Analytica, it is more natural to refer to the columns as labels and rows as records. For instance, an address book table might have the columns or labels LastName, FirstName, Address, City, State, Zip, Phone, Fax, and E-mail, and each individual would occupy one row or record in that table.&lt;br /&gt;
&lt;br /&gt;
The result of an SQL query is a two-dimensional table, called a '''''result table'''''. The rows are the records matching the criteria specified by the query. The columns are the requested fields.&lt;br /&gt;
&lt;br /&gt;
Analytica Enterprise provides functions that accept an SQL query, using standard SQL syntax, as a text-valued parameter. These functions return the result of the query as an array with two dimensions, with its rows indexed by a '''''record index''''', and columns indexed by a '''''label index'''''. So, the basic structure of an Analytica model for retrieving a result table is this.&lt;br /&gt;
&lt;br /&gt;
:[[File:db_access_1.png|200px]]&lt;br /&gt;
&lt;br /&gt;
Each of these three nodes could require the information from the &amp;lt;code&amp;gt;Result_Table&amp;lt;/code&amp;gt;. For example, the definition of the record index would require knowing how many records (rows) are in the result table; the label index might need to read the names of the columns — although, often they are known in advance; and of course, the &amp;lt;code&amp;gt;Result_Table&amp;lt;/code&amp;gt; needs to read the table. The Database library provides the functions, [http://wiki.analytica.com/index.php?title=DbQuery DBQuery], [http://wiki.analytica.com/index.php?title=DbLabels DBLabels], and [http://wiki.analytica.com/index.php?title=DbTable DBTable] to define these variables. These functions work in concert to perform the query only once (when the record index is evaluated), and share the result table between the nodes.&lt;br /&gt;
&lt;br /&gt;
Suppose as an example that we have a database containing the addresses individuals. To ensure the titles are meaningful, we name the indexes Individuals and Address_fields. The query is then encoded in the indexes and variable as follows.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index Individuals := DBQuery(Data_source,'SELECT*FROM Addresses')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index Address_fields := DBLabels(Individuals)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Address_fields := DBTable(Individuals, Address_fields)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, the record index is defined using [http://wiki.analytica.com/index.php?title=DbQuery DBQuery](), the label index is defined using [http://wiki.analytica.com/index.php?title=DbLabels DBLabels](), and the result table is defined using [http://wiki.analytica.com/index.php?title=DbTable DBTable](). Each function is described below.&lt;br /&gt;
&lt;br /&gt;
To specify a data source query, two basic pieces of information must always be known. These are the data source identifier and the SQL query text. These two items are the parameters to the [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() function, and are discussed in the following two subsections.&lt;br /&gt;
&lt;br /&gt;
==DSN and data source==&lt;br /&gt;
&lt;br /&gt;
A '''data source''' is described by a text value, which can contain the Data Source Name (DSN) of the data source, login names, passwords, etc. Here, we describe the essentials of how to identify and access a data source. These follow standard ODBC conventions. For more details, consult one of the many texts on ODBC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt;You must have a DSN already configured on your machine. If not, consult with your Network&lt;br /&gt;
Administrator. See [[Database_access#Configuring_a_DSN|Configuring a DSN]].&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general format of a data source identification text is (the single quotes are Analytica’s text delimiters):&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'attr1=value1; attr2=value2; attr3=value3;'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, the following data source identifier specifies the database called 'Automobile Data', with a user login 'John' and a password of 'Lightning':&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'DSN=Automobile Data; UID=John;PWD=Lightning'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a database is not password protected, then a data source descriptor might be as simple as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'DSN=Automobile Data'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a default data source is configured on your machine (consult your database administrator), you can specify it as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'DSN=DEFAULT'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some systems might require one login and password for the server, and another login and password for the DBMS. In this case, both can be specified as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'DSN=Automobile Data; UID=John;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;PWD=Lightning; UIDDBMS=JQR; PWDDBMS=Thunder'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can use the DRIVER attribute to specify explicitly which driver to use, instead of letting it be determined automatically by the data source type. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'DSN=Automobile Data; DRIVER=SQL Server'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of embedding a long data source connection text inside the [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() statement, you can define a variable in Analytica whose value is the appropriate text value. The name of this variable can then be provided as the argument to [http://wiki.analytica.com/index.php?title=DbQuery DBQuery](). Another alternative is to place the connection information in a file data source (a .DSN file). Such a file would consist of lines such as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DRIVER = SQL Server&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;UID = John&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;PWD = Lightning&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;DSN = Automobile Data&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Assuming this data is in a file named MyConnect.DSN, the connection text can be specified as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'FILEDSN=MyConnect.DSN'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In some applications, you might wish to connect directly to a driver rather than a registered data source. Some drivers allow this as a way to access a data file directly, even when it is not registered. Also, some drivers provide this as a way o f interrogating the driver itself. To perform such a connection, use the driver keyword. For example, if the Paradox driver accepts the directory of the data files as an argument, you can specify:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'DRIVER={Paradox Driver};DIRECTORY='D:\CARS'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The specific fields used here (UID, PWD, UIDDBMS, PWDDBMS, DIRECTORY, etc.) are interpreted by the ODBC driver, and therefore depend on the specific driver used. Any fields interpreted by your driver are allowed.&lt;br /&gt;
&lt;br /&gt;
If you do not wish to embed the full DSN in the connection text, a series of dialogs pop up when the [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() function is evaluated. For example, you can leave the UID and PWD (user name and password) out of your model. When the model is evaluated, Analytica prompts you to enter the required information. Explicitly placing information in your model eliminates the extra dialog. A blank connection text can even be used, in which case you need to choose among the data sources available on your machine when the model is being evaluated. Although the user can  form the DSN via the graphical interface at that point, the result is not automatically placed in the definitions of your Analytica model. However, you might be able to store the information in a DSN file (depending on which drivers and driver manager you are using). You might also be able to register data sources on your machine from that interface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt;In 64-bit Windows, ODBC drivers may be either 64-bit drivers or 32-bit drivers. When you are using Analytica 64-bit, you can only make use of 64-bit ODBC drivers. If you do not have a 64-bit driver for the database you are using installed on your computer, you will not be able to query that database from Analytica 64-bit. Likewise, the 32-bit editions of Analytica can only make use of 32-bit ODBC drivers, so the appropriate 32-bit driver must be installed on your computer.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that 64-bit versions of the Microsoft JET drivers do not exist. These drivers are installed with Microsoft Access and include the Access ODBC driver, the Excel ODBC driver, and the flat file ODBC driver. Microsoft apparently has no plans to release 64-bit versions of these drivers, and has indicated it wants to phase out the use of these drivers entirely. These drivers therefore cannot be utilized from Analytica 64-bit. Most other major database drivers are available in both 32- and 64-bit.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Configuring a DSN==&lt;br /&gt;
&lt;br /&gt;
To access a database using ODBC, you must have a Data Source Name (DSN) already configured on your machine. In general, configuring a DSN requires substantial database administration expertise as well as the appropriate access permissions on your computer and network. To configure a data source, you should consult with your Network Administrator or your database product documentation. The general task of configuring a DSN is beyond the scope of this manual.&lt;br /&gt;
&lt;br /&gt;
If you find you must configure a DSN yourself, the process usually involves the following steps (assuming your database already exists):&lt;br /&gt;
&lt;br /&gt;
# Select the ODBC icon from the Windows Control Panel.&lt;br /&gt;
# Select the User DSN, System DSN, or File DSN tab depending on your needs. Most likely, you will want System DSN. Click the '''Add''' button.&lt;br /&gt;
# Select the driver. For example, if your database is a Microsoft Access database, select the Microsoft Access Driver and click '''Finish'''.&lt;br /&gt;
# You are led through a series of dialogs specific to the driver you selected. These include dialogs that allow you to specify the location of your database, as well as the DSN name that you will use from your Analytica model. An example is shown here.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::[[File:db_access_2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
==Specifying an SQL query==&lt;br /&gt;
&lt;br /&gt;
You can use any SQL query as a text parameter within an Analytica database function. SQL queries can be very powerful, and can include multiple tables, joins, splits, filters, sorting, and so on.&lt;br /&gt;
&lt;br /&gt;
We give only a few simple examples here. If you are interested in more demanding applications, please consult one of the many excellent texts on SQL.&lt;br /&gt;
&lt;br /&gt;
The SQL expression to select a complete table in a relational database, where the table is named VEHICLES, would be:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'SELECT * FROM vehicles'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt;SQL is case insensitive, but Analytica is case sensitive for labels of Column names.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To select only two columns (make and model) from this same table and sort them by make:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'SELECT make, model FROM vehicles ORDER BY make'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These examples provide a starting point. When using multiple tables, one detail to be aware of is that it is possible in SQL to construct a result table with two columns containing the same label. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'SELECT * FROM vehicles, companies'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where both tables for vehicles and companies contain a column labeled '''Id'''. In this case, you can only access one (the first) of the two columns using [http://wiki.analytica.com/index.php?title=DbTable DBTable](). Thus, you should take care to ensure that duplicate column labels do not result. This can be accomplished, for example, using&lt;br /&gt;
the AS keyword, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'SELECT vehicles.Id AS vid, companies.Id AS cid, * FROM vehicles, companies'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For users that are unaccustomed to writing SQL statements, products exist that allow SQL statements to be constructed from a simple graphical user interface. Many databases allow queries to be defined and stored in the database. For example, from Microsoft Access, one can define a query by running Access and using the Query Wizard graphical user interface. The query is given a name and stored in the database. The name of the query can then be used where the name of a table would normally appear, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'SELECT * FROM myQuery'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Retrieving an SQL result table==&lt;br /&gt;
&lt;br /&gt;
To retrieve a result table from a data source, you need:&lt;br /&gt;
&lt;br /&gt;
# The data source connection text.&lt;br /&gt;
# The SQL query. These are discussed in the previous two sections. For illustrative purposes, suppose the connection text is &amp;lt;code&amp;gt;'DSN=Automobile Data'&amp;lt;/code&amp;gt;, and the SQL statement is&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'SELECT * FROM vehicles'. Obtain the relational Result_table&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Thus:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index Records := DBQuery('DSN=Automobile Data',&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;'SELECT * FROM vehicles')&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Index Labels := DBLabels(Records)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Result_table := DBTable(Records, Labels)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now display &amp;lt;code&amp;gt;Result_table&amp;lt;/code&amp;gt; to examine the results.&lt;br /&gt;
&lt;br /&gt;
This basic procedure can be repeated for any result table. The structure of the model stays the same, and just the connection text and SQL query text change.&lt;br /&gt;
&lt;br /&gt;
==Separating columns of a database table==&lt;br /&gt;
&lt;br /&gt;
It is often more convenient for further modeling to create a separate variable for each column of a database table. Each column variable uses the same record index. For example, we might create separate variables for &amp;lt;code&amp;gt;Make&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Year&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Car&amp;lt;/code&amp;gt; model from the vehicles database table.&lt;br /&gt;
&lt;br /&gt;
:[[File:db_access_3.png|200px]]&lt;br /&gt;
&lt;br /&gt;
In this case, the record index is still defined using [http://wiki.analytica.com/index.php?title=DbQuery DBQuery](), and each column is defined using [http://wiki.analytica.com/index.php?title=DbTable DBTable](). The actual SQL query is issued only once when the record index is evaluated. &lt;br /&gt;
&lt;br /&gt;
Suppose you wished to have &amp;lt;code&amp;gt;Make&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Model&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Year&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MPG&amp;lt;/code&amp;gt;, etc., as separate Analytica variables, each a one-dimensional array with a common index. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index Records := DBQuery('DSN=Automobile Data',&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;'SELECT * FROM vehicles')&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Make := DBTable(Records, 'make')&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Model_Year := DBTable(Records, 'year')&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Car_Model := DBTable(Records, 'model')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since &amp;lt;code&amp;gt;Model&amp;lt;/code&amp;gt; is a reserved word in Analytica, we named the variable &amp;lt;code&amp;gt;Car_Model&amp;lt;/code&amp;gt; instead of just &amp;lt;code&amp;gt;Model&amp;lt;/code&amp;gt;. But, the second parameter to [http://wiki.analytica.com/index.php?title=DbTable DBTable]() specifies the name of the column as stored in the database. This does not have to be the same as the name of the variable in Analytica.&lt;br /&gt;
Alternatively, you can construct a table containing a subset of the columns in a result table. For example, if vehicles has a large number of columns, you might create this variable with only the three columns you are interested in:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable SubCarTable:= DBTable(Records, ['make','model','year'])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This table is indexed by &amp;lt;code&amp;gt;Records&amp;lt;/code&amp;gt; and by an implicit index (a.k.a. a null index). The first argument to [http://wiki.analytica.com/index.php?title=DbTable DBTable]() must always be an indexed defined by [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() — remember the SQL query is defined in that node, and this is how [http://wiki.analytica.com/index.php?title=DbTable DBTable]() knows which table is being retrieved.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=DbWrite DBWrite](): Writing to a database==&lt;br /&gt;
&lt;br /&gt;
You can use SQL to change the contents of the external data source from within an Analytica model. Using the appropriate SQL statements, you can add or delete records from an existing database table. You can also add columns, and create or delete tables, if your data source driver supports these operations.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() cannot alter the data source, because it processes the SQL statement in read-only mode. Instead, use [http://wiki.analytica.com/index.php?title=DbWrite DBWrite](), which is identical to [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() except that it processes the SQL statement in read-write mode. [http://wiki.analytica.com/index.php?title=DbWrite DBWrite]() can make any change to the database that can be expressed as an SQL statement, and is supported by the ODBC driver.&lt;br /&gt;
&lt;br /&gt;
To send data from your model into the database, you must convert that data into a text value — more precisely, into an SQL statement. Analytica offers some tools to help this process. Here, we illustrate a common case — writing a multi-dimensional array to a table in a database. We use the &amp;lt;code&amp;gt;ODBC_Library.ana&amp;lt;/code&amp;gt; library distributed with Analytica.&lt;br /&gt;
&lt;br /&gt;
Suppose you want to write the value of variable &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, which is a three dimensional array indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;K&amp;lt;/code&amp;gt;, into a relational table named &amp;lt;code&amp;gt;TableA&amp;lt;/code&amp;gt;, so that other applications can use the data.&lt;br /&gt;
&lt;br /&gt;
First, we need to convert the 3D array into the correct relational table form. Then we convert the table into the SQL text to write to the database.&lt;br /&gt;
&lt;br /&gt;
Our approach is to first convert the three-dimensional array A into a two dimensional table, which we store into &amp;lt;code&amp;gt;TableA&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;TableA&amp;lt;/code&amp;gt; needs the two indexes &amp;lt;code&amp;gt;ARowIndex&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ALabelIndex&amp;lt;/code&amp;gt;. These three variables are defined as follows:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index ALabelIndex := Concat(IndexNames(A),['A'])&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Index ARowIndex := sequence(1, Size(A))&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable TableA := MDArrayToTable(A, ARowIndex, ALabelIndex)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[http://wiki.analytica.com/index.php?title=MdArrayToTable MDArrayToTable]&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;(a, row, col) &amp;lt;/code&amp;gt;'''(pure relational transformation)''' is described in [http://wiki.analytica.com/index.php?title=Relational_tables_and_multiD_arrays#MDArrayToTable.28a.2C_row.2C_col.29_.28pure_relational_transformation.29 MDArrayToTable(a, row, col) (pure relational transformation)]. &amp;lt;code&amp;gt;ALabelIndex&amp;lt;/code&amp;gt; evaluates to [&amp;lt;code&amp;gt;'I','J','K','A'&amp;lt;/code&amp;gt;], and &amp;lt;code&amp;gt;ARowIndex&amp;lt;/code&amp;gt; sets aside one row for each element of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;TableA&amp;lt;/code&amp;gt; is then a table with one row for each element of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, where the value of each index for that element is listed in the corresponding column, and the value of that element appears in the final column.&lt;br /&gt;
&lt;br /&gt;
Next, set up &amp;lt;code&amp;gt;TableA&amp;lt;/code&amp;gt; in the database with the same columns. This is most easily done using the front end provided with your database. For example, if you are using MS Access, start the MS Access program, and from there, create a new table. Alternatively, you could issue the statement:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DBWrite(DB,'CREATE TABLE TableA(I &amp;lt;text&amp;gt;, J &amp;lt;text&amp;gt;, K &amp;lt;text&amp;gt;, A &amp;lt;text&amp;gt;)')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
from an Analytica expression (replacing &amp;lt;code&amp;gt;&amp;lt;text&amp;gt;&amp;lt;/code&amp;gt; with whatever type is appropriate for your application). Be sure that the column labels in the database table have the same names as the labels of &amp;lt;code&amp;gt;ALabelIndex&amp;lt;/code&amp;gt; in the Analytica model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt; If you want to use column labels in the database that are different from the Analytica index names, define &amp;lt;code&amp;gt;ALabelIndex&amp;lt;/code&amp;gt; to be a 1D array, self indexed. Set the domain of &amp;lt;code&amp;gt;ALabelIndex&amp;lt;/code&amp;gt; to be the database labels, and the values of the array to the index names. (The last value is arbitrary.)&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our data is now in the form of a 2D table as needed for a database table. Next we construct the SQL text to write the table to the database. You must choose whether you want to append rows to the existing database table, or replace the table entirely. Or you can replace only selected entries. Your choice affects how you construct the SQL statement. Here, we totally replace any existing data with the new data, so after the operation, the database table is exactly the same as &amp;lt;code&amp;gt;TableA&amp;lt;/code&amp;gt; in the Analytica model. The SQL statements for performing the write is:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;DELETE * FROM TableA&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;INSERT INTO TableA(I, J, K, A) VALUES ('i1','j1','k1','a111')&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;INSERT INTO TableA(I, J, K, A) VALUES ('i1','j1','k2','a112')&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first statement removes existing data, since we are replacing it. We follow this by one &amp;lt;code&amp;gt;INSERT INTO&amp;lt;/code&amp;gt; statement for each row of &amp;lt;code&amp;gt;TableA&amp;lt;/code&amp;gt;. The data to the right of the VALUES keyword is replaced by the specific values for indexes &amp;lt;code&amp;gt;I, J, K&amp;lt;/code&amp;gt;, and array &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; (the example above assumes the values are all text values). If your values are numeric, you should note that MSAccess adds quotes around them automatically.&lt;br /&gt;
&lt;br /&gt;
Since writing the table requires a series of SQL statements, we have two options: Evaluate a series of [http://wiki.analytica.com/index.php?title=DbWrite DBWrite]() functions, or lump the series of SQL statements into one long text value and issue one [http://wiki.analytica.com/index.php?title=DbWrite DBWrite]() statement. In Analytica, the second option is much more efficient for two reasons. First, the overhead of connecting with the database occurs only one time. Second, intermediate result tables do not have to be read from the ODBC driver, while if you issued separate [http://wiki.analytica.com/index.php?title=DbWrite DBWrite]() statements, each one would go through the effort of acquiring the result table, only to be ignored.&lt;br /&gt;
&lt;br /&gt;
== Important feature (double semicolon) ==&lt;br /&gt;
&lt;br /&gt;
To allow multiple SQL statements in a single [http://wiki.analytica.com/index.php?title=DbWrite DBWrite]() function (or in a single [http://wiki.analytica.com/index.php?title=DbQuery DBQuery]() function), Analytica provides an extension to the SQL language. The double semicolon separates multiple statements. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;'DELETE * FROM TableA ;; SELECT * FROM TableA'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This first deletes the data from the table, and then reads the (now empty) table. When ;; is used, only the last SQL statement in the series returns a result table. Most statements that write to a database return an empty result table.&lt;br /&gt;
&lt;br /&gt;
We are now ready to write the Analytica expression that constructs the SQL statement to write the table to the database. The function to do this already exists in the ODBC_Library. First, use the '''Add Module''' item on the '''File''' menu to insert the ODBC_Library into your model; then use the [http://wiki.analytica.com/index.php?title=WriteTableSql WriteTableSql]() function, which returns the SQL statement (as a text value) for writing the table to the database. The function requires that I and L contain no duplicates (which should be the case anyway).&lt;br /&gt;
&lt;br /&gt;
Finally, define:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Write_A_to_DB := DBWrite(DB, WriteTableSql(A, RowIndex,LabelIndex,'TableA'))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating an output node to write to a database ==&lt;br /&gt;
&amp;lt;code&amp;gt;Write_A_to_DB&amp;lt;/code&amp;gt; writes array &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; to the database whenever it is evaluated. But, this happens when the model user causes &amp;lt;code&amp;gt;Write_A_to_DB&amp;lt;/code&amp;gt; to be evaluated, not necessarily whenever &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; changes. To make it easy for the end user to perform the write, we suggest you make an output node for &amp;lt;code&amp;gt;WriteAtoDB&amp;lt;/code&amp;gt;:&lt;br /&gt;
# Select node &amp;lt;code&amp;gt;Write_A_to_DB&amp;lt;/code&amp;gt; in its diagram.&lt;br /&gt;
# Select the '''Make Output Node''' command on the '''Edit''' menu.&lt;br /&gt;
# Move the new output node to a convenient place in the user interface of the model.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initially, the output node shows the '''Calc''' button. When you click it, it writes A to the database. It also displays the result of evaluating [http://wiki.analytica.com/index.php?title=DbWrite DBWrite](), usually an empty window, not very interesting to the user. To avoid this, append “&amp;lt;code&amp;gt;; 'Done&amp;lt;/code&amp;gt;' ” to its definition:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Write_A_to_DB := DBWrite(DB, WriteTableSql(A, RowIndex, LabelIndex,'TableA'); 'Done'&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, when you or an end user of the model, clicks &amp;lt;code&amp;gt;Write_A_to_DB&amp;lt;/code&amp;gt;, after writing &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; to the database, it shows '&amp;lt;code&amp;gt;Done&amp;lt;/code&amp;gt;' in the output node. It reverts to the '''Calc''' button, whenever &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; changes.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Category%3ADatabase_Functions Database Functions]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Analytica Enterprise / {{PAGENAME}} / Database functions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Analytica_Enterprise&amp;diff=38831</id>
		<title>Analytica Enterprise</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Analytica_Enterprise&amp;diff=38831"/>
		<updated>2015-12-29T03:48:32Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt;Analytica User Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need either Analytica Enterprise or [http://wiki.analytica.com/index.php?title=Analytica_Optimizer_Guide Analytica Optimizer] to create models using the features described in this section. You can use the Analytica Power Player or the [http://wiki.analytica.com/index.php?title=ADE_User_Guide Analytica Decision Engine] to run models created with Enterprise or Optimizer with these features, and can change them using [http://wiki.analytica.com/index.php?title=ADE_User_Guide Analytica Decision Engine]. You can use any edition of Analytica to run a model that uses buttons, or was saved as browse-only with hidden definitions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Analytica Enterprise &amp;lt;/strong&amp;gt;offers all the functionality of Analytica Professional, plus your model can read from and write to Excel spreadsheets and databases, use Huge Arrays (up to 100 million elements per Index dimension), apply the Profiler to see computational effort by variable, create Browse-only models, and encrypt confidential model elements. You can order Analytica Enterprise [http://www.lumina.com/shoppingcart/productorder/ here].&lt;br /&gt;
&lt;br /&gt;
==Sections==&lt;br /&gt;
* [[Database access]]&lt;br /&gt;
* [[Database functions]]&lt;br /&gt;
* [[Read and write text files]]&lt;br /&gt;
* [[Read data from URL on internet]]&lt;br /&gt;
* [[Making a browse-only model and hiding definitions]]&lt;br /&gt;
* [[Huge Arrays]]&lt;br /&gt;
* [[Performance Profiler library]]&lt;br /&gt;
* [[RunConsoleProcess - call other applications]]&lt;br /&gt;
* [[COM Automation Objects]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Procedural Programming / {{PAGENAME}} / Appendices&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Other_Procedural_Functions&amp;diff=38830</id>
		<title>Other Procedural Functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Other_Procedural_Functions&amp;diff=38830"/>
		<updated>2015-12-29T03:47:31Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=CurrentDataFolder CurrentDataFolder](''folderPath'')==&lt;br /&gt;
&lt;br /&gt;
Sets the current data folder to '''folderPath'''. The '''''current data folder''''' is the folder used by functions that read data files such as [http://wiki.analytica.com/index.php?title=ReadTextFile ReadTextFile](), [http://wiki.analytica.com/index.php?title=WriteTextFile WriteTextFile](), and [http://wiki.analytica.com/index.php?title=SpreadsheetOpen SpreadsheetOpen]() when their filename parameter contains no other path. When starting a model, it is the current model folder that contains the model. Specifying a path as a parameter to the function changes the current data folder to that path. If '''folderPath''' is omitted, it returns the path to the current data folder.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=CurrentModelFolder CurrentModelFolder](folderPath)==&lt;br /&gt;
&lt;br /&gt;
Sets the current model folder to '''folderPath'''. The '''''current model folder''''' is the folder into which the model (and submodules) are saved, by default. When starting a model, it is the folder containing the model. You can change it by selecting a different folder directly using the folder browser from '''Save as''', or by using this function. If '''folderPath''' is omitted, it returns the path to the current model folder.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=Evaluate Evaluate](e)==&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; is a text value, [http://wiki.analytica.com/index.php?title=Evaluate Evaluate](e) tries to parse &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; as an Analytica expression, evaluates it, and returns its value. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Evaluate('10M /10') → 1M&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One use for Evaluate(e) is to convert a number formatted as text into a number it can compute with, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Evaluate('1.23456e+10') → 12.3456G&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; is an expression that generates a text value, it evaluates the expression, and then parses and evaluates the resulting text value. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;(VAR x := 10; Evaluate(x &amp;amp; &amp;quot;+&amp;quot; &amp;amp; x)) → 20&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; is a number or expression that is not a text value, it just returns its value:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Evaluate(10M /10) → 1M&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; is a text value that is not a valid expression — for example, if it has a syntax error — it returns &amp;lt;code&amp;gt;Null&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Like other functions, it evaluates the parameter as mid (deterministic) or prob (probabilistic), according to the context in which it is called.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=Evaluate Evaluate](e) parses and evaluates text &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; in a global context. Thus, &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; cannot refer to local variables, local indexes, or function parameters defined in the definition that uses [http://wiki.analytica.com/index.php?title=Evaluate Evaluate](e). For example, this would give an evaluation error:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable A := (VAR r := 99; Evaluate('r^2') )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; evaluates to a handle before it is passed to the function, then that object is evaluated and its (mid or sample) value is returned.&lt;br /&gt;
&lt;br /&gt;
===[http://wiki.analytica.com/index.php?title=Evaluate Evaluate] and dependencies===&lt;br /&gt;
&lt;br /&gt;
Analytica’s dependency mechanism does not work with variables or functions whose identifiers appear inside the text parameter of [http://wiki.analytica.com/index.php?title=Evaluate Evaluate](). For example, consider:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable B := Evaluate(&amp;quot;F(A)&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable C := F(A)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Initially &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;C&amp;lt;/code&amp;gt; compute the same value. If you then change the definition of function &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt; or variable &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, Analytica’s dependency maintenance ensures that &amp;lt;code&amp;gt;C&amp;lt;/code&amp;gt; is recomputed when needed using the new definition of &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;. But, &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt; does not know it depends on &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;, so is not recomputed, and can become inconsistent with the new values for &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;. In rare cases, you might intentionally want to break the dependency, in which case [http://wiki.analytica.com/index.php?title=Evaluate Evaluate]() is appropriate; otherwise, use it only with care.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=EvaluateScript EvaluateScript](t)==&lt;br /&gt;
&lt;br /&gt;
This function evaluates a text value &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt; as if it was typescript. This can provide access to typescript commands that aren’t available in expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip &amp;quot;&amp;gt;Avoid using [[EvaluateScript]](t) except from event attributes (&amp;lt;code&amp;gt;OnClick&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OnChange&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Script&amp;lt;/code&amp;gt;), or functions called from event attributes. This minimizes the danger of undermining the no-side effects rule.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=GetProcessInfo GetProcessInfo](item)==&lt;br /&gt;
&lt;br /&gt;
Returns information about the current Analytica process from the Windows operating system. There are a large number of recognized values for '''item''', and for a complete list see [http://wiki.analytica.com/index.php?title=GetProcessInfo GetProcess-Info]. Some of the possible values for item are: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;quot;Process ID&amp;quot;, &amp;quot;Thread ID&amp;quot;, &amp;quot;Computer Name&amp;quot;, &amp;quot;User Name&amp;quot;, &amp;quot;Windows Version&amp;quot;, &amp;quot;Command Line&amp;quot;, &amp;quot;Total RAM&amp;quot;, &amp;quot;Total Virtual&amp;quot;, &amp;quot;Free RAM&amp;quot;, &amp;quot;Private Bytes&amp;quot;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;GetProcessInfo(&amp;quot;User Name&amp;quot;) → &amp;quot;Drice&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also access the value of an environment variable as &amp;quot;''item:name''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;GetProcessInfo(&amp;quot;HOMEPATH”) → &amp;quot;\Users\Drice&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A few options provide information about Analytica’s state: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;quot;User Objects&amp;quot;, &amp;quot;Total Objects&amp;quot;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;GetProcessInfo(&amp;quot;User Objects&amp;quot;) → 76&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=GetRegistryValue GetRegistryValue](root, subfolder, name)==&lt;br /&gt;
&lt;br /&gt;
Reads a value from the Windows system registry. This can be quite useful if you install your Analytica model as part of a larger application, and if your model needs to find certain data files on the user’s computer (for example, for use with [http://wiki.analytica.com/index.php?title=ShowPdfFile ShowPdfFile], [http://wiki.analytica.com/index.php?title=ReadTextFile ReadTextFile], or [http://wiki.analytica.com/index.php?title=RunConsoleProcess RunConsoleProcess]). The locations of those files could be stored in the registry by your installer, so that your model knows where to look.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GetRegistryValue(&amp;quot;HKEY_CURRENT_USER&amp;quot;, &amp;quot;Software/MyCompany/MyProduct&amp;quot;, &amp;quot;FileLocation&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=IgnoreWarnings IgnoreWarnings](expr)==&lt;br /&gt;
&lt;br /&gt;
Evaluates its parameter &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;, and returns its value, while suppressing most '''[[warnings]]''' that might otherwise be displayed during the evaluation. It is useful when you want to evaluate an expression that generates warnings, such as divide by zero, that you know are not important in that context, but you do not want to uncheck the option ''Show Result Warnings'' in the [http://wiki.analytica.com/index.php?title=Preferences_dialog Preferences dialog], because you do want to see warnings that might appear in other parts of the model.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=IsResultComputed IsResultComputed](x)==&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the value of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is computed when the function is evaluated. To test whether the sample value of x has been computed, use [http://wiki.analytica.com/index.php?title=Sample Sample](IsResultComputed(x)), or to test the mid value use [http://wiki.analytica.com/index.php?title=Mid Mid](IsResultComputed(x)).&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=OpenURL OpenURL](url)==&lt;br /&gt;
&lt;br /&gt;
Opens '''url''' in a browser window, using your default browser.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=ShowPdfFile ShowPdfFile](filename)==&lt;br /&gt;
&lt;br /&gt;
Opens '''filename''' using Adobe Reader or Acrobat if one is installed on this computer and the file is a PDF document. [http://wiki.analytica.com/index.php?title=ShowPdfFile ShowPdfFile] is most useful when called from a button script, for example, as a way to provide the user of your model with a way to open a user guide for your model.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=Try Try]( expr, catch, ''errorNum'')==&lt;br /&gt;
&lt;br /&gt;
Attempts to evaluate and return the result for &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;. If an evaluation error occurs directly in &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;, or in a User-Defined Function (UDF) called from &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;catch&amp;lt;/code&amp;gt; is evaluated without reporting the error.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Try( COMCreateObject(&amp;quot;MSXML&amp;quot;), catch: Null )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside the &amp;lt;code&amp;gt;catch&amp;lt;/code&amp;gt; expression, you can refer to local variables named &amp;lt;code&amp;gt;ErrorText&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ErrorNumber&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ErrorLocation&amp;lt;/code&amp;gt;, containing information about the error. &amp;lt;code&amp;gt;ErrorLocation&amp;lt;/code&amp;gt; contains a handle to the object where the error occurred. You can re-issue the error from within the catch expression by calling [http://wiki.analytica.com/index.php?title=ReThrow ReThrow](). In some cases, you might want to change the error text to your own by calling [http://wiki.analytica.com/index.php?title=Error Error]().&lt;br /&gt;
&lt;br /&gt;
You may optionally specify specific error numbers to catch using the '''errorNum''' parameter:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Try( COMCreateObject(&amp;quot;MSXML&amp;quot;),&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;errorNum: 42770, 43033, 43034,&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;catch: Error(&amp;quot;You don’t have MSXML installed&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the error number for the '''errorNum''' parameter, set your catch expression to [http://wiki.analytica.com/index.php?title=MsgBox MsgBox](ErrorNumber) and cause the error to occur. Once you have the number or numbers, reset your '''catch''' expression as you would like it.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=Try Try]() does not suppress or catch warnings. For that, use [http://wiki.analytica.com/index.php?title=IgnoreWarnings IgnoreWarnings]().&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=CurrentDataFolder CurrentDataFolder]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=CurrentModelFolder CurrentModelFolder]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Evaluate Evaluate]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=EvaluateScript EvaluateScript]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Category%3AFunctions Functions]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=GetProcessInfo GetProcessInfo]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=GetRegistryValue GetRegistryValue]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=IgnoreWarnings IgnoreWarnings]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=IsResultComputed IsResultComputed]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=OpenURL OpenURL]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=ShowPdfFile ShowPdfFile]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Try Try]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Dialog Functions / {{PAGENAME}} / Analytica Enterprise&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Dialog_Functions&amp;diff=38829</id>
		<title>Dialog Functions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Dialog_Functions&amp;diff=38829"/>
		<updated>2015-12-29T03:46:08Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dialog functions display dialog boxes to give special information, warnings, or error messages, or to request information from the user. Dialogs are '''''modal''''' — meaning that Analytica pauses evaluation while showing the dialog until the user closes the dialog ('''ShowProgressBar''' is an exception in that it continues evaluation while it displays the progress bar). If the user clicks the '''Cancel''' button, it stops further evaluation — as if the user pressed ''Control+.'' ('''Control+period''').&lt;br /&gt;
&lt;br /&gt;
Dialog functions display their dialog when evaluated. If the definition of a variable &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; calls a dialog function, it will display the dialog when it evaluates &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;. If it evaluates &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; in mid and prob mode, it displays the dialog each time. It does not display the dialog again until it evaluates &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; again — for example, because one of its inputs changes.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=MsgBox MsgBox](message, ''buttons, title'')==&lt;br /&gt;
&lt;br /&gt;
Displays a dialog with the text '''message''', a set of '''buttons''' and an icon (according to numerical codes below), with '''title''' in the dialog header bar. Analytica pauses until the user clicks a button. If the user clicks the '''Cancel''' button, it stops evaluation. Otherwise it returns a number, depending on which button the user presses (see below).&lt;br /&gt;
&lt;br /&gt;
The optional buttons parameter is a number that controls which buttons to display, as follows:&lt;br /&gt;
&lt;br /&gt;
:0 = OK only&lt;br /&gt;
:1 = OK and Cancel (the default if the '''buttons''' parameter is omitted)&lt;br /&gt;
:2 = Abort, Retry, and Ignore&lt;br /&gt;
:3 = Yes, No, and Cancel&lt;br /&gt;
:4 = Yes and No&lt;br /&gt;
:5 = Retry and Cancel&lt;br /&gt;
&lt;br /&gt;
To display an icon in the dialog, add one of these numbers to the '''buttons''' parameter:&lt;br /&gt;
&lt;br /&gt;
:16 = Critical (white X on red circle)&lt;br /&gt;
:32 = Question&lt;br /&gt;
:48 = Exclamation&lt;br /&gt;
:64 = Information&lt;br /&gt;
&lt;br /&gt;
'''[http://wiki.analytica.com/index.php?title=MsgBox MsgBox]''' returns a number depending on which button the user presses:&lt;br /&gt;
&lt;br /&gt;
:1 = OK&lt;br /&gt;
:2 = Cancel (stops any further evaluation)&lt;br /&gt;
:3 = Abort&lt;br /&gt;
:4 = Retry&lt;br /&gt;
:5 = Ignore&lt;br /&gt;
:6 = Yes&lt;br /&gt;
:7 = No&lt;br /&gt;
&lt;br /&gt;
Here are some examples.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Msgbox('OK, I''m done now.', 0+64,'Information') →''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::[[File:msgbox1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Msgbox('Uh uh! Looks like trouble!', 5+16, 'Disaster') →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::[[File:msgbox2.png|200px]]&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Msgbox('Do you really mean that?', 3+32, 'Critical question') →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::[[File:msgbox3.png|250px]]&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Msgbox('This could be a real problem!', 2+48, 'Critical question') →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::[[File:msgbox4.png|250px]]&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=Error Error](message)==&lt;br /&gt;
&lt;br /&gt;
Displays an evaluation error in a dialog mentioning the variable whose definition calls this function, showing the '''message''' text:&lt;br /&gt;
&lt;br /&gt;
::Variable Xyz := Error('There seems to be some kind of problem') &lt;br /&gt;
::Xyz →&lt;br /&gt;
&lt;br /&gt;
:::[[File:msgbox5.png|300px]]&lt;br /&gt;
&lt;br /&gt;
If you click '''Yes''', it opens the definition of the variable or function whose definition (or Check attribute) calls [http://wiki.analytica.com/index.php?title=Error Error]() in edit mode (if the model is editable). If you click '''No''' or '''Cancel''', it stops evaluation.&lt;br /&gt;
&lt;br /&gt;
===Error in check===&lt;br /&gt;
&lt;br /&gt;
If you call [http://wiki.analytica.com/index.php?title=Error Error]() in a [http://wiki.analytica.com/index.php?title=Check_Attribute check attribute], it shows the error message when the check fails ''instead'' of the default check error message, letting you tailor the message.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=AskMsgChoice AskMsgChoice](question, ''title, optionList, default, showAll, comboBox'')==&lt;br /&gt;
&lt;br /&gt;
Opens a dialog displaying '''question''' text with a choice drop down control where the user can select an answer from a list. The '''optionList''' parameter is a list or 1-D array of selections, and '''default''' is initial selection. The selected item is returned as the result.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;showAll&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, then an «All» option is also included, and if selected then the entire '''optionList''' is returned. When '''comboBox''' is specified as &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, then a combo box control is displayed rather than a choice list. In a combo box, the user is free to enter his own text, but the '''optionList''' provides suggestions.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;AskMsgChoice(&amp;quot;Please rate&amp;quot;,&amp;quot;Survey&amp;quot;,[&amp;quot;Loved&amp;quot;,&amp;quot;Liked&amp;quot;, &amp;quot;Neutral&amp;quot;, &amp;quot;Disliked&amp;quot;, &amp;quot;Hated&amp;quot;])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=AskMsgNumber AskMsgNumber](question, ''title, default'')==&lt;br /&gt;
&lt;br /&gt;
Displays a dialog showing '''question''' with '''title''', if given. It shows a field for user to enter a number, containing '''default''' number if given. When the user enters a number into the dialog, and clicks '''OK''', it returns the number.&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=AskMsgText AskMsgText](question, ''title, maxText, default, password'')==&lt;br /&gt;
&lt;br /&gt;
Opens a dialog displaying '''question''' text with a field for the user to provide an answer, which it returns as text.&lt;br /&gt;
&lt;br /&gt;
If you specify '''title''' text it displays that in the title bar of the dialog. If you specify '''maxText''' as a number, it will accept only that many characters. If you specify '''default text''', it displays that as the default answer. If you set '''password''' to true, the characters typed are hidden as they are typed.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;AskMsgText(&amp;quot;Enter your model access key&amp;quot;, title: &amp;quot;License Entry&amp;quot;, maxText: 15)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[http://wiki.analytica.com/index.php?title=ShowProgressBar ShowProgressBar](title, text, p)==&lt;br /&gt;
&lt;br /&gt;
Displays a dialog with the '''title''' in title bar, a '''text''' message and a progress bar showing fraction &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; of progress along the bar. The dialog appears the first time you call it with &amp;lt;code&amp;gt;p&amp;lt;1&amp;lt;/code&amp;gt;. As long as &amp;lt;code&amp;gt;0&amp;lt;=p&amp;lt;1&amp;lt;/code&amp;gt;, it shows a '''Cancel''' button, and continues evaluation. If you click '''Cancel''', it stops further computation, as if the user had pressed ''Control+.'' ('''Control+period'''). If &amp;lt;code&amp;gt;p=1&amp;lt;/code&amp;gt;, it shows the '''OK''' button and stops further computation. If you click '''OK''', it closes the dialog. The dialog also closes if called with &amp;lt;code&amp;gt;p&amp;gt;1&amp;lt;/code&amp;gt; or when the computation completes.&lt;br /&gt;
&lt;br /&gt;
:::[[File:msgbox6.png|250px]]&lt;br /&gt;
&lt;br /&gt;
===Declaration===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[http://wiki.analytica.com/index.php?title=ShowProgressBar ShowProgressBar](title, text: Text atomic; p: number atomic)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
In this example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;VAR xOrig := X;&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;VAR result :=&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;FOR n[] := @Scenario DO (&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;ShowProgressBar(&amp;quot;Progress&amp;quot;, &amp;quot;Computing Across All Scenarios&amp;quot;, (n-1)/Size(Scenario)); &amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;WhatIf(Y, X, xOrig[@Scenario=n]))&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;ShowProgressBar(&amp;quot;Progress&amp;quot;, &amp;quot;Done&amp;quot;, 1);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Category%3AUser-interface_functions User Interface Functions]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Handles to Objects / {{PAGENAME}} / Other Procedural Functions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Handles_to_Objects&amp;diff=38827</id>
		<title>Handles to Objects</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Handles_to_Objects&amp;diff=38827"/>
		<updated>2015-12-29T03:43:21Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A handle is a pointer to a variable, function, module, or other object. Using a handle lets you write variables or functions that work with the object itself, for example to access its attributes — instead of just its value which is what you usually get when you mention a variable by identifier in an expression.&lt;br /&gt;
&lt;br /&gt;
===Viewing handles===&lt;br /&gt;
In a table result, a handle in an index or content cell usually shows the title of the object. If you select '''Show by identifier''' from the '''Object''' menu (or press ''Control+y''), it toggles to show identifiers instead of titles (as it does in the node diagrams). If you double-click a cell containing a handle (title or identifier) it opens its '''Object''' window (as it does when you double-click a node in a diagram). &lt;br /&gt;
&lt;br /&gt;
===Attributes that contain handles===&lt;br /&gt;
The attributes, '''inputs''', '''outputs''', and '''contains''' (the list of objects in a module) each consist of a list of handles to objects. The attribute isIn is a single handle to the module that contains this object — the inverse of '''contains'''.&lt;br /&gt;
&lt;br /&gt;
==List of variables: [v1, v2, ... vn]==&lt;br /&gt;
If you define a variable as a list of variables, for example,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable A := [X, Y, Z]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the variable will have a self index that is a list of handles to those variables. In a table result view of A (or other variable that uses this index), the index A will usually show the titles of the variables. See “List of variables” on page 175 for more. In an expression, the handles in the self index can be accessed using IndexValue(A). The main value of A (either mid value or a probabilistic view of A) contains the results of evaluating X, Y and Z.&lt;br /&gt;
&lt;br /&gt;
== Handle(o) ==&lt;br /&gt;
Returns a handle to an Analytica object, given its identifier &amp;lt;code&amp;gt;o&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Handle(Va1) ¨ Va1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== HandleFromIdentifier(text) ==&lt;br /&gt;
Returns a handle to global object (i.e., not a local variable or parameter), given its identifier as &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable B := 99&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;HandleFromIdentifier(&amp;quot;B&amp;quot;) → Va1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The dependency maintenance is unaware of the dependency on the object. Hence, any changes to the variable &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt; above will not cause the result to recompute.&lt;br /&gt;
&lt;br /&gt;
== ListOfHandles(identifiers...) ==&lt;br /&gt;
Returns a list of handles to the specified Analytica objects, given their identifiers.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;ListOfHandles(Va1,Va2,Va3) ¨ [Va1,Va2,Va3]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Indexes of Handles ==&lt;br /&gt;
&lt;br /&gt;
=== MetaOnly attribute ===&lt;br /&gt;
When an index object is defined as a list of identifiers, the MetaOnly attribute controls whether it is treated as a general index or a meta-index. Meta-indexes are useful when reasoning about the structure or contents of the model itself. A general index evaluates the variables appearing in&lt;br /&gt;
its definition to obtain its mid or sample value, and the values that are recognized by Subscript (i.e., a[i=x]), while a meta-index (having its metaOnly attribute set to 1) does not evaluate the objects in the list. The following comparisons demonstrates the similarities and differences.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Constant E:= exp(1)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable X := -1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot;;&lt;br /&gt;
! General Index&lt;br /&gt;
! Meta-Index&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:300px;&amp;quot; | Index I0 := [E,X,Pi,True]&lt;br /&gt;
| style=&amp;quot;width:300px;&amp;quot; | Index I1 := [E,X,Pi,True]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; | MetaOnly of I0 := 0 {or not set}&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; | MetaOnly of I1 := 1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; | Variable A0 := Table(I0)(1,2,3,4)&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; | Variable A1 := Table(I1)(1,2,3,4)&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; | IndexValue(I0) → [E,X,Pi,True]&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |IndexValue(I1) → [E,X,Pi,True]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |Mid(I0) → 2.718,-1,3.142,1]&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |Mid(I1) →[E,X,Pi,True]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |A0[I0=Handle(E)] → 1&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot;|A1[I1=Handle(E)] → 1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |A0[I0=Handle(True)] → 4&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |A1[I1=Handle(True)] → 4&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |A0[I0=E] → 1&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |A1[I1=E] → Error:-2.718 not in I1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |A0[I0=-1] → 2&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |A1[I1=-1] → Error:-1 not in I1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |A0[I0=True] → 4&lt;br /&gt;
|style=&amp;quot;width:300px;&amp;quot; |A1[I1=True] → Error:1 not in I1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MetaIndex..Do ==&lt;br /&gt;
The construct, &amp;lt;code&amp;gt;MetaIndex i := indexExpr&amp;lt;/code&amp;gt;, declares a local meta-index (see [http://wiki.analytica.com/index.php?title=Local_Indexes Local indexes]). This should generally be used in lieu of the Index &amp;lt;code&amp;gt;i := indexExpr&amp;lt;/code&amp;gt; construct when &amp;lt;code&amp;gt;indexExpr&amp;lt;/code&amp;gt; evaluates to a list of handles.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MetaIndex I := contains of Revenue_Module;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Description of (I)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IndexesOf(X) ==&lt;br /&gt;
Returns the indexes of an array value as a list of handles. The first element of the list is null, rather than a handle, when &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; has an '''''implicit dimension''''' (also known as a '''''null-index''''').&lt;br /&gt;
&lt;br /&gt;
== Local Variables and Handles ==&lt;br /&gt;
When you declare and use local variables that might hold handles, you should declare these local variables using &amp;lt;code&amp;gt;MetaVar..Do or LocalAlias..Do&amp;lt;/code&amp;gt;, rather than &amp;lt;code&amp;gt;Var..Do or For..Do&amp;lt;/code&amp;gt;. When local variables hold handles, there are two semantic interpretations — the local variable could either be a storage location for a handle to an object, or it could act as an alias to the object. The &amp;lt;code&amp;gt;Meta-Var..Do&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;LocalAlias..Do&amp;lt;/code&amp;gt; declarations makes this distinction clear.&lt;br /&gt;
&lt;br /&gt;
== MetaVar..Do ==&lt;br /&gt;
The construct, &amp;lt;code&amp;gt;MetaVar temp := expr&amp;lt;/code&amp;gt;, declares a local variable named &amp;lt;code&amp;gt;temp&amp;lt;/code&amp;gt; that holds an atomic value or an array of values, some of which might be handles. When the value is a handle, the handle is treated as just another entity, whose datatype happens to be a handle. If you assign another handle or value to temp, you simply change the contents of the local variable, and do not alter the object that the handle points to. Use this construct to manage collections of handles.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MetaVar hRevModule := Handle(Revenue_module);&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;MetaVar hExpModule := Handle(Expense_module);&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;MetaIndex m := [hRevModule,hExpModule];&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the next example, suppose a global variable named &amp;lt;code&amp;gt;Hy&amp;lt;/code&amp;gt; exists with a definition of &amp;lt;code&amp;gt;Handle(Y)&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MetaVar a := Handle(X);&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;a := Hy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the assignment, the local variable &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; contains a handle to &amp;lt;code&amp;gt;Y&amp;lt;/code&amp;gt;. The variable &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; is unaltered. You should compare this to the same example using &amp;lt;code&amp;gt;LocalAlias..Do&amp;lt;/code&amp;gt; in the following section.&lt;br /&gt;
&lt;br /&gt;
When you need to iterate over a collection of handles, you can use, e.g.,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MetaVar h[ ] := Contains of Revenue_module;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can assign non-handle values, such as numbers or text, to a local variable declared with &amp;lt;code&amp;gt;MetaVar&amp;lt;/code&amp;gt;. When you do so, there is no difference between &amp;lt;code&amp;gt;MetaVar..Do&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Var..Do&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== LocalAlias..Do ==&lt;br /&gt;
The construct, &amp;lt;code&amp;gt;LocalAlias temp := expr&amp;lt;/code&amp;gt;, evaluates &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; and declares a local variable named &amp;lt;code&amp;gt;temp&amp;lt;/code&amp;gt; that holds a single atomic value. When &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; evaluates to a handle, the local variable identifier acts as an exact alias to the object pointed to by the handle.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;LocalAlias r := Handle(Rate_input) Do r := r * 1.1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The preceding expression is functionally identical to&amp;lt;ref&amp;gt;This expression contains a side-effect to a global variable. Side-effects to global variables are only allowed in expressions or user-defined functions that are run directly from button scripts. This would cause an error if attempted from a variable’s definition.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Rate_input := Rate_input * 1.1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the next example, suppose a global variable named &amp;lt;code&amp;gt;Hy&amp;lt;/code&amp;gt; exists with a definition of &amp;lt;code&amp;gt;Handle(Y)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;LocalAlias a := Handle(X)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;a := Hy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This expression is functionally identical to&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;X := Hy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The expression, if evaluated in a context where side-effects are permitted, would alter the definition of &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt;. Following the assignment to &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, the local variable &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; continues to be an alias to &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt;. You should compare this to the same example for &amp;lt;code&amp;gt;MetaVar..Do&amp;lt;/code&amp;gt; in the preceding section.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; is an array of handles, then the body expression is iterated for each alias. The following expression increases the definition of every global variable within an indicated module to a value 1.1 times its initial value.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;LocalAlias x := Contains of Input_module;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;x := x * 1.1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The rule for &amp;lt;code&amp;gt;LocalAlias&amp;lt;/code&amp;gt; is that the result for the expressions using &amp;lt;code&amp;gt;temp&amp;lt;/code&amp;gt; are identical to what you would get if you replaced every occurrence of &amp;lt;code&amp;gt;temp&amp;lt;/code&amp;gt; within those expressions with the identifier for the variable pointed to by the handle, and then evaluated the expressions&amp;lt;ref&amp;gt;Not every object in Analytica lives in the global namespace (e.g., local indexes), so this rule doesn’t literally apply for handles to objects not in the global namespace. For these, we cannot replace the local name with an identifier since no global identifier exists for the object pointed to by the handle.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An easy mistake to make when using &amp;lt;code&amp;gt;LocalAlias&amp;lt;/code&amp;gt; is to forget that &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; is evaluated before the assignment. This feature allows you to compute the handle to the object that will be aliased, but it also means that you need to remember to surround an identifier with a call to &amp;lt;code&amp;gt;Handle()&amp;lt;/code&amp;gt; when you&lt;br /&gt;
just want a simple alias. If you write&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;LocalAlias x := y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then this assigns to &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; the value of &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, not a handle to the object &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;. If &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; happens to hold a handle to &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; becomes an alias to &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt;, not an alias to &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;. To obtain an alias for &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, you must use &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;LocalAlias x := Handle(y);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can assign non-handle values, such as numbers and text, to a &amp;lt;code&amp;gt;LocalAlias&amp;lt;/code&amp;gt; variable. When you do so, the local variable identifier serves as an alias for a single value, and is the same as &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Var temp[] := expr;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conversions between MetaVar and LocalAlias ==&lt;br /&gt;
When writing expressions that manipulate handles in local variables, you may sometimes need to convert between &amp;lt;code&amp;gt;MetaVar&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;LocalAlias&amp;lt;/code&amp;gt; semantics. When a &amp;lt;code&amp;gt;MetaVar&amp;lt;/code&amp;gt; holds a handle, its value is an entity with the data type of handle. Since subtraction is not defined for a handle, the&lt;br /&gt;
following expression is an error&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MetaVar hr := Handle(Revenue) Do hr - Expenses { Error }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The expression is attempting to subtract the value of expenses (a number) from a handle. In this example, we need the &amp;lt;code&amp;gt;LocalAlias&amp;lt;/code&amp;gt; semantics instead, so given &amp;lt;code&amp;gt;hr&amp;lt;/code&amp;gt; we can convert using&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MetaVar hr := Handle(Revenue);&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;LocalAlias r := hr;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;r - Expenses&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;MetaVar&amp;lt;/code&amp;gt; can also be dereferenced by using the [http://wiki.analytica.com/index.php?title=Evaluate Evaluate]() function: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;MetaVar hr := Handle(Revenue) Do Evaluate(hr) - Expenses&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the other direction, when a &amp;lt;code&amp;gt;LocalAlias&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt;, is an alias for another object and you need the handle to the object, use &amp;lt;code&amp;gt;Handle(r)&amp;lt;/code&amp;gt;. It is legal to use the &amp;lt;code&amp;gt;Handle()&amp;lt;/code&amp;gt; function on a local variable declared using &amp;lt;code&amp;gt;LocalAlias&amp;lt;/code&amp;gt;, but it is an error to apply the &amp;lt;code&amp;gt;Handle()&amp;lt;/code&amp;gt; function to a local variable defined using &amp;lt;code&amp;gt;MetaVar&amp;lt;/code&amp;gt;. This is because a local variable is not an object (it is just a name for a value), and since handles can only point to objects, there is no such thing as a handle to a local variable&amp;lt;ref&amp;gt;A local index is an object, so you can have a handle to a local index. The '''Index..Do''' and '''MetaIndex..Do''' constructs create an index object, along with a local variable name that has '''LocalAlias''' semantics for the index object.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Handle_Functions Handle Functions]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Local_Indexes Local indexes]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;References and Data Structures / {{PAGENAME}} / Dialog Functions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=References_and_Data_Structures&amp;diff=38825</id>
		<title>References and Data Structures</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=References_and_Data_Structures&amp;diff=38825"/>
		<updated>2015-12-29T03:41:57Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A '''reference''' is an indirect link to a value, an atom or an array. A variable can contain a single reference to a value, or it can contain an array of references. Variables and arrays can themselves contain references, nested to any depth. This lets you create complex data structures, such as linked lists, trees, and non-rectangular structures. Use of references is provided by two operators:&lt;br /&gt;
&lt;br /&gt;
* '''\e''' is the '''''reference operation'''''. It creates a reference to the value of expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''#e''' is the '''''dereference operation'''''. It obtains the value referred to by e. If e is not a reference, it issues a warning and returns &amp;lt;code&amp;gt;Null&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
An example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable M&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: 100&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Ref_to_M&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: \ M&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of '''Ref_to_M''' looks like this:&lt;br /&gt;
&lt;br /&gt;
:::[[File:result_ref-to-m.png|300px]]&lt;br /&gt;
&lt;br /&gt;
You can double-click the cell containing «ref» to view the value referenced, in this case:&lt;br /&gt;
&lt;br /&gt;
:::[[File:result_ref-to-m2.png|300px]]&lt;br /&gt;
&lt;br /&gt;
You can also create an array of references. Suppose:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index K&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: 1..5&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Ksquare&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: K^2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Ksquare →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::[[File:result-ksquare.png|250px]]&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Ref_to_Ksquare&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: \ Ksquare&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Ref_to_Ksquare →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::[[File:result_ref_ksquare.png|250px]]&lt;br /&gt;
&lt;br /&gt;
If you click the «ref» cell, it opens:&lt;br /&gt;
&lt;br /&gt;
:::[[File:result_ref_ksquare2.png|250px]]&lt;br /&gt;
&lt;br /&gt;
You can also create an array of references from an array, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Ref_Ksquare_array&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: \ [] Ksquare&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Ksquare →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The empty square brackets [ ] specify that the values referred to have no indexes, i.e., they are atoms. You can now click any of these cells to see what it refers to.&lt;br /&gt;
&lt;br /&gt;
:::[[File:result_ref_ksquare_array.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Clicking the third cell, for example, gives:&lt;br /&gt;
&lt;br /&gt;
:::[[File:result_ref_ksquare_array2.png|300px]]&lt;br /&gt;
&lt;br /&gt;
==Managing indexes of referenced subarrays: \[i, j,...] e==&lt;br /&gt;
&lt;br /&gt;
More generally, you can list in the square brackets any indexes of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; that you want to be indexes of each subarray referenced by the result. The other indexes of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; (if any) are used as indexes for the referencing array. Thus, in the example above, since there were no indexes in square brackets, the index &amp;lt;code&amp;gt;K&amp;lt;/code&amp;gt; was used as an index of the reference array. If instead we write:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;\ [K] Ksquare →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::[[File:result_ref_ksquare_array3.png|250px]]&lt;br /&gt;
&lt;br /&gt;
It creates a similar result to &amp;lt;code&amp;gt;\ Ksquare&amp;lt;/code&amp;gt;, since &amp;lt;code&amp;gt;K&amp;lt;/code&amp;gt; is the only index of &amp;lt;code&amp;gt;Ksquare&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;\ e&amp;lt;/code&amp;gt;&lt;br /&gt;
|Creates a reference to the value of expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;, whether it is an atom or an array. &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;\ [] e&amp;lt;/code&amp;gt;&lt;br /&gt;
|Creates an array indexed by all indexes of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; containing references to all atoms from &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;\ [i] e&amp;lt;/code&amp;gt;&lt;br /&gt;
|Creates an array indexed by any indexes of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; other than &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; of references to subarrays of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; each indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;\ [i, j…] e&amp;lt;/code&amp;gt;&lt;br /&gt;
|Creates an array indexed by any indexes of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; other than &amp;lt;code&amp;gt;i, j …&amp;lt;/code&amp;gt; of references to subarrays of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; each indexed by &amp;lt;code&amp;gt;i, j ….&amp;lt;/code&amp;gt;&lt;br /&gt;
|} &lt;br /&gt;
&lt;br /&gt;
In general, it is better to include the square brackets after the reference operator, and avoid the unadorned reference operator, as in the first row of the table. Being explicit about which indexes to include generally leads to expressions that array abstract as intended.&lt;br /&gt;
&lt;br /&gt;
==IsReference(x)==&lt;br /&gt;
&lt;br /&gt;
This Is a test to see whether its parameter x is a reference. It returns True (1) if x is a reference, False (0) otherwise.&lt;br /&gt;
&lt;br /&gt;
==Using references for linked lists: Example functions==&lt;br /&gt;
&lt;br /&gt;
Linked lists are a common way for programmers to represent an ordered set of items. They are more efficient than arrays when you want often to add or remove items, thereby changing the length of the list (which is more time consuming for arrays). In Analytica, we can represent a linked list as an element with two elements, the item — that is, a reference to the value of the item — and a link — that is, a reference, to the next item:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index Linked_list&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: ['Item', 'Link']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function LL_Put(x, LL)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Description: Puts item x onto linked list LL.&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: \Array(Linked_List, [\x, LL])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function LL_Get_Item(LL)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Description: Gets the value of the first item from linked list LL.&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: # Subscript(#LL, Linked_list, 'Item')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function LL_length(LL)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Parameters: (LL: Atom)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Description: Returns the number of items in linked list LL&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: VAR len := 0;&amp;lt;/code&amp;gt;&lt;br /&gt;
::WHILE (IsReference(LL)) BEGIN&amp;lt;/code&amp;gt;&lt;br /&gt;
:::&amp;lt;code&amp;gt;LL := subscript(#LL, Linked_List, &amp;quot;Next&amp;quot;);&amp;lt;/code&amp;gt;&lt;br /&gt;
:::&amp;lt;code&amp;gt;len := len + 1&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;END;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function LL_from_array(a, i)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Parameters: (a; i: Index)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Description: Creates a linked list from the elements of array a over index i&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition:&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;VAR LL := NULL;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Index iRev := Size(i) .. 1;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;FOR j := iRev&amp;lt;/code&amp;gt;&lt;br /&gt;
:::&amp;lt;code&amp;gt;DO LL := LL_Push(LL, Slice(a, i, j));&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;LL&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See '''Linked List Library.ana''' in the '''Libraries''' folder for these and other functions for working with linked lists.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Analytica_Libraries_and_Templates#Linked_Lists Linked Lists]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Using_References Using References]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Ensuring Array Abstraction / {{PAGENAME}} / Handles to Objects&amp;lt;/footer&amp;gt;&lt;br /&gt;
__FORCETOC__&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Ensuring_Array_Abstraction&amp;diff=38824</id>
		<title>Ensuring Array Abstraction</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Ensuring_Array_Abstraction&amp;diff=38824"/>
		<updated>2015-12-29T03:40:29Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The vast majority of the elements of the Analytica language (operators, functions, and control constructs) fully support Intelligent Arrays — that is, they can handle operands or parameters that are arrays with any number of indexes, and generate a result with the appropriate dimensions. Thus, most models automatically obtain the benefits of array abstraction with no special care.&lt;br /&gt;
&lt;br /&gt;
There are just a few elements that do not inherently enable Intelligent Arrays — i.e., support array abstraction. They fall into these main types:&lt;br /&gt;
&lt;br /&gt;
* '''Functions whose parameters must be atoms''' (not arrays), including [http://wiki.analytica.com/index.php?title=Sequence Sequence], m..n, and [http://wiki.analytica.com/index.php?title=SplitText SplitText]. See below.&lt;br /&gt;
* Functions whose parameter must be a vector (an array with just one index), such as [http://wiki.analytica.com/index.php?title=CopyIndex CopyIndex], [http://wiki.analytica.com/index.php?title=SortIndex SortIndex], [http://wiki.analytica.com/index.php?title=Subset Subset], [http://wiki.analytica.com/index.php?title=Unique Unique], and [http://wiki.analytica.com/index.php?title=Concat Concat] when called with two parameters.&lt;br /&gt;
* The [http://wiki.analytica.com/index.php?title=For_and_While_Loops#While.28Test.29_Do_Body While loop], which requires its termination condition to be an atom.&lt;br /&gt;
* If [http://wiki.analytica.com/index.php?title=Ensuring_Array_Abstraction#If_a_Then_b_Else_c_and_array_abstraction b Then c Else d], when condition &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; is an array, and &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; can give an evaluation error.&lt;br /&gt;
* Functions with an optional index parameter that is '''[http://wiki.analytica.com/index.php?title=Ensuring_Array_Abstraction#Omitted_index_parameters_and_array_abstraction omitted]''', such as [http://wiki.analytica.com/index.php?title=Sum Sum](x), [http://wiki.analytica.com/index.php?title=Product Product], [http://wiki.analytica.com/index.php?title=Functions_Min_and_Max Max], [http://wiki.analytica.com/index.php?title=Functions_Min_and_Max Min], [http://wiki.analytica.com/index.php?title=Average Average], [http://wiki.analytica.com/index.php?title=ArgMin_and_ArgMax Argmax], [http://wiki.analytica.com/index.php?title=SubIndex SubIndex], [http://wiki.analytica.com/index.php?title=ChanceDist ChanceDist], [http://wiki.analytica.com/index.php?title=CumDist CumDist], and [http://wiki.analytica.com/index.php?title=ProbDist ProbDist].&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When using these constructs, you must take special care to ensure that your model is fully arrayabstractable. Here we explain how to do this for each of these five types.&lt;br /&gt;
&lt;br /&gt;
==Functions Expecting Atomic Parameters==&lt;br /&gt;
&lt;br /&gt;
Consider this example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable N := 1..3&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable B := 1..N&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;B → Evaluation error:&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;One or both parameters to Sequence(m, n) or m .. n are not scalars.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The expression &amp;lt;code&amp;gt;1..N&amp;lt;/code&amp;gt;, or equivalently, [http://wiki.analytica.com/index.php?title=Sequence &amp;lt;code&amp;gt;Sequence&amp;lt;/code&amp;gt;]&amp;lt;code&amp;gt;(1, N)&amp;lt;/code&amp;gt;, cannot work if &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt; is an array, because it would have to create a nonrectangular array containing slices with 1, 2, and 3 elements. Analytica does not allow nonrectangular arrays, and so requires the parameters of [http://wiki.analytica.com/index.php?title=Sequence Sequence] to be atoms (single elements).&lt;br /&gt;
&lt;br /&gt;
Most functions and expressions that, like [http://wiki.analytica.com/index.php?title=Sequence Sequence], are used to generate the definition of an index require atomic (or in some cases, vector) parameters, and so are not fully array abstractable. These include [http://wiki.analytica.com/index.php?title=Sequence Sequence], [http://wiki.analytica.com/index.php?title=Subset Subset], [http://wiki.analytica.com/index.php?title=SplitText SplitText], [http://wiki.analytica.com/index.php?title=SortIndex SortIndex] (if the second parameter is omitted), [http://wiki.analytica.com/index.php?title=Concat Concat], [http://wiki.analytica.com/index.php?title=CopyIndex CopyIndex], and [http://wiki.analytica.com/index.php?title=Unique Unique].&lt;br /&gt;
&lt;br /&gt;
Why would you want array abstraction using such a function? Consider this approach to writing a function to compute a factorial:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function Factorial2&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Parameters: (n)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: Product(1..n)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It works if &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is an atom, but not if it is an array, because &amp;lt;code&amp;gt;1..n&amp;lt;/code&amp;gt; requires atom operands. In this version, however, using a '''For''' loop works fine:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function Factorial3&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Parameters: (n)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: FOR m := n DO Product(1..m)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''For''' loop repeats with the loop variable &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; set to each atom of &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, and evaluates the body &amp;lt;code&amp;gt;Product(1..m)&amp;lt;/code&amp;gt; for each value. Because &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; is guaranteed to be an atom, this works fine. The '''For''' loop reassembles the result of each evaluation of &amp;lt;code&amp;gt;Product(1..m)&amp;lt;/code&amp;gt; to create an array with all the same dimensions as &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Atom parameters and array abstraction==&lt;br /&gt;
&lt;br /&gt;
Another way to ensure array abstraction in a function is to use the '''Atom''' qualifier for its parameter( s). When you qualify a parameter &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; as an Atom, you are saying that it must be a single value — not an array — when the function is evaluated, but not when the function is used:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function Factorial3&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Parameters: (n: Atom)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: Product(1..n)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::[[File:factorial3.png|400px]]&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Index K := 1 .. 6&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Factorial3(K) →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::[[File:result-result.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Notice that '''Atom''' does not require the actual parameter &amp;lt;code&amp;gt;K&amp;lt;/code&amp;gt; to be an atom when the function is called. If &amp;lt;code&amp;gt;K&amp;lt;/code&amp;gt; is an array, as in this case, it repeatedly evaluates the function &amp;lt;code&amp;gt;Factorial3(n)&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; set to each atom of array &amp;lt;code&amp;gt;K&amp;lt;/code&amp;gt;. It then reassembles the results back into an array with the same indexes as parameter K, like the '''For''' loop above. This scheme works fine even if you qualify several parameters of the function as '''Atom'''.&lt;br /&gt;
&lt;br /&gt;
In some cases, a function might require a parameter to be an vector (have only one index), or have multiple dimensions with specified indexes. You can use [[Array Qualifiers|Array qualifiers]] to specify this. With this approach, you can ensure your function array abstracts when new dimensions are added to your model, or if parameters are probabilistic.&lt;br /&gt;
&lt;br /&gt;
==While and array abstraction==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;While b Do e&amp;lt;/code&amp;gt; construct requires its termination condition &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; to evaluate to be an atom — that is, a single Boolean value, &amp;lt;code&amp;gt;True (1)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;False (0)&amp;lt;/code&amp;gt;. Otherwise, it would be ambiguous about whether to continue. Again, '''Atom''' is useful to ensure that a function using a '''While''' loop array abstracts, as it was for the [http://wiki.analytica.com/index.php?title=Sequence Sequence] function. Here’s a way to write a [http://wiki.analytica.com/index.php?title=Factorial Factorial] function using a While loop:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function Factorial4&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Parameters: (n: Atom)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition:&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;VAR fact := 1; VAR a := 1;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;WHILE a &amp;lt; n DO (a := a + 1; fact := fact * a)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, the '''Atom''' qualifier assures that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; and hence the '''While''' termination condition &amp;lt;code&amp;gt;a &amp;lt; n&amp;lt;/code&amp;gt; is an atom during each evaluation of '''Factorial4'''.&lt;br /&gt;
&lt;br /&gt;
==If a Then b Else c and array abstraction==&lt;br /&gt;
&lt;br /&gt;
Consider this example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable X := -2..2&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Sqrt(X) → [NAN, NAN, 0, 1, 1.414]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The square root of negative numbers -2 and -1 returns '''NAN''' (not a number) after issuing  a warning. Now consider the definition of '''Y''':&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Y := (IF X&amp;gt;0 THEN Sqrt(X) ELSE 0)&amp;lt;/code&amp;gt; &lt;br /&gt;
:&amp;lt;code&amp;gt;Y → [0, 0, 0, 1 1.414]&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
For the construct IF a THEN b ELSE c, &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; is an array of truth values, as in this case, so it evaluates both &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt;. It returns the corresponding elements of &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt;, according to the value of condition &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; for each index value. Thus, it still ends up evaluating [http://wiki.analytica.com/index.php?title=Sqrt Sqrt](X) even for negative values of &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt;. In this case, it returns &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; for those values, rather than '''NAN''', and so it does not generate an error message.&lt;br /&gt;
&lt;br /&gt;
A similar problem remains with text processing functions that require a parameter to be a text value. Consider this array:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Z := [1000, '10,000', '100,000']&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This kind of array containing true numbers, e.g., 1000, and numbers with commas turned into text values, often arises when copying arrays of numbers from spreadsheets. The following function would seem helpful to remove the commas and convert the text values into numbers:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function RemoveCommas(t)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Parameters: (t)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: Evaluate(TextReplace(t, ',', ''))''&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;RemoveCommas(Z) →&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Evaluation Error: The parameter of Pluginfunction TextReplace must be a text while evaluating function RemoveCommas.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=TextReplace TextReplace] doesn’t like the first value of &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt;, which is a number, where it’s expecting a text value. What if we test if &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt; is text and only applies [http://wiki.analytica.com/index.php?title=TextReplace TextReplace] when it is?&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function RemoveCommas(t)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Parameters: (t)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: IF IsText(t)&lt;br /&gt;
::THEN Evaluate(TextReplace(t, ',', '')) ELSE t''&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;RemoveCommas(Z) → (same error message)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It still doesn’t work because the '''IF''' construct still applies ReplaceText to all elements of &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt;. Now, let’s add the parameter qualifier '''Atom''' to &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function RemoveCommas(t)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Parameters: (t: Atom)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: IF IsText(t)&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;THEN Evaluate(TextReplace(t, ',', '')) ELSE t''&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;RemoveCommas(Z) →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::[[File:result3.png|200px]]&lt;br /&gt;
&lt;br /&gt;
This works fine because the '''Atom''' qualifier means that '''&amp;lt;code&amp;gt;RemoveCommas&amp;lt;/code&amp;gt;''' breaks its parameter &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt; down into atomic elements before evaluating the function. During each evaluation of &amp;lt;code&amp;gt;Remove-Commas&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt;, and hence [http://wiki.analytica.com/index.php?title=Data_Type_Functions#Function_IsText IsText](t), is atomic, either True or False. When False, the '''If''' construct evaluates the '''Else''' part but not the '''Then''' part, and so calls [http://wiki.analytica.com/index.php?title=TextReplace TextReplace] when t is truly a text value. After calling [http://wiki.analytica.com/index.php?title=TextReplace TextReplace] separately for each element, it reassembles the results into the array shown above with the same index as &amp;lt;code&amp;gt;Z&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Omitted index parameters and array abstraction==&lt;br /&gt;
&lt;br /&gt;
Several functions have index parameters that are optional, including [http://wiki.analytica.com/index.php?title=Sum Sum], [http://wiki.analytica.com/index.php?title=Product Product], [http://wiki.analytica.com/index.php?title=Functions_Min_and_Max Max], [http://wiki.analytica.com/index.php?title=Functions_Min_and_Max Min], [http://wiki.analytica.com/index.php?title=Average Average], [http://wiki.analytica.com/index.php?title=ArgMin_and_ArgMax Argmax], [http://wiki.analytica.com/index.php?title=SubIndex SubIndex], [http://wiki.analytica.com/index.php?title=ChanceDist ChanceDist], [http://wiki.analytica.com/index.php?title=CumDist CumDist,] and [http://wiki.analytica.com/index.php?title=ProbDist ProbDist]. For example, with [http://wiki.analytica.com/index.php?title=Sum Sum](x, i), you can omit index &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, and call it as [http://wiki.analytica.com/index.php?title=Sum Sum](x). But, if &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; has more than one index, it is hard to predict which index it sums over. Even if &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; has only one dimension now, you might add other dimensions later, for example for parametric analysis. This ambiguity makes the use of functions with omitted index parameters non-array abstractable.&lt;br /&gt;
&lt;br /&gt;
There is a simple way to avoid this problem and maintain reliable array abstraction: '''''When using functions with optional index parameters, never omit the index!''''' Almost always, you know what you want to sum over, so mention it explicitly. If you add dimensions later, you’ll be glad you did.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt; When the optional index parameter is omitted, and the parameter has more than one dimension, these functions choose the '''''outer index''''', by default. Usually, the outer index is the index created most recently when the model was built. But, this is often not obvious. We designed Intelligent Arrays specifically to shield you from having to worry about this detail of the internal representation.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selecting indexes for iterating with For and Var==&lt;br /&gt;
&lt;br /&gt;
To provide detailed control over array abstraction, the '''For''' loop can specify exactly which indexes to use in the iterator &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;. The old edition of '''For''' still works. It requires that the expression &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; assigned to iterator &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; generate an index — that is, it must be a defined index variable, [http://wiki.analytica.com/index.php?title=Sequence Sequence](m, n), or m..n. The new forms of '''For''' are more flexible. They work for any array (or even atomic) value &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;. The loop iterates by assigning to x successive subarrays of &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, dimensioned by the indexes listed in square brackets. If the square brackets are empty, as in the second line of the table, the successive values of iterator &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; are atoms. In the other cases, the indexes mentioned specify the dimensions of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; to be used in each evaluation of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;. In all cases, the final result of executing the '''For''' loop is a value with the same dimensions as &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|'''For x := a DO e'''&lt;br /&gt;
|Assigns to loop variable &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; successive atoms from index expression &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; and repeats evaluation expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; for each value. Returns an array of values of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; indexed by &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;. &lt;br /&gt;
|-&lt;br /&gt;
|'''For x := a DO e'''&lt;br /&gt;
'''For x[] := a DO e|D'''&lt;br /&gt;
|Assigns to loop variable &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, successive atomic values from array &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;. It repeats evaluation of expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; for each value. It returns an array of values of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; with the same indexes as &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|'''For x[i] := a DO e'''&lt;br /&gt;
|Assigns to loop variable &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; successive subarrays from array &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, each indexed only by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;. It repeats evaluation of expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; for each index value of &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; other than &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;. As before, the result has the same indexes as &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|'''For x[i, j …] := a DO e'''&lt;br /&gt;
|Assigns to loop variable &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; successive subarrays from array &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, each indexed only by &amp;lt;code&amp;gt;i, j ….&amp;lt;/code&amp;gt; It repeats evaluation of expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; for each index value of &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; other than &amp;lt;code&amp;gt;i, j ….&amp;lt;/code&amp;gt; . As before, the result has the same indexes as &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The same approach also works using '''Var''' to define local variables. By putting square brackets listing indexes after the new variable, you can specify the exact dimensions of the variable. These indexes should be a subset (none, one, some, or all) of the indexes of the assigned value &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;. Any subsequent expressions in the context are automatically repeated as each subarray is assigned to the local variable. In this way, a local variable can act as an implicit iterator, like the '''For''' loop.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Var Temp[i1, i2, ...] := X;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Local Indexes / {{PAGENAME}} / References and Data Structures&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Local_Indexes&amp;diff=38822</id>
		<title>Local Indexes</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Local_Indexes&amp;diff=38822"/>
		<updated>2015-12-29T03:39:40Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[category:Concepts]]&lt;br /&gt;
[[Category:Doc Status C]] &amp;lt;!-- For Lumina use, do not change --&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You can declare a local index in the definition of a variable or function. It is possible that the value of the variable or value returned by the function is an array using this index. This is handy because it lets you define a variable or function that creates an array without relying on an externally defined index.&lt;br /&gt;
&lt;br /&gt;
The construct, &amp;lt;code&amp;gt;Index i := indexExpr&amp;lt;/code&amp;gt; defines an index local to the definition in which it is used. The expression &amp;lt;code&amp;gt;indexExpr&amp;lt;/code&amp;gt; can be a sequence, literal list, or other expression that generates an unindexed array, as used to define a global index. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable PowersOf2 := Index j := 0..5; 2^j&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new variable &amp;lt;code&amp;gt;PowersOf2&amp;lt;/code&amp;gt; is an array of powers of two, indexed by the local index &amp;lt;code&amp;gt;j&amp;lt;/code&amp;gt;, with values from 0 to 5:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;PowersOf2 →&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:result-powersof2.png|200px]]&lt;br /&gt;
&lt;br /&gt;
==Dot operator: a . i==&lt;br /&gt;
&lt;br /&gt;
The dot operator in &amp;lt;code&amp;gt;a . i&amp;lt;/code&amp;gt; lets you access a local index &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; via an array &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; that it dimensions. If a local index identifies a dimension of an array that becomes the value of a global variable, it can persist long after evaluation of the expression — unlike other local variables which disappear after the expression is evaluated.&lt;br /&gt;
&lt;br /&gt;
Even though local index &amp;lt;code&amp;gt;j&amp;lt;/code&amp;gt; has no global identifier, you can access it via its parent variable with the dot operator (&amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;), for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;PowersOf2.j → [0,1,2,3,4,5]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When using the subscript operation on a variable with a local index, you need to include the dot (&amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;) operator, but do not need to repeat the name of the variable:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;PowersOf2[.j=5] → 32&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Any other variables depending on &amp;lt;code&amp;gt;PowersOf2&amp;lt;/code&amp;gt; can inherit &amp;lt;code&amp;gt;j&amp;lt;/code&amp;gt; as a local index — for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable P2 := PowersOf2/2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;P2[.j=5] → 16&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example using a local index ==&lt;br /&gt;
In this example, &amp;lt;code&amp;gt;MatSqr&amp;lt;/code&amp;gt; is a user-defined function that returns the square of a matrix — i.e., &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; x &amp;lt;code&amp;gt;A'&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;A'&amp;lt;/code&amp;gt; is the transpose of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;. The result is a square matrix. Rather than require a third index as a parameter, &amp;lt;code&amp;gt;MatSqr&amp;lt;/code&amp;gt; creates the local index, &amp;lt;code&amp;gt;i2&amp;lt;/code&amp;gt;, as a copy of index &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function MatSqr(a: Array; i, j: Index)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition := Index i2:=CopyIndex(i); Sum(a*a[i=i2], j)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The local variable, &amp;lt;code&amp;gt;i2&amp;lt;/code&amp;gt;, in &amp;lt;code&amp;gt;MatSqr&amp;lt;/code&amp;gt; is not within lexical scope in the definition of &amp;lt;code&amp;gt;Z&amp;lt;/code&amp;gt;, so we must use the dot operator (&amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;) to access this dimension. In the example below, we &amp;lt;u&amp;gt;underline&amp;lt;/u&amp;gt; the dot operator for clarity:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Z := Var XX := MatSqr(X, Rows, Cols);&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Sum(XX * Y[I=XX&amp;lt;u&amp;gt;.&amp;lt;/u&amp;gt;i2], XX&amp;lt;u&amp;gt;.&amp;lt;/u&amp;gt;i2)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Analytica's arrays are, in general, multi-dimensional, where each dimension is identified with an Index.  An Index is an Analytica object with a list of [[IndexValue]]s.  Indexes in Analytica come in three varieties:&lt;br /&gt;
&lt;br /&gt;
:''Global Indexes'': These appear as parallelagrams on a diagram.  (e.g., [[image:IndexNode.jpg]] )&lt;br /&gt;
:''[[Self-Indexed Arrays|Self Indexes]]'': A variable whose that can serve as an index, but also has a value.&lt;br /&gt;
:''Local Indexes'': Index objects that do not exist in the global namespace.&lt;br /&gt;
&lt;br /&gt;
Local indexes may be temporary, disappearing after they fall out of lexical context, or they may continue to exist outside of the lexical context where they were declared if an array indexed by the local index is returned.&lt;br /&gt;
&lt;br /&gt;
Local indexes are declared within expressions via the [[Index..Do]] declaration, as in this example:&lt;br /&gt;
&lt;br /&gt;
 [[Index..Do|Index]] X := [[Sequence]](x1,x2,(x2-x1)/1000) Do ArgMax( f(X^2), X )&lt;br /&gt;
&lt;br /&gt;
In the above example, the identifier X exists as a local variable only within the body of the Do clause, and refers to the index defined as a sequence with 1000 points ranging from x1 to x2.  ArgMax finds the maximum of f(X^2) and returns a single value, after which the index X ceases to exist.&lt;br /&gt;
&lt;br /&gt;
Syntactically, an index can also be written using this syntax:&lt;br /&gt;
&lt;br /&gt;
 Index X := [[Sequence]](x1,x2,(x2-x1)/1000);&lt;br /&gt;
 [[ArgMax]]( f(X^2), X )&lt;br /&gt;
&lt;br /&gt;
Here the local variable X is recognized to the end of the current lexical context.&lt;br /&gt;
&lt;br /&gt;
It is possible for an expression to return an array that is indexed by a local index.  When this happens, the local index continues to exist, although no local variable or identifier refers to it directly.  This happens, for example, in the following expression:&lt;br /&gt;
&lt;br /&gt;
 Index Bit := 7..0;&lt;br /&gt;
 [[Mod]]( [[Floor]](N/2^Bit),2 )&lt;br /&gt;
&lt;br /&gt;
which returns the following when N:=137:&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! .Bit &amp;amp;rarr; !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| || 1 || 0 || 0 || 0 || 1 || 0 || 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After this expression is evaluated, the local variable Bit no longer exists, but a 1-D array indexed by .Bit does exist. The only way to access this local index is through the array result.  Suppose BinaryN is defined by the expression above.  The syntax BinaryN.Bit identifies the index.  So, for example, to count the number of bits:&lt;br /&gt;
&lt;br /&gt;
 [[Sum]]( BinaryN, BinaryN.Bit )  &amp;amp;rarr; 3&lt;br /&gt;
&lt;br /&gt;
where the second parameter to [[Sum]] expects an index.&lt;br /&gt;
&lt;br /&gt;
To access the 3rd bit of BinaryN (counting from 0), we could write&lt;br /&gt;
 BinaryN[ BinaryN.Bit = 3 ]&lt;br /&gt;
or we can abbreviate in this case as&lt;br /&gt;
 BinaryN[ .Bit = 3 ]&lt;br /&gt;
since it is clear that .Bit is refering to an index of BinaryN.  This abbreviation is only possible within the [[Subscript/Slice Operator]], not in other contexts.&lt;br /&gt;
&lt;br /&gt;
It is theoretically possible to create an array with more than one local index having the same name.  In this case, the [[A.I]] syntax is ambiguous, and one index is identified.&lt;br /&gt;
&lt;br /&gt;
Within an expression, if you have an array containing a local index, it is possible to define a local variable as an alias to refer to this index in order to avoid having to type, e.g., BinaryN.Bit every time.  This is done using the [[Var..Do]] declaration, not the [[Index..Do]], since the Index..Do construct would create an entirely new index object, and is done as follows:&lt;br /&gt;
&lt;br /&gt;
 [[Var..Do|Var]] I := [[VarTerm]]( BinaryN.Bit, asIndex:True ) Do expr&lt;br /&gt;
&lt;br /&gt;
where inside expr, the local variable I is an alias for the actual index object.  Note that the local name used in expr does not have to be the same as the local index's object name.  The optional asIndex parameter of VarTerm is not actually needed in the example here, but can optionally be included for clarity (it is necessary if you want to alias a [[Self-Indexed Arrays|self-index]], as opposed to aliasing the object having a self-index).   As a full example, the following expression bit-shifts the complement of BinaryN (divides the complement by 2), note how using I as an alias for BinaryN.Bit helps with conciseness within the expression:&lt;br /&gt;
&lt;br /&gt;
 [[Var..Do|Var]] I := [[VarTerm]]( BinaryN.Bit ) Do &lt;br /&gt;
   [[Index Position Operator::@|@I]]=1 [[Or]] ([[Not]] BinaryN)[@I=@I-1]&lt;br /&gt;
 &lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! .Bit &amp;amp;rarr; !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| || 1 || 0 || 1 || 1 || 1 || 0 || 1 || 1 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The numeric equivalent is computed by&lt;br /&gt;
&lt;br /&gt;
 [[Var..Do|Var]] I := [[VarTerm]]( BinaryN.Bit ) Do &lt;br /&gt;
   [[Sum]](2^I * ([[Index Position Operator::@|@I]]=1 [[Or]] ([[Not]] BinaryN)[@I=@I-1]), I )&lt;br /&gt;
&lt;br /&gt;
which returns 187.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Recursion / {{PAGENAME}} / Ensuring Array Abstraction&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Recursion&amp;diff=38821</id>
		<title>Recursion</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Recursion&amp;diff=38821"/>
		<updated>2015-12-29T03:39:04Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A '''''recursive''''' function is a function that calls itself within its definition. This is often a convenient way to define a function, and sometimes the only way. As an example, consider this definition of factorial:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function Factorial2(n: Positive Atom)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition: IF n &amp;gt; 1 THEN N*Factorial2(n-1) ELSE 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If its parameter, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, is greater than 1, &amp;lt;code&amp;gt;Factorial2&amp;lt;/code&amp;gt; calls itself with the actual parameter value &amp;lt;code&amp;gt;n-1&amp;lt;/code&amp;gt;. Otherwise, it simply returns 1. Like any normal recursive function, it has a termination condition under which the recursion stops — when &amp;lt;code&amp;gt;n &amp;lt;= 1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt; The built-in function Factorial does the same, and is fully abstractable, to boot. We define Factorial2 here as a simple example to demonstrate key ideas.&amp;lt;/Tip &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, if you try to use a function in its own definition, it complains about a cyclic dependency loop. To enable recursion, you must display and set the '''Recursive''' attribute:&lt;br /&gt;
&lt;br /&gt;
# Select '''Attributes''' from the '''Object''' menu.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::[[File:procedure_attributes.png|200px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Select '''Functions''' from the '''Class''' menu.&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Scroll down the list of attributes and click '''Recursive''' twice, so that it shows √, meaning that the recursive attribute is displayed for each function in its '''Object''' window and the '''Attribute''' panel.&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;4&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Check '''OK''' to close '''Attributes''' dialog.&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For each function for which you wish to enable recursion:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Open the '''Object Window''' for the function by double-clicking its node (or selecting the node and clicking the '''Object''' button).&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Type '''&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;''' into its '''Recursive''' field.&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::[[File:factorial2.png|400px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As another example, consider this recursive function to compute a list of the prime factors of an integer, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, equal to or greater than &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function Prime_factors(x, y: Positive Atom)&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;Definition:&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Var n := Floor(x/y);&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;IF n&amp;lt;y THEN [x]&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;ELSE IF x = n*y THEN Concat([y], Factors(n, y))&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;ELSE Prime_factors(x, y+1)&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;Factors(60, 2) → [2, 2, 3, 5]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In essence, &amp;lt;code&amp;gt;Prime_factors&amp;lt;/code&amp;gt; says to compute &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; divided by &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, rounded down. If &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; is greater than &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is the last factor, so return &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; as a list. If &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is an exact factor of &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, then concatenate &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; with any factors of &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, equal or greater than &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;. Otherwise, try &amp;lt;code&amp;gt;y+1&amp;lt;/code&amp;gt; as a factor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt;To prevent accidental infinite recursion, it stops and gives a warning if the stack reaches a depth&lt;br /&gt;
of 256 function calls.&amp;lt;/Tip &amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;For and while Loops / {{PAGENAME}} / Local Indexes&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=For_and_While_Loops&amp;diff=38819</id>
		<title>For and While Loops</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=For_and_While_Loops&amp;diff=38819"/>
		<updated>2015-12-29T03:36:19Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== For i := a Do expr ==&lt;br /&gt;
&lt;br /&gt;
The '''For''' loop successively assigns the next atom from array &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; to local index &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, and evaluates expression &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; might refer to &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, for xample to slice out a particular element of an array. &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; might be a list of values defined by &amp;lt;code&amp;gt;m..n&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Sequence(m, n, dx)&amp;lt;/code&amp;gt; or it might be a multidimensional array. Normally, it evaluates the body &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; once for each atom in &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The result of the '''For '''loop is an array with all the indexes of &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; containing the values of each evaluation of &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;. If any or all evaluations of &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; have any additional index(es), they are also indexes of the result.&lt;br /&gt;
&lt;br /&gt;
Usually, the Intelligent Array features take care of iterating over indexes of arrays without the need for explicit looping. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;gt; Analytica’s Intelligent Array features means that you rarely need explicit iteration using '''For''' loops to repeat operations over each dimensions of an array, often used in conventional computer language. If you find yourself using '''For''' loops a lot in Analytica, this might be a sign that you are not using '''Intelligent Arrays''' effectively. If so, please (re)read the sections on [[Intelligent_Arrays|Intelligent Arrays]].&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A '''For''' loop is sometimes useful in these specialized cases:&lt;br /&gt;
&lt;br /&gt;
* To avoid selected evaluations of &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; that might be invalid or out of range, and can be prevented by nesting an &amp;lt;code&amp;gt;If-Then-Else&amp;lt;/code&amp;gt; inside a '''For'''.&lt;br /&gt;
* To apply an Analytica function that requires an atom or one- or two-dimensional array input to a higher-dimensioned array.&lt;br /&gt;
* To reduce the memory needed f or calculations with very large arrays by reducing the memory requirement for intermediate results.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See below for an example of each of these three cases.&lt;br /&gt;
&lt;br /&gt;
==== Library  ====&lt;br /&gt;
Special&lt;br /&gt;
&lt;br /&gt;
====Avoiding out-of-range errors====&lt;br /&gt;
&lt;br /&gt;
Consider the following expression:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;If x&amp;lt;0 Then 0 Else Sqrt(x)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;If-Then-Else&amp;lt;/code&amp;gt; is included in this expression to avoid the warning “Square root of a negative number.” However, if &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is an array of values, this expression cannot avoid the warning since [http://wiki.analytica.com/index.php?title=Sqrt Sqrt](x) is evaluated before &amp;lt;code&amp;gt;If-Then-Else&amp;lt;/code&amp;gt; selects which elements of [http://wiki.analytica.com/index.php?title=Sqrt Sqrt](x) to include. To avoid the warning (assuming &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;), the expression can be rewritten as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;For j:=I do&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;If x[i=j]&amp;lt;0 then 0 else Sqrt(x[i=j])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or as (see next section):&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Using y:=x in i do&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;If y&amp;lt;0 Then 0 else Sqrt(y)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Situations like this can often occur during slicing operations. For example, to shift &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; one position to the right along &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, the following expression would encounter an error:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;if i&amp;lt;2 then x[i=1] else x[i=i-1]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The error occurs when &amp;lt;code&amp;gt;x[i=i-1]&amp;lt;/code&amp;gt; is evaluated since the value corresponding to &amp;lt;code&amp;gt;i-1=0&amp;lt;/code&amp;gt; is out of range. The avoid the error, the expression can be rewritten as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;For j:=i do&lt;br /&gt;
::If j&amp;lt;2 then x[i=1] else x[i=j-1]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Out-of-range errors can also be avoided without using '''For''' by placing the conditional inside an argument. For example, the two examples above can be written without '''For''' as follows:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sqrt(if x&amp;lt;0 then 0 else x)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i=(if i&amp;lt;2 then 1 else i-1)]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Dimensionality reduction =====&lt;br /&gt;
'''For''' can be used to apply a function that requires an atom, one- or two- dimensional input to a multi-dimensional result. This usage is rare in Analytica since array abstraction normally does this automatically; however, the need occasionally arises in some circumstances.&lt;br /&gt;
&lt;br /&gt;
Suppose you have an array &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;, and you wish to apply a function &amp;lt;code&amp;gt;f(x)&amp;lt;/code&amp;gt; to each element of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; along &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;. In a conventional programming language, this would require a loop over the elements of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;; however, in almost all cases, Analytica’s array abstraction does this automatically — the expression is simply &amp;lt;code&amp;gt;f(A)&amp;lt;/code&amp;gt;, and the result remains indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;. However, there are a few cases where Analytica does not automatically array abstract, or it is possible to write a user-defined function that does not automatically array abstract (e.g., by declaring a parameter to be of type &amp;lt;code&amp;gt;Atom&amp;lt;/code&amp;gt;, as detailed in [[Parameter Qualifiers]]). For example, Analytica does not array abstract over functions such as [http://wiki.analytica.com/index.php?title=Sequence Sequence], [http://wiki.analytica.com/index.php?title=Split Split], [http://wiki.analytica.com/index.php?title=Subset Subset], or [http://wiki.analytica.com/index.php?title=Unique Unique], since these return un-indexed lists of varying lengths that are unknown until the function evaluates. Suppose we have the following variables defined (note that &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; is an array of text values):&lt;br /&gt;
&lt;br /&gt;
:A: Index_1 ▼&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &amp;lt;font color=&amp;quot;#FFFFFF&amp;quot;&amp;gt;1&amp;lt;/font&amp;gt;&lt;br /&gt;
!&lt;br /&gt;
|-&lt;br /&gt;
!1&lt;br /&gt;
|A, B, C&lt;br /&gt;
|-&lt;br /&gt;
!2&lt;br /&gt;
|D, E, F&lt;br /&gt;
|-&lt;br /&gt;
!3&lt;br /&gt;
|G, H, I&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:Index_1 ▼&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
We wish to split the text values in A and obtain a two dimensional array of letters indexed by Index_1 and Index_2. Since Split does not array abstract, we must do each row separately and re-index by Index_2 before the result rows are recombined into a single array. This is accomplished by the following loop:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FOR Row := Index_1 DO Array(Index_2, SplitText(A[Index_1=Row], ','))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This results in:&lt;br /&gt;
&lt;br /&gt;
:Index_1 ▼, Index_2 ▶&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 3&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
|A&lt;br /&gt;
|B &lt;br /&gt;
|C&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:100px;&amp;quot; |2&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |D&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |E&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |F&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:100px;&amp;quot; |3&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |G&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |H&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |I&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Reducing memory requirements===&lt;br /&gt;
&lt;br /&gt;
In some cases, it is possible to reduce the amount of memory required for intermediate results during the evaluation of expressions involving large arrays. For example, consider the following expression:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MatrixA:&amp;lt;/code&amp;gt; A two dimensional array indexed by M and N.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MatrixB:&amp;lt;/code&amp;gt; A two dimensional array indexed by N and P.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Average(MatrixA * MatrixB, N)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During the calculation, Analytica needs memory to compute &amp;lt;code&amp;gt;MatrixA * MatrixB&amp;lt;/code&amp;gt;, an array indexed by &amp;lt;code&amp;gt;M&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;. If these indexes have sizes 100, 200, and 300 respectively, then &amp;lt;code&amp;gt;MatrixA * MatrixB&amp;lt;/code&amp;gt; contains 6,000,000 numbers, requiring over 60 megabytes of memory at 10&lt;br /&gt;
bytes per number.&lt;br /&gt;
&lt;br /&gt;
To reduce the memory required, use the following expression instead:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;For L := M Do Average(MatrixA[M=L]*MatrixB, N)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each element &amp;lt;code&amp;gt;MatrixA[M=L]*MatrixB&amp;lt;/code&amp;gt; has dimensions &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, needing only 200x300x10= 600 kilobytes of memory at a time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tip title=&amp;quot;Tip&amp;quot;&amp;gt;For the special case of a [[Matrix_functions#Dot_product_of_two_matrices|dot product]], for an expression of the form &amp;lt;code&amp;gt;Sum(a*b, i)&amp;lt;/code&amp;gt;, it performs a similar transformation internally.&amp;lt;/tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===While(Test) Do Body===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; evaluates &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; repeatedly as long as &amp;lt;code&amp;gt;Test &amp;lt;&amp;gt; 0&amp;lt;/code&amp;gt;. For &amp;lt;code&amp;gt;While ...&amp;lt;/code&amp;gt; to terminate, &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; must produce a side-effect on a local variable that is used by &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt;, causing &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; eventually to equal &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. If &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; never becomes False, &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; continues to loop indefinitely. If you suspect that might be happening, type ''Control+. (Control+period)'' to interrupt execution.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; must evaluate to an atomic (non-array) value; therefore, it is a good idea to force any local variable used in &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; to be atomic valued. &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; is one of the few constructs in Analytica that does not generalize completely to handle arrays. But, there are ways to ensure that variables and functions using &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; support Intelligent Arrays and probabilistic evaluation. See “While and&lt;br /&gt;
array abstraction” on page 386 for details.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; returns the final value found in the last iteration of &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Null&amp;lt;/code&amp;gt; if no iterations occur. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;(Var x := 1; While x &amp;lt; 10 Do x := x+1) ¨ 10&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;(Var x := 1; While x &amp;gt; 10 Do x := x+1) ¨ Null&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; often follows the following pattern:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Var x[]:= ...;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;While (FunctionOf(x)) Do (&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;x := expr;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;);&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;returnValue&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Iterate (initial, expr, until, maxIter, ''warnFlag'') ==&lt;br /&gt;
Suppose the definition of variable x contains a call to [http://wiki.analytica.com/index.php?title=Iterate Iterate](). [http://wiki.analytica.com/index.php?title=Iterate Iterate]() initializes &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; to the value of &amp;lt;code&amp;gt;initial&amp;lt;/code&amp;gt;. While stopping condition until is False (zero), it evaluates expression expr, and assigns the result to x. Given the optional parameter &amp;lt;code&amp;gt;maxIter&amp;lt;/code&amp;gt;, it stops after &amp;lt;code&amp;gt;maxIter&amp;lt;/code&amp;gt; iterations and, if &amp;lt;code&amp;gt;warnFlag&amp;lt;/code&amp;gt; is True, issues a warning — unless it has already been stopped by &amp;lt;code&amp;gt;until&amp;lt;/code&amp;gt; becoming True. If &amp;lt;code&amp;gt;until&amp;lt;/code&amp;gt; is array-valued, it only stops when all elements of &amp;lt;code&amp;gt;until&amp;lt;/code&amp;gt; are True.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=Iterate Iterate]() is designed for convergence algorithms where an expression must be recomputed an unknown number of iterations. [http://wiki.analytica.com/index.php?title=Iterate Iterate] (like [http://wiki.analytica.com/index.php?title=Dynamic Dynamic]) must be the main expression in a definition — it cannot be nested within another expression. But it can, and usually does, contain nested expressions as some of its parameters. [http://wiki.analytica.com/index.php?title=Iterate Iterate]() (again like [http://wiki.analytica.com/index.php?title=Dynamic Dynamic]() and unlike other functions) can, and usually does, mention the variable x that it defines within the expressions for initial and until. These expressions can also refer to variables that depend on &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you use [http://wiki.analytica.com/index.php?title=Iterate Iterate]() in more than one node in your model, you should be careful that the two functions don’t interact adversely. In general, two nodes containing [http://wiki.analytica.com/index.php?title=Iterate Iterate]() should never be mutual ancestors of each other. Doing so makes the nesting order ambiguous and can result in inconsistent computations. Likewise, care must be taken to avoid similar ambiguities when using interacting [http://wiki.analytica.com/index.php?title=Iterate Iterate] and [http://wiki.analytica.com/index.php?title=Dynamic Dynamic] loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt; You can usually write convergence algorithms more cleanly using '''While'''. One difference is that '''While''' requires its stopping condition '''Test''' to be an atom, where [[Iterate]]() allows an array-valued stopping condition until. Nevertheless, it is usually better to use '''While''' because you want it to do an appropriate number of iterations for each element of '''until''', rather than continue until all its elements are '''True'''. But, with '''While''' you need to use one of the tricks described in “While and array abstraction” to ensure the expression fully supports array abstraction.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Intelligent_Arrays Intelligent Arrays]&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Local Variables / {{PAGENAME}} / Recursion&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=For_and_While_Loops&amp;diff=38818</id>
		<title>For and While Loops</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=For_and_While_Loops&amp;diff=38818"/>
		<updated>2015-12-29T03:35:52Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== For i := a Do expr ==&lt;br /&gt;
&lt;br /&gt;
The '''For''' loop successively assigns the next atom from array &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; to local index &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, and evaluates expression &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; might refer to &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, for xample to slice out a particular element of an array. &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; might be a list of values defined by &amp;lt;code&amp;gt;m..n&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Sequence(m, n, dx)&amp;lt;/code&amp;gt; or it might be a multidimensional array. Normally, it evaluates the body &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; once for each atom in &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The result of the '''For '''loop is an array with all the indexes of &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; containing the values of each evaluation of &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;. If any or all evaluations of &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; have any additional index(es), they are also indexes of the result.&lt;br /&gt;
&lt;br /&gt;
Usually, the Intelligent Array features take care of iterating over indexes of arrays without the need for explicit looping. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;gt; Analytica’s Intelligent Array features means that you rarely need explicit iteration using '''For''' loops to repeat operations over each dimensions of an array, often used in conventional computer language. If you find yourself using '''For''' loops a lot in Analytica, this might be a sign that you are not using '''Intelligent Arrays''' effectively. If so, please (re)read the sections on [[Intelligent_Arrays|Intelligent Arrays]].&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A '''For''' loop is sometimes useful in these specialized cases:&lt;br /&gt;
&lt;br /&gt;
* To avoid selected evaluations of &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; that might be invalid or out of range, and can be prevented by nesting an &amp;lt;code&amp;gt;If-Then-Else&amp;lt;/code&amp;gt; inside a '''For'''.&lt;br /&gt;
* To apply an Analytica function that requires an atom or one- or two-dimensional array input to a higher-dimensioned array.&lt;br /&gt;
* To reduce the memory needed f or calculations with very large arrays by reducing the memory requirement for intermediate results.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See below for an example of each of these three cases.&lt;br /&gt;
&lt;br /&gt;
==== Library  ====&lt;br /&gt;
Special&lt;br /&gt;
&lt;br /&gt;
====Avoiding out-of-range errors====&lt;br /&gt;
&lt;br /&gt;
Consider the following expression:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;If x&amp;lt;0 Then 0 Else Sqrt(x)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;If-Then-Else&amp;lt;/code&amp;gt; is included in this expression to avoid the warning “Square root of a negative number.” However, if &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is an array of values, this expression cannot avoid the warning since [http://wiki.analytica.com/index.php?title=Sqrt Sqrt](x) is evaluated before &amp;lt;code&amp;gt;If-Then-Else&amp;lt;/code&amp;gt; selects which elements of [http://wiki.analytica.com/index.php?title=Sqrt Sqrt](x) to include. To avoid the warning (assuming &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;), the expression can be rewritten as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;For j:=I do&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;If x[i=j]&amp;lt;0 then 0 else Sqrt(x[i=j])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or as (see next section):&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Using y:=x in i do&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;If y&amp;lt;0 Then 0 else Sqrt(y)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Situations like this can often occur during slicing operations. For example, to shift &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; one position to the right along &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, the following expression would encounter an error:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;if i&amp;lt;2 then x[i=1] else x[i=i-1]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The error occurs when &amp;lt;code&amp;gt;x[i=i-1]&amp;lt;/code&amp;gt; is evaluated since the value corresponding to &amp;lt;code&amp;gt;i-1=0&amp;lt;/code&amp;gt; is out of range. The avoid the error, the expression can be rewritten as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;For j:=i do&lt;br /&gt;
::If j&amp;lt;2 then x[i=1] else x[i=j-1]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Out-of-range errors can also be avoided without using '''For''' by placing the conditional inside an argument. For example, the two examples above can be written without '''For''' as follows:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sqrt(if x&amp;lt;0 then 0 else x)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i=(if i&amp;lt;2 then 1 else i-1)]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Dimensionality reduction =====&lt;br /&gt;
'''For''' can be used to apply a function that requires an atom, one- or two- dimensional input to a multi-dimensional result. This usage is rare in Analytica since array abstraction normally does this automatically; however, the need occasionally arises in some circumstances.&lt;br /&gt;
&lt;br /&gt;
Suppose you have an array &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;, and you wish to apply a function &amp;lt;code&amp;gt;f(x)&amp;lt;/code&amp;gt; to each element of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; along &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;. In a conventional programming language, this would require a loop over the elements of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;; however, in almost all cases, Analytica’s array abstraction does this automatically — the expression is simply &amp;lt;code&amp;gt;f(A)&amp;lt;/code&amp;gt;, and the result remains indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;. However, there are a few cases where Analytica does not automatically array abstract, or it is possible to write a user-defined function that does not automatically array abstract (e.g., by declaring a parameter to be of type &amp;lt;code&amp;gt;Atom&amp;lt;/code&amp;gt;, as detailed in [[Parameter Qualifiers]]). For example, Analytica does not array abstract over functions such as [http://wiki.analytica.com/index.php?title=Sequence Sequence], [http://wiki.analytica.com/index.php?title=Split Split], [http://wiki.analytica.com/index.php?title=Subset Subset], or [http://wiki.analytica.com/index.php?title=Unique Unique], since these return un-indexed lists of varying lengths that are unknown until the function evaluates. Suppose we have the following variables defined (note that &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; is an array of text values):&lt;br /&gt;
&lt;br /&gt;
:A: Index_1 ▼&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &amp;lt;font color=&amp;quot;#FFFFFF&amp;quot;&amp;gt;1&amp;lt;/font&amp;gt;&lt;br /&gt;
!&lt;br /&gt;
|-&lt;br /&gt;
!1&lt;br /&gt;
|A, B, C&lt;br /&gt;
|-&lt;br /&gt;
!2&lt;br /&gt;
|D, E, F&lt;br /&gt;
|-&lt;br /&gt;
!3&lt;br /&gt;
|G, H, I&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:Index_1 ▼&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
We wish to split the text values in A and obtain a two dimensional array of letters indexed by Index_1 and Index_2. Since Split does not array abstract, we must do each row separately and re-index by Index_2 before the result rows are recombined into a single array. This is accomplished by the following loop:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FOR Row := Index_1 DO Array(Index_2, SplitText(A[Index_1=Row], ','))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This results in:&lt;br /&gt;
&lt;br /&gt;
:Index_1 ▼, Index_2 ▶&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 3&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
|A&lt;br /&gt;
|B &lt;br /&gt;
|C&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:100px;&amp;quot; |2&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |D&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |E&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |F&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:100px;&amp;quot; |3&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |G&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |H&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |I&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Reducing memory requirements===&lt;br /&gt;
&lt;br /&gt;
In some cases, it is possible to reduce the amount of memory required for intermediate results during the evaluation of expressions involving large arrays. For example, consider the following expression:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MatrixA:&amp;lt;/code&amp;gt; A two dimensional array indexed by M and N.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MatrixB:&amp;lt;/code&amp;gt; A two dimensional array indexed by N and P.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Average(MatrixA * MatrixB, N)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During the calculation, Analytica needs memory to compute &amp;lt;code&amp;gt;MatrixA * MatrixB&amp;lt;/code&amp;gt;, an array indexed by &amp;lt;code&amp;gt;M&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;. If these indexes have sizes 100, 200, and 300 respectively, then &amp;lt;code&amp;gt;MatrixA * MatrixB&amp;lt;/code&amp;gt; contains 6,000,000 numbers, requiring over 60 megabytes of memory at 10&lt;br /&gt;
bytes per number.&lt;br /&gt;
&lt;br /&gt;
To reduce the memory required, use the following expression instead:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;For L := M Do Average(MatrixA[M=L]*MatrixB, N)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each element &amp;lt;code&amp;gt;MatrixA[M=L]*MatrixB&amp;lt;/code&amp;gt; has dimensions &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, needing only 200x300x10= 600 kilobytes of memory at a time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tip title=&amp;quot;Tip&amp;quot;&amp;gt;For the special case of a [[Matrix_functions#Dot_product_of_two_matrices|dot product]], for an expression of the form &amp;lt;code&amp;gt;Sum(a*b, i)&amp;lt;/code&amp;gt;, it performs a similar transformation internally.&amp;lt;/tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===While(Test) Do Body===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; evaluates &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; repeatedly as long as &amp;lt;code&amp;gt;Test &amp;lt;&amp;gt; 0&amp;lt;/code&amp;gt;. For &amp;lt;code&amp;gt;While ...&amp;lt;/code&amp;gt; to terminate, &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; must produce a side-effect on a local variable that is used by &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt;, causing &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; eventually to equal &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. If &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; never becomes False, &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; continues to loop indefinitely. If you suspect that might be happening, type ''Control+. (Control+period)'' to interrupt execution.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; must evaluate to an atomic (non-array) value; therefore, it is a good idea to force any local variable used in &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; to be atomic valued. &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; is one of the few constructs in Analytica that does not generalize completely to handle arrays. But, there are ways to ensure that variables and functions using &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; support Intelligent Arrays and probabilistic evaluation. See “While and&lt;br /&gt;
array abstraction” on page 386 for details.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; returns the final value found in the last iteration of &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Null&amp;lt;/code&amp;gt; if no iterations occur. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;(Var x := 1; While x &amp;lt; 10 Do x := x+1) ¨ 10&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;(Var x := 1; While x &amp;gt; 10 Do x := x+1) ¨ Null&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; often follows the following pattern:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Var x[]:= ...;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;While (FunctionOf(x)) Do (&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;x := expr;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;);&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;returnValue&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Iterate (initial, expr, until, maxIter, ''warnFlag'') ==&lt;br /&gt;
Suppose the definition of variable x contains a call to [http://wiki.analytica.com/index.php?title=Iterate Iterate](). [http://wiki.analytica.com/index.php?title=Iterate Iterate]() initializes &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; to the value of &amp;lt;code&amp;gt;initial&amp;lt;/code&amp;gt;. While stopping condition until is False (zero), it evaluates expression expr, and assigns the result to x. Given the optional parameter &amp;lt;code&amp;gt;maxIter&amp;lt;/code&amp;gt;, it stops after &amp;lt;code&amp;gt;maxIter&amp;lt;/code&amp;gt; iterations and, if &amp;lt;code&amp;gt;warnFlag&amp;lt;/code&amp;gt; is True, issues a warning — unless it has already been stopped by &amp;lt;code&amp;gt;until&amp;lt;/code&amp;gt; becoming True. If &amp;lt;code&amp;gt;until&amp;lt;/code&amp;gt; is array-valued, it only stops when all elements of &amp;lt;code&amp;gt;until&amp;lt;/code&amp;gt; are True.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=Iterate Iterate]() is designed for convergence algorithms where an expression must be recomputed an unknown number of iterations. [http://wiki.analytica.com/index.php?title=Iterate Iterate] (like [http://wiki.analytica.com/index.php?title=Dynamic Dynamic]) must be the main expression in a definition — it cannot be nested within another expression. But it can, and usually does, contain nested expressions as some of its parameters. [http://wiki.analytica.com/index.php?title=Iterate Iterate]() (again like [http://wiki.analytica.com/index.php?title=Dynamic Dynamic]() and unlike other functions) can, and usually does, mention the variable x that it defines within the expressions for initial and until. These expressions can also refer to variables that depend on &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you use [http://wiki.analytica.com/index.php?title=Iterate Iterate]() in more than one node in your model, you should be careful that the two functions don’t interact adversely. In general, two nodes containing [http://wiki.analytica.com/index.php?title=Iterate Iterate]() should never be mutual ancestors of each other. Doing so makes the nesting order ambiguous and can result in inconsistent computations. Likewise, care must be taken to avoid similar ambiguities when using interacting [http://wiki.analytica.com/index.php?title=Iterate Iterate] and [http://wiki.analytica.com/index.php?title=Dynamic Dynamic] loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt; You can usually write convergence algorithms more cleanly using '''While'''. One difference is that '''While''' requires its stopping condition '''Test''' to be an atom, where [[Iterate]]() allows an array-valued stopping condition until. Nevertheless, it is usually better to use '''While''' because you want it to do an appropriate number of iterations for each element of '''until''', rather than continue until all its elements are '''True'''. But, with '''While''' you need to use one of the tricks described in “While and array abstraction” to ensure the expression fully supports array abstraction.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Intelligent_Arrays Intelligent Arrays]&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Local Variables / {{PAGENAME}} / Recursion&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=For_and_While_Loops&amp;diff=38816</id>
		<title>For and While Loops</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=For_and_While_Loops&amp;diff=38816"/>
		<updated>2015-12-29T03:35:11Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== For i := a Do expr ==&lt;br /&gt;
&lt;br /&gt;
The '''For''' loop successively assigns the next atom from array &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; to local index &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, and evaluates expression &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; might refer to &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, for xample to slice out a particular element of an array. &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; might be a list of values defined by &amp;lt;code&amp;gt;m..n&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Sequence(m, n, dx)&amp;lt;/code&amp;gt; or it might be a multidimensional array. Normally, it evaluates the body &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; once for each atom in &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The result of the '''For '''loop is an array with all the indexes of &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; containing the values of each evaluation of &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt;. If any or all evaluations of &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; have any additional index(es), they are also indexes of the result.&lt;br /&gt;
&lt;br /&gt;
Usually, the Intelligent Array features take care of iterating over indexes of arrays without the need for explicit looping. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;gt; Analytica’s Intelligent Array features means that you rarely need explicit iteration using '''For''' loops to repeat operations over each dimensions of an array, often used in conventional computer language. If you find yourself using '''For''' loops a lot in Analytica, this might be a sign that you are not using '''Intelligent Arrays''' effectively. If so, please (re)read the sections on [[Intelligent_Arrays|Intelligent Arrays]].&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A '''For''' loop is sometimes useful in these specialized cases:&lt;br /&gt;
&lt;br /&gt;
* To avoid selected evaluations of &amp;lt;code&amp;gt;expr&amp;lt;/code&amp;gt; that might be invalid or out of range, and can be prevented by nesting an &amp;lt;code&amp;gt;If-Then-Else&amp;lt;/code&amp;gt; inside a '''For'''.&lt;br /&gt;
* To apply an Analytica function that requires an atom or one- or two-dimensional array input to a higher-dimensioned array.&lt;br /&gt;
* To reduce the memory needed f or calculations with very large arrays by reducing the memory requirement for intermediate results.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See below for an example of each of these three cases.&lt;br /&gt;
&lt;br /&gt;
==== Library  ====&lt;br /&gt;
Special&lt;br /&gt;
&lt;br /&gt;
====Avoiding out-of-range errors====&lt;br /&gt;
&lt;br /&gt;
Consider the following expression:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;If x&amp;lt;0 Then 0 Else Sqrt(x)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;If-Then-Else&amp;lt;/code&amp;gt; is included in this expression to avoid the warning “Square root of a negative number.” However, if &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is an array of values, this expression cannot avoid the warning since [http://wiki.analytica.com/index.php?title=Sqrt Sqrt](x) is evaluated before &amp;lt;code&amp;gt;If-Then-Else&amp;lt;/code&amp;gt; selects which elements of [http://wiki.analytica.com/index.php?title=Sqrt Sqrt](x) to include. To avoid the warning (assuming &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; is indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;), the expression can be rewritten as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;For j:=I do&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;If x[i=j]&amp;lt;0 then 0 else Sqrt(x[i=j])&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or as (see next section):&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Using y:=x in i do&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;If y&amp;lt;0 Then 0 else Sqrt(y)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Situations like this can often occur during slicing operations. For example, to shift &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; one position to the right along &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, the following expression would encounter an error:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;if i&amp;lt;2 then x[i=1] else x[i=i-1]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The error occurs when &amp;lt;code&amp;gt;x[i=i-1]&amp;lt;/code&amp;gt; is evaluated since the value corresponding to &amp;lt;code&amp;gt;i-1=0&amp;lt;/code&amp;gt; is out of range. The avoid the error, the expression can be rewritten as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;For j:=i do&lt;br /&gt;
::If j&amp;lt;2 then x[i=1] else x[i=j-1]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Out-of-range errors can also be avoided without using '''For''' by placing the conditional inside an argument. For example, the two examples above can be written without '''For''' as follows:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sqrt(if x&amp;lt;0 then 0 else x)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i=(if i&amp;lt;2 then 1 else i-1)]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Dimensionality reduction =====&lt;br /&gt;
'''For''' can be used to apply a function that requires an atom, one- or two- dimensional input to a multi-dimensional result. This usage is rare in Analytica since array abstraction normally does this automatically; however, the need occasionally arises in some circumstances.&lt;br /&gt;
&lt;br /&gt;
Suppose you have an array &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; indexed by &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;, and you wish to apply a function &amp;lt;code&amp;gt;f(x)&amp;lt;/code&amp;gt; to each element of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; along &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;. In a conventional programming language, this would require a loop over the elements of &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;; however, in almost all cases, Analytica’s array abstraction does this automatically — the expression is simply &amp;lt;code&amp;gt;f(A)&amp;lt;/code&amp;gt;, and the result remains indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;. However, there are a few cases where Analytica does not automatically array abstract, or it is possible to write a user-defined function that does not automatically array abstract (e.g., by declaring a parameter to be of type &amp;lt;code&amp;gt;Atom&amp;lt;/code&amp;gt;, as detailed in [[Parameter Qualifiers]]). For example, Analytica does not array abstract over functions such as [http://wiki.analytica.com/index.php?title=Sequence Sequence], [http://wiki.analytica.com/index.php?title=Split Split], [http://wiki.analytica.com/index.php?title=Subset Subset], or [http://wiki.analytica.com/index.php?title=Unique Unique], since these return un-indexed lists of varying lengths that are unknown until the function evaluates. Suppose we have the following variables defined (note that &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; is an array of text values):&lt;br /&gt;
&lt;br /&gt;
:A: Index_1 ▼&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &amp;lt;font color=&amp;quot;#FFFFFF&amp;quot;&amp;gt;1&amp;lt;/font&amp;gt;&lt;br /&gt;
!&lt;br /&gt;
|-&lt;br /&gt;
!1&lt;br /&gt;
|A, B, C&lt;br /&gt;
|-&lt;br /&gt;
!2&lt;br /&gt;
|D, E, F&lt;br /&gt;
|-&lt;br /&gt;
!3&lt;br /&gt;
|G, H, I&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:Index_1 ▼&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
We wish to split the text values in A and obtain a two dimensional array of letters indexed by Index_1 and Index_2. Since Split does not array abstract, we must do each row separately and re-index by Index_2 before the result rows are recombined into a single array. This is accomplished by the following loop:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;FOR Row := Index_1 DO Array(Index_2, SplitText(A[Index_1=Row], ','))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This results in:&lt;br /&gt;
&lt;br /&gt;
:Index_1 ▼, Index_2 ▶&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 3&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
|A&lt;br /&gt;
|B &lt;br /&gt;
|C&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:100px;&amp;quot; |2&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |D&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |E&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |F&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:100px;&amp;quot; |3&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |G&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |H&lt;br /&gt;
|style=&amp;quot;width:100px;&amp;quot; |I&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Reducing memory requirements===&lt;br /&gt;
&lt;br /&gt;
In some cases, it is possible to reduce the amount of memory required for intermediate results during the evaluation of expressions involving large arrays. For example, consider the following expression:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MatrixA:&amp;lt;/code&amp;gt; A two dimensional array indexed by M and N.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MatrixB:&amp;lt;/code&amp;gt; A two dimensional array indexed by N and P.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Average(MatrixA * MatrixB, N)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During the calculation, Analytica needs memory to compute &amp;lt;code&amp;gt;MatrixA * MatrixB&amp;lt;/code&amp;gt;, an array indexed by &amp;lt;code&amp;gt;M&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;. If these indexes have sizes 100, 200, and 300 respectively, then &amp;lt;code&amp;gt;MatrixA * MatrixB&amp;lt;/code&amp;gt; contains 6,000,000 numbers, requiring over 60 megabytes of memory at 10&lt;br /&gt;
bytes per number.&lt;br /&gt;
&lt;br /&gt;
To reduce the memory required, use the following expression instead:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;For L := M Do Average(MatrixA[M=L]*MatrixB, N)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each element &amp;lt;code&amp;gt;MatrixA[M=L]*MatrixB&amp;lt;/code&amp;gt; has dimensions &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, needing only 200x300x10= 600 kilobytes of memory at a time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tip title=&amp;quot;Tip&amp;quot;&amp;gt;For the special case of a [[Matrix_functions#Dot_product_of_two_matrices|dot product]], for an expression of the form &amp;lt;code&amp;gt;Sum(a*b, i)&amp;lt;/code&amp;gt;, it performs a similar transformation internally.&amp;lt;/tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===While(Test) Do Body===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; evaluates &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; repeatedly as long as &amp;lt;code&amp;gt;Test &amp;lt;&amp;gt; 0&amp;lt;/code&amp;gt;. For &amp;lt;code&amp;gt;While ...&amp;lt;/code&amp;gt; to terminate, &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; must produce a side-effect on a local variable that is used by &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt;, causing &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; eventually to equal &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. If &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; never becomes False, &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; continues to loop indefinitely. If you suspect that might be happening, type ''Control+. (Control+period)'' to interrupt execution.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; must evaluate to an atomic (non-array) value; therefore, it is a good idea to force any local variable used in &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; to be atomic valued. &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; is one of the few constructs in Analytica that does not generalize completely to handle arrays. But, there are ways to ensure that variables and functions using &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; support Intelligent Arrays and probabilistic evaluation. See “While and&lt;br /&gt;
array abstraction” on page 386 for details.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; returns the final value found in the last iteration of &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Null&amp;lt;/code&amp;gt; if no iterations occur. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;(Var x := 1; While x &amp;lt; 10 Do x := x+1) ¨ 10&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;(Var x := 1; While x &amp;gt; 10 Do x := x+1) ¨ Null&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;code&amp;gt;While&amp;lt;/code&amp;gt; often follows the following pattern:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Var x[]:= ...;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;While (FunctionOf(x)) Do (&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;x := expr;&amp;lt;/code&amp;gt;&lt;br /&gt;
::&amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;);&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;returnValue&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Iterate (initial, expr, until, maxIter, ''warnFlag'') ==&lt;br /&gt;
Suppose the definition of variable x contains a call to [http://wiki.analytica.com/index.php?title=Iterate Iterate](). [http://wiki.analytica.com/index.php?title=Iterate Iterate]() initializes &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; to the value of &amp;lt;code&amp;gt;initial&amp;lt;/code&amp;gt;. While stopping condition until is False (zero), it evaluates expression expr, and assigns the result to x. Given the optional parameter &amp;lt;code&amp;gt;maxIter&amp;lt;/code&amp;gt;, it stops after &amp;lt;code&amp;gt;maxIter&amp;lt;/code&amp;gt; iterations and, if &amp;lt;code&amp;gt;warnFlag&amp;lt;/code&amp;gt; is True, issues a warning — unless it has already been stopped by &amp;lt;code&amp;gt;until&amp;lt;/code&amp;gt; becoming True. If &amp;lt;code&amp;gt;until&amp;lt;/code&amp;gt; is array-valued, it only stops when all elements of &amp;lt;code&amp;gt;until&amp;lt;/code&amp;gt; are True.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=Iterate Iterate]() is designed for convergence algorithms where an expression must be recomputed an unknown number of iterations. [http://wiki.analytica.com/index.php?title=Iterate Iterate] (like [http://wiki.analytica.com/index.php?title=Dynamic Dynamic]) must be the main expression in a definition — it cannot be nested within another expression. But it can, and usually does, contain nested expressions as some of its parameters. [http://wiki.analytica.com/index.php?title=Iterate Iterate]() (again like [http://wiki.analytica.com/index.php?title=Dynamic Dynamic]() and unlike other functions) can, and usually does, mention the variable x that it defines within the expressions for initial and until. These expressions can also refer to variables that depend on &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you use [http://wiki.analytica.com/index.php?title=Iterate Iterate]() in more than one node in your model, you should be careful that the two functions don’t interact adversely. In general, two nodes containing [http://wiki.analytica.com/index.php?title=Iterate Iterate]() should never be mutual ancestors of each other. Doing so makes the nesting order ambiguous and can result in inconsistent computations. Likewise, care must be taken to avoid similar ambiguities when using interacting [http://wiki.analytica.com/index.php?title=Iterate Iterate] and [http://wiki.analytica.com/index.php?title=Dynamic Dynamic] loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;quot;&amp;gt; You can usually write convergence algorithms more cleanly using '''While'''. One difference is that '''While''' requires its stopping condition '''Test''' to be an atom, where [[Iterate]]() allows an array-valued stopping condition until. Nevertheless, it is usually better to use '''While''' because you want it to do an appropriate number of iterations for each element of '''until''', rather than continue until all its elements are '''True'''. But, with '''While''' you need to use one of the tricks described in “While and array abstraction” to ensure the expression fully supports array abstraction.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[http://wiki.analytica.com/index.php?title=Intelligent_Arrays Intelligent Arrays]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Local Variables / {{PAGENAME}} / Recursion&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Local_Values&amp;diff=38815</id>
		<title>Local Values</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Local_Values&amp;diff=38815"/>
		<updated>2015-12-29T03:34:10Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Defining a local variable: Var v := e   ===&lt;br /&gt;
This construct creates a local variable &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; and initializes it with the value from evaluating expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;. You can then use &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; in subsequent expressions within this context — that is, in following expressions in this group, or nested within expressions in this group. You cannot refer to a local variable outside its context — for example, in the definition of another variable or function.&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; has the same identifier (name) as a global variable, any subsequent mention of &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; in this context refers to the just-defined local variable, not the global.&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
Instead of defining a variable as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sum(Array_a*Array_b, N)/(1 + Sum(Array_a*Array_b, N))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Define it as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR t := Sum(Array_a*Array*b, N); t/(1 + t)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compute a correlation between &amp;lt;code&amp;gt;Xdata&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Ydata&amp;lt;/code&amp;gt;, instead of:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sum((Xdata - Sum(Xdata, Data_index)/Nopts)*(Ydata-&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Sum(Ydata, Data_index)/Nopts), Data_index)/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Sqrt(Sum((Xdata-Sum(Xdata, Data_index)/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Nopts)^2, Data_index) * Sum((Ydata -&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Sum(Ydata, Data_index)/Nopts)^2, Data_index))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Define the correlation as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR mx := Sum(Xdata, Data_index)/Nopts;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR my := Sum(Ydata, Data_index)/Nopts;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR dx := Xdata - mx;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR dy := Ydata - my;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sum(dx*dy, Data_index)/Sqrt(Sum(dx^2, Data_index)*Sum(dy^2, Data_index))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The latter expression is faster to execute and easier to read. The correlation expression in this example is an alternative to Analytica’s built-in [http://wiki.analytica.com/index.php?title=Correlation Correlation]() function when data is dimensioned by an index other than the system index '''&amp;lt;code&amp;gt;Run&amp;lt;/code&amp;gt;'''.&lt;br /&gt;
&lt;br /&gt;
=== Assigning to a local variable:   v := e ===&lt;br /&gt;
The&amp;lt;code&amp;gt; :=&amp;lt;/code&amp;gt; (assignment operator) sets the local variable &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; to the value of expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The assignment expression also returns the value of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;, although it is usually the effect of the assignment that is of primary interest.&lt;br /&gt;
&lt;br /&gt;
The equal sign &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt; does not do assignment. It tests for equality between two values.&lt;br /&gt;
&lt;br /&gt;
Within the definition of a function, you can also assign a new value to any parameter. This only changes the parameter and does not affect any global variables used as actual parameters in the call to the function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;gt;Usually, '''''you cannot assign to a global variable''''' — that is, to a variable created as a diagram node. You can assign only to a local variable, declared in this definition using '''''Var''''' or '''''Index''''', in the current context — that is, at the same or enclosing level in this definition. In a function definition, you can also assign to a parameter.This prevents '''''side effects''''' — i.e., where evaluating a global variable or function changes a global variable, other than one that mentions this variable or function in its definition. Analytica’s lack of side effects makes models much easier to write, understand, and debug than normal computer languages that allow side effects. You can tell how a variable is computed just by looking at its definition, without having to worry about parts of the model not mentioned in the definition. There are a few exceptions to this rule of no assignments to globals: You can assign to globals in button scripts or functions called from button scripts. See [[Button_creation|Button Creation]] for details. You can also assign to a global variable '''V''' from the definition of '''X''' when '''V''' is defined as '''ComputedBy(X)'''.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://wiki.analytica.com/index.php?title=ComputedBy ComputedBy](x) ===&lt;br /&gt;
&lt;br /&gt;
This function indicates that the value of a variable is computed as a side-effect of another variable, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;. Suppose &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; is defined as &amp;lt;code&amp;gt;[http://wiki.analytica.com/index.php?title=ComputedBy ComputedBy](x)&amp;lt;/code&amp;gt;, and the value of &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; needs to be computed, then Analytica will evaluate &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;. During the evaluation of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; must set the value of &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; using an assignment operator. &lt;br /&gt;
&lt;br /&gt;
Even though &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; is a side-effect of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, its definition is still referentially transparent, which means that its definition completely describes its computed value. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[http://wiki.analytica.com/index.php?title=ComputedBy ComputedBy]&amp;lt;/code&amp;gt; is useful when multiple items are computed simultaneously within an expression. It is particularly useful from within an [[Iterate]]() function when several variables need to be updated in each iteration. &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable rot := ... { a 2-D rotation matrix indexed by Dim and Dim2 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable X_rot := ComputedBy(Y_rot)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Y_rot :=&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;BEGIN&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Var v := Array(Dim, [X, Y]);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Var v_r := sum(rot*v, Dim);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;X_rot := v_r[Dim2 = 'x'];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;v_r[Dim2 = 'y'];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;END&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Assigning to a slice of a local variable===&lt;br /&gt;
&lt;br /&gt;
'''''Slice assignment''''' means assigning a value into an element or slice of an array contained by a local variable, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i = n] := e&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; must be a local variable, &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; is an index (local or global), &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; evaluates to be a value or values of &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; is any expression. If &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; was not array or was an array not indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, the slice assignment adds i as a dimension of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;. The result returned from the assignment operator is the value &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;, not the full value of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, which can be a source of confusion but is that way so you can chain assignments, e.g.:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i = 3] := x[i =  5] := 7&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can write some algorithms much more easily and efficiently using slice assignment. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function Fibonacci_series(f1, f2, n: Number Atom) :=&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;INDEX m := 1..n;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;VAR result := 0;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;result[m = 1] := f1;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;result[m = 2] := f2;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;FOR I := 3..n DO result[m = i] := result[m = i -1] + result[m = i - 2];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;result&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the first slice assignment:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;result[m = 1] := f1;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;result&amp;lt;/code&amp;gt; was not previously indexed by &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;. So the assignment adds the index &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; to result, making it into an array with value &amp;lt;code&amp;gt;f1 for m = 1&amp;lt;/code&amp;gt; and its original value, 0, for all other values of &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
More generally, in a slice assignment:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i = n] := e&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; was already indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, it sets &amp;lt;code&amp;gt;x[i=n]&amp;lt;/code&amp;gt; to the value of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;. All other slices of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; over &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; retain their previous values. If &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; was indexed by other indexes, say &amp;lt;code&amp;gt;j&amp;lt;/code&amp;gt;, the result is indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;j&amp;lt;/code&amp;gt;. The assigned slice &amp;lt;code&amp;gt;x[i = n]&amp;lt;/code&amp;gt; has the value &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; for all values of the other index(es) &amp;lt;code&amp;gt;j&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can index by position as well as name in a slice assignment, for example: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[@i = 2] := e&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This assigns the value of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; as the second slice of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; over index &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To set a cell in a multi-dimensional array, include multiple subscript coordinates, e.g.:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i = 2, j = 5, k = 3] := 7&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Slice assignment array abstracts when &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; have extra dimensions, and the abstraction is coordinated when an index is shared by &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;. Using abstraction, it is possible to assign to many cells in a single assignment operation.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Var..Do Var..Do]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Begin-End for Grouping Expressions / {{PAGENAME}} / For and While Loops&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Local_Values&amp;diff=38814</id>
		<title>Local Values</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Local_Values&amp;diff=38814"/>
		<updated>2015-12-29T03:33:44Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Defining a local variable: Var v := e   ===&lt;br /&gt;
This construct creates a local variable &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; and initializes it with the value from evaluating expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;. You can then use &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; in subsequent expressions within this context — that is, in following expressions in this group, or nested within expressions in this group. You cannot refer to a local variable outside its context — for example, in the definition of another variable or function.&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; has the same identifier (name) as a global variable, any subsequent mention of &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; in this context refers to the just-defined local variable, not the global.&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
Instead of defining a variable as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sum(Array_a*Array_b, N)/(1 + Sum(Array_a*Array_b, N))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Define it as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR t := Sum(Array_a*Array*b, N); t/(1 + t)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compute a correlation between &amp;lt;code&amp;gt;Xdata&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Ydata&amp;lt;/code&amp;gt;, instead of:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sum((Xdata - Sum(Xdata, Data_index)/Nopts)*(Ydata-&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Sum(Ydata, Data_index)/Nopts), Data_index)/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Sqrt(Sum((Xdata-Sum(Xdata, Data_index)/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Nopts)^2, Data_index) * Sum((Ydata -&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Sum(Ydata, Data_index)/Nopts)^2, Data_index))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Define the correlation as:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR mx := Sum(Xdata, Data_index)/Nopts;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR my := Sum(Ydata, Data_index)/Nopts;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR dx := Xdata - mx;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;VAR dy := Ydata - my;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Sum(dx*dy, Data_index)/Sqrt(Sum(dx^2, Data_index)*Sum(dy^2, Data_index))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The latter expression is faster to execute and easier to read. The correlation expression in this example is an alternative to Analytica’s built-in [http://wiki.analytica.com/index.php?title=Correlation Correlation]() function when data is dimensioned by an index other than the system index '''&amp;lt;code&amp;gt;Run&amp;lt;/code&amp;gt;'''.&lt;br /&gt;
&lt;br /&gt;
=== Assigning to a local variable:   v := e ===&lt;br /&gt;
The&amp;lt;code&amp;gt; :=&amp;lt;/code&amp;gt; (assignment operator) sets the local variable &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; to the value of expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The assignment expression also returns the value of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;, although it is usually the effect of the assignment that is of primary interest.&lt;br /&gt;
&lt;br /&gt;
The equal sign &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt; does not do assignment. It tests for equality between two values.&lt;br /&gt;
&lt;br /&gt;
Within the definition of a function, you can also assign a new value to any parameter. This only changes the parameter and does not affect any global variables used as actual parameters in the call to the function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Tip Title=&amp;quot;Tip&amp;gt;Usually, '''''you cannot assign to a global variable''''' — that is, to a variable created as a diagram node. You can assign only to a local variable, declared in this definition using '''''Var''''' or '''''Index''''', in the current context — that is, at the same or enclosing level in this definition. In a function definition, you can also assign to a parameter.This prevents '''''side effects''''' — i.e., where evaluating a global variable or function changes a global variable, other than one that mentions this variable or function in its definition. Analytica’s lack of side effects makes models much easier to write, understand, and debug than normal computer languages that allow side effects. You can tell how a variable is computed just by looking at its definition, without having to worry about parts of the model not mentioned in the definition. There are a few exceptions to this rule of no assignments to globals: You can assign to globals in button scripts or functions called from button scripts. See [[Button_creation|Button Creation]] for details. You can also assign to a global variable '''V''' from the definition of '''X''' when '''V''' is defined as '''ComputedBy(X)'''.&amp;lt;/Tip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://wiki.analytica.com/index.php?title=ComputedBy ComputedBy](x) ===&lt;br /&gt;
&lt;br /&gt;
This function indicates that the value of a variable is computed as a side-effect of another variable, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;. Suppose &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; is defined as &amp;lt;code&amp;gt;[http://wiki.analytica.com/index.php?title=ComputedBy ComputedBy](x)&amp;lt;/code&amp;gt;, and the value of &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; needs to be computed, then Analytica will evaluate &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;. During the evaluation of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; must set the value of &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; using an assignment operator. &lt;br /&gt;
&lt;br /&gt;
Even though &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; is a side-effect of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, its definition is still referentially transparent, which means that its definition completely describes its computed value. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[http://wiki.analytica.com/index.php?title=ComputedBy ComputedBy]&amp;lt;/code&amp;gt; is useful when multiple items are computed simultaneously within an expression. It is particularly useful from within an [[Iterate]]() function when several variables need to be updated in each iteration. &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable rot := ... { a 2-D rotation matrix indexed by Dim and Dim2 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable X_rot := ComputedBy(Y_rot)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Variable Y_rot :=&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;BEGIN&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Var v := Array(Dim, [X, Y]);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;Var v_r := sum(rot*v, Dim);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;X_rot := v_r[Dim2 = 'x'];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;v_r[Dim2 = 'y'];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;END&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Assigning to a slice of a local variable===&lt;br /&gt;
&lt;br /&gt;
'''''Slice assignment''''' means assigning a value into an element or slice of an array contained by a local variable, for example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i = n] := e&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; must be a local variable, &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; is an index (local or global), &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; evaluates to be a value or values of &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; is any expression. If &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; was not array or was an array not indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, the slice assignment adds i as a dimension of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;. The result returned from the assignment operator is the value &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;, not the full value of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, which can be a source of confusion but is that way so you can chain assignments, e.g.:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i = 3] := x[i =  5] := 7&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can write some algorithms much more easily and efficiently using slice assignment. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;Function Fibonacci_series(f1, f2, n: Number Atom) :=&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;INDEX m := 1..n;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;VAR result := 0;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;result[m = 1] := f1;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;result[m = 2] := f2;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;FOR I := 3..n DO result[m = i] := result[m = i -1] + result[m = i - 2];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;code&amp;gt;result&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the first slice assignment:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;result[m = 1] := f1;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;result&amp;lt;/code&amp;gt; was not previously indexed by &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;. So the assignment adds the index &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; to result, making it into an array with value &amp;lt;code&amp;gt;f1 for m = 1&amp;lt;/code&amp;gt; and its original value, 0, for all other values of &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
More generally, in a slice assignment:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i = n] := e&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; was already indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;, it sets &amp;lt;code&amp;gt;x[i=n]&amp;lt;/code&amp;gt; to the value of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;. All other slices of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; over &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; retain their previous values. If &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; was indexed by other indexes, say &amp;lt;code&amp;gt;j&amp;lt;/code&amp;gt;, the result is indexed by &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;j&amp;lt;/code&amp;gt;. The assigned slice &amp;lt;code&amp;gt;x[i = n]&amp;lt;/code&amp;gt; has the value &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; for all values of the other index(es) &amp;lt;code&amp;gt;j&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can index by position as well as name in a slice assignment, for example: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[@i = 2] := e&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This assigns the value of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; as the second slice of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; over index &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To set a cell in a multi-dimensional array, include multiple subscript coordinates, e.g.:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;x[i = 2, j = 5, k = 3] := 7&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Slice assignment array abstracts when &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; have extra dimensions, and the abstraction is coordinated when an index is shared by &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;. Using abstraction, it is possible to assign to many cells in a single assignment operation.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Var..Do Var..Do]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Begin-End for Grouping Expressions / {{PAGENAME}} / For and While Loops&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Begin-End_for_Grouping_Expressions&amp;diff=38813</id>
		<title>Begin-End for Grouping Expressions</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Begin-End_for_Grouping_Expressions&amp;diff=38813"/>
		<updated>2015-12-29T03:32:47Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As illustrated above, you can group several expressions (statements) as the definition of a variable or function simply by separating them by semicolons (&amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;). To group several expressions as a condition or action of &amp;lt;code&amp;gt;If a Then b Else c&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;While a Do b&amp;lt;/code&amp;gt;, or, indeed, anywhere a single expression&lt;br /&gt;
is valid, you should enclose the expressions between &amp;lt;code&amp;gt;Begin&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;End&amp;lt;/code&amp;gt;, or between parentheses characters &amp;lt;code&amp;gt;(&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The overall value of the group of statements is the value from evaluating the last expression. For example: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;(VAR x := 10; x := x/2; x - 2) → 3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Analytica also tolerates a semicolon (&amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;) after the last expression in a group. It still returns the value of the last expression. For example:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;(VAR x := 10; x := x/2; x/2;) → 2.5&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The statements can be grouped on one line, or over several lines. In fact, Analytica does not care where new-lines, spaces, or tabs occur within an expression or sequence of expressions — as long as they are not within a number or identifier.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Summary of Programming Constructs / {{PAGENAME}} / Local Variables&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Summary_of_Programming_Constructs&amp;diff=38812</id>
		<title>Summary of Programming Constructs</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Summary_of_Programming_Constructs&amp;diff=38812"/>
		<updated>2015-12-29T03:32:21Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please see the table below for a list of Analytica programming constructs, their meanings, and links to references with more details, if available.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! '''Construct'''&lt;br /&gt;
! '''Meaning:'''&lt;br /&gt;
! '''For more, see'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;e1; e2; … ei&amp;lt;/code&amp;gt;&lt;br /&gt;
| Semicolons join a group of expressions to be evaluated in sequence&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=Begin-End_for_Grouping_Expressions Begin-End for Grouping Expressions]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;BEGIN e1; e2; …&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ei END&amp;lt;/code&amp;gt;&lt;br /&gt;
| A group of expressions to be evaluated in sequence&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=Begin-End_for_Grouping_Expressions Begin-End for Grouping Expressions]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;(e1; e2; … ei)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Another way to group expressions&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=Begin-End_for_Grouping_Expressions Begin-End for Grouping Expressions]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;m .. n&amp;lt;/code&amp;gt;&lt;br /&gt;
| Generates a list of successive integers from &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=Ensuring_Array_Abstraction#Functions_Expecting_Atomic_Parameters Functions Expecting Atomic Parameters]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Var x := e&amp;lt;/code&amp;gt;&lt;br /&gt;
| Define local variable &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and assign initial value &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=Local_Variables#Defining_a_local_variable Defining a Local Variable]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Index i := e&amp;lt;/code&amp;gt;&lt;br /&gt;
| Define local index &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; and assign initial value &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=Local_Indexes Local Indexes]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;x := e&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assigns value from evaluating &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; to local variable &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;.&lt;br /&gt;
Returns value &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;.&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=Local_Variables#Assigning_to_a_local_variable: Assigning to a Local Variable]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;While Test &amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;Do Body&amp;lt;/code&amp;gt;&lt;br /&gt;
| While &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; is True, evaluate &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt; and repeat. &lt;br /&gt;
Returns last value of &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt;.&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=For_and_While_Loops#While.28Test.29_Do_Body While(Test) Do Body]&lt;br /&gt;
|-&lt;br /&gt;
| { comments }&lt;br /&gt;
/* comments */&lt;br /&gt;
| Curly brackets { } and /* */ are alternative ways to enclose comments to be ignored by the parser.&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=Procedural_Programming_Example Procedural Programming Example]&lt;br /&gt;
|-&lt;br /&gt;
| 'text'&lt;br /&gt;
&amp;quot;text&amp;quot;&lt;br /&gt;
| You can use single or double quotes to enclose a literal text value, but they must match.&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=Text_values Text Values]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;For x := a DO e&amp;lt;/code&amp;gt;&lt;br /&gt;
| Assigns to loop variable &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, successive atoms from array &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; and repeats evaluation expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; for each value of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;.&lt;br /&gt;
Returns an array of values of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; with the same indexes as &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;.&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=For_and_While_Loops#For_i_:.3D_a_Do_expr For i := a Do expr]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;For x[i, j…] := a DO e&amp;lt;/code&amp;gt;&lt;br /&gt;
| Same, but it assigns to x successive sub-arrays of &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, each indexed by the indices, &amp;lt;code&amp;gt;[i, j …&amp;lt;/code&amp;gt;&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=For_and_While_Loops#For_i_:.3D_a_Do_expr For i := a Do expr]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;\ e&amp;lt;/code&amp;gt;&lt;br /&gt;
| Creates a reference to the value of expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;.&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=References_and_Data_Structures References and Data Structures]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;\ [i, j …] e&amp;lt;/code&amp;gt;&lt;br /&gt;
| Creates an array indexed by any indexes of &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; other than &amp;lt;code&amp;gt;i, j …&amp;lt;/code&amp;gt; of references to sub-arrays of e each indexed by &amp;lt;code&amp;gt;i, j ….&amp;lt;/code&amp;gt;&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=References_and_Data_Structures References and Data Structures]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;# r&amp;lt;/code&amp;gt;&lt;br /&gt;
| Returns the value referred to by reference &amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt;.&lt;br /&gt;
|[http://wiki.analytica.com/index.php?title=References_and_Data_Structures References and Data Structures]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Procedural Programming Example / {{PAGENAME}} / Begin-End for Grouping Expressions&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Procedural_Programming_Example&amp;diff=38811</id>
		<title>Procedural Programming Example</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Procedural_Programming_Example&amp;diff=38811"/>
		<updated>2015-12-29T03:31:48Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; Procedural Programming &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following function, &amp;lt;code&amp;gt;Factors()&amp;lt;/code&amp;gt;, computes the prime factors of an integer x. It illustrates many of the key constructs of procedural programming.&lt;br /&gt;
&lt;br /&gt;
::[[File:example1.png|400px]]&lt;br /&gt;
&lt;br /&gt;
See below for an explanation of each of these constructs, and cross references to where they are.&lt;br /&gt;
&lt;br /&gt;
::{| border=&amp;quot;0;&amp;quot; style=&amp;quot;width:400px;&amp;quot;&lt;br /&gt;
! '''Numbers identify&amp;lt;br /&amp;gt;&lt;br /&gt;
features below'''&lt;br /&gt;
! '''Function Factors(x)&amp;lt;br /&amp;gt;&lt;br /&gt;
Definition:'''&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &amp;lt;code&amp;gt;VAR result := [1];&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| &amp;lt;code&amp;gt;VAR n := 2;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
|&amp;lt;code&amp;gt;WHILE n &amp;lt;= x DO&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
|&amp;lt;code&amp;gt;BEGIN&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| &amp;lt;code&amp;gt;VAR r := Floor(x/n);&amp;lt;/code&amp;gt; &lt;br /&gt;
&amp;lt;code&amp;gt;IF r*n = x THEN&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
|&amp;lt;code&amp;gt;(result := Concat(result, [n]);&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| &amp;lt;code&amp;gt;x := r)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ELSE n := n + 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 4,7&lt;br /&gt;
|&amp;lt;code&amp;gt;END; /* End While loop */&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 7, 8&lt;br /&gt;
|&amp;lt;code&amp;gt;result /* End Definition */&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This definition illustrates these features:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;VAR x := e&amp;lt;/code&amp;gt; construct defines a local variable x, and sets an initial value e. See [http://wiki.analytica.com/index.php?title=Local_Variables#Defining_a_local_variable Defining a Local Variable].&lt;br /&gt;
# You can group several expressions (statements) into a definition by separating them using “;” (semicolons). Expressions can be on the same line or successive lines. See [http://wiki.analytica.com/index.php?title=Begin-End_for_Grouping_Expressions Begin-End for Grouping Expressions].&lt;br /&gt;
# &amp;lt;code&amp;gt;While test Do body&amp;lt;/code&amp;gt; construct tests condition &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt;, and, if True, evaluates &amp;lt;code&amp;gt;Body&amp;lt;/code&amp;gt;, and repeats until condition &amp;lt;code&amp;gt;Test&amp;lt;/code&amp;gt; is False. See [http://wiki.analytica.com/index.php?title=For_and_While_Loops#While.28Test.29_Do_Body While(Test) Do Body].&lt;br /&gt;
# Begin &amp;lt;code&amp;gt;e1; e2; … End&amp;lt;/code&amp;gt; groups several expressions separated by semicolons “;” — in this case as the body of a While loop. See “Begin-End, (), and “;” for grouping expressions” on page 376.&lt;br /&gt;
#  &amp;lt;code&amp;gt;(e1; e2; …)&amp;lt;/code&amp;gt; is another way to group expressions — in this case, as the action to be taken in the Then case. See [http://wiki.analytica.com/index.php?title=Begin-End_for_Grouping_Expressions Begin-End for Grouping Expressions].&lt;br /&gt;
#  &amp;lt;code&amp;gt;x := e&amp;lt;/code&amp;gt; lets you assign the value of an expression &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; to a local variable &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; or, as in the first case, to a parameter of a function. See [http://wiki.analytica.com/index.php?title=Local_Variables#Assigning_to_a_local_variable: Assigning to a local variable].&lt;br /&gt;
#  A comment is enclosed between /* and */ as an alternative to { and }.&lt;br /&gt;
#  A group of expressions returns the value of the last expression — here the function &amp;lt;code&amp;gt;Factors&amp;lt;/code&amp;gt; returns the value of &amp;lt;code&amp;gt;result&amp;lt;/code&amp;gt; — whether the group is delimited by Begin and End, by parentheses marks ( and ), or, as here, by nothing.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Procedural Programming / {{PAGENAME}} / Summary of Programming Constructs&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=Procedural_Programming&amp;diff=38810</id>
		<title>Procedural Programming</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=Procedural_Programming&amp;diff=38810"/>
		<updated>2015-12-29T03:31:06Z</updated>

		<summary type="html">&lt;p&gt;Jhernandez3: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Analytica User Guide]]&lt;br /&gt;
&amp;lt;breadcrumbs&amp;gt; Analytica User Guide &amp;gt; {{PAGENAME}}&amp;lt;/breadcrumbs&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A '''procedural program''' is a list of instructions to a computer. Each instruction tells the computer what to do, or it might change the sequence to execute the instructions. Most Analytica models are '''''non-procedural''''' — that is, they consist of an unsequenced set of definitions of variables. Each definition is a simple expression that contain functions, operators, constants, and other variables, but no procedural constructs controlling the sequence of execution. In this way, Analytica is like a standard spreadsheet application, in which each cell contains a simple formula with no procedural constructs. Analytica selects the sequence in which to evaluate variables based on the dependencies among them, somewhat in the same way spreadsheets determine the sequence to evaluate their cells. Controlling the evaluation sequence via conditional statements and loops is a large part of programming in a language like in Fortran, Visual Basic, or C++. Non-procedural languages like Analytica free you from having to worry about sequencing. Non-procedural models or programs are usually much easier to write and understand than procedural programs because you can understand each definition (or formula) without worrying about the sequence of execution.&lt;br /&gt;
&lt;br /&gt;
However, procedural languages enable you to write more powerful functions that are hard or impossible without their procedural constructs. For this reason, Analytica offers a set of programming constructs, described in this chapter, providing a general procedural programming language for those who need it.&lt;br /&gt;
&lt;br /&gt;
You can use these constructs to control the flow of execution only within the definition of a variable or function. Evaluating one variable or function cannot (usually) change the value of another variables or functions. Thus, these procedural constructs do not affect the simple non-procedural  relationship among variables and functions. The only exception is that a function called from an event handler such as &amp;lt;code&amp;gt;OnChange&amp;lt;/code&amp;gt; or a button &amp;lt;code&amp;gt;OnClick&amp;lt;/code&amp;gt; attribute can change the definition of a global variable (see [[Button Creation]] for more details).&lt;br /&gt;
&lt;br /&gt;
== Sections ==&lt;br /&gt;
* [[Procedural Programming Example|Procedural Programming Example]]&lt;br /&gt;
* [[Summary of Programming Constructs]]&lt;br /&gt;
* [[Begin-End for Grouping Expressions]]&lt;br /&gt;
* [[Local Variables]]&lt;br /&gt;
* [[For and While Loops]]&lt;br /&gt;
* [[Recursion]]&lt;br /&gt;
* [[Local Indexes]]&lt;br /&gt;
* [[Ensuring Array Abstraction]]&lt;br /&gt;
* [[References and Data Structures]]&lt;br /&gt;
* [[Handles to Objects]]&lt;br /&gt;
* [[Dialog Functions]]&lt;br /&gt;
* [[Other Procedural Functions]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Analytica.NET Analytica.NET]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Functions_By_Category#Conventions_for_parameters_and_operands Conventions for parameters and operands]&lt;br /&gt;
* [http://wiki.analytica.com/index.php?title=Functions_By_Category#Operators Operators][http://wiki.analytica.com/index.php?title=Analytica.NET]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;footer&amp;gt;Building Functions and Libraries / {{PAGENAME}} / Analytica Enterprise&amp;lt;/footer&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhernandez3</name></author>
	</entry>
</feed>