├── Contents.m ├── adigator.m ├── adigatorCreateAuxInput.m ├── adigatorCreateDerivInput.m ├── adigatorOptions.m ├── docs ├── ADiGatorUserGuide.pdf ├── AIAA-GNC-ADiGator-GPOPS-II.pdf ├── COPYING.txt ├── README.md ├── TOMS-2011-0055.pdf ├── TOMS-2013-0067.pdf ├── adigator-CALGO.pdf ├── userguidefiles │ ├── ADiGatorUserGuide.tex │ ├── derivgator_notitle.jpg │ ├── makepdf.sh │ ├── master.bib │ └── shortcuts2.tex └── weinsteinmj_dissertation.pdf ├── examples ├── Contents.m ├── hessians │ ├── Contents.m │ └── logsumexp │ │ ├── Contents.m │ │ ├── logsumexp.m │ │ └── main.m ├── jachesvecprods │ ├── Contents.m │ ├── arrow.m │ ├── arrowsum.m │ └── main.m ├── jacobians │ ├── Contents.m │ ├── arrowhead │ │ ├── Contents.m │ │ ├── arrowhead.m │ │ ├── arrowhead4numjac.m │ │ └── main.m │ └── polydatafit │ │ ├── Contents.m │ │ ├── fit.m │ │ ├── fit4numjac.m │ │ └── main.m ├── optimization │ ├── Contents.m │ ├── fminconEx │ │ ├── Contents.m │ │ ├── confun.m │ │ ├── main.m │ │ └── objfun.m │ ├── fminuncEx │ │ ├── Contents.m │ │ ├── brownf.m │ │ └── main.m │ ├── fsolveEx │ │ ├── Contents.m │ │ ├── bananaf.m │ │ └── main.m │ ├── ipoptEx │ │ ├── Contents.m │ │ ├── dgl2fg.f │ │ ├── gl2f.m │ │ ├── gl2main.m │ │ └── gl2st.m │ └── vectorized │ │ ├── Contents.m │ │ ├── brachistochrone │ │ ├── Contents.m │ │ ├── basic_cons.m │ │ ├── basic_conswrap.m │ │ ├── basic_laggrad.m │ │ ├── basic_laggradwrap.m │ │ ├── basic_objwrap.m │ │ ├── dynamics.m │ │ ├── main_basic_1stderivs.m │ │ ├── main_basic_2ndderivs.m │ │ ├── main_noderivs.m │ │ ├── main_vect_1stderivs.m │ │ ├── main_vect_2ndderivs.m │ │ ├── setupproblem.m │ │ ├── vect_cons.m │ │ ├── vect_conswrap.m │ │ ├── vect_laggrad.m │ │ └── vect_laggradwrap.m │ │ └── minimumclimb │ │ ├── Contents.m │ │ ├── basic_objwrap.m │ │ ├── conswrap.m │ │ ├── dynamics.m │ │ ├── laghesswrap.m │ │ ├── main_1stderivs_nonvect.m │ │ ├── main_1stderivs_vect.m │ │ ├── main_2ndderivs_nonvect.m │ │ ├── main_2ndderivs_vect.m │ │ └── setupproblem.m ├── runAllExamples.m └── stiffodes │ ├── Contents.m │ ├── DCALcontrol │ ├── Contents.m │ ├── TwoLinkSys.m │ ├── getYd.m │ ├── getqd.m │ └── main.m │ ├── brusselator │ ├── Contents.m │ ├── main.m │ ├── mybrussode.m │ └── mybrussode_Jac.m │ └── burgers │ ├── Contents.m │ ├── burgersfun.m │ ├── burgersfun_noloop.m │ └── main.m ├── lib ├── @cada │ ├── Contents.m │ ├── adigatorAnalyzeForData.m │ ├── adigatorEvalInterp2pp.m │ ├── adigatorPrintOutputIndices.m │ ├── adigatorStructAnalyzer.m │ ├── adigatorVarAnalyzer.m │ ├── cada.m │ ├── cadaCheckForDerivs.m │ ├── cadaEmptyEval.m │ ├── cadaOverMap.m │ ├── cadaPrintReMap.m │ ├── cadaUnionVars.m │ ├── cadabinaryarraymath.m │ ├── cadabinarylogical.m │ ├── cadacreatearray.m │ ├── cadaunarylogical.m │ ├── cadaunarymath.m │ ├── colon.m │ ├── cross.m │ ├── diag.m │ ├── horzcat.m │ ├── interp1.m │ ├── interp2.m │ ├── inv.m │ ├── isempty.m │ ├── isequal.m │ ├── isequalwithequalnans.m │ ├── length.m │ ├── max.m │ ├── min.m │ ├── mldivide.m │ ├── mpower.m │ ├── mrdivide.m │ ├── mtimes.m │ ├── nnz.m │ ├── nonzeros.m │ ├── numel.m │ ├── ppval.m │ ├── private │ │ ├── cadaCancelDerivs.m │ │ ├── cadaRemoveRowsCols.m │ │ ├── cadaRepDers.m │ │ ├── cadainversederiv.m │ │ ├── cadamtimesderiv.m │ │ ├── cadamtimesderivvec.m │ │ └── cadaunion.m │ ├── prod.m │ ├── repmat.m │ ├── reshape.m │ ├── size.m │ ├── sparse.m │ ├── sub2ind.m │ ├── subsasgn.m │ ├── subsref.m │ ├── sum.m │ ├── transpose.m │ └── vertcat.m ├── @cadastruct │ ├── Contents.m │ ├── adigatorPrintOutputIndices.m │ ├── adigatorStructAnalyzer.m │ ├── adigatorVarAnalyzer.m │ ├── cadaCheckForDerivs.m │ ├── cadaOverMap.m │ ├── cadaPrintReMap.m │ ├── cadaUnionVars.m │ ├── cadastruct.m │ ├── ctranspose.m │ ├── horzcat.m │ ├── isequal.m │ ├── length.m │ ├── ppval.m │ ├── private │ │ ├── Contents.m │ │ ├── adigatorPrintStructAsgn.m │ │ ├── cadaloopstructderivref.m │ │ └── cadaloopstructfuncref.m │ ├── repmat.m │ ├── reshape.m │ ├── size.m │ ├── struct.m │ ├── subsasgn.m │ ├── subsref.m │ ├── transpose.m │ └── vertcat.m ├── Contents.m ├── adigatorAssignImpVarNames.m ├── adigatorAssignOvermapScheme.m ├── adigatorBreakCont.m ├── adigatorError.m ├── adigatorEvalInterp2pp.m ├── adigatorFindMatchingParen.m ├── adigatorForInitialize.m ├── adigatorForIterEnd.m ├── adigatorForIterStart.m ├── adigatorFunctionEnd.m ├── adigatorFunctionInitialize.m ├── adigatorGenInterp2pp.m ├── adigatorIfInitialize.m ├── adigatorIfIterEnd.m ├── adigatorIfIterStart.m ├── adigatorIfLooper.m ├── adigatorIfLooperi.m ├── adigatorInput.m ├── adigatorMakeNumeric.m ├── adigatorPrintTempFiles.m ├── adigatorSeperateFunLines.m ├── adigatorSetCellEvalFlag.m ├── adigatorStructAnalyzer.m ├── adigatorVarAnalyzer.m └── cadaUtils │ ├── Contents.m │ ├── cadaCheckForDerivs.m │ ├── cadadername.m │ ├── cadafuncname.m │ ├── cadaindprint.m │ └── cadamatprint.m ├── startupadigator.m ├── unit_tests └── test_unarymath_rules.m └── util ├── Contents.m ├── adigatorColor.m ├── adigatorGenFiles4Fmincon.m ├── adigatorGenFiles4Fminunc.m ├── adigatorGenFiles4Fsolve.m ├── adigatorGenFiles4Ipopt.m ├── adigatorGenFiles4gpops2.m ├── adigatorGenHesFile.m ├── adigatorGenJacFile.m ├── adigatorProjectVectLocs.m └── adigatorUncompressJac.m /Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator (Automatic DIfferentiation by GATORs) - A source transformation 2 | % via operator overloading tool for automatic differentiation of MATLAB 3 | % functions. 4 | % 5 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 6 | % Distributed under the GNU General Public License version 3.0 7 | % 8 | % website: https://github.com/matt-weinstein/adigator 9 | % 10 | % ----------------------------------------------------------------------- % 11 | % FILES: 12 | % adigator.m - main adigator function 13 | % adigatorCreateAuxInput.m - function for identifying auxiliary numerical 14 | % inputs 15 | % adigatorCreateDerivInput.m - function for identifying derivative inputs 16 | % adigatorOptions.m - function for setting adigator options 17 | % structure 18 | % startupadigator.m - path setup for adigator toolbox 19 | % 20 | % ----------------------------------------------------------------------- % 21 | % DIRECTORIES: 22 | % docs - readme, licensing, user's guide and reference papers 23 | % examples - various example problems 24 | % lib - ADiGator library of source transformation routines, overloaded 25 | % classes, etc 26 | % util - user utility functions to invoke source transformation -------------------------------------------------------------------------------- /adigatorCreateAuxInput.m: -------------------------------------------------------------------------------- 1 | function x = adigatorCreateAuxInput(xsize,value) 2 | % ADiGator auxiliary input variable creation routine. 3 | % 4 | % --------------------------- Usage ------------------------------------- % 5 | % x = adigatorCreateAuxInput(xsize) 6 | % This function creates an input,x, (which has NO derivatives, but is not 7 | % a fixed value), that is to be used with the function source-to-derivative 8 | % source transformation function, adigator. 9 | % OR 10 | % x = adigatorCreateAuxInput(xsize,value) 11 | % This is useful if you have a vectorized input which is actually a fixed 12 | % value. If the first dimension is vectorized, then value should be a row 13 | % vector, if second dimension is vectorized, then value should be a column 14 | % vector. 15 | % 16 | % ------------------------ Input Information ---------------------------- % 17 | % xsize - size of auxiliary input variable 18 | % value - fixed value of auxiliary input variable (optional, should ony be 19 | % used with vectorized, known auxiliary inputs) 20 | % 21 | % 22 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 23 | % Distributed under the GNU General Public License version 3.0 24 | % 25 | % See also: adigatorCreateDerivInput adigatorOptions adigator 26 | 27 | if isequal(size(xsize),[1 2]) && isequal(xsize,floor(xsize)) 28 | func.size = xsize; 29 | else 30 | error('first input xsize must be integer array of size 1 by 2') 31 | end 32 | if isinf(xsize(1)) && isinf(xsize(2)) 33 | error('only one dimension of the input may be vectorized'); 34 | end 35 | 36 | if nargin == 2 37 | valsize = size(value); 38 | if any(xsize(~isinf(xsize)) ~= valsize(~isinf(xsize))) || any(valsize(isinf(xsize))~=1) 39 | error('Invalue value input'); 40 | end 41 | func.value = value; 42 | end 43 | 44 | x = adigatorInput(func,[]); 45 | -------------------------------------------------------------------------------- /adigatorOptions.m: -------------------------------------------------------------------------------- 1 | function options = adigatorOptions(varargin) 2 | % ADiGator Options Structure Generator: Called in order set/modify default 3 | % ADiGator options. 4 | % 5 | % ------------------------------ Usage ---------------------------------- % 6 | % options = adigatorOptions(field1,value1,field2,value2,...) 7 | % 8 | % ------------------------ Input Information ---------------------------- % 9 | % field: string name of option to be modified 10 | % value: value to set option to 11 | % 12 | % ----------------------- Output Information ---------------------------- % 13 | % options: structure to be passed to adigator, or any of the utility 14 | % ADiGator generation routines (adigatorGenJacFile, 15 | % adigatorGenHesFile, adigatorGenFiles4Fmincon, 16 | % adigatorGenFiles4Ipopt, adigatorGenFiles4gpops2) 17 | % 18 | % OPTIONS: 19 | % ------------------------------------------------------------------------ 20 | % AUXDATA: 1 - auxiliary inputs will always have the same sparsity 21 | % pattern but may change numeric values 22 | % 0 - auxiliary inputs will always have the same numeric 23 | % values (required if inputs are a size to be looped on or 24 | % a reference index, etc.) (default) 25 | % ECHO: 1 - echo to screen the transformation progress (default) 26 | % 0 - dont echo 27 | % UNROLL: 1 - unroll loops and sub functions in derivative program 28 | % 0 - keep loops and sub functions rolled in derivative 29 | % (default) 30 | % COMMENTS: 1 - print comments to derivative file giving the lines of 31 | % user code which correspond to the printed statements 32 | % (default) 33 | % 0 - dont print comments 34 | % OVERWRITE: 1 - if the user supplies a derivative file name which 35 | % corresponds to an already existing file, then setting 36 | % this option will overwrite the existing file. (default 37 | % for adigatorGenFiles4gpops2, adigatorGenJacFile, 38 | % adigatorGenHesFile, adigatorGenFiles4Ipopt, 39 | % adigatorGenFiles4Fmincon) 40 | % 0 - if a file already exists with the same name as the given 41 | % derivative file name, then it will not overwrite and 42 | % error out instead (default for adigator) 43 | % MAXWHILEITER:k - maximum number of iterations to attempt to find a static 44 | % input/output for WHILE loops (default set to 10) - 45 | % increasing this will increase derivative file generation 46 | % times when using WHILE loops 47 | % COMPLEX: 0 - do not expect any variables to be complex, use 48 | % non-complex forms of abs, ctranspose, dot (default) 49 | % 1 - expect variables to be complex, use complex forms of 50 | % ctranspose, abs, dot. 51 | % ------------------------------------------------------------------------ 52 | % 53 | % NOTES: The default value of the OVERWRITE option changes depending 54 | % upon whether the basic adigator file is being called or one of 55 | % the wrapper generation files. 56 | % 57 | % If desired, the defaults of each option may be changed by editing this 58 | % file. 59 | % 60 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 61 | % Distributed under the GNU General Public License version 3.0 62 | % 63 | % See also adigator, adigatorGenFiles4gpops2 64 | 65 | % Set Defaults 66 | options.auxdata = 0; 67 | options.echo = 1; 68 | options.unroll = 0; 69 | options.comments = 1; 70 | options.overwrite = 0; 71 | options.optoutput = 0; 72 | options.maxwhileiter = 10; 73 | options.complex = 0; 74 | if nargin/2 ~= floor(nargin/2) 75 | error('Inputs to adigatorOptions must come in field/value pairs') 76 | end 77 | 78 | % Set user wanted options 79 | for i = 1:nargin/2 80 | field = lower(varargin{2*(i-1)+1}); 81 | value = varargin{2*i}; 82 | switch field 83 | case {'auxdata','echo','unroll','comments','overwrite','genpat',... 84 | 'optoutput','complex'} 85 | options.(field) = logical(value); 86 | case 'maxwhileiter' 87 | options.(field) = value; 88 | otherwise 89 | warning(['Invalid option field: ',field]) 90 | end 91 | end -------------------------------------------------------------------------------- /docs/ADiGatorUserGuide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matt-weinstein/adigator/d002041c7aec727f99b0369fa1957563e46cefe1/docs/ADiGatorUserGuide.pdf -------------------------------------------------------------------------------- /docs/AIAA-GNC-ADiGator-GPOPS-II.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matt-weinstein/adigator/d002041c7aec727f99b0369fa1957563e46cefe1/docs/AIAA-GNC-ADiGator-GPOPS-II.pdf -------------------------------------------------------------------------------- /docs/TOMS-2011-0055.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matt-weinstein/adigator/d002041c7aec727f99b0369fa1957563e46cefe1/docs/TOMS-2011-0055.pdf -------------------------------------------------------------------------------- /docs/TOMS-2013-0067.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matt-weinstein/adigator/d002041c7aec727f99b0369fa1957563e46cefe1/docs/TOMS-2013-0067.pdf -------------------------------------------------------------------------------- /docs/adigator-CALGO.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matt-weinstein/adigator/d002041c7aec727f99b0369fa1957563e46cefe1/docs/adigator-CALGO.pdf -------------------------------------------------------------------------------- /docs/userguidefiles/derivgator_notitle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matt-weinstein/adigator/d002041c7aec727f99b0369fa1957563e46cefe1/docs/userguidefiles/derivgator_notitle.jpg -------------------------------------------------------------------------------- /docs/userguidefiles/makepdf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pdflatex ADiGatorUserGuide.tex 4 | bibtex ADiGatorUserGuide 5 | pdflatex ADiGatorUserGuide.tex 6 | pdflatex ADiGatorUserGuide.tex 7 | rm *.log *.toc *.out *.bbl *.blg *.aux 8 | mv ADiGatorUserGuide.pdf ../ -------------------------------------------------------------------------------- /docs/weinsteinmj_dissertation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matt-weinstein/adigator/d002041c7aec727f99b0369fa1957563e46cefe1/docs/weinsteinmj_dissertation.pdf -------------------------------------------------------------------------------- /examples/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator example problems 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % DIRECTORIES: 8 | % hessians - examples for computing Hessians 9 | % jachesvecprods - examples for computing Jacobian and Hessian vector 10 | % products 11 | % jacobians - examples for computing Jacobians 12 | % optimization - examples for optimization (and system of equations) 13 | % problems 14 | % stiffodes - examples of solving stiff ODEs 15 | % 16 | % ----------------------------------------------------------------------- % 17 | % FILES: 18 | % runAllExamples.m - routine which runs all examples included in the 19 | % adigator package -------------------------------------------------------------------------------- /examples/hessians/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator Hessian example problems 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % DIRECTORIES: 8 | % logsumexp - simple Hessian of log(sum(exp)) function -------------------------------------------------------------------------------- /examples/hessians/logsumexp/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator logsumexp Hessian example 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % logsumexp.m - log(sum(exp)) function file 9 | % main.m - main file which generates Hessian file using 10 | % adigatorGenHesFile -------------------------------------------------------------------------------- /examples/hessians/logsumexp/logsumexp.m: -------------------------------------------------------------------------------- 1 | function y = logsumexp(x) 2 | 3 | y = log(sum(exp(x))); -------------------------------------------------------------------------------- /examples/hessians/logsumexp/main.m: -------------------------------------------------------------------------------- 1 | % This file computes the hessian of the logsumexp problem using 2 | % adigatorGenHesFile 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | clc 7 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 8 | n = 2^5; 9 | 10 | x_x = adigatorCreateDerivInput([n 1],'x'); 11 | output = adigatorGenHesFile('logsumexp',{x_x}); 12 | 13 | x = rand(n,1); 14 | 15 | [H,G,f] = logsumexp_Hes(x); 16 | [G2,f2] = logsumexp_Grd(x); 17 | -------------------------------------------------------------------------------- /examples/jachesvecprods/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator Jacobian/Hessian vector product example problem 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % arrow.m - arrowhead function file 9 | % arrowsum.m - sum of arrowhead function file 10 | % main.m - computes Jacobian vector product of arrowhead function in 11 | % two different ways, Hessian vector product of arrowsum 12 | % function in two different ways -------------------------------------------------------------------------------- /examples/jachesvecprods/arrow.m: -------------------------------------------------------------------------------- 1 | function y = arrow(x) 2 | N = length(x); 3 | 4 | y = zeros(N,1); 5 | y(1) = 2*x(1)^2+sum(x.^2); 6 | y(2:N) = x(1)^2+x(2:N).^2; -------------------------------------------------------------------------------- /examples/jachesvecprods/arrowsum.m: -------------------------------------------------------------------------------- 1 | function y = arrowsum(x) 2 | N = length(x); 3 | 4 | y = zeros(N,1); 5 | y(1) = 2*x(1)^2+sum(x.^2); 6 | y(2:N) = x(1)^2+x(2:N).^2; 7 | 8 | y = sum(y); -------------------------------------------------------------------------------- /examples/jachesvecprods/main.m: -------------------------------------------------------------------------------- 1 | % This file compares computing Jacobian-vector products and Hessian-vector 2 | % products in two different ways. Jacobian-vector products may be computed 3 | % by computing the Jacobian and then multiplying by the vector, or directly 4 | % computing the Jacobian via seeding. Hessian-vector products may be 5 | % computed in a similar manner. 6 | % 7 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 8 | % Distributed under the GNU General Public License version 3.0 9 | clc 10 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 11 | % Will use f(x) = arrow(x) and g(x) = arrowsum(x) = sum(f(x)); 12 | % Consider x = v*t, t scalar 13 | n = 2^10; 14 | x = rand(n,1); 15 | v = rand(n,1); 16 | opts.overwrite = 1; 17 | opts.echo = 0; 18 | 19 | % ------------------------- 1st Deriv of f wrt x ------------------------ % 20 | % Want p = Jf(x)*v - can make function which computes Jf(x) 21 | tic 22 | x_x = adigatorCreateDerivInput([n 1],'x'); 23 | adigator('arrow',{x_x},'arrow_x',opts); 24 | jac.gen = toc; 25 | 26 | x1.f = x; 27 | x1.dx = ones(n,1); 28 | tic 29 | for i = 1:10 30 | f1 = arrow_x(x1); 31 | J1 = sparse(f1.dx_location(:,1),f1.dx_location(:,2),f1.dx,n,n); 32 | p1 = J1*v; 33 | end 34 | jac.eval = toc/10; 35 | 36 | 37 | % -------------------------- 1st Deriv of f wrt t ----------------------- % 38 | % df/dt = Jf(x)*v = p 39 | tic 40 | derinfo.vodname = 't'; % Take derivative wrt variable called 't' 41 | derinfo.vodsize = [1 1]; % 't' is a scalar 42 | derinfo.nzlocs = [(1:n).',ones(n,1)]; % input 'x' has full column deriv wrt 't' 43 | x_t = adigatorCreateDerivInput([n 1],derinfo); 44 | adigator('arrow',{x_t},'arrow_t',opts); 45 | jacv.gen = toc; 46 | 47 | x2.f = x; 48 | x2.dt = v; 49 | tic 50 | for i = 1:10 51 | f2 = arrow_t(x2); 52 | p2 = f2.dt; 53 | end 54 | jacv.eval = toc/10; 55 | 56 | err1 = max(abs(p1-p2)./abs(p1)); 57 | display(['n = ',num2str(n)]); 58 | display('Times for Computing Jf(x) then Multiplying') 59 | disp(jac); 60 | display('Times for Computing Jf(x)*v (Jacobian vector product)') 61 | disp(jacv); 62 | display('Max Pct Diff of J*v both ways') 63 | disp(err1); 64 | 65 | % -------------------------- 2nd Deriv of g wrt x ----------------------- % 66 | adigator('arrowsum',{x_x},'arrowsum_x',opts); 67 | tic 68 | ax1.f = x_x; 69 | ax1.dx = x1.dx; 70 | adigator('arrowsum_x',{ax1},'arrowsum_xx',opts); 71 | hes.gen = toc; 72 | 73 | tic 74 | for i = 1:10 75 | g1 = arrowsum_xx(x1); 76 | H = sparse(g1.dxdx_location(:,1),g1.dxdx_location(:,2),g1.dxdx,n,n); 77 | q1 = H*v; 78 | end 79 | hes.eval = toc/10; 80 | 81 | % ------------------------- 2nd Deriv of g wrt t ------------------------ % 82 | % dg/dx = Gg(x); (arrowsum_x) 83 | % d[dg/dx]/dt = Hg(x)*v; 84 | tic 85 | ax2.f = x_t; 86 | ax2.dx = ones(n,1); 87 | adigator('arrowsum_x',{ax2},'arrowsum_xt',opts); 88 | hesv.gen = toc; 89 | 90 | x2.dx = ones(n,1); 91 | 92 | tic 93 | for i = 1:10 94 | g2 = arrowsum_xt(x2); 95 | q2 = g2.dxdt; 96 | end 97 | hesv.eval = toc/10; 98 | 99 | err2 = max(abs(q1-q2)./abs(q1)); 100 | display('Times for Computing Hf(x) then Multiplying') 101 | disp(hes) 102 | display('Times for Computing Hf(x)*v (Hessian Vector Product)') 103 | disp(hesv) 104 | display('Max Pct Diff of H*v both ways') 105 | disp(err2) 106 | -------------------------------------------------------------------------------- /examples/jacobians/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator Jacobian example problems 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % DIRECTORIES: 8 | % arrowhead - Jacobian of arrowhead function 9 | % polydatafit - Jacobian of polynomial data fitting function -------------------------------------------------------------------------------- /examples/jacobians/arrowhead/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator arrowhead Jacobian example 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % arrowhead.m - arrowhead function 9 | % arrowhead4numjac.m - arrowhead function to be called by numjac 10 | % main.m - computes Jacobian of arrowhead function using 11 | % ADiGator and numjac -------------------------------------------------------------------------------- /examples/jacobians/arrowhead/arrowhead.m: -------------------------------------------------------------------------------- 1 | function y = arrowhead(x) 2 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 3 | % Distributed under the GNU General Public License version 3.0 4 | N = length(x); 5 | 6 | y = zeros(N,1); 7 | y(1) = 2*x(1)^2+sum(x.^2); 8 | y(2:N) = x(1)^2+x(2:N).^2; 9 | -------------------------------------------------------------------------------- /examples/jacobians/arrowhead/arrowhead4numjac.m: -------------------------------------------------------------------------------- 1 | function y = arrowhead4numjac(t,x) 2 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 3 | % Distributed under the GNU General Public License version 3.0 4 | N = length(x); 5 | 6 | y = zeros(N,1); 7 | y(1) = 2*x(1)^2+sum(x.^2); 8 | y(2:N) = x(1)^2+x(2:N).^2; 9 | -------------------------------------------------------------------------------- /examples/jacobians/arrowhead/main.m: -------------------------------------------------------------------------------- 1 | % This file uses both MATLAB finite differences as well as adigator in order 2 | % to compute derivatives of the arrowhead function. User can change N to 3 | % see the effects of increasing problem size. 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 7 | N = 100; 8 | numeval = 20; 9 | x = rand(N,1); 10 | % ------------------------------ ADiGator ------------------------------- % 11 | gx = adigatorCreateDerivInput([N, 1],'x'); % Create Deriv Input 12 | genout = adigatorGenJacFile('arrowhead',{gx}); 13 | S = genout.JacobianStructure; 14 | 15 | tic; 16 | for i = 1:numeval 17 | [Jac,y] = arrowhead_Jac(x); 18 | end 19 | adigatortime = toc/numeval; 20 | 21 | 22 | % -------------------------- Finite Differences ------------------------- % 23 | TOL = 1e-8;% Can change this to make numjac more/less accurate 24 | tic 25 | for i = 1:numeval 26 | dfdx = numjac(@arrowhead4numjac,0,x,y,TOL*ones(N,1),[],0); 27 | end 28 | fdtime = toc/numeval; 29 | 30 | display(['Average deriv eval time using Finite Differences: ',num2str(fdtime)]); 31 | display(['Average deriv eval time using ADiGator: ',num2str(adigatortime)]); 32 | 33 | xs.f = x; 34 | xs.dx = ones(N,1); 35 | -------------------------------------------------------------------------------- /examples/jacobians/polydatafit/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator polynomial data fitting Jacobian example 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % fit.m - polynomial data fitting function 9 | % fit4numjac.m - polynomial data fitting function to be called by numjac 10 | % main.m - computes Jacobian of fit function using ADiGator and 11 | % numjac -------------------------------------------------------------------------------- /examples/jacobians/polydatafit/fit.m: -------------------------------------------------------------------------------- 1 | function p = fit(x, d, m) 2 | % FIT -- Given x and d, fit() returns p 3 | % such that norm(V*p-d) = min, where 4 | % V = [1, x, x.^2, ... x.^(m-1)]. 5 | 6 | dim_x = size(x, 1); 7 | if dim_x < m 8 | error('x must have at least m entries'); 9 | end 10 | 11 | V = ones(dim_x, 1); 12 | 13 | for count = 1 : (m-1) 14 | V = [V, x.^count]; 15 | end 16 | p = V\d; -------------------------------------------------------------------------------- /examples/jacobians/polydatafit/fit4numjac.m: -------------------------------------------------------------------------------- 1 | function p= fit4numjac(t,x, d, m) 2 | % FIT -- Given x and d, fit() returns p 3 | % such that norm(V*p-d) = min, where 4 | % V = [1, x, x.?2, ... x.?(m-1)]. 5 | 6 | dim_x = size(x, 1); 7 | if dim_x < m 8 | error('x must have at least m entries'); 9 | end 10 | 11 | V = ones(dim_x, 1); 12 | 13 | for count = 1 : (m-1) 14 | V = [V, x.^count]; 15 | end 16 | 17 | p = V \ d; -------------------------------------------------------------------------------- /examples/jacobians/polydatafit/main.m: -------------------------------------------------------------------------------- 1 | % This file uses both MATLAB finite differences as well as adigator in order 2 | % to compute derivatives of the fit.m function. The user can change m and n 3 | % to change to problem size. 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 7 | m = 8; 8 | n = 100; 9 | TOL = 1e-5; 10 | 11 | x = floor(rand(n,1)*1000)/1000; 12 | d = floor(rand(n,1)*1000)/1000; 13 | numeval = 25; 14 | 15 | tic 16 | gx = adigatorCreateDerivInput([n,1],'x'); 17 | adigatorGenJacFile('fit',{gx,d,m}); 18 | gentime = toc; 19 | tic 20 | for i = 1:numeval 21 | [J,p] = fit_Jac(x,d,m); 22 | end 23 | adigatortime = toc/numeval; 24 | 25 | 26 | 27 | tic 28 | for i = 1:numeval 29 | dpdx2 = numjac(@(t,x)fit4numjac(t,x,d,m),0,x,p,TOL*ones(n,1),[],0); 30 | end 31 | fdtime = toc/numeval; 32 | 33 | 34 | fprintf('Derivatives of fit function:\n'); 35 | fprintf(['m = %1.0f, n = %1.0f, TOL = ',num2str(TOL),'\n'],m,n); 36 | fprintf(['ADiGator File Generation Time: ',num2str(gentime),'\n']); 37 | fprintf(['ADiGator Average Eval Time: ',num2str(adigatortime),'\n']); 38 | fprintf(['F Diff Average Eval Time: ',num2str(fdtime),'\n']); 39 | -------------------------------------------------------------------------------- /examples/optimization/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator optimization example problems 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % DIRECTORIES: 8 | % fminconEx - simple constrained minimization problem with fmincon 9 | % fminuncEx - unconstrained minimization problem with fminunc 10 | % fsolveEx - system of equations problem with fsolve 11 | % ipoptEx - unconstrained minimization problem with IPOPT 12 | % vectorized - direct collocation optimal control problems using 13 | % vectorized mode of ADiGator -------------------------------------------------------------------------------- /examples/optimization/fminconEx/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator NLP example 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % confun.m - constraint function 9 | % main.m - solves NLP using ADiGator derivatives and fmincon 10 | % objfun.m - objective function -------------------------------------------------------------------------------- /examples/optimization/fminconEx/confun.m: -------------------------------------------------------------------------------- 1 | function [c, ceq] = confun(x) 2 | % Constraints function 3 | 4 | c(1) = 1.5 + x(1) * x(2) - x(1) - x(2); %Inequality constraints 5 | c(2) = -x(1) * x(2)-10; 6 | % No nonlinear equality constraints 7 | ceq=[]; -------------------------------------------------------------------------------- /examples/optimization/fminconEx/main.m: -------------------------------------------------------------------------------- 1 | % In this example we use MATLAB's fmincon function to solve the objective 2 | % function in the file objfun.m with the inequality constraints in function 3 | % confun.m. 4 | % This calls the function adigatorGenFiles4Fmincon to generate derivative 5 | % files. 6 | % If the user does not have MATLAB's optimization package 7 | % installed, then fmincon will not be called, but the derivative file 8 | % creation will still be performed. 9 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 10 | % Distributed under the GNU General Public License version 3.0 11 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 12 | clear all 13 | xi = [-1,1]; 14 | solveflag = exist('fmincon','file'); 15 | % --------------------- Call adigatorGenFiles4Fmincon ------------------- % 16 | setup.order = 2; 17 | setup.numvar = 2; 18 | setup.objective = 'objfun'; 19 | setup.constraint = 'confun'; 20 | 21 | adifuncs = adigatorGenFiles4Fmincon(setup); 22 | 23 | if solveflag 24 | % ------------------- Solve Without Derivatives ----------------------- % 25 | tic; 26 | options = optimset('Algorithm','interior-point','Display','iter'); 27 | [x0,fval0] = ... 28 | fmincon(@objfun,xi,[],[],[],[],[],[],@confun,options); 29 | time0 = toc; 30 | 31 | % ------------------- Solve With 1st Derivatives ---------------------- % 32 | tic; 33 | options = optimset('Algorithm','interior-point'); 34 | options = optimset(options,'GradObj','on','GradConstr','on','Display','iter'); 35 | [x1,fval1] = fmincon(adifuncs.objgrd,xi,[],[],[],[],[],[],... 36 | adifuncs.consgrd,options); 37 | time1 = toc; 38 | 39 | % ------------------- Solve With 2nd Derivatives ---------------------- % 40 | tic; 41 | options = optimset('Algorithm','interior-point',... 42 | 'Display','iter','GradObj','on','GradConstr','on',... 43 | 'Hessian','user-supplied','HessFcn',adifuncs.hessian); 44 | [x2,fval2] = fmincon(adifuncs.objgrd,xi,[],[],[],[],[],[],... 45 | adifuncs.consgrd,options); 46 | time2 = toc; 47 | 48 | % -------------------- Display Solve Times ---------------------------- % 49 | fprintf(['Solve time using no derivatives',... 50 | ': ',num2str(time0),'\n']) 51 | fprintf(['Solve time using 1st derivatives',... 52 | ': ',num2str(time1),'\n']) 53 | fprintf(['Solve time using 2nd derivatives',... 54 | ': ',num2str(time2),'\n']) 55 | end 56 | -------------------------------------------------------------------------------- /examples/optimization/fminconEx/objfun.m: -------------------------------------------------------------------------------- 1 | function f = objfun(x) 2 | % Objective Function File 3 | f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1); -------------------------------------------------------------------------------- /examples/optimization/fminuncEx/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator unconstrained minimization example 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % brownf.m - brown objective function 9 | % main.m - solves optimization problem using ADiGator derivatives and 10 | % fminunc -------------------------------------------------------------------------------- /examples/optimization/fminuncEx/brownf.m: -------------------------------------------------------------------------------- 1 | function f = brownf(x) 2 | %BROWNFG Nonlinear minimization problem (function and its gradients). 3 | % Documentation example. 4 | 5 | % Copyright 1990-2008 The MathWorks, Inc. 6 | 7 | % Evaluate the function. 8 | n=length(x); y=zeros(n,1)*x(1); 9 | i=1:(n-1); 10 | y(i)=(x(i).^2).^(x(i+1,1).^2+1)+(x(i+1).^2).^(x(i).^2+1); 11 | f=sum(y); -------------------------------------------------------------------------------- /examples/optimization/fminuncEx/main.m: -------------------------------------------------------------------------------- 1 | % This function solves the brown optimisation problem using fminunc, where 2 | % first and second derivative files are generated via 3 | % adigatorGenFiles4Fminunc 4 | % 5 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 6 | % Distributed under the GNU General Public License version 3.0 7 | clc 8 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 9 | n = 2^9; 10 | xstart = rand(n,1); 11 | solveflag = exist('fminunc','file'); 12 | 13 | 14 | % ----------------------- Solve with 1st Derivatives -------------------- % 15 | % setup structure for adigatorGenFiles4Fminunc 16 | setup.numvar = n; 17 | setup.objective = 'brownf'; 18 | setup.order = 1; 19 | % Call adigatorGenFiles4Fminunc 20 | tic 21 | adifuncs = adigatorGenFiles4Fminunc(setup); 22 | gentime = toc; 23 | 24 | if n < 2^9 25 | % Dont try to solve with first derivatives if u increase n too much. 26 | if solveflag 27 | tic 28 | options = optimoptions(@fminunc,'GradObj','on',... 29 | 'Algorithm','trust-region','Display','iter'); 30 | [x,fval,exitflag,output] = fminunc(adifuncs.gradient,xstart,options); 31 | solvetime = toc; 32 | disp(['1st deriv gen time + solve time: ',num2str(gentime+solvetime)]); 33 | end 34 | end 35 | 36 | % ----------------------- Solve with 2nd Derivatives -------------------- % 37 | % setup structure for adigatorGenFiles4Fminunc 38 | setup.numvar = n; 39 | setup.objective = 'brownf'; 40 | setup.order = 2; 41 | % Call adigatorGenFiles4Fminunc 42 | tic 43 | adifuncs = adigatorGenFiles4Fminunc(setup); 44 | gentime = toc; 45 | 46 | if solveflag 47 | tic 48 | options = optimoptions(@fminunc,'GradObj','on','Hessian','on',... 49 | 'Algorithm','trust-region','Display','iter'); 50 | [x,fval,exitflag,output] = fminunc(adifuncs.hessian,xstart,options); 51 | solvetime = toc; 52 | disp(['2nd deriv gen time + solve time: ',num2str(gentime+solvetime)]); 53 | end 54 | -------------------------------------------------------------------------------- /examples/optimization/fsolveEx/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator system of equations example 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % bananaf.m - banana function 9 | % main.m - solves banana problem using ADiGator derivatives and fsolve -------------------------------------------------------------------------------- /examples/optimization/fsolveEx/bananaf.m: -------------------------------------------------------------------------------- 1 | function F = bananaf(x) 2 | % Evaluate the vector function for the system of nonlinear equations 3 | % derived from the general n-dimensional Rosenbrock function. 4 | % Copyright 1990-2008 The MathWorks, Inc. 5 | % Get the problem size 6 | n = length(x); 7 | % Evaluate the vector function 8 | odds = 1:2:n; 9 | evens = 2:2:n; 10 | F = zeros(n,1); 11 | F(odds,1) = 1-x(odds); 12 | F(evens,1) = 10.*(x(evens)-x(odds).^2); -------------------------------------------------------------------------------- /examples/optimization/fsolveEx/main.m: -------------------------------------------------------------------------------- 1 | % This function solves the bananaf non-linear equation problem using 2 | % fsolve, where the Jacobian is generated by adigatorGenFiles4Fsolve 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | clear all 7 | clc 8 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 9 | n = 2^8; 10 | xstart = rand(n,1); 11 | solveflag = exist('fsolve','file'); 12 | 13 | % ----------------------- Solve with 1st Derivatives -------------------- % 14 | % setup structure for adigatorGenFiles4Fsolve 15 | setup.numvar = n; 16 | setup.function = 'bananaf'; 17 | % Call adigatorGenFiles4Fsolve 18 | tic 19 | adifuncs = adigatorGenFiles4Fsolve(setup); 20 | gentime = toc; 21 | 22 | odds = 1:2:n; 23 | evens = 2:2:n; 24 | z0 = zeros(n,1); 25 | z0(odds) = -1.9; z0(evens) = 2; 26 | 27 | % Call fsolve 28 | if solveflag 29 | options = optimoptions(@fsolve,'Display','iter','Jacobian','on'); 30 | [x,F,exitflag,output,JAC] = fsolve(adifuncs.jacobian,z0,options); 31 | end 32 | -------------------------------------------------------------------------------- /examples/optimization/ipoptEx/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator unconstrained minimization example w/ IPOPT 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % dgl2fg.f - original fortran code computing function and gradient of GL2 9 | % problem 10 | % gl2f.m - GL2 objective function file 11 | % gl2main.m - solves GL2 problem using ADiGator derivatives and IPOPT 12 | % gl2st.m - initialization of GL2 problem -------------------------------------------------------------------------------- /examples/optimization/ipoptEx/gl2main.m: -------------------------------------------------------------------------------- 1 | % This solves the Ginzburg-Landau (2-dimensional) superconductivity problem 2 | % using IPOPT, supplying derivatives via ADiGator and the 3 | % adigatorGenFiles4Ipopt command 4 | % Parameters which can be changed: 5 | % nx - determines problem size 6 | % vorum - is a problem constant which must be an integer 7 | % 8 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 9 | % Distributed under the GNU General Public License version 3.0 10 | 11 | % Problem setup 12 | clc 13 | vornum = 8; 14 | nx = 2^4; 15 | ny = nx; 16 | n = 4*nx*ny; 17 | 18 | auxdata.nx = nx; 19 | auxdata.ny = ny; 20 | auxdata.tkappa = 5; 21 | auxdata.hx = sqrt(vornum/2)*3/nx; 22 | auxdata.hy = sqrt(vornum/2)*3*sqrt(3)/ny; 23 | auxdata.vornum = vornum; 24 | 25 | 26 | % Setup structure for adigatorGenFiles4Ipopt 27 | setup.numvar = n; 28 | setup.objective = 'gl2f'; 29 | setup.auxdata = auxdata; 30 | setup.order = 2; 31 | 32 | % adigatorGenFiles4Ipopt generates everything required by ipopt 33 | tic 34 | funcs = adigatorGenFiles4Ipopt(setup); 35 | gentime = toc; 36 | 37 | % Get starting point 38 | z0 = gl2st(auxdata); 39 | 40 | % Test callback functions 41 | g0 = feval(funcs.gradient,z0); 42 | h0 = feval(funcs.hessian,z0,1,[]); 43 | Hs = feval(funcs.hessianstructure); 44 | 45 | v = rand(n,1); 46 | 47 | % % Call ipopt 48 | if exist('ipopt','file') 49 | options.ipopt.tol = sqrt(eps); 50 | options.lb = -Inf*ones(n,1); 51 | options.ub = Inf*ones(n,1); 52 | [z, info] = ipopt(z0,funcs,options); 53 | end -------------------------------------------------------------------------------- /examples/optimization/vectorized/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator direct collocation (vectorized) example problems 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % DIRECTORIES: 8 | % brachistochrone - classical brachistochrone problem 9 | % minimumclimb - minimum time to climb of supersonic aircraft -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator brachistochrone example w/ fmincon 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % basic_cons.m - constraint function for use with non-vect 9 | % basic_conswrap.m - constraint wrapper for use with non-vect 10 | % basic_laggrad.m - lagrangian gradient file for use with non-vect 11 | % basic_laggradwrap.m - lagrangian gradient wrapper file for non-vect 12 | % basic_objwrap.m - objective wrapper for non-vect 13 | % dynamics.m - dynamics function 14 | % main_basic_1stderivs.m - solve with 1st derivatives, non-vectorized 15 | % main_basic_2ndderivs.m - solve with 2nd derivatives, non-vectorized 16 | % main_noderivs.m - solve with no supplied derivatives 17 | % main_vect_1stderivs.m - solve with 1st derivatives, vectorized 18 | % main_vect_2ndderivs.m - solve with 2nd derivatives, vectorized 19 | % setupproblem.m - problem setup - initial guess and collocation 20 | % vect_cons.m - constraint function for use with vect 21 | % vect_conswrap.m - constraint wrapper for use with vect 22 | % vect_laggrad.m - lagrangian gradient file for use with vect 23 | % vect_laggradwrap.m - lagrangian gradient wrapper file for vect 24 | -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/basic_cons.m: -------------------------------------------------------------------------------- 1 | function [C,Ceq] = basic_cons(z,probinfo) 2 | 3 | X = z(probinfo.xind); 4 | U = z(probinfo.uind); 5 | tf = z(probinfo.tfind); 6 | 7 | % Calculate h 8 | numintervals = probinfo.numintervals; 9 | h = tf/numintervals; 10 | 11 | % Calculate F 12 | F = dynamics(X,U); 13 | 14 | % Get Reference Indices 15 | k = probinfo.k; 16 | kbp1 = probinfo.kbp1; 17 | kp1 = probinfo.kp1; 18 | 19 | Xk = X(k,:); 20 | Xkbp1 = X(kbp1,:); 21 | Xkp1 = X(kp1,:); 22 | 23 | Fk = F(k,:); 24 | Fkbp1 = F(kbp1,:); 25 | Fkp1 = F(kp1,:); 26 | 27 | C1 = Xkbp1 - 1/2.*(Xkp1+Xk) - h/8.*(Fk-Fkp1); 28 | C2 = Xkp1 - Xk - h/6.*(Fkp1 + 4.*Fkbp1 + Fk); 29 | 30 | Ceq = [C1(:);C2(:)]; 31 | C =[]; -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/basic_conswrap.m: -------------------------------------------------------------------------------- 1 | function [C,Ceq,JC,JCeq] = basic_conswrap(z,probinfo) 2 | 3 | 4 | if nargout == 2 5 | [C,Ceq] = basic_cons(z,probinfo); 6 | else 7 | Z.f = z; 8 | Z.dz = ones(size(z)); 9 | [~,Ceq] = basic_cons_z(Z,probinfo); 10 | JC = []; 11 | C = []; 12 | JCeq = sparse(Ceq.dz_location(:,1),Ceq.dz_location(:,2),Ceq.dz,... 13 | Ceq.dz_size(1),Ceq.dz_size(2)).'; 14 | Ceq = Ceq.f; 15 | end -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/basic_laggrad.m: -------------------------------------------------------------------------------- 1 | function GL = basic_laggrad(z,lambda,probinfo) 2 | % This function builds the lagrangian gradient 3 | 4 | Z.f = z; 5 | Z.dz = ones(length(z),1); 6 | GO = sparse(1,probinfo.tfind,1,1,probinfo.tfind); % Obj Grad 7 | 8 | [~,Ceq] = basic_cons_z(Z,probinfo); 9 | JCeq = sparse(Ceq.dz_location(:,1),Ceq.dz_location(:,2),Ceq.dz,... 10 | Ceq.dz_size(1),Ceq.dz_size(2)); % Cons Jac 11 | GL = GO + lambda.'*JCeq; % Lag Grad -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/basic_laggradwrap.m: -------------------------------------------------------------------------------- 1 | function [H,G] = basic_laggradwrap(z,lambda,probinfo) 2 | 3 | Z.f = z; 4 | Z.dz = ones(size(z)); 5 | GL = basic_laggrad_z(Z,lambda.eqnonlin,probinfo); 6 | H = sparse(GL.dz_location(:,1),GL.dz_location(:,2),GL.dz,... 7 | GL.dz_size(1),GL.dz_size(2)); 8 | 9 | G = GL.f; -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/basic_objwrap.m: -------------------------------------------------------------------------------- 1 | function [tf,G] = basic_objwrap(z,probinfo) 2 | 3 | tf = z(probinfo.tfind); 4 | if nargout > 1 5 | G = sparse(1,probinfo.tfind,1,1,probinfo.tfind); 6 | end -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/dynamics.m: -------------------------------------------------------------------------------- 1 | function Xdot = dynamics(X,U) 2 | % Brachistochrone Dynamics 3 | Xdot = zeros(size(X)); 4 | X3 = X(:,3); 5 | Xdot(:,1) = X3.*sin(U); 6 | Xdot(:,2) = -X3.*cos(U); 7 | Xdot(:,3) = 9.81.*cos(U); -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/main_basic_1stderivs.m: -------------------------------------------------------------------------------- 1 | % This function solves the brachistochrone problem by supplying first 2 | % derivatives without taking advantage of the vectorized nature of the 3 | % problem. A wrapper file for the constraint and objective functions (which 4 | % call derivative files) are created and supplied in basic_conswrap.m and 5 | % basic_objwrap.m, respectively. 6 | % 7 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 8 | % Distributed under the GNU General Public License version 3.0 9 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 10 | 11 | solveflag = exist('fmincon','file'); 12 | if solveflag 13 | options = optimset('Algorithm','interior-point','MaxFunEvals',50000,... 14 | 'GradObj','on','GradConstr','on','Display','iter'); 15 | end 16 | numintervals = [5,10,20,40]; 17 | time = zeros(length(numintervals),1); 18 | for i = 1:length(numintervals) 19 | tic; 20 | % ---------------------- Set Up the Problem ----------------------------- % 21 | if i == 1 22 | [probinfo,upperbound,lowerbound,guess,tau] = setupproblem(numintervals(i)); 23 | else 24 | % If on second or third mesh, use previous solution as initial guess 25 | [probinfo,upperbound,lowerbound,guess,tau] = ... 26 | setupproblem(numintervals(i),X,U,fval,tau); 27 | end 28 | 29 | % ----------------- Create Constraint Derivative File ------------------- % 30 | % NOTE: fmincon is given the function basic_conswrap which builds the 31 | % Jacobian by calling basic_cons_z 32 | gz = adigatorCreateDerivInput([length(guess), 1],'z'); 33 | adigator('basic_cons',{gz,probinfo},'basic_cons_z',adigatorOptions('overwrite',1)); 34 | % Also note, we must create a new derivative file each time we change 35 | % meshes 36 | 37 | % --------------------------- Call fmincon ------------------------------ % 38 | if solveflag 39 | [z,fval] = ... 40 | fmincon(@(x)basic_objwrap(x,probinfo),guess,[],[],[],[],... 41 | lowerbound,upperbound,@(x)basic_conswrap(x,probinfo),options); 42 | else 43 | % No optimization toolbox, just test that functions work 44 | z = guess; 45 | [fval,G] = basic_objwrap(z,probinfo); 46 | [C,Ceq,JC,JCeq] = basic_conswrap(z,probinfo); 47 | end 48 | 49 | % --------------------------- Extract Solution -------------------------- % 50 | t = tau(:).*fval; 51 | X = z(probinfo.xind); 52 | U = z(probinfo.uind); 53 | time(i) = toc; 54 | 55 | % ---------------------------- Plot Solution ---------------------------- % 56 | figure(i); 57 | subplot(2,1,1) 58 | plot(t,X,'-o'); 59 | xlabel('time') 60 | ylabel('states') 61 | legend('x-position','y-position','speed','location','northwest') 62 | title(sprintf(['Mesh %1.0f Solution in ',num2str(time(i)),'s'],i)) 63 | subplot(2,1,2); 64 | plot(t,U,'-o'); 65 | xlabel('time') 66 | ylabel('control') 67 | end 68 | 69 | 70 | fprintf(['Total Time Supplying First Derivatives (non-vectorized): ',... 71 | num2str(sum(time)),'\n']); 72 | -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/main_basic_2ndderivs.m: -------------------------------------------------------------------------------- 1 | % This function solves the brachistochrone problem by supplying first and 2 | % second derivatives without taking advantage of the vectorized nature of 3 | % the problem. A wrapper file for the constraint and objective functions 4 | % (which call derivative files) are created and supplied in 5 | % basic_conswrap.m and basic_objwrap.m, respectively. The lagrangian 6 | % hessian is computed by taking the derivaive of the file basic_laggrad 7 | % which builds the lagrangian gradient. A wrapper file for the lagrangian 8 | % hessian is supplied in basic_laghess.m 9 | % 10 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 11 | % Distributed under the GNU General Public License version 3.0 12 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 13 | 14 | solveflag = exist('fmincon','file'); 15 | if solveflag 16 | options = optimset('Algorithm','interior-point','MaxFunEvals',50000,... 17 | 'GradObj','on','GradConstr','on','Display','iter'); 18 | end 19 | 20 | numintervals = [5,10,20,40]; 21 | time = zeros(length(numintervals),1); 22 | for i = 1:length(numintervals) 23 | start = tic; 24 | % ---------------------- Set Up the Problem ----------------------------- % 25 | if i == 1 26 | [probinfo,upperbound,lowerbound,guess,tau] = setupproblem(numintervals(i)); 27 | else 28 | % If on second or third mesh, use previous solution as initial guess 29 | [probinfo,upperbound,lowerbound,guess,tau] = ... 30 | setupproblem(numintervals(i),X,U,fval,tau); 31 | end 32 | % Need to redo this optimset each time as probinfo changes and is input to 33 | % basic_laggradwrap 34 | if solveflag 35 | options = optimset(options,'Hessian','user-supplied','HessFcn',... 36 | @(z,lambda)basic_laggradwrap(z,lambda,probinfo)); 37 | end 38 | 39 | % ----------------- Create Constraint Derivative File ------------------- % 40 | % NOTE: fmincon is given the function basic_conswrap which builds the 41 | % Jacobian by calling basic_cons_z 42 | gz = adigatorCreateDerivInput([length(guess), 1],'z'); 43 | outputs = adigator('basic_cons',{gz,probinfo},'basic_cons_z',adigatorOptions('overwrite',1)); 44 | 45 | % -------------- Create Lagrangian Gradient Derivative File ------------- % 46 | % NOTE: fmincon is given the function basic_laggradwrap which builds the 47 | % Lagrangian Hessian by calling basic_laggrad_z 48 | glambda = adigatorCreateAuxInput(outputs{2}.func.size); 49 | gH1 = adigator('basic_laggrad',{gz,glambda,probinfo},'basic_laggrad_z',... 50 | adigatorOptions('overwrite',1,'comments',0)); 51 | 52 | % --------------------------- Call fmincon ------------------------------ % 53 | if solveflag 54 | [z,fval] = ... 55 | fmincon(@(x)basic_objwrap(x,probinfo),guess,[],[],[],[],... 56 | lowerbound,upperbound,@(x)basic_conswrap(x,probinfo),options); 57 | else 58 | % No optimization toolbox, just test that functions work 59 | z = guess; 60 | [fval,G] = basic_objwrap(z,probinfo); 61 | [C,Ceq,JC,JCeq] = basic_conswrap(z,probinfo); 62 | lambda.eqnonlin = ones(length(Ceq),1); 63 | [H,G2] = basic_laggradwrap(z,lambda,probinfo); 64 | end 65 | 66 | % --------------------------- Extract Solution -------------------------- % 67 | t = tau(:).*fval; 68 | X = z(probinfo.xind); 69 | U = z(probinfo.uind); 70 | time(i) = toc(start); 71 | 72 | % ---------------------------- Plot Solution ---------------------------- % 73 | figure(i); 74 | subplot(2,1,1) 75 | plot(t,X,'-o'); 76 | xlabel('time') 77 | ylabel('states') 78 | legend('x-position','y-position','speed','location','northwest') 79 | title(sprintf(['Mesh %1.0f Solution in ',num2str(time(i)),'s'],i)) 80 | subplot(2,1,2); 81 | plot(t,U,'-o'); 82 | xlabel('time') 83 | ylabel('control') 84 | end 85 | 86 | fprintf(['Total Time Supplying Second Derivatives (non-vectorized): ',... 87 | num2str(sum(time)),'\n']); 88 | -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/main_noderivs.m: -------------------------------------------------------------------------------- 1 | % this function solves the brachistochrone problem supplying no derivatives 2 | % - the constraint function is built in basic_cons.m and the objective 3 | % function is built in basic_obj.m 4 | % 5 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 6 | % Distributed under the GNU General Public License version 3.0 7 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 8 | 9 | solveflag = exist('fmincon','file'); 10 | 11 | if solveflag 12 | options = optimset('Algorithm','interior-point','MaxFunEvals',50000,... 13 | 'Display','iter','GradObj','on'); 14 | time = zeros(3,1); 15 | numintervals = [5,10,20,40]; 16 | for i = 1:4 17 | tic; 18 | % ---------------------- Set Up the Problem ----------------------------- % 19 | if i == 1 20 | [probinfo,upperbound,lowerbound,guess,tau] = setupproblem(numintervals(i)); 21 | else 22 | % If on second or third mesh, use previous solution as initial guess 23 | [probinfo,upperbound,lowerbound,guess,tau] = ... 24 | setupproblem(numintervals(i),X,U,fval,tau); 25 | end 26 | 27 | % --------------------------- Call fmincon ------------------------------ % 28 | [z,fval] = ... 29 | fmincon(@(x)basic_objwrap(x,probinfo),guess,[],[],[],[],... 30 | lowerbound,upperbound,@(x)basic_cons(x,probinfo),options); 31 | 32 | % --------------------------- Extract Solution -------------------------- % 33 | t = tau(:).*fval; 34 | X = z(probinfo.xind); 35 | U = z(probinfo.uind); 36 | time(i) = toc; 37 | 38 | % ---------------------------- Plot Solution ---------------------------- % 39 | figure(i); 40 | subplot(2,1,1) 41 | plot(t,X,'-o'); 42 | xlabel('time') 43 | ylabel('states') 44 | legend('x-position','y-position','speed','location','northwest') 45 | title(sprintf(['Mesh %1.0f Solution in ',num2str(time(i)),'s'],i)) 46 | subplot(2,1,2); 47 | plot(t,U,'-o'); 48 | xlabel('time') 49 | ylabel('control') 50 | end 51 | 52 | fprintf(['Total Time Supplying No Derivatives: ',num2str(sum(time)),'\n']); 53 | else 54 | fprintf('Example requires optimization toolbox\n'); 55 | end 56 | -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/setupproblem.m: -------------------------------------------------------------------------------- 1 | function [probinfo,upperbound,lowerbound,guess, tau] = setupproblem(numintervals,varargin) 2 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 3 | % Distributed under the GNU General Public License version 3.0 4 | n = 3; 5 | m = 1; 6 | 7 | K = numintervals; 8 | N = numintervals*2+1; 9 | probinfo.numintervals = numintervals; 10 | probinfo.n = n; 11 | probinfo.m = m; 12 | 13 | probinfo.k = 1:2:N-1; 14 | probinfo.kbp1 = probinfo.k+1; 15 | probinfo.kp1 = probinfo.k+2; 16 | 17 | probinfo.xind = reshape(1:n*N,N,n); 18 | probinfo.uind = reshape(n*N+1:n*N+m*N,N,m); 19 | probinfo.tfind = probinfo.uind(end)+1; 20 | 21 | 22 | % Set Bounds; 23 | numvars = probinfo.tfind; 24 | upperbound = zeros(numvars,1); 25 | lowerbound = zeros(numvars,1); 26 | % State 27 | upperbound(probinfo.xind) = 10; 28 | lowerbound(probinfo.xind(:,1:2)) = -10; 29 | lowerbound(probinfo.xind(:,3)) = 0; 30 | % Set state boundary conditions 31 | x0ind = probinfo.xind(1,:); 32 | upperbound(x0ind) = 0; 33 | lowerbound(x0ind) = 0; 34 | xfind = probinfo.xind(end,:); 35 | upperbound(xfind(1:2)) = [2;-2]; 36 | lowerbound(xfind(1:2)) = [2;-2]; 37 | 38 | % Control 39 | upperbound(probinfo.uind) = pi; 40 | lowerbound(probinfo.uind) = -pi; 41 | % tf 42 | upperbound(probinfo.tfind) = 5; 43 | lowerbound(probinfo.tfind) = 0; 44 | 45 | 46 | tau = linspace(0,1,N); 47 | %taum = linspace(0,1,K+1); 48 | 49 | % Set Guesses 50 | guess = zeros(numvars,1); 51 | if nargin == 1 52 | guess(probinfo.xind(:,1)) = linspace(0,2,N); 53 | guess(probinfo.xind(:,2)) = linspace(0,-2,N); 54 | guess(probinfo.xind(:,3)) = linspace(0,0,N); 55 | guess(probinfo.uind) = linspace(-pi,pi,N); 56 | guess(probinfo.tfind) = 1; 57 | else 58 | Xold = varargin{1}; 59 | Uold = varargin{2}; 60 | tfold = varargin{3}; 61 | tauold = varargin{4}; 62 | guess(probinfo.xind) = interp1(tauold(:),Xold,tau(:)); 63 | guess(probinfo.uind) = interp1(tauold(:),Uold,tau(:)); 64 | guess(probinfo.tfind) = tfold; 65 | end 66 | 67 | % % Build A and B s.t. 68 | % % C = A*X + tf*B*F(X,U) 69 | % 70 | % % Letting i be first point in interval, j be second, k be third, and let 71 | % % dt be difference in tau for respective interval 72 | % % C1 = (-1/2*Xi) + (1*Xj) + (-1/2*Xk) + tf*dt*[(-1/8*Fi) + (0*Fj) + (1/8*Fk)] 73 | % % C2 = (-1*Xi) + (0*Xj) + (1*Xk) + tf*dt*[(-1/6*Fi) + (-4/6*Fj) + (-1/6*Fk)] 74 | % 75 | % I = repmat(1:K,3,1); 76 | % J = repmat((1:3).',1,K)+repmat(0:2:2*(K-1),3,1); 77 | % A1v = repmat([-1/2; 1; -1/2],1,K); 78 | % A2v = repmat([ -1; 0; 1],1,K); 79 | % 80 | % deltatau = diag(diff(taum)); 81 | % B1v = repmat([-1/8; 0; 1/8],1,K)*deltatau; 82 | % B2v = repmat([-1/6; -4/6; -1/6],1,K)*deltatau; 83 | % 84 | % A1 = sparse(I,J,A1v,K,N); 85 | % A2 = sparse(I,J,A2v,K,N); 86 | % B1 = sparse(I,J,B1v,K,N); 87 | % B2 = sparse(I,J,B2v,K,N); 88 | % 89 | % probinfo.A = [A1;A2]; 90 | % probinfo.B = [B1;B2]; 91 | end -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/vect_cons.m: -------------------------------------------------------------------------------- 1 | function Ceq = vect_cons(X,F,tf,probinfo) 2 | 3 | % Calculate h 4 | numintervals = probinfo.numintervals; 5 | h = tf/numintervals; 6 | 7 | % Get Reference Indices 8 | k = probinfo.k; 9 | kbp1 = probinfo.kbp1; 10 | kp1 = probinfo.kp1; 11 | 12 | Xk = X(k,:); 13 | Xkbp1 = X(kbp1,:); 14 | Xkp1 = X(kp1,:); 15 | 16 | Fk = F(k,:); 17 | Fkbp1 = F(kbp1,:); 18 | Fkp1 = F(kp1,:); 19 | 20 | % Dynamic Constraints 21 | C1 = Xkbp1 - 1/2.*(Xkp1+Xk) - h/8.*(Fk-Fkp1); 22 | C2 = Xkp1 - Xk - h/6.*(Fkp1 + 4.*Fkbp1 + Fk); 23 | 24 | Ceq = [C1(:);C2(:)]; -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/vect_conswrap.m: -------------------------------------------------------------------------------- 1 | function [C,Ceq,JC,JCeq] = vect_conswrap(z,probinfo) 2 | 3 | C = []; 4 | JC = []; 5 | if nargout > 2 6 | % Create Vectorized Inputs 7 | Xvec.f = z(probinfo.xind); 8 | Xvec.dY = ones(size(Xvec.f)); 9 | Uvec.f = z(probinfo.uind); 10 | Uvec.dY = ones(size(Uvec.f)); 11 | 12 | % Get Vectorized Derivs 13 | Fvec = dynamics_Y(Xvec,Uvec); 14 | 15 | % Create Non-Vectorized Inputs 16 | X.f = Xvec.f; 17 | X.dz = Xvec.dY(:); 18 | F.f = Fvec.f; 19 | F.dz = Fvec.dY(probinfo.dFind); 20 | tf.f = z(probinfo.tfind); 21 | tf.dz = 1; 22 | 23 | Ceq = vect_cons_z(X,F,tf,probinfo); 24 | JCeq = sparse(Ceq.dz_location(:,1),Ceq.dz_location(:,2),Ceq.dz,... 25 | Ceq.dz_size(1),Ceq.dz_size(2)).'; 26 | Ceq = Ceq.f; 27 | 28 | else 29 | X = z(probinfo.xind); 30 | U = z(probinfo.uind); 31 | tf = z(probinfo.tfind); 32 | F = dynamics(X,U); 33 | Ceq = vect_cons(X,F,tf,probinfo); 34 | end -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/vect_laggrad.m: -------------------------------------------------------------------------------- 1 | function GL = vect_laggrad(Xf,dX,Ff,dF,tff,dtf,lambda,probinfo) 2 | 3 | % Make inputs for vect_cons_z 4 | x.f = Xf; 5 | x.dz = dX; 6 | f.f = Ff; 7 | f.dz = dF; 8 | tf.f = tff; 9 | tf.dz = dtf; 10 | 11 | % Build Constraint Jacobian 12 | C = vect_cons_z(x,f,tf,probinfo); 13 | JC = sparse(C.dz_location(:,1),C.dz_location(:,2),... 14 | C.dz,C.dz_size(1),C.dz_size(2)); 15 | 16 | % Build Objective Gradient 17 | GO = sparse(1,probinfo.tfind,1,1,probinfo.tfind); 18 | 19 | % Build Lagrangian Gradient 20 | GL = GO + lambda.'*JC; -------------------------------------------------------------------------------- /examples/optimization/vectorized/brachistochrone/vect_laggradwrap.m: -------------------------------------------------------------------------------- 1 | function [H,G] = vect_laggradwrap(z,lambda,probinfo) 2 | 3 | 4 | % Create Vectorized Inputs 5 | Xvec.f = z(probinfo.xind); 6 | Xvec.dY = ones(size(Xvec.f)); 7 | Uvec.f = z(probinfo.uind); 8 | Uvec.dY = ones(size(Uvec.f)); 9 | 10 | % Get Vectorized Derivs 11 | Fvec = dynamics_YY(Xvec,Uvec); 12 | 13 | 14 | 15 | % Create Non-Vectorized Inputs 16 | X.f = Xvec.f; 17 | X.dz = Xvec.dY(:); 18 | dX = X.dz; 19 | 20 | 21 | F.f = Fvec.f; 22 | F.dz = Fvec.dY(probinfo.dFind); 23 | dF.f = F.dz; 24 | dF.dz = Fvec.dYdY(probinfo.dF2ind); 25 | 26 | tf.f = z(probinfo.tfind); 27 | tf.dz = 1; 28 | dtf = tf.dz; 29 | 30 | 31 | GL = vect_laggrad_z(X,dX,F,dF,tf,dtf,lambda.eqnonlin,probinfo); 32 | 33 | H = sparse(GL.dz_location(:,1),GL.dz_location(:,2),GL.dz,... 34 | GL.dz_size(1),GL.dz_size(2)); 35 | 36 | G = GL.f; -------------------------------------------------------------------------------- /examples/optimization/vectorized/minimumclimb/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator minimum time to climb example w/ fmincon 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % basic_objwrap.m - objective wrapper 9 | % conswrap.m - constraint wrapper 10 | % dynamics.m - dynamics file 11 | % laghesswrap.m - lagrangian hessian wrapper 12 | % main_1stderivs_nonvect.m - solve with 1st derivatives, non-vect 13 | % main_1stderivs_vect.m - solve with 1st derivatives, vect 14 | % main_2ndderivs_nonvect.m - solve with 1st derivatives, non-vect 15 | % main_2ndderivs_vect.m - solve with 2nd derivatives, vect 16 | % setupproblem.m - get initial guess, set up hermite-simpson 17 | % collocation 18 | -------------------------------------------------------------------------------- /examples/optimization/vectorized/minimumclimb/basic_objwrap.m: -------------------------------------------------------------------------------- 1 | function [tf,G] = basic_objwrap(z,probinfo) 2 | 3 | tf = z(probinfo.tfind); 4 | if nargout > 1 5 | G = sparse(1,probinfo.tfind,1,1,probinfo.tfind); 6 | end -------------------------------------------------------------------------------- /examples/optimization/vectorized/minimumclimb/conswrap.m: -------------------------------------------------------------------------------- 1 | function [C,Ceq,JC,JCeq] = conswrap(z,probinfo) 2 | % This function builds the derivatives of C wrt z by calling the dynamics 3 | % derivative file which computes the derivatives of F wrt y, where % 4 | % y = [X U], z = [y tf]. This is done using the fact that C is written as 5 | % C = A*X + tf*B*F(X,U). Thus, we only take the derivatives of F and use 6 | % linear algebra to build the derivative of C. Note: C is a matrix of size 7 | % (N-1) by n, so we unroll this to create a vector of constraints, that is, 8 | % C = C(:), and when we say C, we mean Ceq since we only have equality 9 | % constraints. We build this as follows: 10 | % C = A*X + tf*B*F(X,U) 11 | % dCdX = A*dXdX + tf*B*dFdX 12 | % dCdU = tf*B*dFdU 13 | % dCdtf = B*F 14 | % dCdz = [dCdX dCdU dCdtf] 15 | % Where the derivative matrix multiplications must be achieved by 16 | % unrolling dimensions of the derivative matrices. 17 | % 18 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 19 | % Distributed under the GNU General Public License version 3.0 20 | n = probinfo.n; % Number of states 21 | m = probinfo.m; % Number of controls 22 | N = probinfo.N; % Number of collocation points 23 | 24 | A = probinfo.A; % A is size (N-1) by N 25 | B = probinfo.B; % B is size (N-1) by N 26 | 27 | % C = A*X + B*F(X,U) is size (N-1) by n 28 | 29 | C = []; 30 | JC = []; 31 | if nargout == 2 32 | % Doesn't want derivatives 33 | X = z(probinfo.xind); 34 | U = z(probinfo.uind); 35 | tf = z(probinfo.tfind); 36 | F = dynamics(X,U,probinfo); 37 | Ceq = probinfo.A*X + tf.*probinfo.B*F; 38 | else 39 | X.f = z(probinfo.xind); % X is size N by n 40 | U.f = z(probinfo.uind); % U is size N by m 41 | tf = z(probinfo.tfind); % tf is size 1 by 1 42 | 43 | % dFdy is of dimension N by n by N*(n+m), in this section we unroll 44 | % the first two dimensions such that our dFdy is of dimension 45 | % N*n by N*(n+m) 46 | mFy = N*n; 47 | nFy = N*(n+m); 48 | if probinfo.vectders 49 | % Vectorized Derivatives 50 | X.dY = ones(size(X.f)); 51 | U.dY = ones(size(U.f)); 52 | 53 | F = dynamics_yvect(X,U,probinfo); % F is size N by n 54 | iFy = probinfo.iFy; % previously calculated to roll 1st 2 dims 55 | jFy = probinfo.jFy; % (by adigatorProjectVectLocs) 56 | dFdy = sparse(iFy,jFy,F.dY,mFy,nFy); 57 | else 58 | % Non-Vectorized Derivatives 59 | X.dy = ones(numel(X.f),1); 60 | U.dy = ones(numel(U.f),1); 61 | 62 | F = dynamics_y(X,U,probinfo); % F is size N by n 63 | % Roll first two dimensions 64 | iFy = sub2ind(F.dy_size(1:2),F.dy_location(:,1),F.dy_location(:,2)); 65 | jFy = F.dy_location(:,3); 66 | dFdy = sparse(iFy,jFy,F.dy,mFy,nFy); 67 | end 68 | 69 | % Extract and reshape dFdX, dFdU, and build dXdX 70 | % Here we switch from 71 | % dXdX in N*n by N*n to N by n*N*n 72 | % dFdX in N*n by N*n to N by n*N*n 73 | % dFdU in N*n by N*m to N by n*N*m 74 | dXdX = reshape(sparse(1:N*n,1:N*n,1,N*n,N*n),[N,n*N*n]); 75 | dFdX = reshape(dFdy(:,probinfo.xind(:)), [N,n*N*n]); 76 | dFdU = reshape(dFdy(:,probinfo.uind(:)), [N,n*N*m]); 77 | % dXdX, dFdX and dFdU are now in their reshaped, unrolled form. 78 | 79 | 80 | % The output of this is derivative of C wrt z, where z = [X(:); U(:); tf] 81 | % It is given in the unrolled form, thus 82 | % C is size N-1 by 1 83 | % dCdz is size N-1 by (m+n)*N+1 84 | 85 | % Constraints 86 | Ceq = A*X.f + tf*B*F.f; % (N-1) by n 87 | Ceq = reshape(Ceq, [(N-1)*n,1]); % (N-1)*n by 1 88 | 89 | % Derivative wrt x 90 | dCdX = A*dXdX + tf.*B*dFdX; % (N-1) by n*N*n 91 | dCdX = reshape(dCdX, [(N-1)*n,n*N]); % (N-1)*n by N*n 92 | 93 | % Derivative wrt u 94 | dCdU = tf.*B*dFdU; % (N-1) by n*N*m 95 | dCdU = reshape(dCdU, [(N-1)*n,m*N]); % (N-1)*n by N*m 96 | 97 | % Derivative wrt tf 98 | dCdtf = B*F.f; % (N-1) by n 99 | dCdtf = reshape(dCdtf,[(N-1)*n,1]); % (N-1)*n by 1 100 | 101 | % Build dCdz 102 | dCdz = [dCdX dCdU dCdtf]; % (N-1)*n by N*(m+n) + 1 103 | 104 | % fmincon takes the transpose of it. 105 | JCeq = dCdz.'; 106 | end 107 | -------------------------------------------------------------------------------- /examples/optimization/vectorized/minimumclimb/dynamics.m: -------------------------------------------------------------------------------- 1 | function daeout = dynamics(x,u,probinfo) 2 | 3 | CONSTANTS = probinfo.CONSTANTS; 4 | 5 | CoF = CONSTANTS.CoF; 6 | 7 | h = x(:,1); 8 | v = x(:,2); 9 | fpa = x(:,3); 10 | 11 | c1 = 392.4; c2 = 16818; c3 = 86.138; 12 | c4 = 288.14; c5 = 6.49; c6 = 4.0519e9; 13 | c7 = 288.08; c8 = 5.256; c9 = 216.64; 14 | c10 = 9.06e8; c11 = 1.73; c12 = 0.157; 15 | c13 = 6e-5; c14 = 4.00936; c15 = 2.2; 16 | 17 | Nzeros = zeros(size(h)); 18 | T = Nzeros; 19 | p = Nzeros; 20 | 21 | ihlow = h < 11000; 22 | T(ihlow) = c4 - c5*h(ihlow); 23 | p(ihlow) = c6*(T(ihlow)./c7).^c8; 24 | 25 | ihhigh = ~ihlow; 26 | T(ihhigh) = c9; 27 | p(ihhigh) = c10* exp(c11 - c12*h(ihhigh)); 28 | 29 | rho = c3*p./T; 30 | q = 0.5.*rho.*v.*v.*c13; 31 | 32 | a = c14.*sqrt(T); M = v./a; 33 | Mp = cell(1,6); 34 | for i = 1:6 35 | Mp{i} = M.^(i-1); 36 | end 37 | 38 | numeratorCD0 = Nzeros; denominatorCD0 = Nzeros; 39 | numeratorK = Nzeros; denominatorK = Nzeros; 40 | for i = 1:6 41 | Mpi = Mp{i}; 42 | if i < 6 43 | numeratorCD0 = numeratorCD0 + CoF(1,i).*Mpi; 44 | denominatorCD0 = denominatorCD0 + CoF(2,i).*Mpi; 45 | numeratorK = numeratorK + CoF(3,i).*Mpi; 46 | end 47 | denominatorK = denominatorK + CoF(4,i).*Mpi; 48 | end 49 | Cd0 = numeratorCD0./denominatorCD0; 50 | K = numeratorK./denominatorK; 51 | FD = q.*(Cd0+K.*((c2^2).*(c1^2)./(q.^2)).*(u.^2)); 52 | 53 | FT = Nzeros; 54 | for i = 1:6 55 | ei = Nzeros; 56 | for j = 1:6 57 | ei = ei + CoF(4+j,i).*Mp{j}; 58 | end 59 | FT = FT + ei.*h.^(i-1); 60 | end 61 | FT = FT.*c1/c15; 62 | 63 | hdot = v.*sin(fpa); 64 | vdot = (FT-FD)./c2 - c1.*sin(fpa); 65 | fpadot = c1.*(u-cos(fpa))./v; 66 | 67 | daeout = [hdot vdot fpadot]; -------------------------------------------------------------------------------- /examples/optimization/vectorized/minimumclimb/laghesswrap.m: -------------------------------------------------------------------------------- 1 | function Lzz = laghesswrap(z,lambda,probinfo) 2 | % This function builds the Hessian of the Langrangian, where the Lagrangian 3 | % is defined by L = tf + lambda.'*[AA*X + tf*BB*F(X,U)], where AA and BB 4 | % are matrices of size (N-1)*n by N*n, consisting of the matrices A and B, 5 | % respectively, lying on the block diagonals. This function calls second 6 | % derivative files of the dynamics file which computes F(X,U). It then uses 7 | % linear algebra to build the second derivative of L wrt z, Lzz, using the 8 | % outputs of the derivative, Fy, and Fyy, where y = [X U], z = [y tf]. 9 | % This is done as follows: 10 | % L = tf + lambda.'*[AA*X + tf*BB*F(y)] size 1 by 1 11 | % Ly = lambda.'*[AA*[1 0] + tf*BB*Fy] size 1 by N*(n+m) 12 | % Ltf = 1 + lambda.'*BB*F(y) size 1 by 1 13 | % Lyy = tf*lambda.'*BB*Fyy size N*(n+m) by N*(n+m) 14 | % Ltfy = lambda.'*BB*Fy size 1 by N*(n+m) 15 | % Lytf = Ltfy.' size N*(n+m) by 1 16 | % Ltftf = 0 size 1 by 1 17 | % Lzz = [Lyy Lytf] size N*(n+m)+1 by N*(n+m)+1 18 | % [Ltfy 0] 19 | % Where the derivative matrix multiplications must be achieved by unrolling 20 | % dimensions of the derivative matrices. 21 | % 22 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 23 | % Distributed under the GNU General Public License version 3.0 24 | n = probinfo.n; % Number of states 25 | m = probinfo.m; % Number of controls 26 | N = probinfo.N; % Number of collocation points 27 | 28 | lambda = sparse(lambda.eqnonlin); % Lambda is size 1 by (N-1)*n 29 | 30 | 31 | X.f = z(probinfo.xind); % X is size N by n 32 | U.f = z(probinfo.uind); % U is size N by m 33 | tf = z(probinfo.tfind); % tf is size 1 by 1 34 | 35 | 36 | BB = probinfo.BB; % BB is of size (N-1)*n by N*n 37 | 38 | % Fy is of dimension N by n by N*(n+m), we will need this to compute 39 | % Lytf, so we roll the first two dimensions such that Fy is of size 40 | % N*n by N*(n+m) 41 | mFy = N*n; 42 | nFy = N*(n+m); 43 | % Fyy is of dimension N by n by N*(n+m) by N*(n+m), we will need this to 44 | % compute Lyy, so we roll the first two dimensions and the last two 45 | % dimensions such that Fyy is of dimension N*n by N*(n+m)*N*(n+m) 46 | mFyy = N*n; 47 | nFyy = N*(n+m)*N*(n+m); 48 | if probinfo.vectders 49 | % Vectorized Derivatives 50 | X.dY = ones(size(X.f)); 51 | U.dY = ones(size(U.f)); 52 | 53 | F = dynamics_yyvect(X,U,probinfo); 54 | 55 | % Build Fy 56 | iFy = probinfo.iFy; % previously calculated to roll first 2 dims 57 | jFy = probinfo.jFy; 58 | Fy = sparse(iFy,jFy,F.dY,mFy,nFy); 59 | 60 | % Build Fyy 61 | iFyy = probinfo.iFyy; % previously calculated to roll first 2 dims 62 | jFyy = probinfo.jFyy; % previously calculated to roll last 2 dims 63 | Fyy = sparse(iFyy,jFyy,F.dYdY,mFyy,nFyy); 64 | else 65 | % Non-Vectorized Derivatives 66 | X.dy = ones(numel(X.f),1); 67 | U.dy = ones(numel(U.f),1); 68 | 69 | F = dynamics_yy(X,U,probinfo); 70 | 71 | % Build Fy 72 | % Unroll first two dimensions 73 | iFy = sub2ind(F.dy_size(1:2),F.dy_location(:,1),F.dy_location(:,2)); 74 | jFy = F.dy_location(:,3); 75 | Fy = sparse(iFy,jFy,F.dy,mFy,nFy); 76 | 77 | % Build Fyy 78 | % Unroll first two dimensions 79 | iFyy = sub2ind(F.dydy_size(1:2),F.dydy_location(:,1),F.dydy_location(:,2)); 80 | % Unroll last two dimensions 81 | jFyy = sub2ind(F.dydy_size(3:4),F.dydy_location(:,3),F.dydy_location(:,4)); 82 | Fyy = sparse(iFyy,jFyy,F.dydy,mFyy,nFyy); 83 | end 84 | 85 | % Lyy 86 | Lyy = tf*lambda.'*BB*Fyy; % 1 by N*(n+m)*N*(n+m) 87 | Lyy = reshape(Lyy,[N*(n+m) N*(n+m)]); % N*(n+m) by N*(n+m) 88 | 89 | % Ltfy 90 | Ltfy = lambda.'*BB*Fy; % 1 by N*(n+m) 91 | Lytf = Ltfy.'; % N*(n+m) by 1 92 | 93 | % Lzz 94 | Lzz = [Lyy Lytf;Ltfy 0]; -------------------------------------------------------------------------------- /examples/optimization/vectorized/minimumclimb/main_1stderivs_nonvect.m: -------------------------------------------------------------------------------- 1 | % This function solves the minimum time to climb problem by supplying first 2 | % derivatives without taking advantage of the vectorized nature of the 3 | % problem. A derivative file for the dynamics is created as dynamics_y 4 | % and these derivatives are used to build the constraint jacobian within 5 | % the file conswrap.m 6 | % 7 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 8 | % Distributed under the GNU General Public License version 3.0 9 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 10 | solveflag = exist('fmincon','file'); 11 | if solveflag 12 | options = optimset('Algorithm','interior-point','MaxFunEvals',50000,... 13 | 'GradObj','on','GradConstr','on','Display','iter','MaxIter',1000); 14 | end 15 | time = zeros(4,1); 16 | numintervals = [10,20,40]; 17 | 18 | for i = 1:3 19 | tic; 20 | % ---------------------- Set Up the Problem ----------------------------- % 21 | if i == 1 22 | [probinfo,upperbound,lowerbound,guess,tau] = setupproblem(numintervals(i)); 23 | else 24 | % If on second or third mesh, use previous solution as initial guess 25 | [probinfo,upperbound,lowerbound,guess,tau] = ... 26 | setupproblem(numintervals(i),X,U,fval,tau); 27 | end 28 | 29 | % ------------------- Create Dynamics Derivative File ------------------- % 30 | % NOTE: fmincon is given the function conswrap which builds the 31 | % Jacobian by calling dynamics_y 32 | 33 | % Inputs to dynamics file are X,U,probinfo 34 | % X is size N by n 35 | % U is size N by m 36 | % Let y = [X(:);U(:)] - take derivatives of dynamics file wrt y 37 | % Note: our decision vector is z = [y;tf], and dynamics file is not a 38 | % function of tf, thus dFdz = [dFdy zeros((N+1)*n,1] 39 | n = probinfo.n; m = probinfo.m; N = probinfo.N; 40 | probinfo.vectders = 0; 41 | gX = adigatorCreateDerivInput([N n],... 42 | struct('vodname','y','vodsize',[(m+n)*N 1],... 43 | 'nzlocs',[probinfo.xind(:) probinfo.xind(:)])); 44 | gU = adigatorCreateDerivInput([N m],... 45 | struct('vodname','y','vodsize',[(m+n)*N 1],... 46 | 'nzlocs',[(1:m*N).' probinfo.uind(:)])); 47 | adigator('dynamics',{gX,gU,probinfo},'dynamics_y',adigatorOptions('overwrite',1)); 48 | % Also note, we must create a new derivative file each time we change 49 | % meshes 50 | 51 | % --------------------------- Call fmincon ------------------------------ % 52 | if solveflag 53 | [z,fval] = ... 54 | fmincon(@(x)basic_objwrap(x,probinfo),guess,[],[],[],[],... 55 | lowerbound,upperbound,@(x)conswrap(x,probinfo),options); 56 | else 57 | % just run this for 30 jacobian evaluations 58 | z = guess; 59 | for k = 1:30 60 | [C,Ceq,JC,JCeq] = conswrap(z,probinfo); 61 | [fval,G] = basic_objwrap(z,probinfo); 62 | end 63 | end 64 | 65 | % --------------------------- Extract Solution -------------------------- % 66 | t = tau(:).*z(end); 67 | X = z(probinfo.xind); 68 | U = z(probinfo.uind); 69 | time(i) = toc; 70 | 71 | % ---------------------------- Plot Solution ---------------------------- % 72 | if solveflag 73 | disp(z(end)) 74 | figure(i); 75 | subplot(2,1,1) 76 | plot(t,X,'-o'); 77 | xlabel('time') 78 | ylabel('states') 79 | title(sprintf(['Mesh %1.0f Solution in ',num2str(time(i)),'s'],i)) 80 | subplot(2,1,2); 81 | plot(t,U,'-o'); 82 | xlabel('time') 83 | ylabel('control') 84 | end 85 | end 86 | 87 | 88 | fprintf(['Total Time Supplying First Derivatives (non-vectorized): ',... 89 | num2str(sum(time)),'\n']); 90 | -------------------------------------------------------------------------------- /examples/optimization/vectorized/minimumclimb/main_1stderivs_vect.m: -------------------------------------------------------------------------------- 1 | % This function solves the minimum time to climb problem by supplying first 2 | % derivatives which take advantage of the vectorized nature of the problem. 3 | % A derivative file for the dynamics is created as dynamics_yvect and these 4 | % derivatives are used to build the constraint jacobian within the file 5 | % conswrap.m 6 | % 7 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 8 | % Distributed under the GNU General Public License version 3.0 9 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 10 | solveflag = exist('fmincon','file'); 11 | if solveflag 12 | options = optimset('Algorithm','interior-point','MaxFunEvals',50000,... 13 | 'GradObj','on','GradConstr','on','Display','iter','MaxIter',1000); 14 | end 15 | time = zeros(4,1); 16 | numintervals = [10,20,40]; 17 | [probinfo,upperbound,lowerbound,guess,tau] = setupproblem(numintervals(1)); 18 | % ------------------- Create Dynamics Derivative File ------------------- % 19 | % Since we are doing this vectorized, we only need to take derivatives once 20 | % Inputs to dynamics file are X,U,probinfo 21 | % X is size N by n 22 | % U is size N by m 23 | % Let y(t) = [x(t) u(t)], Y = [X U], taking derivatives of dynamics file 24 | % wrt y(t). 25 | % Note: our decision vector, z, is of form z = [Y(:);tf], and dynamics file 26 | % is not a function of tf. 27 | tic 28 | n = 3; m = 1; 29 | gX = adigatorCreateDerivInput([Inf n],... 30 | struct('vodname','Y','vodsize',[Inf (m+n)],... 31 | 'nzlocs',[(1:n).' (1:n).'])); 32 | gU = adigatorCreateDerivInput([Inf m],... 33 | struct('vodname','Y','vodsize',[Inf (m+n)],... 34 | 'nzlocs',[(1:m).' (n+1:m+n).'])); 35 | gOut = adigator('dynamics',{gX,gU,probinfo},'dynamics_yvect',... 36 | adigatorOptions('overwrite',1)); 37 | % We can now extract sparsity pattern of dF(t)/dy(t) 38 | iFy = gOut{1}.deriv.nzlocs(:,1); 39 | jFy = gOut{1}.deriv.nzlocs(:,2); 40 | time(1) = toc; 41 | 42 | for i = 1:3 43 | tic; 44 | % ---------------------- Set Up the Problem ----------------------------- % 45 | if i > 1 46 | % If on second or third mesh, use previous solution as initial guess 47 | [probinfo,upperbound,lowerbound,guess,tau] = ... 48 | setupproblem(numintervals(i),X,U,fval,tau); 49 | end 50 | % ----------------------- Project Deriv Indices ------------------------- % 51 | % We have already created the derivative file, but now that we have fixed 52 | % the vectorized dimension, we can find the unrolled locations of the 53 | % unrolled derivative. We do this here rather than on each derivative 54 | % evaluation to save time. 55 | [probinfo.iFy, probinfo.jFy] = adigatorProjectVectLocs(probinfo.N,iFy,jFy); 56 | probinfo.vectders = 1; 57 | 58 | % --------------------------- Call fmincon ------------------------------ % 59 | if solveflag 60 | [z,fval] = ... 61 | fmincon(@(x)basic_objwrap(x,probinfo),guess,[],[],[],[],... 62 | lowerbound,upperbound,@(x)conswrap(x,probinfo),options); 63 | else 64 | % just run this for 30 jacobian evaluations 65 | z = guess; 66 | for k = 1:30 67 | [C,Ceq,JC,JCeq] = conswrap(z,probinfo); 68 | [fval,G] = basic_objwrap(z,probinfo); 69 | end 70 | end 71 | 72 | % --------------------------- Extract Solution -------------------------- % 73 | t = tau(:).*z(end); 74 | X = z(probinfo.xind); 75 | U = z(probinfo.uind); 76 | time(i) = time(i) + toc; 77 | 78 | % ---------------------------- Plot Solution ---------------------------- % 79 | if solveflag 80 | disp(z(end)) 81 | figure(i); 82 | subplot(2,1,1) 83 | plot(t,X,'-o'); 84 | xlabel('time') 85 | ylabel('states') 86 | title(sprintf(['Mesh %1.0f Solution in ',num2str(time(i)),'s'],i)) 87 | subplot(2,1,2); 88 | plot(t,U,'-o'); 89 | xlabel('time') 90 | ylabel('control') 91 | end 92 | end 93 | 94 | 95 | fprintf(['Total Time Supplying First Derivatives (vectorized): ',... 96 | num2str(sum(time)),'\n']); 97 | -------------------------------------------------------------------------------- /examples/optimization/vectorized/minimumclimb/main_2ndderivs_nonvect.m: -------------------------------------------------------------------------------- 1 | % This function solves the minimum time to climb problem by supplying first 2 | % and second derivatives without advantage of the vectorized nature of the 3 | % problem. A derivative file for the dynamics is created as dynamics_yvect 4 | % and these derivatives are used to build the constraint jacobian within 5 | % the file conswrap.m. Also, a second derivative file for the dynamics is 6 | % created as dynamics_yyvect, these derivatives, along with the first 7 | % derivatives, are used to build the lagrangian hessian within the file 8 | % laghesswrap.m. 9 | % 10 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 11 | % Distributed under the GNU General Public License version 3.0 12 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 13 | solveflag = exist('fmincon','file'); 14 | if solveflag 15 | options = optimset('Algorithm','interior-point','MaxFunEvals',50000,... 16 | 'GradObj','on','GradConstr','on','Display','iter','MaxIter',1000); 17 | end 18 | time = zeros(4,1); 19 | numintervals = [10,20,40]; 20 | for i = 1:3 21 | tic; 22 | % ---------------------- Set Up the Problem ----------------------------- % 23 | if i == 1 24 | [probinfo,upperbound,lowerbound,guess,tau] = setupproblem(numintervals(i)); 25 | else 26 | % If on second or third mesh, use previous solution as initial guess 27 | [probinfo,upperbound,lowerbound,guess,tau] = ... 28 | setupproblem(numintervals(i),X,U,fval,tau); 29 | end 30 | probinfo.vectders = 0; 31 | if solveflag 32 | options = optimset(options,'Hessian','user-supplied','HessFcn',... 33 | @(z,lambda)laghesswrap(z,lambda,probinfo)); 34 | end 35 | % ------------------- Create Dynamics Derivative File ------------------- % 36 | % NOTE: fmincon is given the function conswrap which builds the 37 | % Jacobian by calling dynamics_y 38 | 39 | % Inputs to dynamics file are X,U,probinfo 40 | % X is size N by n 41 | % U is size N by m 42 | % Let y = [X(:);U(:)] - take derivatives of dynamics file wrt y 43 | % Note: our decision vector is z = [y;tf], and dynamics file is not a 44 | % function of tf, thus dFdz = [dFdy zeros((N+1)*n,1] 45 | n = probinfo.n; m = probinfo.m; N = probinfo.N; 46 | 47 | gX = adigatorCreateDerivInput([N n],... 48 | struct('vodname','y','vodsize',[(m+n)*N 1],... 49 | 'nzlocs',[probinfo.xind(:) probinfo.xind(:)])); 50 | gU = adigatorCreateDerivInput([N m],... 51 | struct('vodname','y','vodsize',[(m+n)*N 1],... 52 | 'nzlocs',[(1:m*N).' probinfo.uind(:)])); 53 | adigator('dynamics',{gX,gU,probinfo},'dynamics_y',... 54 | adigatorOptions('overwrite',1)); 55 | % Make new vars for gX,gU 56 | gX = struct('f',gX,'dy',ones(n*N,1)); 57 | gU = struct('f',gU,'dy',ones(m*N,1)); 58 | adigator('dynamics_y',{gX,gU,probinfo},'dynamics_yy',... 59 | adigatorOptions('overwrite',1,'comments',0)); 60 | % Also note, we must create new derivative files each time we change 61 | % meshes 62 | 63 | % --------------------------- Call fmincon ------------------------------ % 64 | if solveflag 65 | [z,fval] = ... 66 | fmincon(@(x)basic_objwrap(x,probinfo),guess,[],[],[],[],... 67 | lowerbound,upperbound,@(x)conswrap(x,probinfo),options); 68 | else 69 | % just run this for 30 jacobian/hessian evaluations 70 | z = guess; 71 | ldummy.eqnonlin = ones((N-1)*n,1); 72 | for k = 1:30 73 | H = laghesswrap(z,ldummy,probinfo); 74 | [C,Ceq,JC,JCeq] = conswrap(z,probinfo); 75 | [fval,G] = basic_objwrap(z,probinfo); 76 | end 77 | end 78 | 79 | % --------------------------- Extract Solution -------------------------- % 80 | t = tau(:).*z(end); 81 | X = z(probinfo.xind); 82 | U = z(probinfo.uind); 83 | time(i) = toc; 84 | 85 | % ---------------------------- Plot Solution ---------------------------- % 86 | if solveflag 87 | disp(z(end)) 88 | figure(i+3); 89 | subplot(2,1,1) 90 | plot(t,X,'-o'); 91 | xlabel('time') 92 | ylabel('states') 93 | title(sprintf(['Mesh %1.0f Solution in ',num2str(time(i)),'s'],i)) 94 | subplot(2,1,2); 95 | plot(t,U,'-o'); 96 | xlabel('time') 97 | ylabel('control') 98 | end 99 | end 100 | 101 | fprintf(['Total Time Supplying Second Derivatives (non-vectorized): ',... 102 | num2str(sum(time)),'\n']); 103 | -------------------------------------------------------------------------------- /examples/runAllExamples.m: -------------------------------------------------------------------------------- 1 | function runAllExamples() 2 | 3 | cd(['hessians',filesep,'logsumexp']); 4 | main; 5 | cd(['..',filesep,'..']); 6 | drawnow ; input ('hit enter to continue:') ; 7 | 8 | 9 | cd(['jachesvecprods']); 10 | main; 11 | cd(['..']); 12 | drawnow ; input ('hit enter to continue:') ; 13 | 14 | 15 | cd(['jacobians',filesep,'arrowhead']); 16 | main; 17 | cd(['..',filesep,'..']); 18 | drawnow ; input ('hit enter to continue:') ; 19 | 20 | 21 | cd(['jacobians',filesep,'polydatafit']); 22 | main; 23 | cd(['..',filesep,'..']); 24 | drawnow ; input ('hit enter to continue:') ; 25 | 26 | 27 | cd(['optimization',filesep,'fminconEx']); 28 | main; 29 | cd(['..',filesep,'..']); 30 | drawnow ; input ('hit enter to continue:') ; 31 | 32 | 33 | cd(['optimization',filesep,'fminuncEx']); 34 | main; 35 | cd(['..',filesep,'..']); 36 | drawnow ; input ('hit enter to continue:') ; 37 | 38 | 39 | cd(['optimization',filesep,'fsolveEx']); 40 | main; 41 | cd(['..',filesep,'..']); 42 | drawnow ; input ('hit enter to continue:') ; 43 | 44 | 45 | cd(['optimization',filesep,'ipoptEx']); 46 | gl2main; 47 | cd(['..',filesep,'..']); 48 | drawnow ; input ('hit enter to continue:') ; 49 | 50 | cd(['optimization',filesep,'fsolveEx']); 51 | main; 52 | cd(['..',filesep,'..']); 53 | drawnow ; input ('hit enter to continue:') ; 54 | 55 | 56 | cd(['optimization',filesep,'vectorized',filesep,'brachistochrone']); 57 | main_basic_1stderivs; 58 | drawnow ; input ('hit enter to continue:') ; 59 | main_basic_2ndderivs; 60 | drawnow ; input ('hit enter to continue:') ; 61 | main_vect_1stderivs; 62 | drawnow ; input ('hit enter to continue:') ; 63 | main_vect_2ndderivs; 64 | cd(['..',filesep,'..',filesep,'..']); 65 | drawnow ; input ('hit enter to continue:') ; 66 | close all; 67 | 68 | 69 | cd(['optimization',filesep,'vectorized',filesep,'minimumclimb']); 70 | main_1stderivs_nonvect; 71 | drawnow ; input ('hit enter to continue:') ; 72 | main_1stderivs_vect; 73 | drawnow ; input ('hit enter to continue:') ; 74 | main_2ndderivs_nonvect; 75 | drawnow ; input ('hit enter to continue:') ; 76 | main_2ndderivs_vect; 77 | cd(['..',filesep,'..',filesep,'..']); 78 | drawnow ; input ('hit enter to continue:') ; 79 | close all; 80 | 81 | 82 | cd(['stiffodes',filesep,'brusselator']); 83 | main; 84 | cd(['..',filesep,'..']); 85 | drawnow ; input ('hit enter to continue:') ; 86 | 87 | 88 | cd(['stiffodes',filesep,'burgers']); 89 | main; 90 | cd(['..',filesep,'..']); 91 | drawnow ; input ('hit enter to continue:') ; 92 | 93 | 94 | cd(['stiffodes',filesep,'DCALcontrol']); 95 | main; 96 | cd(['..',filesep,'..']); 97 | drawnow ; input ('hit enter to continue:') ; 98 | 99 | close all; 100 | fprintf(1,'Successfully ran all adigator example problems.\n'); 101 | end 102 | -------------------------------------------------------------------------------- /examples/stiffodes/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator stiffode example problems with ode15s 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % DIRECTORIES: 8 | % brusselator - brusselator ODE example 9 | % burgers - burgers ODE example 10 | % DCALcontrol - DCAL controller example -------------------------------------------------------------------------------- /examples/stiffodes/DCALcontrol/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator DCAL controller ODE example 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % main.m - sets up the DCAL controller problem for 2 link robot - 9 | % differentiates getqd, getYd, and TwoLinkSys with ADiGator 10 | % getqd.m - desired trajectory file 11 | % getYd.m - desired trajectory matrix file 12 | % TwoLinkSys.m - robot dynamics with DCAL controller -------------------------------------------------------------------------------- /examples/stiffodes/DCALcontrol/TwoLinkSys.m: -------------------------------------------------------------------------------- 1 | function xdot = TwoLinkSys(t,x) 2 | % Two Link Robot Manipulator System 3 | % Inputs: 4 | % x(1) - link 1 position 5 | % x(2) - link 2 position 6 | % x(3) - link 1 velocity 7 | % x(4) - link 2 velocity 8 | % x(5) - internal filter variable p1 9 | % x(6) - internal filter variable p2 10 | % x(7) - stuff we have to numerically integrate for Thetahat1 - z1 11 | % x(8) - stuff we have to numerically integrate for Thetahat2 - z2 12 | % x(9) - stuff we have to numerically integrate for Thetahat3 - z3 13 | % x(10) - stuff we have to numerically integrate for Thetahat4 - z4 14 | % x(11) - stuff we have to numerically integrate for Thetahat5 - z5 15 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 16 | % Distributed under the GNU General Public License version 3.0 17 | global probinfo 18 | q1 = x(1); 19 | q2 = x(2); 20 | q1dot = x(3); 21 | q2dot = x(4); 22 | q = [q1; q2]; 23 | qdot = [q1dot; q2dot]; 24 | p = x(5:6); 25 | z = x(7:11); 26 | 27 | % ROBOT Model from Burg 97 28 | p1 = probinfo.p1; 29 | p2 = probinfo.p2; 30 | p3 = probinfo.p3; 31 | fd1 = probinfo.fd1; 32 | fd2 = probinfo.fd2; 33 | 34 | M=zeros(2,2); 35 | M(1,1)=p1+2*p3*cos(q2); 36 | M(1,2)=p2+p3*cos(q2); 37 | M(2,1)=p2+p3*cos(q2); 38 | M(2,2)=p2; 39 | 40 | V=zeros(2,2); 41 | V(1,1)=-p3*sin(q2)*q2dot; 42 | V(1,2)=-p3*sin(q2)*(q1dot+q2dot); 43 | V(2,1)= p3*sin(q2)*q1dot; 44 | V(2,2)=0; 45 | 46 | Fd= diag([fd1 fd2]); 47 | 48 | % Get control law 49 | [u,pdot,zdot] = getDCALcontrol(t,q,p,z); 50 | 51 | qdotdot = M\(u-V*qdot-Fd*qdot); 52 | 53 | % Define output 54 | xdot = [qdot;qdotdot;pdot;zdot]; 55 | end 56 | 57 | function [u,pdot,zdot] = getDCALcontrol(t,q,p,z) 58 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 59 | % Distributed under the GNU General Public License version 3.0 60 | global probinfo 61 | K = probinfo.DCAL.K; 62 | Gamma = probinfo.DCAL.Gamma; 63 | 64 | % Add noise to signal if desired 65 | if probinfo.noiseflag 66 | noise = interp1(probinfo.time.',probinfo.noise.',t).'; 67 | q = q.*(1+noise); 68 | end 69 | 70 | % Get Desired Trajectory plus time derivatives 71 | qd = getqd_dtdtdt(struct('f',t,'dt',1)); 72 | 73 | % Compute Error 74 | e = qd.f-q; 75 | 76 | % Build pdot 77 | pdot = -(K+1)*p + (K.^2 + 1)*e; 78 | 79 | % Build filtered error, ef 80 | ef = -K*e+p; 81 | 82 | % Q = [q1 q2 q_1 q_2 q__1 q__2]' 83 | % dQdt = [q_1 q_2 q__1 q__2 q___1 q___2]' 84 | Q.f = [qd.f; qd.dt; qd.dtdt]; 85 | Q.dt = [qd.dt; qd.dtdt; qd.dtdtdt]; 86 | 87 | % Build Yd 88 | Yd = getYd_dt(Q); 89 | Yddot = zeros(Yd.dt_size); 90 | Yddot(sub2ind(Yd.dt_size,Yd.dt_location(:,1),Yd.dt_location(:,2))) = Yd.dt; 91 | Yd = Yd.f; 92 | 93 | % Build zdot 94 | zdot = Yd.'*(e + ef) - Yddot.'*e; 95 | 96 | % Build Thetahat 97 | Thetahat = Gamma*(z + Yd.'*e); 98 | 99 | % Define Control Law 100 | u = Yd*Thetahat + -K*ef + e; 101 | end -------------------------------------------------------------------------------- /examples/stiffodes/DCALcontrol/getYd.m: -------------------------------------------------------------------------------- 1 | function Yd = getYd(Q) 2 | % Input scheme: 3 | % Q(1:2) = qd; Q(3:4) = qd_dot; Q(5:6) = qd_dot_dot; 4 | q1 = Q(1); 5 | q2 = Q(2); 6 | q_1 = Q(3); 7 | q_2 = Q(4); 8 | q__1 = Q(5); 9 | q__2 = Q(6); 10 | 11 | Yd1col = [q__1; 0]; 12 | Yd2col = [q__2; q__1+q__2]; 13 | Yd3col = [2*cos(q2)*q__1 + cos(q2)*q__2 - sin(q2)*q_1*q_2 - sin(q2)*(q_1+q_2)*q_2;... 14 | cos(q2)*q__1 + sin(q2)*q_1^2]; 15 | Yd4col = [q_1; 0]; 16 | Yd5col = [0;q_2]; 17 | 18 | Yd = [Yd1col, Yd2col, Yd3col, Yd4col, Yd5col]; -------------------------------------------------------------------------------- /examples/stiffodes/DCALcontrol/getqd.m: -------------------------------------------------------------------------------- 1 | function qd = getqd(t) 2 | qd = zeros(2,length(t)); 3 | qd(1,:) = 1.57*sin(6*t).*(1-exp(-.05*t.^4)); 4 | qd(2,:) = 1.2*sin(1*t) .*(1-exp(-.05*t.^2)); 5 | % qd(1,:) = 0.7.*sin(2.*t).*(1-exp(-0.3.*t.^3)); 6 | % qd(2,:) = qd(1,:); 7 | end -------------------------------------------------------------------------------- /examples/stiffodes/brusselator/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator brusselator ODE example 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % mybrussode.m - original burgers function taken from brussode.m 9 | % file 10 | % main.m - solves burgers ODE supplying derivatives with ADiGator -------------------------------------------------------------------------------- /examples/stiffodes/brusselator/main.m: -------------------------------------------------------------------------------- 1 | % This file uses both MATLAB finite differences as well as adigator in order 2 | % to solve the brusselator ODE using ode15s. 3 | % 4 | % For this problem, in general, compressed finite differencing seems to be 5 | % the best option as far as time is concerned. However, we compute the 6 | % sparsity matrix using adigator. You can play with N and tspan, but be 7 | % weary that N > 100 will make the non-compressed finite differencing 8 | % extremely slow. 9 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 10 | % ----------------------- Problem Set Up -------------------------------- % 11 | fdflag = 1; 12 | N = 2^3; 13 | if N > 100 14 | fdflag = 0; 15 | end 16 | tspan = [0 100]; 17 | y0 = [1+sin((2*pi/(N+1))*(1:N)); repmat(3,1,N)]; 18 | 19 | % --------------- Generate ADiGator Derivative File --------------------- % 20 | tic 21 | gt = adigatorCreateAuxInput([1 1]); % aux input for t 22 | gy = adigatorCreateDerivInput([2*N, 1],'y'); % deriv input for y 23 | gout = adigatorGenJacFile('mybrussode',{gt,gy,N}); 24 | adigatorgentime = toc; 25 | 26 | % Get Jacobian sparsity pattern from output of adigator 27 | S = gout.JacobianStructure; 28 | 29 | % ---------------- Solve ODE Using Finite Difference -------------------- % 30 | if fdflag 31 | options = odeset('Vectorized','on','Stats','on','RelTol',sqrt(eps),'AbsTol',sqrt(eps)); % Set options 32 | tic; 33 | [t1,y1] = ode15s(@(t,y)mybrussode(t,y,N),tspan,y0,options); % Solve ODE 34 | FDtime = toc; 35 | end 36 | display(' '); 37 | % ---------------- Solve ODE Using Compressed Finite Difference --------- % 38 | options = odeset('Vectorized','on','JPattern',S,'Stats','on','RelTol',sqrt(eps),'AbsTol',sqrt(eps)); % Set options 39 | tic; 40 | [t2,y2] = ode15s(@(t,y)mybrussode(t,y,N),tspan,y0,options); % Solve ODE 41 | CFDtime = toc; 42 | display(' '); 43 | 44 | % --------------------- Solve ODE Using ADiGator ------------------------ % 45 | tic 46 | options = odeset('Vectorized','on','Jacobian',@(t,y)mybrussode_Jac(t,y,N),'JPattern',S,'Stats','on','RelTol',sqrt(eps),'AbsTol',sqrt(eps)); 47 | [t,y] = ode15s(@(t,y)mybrussode(t,y,N),tspan,y0,options); % Solve ODE 48 | adigatortime = toc; 49 | display(' '); 50 | 51 | display(['ADiGator deriv file generation time: ',num2str(adigatorgentime)]); 52 | display(['ODE solve time using ADiGator: ',num2str(adigatortime)]); 53 | if fdflag 54 | display(['ODE solve time using Finite Difference: ',num2str(FDtime)]); 55 | end 56 | display(['ODE solve time using Compressed Finite Difference: ',num2str(CFDtime)]); 57 | -------------------------------------------------------------------------------- /examples/stiffodes/brusselator/mybrussode.m: -------------------------------------------------------------------------------- 1 | function dydt = mybrussode(t,y,N) 2 | % function dydt = mybrussode(t,y,N) 3 | % Taken from MATLAB function brussode.m 4 | % Derivative function 5 | c = 0.02 * (N+1)^2; 6 | dydt = zeros(2*N,size(y,2)); % preallocate dy/dt 7 | 8 | % Evaluate the 2 components of the function at one edge of the grid 9 | % (with edge conditions). 10 | i = 1; 11 | dydt(i,:) = 1 + y(i+1,:).*y(i,:).^2 - 4*y(i,:) + c*(1-2*y(i,:)+y(i+2,:)); 12 | dydt(i+1,:) = 3*y(i,:) - y(i+1,:).*y(i,:).^2 + c*(3-2*y(i+1,:)+y(i+3,:)); 13 | 14 | % Evaluate the 2 components of the function at all interior grid points. 15 | i = 3:2:2*N-3; 16 | dydt(i,:) = 1 + y(i+1,:).*y(i,:).^2 - 4*y(i,:) + ... 17 | c*(y(i-2,:)-2*y(i,:)+y(i+2,:)); 18 | dydt(i+1,:) = 3*y(i,:) - y(i+1,:).*y(i,:).^2 + ... 19 | c*(y(i-1,:)-2*y(i+1,:)+y(i+3,:)); 20 | 21 | % Evaluate the 2 components of the function at the other edge of the grid 22 | % (with edge conditions). 23 | i = 2*N-1; 24 | dydt(i,:) = 1 + y(i+1,:).*y(i,:).^2 - 4*y(i,:) + c*(y(i-2,:)-2*y(i,:)+1); 25 | dydt(i+1,:) = 3*y(i,:) - y(i+1,:).*y(i,:).^2 + c*(y(i-1,:)-2*y(i+1,:)+3); 26 | end -------------------------------------------------------------------------------- /examples/stiffodes/brusselator/mybrussode_Jac.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matt-weinstein/adigator/d002041c7aec727f99b0369fa1957563e46cefe1/examples/stiffodes/brusselator/mybrussode_Jac.m -------------------------------------------------------------------------------- /examples/stiffodes/burgers/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator burgers ODE example 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % burgersfun.m - original burgers function taken from burgersode.m 9 | % file 10 | % burgersfun_noloop.m - modified burgers function, (loops removed) 11 | % main.m - solves burgers ODE supplying derivatives with 12 | % ADiGator - ADiGator differentiates the noloop file -------------------------------------------------------------------------------- /examples/stiffodes/burgers/burgersfun.m: -------------------------------------------------------------------------------- 1 | function out = burgersfun(t,y,N) 2 | % Jacek Kierzenka and Lawrence F. Shampine 3 | % Copyright 1984-2014 The MathWorks, Inc. 4 | % Derivative function. 5 | a = y(1:N); 6 | x = y(N+1:end); 7 | x0 = 0; 8 | a0 = 0; 9 | xNP1 = 1; 10 | aNP1 = 0; 11 | y1 = y(1); 12 | g = zeros(2*N,1).*y1; 13 | for i = 2:N-1 14 | delx = x(i+1) - x(i-1); 15 | g(i) = 1e-4*((a(i+1) - a(i))/(x(i+1) - x(i)) - ... 16 | (a(i) - a(i-1))/(x(i) - x(i-1)))/(0.5*delx) ... 17 | - 0.5*(a(i+1)^2 - a(i-1)^2)/delx; 18 | end 19 | delx = x(2) - x0; 20 | g(1) = 1e-4*((a(2) - a(1))/(x(2) - x(1)) - (a(1) - a0)/(x(1) - x0))/(0.5*delx) ... 21 | - 0.5*(a(2)^2 - a0^2)/delx; 22 | delx = xNP1 - x(N-1); 23 | g(N) = 1e-4*((aNP1 - a(N))/(xNP1 - x(N)) - ... 24 | (a(N) - a(N-1))/(x(N) - x(N-1)))/delx - ... 25 | 0.5*(aNP1^2 - a(N-1)^2)/delx; 26 | % Evaluate monitor function. 27 | M = zeros(N,1).*y1; 28 | for i = 2:N-1 29 | M(i) = sqrt(1 + ((a(i+1) - a(i-1))/(x(i+1) - x(i-1)))^2); 30 | end 31 | M0 = sqrt(1 + ((a(1) - a0)/(x(1) - x0))^2); 32 | M(1) = sqrt(1 + ((a(2) - a0)/(x(2) - x0))^2); 33 | M(N) = sqrt(1 + ((aNP1 - a(N-1))/(xNP1 - x(N-1)))^2); 34 | MNP1 = sqrt(1 + ((aNP1 - a(N))/(xNP1 - x(N)))^2); 35 | % Spatial smoothing with gamma = 2, p = 2. 36 | SM = zeros(N,1).*y1; 37 | for i = 3:N-2 38 | SM(i) = sqrt((4*M(i-2)^2 + 6*M(i-1)^2 + 9*M(i)^2 + ... 39 | 6*M(i+1)^2 + 4*M(i+2)^2)/29); 40 | end 41 | SM0 = sqrt((9*M0^2 + 6*M(1)^2 + 4*M(2)^2)/19); 42 | SM(1) = sqrt((6*M0^2 + 9*M(1)^2 + 6*M(2)^2 + 4*M(3)^2)/25); 43 | SM(2) = sqrt((4*M0^2 + 6*M(1)^2 + 9*M(2)^2 + 6*M(3)^2 + 4*M(4)^2)/29); 44 | SM(N-1) = sqrt((4*M(N-3)^2 + 6*M(N-2)^2 + 9*M(N-1)^2 + 6*M(N)^2 + 4*MNP1^2)/29); 45 | SM(N) = sqrt((4*M(N-2)^2 + 6*M(N-1)^2 + 9*M(N)^2 + 6*MNP1^2)/25); 46 | SMNP1 = sqrt((4*M(N-1)^2 + 6*M(N)^2 + 9*MNP1^2)/19); 47 | for i = 2:N-1 48 | g(i+N) = (SM(i+1) + SM(i))*(x(i+1) - x(i)) - ... 49 | (SM(i) + SM(i-1))*(x(i) - x(i-1)); 50 | end 51 | g(1+N) = (SM(2) + SM(1))*(x(2) - x(1)) - (SM(1) + SM0)*(x(1) - x0); 52 | g(N+N) = (SMNP1 + SM(N))*(xNP1 - x(N)) - (SM(N) + SM(N-1))*(x(N) - x(N-1)); 53 | tau = 1e-3; 54 | g(1+N:end) = - g(1+N:end)/(2*tau); 55 | out = g; 56 | end -------------------------------------------------------------------------------- /examples/stiffodes/burgers/burgersfun_noloop.m: -------------------------------------------------------------------------------- 1 | function out = burgersfun_noloop(t,y,N) 2 | % Jacek Kierzenka and Lawrence F. Shampine 3 | % Copyright 1984-2014 The MathWorks, Inc. 4 | % Derivative function. 5 | a = y(1:N); 6 | a = a(:); 7 | x = y(N+1:end); 8 | x = x(:); 9 | x0 = 0; 10 | a0 = 0; 11 | xNP1 = 1; 12 | aNP1 = 0; 13 | y1 = y(1); 14 | g = zeros(2*N,1).*y1; 15 | i = 2:N-1; 16 | %for i = 2:N-1 17 | delx = x(i+1) - x(i-1); 18 | g(i) = 1e-4*((a(i+1) - a(i))./(x(i+1) - x(i)) - ... 19 | (a(i) - a(i-1))./(x(i) - x(i-1)))./(0.5*delx) ... 20 | - 0.5*(a(i+1).^2 - a(i-1).^2)./delx; 21 | %end 22 | delx = x(2) - x0; 23 | g(1) = 1e-4*((a(2) - a(1))/(x(2) - x(1)) - (a(1) - a0)/(x(1) - x0))/(0.5*delx) ... 24 | - 0.5*(a(2)^2 - a0^2)/delx; 25 | delx = xNP1 - x(N-1); 26 | g(N) = 1e-4*((aNP1 - a(N))/(xNP1 - x(N)) - ... 27 | (a(N) - a(N-1))/(x(N) - x(N-1)))/delx - ... 28 | 0.5*(aNP1^2 - a(N-1)^2)/delx; 29 | % Evaluate monitor function. 30 | M = zeros(N,1).*y1; 31 | i = 2:N-1; 32 | %for i = 2:N-1 33 | M(i) = sqrt(1 + ((a(i+1) - a(i-1))./(x(i+1) - x(i-1))).^2); 34 | %end 35 | M0 = sqrt(1 + ((a(1) - a0)/(x(1) - x0))^2); 36 | M(1) = sqrt(1 + ((a(2) - a0)/(x(2) - x0))^2); 37 | M(N) = sqrt(1 + ((aNP1 - a(N-1))/(xNP1 - x(N-1)))^2); 38 | MNP1 = sqrt(1 + ((aNP1 - a(N))/(xNP1 - x(N)))^2); 39 | % Spatial smoothing with gamma = 2, p = 2. 40 | SM = zeros(N,1).*y1; 41 | i = 3:N-2; 42 | %for i = 3:N-2 43 | SM(i) = sqrt((4*M(i-2).^2 + 6*M(i-1).^2 + 9*M(i).^2 + ... 44 | 6*M(i+1).^2 + 4*M(i+2).^2)/29); 45 | %end 46 | SM0 = sqrt((9*M0^2 + 6*M(1)^2 + 4*M(2)^2)/19); 47 | SM(1) = sqrt((6*M0^2 + 9*M(1)^2 + 6*M(2)^2 + 4*M(3)^2)/25); 48 | SM(2) = sqrt((4*M0^2 + 6*M(1)^2 + 9*M(2)^2 + 6*M(3)^2 + 4*M(4)^2)/29); 49 | SM(N-1) = sqrt((4*M(N-3)^2 + 6*M(N-2)^2 + 9*M(N-1)^2 + 6*M(N)^2 + 4*MNP1^2)/29); 50 | SM(N) = sqrt((4*M(N-2)^2 + 6*M(N-1)^2 + 9*M(N)^2 + 6*MNP1^2)/25); 51 | SMNP1 = sqrt((4*M(N-1)^2 + 6*M(N)^2 + 9*MNP1^2)/19); 52 | i = 2:N-1; 53 | %for i = 2:N-1 54 | g(i+N) = (SM(i+1) + SM(i)).*(x(i+1) - x(i)) - ... 55 | (SM(i) + SM(i-1)).*(x(i) - x(i-1)); 56 | %end 57 | g(1+N) = (SM(2) + SM(1))*(x(2) - x(1)) - (SM(1) + SM0)*(x(1) - x0); 58 | g(N+N) = (SMNP1 + SM(N))*(xNP1 - x(N)) - (SM(N) + SM(N-1))*(x(N) - x(N-1)); 59 | tau = 1e-3; 60 | g(1+N:end) = - g(1+N:end)/(2*tau); 61 | out = g; 62 | end -------------------------------------------------------------------------------- /examples/stiffodes/burgers/main.m: -------------------------------------------------------------------------------- 1 | function sol = main(n,tspan) 2 | % solves the burgers ode.. ADiGator differentiates the function with the 3 | % loops removed, burgersfun_noloop as it is more efficient for AD 4 | % inputs: n - problem dimension (default of 2.^5) 5 | % tspan - time span (default is [0 2]) 6 | % outputs: sol - solution 7 | fprintf ('AdiGator example: %s\n', mfilename ('fullpath')) ; 8 | if nargin == 0 9 | n = 2.^5; 10 | end 11 | if nargin < 2 12 | tspan = [0 2]; 13 | end 14 | 15 | N = n/2; 16 | h = 1/(N+1); 17 | xinit = h*(1:N); 18 | % u(x,0) at grid points 19 | ainit = sin(2*pi*xinit) + 0.5*sin(pi*xinit); 20 | 21 | y0 = [ainit xinit]; 22 | 23 | % Generate ADiGator Jacobian files using adigatorGenJacFile 24 | ay = adigatorCreateDerivInput(size(y0),'y'); 25 | output = adigatorGenJacFile('burgersfun_noloop',{1,ay,N},adigatorOptions('overwrite',1)); 26 | Jpat = output.JacobianStructure; 27 | 28 | % solve ODE 29 | opts = odeset('Mass',@(t,y)burgersmass(t,y,N),'MStateDependence','strong','JPattern',Jpat,... 30 | 'MvPattern',burgersMvPat(N),'RelTol',1e-5,'AbsTol',1e-4,'Jacobian',@(t,y)burgersfun_noloop_Jac(t,y,N)); 31 | display(' '); 32 | sol = ode15s(@(t,y)burgersfun(t,y,N),tspan,y0,opts); 33 | 34 | end 35 | 36 | function S = burgersMvPat(N) 37 | % Jacek Kierzenka and Lawrence F. Shampine 38 | % Copyright 1984-2014 The MathWorks, Inc. 39 | % Sparsity pattern for the derivative of the Mass matrix times a vector 40 | S = sparse(2*N,2*N); 41 | S(1,2) = 1; 42 | S(1,2+N) = 1; 43 | for i = 2:N-1 44 | S(i,i-1) = 1; 45 | S(i,i+1) = 1; 46 | S(i,i-1+N) = 1; 47 | S(i,i+1+N) = 1; 48 | end 49 | S(N,N-1) = 1; 50 | S(N,N-1+N) = 1; 51 | end 52 | 53 | function out = burgersmass(t,y,N) 54 | % Jacek Kierzenka and Lawrence F. Shampine 55 | % Copyright 1984-2014 The MathWorks, Inc. 56 | % Mass matrix function. N is provided by the outer function. 57 | a = y(1:N); 58 | x = y(N+1:end); 59 | x0 = 0; 60 | a0 = 0; 61 | xNP1 = 1; 62 | aNP1 = 0; 63 | M1 = speye(N); 64 | M2 = sparse(N,N); 65 | M2(1,1) = - (a(2) - a0)/(x(2) - x0); 66 | for i = 2:N-1 67 | M2(i,i) = - (a(i+1) - a(i-1))/(x(i+1) - x(i-1)); 68 | end 69 | M2(N,N) = - (aNP1 - a(N-1))/(xNP1 - x(N-1)); 70 | % MMPDE6 71 | M3 = sparse(N,N); 72 | e = ones(N,1); 73 | M4 = spdiags([e -2*e e],-1:1,N,N); 74 | out = [M1 M2 75 | M3 M4]; 76 | end 77 | 78 | -------------------------------------------------------------------------------- /lib/@cada/adigatorStructAnalyzer.m: -------------------------------------------------------------------------------- 1 | function x = adigatorStructAnalyzer(x,xStr,subsflag) 2 | % CADA overloaded version of adigatorStructAnalyzer 3 | % 4 | % Other versions are called to recursively parse structure/cell objects and 5 | % call adigatorVarAnalyzer on each of the CADA objects. The fact that this 6 | % has been called implies that the CADA object lives within a 7 | % cell/structure, thus there are a few special cases that are checked for 8 | % prior to callling adigatorVarAnalyzer. 9 | % 10 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 11 | % Distributed under the GNU General Public License version 3.0 12 | global ADIGATOR 13 | NUMvod = ADIGATOR.NVAROFDIFF; 14 | xID = x.id; 15 | PFLAG = ADIGATOR.RUNFLAG == 2 && ADIGATOR.PRINT.FLAG && ... 16 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.COUNT,2) ~= ADIGATOR.VARINFO.NAMELOCS(xID,2); 17 | if PFLAG 18 | fid = ADIGATOR.PRINT.FID; 19 | indent = ADIGATOR.PRINT.INDENT; 20 | end 21 | % Theres a special case where this needs to print stuff when calling a 22 | % previously created derivative file 23 | if size(ADIGATOR.VARINFO.NAMELOCS,1) >= xID 24 | if isinf(ADIGATOR.VARINFO.NAMELOCS(xID,3)) 25 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.COUNT,3) = ADIGATOR.VARINFO.NAMELOCS(xID,3); 26 | end 27 | if ADIGATOR.VARINFO.NAMELOCS(xID,2) < 0 28 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.COUNT,2) = ADIGATOR.VARINFO.NAMELOCS(xID,2); 29 | end 30 | end 31 | 32 | ADIGATOR.VARINFO.LASTOCC([xID,ADIGATOR.VARINFO.COUNT],1) = ADIGATOR.VARINFO.COUNT; 33 | if ADIGATOR.RUNFLAG > 0 34 | if isinf(ADIGATOR.VARINFO.NAMELOCS(xID,3)) 35 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.COUNT,3) = ADIGATOR.VARINFO.NAMELOCS(xID,3); 36 | end 37 | if ADIGATOR.VARINFO.NAMELOCS(xID,2) < 0 38 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.COUNT,2) = ADIGATOR.VARINFO.NAMELOCS(xID,2); 39 | end 40 | [funcstr,DPFLAG] = cadafuncname(); 41 | for Vcount = 1:NUMvod 42 | if ~isempty(x.deriv(Vcount).nzlocs) 43 | derivstr = cadadername(funcstr,Vcount); 44 | if PFLAG && DPFLAG 45 | fprintf(fid,[indent,derivstr,' = ',x.deriv(Vcount).name,';\n']); 46 | end 47 | x.deriv(Vcount).name = derivstr; 48 | end 49 | end 50 | if PFLAG 51 | fprintf(fid,[indent,funcstr,' = ',x.func.name,';\n']); 52 | end 53 | x.func.name = funcstr; 54 | end 55 | x.id = ADIGATOR.VARINFO.COUNT; 56 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT + 1; 57 | x = adigatorVarAnalyzer('',x,xStr,subsflag); 58 | if isinf(ADIGATOR.VARINFO.NAMELOCS(xID,3)) 59 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.COUNT-1,3) = ADIGATOR.VARINFO.NAMELOCS(xID,3); 60 | end 61 | if ADIGATOR.VARINFO.NAMELOCS(xID,2) < 0 62 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.COUNT-1,2) = ADIGATOR.VARINFO.NAMELOCS(xID,2); 63 | end 64 | end -------------------------------------------------------------------------------- /lib/@cada/cadaCheckForDerivs.m: -------------------------------------------------------------------------------- 1 | function flag = cadaCheckForDerivs(x) 2 | % This just checks and overloaded object to see if it has any derivatives. 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | global ADIGATOR 7 | 8 | flag = 0; 9 | for Vcount = 1:ADIGATOR.NVAROFDIFF 10 | if ~isempty(x.deriv(Vcount).nzlocs) 11 | flag = 1; 12 | break 13 | end 14 | end -------------------------------------------------------------------------------- /lib/@cada/cadaEmptyEval.m: -------------------------------------------------------------------------------- 1 | function [y,varargout] = cadaEmptyEval(varargin) 2 | % This serves to simply increase ADIGATOR.VARINFO.COUNT and assign stuff 3 | % to ADIGATOR.VARINFO.LASTOCC when in empty evaluations 4 | % 5 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 6 | % Distributed under the GNU General Public License version 3.0 7 | global ADIGATOR 8 | for Vcount = 1:nargin 9 | x = varargin{Vcount}; 10 | if isa(x,'cada') 11 | ADIGATOR.VARINFO.LASTOCC(x.id,1) = ADIGATOR.VARINFO.COUNT+nargout-1; 12 | end 13 | end 14 | NUMvod = ADIGATOR.NVAROFDIFF; 15 | y.id = ADIGATOR.VARINFO.COUNT; 16 | y.func = struct('name',[],'size',[0 0],'zerolocs',[],'value',[]); 17 | y.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 18 | ADIGATOR.VARINFO.LASTOCC(ADIGATOR.VARINFO.COUNT,1) =... 19 | ADIGATOR.VARINFO.COUNT+nargout-1; 20 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 21 | y = cada(y); 22 | 23 | varargout = cell(nargout-1,1); 24 | for Ocount = 1:nargout-1 25 | y1.id = ADIGATOR.VARINFO.COUNT; 26 | y1.func = struct('name',[],'size',[0 0],'zerolocs',[],'value',[]); 27 | y1.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 28 | ADIGATOR.VARINFO.LASTOCC(ADIGATOR.VARINFO.COUNT,1) =... 29 | ADIGATOR.VARINFO.COUNT+nargout-1-Ocount; 30 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 31 | varargout{Ocount} = cada(y1); 32 | end -------------------------------------------------------------------------------- /lib/@cada/cadaunarylogical.m: -------------------------------------------------------------------------------- 1 | function y = cadaunarylogical(x,callerstr,dim) 2 | % cadaunarylogical routine called by overloaded unary logical operations: 3 | % logical, not, any, all, isempty 4 | % 5 | % Assumed syntax: y = callerstr(x,dim); 6 | % 7 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 8 | % Distributed under the GNU General Public License version 3.0 9 | global ADIGATOR 10 | NUMvod = ADIGATOR.NVAROFDIFF; 11 | fid = ADIGATOR.PRINT.FID; 12 | PFLAG = ADIGATOR.PRINT.FLAG; 13 | indent = ADIGATOR.PRINT.INDENT; 14 | 15 | if ADIGATOR.EMPTYFLAG 16 | y = cadaEmptyEval(x); 17 | if ~ADIGATOR.RUNFLAG 18 | numvars = find(ADIGATOR.VARINFO.NAMELOCS(:,1),1,'last'); 19 | cadaCancelDerivs(y.id,numvars); 20 | end 21 | return 22 | end 23 | % ---------------------- Build Function Properties -----------------------% 24 | y.id = ADIGATOR.VARINFO.COUNT; 25 | [funcstr,~] = cadafuncname(); 26 | y.func = struct('name',funcstr,'size',[],'zerolocs',... 27 | [],'value',[],'logical',[]); 28 | % Function Size 29 | if dim == 1 30 | y.func.size = [1 x.func.size(2)]; 31 | elseif dim == 2 32 | y.func.size = [x.func.size(1) 1]; 33 | elseif dim == -1 34 | y.func.size = [1 1]; 35 | else 36 | y.func.size = x.func.size; 37 | end 38 | 39 | % Function Value/Zero Locations 40 | switch callerstr 41 | case 'logical' 42 | if ~isempty(x.func.value) 43 | y.func.value = logical(x.func.value); 44 | elseif ~isempty(x.func.zerolocs) 45 | y.func.zerolocs = x.func.zerolocs; 46 | end 47 | case 'not' 48 | if ~isempty(x.func.value) 49 | y.func.value = ~logical(x.func.value); 50 | end 51 | case 'any' 52 | if ~isempty(x.func.value) 53 | y.func.value = any(x.func.value,dim); 54 | end 55 | case 'all' 56 | if ~isempty(x.func.value) 57 | y.func.value = logical(x.func.value); 58 | elseif ~isempty(x.func.zerolocs) 59 | x.func.size(isinf(x.func.size)) = 1; 60 | xtemp = true(x.func.size); 61 | xtemp(x.func.zerolocs) = false; 62 | ytemp = all(xtemp,dim); 63 | y.func.zerolocs = find(~ytemp(:)); 64 | end 65 | otherwise 66 | error(['case not coded: ',callerstr]) 67 | end 68 | 69 | if PFLAG 70 | if dim 71 | fprintf(fid,[indent,funcstr,' = ',... 72 | callerstr,'(',x.func.name,',%1.0d);\n'],dim); 73 | else 74 | fprintf(fid,[indent,funcstr,' = ',... 75 | callerstr,'(',x.func.name,');\n']); 76 | end 77 | end 78 | 79 | y.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 80 | 81 | ADIGATOR.VARINFO.LASTOCC([x.id y.id],1) = ADIGATOR.VARINFO.COUNT; 82 | y = cada(y); 83 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 84 | end -------------------------------------------------------------------------------- /lib/@cada/inv.m: -------------------------------------------------------------------------------- 1 | function y = inv(x) 2 | % CADA overloaded version of INV. 3 | % If x is a matrix, then this function calls cadainversederiv to compute 4 | % the derivatives of the matrix inverse. If x is a scalar, then 1./x is 5 | % called. See cadainversederiv for information on computation of the 6 | % derivative inverse. 7 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 8 | % Distributed under the GNU General Public License version 3.0 9 | global ADIGATOR 10 | 11 | if ADIGATOR.EMPTYFLAG 12 | y = cadaEmptyEval(x); 13 | return 14 | end 15 | NUMvod = ADIGATOR.NVAROFDIFF; 16 | PFLAG = ADIGATOR.PRINT.FLAG; 17 | % --------------------------- Parse Input ------------------------------- % 18 | if x.func.size(1) ~= x.func.size(2) 19 | error('Can only Invert Square Matrices') 20 | else 21 | N = x.func.size(1); 22 | end 23 | 24 | if N == 1 25 | y = 1./x; 26 | return 27 | end 28 | 29 | %-------------------------------------------------------------------------% 30 | % Build Function Properties % 31 | %-------------------------------------------------------------------------% 32 | y.id = ADIGATOR.VARINFO.COUNT; 33 | [funcstr,DPFLAG] = cadafuncname(); 34 | y.func = struct('name',funcstr,'size',[N N],'zerolocs',[],... 35 | 'value',[]); 36 | 37 | if PFLAG 38 | fid = ADIGATOR.PRINT.FID; 39 | indent = ADIGATOR.PRINT.INDENT; 40 | NDstr = sprintf('%1.0f',ADIGATOR.DERNUMBER); 41 | end 42 | 43 | if ~isempty(x.func.value) 44 | y.func.value = inv(x.func.value); 45 | elseif ~isempty(x.func.zerolocs) 46 | xtemp = rand(N,N); 47 | xtemp(x.func.zerolocs) = 0; 48 | warning('off','all') 49 | ytemp = inv(xtemp); 50 | warning('on','all') 51 | y.func.zerolocs = find(~ytemp(:)); 52 | ytemp = abs(ytemp); 53 | else 54 | ytemp = ones(N,N); 55 | end 56 | 57 | % ------------------------Build Derivative Properties---------------------- 58 | y.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 59 | for Vcount = 1:NUMvod 60 | if ~isempty(x.deriv(Vcount).nzlocs) 61 | derivstr = cadadername(funcstr,Vcount); 62 | nzlocs = cadainversederiv(x,ytemp,Vcount,derivstr,DPFLAG); 63 | if ~isempty(nzlocs) 64 | y.deriv(Vcount).nzlocs = nzlocs; 65 | y.deriv(Vcount).name = derivstr; 66 | end 67 | end 68 | end 69 | 70 | % --------------------------Function Printing --------------------------- % 71 | if PFLAG 72 | fprintf(fid,[indent,funcstr,' = inv(',x.func.name,');\n']); 73 | end 74 | 75 | ADIGATOR.VARINFO.LASTOCC([x.id y.id],1) = ADIGATOR.VARINFO.COUNT; 76 | y = cada(y); 77 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; -------------------------------------------------------------------------------- /lib/@cada/isempty.m: -------------------------------------------------------------------------------- 1 | function y = isempty(x) 2 | % CADA overloaded ISEMPTY function. 3 | global ADIGATOR 4 | Dbstuff = dbstack; 5 | if length(Dbstuff)>1 6 | CallingFile = Dbstuff(2).file; 7 | else 8 | CallingFile = []; 9 | end 10 | if length(CallingFile) > 12 && ~isempty(strfind(CallingFile,'adigatortempfunc')) 11 | % if ADIGATOR.FORINFO.FLAG 12 | % keyboard 13 | % y = logical(length(x)); 14 | % return 15 | % end 16 | if ADIGATOR.EMPTYFLAG 17 | y = cadaEmptyEval(x); 18 | return 19 | end 20 | NUMvod = ADIGATOR.NVAROFDIFF; 21 | fid = ADIGATOR.PRINT.FID; 22 | PFLAG = ADIGATOR.PRINT.FLAG; 23 | indent = ADIGATOR.PRINT.INDENT; 24 | xMrow = x.func.size(1); xNcol = x.func.size(2); 25 | % --------------------Build Function Properties-----------------------% 26 | y.id = ADIGATOR.VARINFO.COUNT; 27 | [funcstr,~] = cadafuncname(); 28 | y.func = struct('name',funcstr,'size',[1 1],'zerolocs',... 29 | [],'value',[],'logical',[]); 30 | 31 | if xMrow*xNcol > 0 32 | y.func.value = false; 33 | else 34 | y.func.value = true; 35 | end 36 | 37 | 38 | y.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 39 | 40 | % --------------------------Function Printing ----------------------------% 41 | if PFLAG == 1 42 | fprintf(fid,[indent,funcstr,' = isempty(',x.func.name,');\n']); 43 | end 44 | 45 | ADIGATOR.VARINFO.LASTOCC([x.id y.id],1) = ADIGATOR.VARINFO.COUNT; 46 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 47 | y = cada(y); 48 | 49 | else 50 | y = false; 51 | end -------------------------------------------------------------------------------- /lib/@cada/isequal.m: -------------------------------------------------------------------------------- 1 | function z = isequal(x,y,varargin) 2 | % CADA overloaded version of function ISEQUAL (arrays) 3 | 4 | global ADIGATOR 5 | NUMvod = ADIGATOR.NVAROFDIFF; 6 | Dbstuff = dbstack; 7 | if length(Dbstuff)>1 8 | CallingFile = Dbstuff(2).file; 9 | else 10 | CallingFile = []; 11 | end 12 | if (length(CallingFile) > 16 && strcmp(CallingFile(1:16),'adigatortempfunc')) 13 | if ADIGATOR.EMPTYFLAG 14 | z = cadaEmptyEval(x,y); 15 | return 16 | end 17 | fid = ADIGATOR.PRINT.FID; 18 | PFLAG = ADIGATOR.PRINT.FLAG; 19 | indent = ADIGATOR.PRINT.INDENT; 20 | 21 | % ----------------------------Parse Inputs------------------------------- % 22 | if PFLAG 23 | InputFuncStr = cell(1,nargin); 24 | end 25 | 26 | ValEqualFlag = 1; 27 | % ValEqualFlag 28 | % 0: definitely false 29 | % 1: definitely true 30 | % 2: we dont know 31 | if isa(x,'cada') 32 | RowSize = x.func.size(1); 33 | ColSize = x.func.size(2); 34 | if ~isempty(x.func.value) 35 | Value = x.func.value; 36 | else 37 | ValEqualFlag = 2; 38 | end 39 | if PFLAG; InputFuncStr{1} = [x.func.name,',']; end 40 | ADIGATOR.VARINFO.LASTOCC(x.id,1) = ADIGATOR.VARINFO.COUNT; 41 | elseif isnumeric(x) 42 | RowSize = size(x,1); 43 | ColSize = size(x,2); 44 | Value = x; 45 | if PFLAG; InputFuncStr{1} = [cadamatprint(x),',']; end 46 | else 47 | error('invalid input to ISEQUAL'); 48 | end 49 | for Icount = 2:nargin 50 | if Icount == 2 51 | a = y; 52 | else 53 | a = varargin{Icount-2}; 54 | end 55 | if isa(a,'cada') 56 | aMrow = a.func.size(1); 57 | aNcol = a.func.size(2); 58 | if isempty(a.func.value) 59 | ValEqualFlag = 2; 60 | elseif ValEqualFlag == 1 && ~isequal(a.func.value,Value) 61 | ValEqualFlag = 0; 62 | end 63 | ADIGATOR.VARINFO.LASTOCC(a.id,1) = ADIGATOR.VARINFO.COUNT; 64 | if PFLAG; InputFuncStr{Icount} = [a.func.name,',']; end 65 | elseif isnumeric(a) 66 | aMrow = size(a,1); 67 | aNcol = size(a,2); 68 | if ValEqualFlag == 1 && ~isequal(a,Value) 69 | ValEqualFlag = 0; 70 | end 71 | if PFLAG; InputFuncStr{Icount} = [cadamatprint(a),',']; end 72 | else 73 | error('invalid input to ISEQUAL'); 74 | end 75 | if (aMrow ~= RowSize || aNcol ~= ColSize) 76 | ValEqualFlag = 0; 77 | end 78 | end 79 | 80 | % ----------------------Build Function Properties-------------------------- 81 | z.id = ADIGATOR.VARINFO.COUNT; 82 | [funcstr,~] = cadafuncname(); 83 | z.func = struct('name',funcstr,'size',[1 1],'zerolocs',[],... 84 | 'value',[],'logical',[]); 85 | 86 | %----------------------Function Numeric Values (if exist)-----------------% 87 | if ValEqualFlag < 2 88 | z.func.value = ValEqualFlag; 89 | end 90 | 91 | % ----------------------------Function Printing ------------------------- % 92 | if PFLAG == 1 93 | InputFuncStr = cell2mat(InputFuncStr); 94 | InputFuncStr = ['(',InputFuncStr(1:end-1),')']; 95 | fprintf(fid,[indent,funcstr,' = isequal',InputFuncStr,';\n']); 96 | end 97 | 98 | 99 | % ------------------------Build Derivative Properties---------------------- 100 | z.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 101 | ADIGATOR.VARINFO.LASTOCC(ADIGATOR.VARINFO.COUNT,1) = ADIGATOR.VARINFO.COUNT; 102 | z = cada(z); 103 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 104 | else 105 | % Being called from within adigatorFunctionInitialize 106 | if isa(x,'cada') && isa(y,'cada') 107 | z = true; 108 | x.func.name = []; 109 | y.func.name = []; 110 | if isempty(x.func.value); x.func.value = []; end 111 | if isempty(x.func.zerolocs); x.func.zerolocs = []; end 112 | if isempty(y.func.value); y.func.value = []; end 113 | if isempty(y.func.zerolocs); y.func.zerolocs = []; end 114 | if isequal(x.func,y.func) 115 | for Vcount = 1:NUMvod 116 | if ~isequal(x.deriv(Vcount).nzlocs,y.deriv(Vcount).nzlocs) 117 | z = false; 118 | break 119 | end 120 | end 121 | else 122 | z = false; 123 | end 124 | else 125 | z = false; 126 | end 127 | end -------------------------------------------------------------------------------- /lib/@cada/isequalwithequalnans.m: -------------------------------------------------------------------------------- 1 | function z = isequalwithequalnans(x,y,varargin) 2 | % CADA overloaded version of function ISEQUALWITHEQUALNANS (arrays) 3 | 4 | global ADIGATOR 5 | if ADIGATOR.EMPTYFLAG 6 | z = cadaEmptyEval(x,y); 7 | return 8 | end 9 | NUMvod = ADIGATOR.NVAROFDIFF; 10 | fid = ADIGATOR.PRINT.FID; 11 | PFLAG = ADIGATOR.PRINT.FLAG; 12 | indent = ADIGATOR.PRINT.INDENT; 13 | 14 | % ----------------------------Parse Inputs------------------------------- % 15 | if PFLAG 16 | InputFuncStr = cell(1,nargin); 17 | end 18 | 19 | ValEqualFlag = 1; 20 | % ValEqualFlag 21 | % 0: definitely false 22 | % 1: definitely true 23 | % 2: we dont know 24 | if isa(x,'cada') 25 | RowSize = x.func.size(1); 26 | ColSize = x.func.size(2); 27 | if ~isempty(x.func.value) 28 | Value = x.func.value; 29 | else 30 | ValEqualFlag = 2; 31 | end 32 | if PFLAG; InputFuncStr{1} = [x.func.name,',']; end 33 | elseif isnumeric(x) 34 | RowSize = size(x,1); 35 | ColSize = size(x,2); 36 | Value = x; 37 | if PFLAG; InputFuncStr{1} = [cadamatprint(x),',']; end 38 | else 39 | error('invalid input to ISEQUALWITHEQUALNANS'); 40 | end 41 | for Icount = 2:nargin 42 | if Icount == 2 43 | a = y; 44 | else 45 | a = varargin{Icount-2}; 46 | end 47 | if isa(a,'cada') 48 | aMrow = a.func.size(1); 49 | aNcol = a.func.size(2); 50 | if isempty(a.func.value) 51 | ValEqualFlag = 2; 52 | elseif ValEqualFlag == 1 && ~isequalwithequalnans(a.func.value,Value) 53 | ValEqualFlag = 0; 54 | end 55 | if PFLAG; InputFuncStr{Icount} = [a.func.name,',']; end 56 | elseif isnumeric(a) 57 | aMrow = size(a,1); 58 | aNcol = size(a,2); 59 | if ValEqualFlag == 1 && ~isequalwithequalnans(a,Value) 60 | ValEqualFlag = 0; 61 | end 62 | if PFLAG; InputFuncStr{Icount} = [cadamatprint(a),',']; end 63 | else 64 | error('invalid input to ISEQUALWITHEQUALNANS'); 65 | end 66 | if (aMrow ~= RowSize || aNcol ~= ColSize) 67 | ValEqualFlag = 0; 68 | end 69 | end 70 | 71 | % ----------------------Build Function Properties-------------------------- 72 | z.id = ADIGATOR.VARINFO.COUNT; 73 | [funcstr,~] = cadafuncname(); 74 | z.func = struct('name',funcstr,'size',[1 1],'zerolocs',[],... 75 | 'value',[],'logical',[]); 76 | 77 | %----------------------Function Numeric Values (if exist)-----------------% 78 | if ValEqualFlag < 2 79 | z.func.value = ValEqualFlag; 80 | end 81 | 82 | % ----------------------------Function Printing ------------------------- % 83 | if PFLAG == 1 84 | InputFuncStr = cell2mat(InputFuncStr); 85 | InputFuncStr = ['(',InputFuncStr(1:end-1),')']; 86 | fprintf(fid,[indent,funcstr,' = isequalwithequalnans',InputFuncStr,';\n']); 87 | end 88 | 89 | 90 | % ------------------------Build Derivative Properties---------------------- 91 | z.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 92 | 93 | ADIGATOR.VARINFO.LASTOCC([x.id y.id z.id],1) = ADIGATOR.VARINFO.COUNT; 94 | z = cada(z); 95 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 96 | -------------------------------------------------------------------------------- /lib/@cada/length.m: -------------------------------------------------------------------------------- 1 | function y = length(x) 2 | % CADA overloaded LENGTH 3 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | global ADIGATOR 6 | fid = ADIGATOR.PRINT.FID; 7 | NUMvod = ADIGATOR.NVAROFDIFF; 8 | indent = ADIGATOR.PRINT.INDENT; 9 | 10 | if ADIGATOR.FORINFO.FLAG 11 | IncreaseForSizeCount(); 12 | if ADIGATOR.RUNFLAG == 2 13 | y = ForLength(x); 14 | return 15 | end 16 | end 17 | if ADIGATOR.EMPTYFLAG 18 | y = cadaEmptyEval(x); 19 | if ~ADIGATOR.RUNFLAG 20 | numvars = find(ADIGATOR.VARINFO.NAMELOCS(:,1),1,'last'); 21 | cadaCancelDerivs(y.id,numvars); 22 | end 23 | return 24 | end 25 | 26 | y.id = ADIGATOR.VARINFO.COUNT; 27 | [funcstr,~] = cadafuncname(); 28 | y.func = struct('name',funcstr,'size',[1 1],'zerolocs',[],'value',... 29 | []); 30 | if any(x.func.size == 0) 31 | y.func.value = 0; 32 | else 33 | y.func.value = max(x.func.size); 34 | end 35 | y.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 36 | 37 | if ADIGATOR.PRINT.FLAG 38 | fprintf(fid,[indent,funcstr,' = length(',x.func.name,');\n']); 39 | end 40 | ADIGATOR.VARINFO.LASTOCC([y.id x.id],1) = ADIGATOR.VARINFO.COUNT; 41 | 42 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 43 | y = cada(y); 44 | if ADIGATOR.RUNFLAG == 1 && ADIGATOR.FORINFO.FLAG 45 | AssignForSizes(y.func.value); 46 | end 47 | end 48 | 49 | function IncreaseForSizeCount() 50 | global ADIGATOR ADIGATORFORDATA 51 | INNERLOC = ADIGATOR.FORINFO.INNERLOC; 52 | ADIGATORFORDATA(INNERLOC).COUNT.SIZE =... 53 | ADIGATORFORDATA(INNERLOC).COUNT.SIZE +1; 54 | end 55 | 56 | function AssignForSizes(xSize) 57 | global ADIGATOR ADIGATORFORDATA 58 | INNERLOC = ADIGATOR.FORINFO.INNERLOC; 59 | Scount = ADIGATORFORDATA(INNERLOC).COUNT.SIZE; 60 | ITERCOUNT = ADIGATORFORDATA(INNERLOC).COUNT.ITERATION; 61 | xSize(xSize ==0) = NaN; 62 | % Assign the Sizes 63 | if ITERCOUNT == 1 64 | ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES = xSize; 65 | else 66 | ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES(1,ITERCOUNT) = xSize; 67 | end 68 | end 69 | 70 | function y = ForLength(x) 71 | global ADIGATOR ADIGATORFORDATA 72 | INNERLOC = ADIGATOR.FORINFO.INNERLOC; 73 | Scount = ADIGATORFORDATA(INNERLOC).COUNT.SIZE; 74 | 75 | NUMvod = ADIGATOR.NVAROFDIFF; 76 | indent = ADIGATOR.PRINT.INDENT; 77 | fid = ADIGATOR.PRINT.FID; 78 | CountName = ADIGATORFORDATA(INNERLOC).COUNTNAME; 79 | 80 | y.id = ADIGATOR.VARINFO.COUNT; 81 | [funcstr,~] = cadafuncname(); 82 | y.func = struct('name',funcstr,'size',[1 1],'zerolocs',[],'value',[]); 83 | y.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 84 | 85 | if iscell(ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES) 86 | IndName = ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES{1}; 87 | DepFlag = ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES{3}(1); 88 | IndFlag = 1; 89 | else 90 | IndFlag = 0; 91 | outSize = ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES; 92 | end 93 | 94 | if ~IndFlag 95 | if isinf(outSize) 96 | fprintf(fid,[indent,funcstr,' = length(',x.func.name,');\n']); 97 | else 98 | fprintf(fid,[indent,funcstr,' = %1.0f;\n'],outSize); 99 | end 100 | elseif DepFlag 101 | fprintf(fid,[indent,funcstr,' = ',IndName,'(',CountName,');\n']); 102 | else 103 | fprintf(fid,[indent,funcstr,' = ',IndName,';\n']); 104 | end 105 | 106 | ADIGATOR.VARINFO.LASTOCC([y.id x.id],1) = ADIGATOR.VARINFO.COUNT; 107 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 108 | y = cada(y); 109 | end -------------------------------------------------------------------------------- /lib/@cada/mpower.m: -------------------------------------------------------------------------------- 1 | function z = mpower(x,y) 2 | % CADA overloaded version of function MPOWER. 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | global ADIGATOR 7 | if ADIGATOR.EMPTYFLAG 8 | z = cadaEmptyEval(x,y); 9 | return 10 | end 11 | NUMvod = ADIGATOR.NVAROFDIFF; 12 | PFLAG = ADIGATOR.PRINT.FLAG; 13 | % ----------------------------Parse Inputs------------------------------- % 14 | if isa(x,'cada') && isa(y,'cada') 15 | % Both Inputs are Symbolic 16 | xMrow = x.func.size(1); xNcol = x.func.size(2); 17 | yMrow = y.func.size(1); yNcol = y.func.size(2); 18 | elseif isa(x,'cada') 19 | % y is numeric input 20 | xMrow = x.func.size(1); xNcol = x.func.size(2); 21 | [yMrow,yNcol] = size(y); 22 | ytemp.id = []; 23 | ytemp.func = struct('name',[],'size',[yMrow yNcol],'zerolocs',[],... 24 | 'value',y); 25 | if PFLAG 26 | if yMrow*yNcol == 1 27 | ytemp.func.name = num2str(y,16); 28 | else 29 | ytemp.func.name = cadamatprint(y); 30 | end 31 | end 32 | ytemp.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 33 | y = ytemp; 34 | y = cada(y); 35 | else 36 | % x is numeric input 37 | yMrow = y.func.size(1); yNcol = y.func.size(2); 38 | [xMrow,xNcol] = size(x); 39 | xtemp.id = []; 40 | xtemp.func = struct('name',[],'size',[xMrow xNcol],'zerolocs',[],... 41 | 'value',x); 42 | if PFLAG 43 | if xMrow*xNcol == 1 44 | xtemp.func.name = num2str(x,16); 45 | else 46 | xtemp.func.name = cadamatprint(x); 47 | end 48 | end 49 | xtemp.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 50 | x = xtemp; 51 | x = cada(x); 52 | end 53 | 54 | if xMrow*xNcol == 1 && yMrow*yNcol == 1 55 | z = power(x,y); 56 | else 57 | error('overloaded matrix power can only handle: scalar inputs'); 58 | end 59 | -------------------------------------------------------------------------------- /lib/@cada/nnz.m: -------------------------------------------------------------------------------- 1 | function y = nnz(x) 2 | % CADA overloaded version of function NNZ 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | 7 | global ADIGATOR 8 | if ADIGATOR.EMPTYFLAG 9 | y = cadaEmptyEval(x); 10 | return 11 | end 12 | NUMvod = ADIGATOR.NVAROFDIFF; 13 | fid = ADIGATOR.PRINT.FID; 14 | PFLAG = ADIGATOR.PRINT.FLAG; 15 | indent = ADIGATOR.PRINT.INDENT; 16 | 17 | 18 | % -----------------------Build Y Function-------------------------------- % 19 | y.id = ADIGATOR.VARINFO.COUNT; 20 | funcstr = cadafuncname(); 21 | y.func = struct('name',funcstr,'size',[1 1],'zerolocs',[],'value',[]); 22 | 23 | % Function Numerics/Sparsity 24 | if ~isempty(x.func.value) 25 | % Y is numeric 26 | y.func.value = nnz(x.func.value); 27 | end 28 | 29 | % --------------------------Build Derivative----------------------------- % 30 | y.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 31 | 32 | % ---------------------Print Out Function-------------------------------- % 33 | if PFLAG 34 | fprintf(fid,[indent,funcstr,' = nnz(',x.func.name,');\n']); 35 | end 36 | ADIGATOR.VARINFO.LASTOCC([x.id y.id],1) = ADIGATOR.VARINFO.COUNT; 37 | y = cada(y); 38 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; -------------------------------------------------------------------------------- /lib/@cada/numel.m: -------------------------------------------------------------------------------- 1 | function y = numel(x) 2 | % CADA overloaded NUMEL function 3 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | Dbstuff = dbstack; 6 | if length(Dbstuff) > 1 7 | CallingFile = Dbstuff(2).file; 8 | else 9 | CallingFile = []; 10 | end 11 | if (length(CallingFile) > 16 && strcmp(CallingFile(1:16),'adigatortempfunc')) 12 | y = adigatornumel(x); 13 | else 14 | y = 1; 15 | end 16 | end 17 | 18 | function y = adigatornumel(x) 19 | global ADIGATOR 20 | fid = ADIGATOR.PRINT.FID; 21 | NUMvod = ADIGATOR.NVAROFDIFF; 22 | indent = ADIGATOR.PRINT.INDENT; 23 | if ADIGATOR.FORINFO.FLAG 24 | IncreaseForSizeCount(); 25 | if ADIGATOR.RUNFLAG == 2 26 | y = ForLength(x); 27 | return 28 | end 29 | end 30 | if ADIGATOR.EMPTYFLAG 31 | y = cadaEmptyEval(x); 32 | if ~ADIGATOR.RUNFLAG 33 | numvars = find(ADIGATOR.VARINFO.NAMELOCS(:,1),1,'last'); 34 | cadaCancelDerivs(y.id,numvars); 35 | end 36 | return 37 | end 38 | 39 | y.id = ADIGATOR.VARINFO.COUNT; 40 | [funcstr,~] = cadafuncname(); 41 | y.func = struct('name',funcstr,'size',[1 1],'zerolocs',[],'value',... 42 | []); 43 | y.func.value = prod(x.func.size); 44 | y.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 45 | 46 | if ADIGATOR.PRINT.FLAG 47 | fprintf(fid,[indent,funcstr,' = numel(',x.func.name,');\n']); 48 | end 49 | ADIGATOR.VARINFO.LASTOCC([y.id x.id],1) = ADIGATOR.VARINFO.COUNT; 50 | 51 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 52 | y = cada(y); 53 | if ADIGATOR.RUNFLAG == 1 && ADIGATOR.FORINFO.FLAG 54 | AssignForSizes(y.func.value); 55 | end 56 | end 57 | 58 | 59 | function IncreaseForSizeCount() 60 | global ADIGATOR ADIGATORFORDATA 61 | INNERLOC = ADIGATOR.FORINFO.INNERLOC; 62 | ADIGATORFORDATA(INNERLOC).COUNT.SIZE =... 63 | ADIGATORFORDATA(INNERLOC).COUNT.SIZE +1; 64 | end 65 | 66 | function AssignForSizes(xSize) 67 | global ADIGATOR ADIGATORFORDATA 68 | INNERLOC = ADIGATOR.FORINFO.INNERLOC; 69 | Scount = ADIGATORFORDATA(INNERLOC).COUNT.SIZE; 70 | ITERCOUNT = ADIGATORFORDATA(INNERLOC).COUNT.ITERATION; 71 | xSize(xSize ==0) = NaN; 72 | % Assign the Sizes 73 | if ITERCOUNT == 1 74 | ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES = xSize; 75 | else 76 | ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES(1,ITERCOUNT) = xSize; 77 | end 78 | end 79 | 80 | function y = ForLength(x) 81 | global ADIGATOR ADIGATORFORDATA 82 | INNERLOC = ADIGATOR.FORINFO.INNERLOC; 83 | Scount = ADIGATORFORDATA(INNERLOC).COUNT.SIZE; 84 | 85 | NUMvod = ADIGATOR.NVAROFDIFF; 86 | indent = ADIGATOR.PRINT.INDENT; 87 | fid = ADIGATOR.PRINT.FID; 88 | CountName = ADIGATORFORDATA(INNERLOC).COUNTNAME; 89 | 90 | y.id = ADIGATOR.VARINFO.COUNT; 91 | [funcstr,~] = cadafuncname(); 92 | y.func = struct('name',funcstr,'size',[1 1],'zerolocs',[],'value',[]); 93 | y.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 94 | 95 | if iscell(ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES) 96 | IndName = ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES{1}; 97 | DepFlag = ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES{3}(1); 98 | IndFlag = 1; 99 | else 100 | IndFlag = 0; 101 | outSize = ADIGATORFORDATA(INNERLOC).SIZE(Scount).SIZES; 102 | end 103 | 104 | if ~IndFlag 105 | if isinf(outSize) 106 | fprintf(fid,[indent,funcstr,' = numel(',x.func.name,');\n']); 107 | else 108 | fprintf(fid,[indent,funcstr,' = %1.0f;\n'],outSize); 109 | end 110 | elseif DepFlag 111 | fprintf(fid,[indent,funcstr,' = ',IndName,'(',CountName,');\n']); 112 | else 113 | fprintf(fid,[indent,funcstr,' = ',IndName,';\n']); 114 | end 115 | 116 | ADIGATOR.VARINFO.LASTOCC([y.id x.id],1) = ADIGATOR.VARINFO.COUNT; 117 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 118 | y = cada(y); 119 | end -------------------------------------------------------------------------------- /lib/@cada/private/cadaCancelDerivs.m: -------------------------------------------------------------------------------- 1 | function cadaCancelDerivs(varid,numvars) 2 | % this function is called by operations which operate on cada objects which 3 | % may contain derivatives, but the operation always results in an empty 4 | % derivative, 5 | % ex: a == x(1:3), dont want to print derivs of x(1:3) 6 | % 7 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 8 | % Distributed under the GNU General Public License version 3.0 9 | global ADIGATOR 10 | if ~ADIGATOR.RUNFLAG 11 | depvars = find(ADIGATOR.VARINFO.LASTOCC == varid); 12 | depvars = depvars(depvars > numvars); 13 | for Vcount = 1:length(depvars) 14 | depvar = depvars(Vcount); 15 | if depvar ~= varid 16 | ADIGATOR.VARINFO.NAMELOCS(depvar,3) = Inf; 17 | cadaCancelDerivs(depvar,numvars); 18 | end 19 | end 20 | end -------------------------------------------------------------------------------- /lib/@cada/private/cadaRemoveRowsCols.m: -------------------------------------------------------------------------------- 1 | function y = cadaRemoveRowsCols(x,ySize) 2 | %function y = cadaRemoveRowsCols(x,ySize) 3 | % This function is written to remove any rows/columns from an overloaded 4 | % object. This is called from overloaded binary operations when in the 5 | % Printing run of a FOR loop and two inputs to the binary operation are 6 | % overloaded. 7 | % 8 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 9 | % Distributed under the GNU General Public License version 3.0 10 | global ADIGATOR 11 | fid = ADIGATOR.PRINT.FID; 12 | indent = ADIGATOR.PRINT.INDENT; 13 | NUMvod = ADIGATOR.NVAROFDIFF; 14 | NDstr = sprintf('%1.0f',ADIGATOR.DERNUMBER); 15 | y = x; 16 | y.func.size = ySize; 17 | funcstr = ['cada',NDstr,'tempf1']; 18 | y.func.name = funcstr; 19 | ySize(isinf(ySize)) = 1; 20 | x.func.size(isinf(x.func.size)) = 1; 21 | % Function Numerics/Sparsity 22 | if ~isempty(y.func.value) 23 | y.func.value = y.func.value(1:ySize(1),1:ySize(2)); 24 | elseif ~isempty(y.func.zerolocs) 25 | xtemp = true(x.func.size); 26 | xtemp(y.func.zerolocs) = false; 27 | ytemp = xtemp(1:ySize(1),1:ySize(2)); 28 | y.func.zerolocs = find(~ytemp(:)); 29 | end 30 | % Get Linear Index 31 | xtemp = zeros(x.func.size); 32 | xtemp(:) = 1:x.func.size(1)*x.func.size(2); 33 | yref = xtemp(1:ySize(1),1:ySize(2)); 34 | yref = yref(:); 35 | 36 | 37 | % Derivatives 38 | for Vcount = 1:NUMvod 39 | if ~isempty(y.deriv(Vcount).nzlocs) 40 | derivstr = cadadername(funcstr,Vcount); 41 | xrows = x.deriv(Vcount).nzlocs(:,1); 42 | xcols = x.deriv(Vcount).nzlocs(:,2); 43 | nzx = length(xrows); 44 | dx = sparse(xrows,xcols,1:nzx,prod(x.func.size),ADIGATOR.VAROFDIFF(Vcount).usize); 45 | dy = dx(yref,:); 46 | 47 | [yrows,ycols,derInds] = find(dy); 48 | if size(yrows,2) > 1; yrows = yrows.'; ycols = ycols.'; end 49 | if ~isempty(yrows) 50 | TFind1 = cadaindprint(derInds(:)); 51 | fprintf(fid,[indent,derivstr,' = ',x.deriv(Vcount).name,'(',TFind1,');\n']); 52 | y.deriv(Vcount).nzlocs = [yrows ycols]; 53 | y.deriv(Vcount).name = derivstr; 54 | else 55 | y.deriv(Vcount).nzlocs = []; 56 | y.deriv(Vcount).name = []; 57 | end 58 | end 59 | end 60 | 61 | % Print Function 62 | if ySize < x.func.size 63 | fprintf(fid,[indent,funcstr,' = ',x.func.name,'(1:%1.0f,1:%1.0f);\n'],ySize(1),ySize(2)); 64 | elseif ySize(1) < x.func.size(1) 65 | fprintf(fid,[indent,funcstr,' = ',x.func.name,'(1:%1.0f,:);\n'],ySize(1)); 66 | else 67 | fprintf(fid,[indent,funcstr,' = ',x.func.name,'(:,1:%1.0f);\n'],ySize(1)); 68 | end -------------------------------------------------------------------------------- /lib/@cada/private/cadaRepDers.m: -------------------------------------------------------------------------------- 1 | function [yName,yInds] = cadaRepDers(xName,xInds,ySize,Vcount,DPFLAG) 2 | % This function is used to repmat derivatives of scalar variables. 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | global ADIGATOR 7 | fid = ADIGATOR.PRINT.FID; 8 | indent = ADIGATOR.PRINT.INDENT; 9 | NDstr = sprintf('%1.0f',ADIGATOR.DERNUMBER); 10 | 11 | nv = ADIGATOR.VAROFDIFF(Vcount).usize; 12 | dx = sparse(xInds(:,1),xInds(:,2),1:size(xInds,1),1,nv); 13 | dy = repmat(dx,ySize,1); 14 | 15 | [yrows,ycols,yind] = find(dy); 16 | 17 | if size(yrows,2) > 1 18 | yrows = yrows.'; ycols = ycols.'; 19 | end 20 | yInds = [yrows,ycols]; 21 | 22 | if DPFLAG 23 | yName = ['cada',NDstr,'tempd',ADIGATOR.VAROFDIFF(Vcount).name]; 24 | Dind1 = cadaindprint(yind); 25 | fprintf(fid,[indent,yName,' = ',xName,'(',Dind1,');\n']); 26 | else 27 | yName = xName; 28 | end -------------------------------------------------------------------------------- /lib/@cada/private/cadainversederiv.m: -------------------------------------------------------------------------------- 1 | function nzlocs = cadainversederiv(x,ytemp,Vcount,derivstr,DPFLAG) 2 | % This function does the Derivative Calculations for Matrix Inverse, thus, 3 | % mldivide, mrdivide, and inv call this function for matrix derivatives. 4 | % Letting y = inv(x), the derivative of the inverse is calculated using the 5 | % fact that I = y*x, thus dI = dy*x + y*dx = 0 => dy = -y*dx*y 6 | % 7 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 8 | % Distributed under the GNU General Public License version 3.0 9 | global ADIGATOR 10 | if DPFLAG 11 | fid = ADIGATOR.PRINT.FID; 12 | indent = ADIGATOR.PRINT.INDENT; 13 | NDstr = sprintf('%1.0f',ADIGATOR.DERNUMBER); 14 | end 15 | 16 | N = x.func.size(1); 17 | 18 | dxind = x.deriv(Vcount).nzlocs; 19 | nv = ADIGATOR.VAROFDIFF(Vcount).usize; 20 | nzx = size(dxind,1); 21 | % -------------------- X has Derivatives ---------------------------- % 22 | % we need to compute dy = -y*dx*y, 23 | % let dA = y*dx, we can compute dA by 24 | % dA = y*reshape(dx,N,N*nv) then reshape to size 25 | % [N*N,nv] 26 | dx = sparse(dxind(:,1),dxind(:,2),1:nzx,N*N,nv); 27 | dxReshape = reshape(dx,N,N*nv); 28 | dA = reshape(ytemp*dxReshape,N*N,nv); 29 | 30 | % We now have dA, let dy = dA*y, we can compute the transpose of dy 31 | % by dy' = y'*dA' 32 | % First get dA transpose 33 | ATranMap = zeros(N,N); ATranMap(:) = 1:N*N; 34 | ATranMap = ATranMap.'; 35 | dATranReshape = reshape(dA(ATranMap(:),:),N,N*nv); 36 | % Now can get dy' 37 | dyTran = reshape(ytemp.'*dATranReshape,N*N,nv); 38 | % Now get dy from dy' 39 | yTranMap = ATranMap; 40 | dy = dyTran(yTranMap(:),:); 41 | % we now have -dy really, but has same non-zero locations 42 | [yrows,ycols] = find(dy); 43 | if size(yrows,2) > 1; yrows = yrows.'; ycols = ycols.'; end 44 | 45 | if ~isempty(yrows) 46 | nzlocs = [yrows ycols]; 47 | if DPFLAG 48 | % --------------------- Derivative Printing --------------------- % 49 | % We need to print out all of the calculations that we just did 50 | % above 51 | % 1. Print out Calculations to get to dA 52 | % 1a. Project x derivative variable into a matrix corresponding to 53 | % dxReshape 54 | TD1 = ['cada',NDstr,'td1']; % dx' in file 55 | if N*N*nv > 250 && nzx < .6*N*N*nv 56 | SPflag = 1; 57 | % Do projection sparsely - dx is larger than 250 and has at least 58 | % 40% zeros 59 | dxrInds = zeros(nzx,2); 60 | [dxrInds(:,1),dxrInds(:,2)] = find(reshape(dxReshape,N,N*nv)); 61 | TDind1 = cadaindprint(dxrInds(:,1)); 62 | TDind2 = cadaindprint(dxrInds(:,2)); 63 | % Print out the Projection 64 | fprintf(fid,[indent,TD1,' = sparse(',TDind1,',',TDind2,',',... 65 | x.deriv(Vcount).name,',%1.0d,%1.0d);\n'],N,N*nv); 66 | else 67 | SPflag = 0; 68 | % Project into zeros using a linear index 69 | dxIndLin = sub2ind([N*N,nv],dxind(:,1),dxind(:,2)); 70 | % Note that dxreshape and dx share the same LINEAR index. 71 | TDind1 = cadaindprint(dxIndLin(:)); 72 | % Print out the projection 73 | fprintf(fid,[indent,TD1,' = zeros(%1.0d,%1.0d);\n'],N,N*nv); 74 | fprintf(fid,[indent,TD1,'(',TDind1,') = ',... 75 | x.deriv(Vcount).name,';\n']); 76 | end 77 | % 1b. We can now print out calculations for dAReshape = 78 | % y*dxReshape, or equivalently, x\dxReshape, reshape to dA here as 79 | % well 80 | if SPflag && nnz(dA) > 0.6*N*N*nv 81 | fprintf(fid,[indent,TD1,' = reshape(full(',x.func.name,'\\',TD1,... 82 | '),%1.0d,%1.0d);\n'],N*N,nv); 83 | SPflag = 0; 84 | else 85 | fprintf(fid,[indent,TD1,' = reshape(',x.func.name,'\\',TD1,... 86 | ',%1.0d,%1.0d);\n'],N*N,nv); 87 | end 88 | % TD1 is now dA 89 | % 2. Print out Calculations to get dy 90 | % 2a. print out dATranReshape 91 | TDind1 = cadaindprint(ATranMap(:)); 92 | fprintf(fid,[indent,TD1,' = reshape(',TD1,'(',TDind1,',:),',... 93 | '%1.0d,%1.0d);\n'],N,N*nv); 94 | % TD1 is now dATranReshape 95 | % 2b. Print out calculations to get dyTranReshape = 96 | % y'*dATranReshape = x'\dATransposeReshape 97 | fprintf(fid,[indent,TD1,' = ',x.func.name,'.''\\',TD1,';\n']); 98 | % 2c. Need to get a linear reference which will reference off of 99 | % dyTranReshape into the non-zeros of dy. 100 | [yTrows,yTcols] = find(dyTran); 101 | dyTIndLin = sub2ind([N*N,nv],yTrows,yTcols); 102 | dyTran = sparse(yTrows,yTcols,dyTIndLin,N*N,nv); 103 | dy = dyTran(yTranMap(:),:); 104 | % Note that dyTranReshape and dyTran share the same linear index. 105 | dyIndLin = nonzeros(dy); 106 | TDind1 = cadaindprint(dyIndLin(:)); 107 | % Can now print out dy 108 | if SPflag 109 | fprintf(fid,[indent,derivstr,' = -full(',TD1,'(',TDind1,'));\n']); 110 | else 111 | fprintf(fid,[indent,derivstr,' = -',TD1,'(',TDind1,');\n']); 112 | end 113 | end 114 | else 115 | nzlocs = []; 116 | end -------------------------------------------------------------------------------- /lib/@cada/private/cadaunion.m: -------------------------------------------------------------------------------- 1 | function [z,zxind,zyind,xflag,yflag] = cadaunion(x,y,m,n) 2 | % CADA derivative UNION 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | 7 | xrows = x(:,1); xcols = x(:,2); nzx = size(x,1); 8 | yrows = y(:,1); ycols = y(:,2); nzy = size(y,1); 9 | 10 | x = sparse(xrows,xcols,-ones(nzx,1),m,n); 11 | y = sparse(yrows,ycols,2*ones(nzy,1),m,n); 12 | 13 | z = x+y; 14 | % Get nonzero locs of z deriv 15 | [zrows,zcols,zind] = find(z); 16 | if size(zrows,2) > 1 17 | zrows = zrows'; zcols = zcols'; zind = zind'; 18 | end 19 | z = [zrows,zcols]; nzz = length(zrows); 20 | 21 | % Get which indices of z correspond to x 22 | zxind = find(zind<2); 23 | if nzz == nzx; xflag = 1; else xflag = 0; end 24 | 25 | % Get which indices of z correspond to y 26 | zyind = find(zind>0); 27 | if nzz == nzy; yflag = 1; else yflag = 0; end -------------------------------------------------------------------------------- /lib/@cada/sub2ind.m: -------------------------------------------------------------------------------- 1 | function K = sub2ind(Asize,I,J) 2 | % Overloaded sub2ind - only works on known numeric objects and with 3 3 | % inputs 4 | % 5 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 6 | % Distributed under the GNU General Public License version 3.0 7 | global ADIGATOR 8 | if ADIGATOR.EMPTYFLAG 9 | K = cadaEmptyEval(Asize,I,J); 10 | return 11 | end 12 | PFLAG = ADIGATOR.PRINT.FLAG; 13 | indent = ADIGATOR.PRINT.INDENT; 14 | fid = ADIGATOR.PRINT.FID; 15 | NUMvod = ADIGATOR.NVAROFDIFF; 16 | [Asize,Astr] = parseInput(Asize); 17 | [I,Istr] = parseInput(I); 18 | [J,Jstr] = parseInput(J); 19 | Knum = sub2ind(Asize,I,J); 20 | 21 | K.id = ADIGATOR.VARINFO.COUNT; 22 | [funcstr,~] = cadafuncname(); 23 | K.func = struct('name',funcstr,'size',size(Knum),'zerolocs',[],'value',Knum); 24 | K.deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 25 | if PFLAG 26 | fprintf(fid,[indent,funcstr,' = sub2ind(',Astr,',',Istr,',',Jstr,');\n']); 27 | end 28 | ADIGATOR.VARINFO.LASTOCC(K.id,1) = ADIGATOR.VARINFO.COUNT; 29 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 30 | K = cada(K); 31 | end 32 | function [num,str] = parseInput(x) 33 | global ADIGATOR 34 | PFLAG = ADIGATOR.PRINT.FLAG; 35 | if isa(x,'cada') 36 | if ~isempty(x.func.value) 37 | str = x.func.name; 38 | num = x.func.value; 39 | ADIGATOR.VARINFO.LASTOCC(x.id,1) = ADIGATOR.VARINFO.COUNT; 40 | else 41 | error('overloaded sub2ind only meant to be used on known numeric objects') 42 | end 43 | else 44 | num = x; 45 | if PFLAG 46 | str = cadaindprint(x); 47 | else 48 | str = []; 49 | end 50 | end 51 | 52 | end -------------------------------------------------------------------------------- /lib/@cadastruct/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator overloaded @cadastruct class - all cell/structs of original 2 | % program replaced by objects of cadastruct class in intermediate program 3 | % 4 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | % 7 | % ----------------------------------------------------------------------- % 8 | % FILES: 9 | % adigatorPrintOutputIndices.m - print output derivative indices, calls 10 | % overloaded cada version 11 | % adigatorStructAnalyzer.m - recursively parses cells/structures 12 | % (overloaded cadastruct version) 13 | % adigatorVarAnalyzer.m - analyzes variables after they have been 14 | % assigned in intermediate program 15 | % (overloaded cadastruct version) 16 | % cadaCheckForDerivs.m - check to see if any of the cada objects 17 | % belonging to the cell/structure have 18 | % derivatives 19 | % cadaOverMap.m - builds overmapped objects in overmapping 20 | % evaluation, stores variables when 21 | % necessary, calls cadaPrintReMap when 22 | % necessary (cadastruct overloaded version) 23 | % cadaPrintReMap.m - prints re-mapping procedures when either 24 | % going from an undermapped object to an 25 | % overmapped object (adding zeros), or the 26 | % opposite (removing zeros) (cadastruct 27 | % overloaded version) 28 | % cadaUnionVars.m - cadastruct overloaded union operator 29 | % cadastruct.m - cadastruct class definition file 30 | % ctranspose.m - overloaded ctranspose 31 | % horzcat.m - overloaded horzcat 32 | % isequal.m - overloaded isequal 33 | % length.m - overloaded length 34 | % numel.m - overloaded numel 35 | % ppval.m - overloaded ppval 36 | % repmat.m - overloaded repmat 37 | % reshape.m - overloaded reshape 38 | % size.m - overloaded size 39 | % struct.m - overloaded struct 40 | % subsasgn.m - overloaded subsasgn 41 | % subsref.m - overloaded subsref 42 | % transpose.m - overloaded transpose 43 | % vertcat.m - overloaded vertcat 44 | % ----------------------------------------------------------------------- % 45 | % PRIVATE DIRECTORY FILES: 46 | % adigatorPrintStructAsgn.m - prints out structure assignments recursively 47 | % cadaloopstructderivref.m - prints loop iteration dependent derivative 48 | % variable references from within structures 49 | % cadaloopstructfuncref.m - prints loop iteration dependent function 50 | % variable references from within structures -------------------------------------------------------------------------------- /lib/@cadastruct/adigatorPrintOutputIndices.m: -------------------------------------------------------------------------------- 1 | function adigatorPrintOutputIndices(x) 2 | % Parses through object to call CADA version of adigatorPrintOutputIndices 3 | % 4 | % See also: cada/adigatorPrintOutputIndices 5 | ParsePrint(x.id,x.val,x.name); 6 | end 7 | 8 | function ParsePrint(sid,x,xname) 9 | global ADIGATOR 10 | if isa(x,'cada') 11 | % Need to give this the proper names - going to do this by creating 12 | % ''dummy'' entries in NAMELOCS 13 | xid = ADIGATOR.VARINFO.COUNT; 14 | adigatorAssignImpVarNames(xid,xname,0); 15 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 16 | x.id = xid; 17 | ADIGATOR.VARINFO.NAMELOCS(xid,2) = ADIGATOR.VARINFO.NAMELOCS(sid,2); 18 | adigatorPrintOutputIndices(x); 19 | elseif isstruct(x) && ~isempty(x) 20 | fnames = fieldnames(x); 21 | if numel(x) > 1 22 | for I = 1:numel(x) 23 | for J = 1:length(fnames) 24 | F = fnames{J}; 25 | ParsePrint(sid,x(I).(F),sprintf([xname,'(%1.0f).',F],I)); 26 | end 27 | end 28 | else 29 | for J = 1:length(fnames) 30 | F = fnames{J}; 31 | ParsePrint(sid,x.(F),[xname,'.',F]); 32 | end 33 | end 34 | elseif iscell(x) && ~isempty(x) 35 | for I = 1:numel(x) 36 | ParsePrint(sid,x{I},sprintf([xname,'{%1.0f}'],I)); 37 | end 38 | end 39 | end -------------------------------------------------------------------------------- /lib/@cadastruct/adigatorStructAnalyzer.m: -------------------------------------------------------------------------------- 1 | function x = adigatorStructAnalyzer(x,xStr,subsflag) 2 | % CADASTRUCT overloaded version of adigatorStructAnalyzer 3 | % 4 | % Called to recursively parse structure/cell objects and call 5 | % adigatorVarAnalyzer on each of the CADA objects. 6 | 7 | global ADIGATOR 8 | if isa(x,'cadastruct') && ~x.arrayflag 9 | x = x.val; 10 | if ~isempty(x) 11 | x = orderfields(x); 12 | fnames = fieldnames(x); 13 | for I = 1:length(fnames) 14 | F = fnames{I}; 15 | x.(F) = adigatorStructAnalyzer(x.(F),[xStr,'.',F],0); 16 | end 17 | end 18 | else 19 | xID = x.id; 20 | if size(ADIGATOR.VARINFO.NAMELOCS,1) >= xID 21 | if isinf(ADIGATOR.VARINFO.NAMELOCS(xID,3)) 22 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.COUNT,3) = ADIGATOR.VARINFO.NAMELOCS(xID,3); 23 | end 24 | if ADIGATOR.VARINFO.NAMELOCS(xID,2) < 0 25 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.COUNT,2) = ADIGATOR.VARINFO.NAMELOCS(xID,2); 26 | end 27 | end 28 | ADIGATOR.VARINFO.LASTOCC([xID,ADIGATOR.VARINFO.COUNT],1) = ADIGATOR.VARINFO.COUNT; 29 | xid = ADIGATOR.VARINFO.COUNT; 30 | if ADIGATOR.RUNFLAG == 2 && ~ADIGATOR.EMPTYFLAG && ... 31 | any(ADIGATOR.VARINFO.NAMELOCS(xid,2) ~= ... 32 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.LASTOCC(:,1)==xid,2)) 33 | adigatorPrintStructAsgn(x,xStr,x.name,xid,x.id); 34 | end 35 | x.name = xStr; 36 | x.id = xid; 37 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT + 1; 38 | x = adigatorVarAnalyzer('',x,xStr,subsflag); 39 | end 40 | -------------------------------------------------------------------------------- /lib/@cadastruct/cadaCheckForDerivs.m: -------------------------------------------------------------------------------- 1 | function flag = cadaCheckForDerivs(x) 2 | % This just checks and overloaded structure array to see if it has any 3 | % derivatives 4 | % 5 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 6 | % Distributed under the GNU General Public License version 3.0 7 | flag = structparse(x.val); 8 | end 9 | 10 | function flag = structparse(x) 11 | 12 | if isstruct(x) 13 | [M,N] = size(x); 14 | Fnames = fieldnames(x); 15 | for I=1:M 16 | for J = 1:N 17 | for K = 1:length(Fnames) 18 | Fstr = Fnames{K}; 19 | flag = structparse(x(I,J).(Fstr)); 20 | if flag 21 | return 22 | end 23 | end 24 | end 25 | end 26 | elseif iscell(x) 27 | [M,N] = size(x); 28 | for I=1:M 29 | for J = 1:N 30 | flag = structparse(x{I,J}); 31 | if flag 32 | return 33 | end 34 | end 35 | end 36 | elseif isa(x,'cada') 37 | flag = cadaCheckForDerivs(x); 38 | else 39 | flag = 0; 40 | end 41 | 42 | end -------------------------------------------------------------------------------- /lib/@cadastruct/cadaUnionVars.m: -------------------------------------------------------------------------------- 1 | function z = cadaUnionVars(x,y) 2 | % Union two cadastruct vars together 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | 7 | if ~isa(x,'cadastruct') 8 | z = y; 9 | xval = x; 10 | yval = y.val; 11 | elseif ~isa(y,'cadastruct') 12 | xval = x.val; 13 | yval = y; 14 | z = x; 15 | else 16 | xval = x.val; 17 | yval = y.val; 18 | z = x; 19 | end 20 | 21 | z.val = uniondriver(xval,yval,z.name); 22 | end 23 | 24 | function z = uniondriver(x,y,name) 25 | if isa(x,'cadastruct') 26 | x = x.val; 27 | end 28 | if isa(y,'cadastruct') 29 | y = y.val; 30 | end 31 | xclass = class(x); yclass = class(y); 32 | if ~strcmp(xclass,yclass) 33 | if (isa(x,'cada') && prod(x.func.size) == 0) || (isnumeric(x) && isempty(x)) 34 | z = y; 35 | elseif isa(y,'cada') && prod(y.func.size) == 0 || (isnumeric(y) && isempty(y)) 36 | z = x; 37 | else 38 | error([name,' takes on either an ',xclass,' or a ',yclass,... 39 | ' depending upon a loop iteration, conditional statement,',... 40 | ' function call, etc. This is not allowed']); 41 | end 42 | else 43 | switch xclass 44 | case 'cada' 45 | z = cadaUnionVars(x,y); 46 | case 'struct' 47 | z = structureunion(x,y,name); 48 | case 'cell' 49 | z = cellunion(x,y,name); 50 | otherwise 51 | z = x; 52 | end 53 | end 54 | 55 | end 56 | 57 | function z = structureunion(x,y,name) 58 | xMrow = size(x,1); xNcol = size(x,2); xfields = fieldnames(x); 59 | yMrow = size(y,1); yNcol = size(y,2); yfields = fieldnames(y); 60 | zMrow = max(xMrow,yMrow); zNcol = max(xNcol,yNcol); 61 | 62 | % Need to determine 4 sets {i,j,f}, where z(i,j).f = 63 | % Set 1: x(i,j).f U y(i,j).f 64 | % Set 2: x(i,j).f; 65 | % Set 3: y(i,j).f; 66 | % Set 4: empty 67 | zfields = unique([xfields;yfields]); 68 | zset = [zfields.'; repmat({cell(zMrow,zNcol)},1,length(zfields))]; 69 | % Initialize z 70 | z = struct(zset{:}); 71 | if zMrow*zNcol == 1 72 | for Fcount = 1:length(zfields) 73 | F = zfields{Fcount}; 74 | xfieldflag = any(strcmp(F,xfields)); 75 | yfieldflag = any(strcmp(F,yfields)); 76 | if xfieldflag 77 | if yfieldflag 78 | % Case 1 79 | z.(F) = uniondriver(x.(F),y.(F),sprintf('%s.%s',name,F)); 80 | else 81 | % Case 2 82 | z.(F) = x.(F); 83 | end 84 | elseif yfieldflag 85 | % Case 3 86 | z.(F) = y.(F); 87 | end 88 | end 89 | else 90 | for Fcount = 1:length(zfields) 91 | F = zfields{Fcount}; 92 | xfieldflag = any(strcmp(F,xfields)); 93 | yfieldflag = any(strcmp(F,yfields)); 94 | for I = 1:zMrow 95 | for J = 1:zNcol 96 | if xfieldflag && I <= xMrow && J <= xNcol 97 | if yfieldflag && I <= yMrow && J <= yNcol 98 | % Case 1 99 | z(I,J).(F) = uniondriver(x(I,J).(F),y(I,J).(F),sprintf('%s(%1.0f,%1.0f).%s',name,I,J,F)); 100 | else 101 | % Case 2 102 | z(I,J).(F) = x(I,J).(F); 103 | end 104 | elseif yfieldflag && I <= yMrow && J <= yNcol 105 | % Case 3 106 | z(I,J).(F) = y(I,J).(F); 107 | end 108 | end 109 | end 110 | end 111 | end 112 | end 113 | 114 | function z = cellunion(x,y,name) 115 | xMrow = size(x,1); xNcol = size(x,2); 116 | yMrow = size(y,1); yNcol = size(y,2); 117 | zMrow = max(xMrow,yMrow); zNcol = max(xNcol,yNcol); 118 | 119 | z = cell(zMrow,zNcol); 120 | for I = 1:zMrow 121 | for J = 1:zNcol 122 | if I <= xMrow && J <= xNcol 123 | if I <= yMrow && J <= yNcol 124 | z{I,J} = uniondriver(x{I,J},y{I,J},sprintf('%s{%1.0f,%1.0f}',name,I,J)); 125 | else 126 | z{I,J} = x{I,J}; 127 | end 128 | elseif I <= yMrow && J <= yNcol 129 | z{I,J} = y{I,J}; 130 | end 131 | end 132 | end 133 | end -------------------------------------------------------------------------------- /lib/@cadastruct/cadastruct.m: -------------------------------------------------------------------------------- 1 | classdef cadastruct 2 | % cadastruct classdef file for use with the ADiGator package. 3 | % 4 | % This class was introduced in order to adigator to handle cell and 5 | % structure array references/assignments. It is used internally by the 6 | % ADiGator algorithm and is not intended for general use. 7 | % 8 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 9 | % Distributed under the GNU General Public License version 3.0 10 | 11 | properties 12 | % Unique integer ID 13 | id 14 | % Name of the cell/structure in the printed derivative file 15 | name 16 | % Structure/cell data containing CADA objects 17 | val 18 | % Flag stating whether data is cell/structure array or scalar structure 19 | arrayflag 20 | end 21 | 22 | % Constructor 23 | methods 24 | function y = cadastruct(x,name,id,arrayflag) 25 | if nargin == 1 && isstruct(x) 26 | y.id = x.id; 27 | y.name = x.name; 28 | y.val = x.val; 29 | y.arrayflag = x.arrayflag; 30 | else 31 | y.id = id; 32 | y.name = name; 33 | y.val = x; 34 | y.arrayflag = arrayflag; 35 | end 36 | end 37 | end 38 | 39 | % Overloaded Methods 40 | methods 41 | y = ctranspose(x) 42 | y = horzcat(varargin) 43 | z = isequal(x,y,varargin) 44 | y = length(x) 45 | yi = ppval(pp,xi) 46 | y = repmat(x,varargin) 47 | y = reshape(x,varargin) 48 | varargout = size(x,varargin) 49 | y = struct(varargin) 50 | x = subsasgn(x,s,b) 51 | y = subsref(x,s) 52 | y = transpose(x) 53 | y = vertcat(varargin) 54 | function y = isfield(x,f) 55 | % CADASTRUCT overloaded ISFIELD function 56 | y = isfield(x.val,f); 57 | end 58 | function y = numel(varargin) 59 | % CADASTRUCT overloaded NUMEL - always returns 1, cannot be used to 60 | % determine number of elements of cell/structure array 61 | y = 1; 62 | end 63 | end 64 | 65 | % Overloaded Utility Methods 66 | methods 67 | adigatorPrintOutputIndices(x); 68 | x = adigatorStructAnalyzer(x,xStr,subsflag) 69 | x = adigatorVarAnalyzer(FunString,x,xStr,subsflag) 70 | flag = cadaCheckForDerivs(x) 71 | xOut = cadaOverMap(x,DAid) 72 | y = cadaPrintReMap(x,y,varID) 73 | z = cadaUnionVars(x,y) 74 | end 75 | 76 | % Access Methods 77 | methods 78 | function val = cadaGetStruct(y) 79 | % Value access for cadastruct 80 | val = y.val; 81 | end 82 | function val = cadaGetStructID(y) 83 | % ID access for cadastruct 84 | val = y.id; 85 | end 86 | function aflag = cadaIsArray(x) 87 | % Checks if object corresponds to a structure/cell array 88 | aflag = x.arrayflag; 89 | end 90 | function [val, name, id, arrayflag] = cadastructDecomp(x) 91 | % Accesses all cadastruct data 92 | val = x.val; 93 | name = x.name; 94 | id = x.id; 95 | arrayflag = x.arrayflag; 96 | end 97 | end 98 | 99 | end -------------------------------------------------------------------------------- /lib/@cadastruct/ctranspose.m: -------------------------------------------------------------------------------- 1 | function y = ctranspose(x) 2 | % CADASTRUCT overloaded version of CTRANSPOSE 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | global ADIGATOR 7 | fid = ADIGATOR.PRINT.FID; 8 | PFLAG = ADIGATOR.PRINT.FLAG; 9 | indent = ADIGATOR.PRINT.INDENT; 10 | 11 | y = x; 12 | y.id = ADIGATOR.VARINFO.COUNT; 13 | if ADIGATOR.RUNFLAG == 2 14 | nameloc = ADIGATOR.VARINFO.NAMELOCS(y.id,1); 15 | if nameloc > 0 16 | yname = ADIGATOR.VARINFO.NAMES{nameloc}; 17 | else 18 | yname = sprintf(['cada',NDstr,'s%1.0f'],ADIGATOR.VARINFO.NAMELOCS(yid,2)); 19 | end 20 | else 21 | yname = 'cadadummystruct'; 22 | end 23 | y.name = yname; 24 | y.val = ctranspose(x.val); 25 | 26 | if PFLAG && ~ADIGATOR.EMPTYFLAG 27 | fprintf(fid,[indent,yname,' = ctranspose(',x.name,');\n']); 28 | end 29 | 30 | ADIGATOR.VARINFO.LASTOCC([y.id x.id],1) = ADIGATOR.VARINFO.COUNT; 31 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 32 | end -------------------------------------------------------------------------------- /lib/@cadastruct/isequal.m: -------------------------------------------------------------------------------- 1 | function z = isequal(x,y,varargin) 2 | % CADASTRUCT overloaded version of function ISEQUAL (arrays) 3 | % Implementation is only for internal ADiGator algorithm isequal calls, 4 | % logic has not been coded to allow users to use isequal on structures/cell 5 | % arrays. 6 | 7 | Dbstuff = dbstack; 8 | if length(Dbstuff)>1 9 | CallingFile = Dbstuff(2).file; 10 | else 11 | CallingFile = []; 12 | end 13 | if (length(CallingFile) > 16 && strcmp(CallingFile(1:16),'adigatortempfunc')) 14 | error('not yet coded') 15 | elseif nargin > 2 16 | error('not yet coded') 17 | end 18 | 19 | z = isequal(x.val,y.val); -------------------------------------------------------------------------------- /lib/@cadastruct/length.m: -------------------------------------------------------------------------------- 1 | function y = length(x) 2 | % CADASTRUCT overloaded LENGTH 3 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | global ADIGATOR 6 | % just make a dummy CADA variable and use CADA length 7 | NUMvod = ADIGATOR.NVAROFDIFF; 8 | func = struct('name',x.name,'size',size(x.val),'zerolocs',[],'value',[]); 9 | deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 10 | 11 | xdummy = cada(x.id,func,deriv); 12 | y = length(xdummy); 13 | end -------------------------------------------------------------------------------- /lib/@cadastruct/ppval.m: -------------------------------------------------------------------------------- 1 | function yi = ppval(pp,xi) 2 | % CADASTRUCT overloaded PPVAL 3 | % This is just a wrapper for the CADA ppval. 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | global ADIGATOR 7 | if ~isa(xi,'cada') 8 | NUMvod = ADIGATOR.NVAROFDIFF; 9 | PFLAG = ADIGATOR.PRINT.FLAG; 10 | func = struct('name',[],'size',size(xi),'zerolocs',[],... 11 | 'value',xi); 12 | deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 13 | if PFLAG && ~ADIGATOR.EMPTYFLAG 14 | if numel(xi) < 11 && floor(xi(:))==xi(:) 15 | func.name = mat2str(xi); 16 | else 17 | func.name = cadamatprint(xi); 18 | end 19 | end 20 | xi = cada([],func,deriv); 21 | end 22 | 23 | if pp.arrayflag 24 | ADIGATOR.VARINFO.LASTOCC(pp.id,1) = ADIGATOR.VARINFO.COUNT; 25 | ADIGATOR.VARINFO.NAMELOCS(pp.id,3) = -Inf; 26 | fnames = fieldnames(pp.val); 27 | ppname = pp.name; 28 | for Fcount = 1:length(fnames) 29 | F = fnames{Fcount}; 30 | v = pp.val.(F); 31 | if isa(v,'cada') 32 | v.func.name = [ppname,'.',F]; 33 | end 34 | end 35 | else 36 | fnames = fieldnames(pp.val); 37 | for Fcount = 1:length(fnames) 38 | F = fnames{Fcount}; 39 | v = pp.val.(F); 40 | if isa(v,'cada') 41 | vid = v.id; 42 | ADIGATOR.VARINFO.LASTOCC(vid,1) = ADIGATOR.VARINFO.COUNT; 43 | ADIGATOR.VARINFO.NAMELOCS(vid,3) = -Inf; 44 | end 45 | end 46 | end 47 | yi = ppval(pp.val,xi); 48 | 49 | 50 | end -------------------------------------------------------------------------------- /lib/@cadastruct/private/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator overloaded @cadastruct class private library folder 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % adigatorPrintStructAsgn.m - prints out structure assignments recursively 9 | % cadaloopstructderivref.m - prints loop iteration dependent derivative 10 | % variable references from within structures 11 | % cadaloopstructfuncref.m - prints loop iteration dependent function 12 | % variable references from within structures 13 | -------------------------------------------------------------------------------- /lib/@cadastruct/private/adigatorPrintStructAsgn.m: -------------------------------------------------------------------------------- 1 | function adigatorPrintStructAsgn(x,xStrA,xStrR,idA,idR) 2 | % this does a recursive call to build proper strings and print out 3 | % structure assignments 4 | % 5 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 6 | % Distributed under the GNU General Public License version 3.0 7 | global ADIGATOR 8 | if isa(x,'cadastruct') 9 | x = x.val; 10 | end 11 | 12 | if isa(x,'cada') 13 | fid = ADIGATOR.PRINT.FID; 14 | indent = ADIGATOR.PRINT.INDENT; 15 | namelocA = ADIGATOR.VARINFO.NAMELOCS(idA,1); 16 | Aflag = 0; 17 | if namelocA == 0 18 | Aflag = 1; 19 | namelocA = length(ADIGATOR.VARINFO.NAMES)+1; 20 | ADIGATOR.VARINFO.NAMES{namelocA} = []; 21 | end 22 | namelocR = ADIGATOR.VARINFO.NAMELOCS(idR,1); 23 | Rflag = 0; 24 | if namelocR == 0 25 | Rflag = 1; 26 | namelocR = length(ADIGATOR.VARINFO.NAMES)+1; 27 | ADIGATOR.VARINFO.NAMES{namelocR} = []; 28 | end 29 | oldnameA = ADIGATOR.VARINFO.NAMES{namelocA}; 30 | oldnameR = ADIGATOR.VARINFO.NAMES{namelocR}; 31 | ADIGATOR.VARINFO.NAMES{namelocA} = xStrA; 32 | ADIGATOR.VARINFO.NAMES{namelocR} = xStrR; 33 | [funcstrA,DPflag] = cadafuncname(idA); 34 | funcstrR = cadafuncname(idR); 35 | xderiv = x.deriv; 36 | if DPflag 37 | for Vcount = 1:length(xderiv) 38 | if ~isempty(xderiv(Vcount).nzlocs) 39 | derivstrA = cadadername(funcstrA,Vcount,idA); 40 | derivstrR = cadadername(funcstrR,Vcount,idR); 41 | fprintf(fid,[indent,derivstrA,' = ',derivstrR,';\n']); 42 | end 43 | end 44 | end 45 | fprintf(fid,[indent,funcstrA,' = ',funcstrR,';\n']); 46 | ADIGATOR.VARINFO.NAMES{namelocA} = oldnameA; 47 | ADIGATOR.VARINFO.NAMES{namelocR} = oldnameR; 48 | if Rflag 49 | ADIGATOR.VARINFO.NAMES(namelocR) = []; 50 | end 51 | if Aflag 52 | ADIGATOR.VARINFO.NAMES(namelocA) = []; 53 | end 54 | elseif isstruct(x) 55 | fnames = fieldnames(x); 56 | for Fcount = 1:length(fnames) 57 | F = fnames{Fcount}; 58 | if numel(x) > 1 59 | for I = 1:size(x,1) 60 | for J = 1:size(x,2) 61 | Istr = sprintf('%1.0d,%1.0d',I,J); 62 | adigatorPrintStructAsgn(x(I,J).(F),[xStrA,'(',Istr,').',F],[xStrR,'(',Istr,').',F],idA,idR); 63 | end 64 | end 65 | else 66 | adigatorPrintStructAsgn(x.(F),[xStrA,'.',F],[xStrR,'.',F],idA,idR); 67 | end 68 | end 69 | elseif iscell(x) 70 | for I = 1:size(x,1) 71 | for J = 1:size(x,2) 72 | Istr = sprintf('%1.0d,%1.0d',I,J); 73 | adigatorPrintStructAsgn(x{I,J},[xStrA,'{',Istr,'}'],[xStrR,'{',Istr,'}'],idA,idR); 74 | end 75 | end 76 | else 77 | fid = ADIGATOR.PRINT.FID; 78 | indent = ADIGATOR.PRINT.INDENT; 79 | fprintf(fid,[indent,xStrA,' = ',xStrR,';\n']); 80 | end 81 | 82 | end -------------------------------------------------------------------------------- /lib/@cadastruct/private/cadaloopstructderivref.m: -------------------------------------------------------------------------------- 1 | function cadaloopstructderivref(inputstruct) 2 | % This function prints out the iteration dependent structure/cell array 3 | % referencing and assignment stuff - called from overloaded CADASTRUCT 4 | % subsasgn/subsref 5 | % 6 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 7 | % Distributed under the GNU General Public License version 3.0 8 | 9 | refflag = inputstruct.refflag; 10 | % refflag = 1 => subsref => y = x(i) 11 | % refflag = 0 => subsasgn => x(i) = y 12 | if refflag 13 | derivstr = inputstruct.dyStr; 14 | derivrefstr = inputstruct.dxiStr; 15 | else 16 | derivstr = inputstruct.dxiStr; 17 | derivrefstr = inputstruct.dyStr; 18 | end 19 | 20 | fid = inputstruct.fid; 21 | indent = inputstruct.indent; 22 | IndName = inputstruct.IndName; 23 | IndFlags = inputstruct.IndFlags; 24 | CountName = inputstruct.CountName; 25 | vvec = inputstruct.vvec; 26 | nzd = inputstruct.nzd; 27 | NDstr = inputstruct.NDstr; 28 | vecDim = inputstruct.vecDim; 29 | emptycheck = inputstruct.emptycheck; 30 | emptyfieldcheck = inputstruct.emptyfieldcheck; 31 | % this will only be true if being called from s(i).y(j) = b, where b is cada 32 | 33 | if isempty(IndName) 34 | fprintf(fid,[indent,derivstr,' = ',derivrefstr,';\n']); 35 | else 36 | if vvec 37 | % Vectorized 38 | if IndFlags(1) 39 | % Indices change on this loop 40 | asgnind = ['(:,logical(',IndName,'(:,',CountName,')))']; 41 | else 42 | % Indices do not change on this loop 43 | asgnind = ['(:,logical(',IndName,'))']; 44 | end 45 | else 46 | % Non-Vectorized 47 | if IndFlags(1) 48 | % Indices change on this loop 49 | asgnind = ['(logical(',IndName,'(:,',CountName,')))']; 50 | else 51 | % Indices do not change on this loop 52 | asgnind = ['(logical(',IndName,'))']; 53 | end 54 | end 55 | 56 | if refflag 57 | % Initialize dy if reference - dont need initiliaze if is assignment 58 | TD1 = ['cada',NDstr,'td1']; 59 | if vvec 60 | fprintf(fid,[indent,TD1,' = zeros(',vecDim,',%1.0d);\n'],nzd); 61 | else 62 | fprintf(fid,[indent,TD1,' = zeros(%1.0d,1);\n'],nzd); 63 | end 64 | end 65 | if emptycheck 66 | TF1 = ['cada',NDstr,'tf1']; 67 | if vvec 68 | fprintf(fid,[indent,TF1,' = ',asgnind(4:end-1),';\n']); 69 | asgnind = ['(:,',TF1,')']; 70 | else 71 | fprintf(fid,[indent,TF1,' = ',asgnind(2:end-1),';\n']); 72 | asgnind = ['(',TF1,')']; 73 | end 74 | fprintf(fid,[indent,'cadaconditional1 = any(',TF1,');\n']); 75 | fprintf(fid,[indent,'if cadaconditional1\n']); 76 | indent = [indent,' ']; 77 | elseif emptyfieldcheck 78 | TD2 = ['cada',NDstr,'td2']; 79 | fprintf(fid,[indent,TD2,' = ',derivrefstr,';\n']); 80 | fprintf(fid,[indent,'cadaconditional1 = ~isempty(',TD2,');\n']); 81 | fprintf(fid,[indent,'if cadaconditional1\n']); 82 | indent = [indent,' ']; 83 | derivrefstr = TD2; 84 | end 85 | if refflag 86 | % reference is dy(logical) = dxi 87 | fprintf(fid,[indent,TD1,asgnind,' = ',derivrefstr,';\n']); 88 | else 89 | % assignment is dxi = dy(logical) 90 | fprintf(fid,[indent,derivstr,' = ',derivrefstr,asgnind,';\n']); 91 | end 92 | if emptycheck || emptyfieldcheck 93 | indent(1:4) = []; 94 | fprintf(fid,[indent,'end\n']); 95 | end 96 | if refflag 97 | fprintf(fid,[indent,derivstr,' = ',TD1,';\n']); 98 | end 99 | end -------------------------------------------------------------------------------- /lib/@cadastruct/private/cadaloopstructfuncref.m: -------------------------------------------------------------------------------- 1 | function cadaloopstructfuncref(inputstruct) 2 | % This function prints out the iteration dependent structure/cell array 3 | % referencing and assignment stuff - called from overloaded CADASTRUCT 4 | % subsasgn/subsref 5 | % 6 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 7 | % Distributed under the GNU General Public License version 3.0 8 | 9 | refflag = inputstruct.refflag; 10 | % refflag = 1 => subsref => y = x(i) 11 | % refflag = 0 => subsasgn => x(i) = y 12 | funcstr = inputstruct.yStr; 13 | funrefstr = inputstruct.xiStr; 14 | 15 | fid = inputstruct.fid; 16 | indent = inputstruct.indent; 17 | sizecheck = inputstruct.sizecheck; 18 | 19 | if sizecheck 20 | IndName = inputstruct.IndName; 21 | 22 | CountName = inputstruct.CountName; 23 | vvec = inputstruct.vvec; 24 | vMrow = inputstruct.vsize(1); 25 | vNcol = inputstruct.vsize(2); 26 | NDstr = inputstruct.NDstr; 27 | vecDim = inputstruct.vecDim; 28 | emptyfieldcheck = inputstruct.emptyfieldcheck; 29 | TF1 = ['cada',NDstr,'tempf1']; 30 | TF2 = ['cada',NDstr,'tempf2']; 31 | if ~strcmp(TF1,funrefstr) 32 | fprintf(fid,[indent,TF1,' = ',funrefstr,';\n']); 33 | end 34 | if refflag 35 | % Initialize to zeros if reference. 36 | if vvec == 1 37 | fprintf(fid,[indent,TF2,' = zeros(',vecDim,',%1.0f);\n'],vNcol); 38 | elseif vvec == 2 39 | fprintf(fid,[indent,TF2,' = zeros(%1.0f,',vecDim,');\n'],vMrow); 40 | else 41 | fprintf(fid,[indent,TF2,' = zeros(%1.0f,%1.0f);\n'],vMrow,vNcol); 42 | end 43 | end 44 | if emptyfieldcheck 45 | fprintf(fid,[indent,'cadaconditional1 = ~isempty(',TF1,');\n']); 46 | fprintf(fid,[indent,'if cadaconditional1\n']); 47 | indent = [indent,' ']; 48 | end 49 | if ~isempty(IndName) 50 | % Check to make sure that this reference actually happens 51 | IndDep = inputstruct.IndDep; 52 | if IndDep 53 | fprintf(fid,[indent,'cadaconditional1 = ~',IndName,'(%1.0f,',CountName,');\n'],inputstruct.Scount); 54 | else 55 | fprintf(fid,[indent,'cadaconditional1 = ~',IndName,'(%1.0f);\n'],inputstruct.Scount); 56 | end 57 | fprintf(fid,[indent,'if cadaconditional1\n']); 58 | indent = [indent,' ']; 59 | end 60 | if refflag 61 | if vvec == 1 62 | fprintf(fid,[indent,TF2,'(:,1:size(',TF1,',2)) = ',TF1,';\n']); 63 | elseif vvec == 2 64 | fprintf(fid,[indent,TF2,'(1:size(',TF1,',1),:) = ',TF1,';\n']); 65 | else 66 | fprintf(fid,[indent,TF2,'(1:size(',TF1,',1),1:size(',TF1,',2)) = ',TF1,';\n']); 67 | end 68 | else 69 | if vvec == 1 70 | fprintf(fid,[indent,TF2,' = ',funcstr,'(:,1:size(',TF1,',2));\n']); 71 | elseif vvec == 2 72 | fprintf(fid,[indent,TF2,' = ',funcstr,'(1:size(',TF1,',1),:);\n']); 73 | else 74 | fprintf(fid,[indent,TF2,' = ',funcstr,'(1:size(',TF1,',1),1:size(',TF1,',2));\n']); 75 | end 76 | end 77 | if ~isempty(IndName) 78 | indent(1:4) = []; 79 | fprintf(fid,[indent,'end\n']); 80 | end 81 | if emptyfieldcheck 82 | indent(1:4) = []; 83 | fprintf(fid,[indent,'end\n']); 84 | end 85 | if refflag 86 | fprintf(fid,[indent,funcstr,' = ',TF2,';\n']); 87 | else 88 | fprintf(fid,[indent,funrefstr,' = ',TF2,';\n']); 89 | end 90 | elseif refflag 91 | fprintf(fid,[indent,funcstr,' = ',funrefstr,';\n']); 92 | else 93 | fprintf(fid,[indent,funrefstr,' = ',funcstr,';\n']); 94 | end -------------------------------------------------------------------------------- /lib/@cadastruct/reshape.m: -------------------------------------------------------------------------------- 1 | function y = reshape(x,varargin) 2 | % CADASTRUCT overloaded version of function RESHAPE. 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | global ADIGATOR 7 | fid = ADIGATOR.PRINT.FID; 8 | PFLAG = ADIGATOR.PRINT.FLAG; 9 | indent = ADIGATOR.PRINT.INDENT; 10 | % ----------------------------Determine Inputs----------------------------% 11 | varargSize = length(varargin); 12 | if varargSize == 0 ; 13 | error('Requires at least 2 inputs.'); 14 | elseif varargSize == 1 15 | if isa(varargin{1},'cada') 16 | if ~isempty(varargin{1}.func.value) 17 | ADIGATOR.VARINFO.LASTOCC(varargin{1}.id,1) = ADIGATOR.VARINFO.COUNT; 18 | if length(varargin{1}.func.value) > 2 19 | error('cannot RESHAPE more than 2 dimensions') 20 | elseif length(varargin{1}.func.value) == 1 21 | error('Size vector must have at least two elements.'); 22 | end 23 | FMrow = varargin{1}.func.value(1); 24 | FNcol = varargin{1}.func.value(2); 25 | RepStr = varargin{1}.func.name; 26 | elseif ~ADIGATOR.EMPTYFLAG 27 | error('cannot RESHAPE a strictly symbolic dimension') 28 | end 29 | elseif length(varargin{1}) == 2 30 | FMrow = varargin{1}(1); 31 | FNcol = varargin{1}(2); 32 | RepStr = sprintf('%1.0f,%1.0f',FMrow,FNcol); 33 | elseif ~ADIGATOR.EMPTYFLAG 34 | error('cannot RESHAPE more than 2 dimensions') 35 | else 36 | FMrow = []; 37 | FNcol = []; 38 | end 39 | elseif varargSize == 2 40 | FMrow = varargin{1}; 41 | if isa(FMrow,'cada') 42 | if ~isempty(FMrow.func.value) 43 | ADIGATOR.VARINFO.LASTOCC(FMrow.id,1) = ADIGATOR.VARINFO.COUNT; 44 | RowStr = FMrow.func.name; 45 | FMrow = FMrow.func.value; 46 | elseif ~ADIGATOR.EMPTYFLAG 47 | error('cannot RESHAPE a strictly symbolic dimension') 48 | else 49 | FMrow = []; 50 | end 51 | else 52 | RowStr = sprintf('%1.0f',FMrow); 53 | end 54 | FNcol = varargin{2}; 55 | if isa(FNcol,'cada') 56 | if ~isempty(FNcol.func.value) 57 | ADIGATOR.VARINFO.LASTOCC(FNcol.id,1) = ADIGATOR.VARINFO.COUNT; 58 | ColStr = FNcol.func.name; 59 | FNcol = FNcol.func.value; 60 | elseif ~ADIGATOR.EMPTYFLAG 61 | error('cannot RESHAPE a strictly symbolic dimension') 62 | else 63 | FNcol = []; 64 | end 65 | else 66 | ColStr = sprintf('%1.0f',FNcol); 67 | end 68 | RepStr = ['',RowStr,',',ColStr,'']; 69 | else 70 | error('Too many input arguments.'); 71 | end 72 | if FMrow*FNcol ~= numel(x.val) 73 | error('To RESHAPE the number of elements must not change.') 74 | end 75 | 76 | % --------------------------Parse X-------------------------------------- % 77 | y = x; 78 | y.id = ADIGATOR.VARINFO.COUNT; 79 | if ADIGATOR.RUNFLAG == 2 80 | nameloc = ADIGATOR.VARINFO.NAMELOCS(y.id,1); 81 | if nameloc > 0 82 | yname = ADIGATOR.VARINFO.NAMES{nameloc}; 83 | else 84 | yname = sprintf('cada%1.0ds%1.0f',ADIGATOR.NVAROFDIFF,ADIGATOR.VARINFO.NAMELOCS(y.id,2)); 85 | end 86 | else 87 | yname = 'cadadummystruct'; 88 | end 89 | y.name = yname; 90 | if ~ADIGATOR.EMPTYFLAG || (~isempty(FMrow) && ~isempty(FNcol)) 91 | y.val = reshape(x.val,FMrow,FNcol); 92 | end 93 | 94 | if ADIGATOR.RUNFLAG > 0 && isinf(ADIGATOR.VARINFO.NAMELOCS(x.id,3)) 95 | ADIGATOR.VARINFO.NAMELOCS(y.id,3) = ADIGATOR.VARINFO.NAMELOCS(x.id,3); 96 | end 97 | if PFLAG && ~ADIGATOR.EMPTYFLAG 98 | fprintf(fid,[indent,yname,' = reshape(',x.name,',',RepStr,');\n']); 99 | end 100 | 101 | ADIGATOR.VARINFO.LASTOCC([y.id x.id],1) = ADIGATOR.VARINFO.COUNT; 102 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 103 | end -------------------------------------------------------------------------------- /lib/@cadastruct/size.m: -------------------------------------------------------------------------------- 1 | function varargout = size(x,varargin) 2 | % CADASTRUCT overloaded SIZE routine 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | 7 | global ADIGATOR 8 | % just make a dummy CADA variable and use CADA length 9 | NUMvod = ADIGATOR.NVAROFDIFF; 10 | func = struct('name',x.name,'size',size(x.val),'zerolocs',[],'value',[]); 11 | deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 12 | xdummy = cada(x.id,func,deriv); 13 | if nargout == 1 && nargin == 1 14 | % This is the case that Matlab Workspace will call - If you put a 15 | % keyboard in this section you are going to crash matlab if you have the 16 | % workspace open. 17 | Dbstuff = dbstack; 18 | if length(Dbstuff)>1 19 | CallingFile = Dbstuff(2).file; 20 | else 21 | CallingFile = []; 22 | end 23 | if ADIGATOR.OPTIONS.KEYBOARD 24 | error(['Cannot use size with nargin = nargout = 1 when you have a',... 25 | '''keyboard'' within the code - causes an error with the MATLAB WorkSpace.']); 26 | elseif (length(CallingFile) > 16 && strcmp(CallingFile(1:16),'adigatortempfunc')) 27 | varargout{1} = size(xdummy); 28 | else 29 | varargout{1} = func.size; 30 | end 31 | elseif nargin == 2 && (nargout == 1 || nargout == 0) 32 | varargout{1} = size(xdummy,varargin{1}); 33 | elseif nargin == 1 && (nargout == 2 || nargout == 0) 34 | [varargout{1}, varargout{2}] = size(xdummy); 35 | elseif nargout > 2 36 | error('Too many output arguments') 37 | elseif nargin > 2 38 | error('Too many input arguments') 39 | end -------------------------------------------------------------------------------- /lib/@cadastruct/struct.m: -------------------------------------------------------------------------------- 1 | function y = struct(varargin) 2 | % CADASTRUCT overloaded version of function STRUCT 3 | 4 | inputs = varargin; 5 | for i = 2:2:nargin 6 | if isa(inputs{i},'cadastruct') 7 | inputs{i} = inputs{i}.val; 8 | end 9 | end 10 | y = struct(inputs{:}); -------------------------------------------------------------------------------- /lib/@cadastruct/transpose.m: -------------------------------------------------------------------------------- 1 | function y = transpose(x) 2 | % CADASTRUCT overloaded version of TRANSPOSE 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | global ADIGATOR 7 | fid = ADIGATOR.PRINT.FID; 8 | PFLAG = ADIGATOR.PRINT.FLAG; 9 | indent = ADIGATOR.PRINT.INDENT; 10 | 11 | y = x; 12 | y.id = ADIGATOR.VARINFO.COUNT; 13 | if ADIGATOR.RUNFLAG == 2 14 | nameloc = ADIGATOR.VARINFO.NAMELOCS(y.id,1); 15 | if nameloc > 0 16 | yname = ADIGATOR.VARINFO.NAMES{nameloc}; 17 | else 18 | yname = sprintf('cada%1.0ds%1.0f',ADIGATOR.NVAROFDIFF,ADIGATOR.VARINFO.NAMELOCS(y.id,2)); 19 | end 20 | else 21 | yname = 'cadadummystruct'; 22 | end 23 | y.name = yname; 24 | y.val = transpose(x.val); 25 | 26 | if PFLAG && ~ADIGATOR.EMPTYFLAG 27 | fprintf(fid,[indent,yname,' = transpose(',x.name,');\n']); 28 | end 29 | if ADIGATOR.RUNFLAG > 0 && isinf(ADIGATOR.VARINFO.NAMELOCS(x.id,3)) 30 | ADIGATOR.VARINFO.NAMELOCS(y.id,3) = ADIGATOR.VARINFO.NAMELOCS(x.id,3); 31 | end 32 | ADIGATOR.VARINFO.LASTOCC([y.id x.id],1) = ADIGATOR.VARINFO.COUNT; 33 | ADIGATOR.VARINFO.COUNT = ADIGATOR.VARINFO.COUNT+1; 34 | end -------------------------------------------------------------------------------- /lib/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator source transformation library 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % CLASSES: 8 | % cada - primary overloaded class, all doubles of 9 | % original program replaced by objects of 10 | % cada class in intermediate program 11 | % cadastruct - all cells/structures of original program 12 | % replaced by objects of cadastruct class 13 | % in intermediate program, cadastruct 14 | % objects contain cell/structure arrays 15 | % which also contain cada objects. 16 | % adigatorInput - class to define adigator input variables 17 | % 18 | % ----------------------------------------------------------------------- % 19 | % FILES: 20 | % adigatorAssignImpVarNames.m - adds new row to ADIGATOR.VARINFO.NAMELOCS 21 | % when new user variable encountered 22 | % adigatorAssignOvermapScheme.m - uses data collected in ADIGATOR.VARINFO 23 | % on parsing run to assign overmapping 24 | % scheme 25 | % adigatorBreakCont.m - called from intermediate program where a 26 | % break/continue statement used to be 27 | % adigatorError.m - called from intermediate program where an 28 | % error statement used to be 29 | % adigatorEvalInterp2pp.m - evaluates a 2D piecewise polynomial as 30 | % built by adigatorGenInterp2pp 31 | % adigatorForInitialize.m - initialization of for loops in 32 | % intermediate program 33 | % adigatorForIterEnd.m - called at end of each loop iteration 34 | % adigatorForIterStart.m - called at start of each loop iteration 35 | % adigatorFunctionEnd.m - called at end of each adigatortempfunc# 36 | % adigatorFunctionInitialize.m - called at start of each adigatortempfunc# 37 | % adigatorGenInterp2pp.m - generates coefficients of 2D 38 | % interpolation polynomials 39 | % adigatorIfInitialize.m - initialization of conditional 40 | % if/elseif/else statements in intermediate 41 | % program 42 | % adigatorIfIterEnd.m - called at start of each if/elseif/else 43 | % branch 44 | % adigatorIfIterStart.m - called at end of each if/elseif/else 45 | % branch 46 | % adigatorIfLooper.m - initializes a loop on an if statement if 47 | % ADIGATOR.OPTIONS.UNROLL = 1 48 | % adigatorIfLooperi.m - called on each iteration of an if 49 | % statement if ADIGATOR.OPTIONS.UNROLL = 1 50 | % adigatorMakeNumeric.m - transforms a double object into a known 51 | % numeric cada object 52 | % adigatorPrintTempFiles.m - transforms user functions into 53 | % intermediate functions 54 | % adigatorSeperateFunLines.m - looks for multiple lines of code on 55 | % single function line 56 | % adigatorSetCellEvalFlag.m - sets a global flag so that any celleval 57 | % commands in the intermediate program do 58 | % not invoke cadastruct operations 59 | % adigatorStructAnalyzer.m - recursively parses cells/structures 60 | % (non-overloaded version) 61 | % adigatorVarAnalyzer.m - analyzes variables after they have been 62 | % assigned in intermediate program 63 | % (non-overloaded version) 64 | % ----------------------------------------------------------------------- % 65 | % DIRECTORIES: 66 | % cadaUtils - common utility functions called by 67 | % cada/cadastruct routines -------------------------------------------------------------------------------- /lib/adigatorAssignImpVarNames.m: -------------------------------------------------------------------------------- 1 | function adigatorAssignImpVarNames(VarID,VarStr,SubsFlag) 2 | %function adigatorAssignImpVarNames(VarID,VarStr,SubsFlag) 3 | % this module assigns values to the ADIGATOR.VARINFO.NAMES and 4 | % ADIGATOR.VARINFO.NAMELOCS fields for a given user defined Assignment 5 | % Variable 6 | % --------------------- Input Information ------------------------------- % 7 | % VarID - .id field of the overloaded variable 8 | % VarStr - user string which variable is named in output file 9 | % SubsFlag - binary flag, true means variable was a subs-assignment 10 | % 11 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 12 | % Distributed under the GNU General Public License version 3.0 13 | global ADIGATOR 14 | cadaStrCmp = strcmp(VarStr,ADIGATOR.VARINFO.NAMES); 15 | 16 | if ~any(cadaStrCmp) 17 | %--Create New VARNAMES Cell-- 18 | VarNameLoc = length(ADIGATOR.VARINFO.NAMES)+1; 19 | %--Set VARNAMELOCS-- 20 | ADIGATOR.VARINFO.NAMES{VarNameLoc,1} = VarStr; 21 | ADIGATOR.VARINFO.NAMELOCS(VarID,1) = VarNameLoc; 22 | else 23 | %--Already has VARNAMES Cell-- 24 | NameIndices = 1:length(ADIGATOR.VARINFO.NAMES); 25 | VarNameLoc = NameIndices(cadaStrCmp); 26 | %--Set VARNAMELOCS-- 27 | if length(VarNameLoc) > 1 28 | for Vcount = VarNameLoc(2:end) 29 | ADIGATOR.VARINFO.NAMES{Vcount} = '-'; 30 | ADIGATOR.VARINFO.NAMELOCS(ADIGATOR.VARINFO.NAMELOCS(:,1)==Vcount,1) = VarNameLoc(1); 31 | end 32 | VarNameLoc = VarNameLoc(1); 33 | end 34 | ADIGATOR.VARINFO.NAMELOCS(VarID,1) = VarNameLoc; 35 | end 36 | if SubsFlag == 0 37 | ADIGATOR.VARINFO.NAMELOCS(VarID,3) = 1; 38 | end 39 | end -------------------------------------------------------------------------------- /lib/adigatorBreakCont.m: -------------------------------------------------------------------------------- 1 | function adigatorBreakCont(type,IfCount,BroCount) 2 | % All user defined BREAKS/CONTINUES are replaced with this function in the 3 | % intermediate program. 4 | % 5 | % Inputs: 6 | % type - string defining whether the statement is a 'break' or 'continue' 7 | % IfCount - integer identifying the conditional if/elseif/else set to 8 | % which the break/continue belongs 9 | % BroCount - integer identifying the branch of the conditional set to 10 | % which the break/continue belongs 11 | % 12 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 13 | % Distributed under the GNU General Public License version 3.0 14 | global ADIGATOR 15 | 16 | if ~ADIGATOR.RUNFLAG 17 | if ~ADIGATOR.FORINFO.FLAG 18 | error('breaks and continues must be contained within a loop') 19 | elseif ADIGATOR.OPTIONS.UNROLL 20 | error('breaks and continues cannot be used when unrolling loops.') 21 | end 22 | if strcmp(type,'break') 23 | ADIGATOR.BREAKLOCS(end+1,:) = [IfCount, BroCount,... 24 | ADIGATOR.FORINFO.INNERLOC,ADIGATOR.FORINFO.OUTERLOC]; 25 | else 26 | ADIGATOR.CONTLOCS(end+1,:) = [IfCount, BroCount,... 27 | ADIGATOR.FORINFO.INNERLOC,ADIGATOR.FORINFO.OUTERLOC]; 28 | end 29 | elseif ADIGATOR.RUNFLAG == 2 && ~ADIGATOR.EMPTYFLAG 30 | fprintf(ADIGATOR.PRINT.FID,[ADIGATOR.PRINT.INDENT,type,'\n']); 31 | end 32 | end -------------------------------------------------------------------------------- /lib/adigatorError.m: -------------------------------------------------------------------------------- 1 | function adigatorError(IfCount,BroCount,ErrorMsg) 2 | % All user error functions are replaced with this function in the 3 | % intermediate program. 4 | % 5 | % Inputs: 6 | % IfCount - integer identifying the conditional if/elseif/else set to 7 | % which the error belongs 8 | % BroCount - integer identifying the branch of the conditional set to 9 | % which the error belongs 10 | % ErrorMsg - string containing the error message to be printed (won't 11 | % work well if this is more complex than a simple string) 12 | % 13 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 14 | % Distributed under the GNU General Public License version 3.0 15 | global ADIGATOR 16 | 17 | if ~ADIGATOR.RUNFLAG && ~ADIGATOR.OPTIONS.PREALLOCATE 18 | ADIGATOR.ERRORLOCS(end+1,:) = [IfCount, BroCount]; 19 | elseif ADIGATOR.RUNFLAG == 2 && ~ADIGATOR.EMPTYFLAG 20 | fprintf(ADIGATOR.PRINT.FID,[ADIGATOR.PRINT.INDENT,ErrorMsg,'\n']); 21 | end 22 | end -------------------------------------------------------------------------------- /lib/adigatorEvalInterp2pp.m: -------------------------------------------------------------------------------- 1 | function ZI = adigatorEvalInterp2pp(pp,XI,YI) 2 | % function ZI = adigatorEvalInterp2pp(pp,XI,YI) 3 | % NON-OVERLOADED VERSION 4 | % This function is used to evaluate the 2-D piecewise polynomials generated 5 | % using the adigatorGenInterp2pp function. Since MATLAB does not have a 6 | % built in 2-D polynomial evaluation command, this file will need to be in 7 | % the user's path if they create a derivative file by using the adigator 8 | % command on a function file which contains an interp2 command. The inputs 9 | % to this are the pp generated by pp = adigatorGenInterp2pp(X,Y,Z,method), 10 | % as well as the inputs XI, YI. 11 | % 12 | % The following two lines of code: 13 | % 14 | % pp = adigatorGenInterp2pp(X,Y,Z,method); 15 | % ZI = adigatorEvalInterp2pp(pp,XI,YI); 16 | % 17 | % Are (roughly) equivalent to the single line of code: 18 | % 19 | % ZI = interp2(X,Y,Z,XI,YI,method,'extrap'); 20 | % 21 | % Where the difference is due to rounding errors since when using the 22 | % adigatorGenInterp2pp and adigatorEvalInterp2pp commands, the 2-D 23 | % coefficients are calculated, whereas MATLAB interp2 essentially performs 24 | % interp1 twice, thus generating 1-D coefficients twice. 25 | % 26 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 27 | % Distributed under the GNU General Public License version 3.0 28 | % 29 | % See also interp2, interp1, ppval, adigatorGenInterp2pp 30 | 31 | 32 | % -------------------------- Get pp Data -------------------------------- % 33 | xorder = pp.xorder; 34 | yorder = pp.yorder; 35 | X = pp.xbreaks; 36 | Y = pp.ybreaks.'; 37 | D = pp.coefs; 38 | % Info on D: 39 | % 1st index corresponds to y location 40 | % 2nd index corresponds to x location 41 | % 3rd index corresponds to y order 42 | % 4th index corresponds to x order 43 | 44 | M = length(Y); 45 | N = length(X); 46 | 47 | % Find where XI and YI lie 48 | [~,xindex] = histc(XI,[-inf,X(2:N-1),inf]); 49 | [~,yindex] = histc(YI,[-inf;Y(2:M-1);inf]); 50 | 51 | if size(XI) == size(YI) 52 | % ZI will be the size of XI and YI - will need to use a linear index for 53 | % this 54 | [ZIrow,ZIcol] = size(XI); 55 | 56 | % Switch to Linear Indexing on first to dimensions of D 57 | %D = reshape(D,[(M-1)*(N-1),yorder,xorder]); 58 | D = cellfun(@(Di)reshape(Di,[(M-1)*(N-1),1]),D,'UniformOutput',0); 59 | xyindex = sub2ind([M-1,N-1],yindex(:),xindex(:)); 60 | 61 | % Switch to XI-X, YI-Y 62 | XD = XI(:) - X(xindex(:)).'; 63 | YD = YI(:) - Y(yindex(:)); 64 | 65 | % Build ZI 66 | ZI = zeros(ZIrow*ZIcol,1); 67 | for I=1:yorder 68 | for J=1:xorder 69 | ZI = ZI + D{I,J}(xyindex).*YD.^(yorder-I).*XD.^(xorder-J); 70 | %ZI = ZI + D(xyindex,I,J).*YD.^(yorder-I).*XD.^(xorder-J); 71 | end 72 | end 73 | ZI = reshape(ZI,[ZIrow, ZIcol]); 74 | elseif (size(XI,1) == 1 && size(YI,2) == 1) || ... 75 | (size(XI,2) == 1 && size(YI,1) == 1) 76 | % ZI will have row dimension of length of YI and column dimension of 77 | % length of XI 78 | ZIrow = length(YI); ZIcol = length(XI); 79 | 80 | % Switch to XI-X, YI-Y 81 | XD = XI(:) - X(xindex(:)).'; 82 | YD = YI(:) - Y(yindex(:)); 83 | 84 | XD = repmat(XD.',[ZIrow 1]); 85 | YD = repmat(YD,[1 ZIcol]); 86 | 87 | ZI = zeros(ZIrow,ZIcol); 88 | for I = 1:yorder 89 | for J = 1:xorder 90 | ZI = ZI + D{I,J}(yindex,xindex).*YD.^(yorder-I).*XD.^(xorder-J); 91 | %ZI = ZI + D(yindex,xindex,I,J).*YD.^(yorder-I).*XD.^(xorder-J); 92 | end 93 | end 94 | else 95 | error('XI and YI must be the same size or vectors of different orientations.') 96 | end -------------------------------------------------------------------------------- /lib/adigatorFindMatchingParen.m: -------------------------------------------------------------------------------- 1 | function m = adigatorFindMatchingParen(str,n) 2 | % Finds the parenthesis pair given an open or close location. Modified from 3 | % MATLAB Cody problem to identifier type of bracket e.g. (, [, { 4 | % Inputs: 5 | % str - string to parse 6 | % n - location of open/close 7 | % Copyright 2011-214 Matthew J. Weinstein 8 | % Distributed under the GNU General Public License version 3.0 9 | 10 | if strcmp(str(n),'{') || strcmp(str(n),'}') 11 | os = '{'; cs = '}'; 12 | elseif strcmp(str(n),'(') || strcmp(str(n),')') 13 | os = '('; cs = ')'; 14 | elseif strcmp(str(n),'[') || strcmp(str(n),']') 15 | os = '['; cs = ']'; 16 | else 17 | error('String location not a bracket'); 18 | end 19 | 20 | startLocs = strfind(str,os); 21 | endLocs = strfind(str,cs); 22 | 23 | 24 | if any(startLocs == n) 25 | forward = true; 26 | else 27 | % If given closing location, just flip problem 28 | forward = false; 29 | ll = 1:length(str); 30 | str2 = fliplr(str); 31 | ll2 = fliplr(ll); 32 | startLocs = strfind(str2,cs); 33 | endLocs = strfind(str2,os); 34 | n = find(ll2 == n); 35 | end 36 | 37 | endLocs = endLocs(endLocs > n); 38 | startLocs = startLocs(startLocs > n); 39 | m = 0; 40 | for k = 1:length(endLocs) 41 | nb = nnz(startLocs < endLocs(k)); 42 | if nb == k-1 43 | m = endLocs(k); 44 | break; 45 | end 46 | end 47 | 48 | if forward == false 49 | m = ll2(m); 50 | end 51 | end -------------------------------------------------------------------------------- /lib/adigatorIfIterStart.m: -------------------------------------------------------------------------------- 1 | function [outEvalStr, outEvalVar] = adigatorIfIterStart(IfCount,BroCount) 2 | % This transformation routine is placed prior the the beginning of each 3 | % IF/ELSEIF/ELSE block in the intermediate program. 4 | % 5 | % Inputs: 6 | % IfCount - integer identifying the conditional if/elseif/else set 7 | % BroCount - integer identifying the branch of the conditional set 8 | % (e.g. 1 corresponds to the opening "if" branch) 9 | % 10 | % Outputs: 11 | % outEvalStr - cell arary of strings to be evaluated on the output in 12 | % order to modify the workspace 13 | % outEvalVar - cell array containing variables to be placed into the 14 | % workspace 15 | % 16 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 17 | % Distributed under the GNU General Public License version 3.0 18 | global ADIGATOR 19 | if ADIGATOR.OPTIONS.PREALLOCATE 20 | % Pre-Allocating cells/structures - have to treat everything as if it is 21 | % a true statement. 22 | outEvalStr = []; 23 | outEvalVar = []; 24 | elseif ~ADIGATOR.RUNFLAG 25 | % --------------------------------------------------------------------- % 26 | % Empty Run % 27 | % --------------------------------------------------------------------- % 28 | ADIGATOR.IFDATA(IfCount).BROS(BroCount).START = ADIGATOR.VARINFO.COUNT; 29 | outEvalVar = []; 30 | outEvalStr = []; 31 | elseif ADIGATOR.RUNFLAG == 1 32 | % --------------------------------------------------------------------- % 33 | % OverMap Run % 34 | % --------------------------------------------------------------------- % 35 | ADIGATOR.EMPTYFLAG = ~ADIGATOR.IFDATA(IfCount).BROS(BroCount).RUNFLAG; 36 | if ~ADIGATOR.EMPTYFLAG && ~isempty(ADIGATOR.IFDATA(IfCount).BROS(BroCount).PRIORDEP) 37 | [outEvalStr outEvalVar] = GetIncomingVariables(... 38 | ADIGATOR.IFDATA(IfCount).PRIORDEP,ADIGATOR.IFDATA(IfCount).BROS(BroCount).PRIORDEP); 39 | else 40 | outEvalVar = []; 41 | outEvalStr = []; 42 | end 43 | else 44 | % --------------------------------------------------------------------- % 45 | % Printing Run % 46 | % --------------------------------------------------------------------- % 47 | fid = ADIGATOR.PRINT.FID; 48 | indent = ADIGATOR.PRINT.INDENT; 49 | if BroCount == 1 50 | % ---------------------------- IF ----------------------------------- % 51 | if ADIGATOR.IFDATA(IfCount).BROS(1).RUNFLAG && ADIGATOR.IFDATA(IfCount).PRINTFLAG 52 | fprintf(fid,[indent,'if cadaconditional1\n']); 53 | end 54 | else 55 | % ------------------------ ELSEIF/ELSE ------------------------------ % 56 | if ADIGATOR.IFDATA(IfCount).BROS(BroCount).RUNFLAG 57 | if ADIGATOR.EMPTYFLAG 58 | % Previous Case didnt run, check to make sure IF statement has been 59 | % printed. 60 | IfFlag = 0; 61 | for Bcount = 1:BroCount-1 62 | if ADIGATOR.IFDATA(IfCount).BROS(Bcount).RUNFLAG 63 | IfFlag = 1; break 64 | end 65 | end 66 | else 67 | IfFlag = 1; 68 | end 69 | if IfFlag 70 | if ~ADIGATOR.IFDATA(IfCount).ELSEFLAG ||... 71 | BroCount < length(ADIGATOR.IFDATA(IfCount).BROS) 72 | fprintf(fid,[indent,'elseif cadaconditional%1.0d\n'],BroCount); 73 | else 74 | fprintf(fid,[indent,'else\n']); 75 | end 76 | else 77 | if (~ADIGATOR.IFDATA(IfCount).ELSEFLAG ||... 78 | BroCount < length(ADIGATOR.IFDATA(IfCount).BROS)) ... 79 | && ADIGATOR.IFDATA(IfCount).PRINTFLAG 80 | fprintf(fid,[indent,'if cadaconditional%1.0d\n'],BroCount); 81 | end 82 | end 83 | end 84 | end 85 | ADIGATOR.PRINT.INDENT = [indent,' ']; 86 | ADIGATOR.EMPTYFLAG = ~ADIGATOR.IFDATA(IfCount).BROS(BroCount).RUNFLAG; 87 | if ~ADIGATOR.EMPTYFLAG && ~isempty(ADIGATOR.IFDATA(IfCount).BROS(BroCount).PRIORDEP) 88 | [outEvalStr outEvalVar] = GetIncomingVariables(... 89 | ADIGATOR.IFDATA(IfCount).PRIORDEP,ADIGATOR.IFDATA(IfCount).BROS(BroCount).PRIORDEP); 90 | else 91 | outEvalVar = []; 92 | outEvalStr = []; 93 | end 94 | end 95 | 96 | end 97 | 98 | function [outEvalStr outEvalVar] = GetIncomingVariables(PriorDepStruc,PriorDepLocs) 99 | global ADIGATOR 100 | 101 | NameLocs = ADIGATOR.VARINFO.NAMELOCS(:,1); 102 | Names = ADIGATOR.VARINFO.NAMES; 103 | 104 | nOut = length(PriorDepLocs); 105 | outEvalStr = cell(nOut,1); 106 | outEvalVar = cell(nOut,1); 107 | for iOut = 1:nOut 108 | VarLoc = PriorDepLocs(iOut); 109 | NameLoc = NameLocs(VarLoc); 110 | VarName = Names{NameLoc}; 111 | outEvalStr{iOut} = sprintf([VarName,' = adigatorIfEvalVar{%1.0f};'],iOut); 112 | outEvalVar{iOut} = PriorDepStruc.Vars{PriorDepStruc.Locs == VarLoc}; 113 | end 114 | end 115 | -------------------------------------------------------------------------------- /lib/adigatorIfLooper.m: -------------------------------------------------------------------------------- 1 | function ifLoop = adigatorIfLooper(IfCount) 2 | % This transformation routine is called when we are unrolling loops and 3 | % encounter an IF statement. In some instances it may be required to 4 | % evaluate the conditional set twice. 5 | % 6 | % Inputs: 7 | % IfCount - integer identifying the conditional if/elseif/else set 8 | % 9 | % Outputs: 10 | % ifLoop - variable to be looped upon and passed to adigatorIfLooperi 11 | % 12 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 13 | % Distributed under the GNU General Public License version 3.0 14 | global ADIGATOR 15 | if ADIGATOR.OPTIONS.PREALLOCATE 16 | ifLoop = 1; 17 | elseif ~ADIGATOR.RUNFLAG 18 | ifLoop = 0; 19 | ADIGATOR.IFDATA(IfCount).OUTERFLAG = 1; 20 | elseif ~ADIGATOR.IFINFO.INNERLOC 21 | % Outermost IF statement 22 | ADIGATOR.IFDATA(IfCount).RESETLOC = 0; 23 | ADIGATOR.IFINFO.INNERLOC = IfCount; 24 | ifLoop = [1 2]; 25 | elseif ADIGATOR.IFINFO.INNERLOC 26 | ADIGATOR.IFDATA(IfCount).RESETLOC = ADIGATOR.IFINFO.INNERLOC; 27 | ADIGATOR.IFINFO.INNERLOC = IfCount; 28 | if ADIGATOR.RUNFLAG == 1 29 | % Overmapping evaluation of outer conditional 30 | ifLoop = 1; 31 | else 32 | % Printing an outer conditional statement, but there exists a loop in 33 | % between the outer conditional and this conditional. 34 | ifLoop = [1 2]; 35 | end 36 | end -------------------------------------------------------------------------------- /lib/adigatorIfLooperi.m: -------------------------------------------------------------------------------- 1 | function adigatorIfLooperi(ifLoopi,IfCount) 2 | % This is a transformation routine that is used when we are unrolling loops 3 | % but encounter an IF statement. It is placed within the "if loop" set by 4 | % adigatorIfLooper. 5 | % 6 | % Inputs: 7 | % ifLoopi - variable set by adigatorIfLooper which determines what type 8 | % evaluation of the conditional statement must be performed. 9 | % IfCount - integer identifying the conditional if/elseif/else set 10 | % 11 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 12 | % Distributed under the GNU General Public License version 3.0 13 | global ADIGATOR 14 | if ADIGATOR.OPTIONS.PREALLOCATE 15 | return 16 | end 17 | ADIGATOR.RUNFLAG = ifLoopi; 18 | if ifLoopi 19 | ADIGATOR.VARINFO.COUNT = ADIGATOR.IFDATA(IfCount).BROS(1).START; 20 | ADIGATOR.PREOPCOUNT = ADIGATOR.VARINFO.COUNT; 21 | if ifLoopi == 1 22 | ADIGATOR.PRINT.FLAG = 0; 23 | else 24 | ADIGATOR.PRINT.FLAG = 1; 25 | end 26 | end -------------------------------------------------------------------------------- /lib/adigatorInput.m: -------------------------------------------------------------------------------- 1 | classdef adigatorInput 2 | % adigatorInput class - used only for specifying derivative and auxiliary 3 | % inputs to adigator(). Called by adigatorCreateDerivInput and 4 | % adigatorCreateAuxInput. 5 | % 6 | % Constructor syntax y = adigatorInput(func,deriv) 7 | % 8 | % See also: adigatorCreateDerivInput adigatorCreateAuxInput adigator 9 | 10 | properties 11 | % Function information - size and any fixed information 12 | func 13 | % Derivative information on size/name of variable of differentiation and non-zero locations 14 | deriv 15 | end 16 | 17 | methods 18 | function y = adigatorInput(func,deriv) 19 | % adigatorInput constructor function 20 | if ~isstruct(func) 21 | error('first func input to adigatorInput must be a structure with field .size'); 22 | end 23 | if ~isfield(func,'size') || length(func.size) ~= 2 24 | error('adigatorInput must have defined function size of length 2'); 25 | end 26 | if ~isfield(func,'value') 27 | func.value = []; 28 | end 29 | y.func = func; 30 | 31 | if isempty(deriv) 32 | y.deriv = []; 33 | elseif ~isstruct(deriv) 34 | error('deriv input must be structure'); 35 | end 36 | 37 | if ~isempty(deriv) 38 | if ~isfield(deriv,'vodname') || ~isfield(deriv,'vodsize') || ~isfield(deriv,'nzlocs') 39 | error('deriv structure must be empty or contain fields: vodname, vodsize, nzlocs'); 40 | end 41 | end 42 | 43 | ysize = func.size; 44 | for i = 1:length(deriv) 45 | xsize = deriv(i).vodsize; 46 | if length(xsize) ~= 2 47 | error('deriv.vodsize must be of length 2'); 48 | end 49 | m = prod(ysize); n = prod(xsize); 50 | nzlocs = deriv(i).nzlocs; 51 | if size(nzlocs,2) ~= 2 52 | error(['nzlocs must be given in row/column format as an Nx2 ',... 53 | 'integer matrix where first column corresponds to function ',... 54 | 'values and second column corresponds to the variable ',... 55 | 'of differentiation']); 56 | end 57 | if any(nzlocs(:,1) > m) || any(nzlocs(:,1) ~= abs(floor(nzlocs(:,1)))) 58 | error('nzlocs either outside of bounds or not positive integers'); 59 | elseif any(nzlocs(:,2) > n) || any(nzlocs(:,2) ~= abs(floor(nzlocs(:,2)))) 60 | error('nzlocs either outside of bounds or not positive integers'); 61 | end 62 | 63 | vodname = deriv(i).vodname; 64 | if ~ischar(vodname) 65 | error('vodname must be string with no spaces'); 66 | end 67 | end 68 | 69 | y.deriv = deriv; 70 | end 71 | 72 | end 73 | 74 | end -------------------------------------------------------------------------------- /lib/adigatorMakeNumeric.m: -------------------------------------------------------------------------------- 1 | function y = adigatorMakeNumeric(x) 2 | %function y = adigatorMakeNumeric(x) 3 | % This routine turns a numeric object into an overloaded object. 4 | % ----------------------- Input Information ----------------------------- % 5 | % x: numeric object 6 | % --------------------- Output Information ------------------------------ % 7 | % y: overloaded object 8 | % 9 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 10 | % Distributed under the GNU General Public License version 3.0 11 | global ADIGATOR 12 | NUMvod = ADIGATOR.NVAROFDIFF; 13 | VarID = ADIGATOR.VARINFO.COUNT; 14 | [funcname,~] = cadafuncname(); 15 | func = struct('name',funcname,'size',size(x),'zerolocs',[],'value',x); 16 | deriv = struct('name',cell(NUMvod,1),'nzlocs',cell(NUMvod,1)); 17 | y = cada(VarID,func,deriv); 18 | ADIGATOR.VARINFO.LASTOCC(VarID,1) = VarID; 19 | end -------------------------------------------------------------------------------- /lib/adigatorSeperateFunLines.m: -------------------------------------------------------------------------------- 1 | function [FunStr,NUMFunStr] = adigatorSeperateFunLines(FunStrFull) 2 | %function [FunStr,NUMFunStr] = adigatorSeperateFunLines(FunStrFull) 3 | % This function seperates function lines when multiple commands are given 4 | % on the same line 5 | % 6 | % Inputs: 7 | % FunStrFull - full line read from a file (possibly containing multiple 8 | % commands) 9 | % 10 | % Outputs: 11 | % FunStr - cell array of individual commands 12 | % NUMFunStr - number of individual commands 13 | % 14 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 15 | % Distributed under the GNU General Public License version 3.0 16 | 17 | if ~strcmp(FunStrFull(1),'%') 18 | % Find comments at end of line 19 | commentloc = findcomments(FunStrFull); 20 | if commentloc 21 | CommentStr = strtrim(FunStrFull(commentloc:end)); 22 | FunStrFull = strtrim(FunStrFull(1:commentloc-1)); 23 | end 24 | % ---------------- Check for Multiple Commands on Single Line --------- % 25 | FunStrLocs = strfind(FunStrFull,';'); 26 | doubleSemiCheck = diff(FunStrLocs) == 1; 27 | if any(doubleSemiCheck) 28 | doubleSemi = 1; 29 | FunStrLocs = FunStrLocs([~doubleSemiCheck true]); 30 | else 31 | doubleSemi = 0; 32 | end 33 | % Check and make sure ';' isnt in vertcat 34 | if ~isempty(FunStrLocs) 35 | SquareLocs1 = strfind(FunStrFull,'['); 36 | if ~isempty(SquareLocs1) 37 | NUMSQL = length(SquareLocs1); 38 | for Scount = 1:NUMSQL 39 | % Need to find where bracket with Scount closes 40 | CloseLoc = adigatorFindMatchingParen(FunStrFull,SquareLocs1(Scount)); 41 | for S2count = 1:length(FunStrLocs) 42 | if FunStrLocs(S2count) > SquareLocs1(Scount) &&... 43 | FunStrLocs(S2count) < CloseLoc 44 | FunStrLocs(S2count) = 0; 45 | end 46 | end 47 | end 48 | FunStrLocs = nonzeros(FunStrLocs); 49 | end 50 | SquareLocs1 = strfind(FunStrFull,'{'); 51 | if ~isempty(SquareLocs1) 52 | NUMSQL = length(SquareLocs1); 53 | for Scount = 1:NUMSQL 54 | % Need to find where bracket with Scount closes 55 | CloseLoc = adigatorFindMatchingParen(FunStrFull,SquareLocs1(Scount)); 56 | for S2count = 1:length(FunStrLocs) 57 | if FunStrLocs(S2count) > SquareLocs1(Scount) &&... 58 | FunStrLocs(S2count) < CloseLoc 59 | FunStrLocs(S2count) = 0; 60 | end 61 | end 62 | end 63 | FunStrLocs = nonzeros(FunStrLocs); 64 | end 65 | end 66 | % ----------------seperate multiple commands----------------------- 67 | if isempty(FunStrLocs) ||... 68 | (length(FunStrLocs) == 1 && FunStrLocs == length(FunStrFull)) 69 | % only one line 70 | FunStr = cell(1,1); 71 | FunStr{1} = FunStrFull; 72 | NUMFunStr = 1; 73 | elseif FunStrLocs(end) ~= length(FunStrFull) 74 | % 2 or more lines 75 | % last line either comment or unsuppressed 76 | NUMFunStr = length(FunStrLocs) + 1; 77 | FunStr = cell(NUMFunStr,1); 78 | FunStr{1} = FunStrFull(1:FunStrLocs(1)); 79 | for FScount = 1:NUMFunStr-2 80 | FunStr{FScount+1} = strtrim(FunStrFull(FunStrLocs(FScount)+1:FunStrLocs(FScount+1))); 81 | end 82 | FunStr{NUMFunStr} = strtrim(FunStrFull(FunStrLocs(end)+1:end)); 83 | else 84 | % 2 or more lines, last line suppressed 85 | NUMFunStr = length(FunStrLocs); 86 | FunStr = cell(NUMFunStr,1); 87 | FunStr{1} = FunStrFull(1:FunStrLocs(1)); 88 | for FScount = 2:NUMFunStr 89 | FunStr{FScount} = strtrim(FunStrFull(FunStrLocs(FScount-1)+1:FunStrLocs(FScount))); 90 | end 91 | end 92 | % Check for double ; at end of line 93 | if doubleSemi 94 | FunStr = regexprep(FunStr,';;$',';'); 95 | end 96 | if commentloc 97 | FunStr{end+1,1} = CommentStr; 98 | end 99 | else 100 | NUMFunStr = 1; 101 | FunStr = cell(1); 102 | FunStr{1} = FunStrFull; 103 | end 104 | end 105 | function comment = findcomments(str) 106 | % Look for a comment at end of string 107 | comment = 0; 108 | commentlocs = strfind(str,'%'); 109 | if ~isempty(commentlocs) 110 | % Make sure no %'s are used to build a string 111 | leftstrlocs = regexp(str,'[=''\(,]\s*'''); 112 | rightstrlocs = regexp(str,'''\s*[''\),]'); 113 | % if these lengths arent equal its possible that they occur after the 114 | % comment 115 | if length(leftstrlocs) < length(rightstrlocs) 116 | rightstrlocs = rightstrlocs(1:length(leftstrlocs)); 117 | elseif length(leftstrlocs) > length(rightstrlocs) 118 | leftstrlocs = leftsrlocs(1:length(rightstrlocs)); 119 | end 120 | if ~isempty(leftstrlocs) 121 | for C = commentlocs 122 | if ~any(C > leftstrlocs & C < rightstrlocs) 123 | comment = C; 124 | end 125 | end 126 | else 127 | comment = commentlocs(1); 128 | end 129 | end 130 | end -------------------------------------------------------------------------------- /lib/adigatorSetCellEvalFlag.m: -------------------------------------------------------------------------------- 1 | function adigatorSetCellEvalFlag(flagval) 2 | % function adigatorSetCellEvalFlag(flagval) 3 | % This function was created with V2 when structures started getting handled 4 | % differently - it is used to tell @cadastruct/subsasgn when a 5 | % cellfun(@eval,cellstr) is being used to modify the overloaded workspace. 6 | % It simply sets a global flag equal to the input. 7 | 8 | global ADIGATOR 9 | ADIGATOR.CELLEVALFLAG = flagval; 10 | end -------------------------------------------------------------------------------- /lib/adigatorStructAnalyzer.m: -------------------------------------------------------------------------------- 1 | function x = adigatorStructAnalyzer(x,xStr,~) 2 | % Non-overloaded adigatorStructAnalyzer - only called for structures or strings 3 | % 4 | % Called to recursively parse structure/cell objects and call 5 | % adigatorVarAnalyzer on each of the CADA objects. 6 | % 7 | % Inputs: 8 | % x - variable which was just created 9 | % xStr - string name of variable in the program. 10 | % 11 | % Outputs: 12 | % x - same variable, if structure, contains ordered fields and each field 13 | % is sent to adigatorStructAnalyzer 14 | 15 | if isstruct(x) && ~isempty(x) 16 | x = orderfields(x); 17 | fnames = fieldnames(x); 18 | for I = 1:length(fnames) 19 | F = fnames{I}; 20 | x.(F) = adigatorStructAnalyzer(x.(F),[xStr,'.',F],0); 21 | end 22 | end 23 | 24 | end -------------------------------------------------------------------------------- /lib/cadaUtils/Contents.m: -------------------------------------------------------------------------------- 1 | % CADA Common Utilities 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % cadaCheckForDerivs.m - dummy routine to be called on non-overloaded 9 | % variables, always returns false 10 | % cadadername.m - get derivative variable name for printing 11 | % cadafuncname.m - get function variable name for printing 12 | % cadaindprint.m - store indices/generate variable name 13 | % cadamatprint.m - store data/generate variable name -------------------------------------------------------------------------------- /lib/cadaUtils/cadaCheckForDerivs.m: -------------------------------------------------------------------------------- 1 | function flag = cadaCheckForDerivs(x) 2 | % Dummy routine for non-overloaded variables, just returns false 3 | % 4 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | 7 | flag = false; 8 | 9 | end -------------------------------------------------------------------------------- /lib/cadaUtils/cadadername.m: -------------------------------------------------------------------------------- 1 | function derivstr = cadadername(funcname,Vcount,varargin) 2 | % This gets the derivative name of some overloaded object. 3 | % 4 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 5 | % Distributed under the GNU General Public License version 3.0 6 | global ADIGATOR 7 | if nargin == 2 8 | VarID = ADIGATOR.VARINFO.COUNT; 9 | elseif nargin == 3 10 | VarID = varargin{1}; 11 | end 12 | 13 | if ADIGATOR.PRINT.FLAG == 1 14 | nameindex = ADIGATOR.VARINFO.NAMELOCS(VarID); 15 | if nameindex && (ADIGATOR.VARINFO.NAMELOCS(VarID,2)>=0) 16 | if ADIGATOR.DERNUMBER == 1 17 | derivstr = [ADIGATOR.VARINFO.NAMES{nameindex},'.d',... 18 | ADIGATOR.VAROFDIFF(Vcount).name]; 19 | elseif length(funcname) > 2 && strcmp(funcname(end-1:end),'.f') 20 | derivstr = [funcname(1:end-2),'.d',ADIGATOR.VAROFDIFF(Vcount).name]; 21 | else 22 | derivstr = [funcname,'d',ADIGATOR.VAROFDIFF(Vcount).name]; 23 | end 24 | elseif length(funcname) > 2 && strcmp(funcname(end-1:end),'.f') 25 | derivstr = [funcname(1:end-2),'.d',ADIGATOR.VAROFDIFF(Vcount).name]; 26 | else 27 | derivstr = [funcname,'d',ADIGATOR.VAROFDIFF(Vcount).name]; 28 | end 29 | else 30 | derivstr = [funcname,'d',ADIGATOR.VAROFDIFF(Vcount).name]; 31 | end 32 | -------------------------------------------------------------------------------- /lib/cadaUtils/cadafuncname.m: -------------------------------------------------------------------------------- 1 | function [funcstr,derivflag] = cadafuncname(varargin) 2 | % Get function string of an object and a flag stating whether or not we 3 | % need to calculate derivatives. 4 | % 5 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 6 | % Distributed under the GNU General Public License version 3.0 7 | global ADIGATOR 8 | 9 | if nargin == 0 10 | VarID = ADIGATOR.VARINFO.COUNT; 11 | elseif nargin == 1 12 | VarID = varargin{1}; 13 | end 14 | derivflag = 0; 15 | if ADIGATOR.PRINT.FLAG 16 | 17 | nameindex = ADIGATOR.VARINFO.NAMELOCS(VarID,1); 18 | 19 | if nameindex == 0 20 | % intermediate variable 21 | namenum = ADIGATOR.VARINFO.NAMELOCS(VarID,2); 22 | funcstr = sprintf('cada%1.0df%1.0d',ADIGATOR.DERNUMBER,namenum); 23 | if ~isinf(ADIGATOR.VARINFO.NAMELOCS(VarID,3)) 24 | derivflag = 1; 25 | end 26 | else 27 | % important variable 28 | if ADIGATOR.DERNUMBER == 1 29 | if isinf(ADIGATOR.VARINFO.NAMELOCS(VarID,3)) 30 | funcstr = ADIGATOR.VARINFO.NAMES{nameindex}; 31 | derivflag = 0; 32 | elseif ADIGATOR.VARINFO.NAMELOCS(VarID,2) < 0 33 | funcstr = ADIGATOR.VARINFO.NAMES{nameindex}; 34 | CheckStrings = ADIGATOR.DERIVCHECKS(-ADIGATOR.VARINFO.NAMELOCS(VarID,2)).STRINGS; 35 | if isempty(CheckStrings) || any(~(cellfun('isempty',regexp(funcstr,CheckStrings,'start')))) 36 | derivflag = 1; 37 | end 38 | else 39 | funcstr = [ADIGATOR.VARINFO.NAMES{nameindex},'.f']; 40 | derivflag = 1; 41 | end 42 | else 43 | funcstr = [ADIGATOR.VARINFO.NAMES{nameindex}]; 44 | if ADIGATOR.DERIVCHECKS(ADIGATOR.FILE.FUNID).NUM 45 | % There are only certain variables that we need to print out 46 | % derivatives for. 47 | CheckStrings = ADIGATOR.DERIVCHECKS(ADIGATOR.FILE.FUNID).STRINGS; 48 | % Check for variables ending in CheckStrings 49 | if isempty(CheckStrings) || any(~(cellfun('isempty',regexp(funcstr,CheckStrings,'start')))) 50 | derivflag = 1; 51 | end 52 | else 53 | derivflag = 1; 54 | end 55 | 56 | end 57 | end 58 | else 59 | funcstr = sprintf('f%1.0d',VarID); 60 | derivflag = 0; 61 | end 62 | 63 | end -------------------------------------------------------------------------------- /lib/cadaUtils/cadaindprint.m: -------------------------------------------------------------------------------- 1 | function varargout = cadaindprint(x,varargin) 2 | % function cadaindprint(x,varargin) 3 | % Overloaded index printing scheme called from overloaded CADA functions. 4 | % x is the index which is to be printed, this function stores the index, 5 | % then either gives back the reference which will be used in the evaluation 6 | % of the created file to get to this index, or assigns the given input name 7 | % to the index reference. 8 | % 9 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 10 | % Distributed under the GNU General Public License version 3.0 11 | global ADIGATOR ADIGATORDATA 12 | 13 | if numel(x) == 1 && nargin == 1 14 | varargout{1} = sprintf('%1.0f',x); 15 | return 16 | end 17 | ADIGATORDATA.INDEXCOUNT = ADIGATORDATA.INDEXCOUNT+1; 18 | INDEXCOUNT = ADIGATORDATA.INDEXCOUNT; 19 | Ind = sprintf('Index%1.0d',INDEXCOUNT); 20 | INDEXNAME = sprintf('Gator%1.0dData.Index%1.0d',ADIGATOR.DERNUMBER,INDEXCOUNT); 21 | if x == ones(size(x)) 22 | x = ones(numel(x),1); 23 | end 24 | ADIGATORDATA.DATA.(Ind) = x; 25 | if nargin == 2 26 | fprintf(ADIGATOR.PRINT.FID,[ADIGATOR.PRINT.INDENT,varargin{1},... 27 | ' = ',INDEXNAME,';\n']); 28 | else 29 | varargout{1} = INDEXNAME; 30 | end -------------------------------------------------------------------------------- /lib/cadaUtils/cadamatprint.m: -------------------------------------------------------------------------------- 1 | function varargout = cadamatprint(x,varargin) 2 | % function cadamatprint(x,varargin) 3 | % Overloaded matrix data printing scheme 4 | % 5 | % Copyright 2011-214 Matthew J. Weinstein and Anil V. Rao 6 | % Distributed under the GNU General Public License version 3.0 7 | global ADIGATOR ADIGATORDATA 8 | 9 | if isnumeric(x) && numel(x) == 1 && nargin == 1 10 | nStr = num2str(x,16); 11 | if strcmp(nStr(1),'-') 12 | nStr = ['(',nStr,')']; 13 | end 14 | varargout{1} = nStr; 15 | return 16 | end 17 | ADIGATORDATA.DATACOUNT = ADIGATORDATA.DATACOUNT+1; 18 | DATACOUNT = ADIGATORDATA.DATACOUNT; 19 | Ind = sprintf('Data%1.0d',DATACOUNT); 20 | DATANAME = sprintf('Gator%1.0dData.Data%1.0d',ADIGATOR.DERNUMBER,DATACOUNT); 21 | 22 | ADIGATORDATA.DATA.(Ind) = x; 23 | if nargin == 2 24 | fprintf(ADIGATOR.PRINT.FID,[ADIGATOR.PRINT.INDENT,varargin{1},... 25 | ' = ',DATANAME,';\n']); 26 | else 27 | varargout{1} = DATANAME; 28 | end -------------------------------------------------------------------------------- /startupadigator.m: -------------------------------------------------------------------------------- 1 | % startupadigator: will add adigator directories to the Matlab path. 2 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 3 | % Distributed under the GNU General Public License version 3.0 4 | currpath = pwd; 5 | addpath(currpath); 6 | addpath([currpath,filesep,'lib']); 7 | addpath([currpath,filesep,'lib',filesep,'cadaUtils']); 8 | addpath([currpath,filesep,'util']); 9 | 10 | fprintf(' ADiGator Successfully Installed\n\n') 11 | 12 | copyingfile = [currpath,filesep,'COPYING.txt']; 13 | if strcmp(filesep,'\');copyingfile = regexprep(copyingfile,'\\','\\\\'); end 14 | COPYINGlink = ['COPYING.txt']; 15 | COPYINGurl = 'http://www.gnu.org/licenses/'; 16 | 17 | fprintf([... 18 | ' ADiGator is free software: you can redistribute it and/or modify\n',... 19 | ' it under the terms of the GNU General Public License as published by\n',... 20 | ' the Free Software Foundation, either version 3 of the License, or\n',... 21 | ' (at your option) any later version.\n',... 22 | ' \n',... 23 | ' ADiGator is distributed in the hope that it will be useful,\n',... 24 | ' but WITHOUT ANY WARRANTY; without even the implied warranty of\n',... 25 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n',... 26 | ' GNU General Public License for more details.\n',... 27 | ' \n',... 28 | ' You should have received a copy of the GNU General Public License\n',... 29 | ' along with ADiGator at ',COPYINGlink,'.\n',... 30 | ' If not, see ',COPYINGurl,'.\n\n']); 31 | 32 | adigatorurl = 'http://sourceforge.net/projects/adigator/'; 33 | 34 | fprintf([... 35 | ' For updated versions of the code please visit the sourceforge page\n',... 36 | ' at ',adigatorurl,'.\n Please report any bugs to the sourceforge forums.\n']); -------------------------------------------------------------------------------- /unit_tests/test_unarymath_rules.m: -------------------------------------------------------------------------------- 1 | function violations = test_unarymath_rules() 2 | 3 | mkdir('tmp'); 4 | addpath('tmp'); 5 | fid = fopen('cadaunarymath.m','r'); 6 | frewind(fid); 7 | 8 | l = fgetl(fid); 9 | while ~isnumeric(l) 10 | if strcmp(strtrim(l),'function dydx = getdydx(x,callerstr)') 11 | break; 12 | end 13 | l = fgetl(fid); 14 | end 15 | 16 | fnames = cell(1,0); 17 | while ~isnumeric(l) 18 | l = strtrim(l); 19 | if strncmp(l,'case',4) 20 | tmp = strtrim(l(5:end)); 21 | fnames{end+1} = tmp(2:end-1); %#ok 22 | end 23 | l = fgetl(fid); 24 | end 25 | bad = zeros(size(fnames)); 26 | for ii = 1:length(fnames) 27 | bad(ii) = test_this(fnames{ii}); 28 | end 29 | 30 | for ii = 1:length(fnames) 31 | if bad(ii) 32 | fprintf('%s - %d violations\n',fnames{ii},bad(ii)); 33 | end 34 | end 35 | violations = sum(bad); 36 | 37 | end 38 | 39 | function bad = test_this(fun) 40 | fname = ['test_',fun]; 41 | ffname = ['tmp/',fname]; 42 | fid2 = fopen([ffname,'.m'],'w+'); 43 | fprintf(fid2,'function y = %s(x)\n',fname); 44 | fprintf(fid2,'y = %s(x);\n',fun); 45 | fprintf(fid2,'end\n'); 46 | fclose(fid2); 47 | 48 | dname = [fname,'_dx']; 49 | rehash; 50 | ax = adigatorCreateDerivInput([1 1],'x'); 51 | 52 | adigator(fname,{ax},dname,adigatorOptions('overwrite',1)); 53 | movefile([dname,'.*'],'tmp/'); 54 | bad = 0; 55 | 56 | xtest = [linspace(-0.9,0.9,10) linspace(-2*pi,2*pi,10) linspace(-360,360,10)]; 57 | for ii = 1:length(xtest) 58 | xx.f = xtest(ii); 59 | xx.dx = 1; 60 | yy = feval(dname,xx); 61 | 62 | ee = 1e-6; 63 | f1 = feval(fname,xx.f); 64 | f2 = feval(fname,xx.f+ee); 65 | df = (f2-f1)/ee; 66 | if abs(yy.dx-df)/(1+abs(df)) > 1e-4 67 | bad = bad + 1; 68 | if isnan(f1) || isinf(f1) || abs(df) > 1e8 69 | % Neglect these corner cases - finite difference as wrong as AD 70 | bad = bad-1; 71 | else 72 | %keyboard 73 | end 74 | end 75 | end 76 | 77 | end -------------------------------------------------------------------------------- /util/Contents.m: -------------------------------------------------------------------------------- 1 | % ADiGator user utilities 2 | % 3 | % Copyright 2011-2015 Matthew J. Weinstein and Anil V. Rao 4 | % Distributed under the GNU General Public License version 3.0 5 | % 6 | % ----------------------------------------------------------------------- % 7 | % FILES: 8 | % adigator.m - main source transformation AD driver 9 | % adigatorColor.m - CPR coloring scheme 10 | % adigatorCreateAuxInput.m - creates ADiGator input vars for auxiliary 11 | % inputs 12 | % adigatorCreateDerivInput.m - creates ADiGator input vars for derivative 13 | % inputs 14 | % adigatorGenFiles4Fmincon.m - black box derivative file generation for 15 | % use with fmincon (constrained minimization) 16 | % adigatorGenFiles4Fminunc.m - black box derivative file generation for 17 | % use with fminunc 18 | % (unconstrained minimization) 19 | % adigatorGenFiles4Fsolve.m - black box derivative file generation for 20 | % use with fsolve (system of equations) 21 | % adigatorGenFiles4gpops2.m - black box derivative file generation for 22 | % use with GPOPS2 optimal control software 23 | % adigatorGenFiles4Ipopt.m - black box derivative file generation for 24 | % use with IPOPT (constrained minimization) 25 | % adigatorGenHesFile.m - generates first and second derivative files 26 | % with wrapper files 27 | % adigatorGenJacFile.m - generates first derivative files with 28 | % wrapper file 29 | % adigatorOptions.m - creates adigator Options structure 30 | % adigatorProjectVectLocs.m - projects locations of non-vectorized 31 | % Jacobian into those of vectorized Jacobian 32 | % adigatorUncompressJac.m - uncompresses Jacobians for use with CPR 33 | % coloring 34 | % ----------------------------------------------------------------------- % 35 | % DIRECTORIES: 36 | % private - adigatortempfunc#.m files get stored here -------------------------------------------------------------------------------- /util/adigatorColor.m: -------------------------------------------------------------------------------- 1 | function [c,S] = adigatorColor(J) 2 | % function [c,S] = adigatorColor(J) 3 | % 4 | % CPR Coloring algorithm - very simplistic. 5 | % You can use coloring if you know your Jacobian sparsity pattern prior to 6 | % calling ADiGator. 7 | % 8 | % J: Jacobian sparsity pattern 9 | % 10 | % c: colors 11 | % S: Seed matrix 12 | % 13 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 14 | % Distributed under the GNU General Public License version 3.0 15 | % 16 | % see also adigatorUncompressJac adigatorCreateDerivInput 17 | 18 | n = size(J,2); 19 | c = zeros(1,n); 20 | 21 | JJ = J.'*J; 22 | % JJ symmetric matrix, if JJ(i,j) ~= 0, then columns i and j of J share a 23 | % non-zero row value. 24 | x = 1:n; 25 | 26 | nc = 0; 27 | for i = 1:n 28 | % Loop on columns 2 through n 29 | ci = 0; 30 | Ji = J(:,i); 31 | if any(Ji) 32 | for k = 1:nc 33 | % Determine if column i can use any of the previously used colors 34 | xci = x(c==k); 35 | % xci is collection of columns using color k 36 | if ~any(JJ(xci,i)) 37 | % if any element of JJ(xci,i) non-zero, then column i shares a 38 | % non-zero with one of the columns using color k 39 | ci = k; 40 | break 41 | end 42 | end 43 | if ci == 0 44 | % could not find a suitable color 45 | ci = nc+1; 46 | nc = ci; 47 | end 48 | end 49 | c(i) = ci; 50 | end 51 | 52 | if nargout == 2 53 | % Want to build seed matrix as well 54 | x(c==0) = []; 55 | c(c==0) = []; 56 | S = sparse(x,c,1,n,nc); 57 | end -------------------------------------------------------------------------------- /util/adigatorProjectVectLocs.m: -------------------------------------------------------------------------------- 1 | function varargout = adigatorProjectVectLocs(N,varargin) 2 | % Syntax for adigatorProjectVectLocs is 3 | % [I1,I2,...,In] = adigatorProjectVectLocs(N,i1,i2,...,in) 4 | % Where N is vectorized dimension, 5 | % i1,...,in are the locations of the small problem, and 6 | % I1,...,In are the locations of the large problem 7 | % 8 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 9 | % Distributed under the GNU General Public License version 3.0 10 | if nargout ~= nargin-1 || nargin == 1 11 | error('invalid inputs') 12 | end 13 | varargout = cell(1,nargout); 14 | for ii = 1:nargout 15 | n = length(varargin{ii}); 16 | varargout{ii} = repmat((1:N).',1,n) + N.*ones(N,n)*diag(varargin{ii}-1); 17 | end 18 | -------------------------------------------------------------------------------- /util/adigatorUncompressJac.m: -------------------------------------------------------------------------------- 1 | function J = adigatorUncompressJac(Jpat,c,JSnz) 2 | % function J = adigatorUncompressJac(Jpat,c,JSnz) 3 | % 4 | % Uncompress Jacobian 5 | % 6 | % Jpat: Jacobian Sparsity Pattern 7 | % c: colors 8 | % JSnz: Non-zeros of the compressed Jacobian 9 | % 10 | % J: Jacobian 11 | % 12 | % Copyright 2011-2014 Matthew J. Weinstein and Anil V. Rao 13 | % Distributed under the GNU General Public License version 3.0 14 | % 15 | % see also adigatorColor adigatorCreateDerivInput 16 | 17 | [m,n] = size(Jpat); 18 | [i,j] = find(Jpat); 19 | order = nonzeros(sparse(i,c(j),1:length(i),m,n)); 20 | J = sparse(i,j,JSnz(order),m,n); --------------------------------------------------------------------------------