├── .gitignore ├── .gitmodules ├── CONTACT-INFO.txt ├── LICENSE.txt ├── README.md ├── clean.m ├── doc ├── computationgraphs.pdf ├── computationgraphs.tex ├── csparse.pdf ├── csparse.tex ├── ipm.pdf ├── ipm.tex ├── sphinx │ ├── Makefile │ ├── _build │ │ └── html │ │ │ ├── basics.html │ │ │ ├── computation.html │ │ │ ├── defs.html │ │ │ ├── genindex.html │ │ │ ├── index.html │ │ │ ├── install.html │ │ │ ├── intro.html │ │ │ ├── operations.html │ │ │ ├── optimization.html │ │ │ ├── search.html │ │ │ └── searchindex.js │ ├── basics.rst │ ├── computation.rst │ ├── conf.py │ ├── defs.rst │ ├── index.rst │ ├── install.rst │ ├── intro.rst │ ├── operations.rst │ ├── optimization.rst │ └── requirements.txt ├── tenscalc.pdf ├── tenscalc.tex ├── timeseries.pdf └── timeseries.tex ├── examples ├── TCgames.m ├── basicTests.m ├── csparse │ ├── tutorialFIM.m │ ├── tutorialFIMextended.m │ ├── tutorialLQ.m │ ├── tutorialLQextended.m │ ├── tutorialNN.m │ ├── tutorialNN1.m │ └── tutorialNNextended.m ├── dist2convex.m ├── flops.m ├── l1l2estimationCS.m ├── minmaxTest.m ├── mls.m ├── mpcmhe │ ├── mpc_dcmotor.m │ ├── mpc_dcmotor_simulink.m │ ├── mpc_dcmotor_simulink_S.slx │ ├── mpc_quadcopter.m │ ├── mpc_unicycle.m │ ├── mpcmhe_dcmotor.m │ └── mpcmhe_unicycle.m ├── robustRegressL1.m ├── sls.m ├── slseq.m └── testing │ ├── numericalGradient.m │ ├── testComponentwise.m │ ├── testDeclares.m │ ├── testFactorizations.m │ ├── testInstructionsTable.m │ ├── testLDL.m │ ├── testLDL_raw.c │ ├── testLU.m │ ├── testLU_raw.c │ ├── testLUatomic.m │ ├── testLUatomic_raw.c │ ├── testLinearAlgebra.m │ ├── testLogDet.m │ ├── testNorms.m │ ├── testScaling.m │ ├── testSensitivity.m │ ├── testSet.m │ ├── testSet_raw.c │ ├── testSubsref.m │ ├── testSubsref_raw.c │ ├── testSum.m │ ├── testSum_raw.c │ ├── testTprod.m │ ├── testTprod2.m │ ├── testTprod2_raw.c │ ├── testTprod_raw.c │ ├── testUMFPACK.c │ └── testVec2Tensor.m ├── install_tenscalc.m ├── lib ├── @TCsysid │ ├── TCsysid.m │ ├── callSolver.m │ └── createSolver.m ├── @Tcalculus │ ├── Tcalculus.m │ ├── checkTprodSizes.m │ ├── gradient.m │ ├── precompute.m │ ├── spy.m │ ├── str.m │ ├── tprod.m │ ├── tprod_argin2operands.m │ ├── tprod_simplify.m │ └── tprod_tprod2matlab.m ├── @csparse │ ├── COPYRIGHT.c │ ├── COPYRIGHT.m │ ├── computeMatlabInstructions.m │ ├── computeScalarInstructions.m │ ├── csparse.m │ ├── dependencyGroups.m │ ├── private │ │ ├── loadCSparse.m │ │ ├── mat2str_compact.m │ │ └── toporder.m │ ├── saveScalarized.m │ ├── saveVectorized.m │ ├── sparsity_cat.m │ ├── sparsity_clp.m │ ├── sparsity_componentwise.m │ ├── sparsity_compose.m │ ├── sparsity_compose_full.m │ ├── sparsity_det_ldl.m │ ├── sparsity_det_lu.m │ ├── sparsity_diag.m │ ├── sparsity_ldl.m │ ├── sparsity_ldl_d.m │ ├── sparsity_ldl_l.m │ ├── sparsity_logdet_ldl.m │ ├── sparsity_logdet_lu.m │ ├── sparsity_lu.m │ ├── sparsity_lu_d.m │ ├── sparsity_lu_l.m │ ├── sparsity_lu_u.m │ ├── sparsity_max.m │ ├── sparsity_max2.m │ ├── sparsity_min.m │ ├── sparsity_min2.m │ ├── sparsity_mldivide_d.m │ ├── sparsity_mldivide_l1.m │ ├── sparsity_mldivide_u.m │ ├── sparsity_mldivide_u1.m │ ├── sparsity_norm1.m │ ├── sparsity_norm2.m │ ├── sparsity_norminf.m │ ├── sparsity_plus.m │ ├── sparsity_rdivide.m │ ├── sparsity_subsref.m │ ├── sparsity_tprod.m │ ├── sparsity_transpose.m │ ├── str.m │ ├── writeCasmLBinstructions.m │ ├── writeCasmSBinstructions.m │ ├── writeCfunctionpergroup.m │ ├── writeCprofiling.c │ ├── writeMatlab.m │ └── writeMatlabInstructions.m ├── CGregistration.json ├── CGregistration.m ├── Ctprod.c ├── Ctprod.mexmaci64 ├── TClasso.m ├── TcheckVariable.m ├── Tconstant.m ├── Teye.m ├── TltiConstraints.m ├── Tmpc.m ├── Tmpcmhe.m ├── Tones.m ├── Tvariable.m ├── TvariablesMPC.m ├── Tvars2optimizeCS.m ├── Tzeros.m ├── analyzeHess.m ├── bitrate.m ├── class2compute.m ├── class2equilibriumLatentCS.m ├── class2minmaxCS.m ├── class2optimizeCS.m ├── clp.m ├── cmex2compute.m ├── cmex2equilibriumLatentCS.m ├── cmex2minmaxCS.m ├── cmex2optimizeCS.m ├── csparse │ ├── compileInstructionsTable.m │ ├── instructionsTableFunctions.h │ ├── instructionsTableHeight4MEX.c │ ├── instructionsTableTypes.h │ ├── instructionsTableUTHash.c │ └── uthash.h ├── cube.m ├── debugConvergenceAnalysis.m ├── fasttable.m ├── gradientVector.m ├── instructionTypes.m ├── ipmPD_CS.m ├── ipmPD_CSsimple.m ├── ipmPD_CSsolver.c ├── ipmPD_CSsolver.m ├── ipmPD_CStimesLambda.m ├── ipmPDeq_CSsolver.c ├── ipmPDeq_CSsolver.m ├── ipmPDeqlat_CS.m ├── ipmPDminmax_CS.m ├── ipmPDminmax_CSsolver.c ├── ipmPDminmax_CSsolver.m ├── isTcalculus.m ├── logdet.m ├── memory2subscript.m ├── myeye.m ├── myisequal.m ├── mytprod.m ├── mytprodSparse.m ├── nlss.m ├── norm2.m ├── packExpressions.m ├── packVariables.m ├── pdist2t.m ├── private │ ├── checkOutputExpressions.m │ ├── checkParameters.m │ ├── packVariables.m │ ├── parameters4all.m │ ├── parameters4compute.m │ ├── parameters4equilibrium.m │ ├── parameters4minmax.m │ ├── parameters4optimize.m │ ├── parseConstraints.m │ ├── storeExpressions.m │ └── variableIndices.m ├── relu.m ├── rm_tmps.m ├── serialize.m ├── sqr.m ├── srelu.m ├── subscript2memory.m ├── toCalculus.m ├── tprod.m ├── traceinv.m ├── tsCross.m ├── tsDerivative.m ├── tsDerivative2.m ├── tsDot.m ├── tsIntegral.m ├── tsIntegrate.m ├── tsODE.m ├── tsQdot.m ├── tsQdotStar.m ├── tsRotation.m ├── tsRotationT.m └── vec2tensor.m └── readthedocs.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # assume case sensitive, which is achieved with 2 | # git config core.ignorecase false 3 | 4 | ## examples to be fixed 5 | /myexamples 6 | 7 | ## other files to be fixed 8 | /test-asm/ 9 | /lib/tools/ 10 | /doc/instructionscheduling.* 11 | 12 | ## private files 13 | COPYING-GPLv3-statement.txt 14 | TODO.txt 15 | CONVERGENCE_DEBUG.txt 16 | 17 | ## temporary scripts for testing 18 | /doc/StudyInfeasibility.nb 19 | /lib/@csparse/testldl.m 20 | 21 | ## Automatically generated by installation 22 | initInstructionsTable.* 23 | instructionsTableHeight.* 24 | appendInstruction.* 25 | appendUniqueInstruction.* 26 | getInstruction.* 27 | findInstructionsByType.* 28 | getDependencies.* 29 | writeCinstructionsC.* 30 | writeAsmInstructionsC.* 31 | instructionsTable_load.* 32 | instructionsTable.* 33 | 34 | ## Automatically generated files 35 | /lib/tools/output 36 | tmp* 37 | @tmp* 38 | /lib/*.tex 39 | 40 | ## Automatically generated by simulink 41 | *.slxc 42 | slprj/ 43 | 44 | ## Automatically generated doc files 45 | doc/html/ 46 | doc/latex/ 47 | doc/xml/ 48 | doc/sphinx/_build/ 49 | 50 | ## "old" files 51 | *_old 52 | *_old.* 53 | old/ 54 | 55 | ## Related packages 56 | /TimDavis/ 57 | /dag_trans_red/ 58 | /doc/references/ 59 | /tprod/ 60 | /uthash/ 61 | 62 | ## Sync unison stuff 63 | .addsubfolders.unison 64 | .addthisfolder.unison 65 | 66 | ## Apple stuff 67 | .DS_Store 68 | 69 | ## Emacs backups 70 | auto/ 71 | *~ 72 | #*# 73 | .#*# 74 | 75 | 76 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "SuiteSparse"] 2 | path = SuiteSparse 3 | url = https://github.com/DrTimothyAldenDavis/SuiteSparse.git 4 | -------------------------------------------------------------------------------- /CONTACT-INFO.txt: -------------------------------------------------------------------------------- 1 | Contact information: 2 | Joao Hespanha 3 | hespanha@ucsb.edu 4 | 5 | This file is part of Tenscalc. 6 | 7 | Copyright 2012-2017 The Regents of the University of California 8 | (author: Dr. Joao Hespanha). All rights reserved. 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Academic Use Software License: © 2012-20 UCSB (“Institution”). Academic 2 | or nonprofit researchers are permitted to use this Software (as 3 | defined below) subject to Paragraphs 1-4: 4 | 5 | 1. Institution hereby grants to you free of charge, so long as you are 6 | an academic or nonprofit researcher, a nonexclusive license under 7 | Institution’s copyright ownership interest in this software and any 8 | derivative works made by you thereof (collectively, the “Software”) 9 | to use, copy, and make derivative works of the Software solely for 10 | internal educational or academic research purposes, in all cases 11 | subject to the terms of this Academic Software License. Except as 12 | granted herein, all rights are reserved by Institution. 13 | 14 | 2. Please note you are prohibited from further transferring the 15 | Software -- including any derivatives you make thereof -- to any 16 | person or entity without Institution’s prior written 17 | permission. Failure by you to adhere to the requirements in 18 | Paragraphs 1 and 2 will result in immediate termination of the 19 | license granted to you pursuant to this Academic Software License 20 | effective as of the date you first used the Software. 21 | 22 | 3. IN NO EVENT SHALL INSTITUTION BE LIABLE TO ANY ENTITY OR PERSON FOR 23 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, 24 | INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE, 25 | EVEN IF INSTITUTION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 26 | DAMAGE. INSTITUTION SPECIFICALLY DISCLAIMS ANY AND ALL WARRANTIES, 27 | EXPRESS AND IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 | PURPOSE. THE SOFTWARE IS PROVIDED “AS IS.” INSTITUTION HAS NO 30 | OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, 31 | OR MODIFICATIONS OF THIS SOFTWARE. 32 | 33 | 4. Neither the name of the copyright holder nor the names of its 34 | contributors may be used to endorse or promote products derived 35 | from this software without specific prior written permission. 36 | 37 | Commercial entities: please contact the UCSB Office of Technology & 38 | Industry Alliances at info@tia.ucsb.edu for licensing opportunities. 39 | 40 | -------------------------------------------------------------------------------- /clean.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all; 7 | 8 | !rm -r lib/tmp* lib/@tmp* lib/*/tmp* lib/*/@tmp* 9 | !rm -r examples/tmp* examples/@tmp* 10 | !rm -r examples/*/tmp* examples/*/@tmp* 11 | !rm - rexamples/*/*/tmp* examples/*/*/@tmp* 12 | -------------------------------------------------------------------------------- /doc/computationgraphs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hespanha/tenscalc/0632eb83d6be854406f4d3794bb4e92221fdbc13/doc/computationgraphs.pdf -------------------------------------------------------------------------------- /doc/csparse.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hespanha/tenscalc/0632eb83d6be854406f4d3794bb4e92221fdbc13/doc/csparse.pdf -------------------------------------------------------------------------------- /doc/ipm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hespanha/tenscalc/0632eb83d6be854406f4d3794bb4e92221fdbc13/doc/ipm.pdf -------------------------------------------------------------------------------- /doc/sphinx/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | 22 | apidoc: 23 | sphinx-apidoc -o ./apidoc ../../lib 24 | -------------------------------------------------------------------------------- /doc/sphinx/_build/html/defs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <no title> — Tenscalc Users' Guide 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 31 | 32 |
33 |
34 |
35 |
36 | 37 | 38 | 39 |
40 |
41 |
42 |
43 | 64 |
65 |
66 | 76 | 80 | 81 | -------------------------------------------------------------------------------- /doc/sphinx/_build/html/search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Search — Tenscalc Users' Guide 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 36 | 37 |
38 |
39 |
40 |
41 | 42 |

Search

43 | 44 | 52 | 53 | 54 |

55 | Searching for multiple words only shows matches that contain 56 | all words. 57 |

58 | 59 | 60 |
61 | 62 | 63 | 64 |
65 | 66 | 67 | 68 |
69 | 70 |
71 | 72 | 73 |
74 |
75 |
76 |
77 | 81 |
82 |
83 | 93 | 97 | 98 | -------------------------------------------------------------------------------- /doc/sphinx/computation.rst: -------------------------------------------------------------------------------- 1 | .. include:: defs.rst 2 | 3 | ================================== 4 | Code generation for computations 5 | ================================== 6 | 7 | .. warning:: This section of the documentation is still **incomplete**. 8 | 9 | 10 | **Computation trees** 11 | 12 | Sets of computations organized as dependency graphs, with multiple 13 | roots (input variables) and leaves (output expressions). 14 | 15 | Defining a computation 16 | ====================== 17 | 18 | .. class:: csparse 19 | 20 | .. method:: cs=csparse() 21 | 22 | Creates an empty computation tree 23 | 24 | :returns: empty |csparse| object 25 | 26 | .. method:: declareSet(cs,destination,functionName) 27 | 28 | Adds an input variable to the tree 29 | 30 | :param cs: |csparse| object 31 | :param destination: |tcalculus| tensor variable created using |tvariable| 32 | :param functionname: name of the function to be created 33 | :type functionname: string 34 | 35 | .. method:: declareGet(cs,sources,functionName) 36 | 37 | Adds output expressions to the tree 38 | 39 | :param cs: |csparse| object 40 | :param sources: cell array of |tcalculus| tensor-valued expressions 41 | :param functionname: name of the function to be created 42 | :type functionname: string 43 | 44 | .. method:: declareCopy(cs,destinations,sources,functionName) 45 | 46 | Sets the value of input variables, based on the value of output 47 | expressions 48 | 49 | :param cs: |csparse| object 50 | :param sources: cell array of |tcalculus| tensor-valued expressions 51 | :param destinations: cell array of |tcalculus| tensor variables created using |tvariable| 52 | :param functionname: name of the function to be created 53 | :type functionname: string 54 | 55 | 56 | Code generation 57 | =============== 58 | 59 | .. function:: cmex2compute(parameter1,value1,parameter2,values2, ...) 60 | .. function:: class2compute(parameter1,value1,parameter2,values2, ...) 61 | 62 | Generate code to set values of input variables, get values of 63 | output expressions, and copy output expressions to input variables. 64 | 65 | :param parameter1: parameter to set 66 | :type parameter1: string 67 | :param parameter2: parameter to set, ... 68 | :type parameter2: string 69 | :returns: name of the |matlab| class created 70 | :rtype: string 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /doc/sphinx/defs.rst: -------------------------------------------------------------------------------- 1 | .. Packages, etc. 2 | 3 | .. |tenscalc| replace:: TensCalc 4 | .. |funpartools| replace:: FunParTools 5 | .. |cmextools| replace:: CmexTools 6 | .. |github| replace:: GitHub 7 | 8 | 9 | .. Languages 10 | 11 | .. |matlab| replace:: MATLAB© 12 | .. |C| replace:: C 13 | 14 | .. Classes 15 | 16 | .. |tcalculus| replace:: :class:`Tcalculus` 17 | .. |csparse| replace:: :class:`csparse` 18 | 19 | .. Functions 20 | 21 | .. |tvariable-section| replace:: :ref:`Tvariable ` 22 | .. |tvariable| replace:: :func:`Tvariable` 23 | .. |tzeros| replace:: :func:`Tzeros` 24 | .. |tones| replace:: :func:`Tones` 25 | .. |teye| replace:: :func:`Teye` 26 | .. |tconstant| replace:: :func:`Tconstant` 27 | 28 | .. |size| replace:: :func:`size` 29 | 30 | .. |reshape| replace:: :func:`reshape` 31 | .. |repmat| replace:: :func:`repmat` 32 | .. |full| replace:: :func:`full` 33 | .. |cat| replace:: :func:`cat` 34 | .. |vertcat| replace:: :func:`vertcat` 35 | .. |horzcat| replace:: :func:`horzcat` 36 | .. |vec2tensor| replace:: :func:`vec2tensor` 37 | 38 | .. |sqrt| replace:: :func:`sqrt` 39 | .. |abs| replace:: :func:`abs` 40 | .. |max| replace:: :func:`max` 41 | .. |tprod| replace:: :func:`tprod` 42 | .. |norm| replace:: :func:`norm` 43 | .. |norm1| replace:: :func:`norm1` 44 | .. |norminf| replace:: :func:`norminf` 45 | .. |sum| replace:: :func:`sum` 46 | .. |diag| replace:: :func:`diag` 47 | .. |trace| replace:: :func:`trace` 48 | .. |det| replace:: :func:`det` 49 | .. |logdet| replace:: :func:`logdet` 50 | .. |inv| replace:: :func:`inv` 51 | .. |traceinv| replace:: :func:`traceinv` 52 | .. |lu| replace:: :func:`lu` 53 | .. |ldl| replace:: :func:`ldl` 54 | .. |lu_d| replace:: :func:`lu_d` 55 | .. |ldl_d| replace:: :func:`ldl_d` 56 | .. |*| replace:: :func:`*` 57 | .. |+| replace:: :func:`+` 58 | .. |mldivide| replace:: :func:`mldivide` 59 | 60 | .. |gradient| replace:: :func:`gradient` 61 | 62 | .. |cmex2optimizeCS| replace:: :func:`cmex2optimizeCS` 63 | .. |class2optimizeCS| replace:: :func:`class2optimizeCS` 64 | 65 | .. |cmex2equilibriumLatentCS| replace:: :func:`cmex2equilibriumLatentCS` 66 | .. |class2equilibriumLatentCS| replace:: :func:`class2equilibriumLatentCS` 67 | 68 | .. |cmex2compute| replace:: :func:`cmex2compute` 69 | .. |class2compute| replace:: :func:`class2compute` 70 | 71 | .. |Tvars2optimizeCS| replace:: :func:`Tvars2optimizeCS` 72 | -------------------------------------------------------------------------------- /doc/sphinx/index.rst: -------------------------------------------------------------------------------- 1 | .. include:: defs.rst 2 | 3 | ===================== 4 | Tenscalc User Guide 5 | ===================== 6 | 7 | .. toctree:: 8 | :maxdepth: 2 9 | :numbered: 10 | :caption: Contents: 11 | 12 | intro 13 | install 14 | basics 15 | operations 16 | optimization 17 | computation 18 | 19 | * :ref:`genindex` 20 | 21 | * :ref:`search` 22 | 23 | 24 | -------------------------------------------------------------------------------- /doc/sphinx/install.rst: -------------------------------------------------------------------------------- 1 | .. include:: defs.rst 2 | 3 | ============== 4 | Installation 5 | ============== 6 | 7 | |tenscalc| is available on |github| and requires the installation of 3 8 | toolboxes, which must be installed in the following order: 9 | 10 | 1. |funpartools|: ``_ 11 | 2. |cmextools|: ``_ 12 | 3. |tenscalc|: ``_ 13 | 14 | Installations instructions for all these tools is available at 15 | |github|. 16 | 17 | Issues 18 | ====== 19 | 20 | While most |matlab| scripts are agnostic to the underlying operating 21 | systems (OSs), the use of mex functions depends heavily on the 22 | operating system. 23 | 24 | Our goal is to build a toolbox that works across multiple OSs; at 25 | least under OSX, linux, and Microsoft Windows. However, most of our 26 | testing was done under OSX so one should expect some bugs under the 27 | other OSs. Currently, it is fair to say that |tenscalc| has been tested 28 | 29 | * fairly extensively under OSX 30 | * lightly under linux 31 | * very lightly under Microsoft Windows 32 | 33 | Any help in fixing bugs is greatly appreciated. 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/sphinx/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinxcontrib-matlabdomain 2 | 3 | -------------------------------------------------------------------------------- /doc/tenscalc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hespanha/tenscalc/0632eb83d6be854406f4d3794bb4e92221fdbc13/doc/tenscalc.pdf -------------------------------------------------------------------------------- /doc/timeseries.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hespanha/tenscalc/0632eb83d6be854406f4d3794bb4e92221fdbc13/doc/timeseries.pdf -------------------------------------------------------------------------------- /examples/basicTests.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | %% Optimizations in tenscalc/examples 7 | examplesFolder=which('cmex2optimizeCS'); 8 | examplesFolder=fileparts(examplesFolder); 9 | cd(fullfile(examplesFolder,'../examples')); 10 | 11 | clear all; 12 | % remove previous solvers 13 | delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 14 | 15 | mls 16 | sls 17 | l1l2estimationCS 18 | 19 | clear all; 20 | % remove previous solvers 21 | delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 22 | 23 | %% Optimizations in tenscalc/examples/mpcmhe 24 | examplesFolder=which('cmex2optimizeCS'); 25 | examplesFolder=fileparts(examplesFolder); 26 | cd(fullfile(examplesFolder,'../examples/mpcmhe')); 27 | 28 | clear all; 29 | % remove previous solvers 30 | delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 31 | 32 | mpc_dcmotor 33 | mpcmhe_dcmotor 34 | mpc_unicycle 35 | 36 | clear all; 37 | % remove previous solvers 38 | delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 39 | 40 | %% Back to examples 41 | examplesFolder=which('cmex2optimizeCS'); 42 | examplesFolder=fileparts(examplesFolder); 43 | cd(fullfile(examplesFolder,'../examples')); 44 | -------------------------------------------------------------------------------- /examples/csparse/tutorialFIM.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all; 7 | % remove previous classes 8 | delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 9 | 10 | %% Create symbolic ecxpressions 11 | 12 | Tvariable theta [6]; % initial position/velocity 13 | Tvariable t []; % time 14 | Tvariable M [3,3]; % camera matrix parameter 15 | Tvariable p [3]; % camera position 16 | Tvariable invS [2,2]; % error covariance; 17 | 18 | q=theta(1:3)+theta(4:6)*t; 19 | mu=(M(1:2,:)*(p-q))./(M([3,3],:)*(p-q)); 20 | 21 | 22 | g=gradient(mu,theta); 23 | 24 | FIM=tprod(g,[-1,1],invS,[-1,-2],g,[-2,2]); 25 | %FIM=g'*invS*g; 26 | 27 | %% Generate code 28 | code=csparse(); 29 | 30 | declareSet(code,theta,'set_theta'); 31 | declareSet(code,t,'set_t'); 32 | declareSet(code,M,'set_M'); 33 | declareSet(code,p,'set_p'); 34 | declareSet(code,invS,'set_invS'); 35 | 36 | declareGet(code,FIM,'get_FIM'); 37 | 38 | cmex2compute('csparseObject',code,'classname','tmpFIM'); 39 | %class2compute('csparseObject',code,'classname','tmpFIM'); 40 | 41 | obj=tmpFIM(); 42 | 43 | %% Call code 44 | 45 | s = RandStream('mt19937ar','Seed',0); 46 | RandStream.setGlobalStream(s); 47 | 48 | theta=rand(6,1); 49 | set_theta(obj,theta); 50 | M=eye(3)+rand(3,3); 51 | set_M(obj,M); 52 | invS=rand(2,2);invS=invS'*invS; 53 | set_invS(obj,invS); 54 | 55 | FIM=zeros(6,6); 56 | fprintf('Comoputing FIMs... '); 57 | t0=clock(); 58 | for i=1:100000 59 | t=rand(1); 60 | set_t(obj,t); 61 | p=5+rand(3,1); % 5+ to keep p away from q 62 | set_p(obj,p); 63 | FIM=FIM+get_FIM(obj); 64 | end 65 | fprintf('done %.3f sec\n',etime(clock(),t0)); 66 | FIM,; 67 | -------------------------------------------------------------------------------- /examples/csparse/tutorialFIMextended.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all; 7 | % remove previous classes 8 | %delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 9 | 10 | %% Create symbolic ecxpressions 11 | 12 | Tvariable theta [6]; % initial position/velocity 13 | Tvariable t []; % time 14 | Tvariable M [3,3]; % camera matrix parameter 15 | Tvariable p [3]; % camera position 16 | Tvariable invS [2,2]; % error covariance; 17 | 18 | q=theta(1:3)+theta(4:6)*t; 19 | mu=(M(1:2,:)*(p-q))./(M([3,3],:)*(p-q)); 20 | 21 | 22 | g=gradient(mu,theta); 23 | 24 | FIM=tprod(g,[-1,1],invS,[-1,-2],g,[-2,2]); 25 | %FIM=g'*invS*g; 26 | 27 | %% Generate code 28 | code=csparse(); 29 | 30 | declareSet(code,theta,'set_theta'); 31 | declareSet(code,t,'set_t'); 32 | declareSet(code,M,'set_M'); 33 | declareSet(code,p,'set_p'); 34 | declareSet(code,invS,'set_invS'); 35 | 36 | declareGet(code,FIM,'get_FIM'); 37 | 38 | classname='tmpFIM'; 39 | classname=cmex2compute('csparseObject',code,'pedigreeClass',classname,'executeScript','asneeded'); 40 | %classname=class2compute('csparseObject',code,'classname',classname,'executeScript','asneeded'); 41 | 42 | help(classname); 43 | obj=feval(classname); 44 | 45 | %% Call code 46 | 47 | s = RandStream('mt19937ar','Seed',0); 48 | RandStream.setGlobalStream(s); 49 | 50 | theta=rand(6,1); 51 | set_theta(obj,theta); 52 | t=rand(1); 53 | set_t(obj,t); 54 | M=eye(3)+rand(3,3); 55 | set_M(obj,M); 56 | invS=rand(2,2);invS=invS'*invS; 57 | set_invS(obj,invS); 58 | 59 | %[logf,logff]=get_logf(obj),; 60 | FIM=zeros(6,6); 61 | fprintf('Comoputing FIMs... '); 62 | t0=clock(); 63 | for i=1:100000 64 | p=5+rand(3,1); % 5+ to keep p away from q 65 | set_p(obj,p); 66 | FIM=FIM+get_FIM(obj); 67 | end 68 | fprintf('done %.3f sec\n',etime(clock(),t0)); 69 | FIM,; 70 | -------------------------------------------------------------------------------- /examples/csparse/tutorialLQ.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all; 7 | % remove previous classes 8 | delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 9 | 10 | %% Defines sizes 11 | 12 | N=100; % length of x 13 | n=2; % length of x0 14 | k=10; % length of u 15 | 16 | %% Create symbolic ecxpressions 17 | 18 | Tvariable A [N,n]; 19 | Tvariable x0 [n]; 20 | Tvariable B [N,k]; 21 | Tvariable u [k]; 22 | 23 | x=A*x0+B*u; 24 | 25 | J=norm2(x)+norm2(u); 26 | 27 | g=gradient(J,u); 28 | h=gradient(g,u); 29 | 30 | factor=ldl(h); % faster but less robust and needs to be symmetric 31 | %factor=lu(h); 32 | 33 | ustar=-(factor\g); 34 | 35 | %% Generate code 36 | code=csparse(); 37 | 38 | declareSet(code,A, 'set_A','set variable A'); 39 | declareSet(code,x0,'set_x0','set variable x0'); 40 | declareSet(code,B, 'set_B','set variable B'); 41 | declareSet(code,u, 'set_u','set variable u'); 42 | 43 | declareGet(code,{J,g,h},'get_Jgh','get cost, gradient and hessian'); 44 | declareGet(code,{ustar},'get_ustar','optimal u'); 45 | declareCopy(code,u,ustar,'copy_ustar2u','copy ustar to u'); 46 | 47 | cmex2compute('csparseObject',code,'classname','tmpLQ'); 48 | %class2compute('csparseObject',code,'classname','tmpLQ'); 49 | 50 | obj=tmpLQ(); 51 | 52 | %% Call code 53 | 54 | s = RandStream('mt19937ar','Seed',0); 55 | RandStream.setGlobalStream(s); 56 | 57 | A=rand(N,n); 58 | x0=rand(n,1); 59 | B=rand(N,k); 60 | 61 | set_A(obj,A); 62 | set_B(obj,B); 63 | set_x0(obj,x0); 64 | set_u(obj,zeros(k,1)); 65 | 66 | [J,g,h]=get_Jgh(obj); % cost, grad, and hessian for zero 0 67 | fprintf('cost for u=0 is %f\n',J); 68 | 69 | ustar=get_ustar(obj); 70 | copy_ustar2u(obj); % be careful: after copy ustar changes! 71 | 72 | [J,g,h]=get_Jgh(obj); % cost, grad, and hessian for optimal u 73 | fprintf('cost for optimal u is %f\n',J); 74 | -------------------------------------------------------------------------------- /examples/csparse/tutorialLQextended.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all; 7 | % remove previous classes 8 | %delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 9 | 10 | %% Defines sizes 11 | 12 | N=100; % length of x 13 | n=2; % length of x0 14 | k=10; % length of u 15 | 16 | %% Create symbolic ecxpressions 17 | 18 | Tvariable A [N,n]; 19 | Tvariable x0 [n]; 20 | Tvariable B [N,k]; 21 | Tvariable u [k]; 22 | 23 | x=A*x0+B*u; 24 | 25 | J=norm2(x)+norm2(u); 26 | 27 | g=gradient(J,u); 28 | h=gradient(g,u); 29 | 30 | factor1=lu(h); 31 | 32 | ustar1=-(factor1\g); 33 | 34 | factor2=ldl(h); 35 | 36 | ustar2=-(factor2\g); 37 | 38 | %% Generate code 39 | code=csparse(); 40 | 41 | declareSet(code,A, 'set_A','set variable A'); 42 | declareSet(code,x0,'set_x0','set variable x0'); 43 | declareSet(code,B, 'set_B','set variable B'); 44 | declareSet(code,u, 'set_u','set variable u'); 45 | 46 | declareGet(code,{J,g,h},'get_Jgh','get cost, gradient and hessian'); 47 | declareGet(code,{ustar1},'get_ustar1','get cost, gradient and hessian'); 48 | declareGet(code,{ustar2},'get_ustar2','get cost, gradient and hessian'); 49 | declareCopy(code,u,ustar1,'copy_ustar12u','copy ustar to u'); 50 | declareCopy(code,u,ustar2,'copy_ustar22u','copy ustar to u'); 51 | 52 | classname='tmpLQ'; 53 | classname=cmex2compute('csparseObject',code,'pedigreeClass',classname,'executeScript','asneeded'); 54 | %classname=class2compute('csparseObject',code,'classname',classname); 55 | 56 | help(classname); 57 | obj=feval(classname); 58 | 59 | %% Call code 60 | 61 | s = RandStream('mt19937ar','Seed',0); 62 | RandStream.setGlobalStream(s); 63 | 64 | A=rand(N,n); 65 | x0=rand(n,1); 66 | B=rand(N,k); 67 | 68 | set_A(obj,A); 69 | set_B(obj,B); 70 | set_x0(obj,x0); 71 | set_u(obj,zeros(k,1)); 72 | 73 | [J,g,h]=get_Jgh(obj); % cost, grad, and hessian for zero 0 74 | fprintf('cost for u=0 is %f\n',J); 75 | 76 | ustar=get_ustar1(obj) 77 | copy_ustar12u(obj); 78 | [J,g,h]=get_Jgh(obj); 79 | J,; 80 | 81 | set_u(obj,zeros(k,1)); 82 | ustar=get_ustar2(obj) 83 | copy_ustar22u(obj); 84 | 85 | [J,g,h]=get_Jgh(obj); % cost, grad, and hessian for optimal u 86 | fprintf('cost for optimal u is %f\n',J); 87 | -------------------------------------------------------------------------------- /examples/dist2convex.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | % Many ways to skin a cat... 7 | % 8 | % This example is about finding the "convex combination" x that minimizes 9 | % J(x)= \|A x - b\|^2 10 | % where sum(x)=1, x>=0 11 | 12 | clear all 13 | % remove previous solvers 14 | delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 15 | 16 | solverGeneration=@cmex2optimizeCS; 17 | 18 | N=100; 19 | d=9; 20 | 21 | if 1 22 | % using equality contraint 23 | Tvariable x [N]; 24 | 25 | optimizationVariables={x}; 26 | constraints={sum(x,1)==1,x>=0}; 27 | else 28 | % using one less variable 29 | Tvariable x1 N-1; 30 | 31 | x=[x1;1-sum(x1,1)]; 32 | optimizationVariables={x1}; 33 | constraints={x>=0}; 34 | end 35 | 36 | if 0 37 | % using original cost function 38 | Tvariable A [d,N]; 39 | Tvariable b d; 40 | 41 | J=norm2(A*x-b); 42 | 43 | parameters={A,b}; 44 | else 45 | % expanding norm 46 | % J=(x'*A'-b')*(A*x-b) 47 | % =x'*(A'*A)*x-2*b'*A*x 48 | Tvariable AA [N,N]; 49 | Tvariable bA2 [N]; 50 | 51 | J=x*AA*x-bA2*x; 52 | 53 | parameters={AA,bA2}; 54 | end 55 | 56 | 57 | [classname,code]=solverGeneration('classname','tmp_mind2cvx',... 58 | 'objective',J,... 59 | 'optimizationVariables',optimizationVariables,... 60 | 'constraints',constraints,... 61 | 'outputExpressions',{J,x},... 62 | 'parameters',parameters,... 63 | 'skipAffine',false,... 64 | 'compilerOptimization','-O1',... 65 | 'addEye2Hessian',true,... 66 | 'adjustAddEye2Hessian',false,... 67 | 'profiling',false,... 68 | 'solverVerboseLevel',2); 69 | 70 | s = RandStream('mt19937ar','Seed',0); 71 | RandStream.setGlobalStream(s); 72 | 73 | A=randn(d,N); 74 | b=randn(d,1); 75 | 76 | obj=feval(classname); 77 | 78 | % Set parameters 79 | if exist('AA','var') 80 | setP_AA(obj,A'*A); 81 | setP_bA2(obj,2*A'*b); 82 | else 83 | setP_A(obj,A); 84 | setP_b(obj,b); 85 | end 86 | % Initialize primal variables 87 | if exist('x1','var') 88 | x0=1/2/N*ones(N-1,1); 89 | setV_x1(obj,x0); 90 | x0=[x0;1-sum(x0)]; 91 | else 92 | x0=1/2/N*ones(N,1); 93 | setV_x(obj,x0); 94 | end 95 | 96 | 97 | % Solve optimization 98 | mu0=1; 99 | maxIter=30; 100 | saveIter=-1; 101 | clear iter time; 102 | nRepeats=1000; 103 | for i=1:nRepeats 104 | [status,iter(i),time(i)]=solve(obj,mu0,int32(maxIter),int32(saveIter)); 105 | end 106 | fprintf('iter: mean=%.2f, min=%.2f, max=%.2f\n',... 107 | mean(iter),min(iter),max(iter)); 108 | fprintf('time [us]: median=%.2f, min=%.2f, max=%.2f\n',... 109 | 1e6*median(time),1e6*min(time),1e6*max(time)); 110 | -------------------------------------------------------------------------------- /examples/mpcmhe/mpc_dcmotor_simulink.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all 7 | % remove previous solvers 8 | %delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 9 | 10 | %% Generate solver 11 | 12 | % Create symbolic optimization 13 | 14 | nX=2; % state size 15 | nU=1; % control size 16 | T=30; % forward horizon 17 | 18 | % DC-motor-like transfer function 19 | % [dot x1]=[0 1][x1]+[0]u 20 | % [dot x2] [0 p][x2] [k] 21 | % y=x1 22 | 23 | Tvariable p [1,1]; 24 | Tvariable k [1,1]; 25 | dxFun=@(x,u,p,k)[0,1;0,p]*x+[0;k]*u; 26 | 27 | [Ts,xMeas,xFut,~,uFut,ode]=TvariablesMPC(nX,nU,T,0,dxFun,p,k); 28 | 29 | % parameters for state and input constraints 30 | Tvariable uMax []; 31 | Tvariable xMax [2,1]; 32 | 33 | % Criterium 34 | 35 | Tvariable r [1,T]; % reference 36 | J=norm2(xFut(1,:)-r)+norm2(uFut)/50; 37 | 38 | % Warm start 39 | 40 | xFutWarm=[xFut(:,2:end),zeros(nX,1)]; 41 | uFutWarm=[uFut(:,2:end),zeros(nU,1)]; 42 | xFutWarm=min(xFutWarm,.9*repmat(xMax,[1,T])); 43 | xFutWarm=max(xFutWarm,-.9*repmat(xMax,[1,T])); 44 | uFutWarm=min(uFutWarm,.9*uMax); 45 | uFutWarm=max(uFutWarm,-.9*uMax); 46 | 47 | % inequality constraints 48 | constraints={uFut<=uMax, uFut>=-uMax,... 49 | xFut<=repmat(xMax,[1,T]),xFut>=-repmat(xMax,[1,T])}; 50 | 51 | [classname,code]=cmex2optimizeCS(... 52 | 'classname','tmp_mpc_dcmotor',... 53 | ... 54 | 'objective',J,... 55 | 'optimizationVariables',{xFut,uFut},... 56 | 'constraints',{ode,constraints{:}},... 57 | 'parameters',{p,k,Ts,r,uMax,xMax,xMeas},... 58 | 'outputExpressions',{J,[xMeas,xFut],uFut,xFutWarm,uFutWarm},... 59 | ... 60 | 'simulinkLibrary','tmp_mpc_dcmotor_SL',... 61 | ... 62 | 'compilerOptimization','-O0',... 63 | 'solverVerboseLevel',2); 64 | 65 | %open_system('tmp_mpc_dcmotor_SL'); 66 | 67 | 68 | %% Simulate system 69 | 70 | % set parameter values 71 | p=2;k=1; 72 | Ts=.1; 73 | 74 | uMax=1; 75 | xMax=[.4;.3]; 76 | 77 | refmax=.35; 78 | refomega=.5; 79 | 80 | % set process initial condition 81 | t0=0; 82 | xMeas=[.2;.2]; 83 | 84 | % cold start 85 | uFutCold=.1*randn(nU,T); 86 | xFutCold=.1*randn(nX,T); 87 | 88 | mu0=1; 89 | maxIter=50; 90 | saveIter=false; 91 | 92 | open_system('mpc_dcmotor_simulink_S'); 93 | set_param('mpc_dcmotor_simulink_S',... 94 | 'RelTol','1e-6',... 95 | 'StartTime','0','StopTime','15'); 96 | out=sim('mpc_dcmotor_simulink_S'); 97 | 98 | fig=21;figure(fig);clf; 99 | set(fig,'Name','Closed-loop (simulink)'); 100 | plot(x.time,squeeze(x.signals.values),'.-',... 101 | u.time,squeeze(u.signals.values),'.-',... 102 | ref.time,squeeze(ref.signals.values),'.-');grid on; 103 | legend('x1','x2','u','r'); 104 | xlabel('t'); 105 | 106 | fig=fig+1;figure(fig);clf; 107 | set(fig,'Name','Solver (simulink)'); 108 | subplot(2,1,1); 109 | plot(cost.time,squeeze(cost.signals.values),'.-');grid on; 110 | ylabel('MPC cost'); 111 | subplot(2,1,2); 112 | yyaxis left 113 | plot(iter.time,squeeze(iter.signals.values),'.-');grid on; 114 | ylabel('# iterations'); 115 | yyaxis right 116 | plot(stime.time,1000*squeeze(stime.signals.values),'.-');grid on; 117 | ylabel('solver time [ms]'); 118 | xlabel('t'); 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /examples/mpcmhe/mpc_dcmotor_simulink_S.slx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hespanha/tenscalc/0632eb83d6be854406f4d3794bb4e92221fdbc13/examples/mpcmhe/mpc_dcmotor_simulink_S.slx -------------------------------------------------------------------------------- /examples/robustRegressL1.m: -------------------------------------------------------------------------------- 1 | % This script uses Tenscals's function `cmex2optimizeCS` to 2 | % generate a solver for an L1-regularized regression of the form: 3 | % 4 | % minimize || y - theta0 ones(size(y)) - H \theta ||_2 + lambda ||\theta||_1 5 | % 6 | % w.r.t. theta0 in R, theta in R^n 7 | % 8 | % The solver can be generated once and then called multiple 9 | % times. Creating a solver typically takes much longer than solving 10 | % the optimization by creating the solver. 11 | % 12 | % This script gives you the option of skipping creating the solver, 13 | % but you can only skip generating a solver if you have done it once. 14 | 15 | % This file is part of Tencalc. 16 | % 17 | % Copyright (C) 2012-21 The Regents of the University of California 18 | % (author: Dr. Joao Hespanha). All rights reserved. 19 | 20 | clear all; 21 | % remove previous solvers 22 | %delete('toremove.m','tmp*');rc=rmdir('@tmp*','s'); 23 | 24 | help robustRegressL1 25 | 26 | createSolvers=input('Do you want to create the solvers (Y/n)? ','s'); 27 | createSolvers=~isequal(createSolvers,'n'); 28 | 29 | %%%%%%%%%%%%%%%%%%% 30 | %% Load test data 31 | %%%%%%%%%%%%%%%%%%% 32 | 33 | m=1000; % size of training data 34 | n=15; % # of independent variables 35 | 36 | if createSolvers 37 | 38 | %%%%%%%%%%%%%%%%%%% 39 | %% Generate solver 40 | %%%%%%%%%%%%%%%%%%% 41 | 42 | Tcalculus.clear(); 43 | 44 | Tvariable lambda []; 45 | 46 | Tvariable theta0 []; 47 | Tvariable theta [n]; 48 | Tvariable absTheta [n]; 49 | 50 | Tvariable y [m]; 51 | Tvariable H [m,n]; 52 | 53 | v2=norm2(y-theta0*Tones(m)-H*theta); 54 | J =sqrt(v2)+lambda*sum(absTheta,1); 55 | 56 | classname=cmex2optimizeCS('classname','tmp_lasso',... 57 | 'objective',J,... 58 | 'optimizationVariables',{theta0,theta,absTheta},... 59 | 'constraints',{absTheta>theta;absTheta>-theta},... 60 | 'parameters',{lambda,y,H},... 61 | 'outputExpressions',{theta,theta0,J},... 62 | 'scaleCost',1,... 63 | 'solverVerboseLevel',2); 64 | end 65 | 66 | %%%%%%%%%%%%%%% 67 | %% Use solver 68 | %%%%%%%%%%%%%%% 69 | 70 | % Create object 71 | obj=tmp_lasso(); 72 | 73 | s = RandStream('mt19937ar','Seed',0); % fix seed for reproducibility 74 | RandStream.setGlobalStream(s); 75 | 76 | lambda=10; 77 | setP_lambda(obj,lambda); 78 | 79 | for i=1:3 80 | 81 | %% Generate synthetic training data 82 | thisTheta=randn(n,1); 83 | thisTheta(rand(n,1)<.5)=0; 84 | thisTheta0=randn(1,1); 85 | thisH=randn(m,n); 86 | thisy=thisTheta0+thisH*thisTheta+.2*randn(m,1); 87 | 88 | %% Set parameters 89 | setP_y(obj,thisy); 90 | setP_H(obj,thisH); 91 | 92 | %% Random initial value for solver 93 | theta=.01*randn(n,1); 94 | theta0=mean(thisy-thisH*theta); 95 | 96 | setV_theta0(obj,theta0); 97 | setV_theta(obj,theta); 98 | setV_absTheta(obj,abs(theta)+1); 99 | 100 | % Solve optimization 101 | mu0=.001; 102 | maxIter=100; 103 | saveIter=-1; 104 | [status,iter,time]=solve(obj,mu0,int32(maxIter),int32(saveIter)); 105 | % Get outputs 106 | [theta,theta0,J]=getOutputs(obj); 107 | 108 | fprintf('Cost = %.2f, theta0 = %.3f, theta =\n',J,theta0); 109 | disp(theta'); 110 | 111 | if status 112 | error('Solver failed') 113 | end 114 | end 115 | -------------------------------------------------------------------------------- /examples/testing/numericalGradient.m: -------------------------------------------------------------------------------- 1 | function grad=numericalGradient(f,x,h) 2 | % 3 | % This file is part of Tencalc. 4 | % 5 | % Copyright (C) 2012-21 The Regents of the University of California 6 | % (author: Dr. Joao Hespanha). All rights reserved. 7 | 8 | sizef=size(f(x)); 9 | sizex=size(x); 10 | sizegrad=[sizef,sizex]; 11 | if isequal(sizef,[1,1]) && length(sizex)<=2 12 | grad=nan(sizex); 13 | for j1=1:size(x,1) 14 | for j2=1:size(x,2) 15 | hj=zeros(sizex); 16 | hj(j1,j2)=h/2; 17 | grad(j1,j2)=(f(x+hj)-f(x-hj))/h; 18 | end 19 | end 20 | elseif length(sizef)<=2 && sizex(2)<=1 21 | grad=nan([sizef,sizex(1)]); 22 | for j1=1:size(x,1) 23 | hj=zeros(sizex); 24 | hj(j1)=h/2; 25 | grad(:,:,j1)=(f(x+hj)-f(x-hj))/h; 26 | end 27 | if sizef(2)==1 28 | sizegrad(2)=[] 29 | reshape(grad,sizegrad); 30 | end 31 | else 32 | sizef,sizex, 33 | error('numerical Gradient not fully implemented'); 34 | end 35 | end 36 | 37 | -------------------------------------------------------------------------------- /examples/testing/testComponentwise.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all; 7 | !rm -fr tmp* @tmp* 8 | 9 | s = RandStream('mt19937ar','Seed',0); 10 | RandStream.setGlobalStream(s); 11 | 12 | gen={@cmex2compute,@class2compute}; 13 | 14 | %% Test componentwise 15 | 16 | if 1 17 | N=2; 18 | 19 | Tvariable a [N]; 20 | %A=diag(a); 21 | A=a; 22 | 23 | cA=componentwise(A,@cos,'cos(%s)'); 24 | sA=componentwise(A,@sin,'sin(%s)',@(x)componentwise(x,@cos,'cos(%s)',@(x)-componentwise(x,@sin,'sin(%s)'))); 25 | dA=componentwise(A,@(x)2*x,'2*%s',@(x)2*Tones(size(x)),@(x)Tzeros(size(x))); 26 | 27 | dsA=gradient(sA,a); 28 | d2sA=gradient(dsA,a); 29 | 30 | ddA=gradient(dA,a); 31 | d2dA=gradient(ddA,a); 32 | 33 | for i=1:length(gen) 34 | code=csparse(); 35 | declareSet(code,a,'set_a'); 36 | declareGet(code,{A,cA,sA,dA,full(dsA),full(d2sA),full(ddA),full(d2dA)},'getAll'); 37 | 38 | classname=gen{i}('classname','tmp','csparseObject',code); 39 | 40 | str(code,1); 41 | 42 | obj=feval(classname); 43 | set_a(obj,(2:N+1)'); 44 | [A_,cA_,sA_,dA_,dsA_,d2sA_,ddA_,d2dA_]=getAll(obj) 45 | 46 | end 47 | end 48 | 49 | %% Test functions derived from componentwise 50 | 51 | % function, derivative 52 | fun={@srelu,@(x)exp(x)./(1+exp(x)),@(x)exp(x)./(1+exp(x)).^2; 53 | @normpdf,@(x)-x.*exp(-x.^2/2)/sqrt(2*pi),@(x)(x.^2-1).*exp(-x.^2/2)/sqrt(2*pi); 54 | @atan,@(x)1./(1+x.^2),@(x)-2*x./(1+x.^2).^2; 55 | @sqr,@(x)2*x,@(x)2*ones(size(x)); 56 | @cube,@(x)3*x.^2,@(x)6*x; 57 | @sqrt,@(x).5./sqrt(x),@(x)-.25.*x^(-1.5); 58 | @exp,@exp,@exp; 59 | @log,@(x)1./x,@(x)-1./x.^2; 60 | @sin,@cos,@(x)-sin(x); 61 | @cos,@(x)-sin(x),@(x)-cos(x); 62 | @tan,@(x)sec(x).^2,@(x)2*sec(x).^2.*tan(x); 63 | @atan,@(x)1./(1+x.^2),@(x)-2*x./(1+x.^2).^2; 64 | @(x)power(x,4),@(x)4*power(x,3),@(x)12*power(x,2); 65 | @round,@(x)zeros(size(x)),@(x)zeros(size(x)); 66 | @ceil,@(x)zeros(size(x)),@(x)zeros(size(x)); 67 | @floor,@(x)zeros(size(x)),@(x)zeros(size(x)); 68 | @sign,@(x)zeros(size(x)),@(x)zeros(size(x)); 69 | @abs,@sign,@(x)zeros(size(x)); 70 | @relu,@heaviside,@(x)zeros(size(x)); 71 | }; 72 | 73 | for f=1:size(fun,1) 74 | for i=1:length(gen) 75 | fprintf('*****trying %s with %s\n',char(fun{f,1}),char(gen{i})); 76 | code=csparse(); 77 | 78 | Tvariable x [2]; 79 | y=fun{f,1}(x); 80 | dy=gradient(y,x); 81 | d2y=gradient(dy,x); 82 | declareSet(code,x,'set_x'); 83 | declareGet(code,{y,dy,full(d2y)},'get'); 84 | 85 | classname=gen{i}('classname',sprintf('tmp%d%d',f,i),'csparseObject',code); 86 | 87 | obj=feval(classname); 88 | x=rand(2,1); 89 | set_x(obj,x); 90 | [y_,dy_,d2y_]=get(obj); 91 | 92 | y=fun{f,1}(x); 93 | dy=diag(fun{f,2}(x)); 94 | d2y=zeros(2,2,2); 95 | d2y(1,1,1)=fun{f,3}(x(1)); 96 | d2y(2,2,2)=fun{f,3}(x(2)); 97 | 98 | if norm(y-y_,inf)>10*eps 99 | y,y_, 100 | error('error in computation of %s',char(fun{f,1})); 101 | end 102 | if norm(dy-dy_,inf)>10*eps 103 | dy,dy_, 104 | error('error in computation of %s''',char(fun{f,1})); 105 | end 106 | if any(abs(d2y-d2y_)>100*eps,'all') 107 | d2y,d2y_, 108 | error('error in computation of %s''''',char(fun{f,1})); 109 | end 110 | clear obj 111 | end 112 | end 113 | -------------------------------------------------------------------------------- /examples/testing/testFactorizations.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | !rm -fr tmp* @tmp* 3 | 4 | s = RandStream('mt19937ar','Seed',0); 5 | RandStream.setGlobalStream(s); 6 | 7 | gen={@cmex2compute,@class2compute}; 8 | 9 | N=5; 10 | 11 | % Make a matrix symmetric as ldl does it. 12 | sym=@(A)tril(A)+tril(A)'-diag(diag(A)); 13 | 14 | close=@(A,B,tol)norm(A(:)-B(:),inf)<=tol; 15 | 16 | for g=1:length(gen) 17 | Tcalculus.clear(); 18 | 19 | fprintf('*****trying %s\n',char(gen{g})); 20 | code=csparse(); 21 | tc=struct(); 22 | 23 | % non symmetric 24 | [i,j]=find(ones(N,N)); 25 | k=randi(N*N,floor(.25*N*N),1); 26 | i(k)=[]; 27 | j(k)=[]; 28 | %[i,j] 29 | tc.a=Tvariable('a',length(i)); 30 | tc.A=vec2tensor(tc.a,[N,N],[i,j]); 31 | 32 | % symmetric 33 | [i,j]=find(ones(N,N)); 34 | k=randi(N*N,floor(.25*N*N),1); 35 | k(i(k)==j(k))=[]; % do not remove diagonal elements to not mess up ldl fact. 36 | i(k)=[]; 37 | j(k)=[]; 38 | k0=find(i==j); 39 | k1=find(i>j); 40 | is=[i(k0);i(k1);j(k1)]; 41 | js=[j(k0);j(k1);i(k1)]; 42 | %[is,js] 43 | tc.as=Tvariable('as',length(k0)+length(k1)); 44 | as=[tc.as;tc.as(end-length(k1)+1:end)]; 45 | tc.As=vec2tensor(as,[N,N],[is,js]); 46 | 47 | tc.ldl_d_As=ldl_d(ldl(tc.As)); 48 | tc.ldl_l_As=ldl_l(ldl(tc.As)); 49 | 50 | tc.lu_l_A=lu_l(lu(tc.A)); 51 | tc.lu_u_A=lu_u(lu(tc.A)); 52 | tc.lu_d_A=lu_d(lu(tc.A)); 53 | 54 | 55 | declareSet(code,tc.a,'set_a'); 56 | declareSet(code,tc.as,'set_as'); 57 | declareGet(code,tc,'getAll'); 58 | 59 | classname=gen{g}('classname',sprintf('tmp%d',g),'csparseObject',code); 60 | 61 | obj=feval(classname); 62 | 63 | in.a=rand(size(tc.a),1); 64 | set_a(obj,in.a); 65 | in.as=rand(size(tc.as),1); 66 | set_as(obj,in.as); 67 | out=getAll_struct(obj), 68 | 69 | fprintf('LDL factorization\n'); 70 | full(out.As) 71 | full(out.ldl_d_As) 72 | full(out.ldl_l_As) 73 | 74 | full(out.ldl_l_As*diag(out.ldl_d_As)*out.ldl_l_As') 75 | if ~close(out.As,out.ldl_l_As*diag(out.ldl_d_As)*out.ldl_l_As',1e3*eps) 76 | 77 | error('error in LDL computation of %s',char(gen{g})); 78 | end 79 | 80 | 81 | fprintf('LU factorization\n'); 82 | full(out.A), 83 | full(out.lu_l_A), 84 | full(out.lu_u_A), 85 | full(out.lu_d_A), 86 | full(out.lu_l_A*out.lu_u_A), 87 | if ~close(out.A,out.lu_l_A*out.lu_u_A,1e3*eps), 88 | 89 | error('error in LU computation of %s',char(gen{g})); 90 | end 91 | 92 | clear obj 93 | end 94 | 95 | -------------------------------------------------------------------------------- /examples/testing/testInstructionsTable.m: -------------------------------------------------------------------------------- 1 | compileInstructionsTable 2 | 3 | 4 | %% unload library if it is loaded 5 | if libisloaded('instructionsTable') 6 | unloadlibrary('instructionsTable') 7 | end 8 | [notfound,warnings]=loadlibrary('instructionsTable','instructionsTable.h'); 9 | m=libfunctions('instructionsTable'); 10 | 11 | 12 | s = RandStream('mt19937ar','Seed',1); 13 | RandStream.setGlobalStream(s); 14 | 15 | N=10000; 16 | nP=30; 17 | maxP=1; 18 | nO=10; 19 | maxO=1; 20 | 21 | profile on 22 | 23 | initInstructionsTable() 24 | fprintf('Calling appendInstruction %d times...');t0=clock; 25 | Itype=int32(23); 26 | for i=1:N 27 | k=ceil(nP*rand()); 28 | parameters=double(ceil(maxP*rand(1,k))); 29 | k=ceil(nO*rand()); 30 | operands=int64(maxO*rand(1,k)); 31 | index=appendInstruction(Itype,parameters,operands); 32 | [Rtype,Rparameters,Roperands]=getInstruction(index); 33 | if (Itype~=Rtype || ~isequal(parameters,Rparameters) || ~isequal(operands,Roperands)) 34 | Itype 35 | Rtype 36 | parameters 37 | Rparameters 38 | operands 39 | Roperands 40 | error('mismatch\n'); 41 | end 42 | end 43 | fprintf('table size = %d, done (%.3f sec, %.3f us/call)\n',index,etime(clock,t0),1e6*etime(clock,t0)/N); 44 | 45 | initInstructionsTable() 46 | fprintf('Calling appendUniqueInstruction %d times...');t0=clock; 47 | for i=1:N 48 | k=ceil(nP*rand()); 49 | parameters=double(ceil(maxP*rand(1,k))); 50 | k=ceil(nO*rand()); 51 | operands=int64(maxO*rand(1,k)); 52 | index=appendUniqueInstruction(Itype,parameters,operands); 53 | [Rtype,Rparameters,Roperands]=getInstruction(index); 54 | if (Itype~=Rtype || ~isequal(parameters,Rparameters) || ~isequal(operands,Roperands)) 55 | Itype 56 | Rtype 57 | parameters 58 | Rparameters 59 | operands 60 | Roperands 61 | error('mismatch\n'); 62 | end 63 | end 64 | fprintf('table size = %d, done (%.3f sec, %.3f us/call)\n',index,etime(clock,t0),1e6*etime(clock,t0)/N); 65 | 66 | profile off 67 | profile viewer 68 | 69 | 70 | unloadlibrary('instructionsTable') 71 | -------------------------------------------------------------------------------- /examples/testing/testLDL.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all 7 | 8 | !rm -f tmpC* 9 | 10 | streamSelect=RandStream.create('mt19937ar','seed',0); 11 | RandStream.setGlobalStream(streamSelect); 12 | 13 | n=6 14 | m=2 15 | 16 | profile on 17 | t0=clock; 18 | fprintf('Creating code... '); 19 | createGateway('template','testLDL_raw.c',... 20 | 'callType','include',... 21 | 'compileGateways',true,... 22 | 'compilerOptimization','-O0',... 23 | 'preprocessParameters',{n,m},... 24 | 'verboseLevel',2); 25 | fprintf('done creating code (%.2f sec)\n',etime(clock,t0)); 26 | profile viewer 27 | 28 | WW=rand(n); 29 | WW=WW*diag(randn(n,1))*WW'; 30 | WW(abs(WW(:))<.1)=0; 31 | 32 | B=rand(n,m); 33 | 34 | fprintf('Matlab:\n'); 35 | WW 36 | 37 | % matlab's sparse LDL 38 | sWW=sparse(WW); 39 | [l,d,p]=ldl(sWW,'vector'); 40 | full(l),full(d),p 41 | full(l*d*l'-sWW(p,p)) 42 | 43 | 44 | t0=clock; 45 | [l,u,p]=ldl(sWW,'vector'); 46 | fprintf(' ldl: %.1f us\n',1e6*etime(clock,t0)) 47 | t0=clock; 48 | [l,u,p]=ldl(sWW,'vector'); 49 | fprintf(' ldl: %.1f us\n',1e6*etime(clock,t0)) 50 | 51 | if 1 52 | X=WW\B; 53 | t0=clock; 54 | X=WW\B; 55 | fprintf(' mldivide: %.1f us\n',1e6*etime(clock,t0)) 56 | t0=clock; 57 | X=WW\B; 58 | fprintf(' mldivide: %.1f us\n',1e6*etime(clock,t0)) 59 | end 60 | 61 | fprintf('C code:\n'); 62 | [LDL,X]=tmpC_testLDL(WW,B); 63 | t0=clock; 64 | [LDL,X]=tmpC_testLDL(WW,B); 65 | fprintf(' csparse: %.1f us\n',1e6*etime(clock,t0)) 66 | L=tril(LDL,-1)+eye(n); 67 | U=triu(LDL,1)+eye(n); 68 | D=diag(diag(LDL)); 69 | X 70 | 71 | if 1 72 | LDL 73 | L 74 | D 75 | U 76 | 77 | WW 78 | L*D*U 79 | 80 | X 81 | WW\B 82 | end 83 | 84 | if norm(WW-L*D*U)>eps 85 | WW 86 | L*D*U 87 | fprintf('mismatch WW~=LDL: %e (perhaps due to permutation)\n',norm(WW-L*D*U)) 88 | end 89 | 90 | if norm(X-WW\B)>eps 91 | fprintf('mismatch X~=WW\\B: %e (should match even with permutation)\n',norm(X-WW\B)) 92 | end 93 | 94 | -------------------------------------------------------------------------------- /examples/testing/testLDL_raw.c: -------------------------------------------------------------------------------- 1 | /**********************************/ 2 | /* Definition of Matlab's gateway */ 3 | /**********************************/ 4 | 5 | #ifdef createGateway 6 | 7 | MEXfunction tmpC_testLDL 8 | Cfunction tmpC_testLDL_raw 9 | include testLDL_raw.c 10 | 11 | inputs 12 | double A[n,n] 13 | double B[n,m] 14 | 15 | outputs 16 | double LDL[n,n] 17 | double X[n,m] 18 | 19 | 20 | preprocess(n,m) 21 | 22 | code=csparse(); 23 | 24 | Tvariable A [n,n]; 25 | Tvariable B [n,m]; 26 | 27 | declareSet(code,A,'setA'); 28 | declareSet(code,B,'setB'); 29 | declareGet(code,ldl(A),'getLDL'); 30 | declareGet(code,ldl(A)\B,'getX'); 31 | 32 | fprintf('After Set/Get declarations\n'); 33 | disp(code) 34 | 35 | compile2C(code,inf,inf,'tmpC_testLDL_CS.c','tmpC_testLDL_CS.h','tmpC_testLDL_CS.log','',0); 36 | 37 | fprintf('After Compile2C\n'); 38 | disp(code) 39 | #endif 40 | 41 | #include "tmpC_testLDL_CS.c" 42 | 43 | void tmpC_testLDL_raw(const double *A, 44 | const double *B, 45 | double *LDL, 46 | double *X, 47 | mwSize n, 48 | mwSize m) 49 | { 50 | clock_t dt; 51 | 52 | setA(A); 53 | setB(B); 54 | 55 | dt=clock(); 56 | getLDL(LDL); 57 | dt=clock()-dt; 58 | mexPrintf(" getLDL: %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 59 | 60 | dt=clock(); 61 | getX(X); 62 | dt=clock()-dt; 63 | mexPrintf(" getX: %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 64 | 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /examples/testing/testLU.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all 7 | 8 | streamSelect=RandStream.create('mt19937ar','seed',0); 9 | RandStream.setGlobalStream(streamSelect); 10 | 11 | n=6 12 | m=2 13 | 14 | profile on 15 | t0=clock; 16 | fprintf('Creating code... '); 17 | createGateway('template','testLU_raw.c',... 18 | 'callType','include',... 19 | 'compileGateways',true,... 20 | 'compilerOptimization','-O0',... 21 | 'preprocessParameters',{n,m},... 22 | 'verboseLevel',2); 23 | fprintf('done creating code (%.2f sec)\n',etime(clock,t0)); 24 | profile viewer 25 | 26 | WW=rand(n); 27 | WW(abs(WW(:))<.6)=0; 28 | WW=WW*WW'; 29 | 30 | B=rand(n,m); 31 | 32 | fprintf('Matlab:\n'); 33 | WW 34 | 35 | % matlab's sparse LU 36 | sWW=sparse(WW); 37 | [l,u,p,q]=lu(sWW,'vector'); 38 | full(l),full(u),p,q 39 | full(l*u-sWW(p,q)) 40 | 41 | 42 | t0=clock; 43 | [l,u,p,q]=lu(sWW,'vector'); 44 | fprintf(' lu: %.1f us\n',1e6*etime(clock,t0)) 45 | t0=clock; 46 | [l,u,p,q]=lu(sWW,'vector'); 47 | fprintf(' lu: %.1f us\n',1e6*etime(clock,t0)) 48 | 49 | if 0 50 | X=WW\B; 51 | t0=clock; 52 | X=WW\B; 53 | fprintf(' mldivide: %.1f us\n',1e6*etime(clock,t0)) 54 | t0=clock; 55 | X=WW\B; 56 | fprintf(' mldivide: %.1f us\n',1e6*etime(clock,t0)) 57 | end 58 | 59 | fprintf('C code:\n'); 60 | [LU,X]=tmpC_testLU(WW,B); 61 | t0=clock; 62 | [LU,X]=tmpC_testLU(WW,B); 63 | fprintf(' csparse: %.1f us\n',1e6*etime(clock,t0)) 64 | 65 | [i,j,v]=find(LU); 66 | k=i>j; 67 | L=full(sparse(i(k),j(k),v(k),n,n)+speye(n)); 68 | k=i<=j; 69 | U=full(sparse(i(k),j(k),v(k),n,n)); 70 | 71 | if 1 72 | LU 73 | L 74 | U 75 | 76 | WW 77 | L*U 78 | 79 | X 80 | WW\B 81 | end 82 | 83 | if norm(WW-L*U)>eps 84 | fprintf('mismatch WW~=LU: %e\n',norm(WW-L*U)) 85 | end 86 | 87 | if norm(X-WW\B)>eps 88 | fprintf('mismatch X~=WW\\B: %e\n',norm(X-WW\B)) 89 | end 90 | 91 | -------------------------------------------------------------------------------- /examples/testing/testLU_raw.c: -------------------------------------------------------------------------------- 1 | /**********************************/ 2 | /* Definition of Matlab's gateway */ 3 | /**********************************/ 4 | 5 | #ifdef createGateway 6 | 7 | MEXfunction tmpC_testLU 8 | Cfunction tmpC_testLU_raw 9 | include testLU_raw.c 10 | 11 | inputs 12 | double A[n,n] 13 | double B[n,m] 14 | 15 | outputs 16 | double LU[n,n] 17 | double X[n,m] 18 | 19 | 20 | preprocess(n,m) 21 | 22 | code=csparse(); 23 | 24 | Tvariable A [n,n]; 25 | Tvariable B [n,m]; 26 | 27 | declareSet(code,A,'setA'); 28 | declareSet(code,B,'setB'); 29 | declareGet(code,lu(A),'getLU'); 30 | declareGet(code,lu(A)\B,'getX'); 31 | 32 | fprintf('After Set/Get declarations\n'); 33 | disp(code) 34 | 35 | compile2C(code,inf,inf,'tmpC_testLU_CS.c','tmpC_testLU_CS.h','tmpC_testLU_CS.log','',0); 36 | 37 | fprintf('After Compile2C\n'); 38 | disp(code) 39 | #endif 40 | 41 | #include "tmpC_testLU_CS.c" 42 | 43 | void tmpC_testLU_raw(const double *A, 44 | const double *B, 45 | double *LU, 46 | double *X, 47 | mwSize n, 48 | mwSize m) 49 | { 50 | clock_t dt; 51 | 52 | setA(A); 53 | setB(B); 54 | 55 | dt=clock(); 56 | getLU(LU); 57 | dt=clock()-dt; 58 | mexPrintf(" getLU: %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 59 | 60 | dt=clock(); 61 | getX(X); 62 | dt=clock()-dt; 63 | mexPrintf(" getX: %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 64 | 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /examples/testing/testLUatomic.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all 7 | 8 | streamSelect=RandStream.create('mt19937ar','seed',0); 9 | RandStream.setGlobalStream(streamSelect); 10 | 11 | n=3 12 | m=1 13 | 14 | %profile on 15 | t0=clock; 16 | fprintf('Creating code... '); 17 | createGateway('template','testLUatomic_raw.c',... 18 | 'callType','include',... 19 | 'compileGateways',true,... 20 | 'compilerOptimization','-O0',... 21 | 'preprocessParameters',{n},... 22 | 'verboseLevel',2); 23 | fprintf('done creating code (%.2f sec)\n',etime(clock,t0)); 24 | %profile viewer 25 | 26 | WW=rand(n); 27 | WW(abs(WW(:))<.6)=0; 28 | WW=WW*WW'; 29 | 30 | B=rand(n,m); 31 | 32 | fprintf('Matlab:\n'); 33 | %WW 34 | 35 | % matlab's sparse LU 36 | sWW=sparse(WW); 37 | if 0 38 | [l,u,p,q]=lu(sWW,'vector'); 39 | full(l),full(u),p,q 40 | full(l*u-sWW(p,q)) 41 | end 42 | 43 | t0=clock; 44 | [l,u,p,q]=lu(sWW,'vector'); 45 | fprintf(' lu: %.1f us\n',1e6*etime(clock,t0)) 46 | t0=clock; 47 | [l,u,p,q]=lu(sWW,'vector'); 48 | fprintf(' lu: %.1f us\n',1e6*etime(clock,t0)) 49 | t0=clock; 50 | [l,u,p,q]=lu(sWW,'vector'); 51 | fprintf(' lu: %.1f us\n',1e6*etime(clock,t0)) 52 | 53 | if 0 54 | X=WW\B; 55 | t0=clock; 56 | X=WW\B; 57 | fprintf(' mldivide: %.1f us\n',1e6*etime(clock,t0)) 58 | t0=clock; 59 | X=WW\B; 60 | fprintf(' mldivide: %.1f us\n',1e6*etime(clock,t0)) 61 | end 62 | 63 | fprintf('C code:\n'); 64 | t0=clock; 65 | [X]=tmpC_testLUatomic(WW,B); 66 | fprintf(' csparse: %.1f us\n',1e6*etime(clock,t0)) 67 | t0=clock; 68 | [X]=tmpC_testLUatomic(WW,B); 69 | fprintf(' csparse: %.1f us\n',1e6*etime(clock,t0)) 70 | t0=clock; 71 | [X]=tmpC_testLUatomic(WW,B); 72 | fprintf(' csparse: %.1f us\n',1e6*etime(clock,t0)) 73 | 74 | if 0 75 | X 76 | WW\B 77 | end 78 | 79 | if norm(X-WW\B)>eps 80 | fprintf('mismatch X~=WW\\B: %e\n',norm(X-WW\B)) 81 | end 82 | 83 | -------------------------------------------------------------------------------- /examples/testing/testLUatomic_raw.c: -------------------------------------------------------------------------------- 1 | /**********************************/ 2 | /* Definition of Matlab's gateway */ 3 | /**********************************/ 4 | 5 | #ifdef createGateway 6 | 7 | MEXfunction tmpC_testLUatomic 8 | Cfunction tmpC_testLUatomic_raw 9 | include testLUatomic_raw.c 10 | 11 | inputs 12 | double A[n,n] 13 | double B[n,1] 14 | 15 | outputs 16 | double X[n,1] 17 | 18 | 19 | preprocess(n) 20 | 21 | code=csparse(); 22 | 23 | Tvariable A [n,n]; 24 | Tvariable B [n]; 25 | 26 | declareSet(code,A,'setA'); 27 | declareSet(code,B,'setB'); 28 | luA=declareAlias(code,lu(A),'luA',true); 29 | declareGet(code,luA\B,'getX'); 30 | 31 | fprintf('After Set/Get declarations\n'); 32 | disp(code) 33 | 34 | compile2C(code,inf,inf,'tmpC_testLU_CS.c','tmpC_testLU_CS.h','tmpC_testLU_CS.log','',0); 35 | 36 | fprintf('After Compile2C\n'); 37 | disp(code) 38 | #endif 39 | 40 | #include "tmpC_testLU_CS.c" 41 | 42 | void tmpC_testLUatomic_raw(const double *A, 43 | const double *B, 44 | double *X, 45 | mwSize n) 46 | { 47 | clock_t dt; 48 | 49 | setA(A); 50 | setB(B); 51 | 52 | dt=clock(); 53 | getX(X); 54 | dt=clock()-dt; 55 | mexPrintf(" getX: %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /examples/testing/testScaling.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all; 7 | !rm -fr tmp* @tmp* 8 | 9 | %% min_u max_d (x-1)^2-2*d^2 with x=u+d; 10 | % without latent variables 11 | 12 | Tvariable u; 13 | Tvariable d; 14 | x=u+d; 15 | 16 | J=(x-1).^2-2*d.^2; 17 | 18 | pars.P1optimizationVariables={u}; 19 | pars.P2optimizationVariables={d}; 20 | pars.P1objective=J; 21 | pars.P2objective=-J; 22 | pars.P1constraints={d>-.1}; 23 | pars.P2constraints={d>-.1}; 24 | pars.outputExpressions=struct('u',u,'d',d,'x',x); 25 | 26 | pars.scaleCost=1e-3; 27 | 28 | %pars.desiredDualityGap=1e-10; 29 | pars.classname='tmp'; 30 | pars.debugConvergence=false; 31 | pars.solverVerboseLevel=3; 32 | 33 | classname=class2equilibriumLatentCS(pars); 34 | 35 | obj=feval(classname); 36 | 37 | setV_u(obj,1); 38 | setV_d(obj,1); 39 | sol=solve(obj), 40 | out=getOutputs(obj), 41 | 42 | 43 | clear all; 44 | 45 | %% min_u max_d (x-1)^2-2*d^2 with x=u+d; 46 | % with equality but no latent variables 47 | 48 | Tvariable u; 49 | Tvariable d; 50 | Tvariable xu; 51 | Tvariable xd; 52 | 53 | Ju=(xu-1).^2-2*d.^2; 54 | Jd=(xd-1).^2-2*d.^2; 55 | 56 | pars.P1optimizationVariables={u,xu}; 57 | pars.P2optimizationVariables={d,xd}; 58 | pars.P1objective=Ju; 59 | pars.P2objective=-Jd; 60 | pars.P1constraints={xu==u+d,d>-.1}; 61 | pars.P2constraints={xd==u+d,d>-.1}; 62 | pars.outputExpressions=struct('u',u,'d',d,'xu',xu,'xd',xd); 63 | 64 | pars.scaleCost=1e-3; 65 | 66 | %pars.desiredDualityGap=1e-10; 67 | pars.classname='tmp'; 68 | pars.debugConvergence=false; 69 | pars.solverVerboseLevel=3; 70 | 71 | classname=class2equilibriumLatentCS(pars); 72 | 73 | obj=feval(classname); 74 | 75 | setV_u(obj,1); 76 | setV_d(obj,1); 77 | setV_xu(obj,1); 78 | setV_xd(obj,-1); 79 | sol=solve(obj), 80 | out=getOutputs(obj), 81 | 82 | clear all 83 | %% min_u max_d (x-1)^2-2*d^2 with x=u+d; 84 | % with latent variables 85 | 86 | Tvariable u; 87 | Tvariable d; 88 | Tvariable x; 89 | 90 | pars.latentVariables={x}; 91 | pars.latentConstraints={x==u+d}; 92 | 93 | J=(x-1).^2-2*d.^2; 94 | 95 | pars.P1optimizationVariables={u}; 96 | pars.P2optimizationVariables={d}; 97 | pars.P1objective=J; 98 | pars.P2objective=-J; 99 | pars.P1constraints={d>-.1}; 100 | pars.P2constraints={d>-.1}; 101 | pars.outputExpressions=struct('u',u,'d',d,'x',x); 102 | 103 | pars.scaleCost=1e-3; 104 | 105 | %pars.desiredDualityGap=1e-10; 106 | pars.classname='tmp'; 107 | pars.debugConvergence=false; 108 | pars.solverVerboseLevel=3; 109 | 110 | classname=class2equilibriumLatentCS(pars); 111 | 112 | obj=feval(classname); 113 | 114 | setV_u(obj,1); 115 | setV_d(obj,1); 116 | setV_x(obj,1); 117 | sol=solve(obj), 118 | out=getOutputs(obj), 119 | 120 | -------------------------------------------------------------------------------- /examples/testing/testSensitivity.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all; 7 | !rm -fr @tmp* tmp*; 8 | 9 | %% Unconstrained 10 | 11 | Tvariable P [3,3]; 12 | Tvariable x [3]; 13 | 14 | J=x*(P*x); 15 | 16 | out=Tvars2optimizeCS('objective',J,... 17 | 'optimizationVariables',{x},... 18 | 'sensitivityVariables',{x},... 19 | 'constraints',{}) 20 | oExpr={J,x,full(out.Hess),full(out.Du1),full(out.DfDu1),full(out.D2fDu1)}; 21 | 22 | classname=cmex2optimizeCS('classname','tmp_test',... 23 | 'objective',J,... 24 | 'optimizationVariables',{x},... 25 | 'sensitivityVariables',{x},... 26 | 'constraints',{},... 27 | 'parameters',{P},... 28 | 'outputExpressions',oExpr,... 29 | 'addEye2Hessian',1e-10,... 30 | 'umfpack',false,... 31 | 'solverVerboseLevel',3); 32 | obj=feval(classname); 33 | 34 | P=rand(3); 35 | P=P'*P; 36 | setP_P(obj,P); 37 | setV_x(obj,rand(3,1)) 38 | 39 | mu0=1; 40 | maxIter=200; 41 | saveIter=0; 42 | [status,iter,time]=solve(obj,mu0,int32(maxIter),int32(saveIter)); 43 | 44 | [oExpr{:}]=getOutputs(obj); 45 | 46 | oExpr{:},2*P, 47 | 48 | 49 | clear all; 50 | 51 | %% Constrained 52 | 53 | Tvariable P [3,3]; 54 | Tvariable x [3]; 55 | Tvariable z [3]; 56 | 57 | J=x*(P*x); 58 | 59 | out=Tvars2optimizeCS('objective',J,... 60 | 'optimizationVariables',{x,z},... 61 | 'sensitivityVariables',{z},... 62 | 'constraints',{x==z,x>=1}) 63 | oExpr={J,x,z,full(out.Hess),full(out.Du1),full(out.DfDu1),full(out.D2fDu1)}; 64 | 65 | classname=class2optimizeCS('classname','tmp_test',... 66 | 'objective',J,... 67 | 'optimizationVariables',{x,z},... 68 | 'sensitivityVariables',{z},... 69 | 'constraints',{x==z,z<=10},... 70 | 'parameters',{P},... 71 | 'outputExpressions',oExpr,... 72 | 'addEye2Hessian',1e-10,... 73 | 'umfpack',false,... 74 | 'solverVerboseLevel',3); 75 | obj=feval(classname); 76 | 77 | P=rand(3); 78 | P=P'*P; 79 | setP_P(obj,P); 80 | setV_x(obj,5+rand(3,1)) 81 | setV_z(obj,5+rand(3,1)) 82 | 83 | mu0=1; 84 | maxIter=200; 85 | saveIter=0; 86 | [status,iter,time]=solve(obj,mu0,int32(maxIter),int32(saveIter)); 87 | 88 | [oExpr{:}]=getOutputs(obj); 89 | 90 | oExpr{:},2*P, 91 | 92 | -------------------------------------------------------------------------------- /examples/testing/testSet.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all 7 | 8 | !rm -rf @tmp* tmp* 9 | 10 | n1=3%0 11 | n2=4%0 12 | n3=2 13 | 14 | 15 | %profile on 16 | t0=clock; 17 | fprintf('Creating code... '); 18 | createGateway('template','testSet_raw.c',... 19 | 'callType','include',... 20 | 'compileGateways',true,... 21 | 'preprocessParameters',{n1,n2,n3},... 22 | 'verboseLevel',1); 23 | fprintf('done creating code (%.2f sec)\n',etime(clock,t0)); 24 | %profile viewer 25 | 26 | for i=1:3 27 | A=rand(n1,n2,n3); 28 | B=rand(n1,n2,n3); 29 | C=rand(n1,n2,n3); 30 | 31 | ABC=cat(1,A,B,C); 32 | 33 | AB=ABC(1:2*n1,:,:); 34 | BC=ABC(n1+1:end,:,:); 35 | 36 | 37 | t0=clock; 38 | DD=-AB+BC; 39 | fprintf(' Matlab plus(%d): %.1f us\n',i,1e6*etime(clock,t0)) 40 | 41 | t0=clock; 42 | D=tmpC_testSet(A,B,C); 43 | fprintf(' csparse(%d) : %.1f us\n',i,1e6*etime(clock,t0)) 44 | end 45 | 46 | if ~isequal(DD,D) 47 | error('mismatch %f\n',norm(DD(:)-D(:))) 48 | end 49 | 50 | -------------------------------------------------------------------------------- /examples/testing/testSet_raw.c: -------------------------------------------------------------------------------- 1 | /**********************************/ 2 | /* Definition of Matlab's gateway */ 3 | /**********************************/ 4 | 5 | #ifdef createGateway 6 | 7 | MEXfunction tmpC_testSet 8 | Cfunction tmpC_testSet_raw 9 | include testSet_raw.c 10 | 11 | inputs 12 | double A[n1,n2,n3] 13 | double B[n1,n2,n3] 14 | double C[n1,n2,n3] 15 | 16 | outputs 17 | double D[n1*2,n2,n3] 18 | 19 | 20 | preprocess(n1,n2,n3) 21 | 22 | code=csparse(); 23 | 24 | Tvariable A [n1,n2,n3]; 25 | Tvariable B [n1,n2,n3]; 26 | Tvariable C [n1,n2,n3]; 27 | 28 | Tvariable ABC [3*n1,n2,n3]; 29 | 30 | AB=ABC(1:2*n1,:,:); 31 | BC=ABC(n1+1:end,:,:); 32 | 33 | declareSet(code,ABC(1:n1,:,:),'setA'); 34 | declareSet(code,ABC(n1+1:2*n1,:,:),'setB'); 35 | declareSet(code,ABC(2*n1+1:3*n1,:,:),'setC'); 36 | declareGet(code,-AB+BC,'getSum'); 37 | 38 | fprintf('After Set/Get declarations\n'); 39 | disp(code) 40 | 41 | compile2C(code,inf,inf,'tmpC_testSet_CS.c'); 42 | 43 | fprintf('After Compile2C\n'); 44 | disp(code) 45 | #endif 46 | 47 | #include "tmpC_testSet_CS.c" 48 | 49 | void tmpC_testSet_raw(const double *A, 50 | const double *B, 51 | const double *C, 52 | double *D, 53 | mwSize n1, 54 | mwSize n2, 55 | mwSize n3) 56 | { 57 | clock_t dt=clock(); 58 | 59 | setA(A); 60 | setB(B); 61 | setC(C); 62 | 63 | getSum(D); 64 | 65 | dt=clock()-dt; 66 | mexPrintf(" testset_raw (sets+compute+get): %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 67 | 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /examples/testing/testSubsref.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | clear all 7 | 8 | !rm -f tmpC* 9 | 10 | N=6; 11 | 12 | profile on 13 | t0=clock; 14 | fprintf('Creating code... '); 15 | createGateway('template','testSubsref_raw.c',... 16 | 'callType','include',... 17 | 'compileGateways',true,... 18 | 'compilerOptimization','-O0',... 19 | 'preprocessParameters',{N},... 20 | 'verboseLevel',2); 21 | fprintf('done creating code (%.2f sec)\n',etime(clock,t0)); 22 | profile viewer 23 | 24 | t=cumsum(rand(N,1)); 25 | dt1=1./(t(2:end)-t(1:end-1)); 26 | X=rand(N,1); 27 | 28 | fprintf('Matlab:\n'); 29 | t0=clock; 30 | DX1=(X(2:end)-X(1:end-1)).*dt1; % velocity 31 | DDX1=(DX1(2:end)-DX1(1:end-1)).*dt1(1:end-1); % acceleration 32 | fprintf(' %.1f us\n',1e6*etime(clock,t0)) 33 | DX1, 34 | DDX1, 35 | 36 | fprintf('C code:\n'); 37 | t0=clock; 38 | [DX,DDX]=tmpC_testSubsref(X,dt1); 39 | fprintf(' csparse: %.1f us\n',1e6*etime(clock,t0)) 40 | DX, 41 | DDX, 42 | 43 | if ~isequal(DX,DX1) 44 | error('mismatch %f\n',norm(DX(:)-DX1(:))) 45 | end 46 | 47 | if ~isequal(DDX,DDX1) 48 | error('mismatch %f\n',norm(DDX(:)-DDX1(:))) 49 | end 50 | 51 | -------------------------------------------------------------------------------- /examples/testing/testSubsref_raw.c: -------------------------------------------------------------------------------- 1 | /**********************************/ 2 | /* Definition of Matlab's gateway */ 3 | /**********************************/ 4 | 5 | #ifdef createGateway 6 | 7 | MEXfunction tmpC_testSubsref 8 | Cfunction tmpC_testSubsref_raw 9 | include testSubsref_raw.c 10 | 11 | inputs 12 | double X[N] 13 | double dt1[N-1] 14 | 15 | outputs 16 | double DX[N-1] 17 | double DDX[N-2] 18 | 19 | 20 | preprocess(N) 21 | 22 | code=csparse(); 23 | 24 | Tvariable X N; 25 | Tvariable dt1 N-1; 26 | 27 | DX=(X(2:end)-X(1:end-1)).*dt1; % velocity 28 | DDX=(DX(2:end)-DX(1:end-1)).*dt1(1:end-1); % acceleration 29 | 30 | declareSet(code,X,'setX'); 31 | declareSet(code,dt1,'setDt1'); 32 | declareGet(code,DX,'getDX'); 33 | declareGet(code,DDX,'getDDX'); 34 | 35 | fprintf('After Set/Get declarations\n'); 36 | disp(code) 37 | 38 | compile2C(code,inf,inf,'tmpC_testSubsref_CS.c','tmpC_testSubsref_CS.h','tmpC_testSubsref_CS.log','',0); 39 | 40 | fprintf('After Compile2C\n'); 41 | disp(code) 42 | #endif 43 | 44 | #include "tmpC_testSubsref_CS.c" 45 | 46 | void tmpC_testSubsref_raw(const double *X, 47 | const double *dt1, 48 | double *DX, 49 | double *DDX, 50 | mwSize N) 51 | { 52 | 53 | setX(X); 54 | setDt1(dt1); 55 | 56 | clock_t dt=clock(); 57 | 58 | getDX(DX); 59 | getDDX(DDX); 60 | 61 | dt=clock()-dt; 62 | mexPrintf(" testsum_raw: %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 63 | 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /examples/testing/testSum.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | !rm -f tmpC* 7 | 8 | clear all 9 | 10 | n1=30 11 | n2=40 12 | n3=2 13 | 14 | 15 | profile on 16 | t0=clock; 17 | fprintf('Creating code... '); 18 | createGateway('template','testSum_raw.c',... 19 | 'callType','include',... 20 | 'compileGateways',true,... 21 | 'preprocessParameters',{n1,n2,n3},... 22 | 'verboseLevel',2); 23 | fprintf('done creating code (%.2f sec)\n',etime(clock,t0)); 24 | profile viewer 25 | 26 | for i=1:3 27 | A=rand(n1,n2,n3); 28 | B=rand(n1,n2,n3); 29 | C=rand(n1,n2,n3); 30 | 31 | t0=clock; 32 | DD=-A+B+C; 33 | fprintf(' Matlab plus(%d): %.1f us\n',i,1e6*etime(clock,t0)) 34 | 35 | t0=clock; 36 | D=tmpC_testSum(A,B,C); 37 | fprintf(' csparse(%d) : %.1f us\n',i,1e6*etime(clock,t0)) 38 | end 39 | 40 | if ~isequal(DD,D) 41 | error('mismatch %f\n',norm(DD(:)-D(:))) 42 | end 43 | 44 | -------------------------------------------------------------------------------- /examples/testing/testSum_raw.c: -------------------------------------------------------------------------------- 1 | /**********************************/ 2 | /* Definition of Matlab's gateway */ 3 | /**********************************/ 4 | 5 | #ifdef createGateway 6 | 7 | MEXfunction tmpC_testSum 8 | Cfunction tmpC_testSum_raw 9 | include testSum_raw.c 10 | 11 | inputs 12 | double A[n1,n2,n3] 13 | double B[n1,n2,n3] 14 | double C[n1,n2,n3] 15 | 16 | outputs 17 | double D[n1,n2,n3] 18 | 19 | 20 | preprocess(n1,n2,n3) 21 | 22 | code=csparse(); 23 | 24 | Tvariable A [n1,n2,n3]; 25 | Tvariable B [n1,n2,n3]; 26 | Tvariable C [n1,n2,n3]; 27 | 28 | declareSet(code,A,'setA'); 29 | declareSet(code,B,'setB'); 30 | declareSet(code,C,'setC'); 31 | declareGet(code,-A+B+C,'getSum'); 32 | 33 | fprintf('After Set/Get declarations\n'); 34 | disp(code) 35 | 36 | compile2C(code,inf,inf,'tmpC_testSum_CS.c'); 37 | 38 | fprintf('After Compile2C\n'); 39 | disp(code) 40 | #endif 41 | 42 | #include "tmpC_testSum_CS.c" 43 | 44 | void tmpC_testSum_raw(const double *A, 45 | const double *B, 46 | const double *C, 47 | double *D, 48 | mwSize n1, 49 | mwSize n2, 50 | mwSize n3) 51 | { 52 | clock_t dt=clock(); 53 | 54 | setA(A); 55 | setB(B); 56 | setC(C); 57 | 58 | getSum(D); 59 | 60 | dt=clock()-dt; 61 | mexPrintf(" testsum_raw (sets+compute+get): %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 62 | 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /examples/testing/testTprod.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | !rm -f tmpC* 7 | 8 | clear all 9 | 10 | n1=30 11 | n2=20 12 | n3=20 13 | 14 | profile on 15 | t0=clock; 16 | fprintf('Creating code... '); 17 | createGateway('template','testTprod_raw.c',... 18 | 'callType','include',... 19 | 'compileGateways',true,... 20 | 'preprocessParameters',{n1,n2,n3},... 21 | 'verboseLevel',2); 22 | fprintf('done creating code (%.2f sec)\n',etime(clock,t0)); 23 | profile viewer 24 | 25 | A=rand(n1,n2,n3); 26 | B=rand(n1,n2,n3); 27 | C=rand(n1,n2,n3); 28 | 29 | fprintf('Matlab:\n'); 30 | ind=[-1,1,2]; 31 | DD=mytprod(A,ind,B,ind,C,ind); 32 | t0=clock; 33 | DD=mytprod(A,ind,B,ind,C,ind); 34 | fprintf(' mytprod: %.1f us\n',1e6*etime(clock,t0)) 35 | t0=clock; 36 | DD=mytprod(A,ind,B,ind,C,ind); 37 | fprintf(' mytprod: %.1f us\n',1e6*etime(clock,t0)) 38 | 39 | fprintf('C code:\n'); 40 | D=tmpC_testTprod(A,B,C); 41 | t0=clock; 42 | D=tmpC_testTprod(A,B,C); 43 | fprintf(' csparse: %.1f us\n',1e6*etime(clock,t0)) 44 | 45 | if ~isequal(DD,D) 46 | error('mismatch %f\n',norm(DD(:)-D(:))) 47 | end 48 | 49 | -------------------------------------------------------------------------------- /examples/testing/testTprod2.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | !rm -f tmpC* 7 | 8 | clear all 9 | 10 | N=4 11 | 12 | profile on 13 | t0=clock; 14 | fprintf('Creating code... '); 15 | createGateway('template','testTprod2_raw.c',... 16 | 'callType','include',... 17 | 'compileGateways',true,... 18 | 'preprocessParameters',{N},... 19 | 'verboseLevel',2); 20 | fprintf('done creating code (%.2f sec)\n',etime(clock,t0)); 21 | profile viewer 22 | 23 | A=rand(N,N); 24 | 25 | fprintf('Matlab:\n'); 26 | t0=clock; 27 | eye_21=eye(N); 28 | plus_26=eye_21(2:end,:)-eye_21(1:end-1,:) 29 | plus_30=plus_26(2:end,:)-plus_26(1:end-1,:) 30 | tprod_37=tprod(plus_30,[-1,1],plus_30,[-1,2]) 31 | fprintf(' mytprod: %.1f us\n',1e6*etime(clock,t0)) 32 | 33 | fprintf('C code:\n'); 34 | [p26,p30,t37]=tmpC_testTprod2(A) 35 | t0=clock; 36 | 37 | [p26,p30,t37]=tmpC_testTprod2(A) 38 | fprintf(' csparse: %.1f us\n',1e6*etime(clock,t0)) 39 | 40 | if ~isequal(tprod_37,t37) 41 | error('mismatch %f\n',norm(tprod_37(:)-t37(:))) 42 | end 43 | 44 | -------------------------------------------------------------------------------- /examples/testing/testTprod2_raw.c: -------------------------------------------------------------------------------- 1 | /**********************************/ 2 | /* Definition of Matlab's gateway */ 3 | /**********************************/ 4 | 5 | #ifdef createGateway 6 | 7 | MEXfunction tmpC_testTprod2 8 | Cfunction tmpC_testTprod2_raw 9 | include testTprod2_raw.c 10 | 11 | inputs 12 | double A[N,N] 13 | 14 | outputs 15 | double plus_26[N-1,N] 16 | double plus_30[N-2,N] 17 | double tprod_37[N,N] 18 | 19 | 20 | preprocess(N) 21 | 22 | code=csparse(); 23 | 24 | eye_21=Teye([N,N]); 25 | plus_26=eye_21(2:end,:)-eye_21(1:end-1,:) 26 | plus_30=plus_26(2:end,:)-plus_26(1:end-1,:) 27 | tprod_37=tprod(plus_30,[-1,1],plus_30,[-1,2]) 28 | 29 | declareGet(code,full(plus_26),'get_plus_26'); 30 | declareGet(code,full(plus_30),'get_plus_30'); 31 | declareGet(code,full(tprod_37),'get_tprod_37'); 32 | 33 | 34 | compile2C(code,inf,inf,'tmpC_testTprod2_CS.c'); 35 | code 36 | 37 | #endif 38 | 39 | #include "tmpC_testTprod2_CS.c" 40 | 41 | void tmpC_testTprod2_raw(const double *A, 42 | double *plus_26, 43 | double *plus_30, 44 | double *tprod_37, 45 | mwSize N) 46 | { 47 | 48 | clock_t dt=clock(); 49 | 50 | get_plus_26(plus_26); 51 | get_plus_30(plus_30); 52 | get_tprod_37(tprod_37); 53 | 54 | dt=clock()-dt; 55 | mexPrintf(" testTprod2_raw: %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 56 | 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /examples/testing/testTprod_raw.c: -------------------------------------------------------------------------------- 1 | /**********************************/ 2 | /* Definition of Matlab's gateway */ 3 | /**********************************/ 4 | 5 | #ifdef createGateway 6 | 7 | MEXfunction tmpC_testTprod 8 | Cfunction tmpC_testTprod_raw 9 | include testTprod_raw.c 10 | 11 | inputs 12 | double A[n1,n2,n3] 13 | double B[n1,n2,n3] 14 | double C[n1,n2,n3] 15 | 16 | outputs 17 | double D[n2,n3] 18 | 19 | 20 | preprocess(n1,n2,n3) 21 | 22 | code=csparse(); 23 | 24 | Tvariable A [n1,n2,n3]; 25 | Tvariable B [n1,n2,n3]; 26 | Tvariable C [n1,n2,n3]; 27 | 28 | declareSet(code,A,'setA'); 29 | declareSet(code,B,'setB'); 30 | declareSet(code,C,'setC'); 31 | ind=[-1,1,2]; 32 | declareGet(code,tprod(A,ind,B,ind,C,ind),'getTprod'); 33 | 34 | compile2C(code,inf,inf,'tmpC_testTprod_CS.c'); 35 | 36 | #endif 37 | 38 | #include "tmpC_testTprod_CS.c" 39 | 40 | void tmpC_testTprod_raw(const double *A, 41 | const double *B, 42 | const double *C, 43 | double *D, 44 | mwSize n1, 45 | mwSize n2, 46 | mwSize n3) 47 | { 48 | 49 | setA(A); 50 | setB(B); 51 | setC(C); 52 | 53 | clock_t dt=clock(); 54 | 55 | getTprod(D); 56 | 57 | dt=clock()-dt; 58 | mexPrintf(" testTprod_raw: %.1lf us\n",dt/(double)CLOCKS_PER_SEC*1e6); 59 | 60 | } 61 | 62 | 63 | -------------------------------------------------------------------------------- /examples/testing/testUMFPACK.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "umfpack.h" 3 | 4 | double *null = (double *) NULL ; 5 | void *Symbolic[1],*Numeric[1]; 6 | double Ax0[9]; 7 | double *Ax[1]={Ax0}; 8 | int Ap0[4]={0,3,6,9}; 9 | int *Ap[1]={Ap0}; 10 | int Ai0[9]={0,1,2,0,1,2,0,1,2}; 11 | int *Ai[1]={Ai0}; 12 | double b0[3]; 13 | double *b[1]={b0}; 14 | double x0[3]; 15 | double *x[1]={x0}; 16 | 17 | int main (void) 18 | { 19 | #ifndef BB 20 | Ax[0][0]=0; 21 | Ax[0][1]=1; 22 | Ax[0][2]=2; 23 | Ax[0][3]=3; 24 | Ax[0][4]=4; 25 | Ax[0][5]=5; 26 | Ax[0][6]=6; 27 | Ax[0][7]=4; 28 | Ax[0][8]=5; 29 | b[0][0]=9; 30 | b[0][1]=10; 31 | b[0][2]=12; 32 | 33 | #endif 34 | (void)umfpack_di_symbolic(3,3,Ap[0],Ai[0],Ax[0],&Symbolic[0],null,null); 35 | (void)umfpack_di_numeric(Ap[0],Ai[0],Ax[0],Symbolic[0],&Numeric[0],null,null); 36 | umfpack_di_free_symbolic(&Symbolic[0]); 37 | 38 | {int atomicID=0; 39 | /* b[atomicID][0]=m[9]; */ 40 | /* b[atomicID][1]=m[10]; */ 41 | /* b[atomicID][2]=m[11]; */ 42 | (void)umfpack_di_solve(UMFPACK_A,Ap[atomicID],Ai[atomicID],Ax[atomicID],x[atomicID],b[atomicID],Numeric,null,null); 43 | } 44 | (void) umfpack_di_solve (UMFPACK_A, Ap[0], Ai[0], Ax[0], x[0], b[0], Numeric[0], null, null) ; 45 | umfpack_di_free_numeric (&Numeric[0]) ; 46 | 47 | int n=sizeof(Ap0)/sizeof(int)-1; 48 | for (int i = 0 ; i < n ; i++) printf ("b [%d] = %g, x [%d] = %g\n", i, b[0][i],i, x[0] [i]) ; 49 | return (0) ; 50 | } 51 | -------------------------------------------------------------------------------- /install_tenscalc.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | fprintf('Seeting up path:\n'); 7 | home=[fileparts(which('install_tenscalc')),'/lib']; 8 | folders={home;[home,'/csparse']}; 9 | 10 | s=path; 11 | if ispc 12 | old=regexp(s,'[^;]*(tenscalc.lib.csparse|tenscalc.lib)[^/;]*','match'); 13 | else 14 | old=regexp(s,'[^:]*(tenscalc.lib.csparse|tenscalc.lib)[^/:]*','match'); 15 | end 16 | if ~isempty(old) 17 | fprintf(' removing from path:\n'); 18 | disp(old') 19 | rmpath(old{:}) 20 | end 21 | 22 | fprintf(' adding to path:\n'); 23 | addpath(folders{:}); 24 | disp(folders) 25 | 26 | fprintf(' saving path...'); 27 | try 28 | savepath; 29 | catch me 30 | fprintf('ATTENTION: unable to save path. This was probably caused because of insufficient permissions. Either change the permissions of your ''matlabroot'' folder or add following strings to the matlab path:'); 31 | disp(folders) 32 | rethrow(me) 33 | end 34 | fprintf('done with path!\n'); 35 | 36 | 37 | fprintf('Compiling...\n'); 38 | compileInstructionsTable; 39 | fprintf('done!\n'); 40 | 41 | pth=findSuiteSparse(); 42 | if isempty(pth.include_paths) 43 | fprintf('The umfpack not installed or not in the path, ''umfpack'' option will not be available. This should not be a problem. However, if you have umfpack installed add ''SuiteSparse/UMFPACK/MATLAB/'' to your matlab path\n'); 44 | else 45 | fprintf('umfpack found at \"%s\"\n',pth) 46 | end 47 | -------------------------------------------------------------------------------- /lib/@Tcalculus/checkTprodSizes.m: -------------------------------------------------------------------------------- 1 | function [tprod_size,sums_size]=checkTprodSizes(varargin) 2 | % This file is part of Tencalc. 3 | % 4 | % Copyright (C) 2012-21 The Regents of the University of California 5 | % (author: Dr. Joao Hespanha). All rights reserved. 6 | % Copyright 2012-2017 Joao Hespanha 7 | 8 | if mod(nargin,2) 9 | error('tprod: number of arguments must be even\n'); 10 | end 11 | 12 | tprod_size=[]; 13 | sums_size=[]; 14 | for i=1:2:nargin 15 | obj=varargin{i}; 16 | ind=varargin{i+1}; 17 | if ~isnumeric(ind) 18 | ind 19 | error('tprod: argument %d must be numeric\n',i+1); 20 | end 21 | osize=size(obj); 22 | 23 | if length(ind)~=length(osize) 24 | fprintf('tprod('); 25 | for i=1:2:nargin 26 | obj_=toCalculus(varargin{i}); 27 | ind_=varargin{i+1}; 28 | fprintf('M[%s],[%s],',index2str(size(obj_)),index2str(ind_)); 29 | end 30 | fprintf(')\n'); 31 | obj,ind 32 | error(['tprod requires each indice to have the same number of ' ... 33 | 'entries as the size of the corresponding object\n']) 34 | end 35 | 36 | for j=1:length(ind) 37 | if ind(j)>0 38 | if length(tprod_size)=ind(j) && tprod_size(ind(j))>0 ... 43 | && tprod_size(ind(j))~=osize(j) 44 | obj,tprod_size 45 | error(['incompatible sizes found in object ' ... 46 | '%d, dimension %d (%d~=%d)\n'],i,j, ... 47 | tprod_size(ind(j)),osize(j)); 48 | end 49 | tprod_size(ind(j))=osize(j); 50 | else 51 | if length(sums_size)<-ind(j) 52 | % pad with nan 53 | sums_size(end+1:-ind(j))=nan; 54 | end 55 | if length(sums_size)>=-ind(j) && sums_size(-ind(j))>0 ... 56 | && sums_size(-ind(j))~=osize(j) 57 | obj,sums_size 58 | error(['incompatible sizes found in object ' ... 59 | '%d, dimension %d (%d~=%d)\n'],i,j, ... 60 | sums_size(-ind(j)),osize(j)); 61 | end 62 | sums_size(-ind(j))=osize(j); 63 | end 64 | end 65 | end 66 | 67 | if any(isnan(tprod_size)) || any(isnan(sums_size)) 68 | tprod_size,sums_size 69 | error('tprod has no size for some indices/summations\n',i) 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /lib/@Tcalculus/precompute.m: -------------------------------------------------------------------------------- 1 | function varargout=precompute(varargin) 2 | % This file is part of Tencalc. 3 | % 4 | % Copyright (C) 2012-21 The Regents of the University of California 5 | % (author: Dr. Joao Hespanha). All rights reserved. 6 | 7 | maxNumel2ExpandConstants=2000; 8 | maxNnz2ExpandConstants=1000; 9 | 10 | varargout=varargin; 11 | 12 | for i=1:length(varargin) 13 | type=getType(varargin{i}); 14 | if ~isequal(type,'constant') && ~isequal(type,'zeros') && ~isequal(type,'ones') && getIsStatic(varargin{i}) 15 | osize=size(varargin{i}); 16 | if prod(osize)>maxNumel2ExpandConstants 17 | fprintf('precompute: not pre-computing constant [%s] with two many elements (numel = %d>%d)\n',index2str(osize),prod(osize),maxNumel2ExpandConstants); 18 | continue; 19 | end 20 | x=optimize4matlab(varargin{i}); 21 | ex=eval(str(x)); 22 | if 0%length(size(varargin{i}))>2 23 | fprintf('precompute: not pre-computing constant [%s] with dimension>=2 (numel = %d, nnz = %d)\n',index2str(size(x)),prod(size(x)),nnz(ex)); 24 | continue; 25 | end 26 | if nnz(ex)>maxNnz2ExpandConstants 27 | fprintf('precompute: not precomputing constant [%s] with too many non-zero elements (numel = %d, nnz = %d>%d)\n',index2str(size(x)),prod(size(x)),nnz(ex),maxNnz2ExpandConstants); 28 | continue; 29 | end 30 | %varargin{i} 31 | varargout{i}=Tconstant(ex,osize); 32 | fprintf('precompute: precomputing (osize: %s -> %s, nnz: %d)\n',index2str(osize),index2str(size(varargout{i})),nnz(ex)); 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/@Tcalculus/tprod_argin2operands.m: -------------------------------------------------------------------------------- 1 | function [tprod_size,sums_size,objs,inds]=tprod_argin2operands(varargin) 2 | % This file is part of Tencalc. 3 | % 4 | % Copyright (C) 2012-21 The Regents of the University of California 5 | % (author: Dr. Joao Hespanha). All rights reserved. 6 | 7 | if mod(nargin,2) 8 | error('tprod: number of arguments must be even\n'); 9 | end 10 | 11 | tprod_size=[]; 12 | sums_size=[]; 13 | objs=cell(nargin/2,1); 14 | inds=cell(nargin/2,1); 15 | 16 | for i=1:2:nargin 17 | objs{(i-1)/2+1}=toCalculus(varargin{i}); 18 | ind=varargin{i+1}; 19 | 20 | % if any(diff(sort(ind))==0) 21 | % ind 22 | % warning('currently tprod does not support repeated indices: ind(%d)=[%s]\n',... 23 | % (i+1)/2,index2str(ind)); 24 | % end 25 | 26 | if ~isnumeric(ind) 27 | ind 28 | error('tprod: argument %d must be numeric\n',i+1); 29 | end 30 | if isempty(ind) 31 | % make empty indices uniform to make sure (my)isequal 32 | % works when compaaring the indices 33 | inds{(i-1)/2+1}=[]; 34 | else 35 | inds{(i-1)/2+1}=ind; 36 | end 37 | osize=size(objs{(i-1)/2+1}); 38 | 39 | if length(ind)~=length(osize) 40 | osize 41 | ind 42 | error(['tprod requires each indice to have the same number of ' ... 43 | 'entries as the size of the corresponding object\n']) 44 | end 45 | 46 | for j=1:length(ind) 47 | if ind(j)>0 48 | if length(tprod_size)=ind(j) && tprod_size(ind(j))>0 ... 53 | && tprod_size(ind(j))~=osize(j) 54 | objs{(i-1)/2+1},tprod_size 55 | error(['incompatible sizes found in object ' ... 56 | '%d, dimension %d (%d~=%d)\n'],(i+1)/2,j, ... 57 | tprod_size(ind(j)),osize(j)); 58 | end 59 | tprod_size(ind(j))=osize(j); 60 | else 61 | if length(sums_size)<-ind(j) 62 | % pad with nan 63 | sums_size(end+1:-ind(j))=nan; 64 | end 65 | if length(sums_size)>=-ind(j) && sums_size(-ind(j))>0 ... 66 | && sums_size(-ind(j))~=osize(j) 67 | objs{(i-1)/2+1},sums_size 68 | error(['incompatible sizes found in object ' ... 69 | '%d, dimension %d (%d~=%d)\n'],(i+1)/2,j, ... 70 | sums_size(-ind(j)),osize(j)); 71 | end 72 | sums_size(-ind(j))=osize(j); 73 | end 74 | end 75 | end 76 | 77 | if any(isnan(tprod_size)) || any(isnan(sums_size)) 78 | tprod_size,sums_size 79 | error('tprod has no size for some indices/summations\n',i) 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /lib/@csparse/COPYRIGHT.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tencalc. 3 | 4 | Copyright (C) 2012-21 The Regents of the University of California 5 | (author: Dr. Joao Hespanha). All rights reserved. 6 | */ 7 | -------------------------------------------------------------------------------- /lib/@csparse/COPYRIGHT.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | -------------------------------------------------------------------------------- /lib/@csparse/private/loadCSparse.m: -------------------------------------------------------------------------------- 1 | function [osize,subscripts,values,matrix]=loadCSparse(filename_subscripts,filename_values,ignoremagic) 2 | % [osize,subscripts,values,matrix]=loadCSparse(filename_subscripts,filename_values) 3 | % 4 | % Load a sparse tensor saved by @csparse generated code. 5 | % 6 | % Inputs: 7 | % 8 | % filename_subscripts - filename with the subscripts of the 9 | % nonzero entries 10 | % filename_values - filename with the values of the 11 | % nonzero entries 12 | % 13 | % Outputs: 14 | % 15 | % osize - dimension of the sparse tensor 16 | % subscripts - int64-valued array with the subscripts of the 17 | % nonzero entries, with one row per dimension and 18 | % one column per nonzero entry 19 | % values - double-valued array with the values of the nonzero entries 20 | % matrix (optional) - sparse matrix (only possible if the tensor 21 | % is two dimensional (matrix) 22 | % 23 | % This file is part of Tencalc. 24 | % 25 | % Copyright (C) 2012-21 The Regents of the University of California 26 | % (author: Dr. Joao Hespanha). All rights reserved. 27 | 28 | if nargin<3 29 | ignoremagic=false; 30 | end 31 | 32 | osize=nan; 33 | subscripts=nan; 34 | values=nan; 35 | matrix=nan; 36 | 37 | fd1=fopen(filename_subscripts,'r'); 38 | if fd1<0 39 | fprintf(' loadCsparse: cannot open subscripts file "%s" (fd=%d)\n',filename_subscripts,fd1) 40 | return 41 | end 42 | 43 | fd2=fopen(filename_values,'r'); 44 | if fd2<0 45 | fprintf(' loadCsparse: cannot open values file "%s" (fd=%d)\n',filename_values,fd2) 46 | fclose(fd1); 47 | return 48 | end 49 | 50 | magic1=fread(fd1,1,'int64=>int64'); 51 | magic2=fread(fd2,1,'int64=>int64'); 52 | 53 | if ~ignoremagic && magic1~=magic2 54 | fprintf(' loadCsparse: mismatch between magic numbers in subscripts "%s" and values "%s" files (%d ~= %d)\n',filename_subscripts,filename_values,magic1,magic2) 55 | fclose(fd1); 56 | fclose(fd2); 57 | return 58 | end 59 | 60 | nDim=fread(fd1,1,'int32=>int32'); 61 | osize=fread(fd1,nDim,'int64=>int64'); 62 | nnz=fread(fd1,1,'int64=>int64'); 63 | subscripts=fread(fd1,[nDim,nnz],'int64=>int64'); 64 | values=fread(fd2,[nnz,1],'double=>double'); 65 | 66 | fclose(fd1); 67 | fclose(fd2); 68 | 69 | if size(subscripts,2)~=length(values) 70 | fprintf(' loadCsparse: mismatch between subscripts file "%s" and values file "%s"\n',... 71 | filename_subscripts,filename_values); 72 | osize=nan; 73 | return 74 | end 75 | 76 | if nargout>=3 77 | while length(osize)<2 78 | osize(end+1)=1; 79 | subscripts=[subscripts;ones(1,size(subscripts,2),'int64')]; 80 | end 81 | if length(osize)==2 82 | matrix=sparse(double(subscripts(1,:)),double(subscripts(2,:)),values,double(osize(1)),double(osize(2))); 83 | else 84 | osize 85 | error('can only return sparse 2-dimensional matrices'); 86 | end 87 | end 88 | end 89 | -------------------------------------------------------------------------------- /lib/@csparse/private/mat2str_compact.m: -------------------------------------------------------------------------------- 1 | function str=mat2str_compact(mat) 2 | % This file is part of Tencalc. 3 | % 4 | % Copyright (C) 2012-21 The Regents of the University of California 5 | % (author: Dr. Joao Hespanha). All rights reserved. 6 | 7 | msize=size(mat); 8 | 9 | if nnz(mat)==0 10 | %mat=full(mat); 11 | str=sprintf('zeros(%s)',index2str(msize)); 12 | elseif all(mat==1,'all') 13 | str=sprintf('ones(%s)',index2str(msize)); 14 | elseif length(msize)==2 & msize(2)==1 & mat(2:end)==mat(1:end-1)+1 15 | mat=full(mat); 16 | str=sprintf('((%d:%d)'')',mat(1),mat(end)); 17 | elseif length(msize)==2 & msize(1)==1 & mat(2:end)==mat(1:end-1)+1 18 | mat=full(mat); 19 | str=sprintf('(%d:%d)',mat(1),mat(end)); 20 | elseif length(msize)==2 & msize(2)==1 & mat(2:end)==mat(1:end-1)-1 21 | mat=full(mat); 22 | str=sprintf('((%d:-1:%d)'')',mat(1),mat(end)); 23 | elseif length(msize)==2 & msize(1)==1 & mat(2:end)==mat(1:end-1)-1 24 | mat=full(mat); 25 | str=sprintf('(%d:-1:%d)',mat(1),mat(end)); 26 | else 27 | if length(size(mat))<=2 28 | str=mat2str(mat); 29 | else 30 | str=serialize(mat); 31 | % remove final ';' 32 | str(end)=[]; 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/@csparse/private/toporder.m: -------------------------------------------------------------------------------- 1 | function node_order = toporder(adjmat) 2 | % node_order = toporder(adjmat) 3 | % 4 | % Computes a topological ordering of the nodes for a directed 5 | % acyclic graph defined by its adjacency matrix. 6 | % 7 | % Adapted from: 8 | % Transitive reduction of a DAG by Frederik Gwinner 9 | % Copyright (c) 2011, Frederik Gwinner 10 | % All rights reserved. 11 | % Code covered by the BSD License 12 | 13 | % Check whether adjacency matrix is square 14 | V=size(adjmat,1); 15 | 16 | % % get topological ordering of the nodes 17 | node_indices = 1:V; 18 | node_order=[]; 19 | start_nodes = node_indices(sum(adjmat,1)==0);%nodes having no incoming edges 20 | sort_adj=adjmat; % copy of the initial matrix 21 | while ~isempty(start_nodes) 22 | n = start_nodes(1); 23 | start_nodes(1)=[]; 24 | node_order=[node_order,n]; 25 | successors = node_indices(logical(adjmat(n,:))); 26 | for mi=1:numel(successors) 27 | m=successors(mi); 28 | sort_adj(n,m)=0; 29 | if sum(sort_adj(:,m))==0 30 | start_nodes=[start_nodes,m]; 31 | end 32 | end 33 | end 34 | 35 | if sum(sum(sort_adj))~=0 36 | % if there's still an edge left, the graph must have 37 | % contained a cycle 38 | node_order=[]; 39 | end 40 | 41 | end -------------------------------------------------------------------------------- /lib/@csparse/sparsity_cat.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_cat(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'cat', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | dimension=getOne(obj.vectorizedOperations,'parameters',thisExp); 15 | 16 | %% Compute sparsity pattern 17 | subsY=zeros(length(osize),0,'uint64'); 18 | instrY=zeros(0,1); 19 | 20 | j=0; 21 | for i=1:length(operands) 22 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(i)); 23 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(i)); 24 | 25 | subsY=[subsY,[subsX(1:dimension-1,:);subsX(dimension,:)+j;subsX(dimension+1:end,:)]]; 26 | 27 | osize1=getOne(obj.vectorizedOperations,'osize',operands(i)); 28 | j=j+osize1(dimension); 29 | 30 | instrY=[instrY;instrX]; 31 | end 32 | 33 | % if isequal(osize,[16,40]) 34 | % error('cat G_z') 35 | % end 36 | 37 | % if isequal(osize,[40,40]) 38 | % error('cat WW') 39 | % end 40 | end 41 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_clp.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_clp(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'clp', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. For x >= 0, 6 | % clp(x,dx) = max { alpha >0 : x + alpha dx >= 0 } 7 | % 8 | % This file is part of Tencalc. 9 | % 10 | % Copyright (C) 2012-21 The Regents of the University of California 11 | % (author: Dr. Joao Hespanha). All rights reserved. 12 | 13 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 14 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 15 | 16 | subsY=zeros(0,1); 17 | 18 | %% Get instructions for operands 19 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 20 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(1)); 21 | 22 | subsdX=getOne(obj.vectorizedOperations,'subscripts',operands(2)); 23 | instrdX=getOne(obj.vectorizedOperations,'instructions',operands(2)); 24 | 25 | [kX,kdX]=ismember(subsX',subsdX','rows'); 26 | 27 | if any(~ismember(subsdX',subsX','rows')) 28 | error(['sparsity_clp: structurally zero values for x not allowed ' ... 29 | 'when dx is not structurally zero']) 30 | end 31 | 32 | %% Determine instructions for Y 33 | operands=[instrX(kX)';instrdX(kdX(kX))']; 34 | instrY=newInstruction(obj,obj.Itypes.I_clp,[],operands(:),thisExp); 35 | end 36 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_componentwise.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_componentwise(obj,thisExp,fun) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'compose' that completely fills the matrix. 4 | % 5 | % This file is part of Tencalc. 6 | % 7 | % Copyright (C) 2012-21 The Regents of the University of California 8 | % (author: Dr. Joao Hespanha). All rights reserved. 9 | 10 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 11 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 12 | 13 | subs1=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 14 | instr1=getOne(obj.vectorizedOperations,'instructions',operands(1)); 15 | 16 | if fun{1}(0) ~= 0 17 | subsY=memory2subscript(osize,1:prod(osize)); 18 | [lia,locb]=ismember(subsY',subs1','rows'); 19 | 20 | % fill matrix 21 | instrFull=nan(size(subsY,2),1); 22 | % non-zero 23 | instrFull(lia)=instr1(locb(lia)); 24 | if ~all(lia) 25 | % zero 26 | instrFull(~lia)=newInstructions(obj,obj.Itypes.I_load,num2cell(zeros(sum(~lia),1)),{[]},thisExp); 27 | end 28 | instr1=instrFull; 29 | else 30 | subsY=subs1; 31 | end 32 | 33 | cfun=double(regexprep(fun{2},'%s','\0')); 34 | 35 | instrY=newInstructions(obj,obj.Itypes.I_componentwise,{cfun},num2cell(instr1,2),thisExp); 36 | 37 | end 38 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_compose.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_compose(obj,thisExp,instruction) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'compose' that preserves sparsity. 4 | % 5 | % This file is part of Tencalc. 6 | % 7 | % Copyright (C) 2012-21 The Regents of the University of California 8 | % (author: Dr. Joao Hespanha). All rights reserved. 9 | 10 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 11 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 12 | 13 | subsY=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 14 | instr1=getOne(obj.vectorizedOperations,'instructions',operands(1)); 15 | 16 | instrY=newInstructions(obj,instruction,{[]},num2cell(instr1,2),thisExp); 17 | end -------------------------------------------------------------------------------- /lib/@csparse/sparsity_compose_full.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_compose_full(obj,thisExp,instruction) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'compose' that completely fills the matrix. 4 | % 5 | % This file is part of Tencalc. 6 | % 7 | % Copyright (C) 2012-21 The Regents of the University of California 8 | % (author: Dr. Joao Hespanha). All rights reserved. 9 | 10 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 11 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 12 | 13 | subs1=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 14 | instr1=getOne(obj.vectorizedOperations,'instructions',operands(1)); 15 | 16 | subsY=memory2subscript(osize,1:prod(osize)); 17 | [lia,locb]=ismember(subsY',subs1','rows'); 18 | 19 | % fill matrix 20 | instrFull=nan(size(subsY,2),1); 21 | % non-zero 22 | instrFull(lia)=instr1(locb(lia)); 23 | if ~all(lia) 24 | % zero 25 | instrFull(~lia)=newInstructions(obj,obj.Itypes.I_load,num2cell(zeros(sum(~lia),1)),{[]},thisExp); 26 | end 27 | instrY=newInstructions(obj,instruction,{[]},num2cell(instrFull,2),thisExp); 28 | end -------------------------------------------------------------------------------- /lib/@csparse/sparsity_det_ldl.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY]=sparsity_det_ldl(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'logdet_ldl', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % det_ldl(LDL): 8 | % 1) computes det(D) by 9 | % . computing the product of the main diagonal entries of LDL 10 | % 11 | % This file is part of Tencalc. 12 | % 13 | % Copyright (C) 2012-21 The Regents of the University of California 14 | % (author: Dr. Joao Hespanha). All rights reserved. 15 | 16 | verboseLevel=0; 17 | 18 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 19 | 20 | osizeLDL=getOne(obj.vectorizedOperations,'osize',operands(1)); 21 | subsLDL=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 22 | instrLDL=getOne(obj.vectorizedOperations,'instructions',operands(1)); 23 | if length(osizeLDL)~=2 || osizeLDL(1)~=osizeLDL(2) 24 | osizeLDL 25 | error('sparsity_det_ldl: in det_ldl(LDL), LDL must be a square (2D) matrix\n'); 26 | else 27 | n=double(osizeLDL(1)); 28 | end 29 | 30 | if verboseLevel>0 31 | t0=clock(); 32 | n0=instructionsTableHeight(); 33 | fprintf(' sparsity_det_ldl (%3d): LDL size=%-10s, nnz=%d\n',... 34 | thisExp,['[',index2str(osizeLDL),']'],length(instrLDL)); 35 | end 36 | 37 | % find instructions for diagonal 38 | k=find(subsLDL(1,:)==subsLDL(2,:)); % find diagonal elements 39 | instrX=instrLDL(k); 40 | 41 | subsY=zeros(0,1); 42 | if length(instrX)==n 43 | instrY=newInstruction(obj,obj.Itypes.I_sumprod,[length(instrX),1],instrX(:)',thisExp); 44 | else 45 | error('sparsity_det_ldl: LDL structurally singular in det_ldl(LDL)\n'); 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_det_lu.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY]=sparsity_det_lu(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'det_lu', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % det_lu(LU): 8 | % 1) computes det(LU) by 9 | % . computing the product of the main diagonal entries of LU 10 | % . multiplying the result by -1 in case the one of the 11 | % premutations changes the sign of the det. 12 | % 13 | % This file is part of Tencalc. 14 | % 15 | % Copyright (C) 2012-21 The Regents of the University of California 16 | % (author: Dr. Joao Hespanha). All rights reserved. 17 | 18 | verboseLevel=0; 19 | 20 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 21 | 22 | osizeLU=getOne(obj.vectorizedOperations,'osize',operands(1)); 23 | subsLU=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 24 | instrLU=getOne(obj.vectorizedOperations,'instructions',operands(1)); 25 | pq=getOne(obj.vectorizedOperations,'parameters',operands(1)); 26 | p=pq{1}; % row permutation 27 | q=pq{2}; % col permutation; 28 | if length(osizeLU)~=2 || osizeLU(1)~=osizeLU(2) 29 | osizeLU 30 | error('sparsity_det_lu: in det_lu(LU), LU must be a square (2D) matrix\n'); 31 | else 32 | n=double(osizeLU(1)); 33 | end 34 | 35 | if verboseLevel>0 36 | t0=clock(); 37 | n0=instructionsTableHeight(); 38 | fprintf(' sparsity_det_lu (%3d): LU size=%-10s, nnz=%d\n',... 39 | thisExp,['[',index2str(osizeLU),']'],length(instrLU)); 40 | end 41 | 42 | % find instructions for diagonal 43 | k=find(subsLU(1,:)==subsLU(2,:)); % find diagonal elements 44 | instrX=instrLU(k); 45 | 46 | subsY=zeros(0,1); 47 | if length(instrX)==n 48 | instrY=newInstruction(obj,obj.Itypes.I_sumprod,[length(instrX),1],instrX(:)',thisExp); 49 | P(p,1:n)=speye(n); 50 | Q(q,1:n)=speye(n); 51 | s=det(P*Q); 52 | if s<0 53 | instrY=newInstruction(obj,obj.Itypes.I_sum,[-1],instrY,thisExp); 54 | end 55 | else 56 | error('sparsity_det_lu: LU structurally singular in det_lu(LU)\n'); 57 | end 58 | 59 | end 60 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_diag.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY]=sparsity_diag(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'subsref' and returns the positions in memory 4 | % of the nonzero elements 5 | % 6 | % This file is part of Tencalc. 7 | % 8 | % Copyright (C) 2012-21 The Regents of the University of California 9 | % (author: Dr. Joao Hespanha). All rights reserved. 10 | 11 | verboseLevel=0; 12 | 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | 15 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 16 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(1)); 17 | 18 | if verboseLevel>0 19 | t0=clock(); 20 | n0=instructionsTableHeight(); 21 | fprintf('\n sparsify_diag(%3d): X ndim=%d, nnz=%d\n',... 22 | thisExp,size(subsX,1),length(instrX)); 23 | end 24 | 25 | if size(subsX,1)~=1 26 | error('diag only implemented for 1D vectors (%d dimensions instead)',size(subsX,1)); 27 | end 28 | subsY=[subsX;subsX]; 29 | instrY=instrX; 30 | 31 | if verboseLevel>0 32 | fprintf(' sparsify_diag(%3d): Y ndim=%d, nnz=%d, new instr=%4d (%d..%d) (%.2f sec)\n',... 33 | thisExp,size(subsY,1),length(instrY),... 34 | instructionsTableHeight()-n0,n0+1,instructionsTableHeight(),etime(clock,t0)); 35 | end 36 | 37 | end 38 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_ldl_d.m: -------------------------------------------------------------------------------- 1 | function [subsX,instrX]=sparsity_ldl_d(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'ldl_d', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % ldl_d(LDL): 8 | % 1) computes D by 9 | % . extracting the main diagonal entries of LDL 10 | % 11 | % This file is part of Tencalc. 12 | % 13 | % Copyright (C) 2012-21 The Regents of the University of California 14 | % (author: Dr. Joao Hespanha). All rights reserved. 15 | 16 | verboseLevel=0; 17 | 18 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 19 | 20 | osizeLDL=getOne(obj.vectorizedOperations,'osize',operands(1)); 21 | subsLDL=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 22 | instrLDL=getOne(obj.vectorizedOperations,'instructions',operands(1)); 23 | q=getOne(obj.vectorizedOperations,'parameters',operands(1)); 24 | q=q{1}; % column (and row) permutation 25 | if length(osizeLDL)~=2 || osizeLDL(1)~=osizeLDL(2) 26 | osizeLDL 27 | error('ldl_d: in ldl_l(LDL), LDL must be a square (2D) matrix\n'); 28 | else 29 | n=double(osizeLDL(1)); 30 | end 31 | 32 | if verboseLevel>0 33 | t0=clock(); 34 | n0=instructionsTableHeight(); 35 | fprintf(' sparsify_ldl_d (%3d): LDL size=%-10s, nnz=%d\n',... 36 | thisExp,['[',index2str(osizeLDL),']'],length(instrLDL)); 37 | end 38 | 39 | % Compute instructions 40 | k=find(subsLDL(1,:)==subsLDL(2,:)); % find diagonal elements 41 | subsX=subsLDL(1,k); 42 | instrX=instrLDL(k); 43 | 44 | % keep subsX in the natural order 45 | [subsX,k]=sortrows(subsX'); 46 | subsX=subsX'; 47 | instrX=instrX(k); 48 | 49 | if verboseLevel>0 50 | fprintf(' sparsify_ldl_d (%3d): D size=%-10s, nnz=%d, # new instr=%4d (%d..%d) (%.2f sec)\n',... 51 | thisExp,['[',index2str(osizeLDL(1)),']'],length(instrX),... 52 | instructionsTableHeight()-n0,n0+1,instructionsTableHeight(),etime(clock,t0)); 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_ldl_l.m: -------------------------------------------------------------------------------- 1 | function [subsX,instrX]=sparsity_ldl_l(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'ldl_l', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % ldl_l(LDL): 8 | % 1) computes L by 9 | % . extracting the lower diagonal entries of LDL 10 | % . adding ones in the main diagonal 11 | % 12 | % This file is part of Tencalc. 13 | % 14 | % Copyright (C) 2012-21 The Regents of the University of California 15 | % (author: Dr. Joao Hespanha). All rights reserved. 16 | 17 | verboseLevel=0; 18 | 19 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 20 | 21 | osizeLDL=getOne(obj.vectorizedOperations,'osize',operands(1)); 22 | subsLDL=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 23 | instrLDL=getOne(obj.vectorizedOperations,'instructions',operands(1)); 24 | q=getOne(obj.vectorizedOperations,'parameters',operands(1)); 25 | q=q{1}; % column (and row) permutation 26 | if length(osizeLDL)~=2 || osizeLDL(1)~=osizeLDL(2) 27 | osizeLDL 28 | error('ldl_d: in ldl_l(LDL), LDL must be a square (2D) matrix\n'); 29 | else 30 | n=double(osizeLDL(1)); 31 | end 32 | 33 | if verboseLevel>0 34 | t0=clock(); 35 | n0=instructionsTableHeight(); 36 | fprintf(' sparsify_ldl_d (%3d): LDL size=%-10s, nnz=%d\n',... 37 | thisExp,['[',index2str(osizeLDL),']'],length(instrLDL)); 38 | end 39 | 40 | % Compute instructions 41 | k=find(subsLDL(1,:)>subsLDL(2,:)); % find below diagonal 42 | subsX=[subsLDL(1,k);subsLDL(2,k)]; 43 | instrX=instrLDL(k); 44 | 45 | % add ones to diagonal 46 | subsX=[subsX,[1:osizeLDL(1);1:osizeLDL(1)]]; 47 | instrX=[instrX;repmat(newInstructions(obj,obj.Itypes.I_load,... 48 | {1},{[]},thisExp),osizeLDL(1),1)]; 49 | 50 | % apply q permutation to rows 51 | subsX(1,:)=q(subsX(1,:)); 52 | 53 | % keep subsX in the natural order 54 | [subsX,k]=sortrows(subsX'); 55 | subsX=subsX'; 56 | instrX=instrX(k); 57 | 58 | if verboseLevel>0 59 | fprintf(' sparsify_ldl_d (%3d): D size=%-10s, nnz=%d, # new instr=%4d (%d..%d) (%.2f sec)\n',... 60 | thisExp,['[',index2str(osizeLDL(1)),']'],length(instrX),... 61 | instructionsTableHeight()-n0,n0+1,instructionsTableHeight(),etime(clock,t0)); 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_logdet_ldl.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY]=sparsity_logdet_ldl(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'logdet_ldl', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % logdet_ldl(LDL): 8 | % 1) computes det(D) by 9 | % . computing the product of the main diagonal entries of LDL 10 | % 11 | % This file is part of Tencalc. 12 | % 13 | % Copyright (C) 2012-21 The Regents of the University of California 14 | % (author: Dr. Joao Hespanha). All rights reserved. 15 | 16 | verboseLevel=0; 17 | 18 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 19 | 20 | osizeLDL=getOne(obj.vectorizedOperations,'osize',operands(1)); 21 | subsLDL=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 22 | instrLDL=getOne(obj.vectorizedOperations,'instructions',operands(1)); 23 | if length(osizeLDL)~=2 || osizeLDL(1)~=osizeLDL(2) 24 | osizeLDL 25 | error('sparsity_logdet_ldl: in logdet_ldl(LDL), LDL must be a square (2D) matrix\n'); 26 | else 27 | n=double(osizeLDL(1)); 28 | end 29 | 30 | if verboseLevel>0 31 | t0=clock(); 32 | n0=instructionsTableHeight(); 33 | fprintf(' sparsity_logdet_ldl (%3d): LDL size=%-10s, nnz=%d\n',... 34 | thisExp,['[',index2str(osizeLDL),']'],length(instrLDL)); 35 | end 36 | 37 | % find instructions for diagonal 38 | k=find(subsLDL(1,:)==subsLDL(2,:)); % find diagonal elements 39 | instrX=instrLDL(k); 40 | 41 | subsY=zeros(0,1); 42 | if length(instrX)==n 43 | % log(prod) 44 | %instrY=newInstruction(obj,obj.Itypes.I_sumprod,[length(instrX),1],instrX(:)',thisExp); 45 | %instrY=newInstruction(obj,obj.Itypes.I_log,[],instrY,thisExp); 46 | % sum(log) 47 | instrY=newInstructions(obj,obj.Itypes.I_abs,{[]},num2cell(instrX,2),thisExp); 48 | instrY=newInstructions(obj,obj.Itypes.I_log,{[]},num2cell(instrY,2),thisExp); 49 | parameters=ones(1,numel(instrY)); 50 | instrY=newInstruction(obj,obj.Itypes.I_sum,parameters,instrY,thisExp); 51 | else 52 | error('sparsity_logdet_ldl: LDL structurally singular in logdet_ldl(LDL)\n'); 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_logdet_lu.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY]=sparsity_logdet_lu(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'logdet_lu', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % logdet_lu(LU): 8 | % 1) computes det(LU) by 9 | % . computing the product of the main diagonal entries of LU 10 | % . multiplying the result by -1 in case the one of the 11 | % premutations changes the sign of the det. 12 | % 13 | % This file is part of Tencalc. 14 | % 15 | % Copyright (C) 2012-21 The Regents of the University of California 16 | % (author: Dr. Joao Hespanha). All rights reserved. 17 | 18 | verboseLevel=0; 19 | 20 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 21 | 22 | osizeLU=getOne(obj.vectorizedOperations,'osize',operands(1)); 23 | subsLU=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 24 | instrLU=getOne(obj.vectorizedOperations,'instructions',operands(1)); 25 | pq=getOne(obj.vectorizedOperations,'parameters',operands(1)); 26 | p=pq{1}; % row permutation 27 | q=pq{2}; % col permutation; 28 | if length(osizeLU)~=2 || osizeLU(1)~=osizeLU(2) 29 | osizeLU 30 | error('sparsity_logdet_lu: in logdet_lu(LU), LU must be a square (2D) matrix\n'); 31 | else 32 | n=double(osizeLU(1)); 33 | end 34 | 35 | if verboseLevel>0 36 | t0=clock(); 37 | n0=instructionsTableHeight(); 38 | fprintf(' sparsity_logdet_lu (%3d): LU size=%-10s, nnz=%d\n',... 39 | thisExp,['[',index2str(osizeLU),']'],length(instrLU)); 40 | end 41 | 42 | % find instructions for diagonal 43 | k=find(subsLU(1,:)==subsLU(2,:)); % find diagonal elements 44 | instrX=instrLU(k); 45 | 46 | subsY=zeros(0,1); 47 | if length(instrX)==n 48 | % log(prod) 49 | % instrY=newInstruction(obj,obj.Itypes.I_sumprod,[length(instrX),1],instrX(:)',thisExp); 50 | % P(p,1:n)=speye(n); 51 | % Q(q,1:n)=speye(n); 52 | % s=det(P*Q); 53 | % if s<0 54 | % instrY=newInstruction(obj,obj.Itypes.I_sum,[-1],instrY,thisExp); 55 | % end 56 | % instrY=newInstruction(obj,obj.Itypes.I_log,[],instrY,thisExp); 57 | instrY=newInstructions(obj,obj.Itypes.I_abs,{[]},num2cell(instrX,2),thisExp); 58 | instrY=newInstructions(obj,obj.Itypes.I_log,{[]},num2cell(instrY,2),thisExp); 59 | parameters=ones(1,numel(instrY)); 60 | instrY=newInstruction(obj,obj.Itypes.I_sum,parameters,instrY,thisExp); 61 | else 62 | error('sparsity_logdet_lu: LU structurally singular in logdet_lu(LU)\n'); 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_lu_d.m: -------------------------------------------------------------------------------- 1 | function [subsX,instrX]=sparsity_lu_d(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'lu_d', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % lu_d(LDL): 8 | % 1) computes D by 9 | % . extracting the main diagonal entries of LU 10 | % . adjust sign to account for permutations 11 | % 12 | % This file is part of Tencalc. 13 | % 14 | % Copyright (C) 2012-21 The Regents of the University of California 15 | % (author: Dr. Joao Hespanha). All rights reserved. 16 | 17 | verboseLevel=0; 18 | 19 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 20 | 21 | osizeLU=getOne(obj.vectorizedOperations,'osize',operands(1)); 22 | subsLU=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 23 | instrLU=getOne(obj.vectorizedOperations,'instructions',operands(1)); 24 | pq=getOne(obj.vectorizedOperations,'parameters',operands(1)); 25 | 26 | if length(osizeLU)~=2 || osizeLU(1)~=osizeLU(2) 27 | osizeLU 28 | error('lu_d: in lu_l(LU), LU must be a square (2D) matrix\n'); 29 | else 30 | n=double(osizeLU(1)); 31 | end 32 | 33 | if verboseLevel>0 34 | t0=clock(); 35 | n0=instructionsTableHeight(); 36 | fprintf(' sparsify_lu_d (%3d): LU size=%-10s, nnz=%d\n',... 37 | thisExp,['[',index2str(osizeLU),']'],length(instrLU)); 38 | end 39 | 40 | % Compute instructions 41 | k=find(subsLU(1,:)==subsLU(2,:)); % find diagonal elements 42 | subsX=subsLU(1,k); 43 | instrX=instrLU(k); 44 | 45 | % keep subsX in the natural order 46 | [subsX,k]=sortrows(subsX'); 47 | subsX=subsX'; 48 | instrX=instrX(k); 49 | 50 | % undo sign changes in determinant by permutations 51 | si=det(sparse(1:n,pq{1},ones(n,1),n,n))*det(sparse(1:n,pq{2},ones(n,1),n,n)); 52 | if si<0 53 | instructions=num2cell(instrX,2); 54 | instrX=newInstructions(obj,obj.Itypes.I_sum,{-1},instructions,thisExp); 55 | end 56 | 57 | if verboseLevel>0 58 | fprintf(' sparsify_lu_d (%3d): D size=%-10s, nnz=%d, # new instr=%4d (%d..%d) (%.2f sec)\n',... 59 | thisExp,['[',index2str(osizeLU(1)),']'],length(instrX),... 60 | instructionsTableHeight()-n0,n0+1,instructionsTableHeight(),etime(clock,t0)); 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_lu_l.m: -------------------------------------------------------------------------------- 1 | function [subsX,instrX]=sparsity_lu_l(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'lu_d', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % lu_l(LDL): 8 | % 1) computes L by 9 | % . extracting the lower diagonal entries of LU 10 | % . adding ones in the main diagonal 11 | % 12 | % This file is part of Tencalc. 13 | % 14 | % Copyright (C) 2012-21 The Regents of the University of California 15 | % (author: Dr. Joao Hespanha). All rights reserved. 16 | 17 | verboseLevel=0; 18 | 19 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 20 | 21 | osizeLU=getOne(obj.vectorizedOperations,'osize',operands(1)); 22 | subsLU=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 23 | instrLU=getOne(obj.vectorizedOperations,'instructions',operands(1)); 24 | pq=getOne(obj.vectorizedOperations,'parameters',operands(1)); 25 | p=pq{1}; % row permutations 26 | if length(osizeLU)~=2 || osizeLU(1)~=osizeLU(2) 27 | osizeLU 28 | error('lu_d: in lu_l(LU), LU must be a square (2D) matrix\n'); 29 | else 30 | n=double(osizeLU(1)); 31 | end 32 | 33 | if verboseLevel>0 34 | t0=clock(); 35 | n0=instructionsTableHeight(); 36 | fprintf(' sparsify_lu_d (%3d): LU size=%-10s, nnz=%d\n',... 37 | thisExp,['[',index2str(osizeLU),']'],length(instrLU)); 38 | end 39 | 40 | % Compute instructions 41 | k=find(subsLU(1,:)>subsLU(2,:)); % find below diagonal 42 | subsX=[subsLU(1,k);subsLU(2,k)]; 43 | instrX=instrLU(k); 44 | 45 | % add ones to diagonal 46 | subsX=[subsX,[1:osizeLU(1);1:osizeLU(1)]]; 47 | instrX=[instrX;repmat(newInstructions(obj,obj.Itypes.I_load,... 48 | {1},{[]},thisExp),osizeLU(1),1)]; 49 | 50 | % apply q permutation to rows 51 | subsX(1,:)=p(subsX(1,:)); 52 | 53 | % keep subsX in the natural order 54 | [subsX,k]=sortrows(subsX'); 55 | subsX=subsX'; 56 | instrX=instrX(k); 57 | 58 | if verboseLevel>0 59 | fprintf(' sparsify_lu_l (%3d): D size=%-10s, nnz=%d, # new instr=%4d (%d..%d) (%.2f sec)\n',... 60 | thisExp,['[',index2str(osizeLU(1)),']'],length(instrX),... 61 | instructionsTableHeight()-n0,n0+1,instructionsTableHeight(),etime(clock,t0)); 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_lu_u.m: -------------------------------------------------------------------------------- 1 | function [subsX,instrX]=sparsity_lu_u(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'lu_d', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % lu_l(LDL): 8 | % 1) computes U by 9 | % . extracting the lower diagonal entries of LU (including main diagonal) 10 | % 11 | % This file is part of Tencalc. 12 | % 13 | % Copyright (C) 2012-21 The Regents of the University of California 14 | % (author: Dr. Joao Hespanha). All rights reserved. 15 | 16 | verboseLevel=0; 17 | 18 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 19 | 20 | osizeLU=getOne(obj.vectorizedOperations,'osize',operands(1)); 21 | subsLU=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 22 | instrLU=getOne(obj.vectorizedOperations,'instructions',operands(1)); 23 | pq=getOne(obj.vectorizedOperations,'parameters',operands(1)); 24 | q=pq{2}; % column permutations 25 | if length(osizeLU)~=2 || osizeLU(1)~=osizeLU(2) 26 | osizeLU 27 | error('lu_d: in lu_l(LU), LU must be a square (2D) matrix\n'); 28 | else 29 | n=double(osizeLU(1)); 30 | end 31 | 32 | if verboseLevel>0 33 | t0=clock(); 34 | n0=instructionsTableHeight(); 35 | fprintf(' sparsify_lu_d (%3d): LU size=%-10s, nnz=%d\n',... 36 | thisExp,['[',index2str(osizeLU),']'],length(instrLU)); 37 | end 38 | 39 | % Compute instructions 40 | k=find(subsLU(1,:)<=subsLU(2,:)); % find below diagonal 41 | subsX=[subsLU(1,k);subsLU(2,k)]; 42 | instrX=instrLU(k); 43 | 44 | % apply q permutation to columns 45 | subsX(2,:)=q(subsX(2,:)); 46 | 47 | % keep subsX in the natural order 48 | [subsX,k]=sortrows(subsX'); 49 | subsX=subsX'; 50 | instrX=instrX(k); 51 | 52 | if verboseLevel>0 53 | fprintf(' sparsify_lu_u (%3d): D size=%-10s, nnz=%d, # new instr=%4d (%d..%d) (%.2f sec)\n',... 54 | thisExp,['[',index2str(osizeLU(1)),']'],length(instrX),... 55 | instructionsTableHeight()-n0,n0+1,instructionsTableHeight(),etime(clock,t0)); 56 | end 57 | 58 | end 59 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_max.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_max(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'max_nz', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | dimension=getOne(obj.vectorizedOperations,'parameters',thisExp); 15 | osize1=getOne(obj.vectorizedOperations,'osize',operands(1)); 16 | 17 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 18 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(1)); 19 | 20 | subsY=subsX; 21 | subsY(dimension,:)=[]; 22 | [subsY,iSmall,iLarge]=unique(subsY','rows'); 23 | subsY=subsY'; 24 | 25 | instrY=nan(length(iSmall),1); 26 | for i=1:length(iSmall) 27 | k=(iLarge==iSmall(i)); 28 | operands=instrX(k); 29 | if length(operands)==prod(osize1(dimension)) 30 | if length(operands)>1 31 | instrY(i)=newInstruction(obj,obj.Itypes.I_max,[],operands,thisExp); 32 | else 33 | instrY(i)=operands; 34 | end 35 | else 36 | instrY(i)=newInstruction(obj,obj.Itypes.I_max0,[],operands,thisExp); 37 | end 38 | end 39 | end 40 | 41 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_max2.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_max2(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'plus', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | verboseLevel=0; 13 | 14 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 15 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 16 | 17 | %% Compute sparsity pattern 18 | subsY=zeros(0,length(osize),'uint64'); 19 | instrXs=zeros(0,length(operands),'uint64'); % one operand per column 20 | for i=1:length(operands) 21 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(i))'; 22 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(i)); 23 | nnzX{i}=length(instrX); 24 | [liX,kY]=ismember(subsX,subsY,'rows'); 25 | instrXs(kY(liX),i)=instrX(liX); 26 | subsY=[subsY;subsX(~liX,:)]; 27 | instrXs(end+1:size(subsY,1),i)=instrX(~liX); % grow instrXs 28 | end 29 | [~,k]=sortrows(subsY,size(subsY,2):-1:1); 30 | subsY=subsY(k,:)'; 31 | instrXs=instrXs(k,:); 32 | 33 | %% Determine instructions for Y 34 | instrY=nan(size(subsY,2),1); 35 | nTerms=sum(instrXs~=0,2); 36 | 37 | [instrXs,k]=sort(instrXs,2,'ascend'); % sort terms by instructions 38 | 39 | %% Compute instructions 40 | for n=1:max(nTerms) 41 | k=find(nTerms==n); 42 | if ~isempty(k) 43 | instructions=num2cell(instrXs(k,end-n+1:end),2); 44 | if n max0 (to account for structural zero) 46 | instrY(k)=newInstructions(obj,obj.Itypes.I_max0,{[]},instructions,thisExp); 47 | else 48 | instrY(k)=newInstructions(obj,obj.Itypes.I_max,{[]},instructions,thisExp); 49 | end 50 | end 51 | end 52 | 53 | if verboseLevel>0 54 | fprintf(' sparsify: size=%-10s, nnz=%4d (%6.2f%%) <- max2(',... 55 | ['[',index2str(osize),']'],length(instrY),100*length(instrY)/prod(osize)); 56 | for i=1:length(operands) 57 | fprintf('size=%-10s, nnz=%4d; ',['[',index2str(osize),']'],nnzX{i}); 58 | end 59 | fprintf(')\n'); 60 | end 61 | 62 | end 63 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_min.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_min(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'min_nz', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | dimension=getOne(obj.vectorizedOperations,'parameters',thisExp); 15 | osize1=getOne(obj.vectorizedOperations,'osize',operands(1)); 16 | 17 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 18 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(1)); 19 | 20 | subsY=subsX; 21 | subsY(dimension,:)=[]; 22 | [subsY,iSmall,iLarge]=unique(subsY','rows'); 23 | subsY=subsY'; 24 | 25 | instrY=nan(length(iSmall),1); 26 | for i=1:length(iSmall) 27 | k=(iLarge==iSmall(i)); 28 | operands=instrX(k); 29 | if length(operands)==prod(osize1(dimension)) 30 | if length(operands)>1 31 | instrY(i)=newInstruction(obj,obj.Itypes.I_min,[],operands,thisExp); 32 | else 33 | instrY(i)=operands; 34 | end 35 | else 36 | instrY(i)=newInstruction(obj,obj.Itypes.I_min0,[],operands,thisExp); 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_min2.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_min2(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'plus', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | verboseLevel=0; 13 | 14 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 15 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 16 | 17 | %% Compute sparsity pattern 18 | subsY=zeros(0,length(osize),'uint64'); 19 | instrXs=zeros(0,length(operands),'uint64'); % one operand per column 20 | for i=1:length(operands) 21 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(i))'; 22 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(i)); 23 | nnzX{i}=length(instrX); 24 | [liX,kY]=ismember(subsX,subsY,'rows'); 25 | instrXs(kY(liX),i)=instrX(liX); 26 | subsY=[subsY;subsX(~liX,:)]; 27 | instrXs(end+1:size(subsY,1),i)=instrX(~liX); % grow instrXs 28 | end 29 | [~,k]=sortrows(subsY,size(subsY,2):-1:1); 30 | subsY=subsY(k,:)'; 31 | instrXs=instrXs(k,:); 32 | 33 | %% Determine instructions for Y 34 | instrY=nan(size(subsY,2),1); 35 | nTerms=sum(instrXs~=0,2); 36 | [instrXs,k]=sort(instrXs,2,'ascend'); % sort terms by instructions 37 | 38 | %% Compute instructions 39 | for n=1:max(nTerms) 40 | k=find(nTerms==n); 41 | if ~isempty(k) 42 | instructions=num2cell(instrXs(k,end-n+1:end),2); 43 | if n min0 (to account for structural zero) 45 | instrY(k)=newInstructions(obj,obj.Itypes.I_min0,{[]},instructions,thisExp); 46 | else 47 | instrY(k)=newInstructions(obj,obj.Itypes.I_min,{[]},instructions,thisExp); 48 | end 49 | end 50 | end 51 | 52 | if verboseLevel>0 53 | fprintf(' sparsify: size=%-10s, nnz=%4d (%6.2f%%) <- min2(',... 54 | ['[',index2str(osize),']'],length(instrY),100*length(instrY)/prod(osize)); 55 | for i=1:length(operands) 56 | fprintf('size=%-10s, nnz=%4d; ',['[',index2str(osize),']'],nnzX{i}); 57 | end 58 | fprintf(')\n'); 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_norm1.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_norm1(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'norm2', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | 15 | subsY=zeros(0,1); 16 | 17 | %% Get instructions for operand 18 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(1))'; 19 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(1)); 20 | 21 | 22 | %% Determine instructions for Y 23 | instrY=newInstruction(obj,obj.Itypes.I_plus_abs,[],instrX(:)',thisExp); 24 | end 25 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_norm2.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_norm2(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'norm2', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | 15 | subsY=zeros(0,1); 16 | 17 | %% Get instructions for operand 18 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(1))'; 19 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(1)); 20 | 21 | 22 | %% Determine instructions for Y 23 | instrY=newInstruction(obj,obj.Itypes.I_plus_sqr,[],instrX(:)',thisExp); 24 | end -------------------------------------------------------------------------------- /lib/@csparse/sparsity_norminf.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_norminf(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'norm2', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | 15 | subsY=zeros(0,1); 16 | 17 | %% Get instructions for operand 18 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(1))'; 19 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(1)); 20 | 21 | 22 | %% Determine instructions for Y 23 | if length(instrX)==1 24 | instrY=newInstruction(obj,obj.Itypes.I_abs,[],instrX(:)',thisExp); 25 | else 26 | instrY=newInstruction(obj,obj.Itypes.I_max_abs,[],instrX(:)',thisExp); 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_plus.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY]=sparsity_plus(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'plus', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | verboseLevel=0; 13 | 14 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 15 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 16 | parameters=getOne(obj.vectorizedOperations,'parameters',thisExp); 17 | 18 | %% Compute sparsity pattern 19 | subsY=zeros(0,length(osize),'uint64'); 20 | instrXs=zeros(0,length(operands),'uint64'); % one operand per column 21 | for i=1:length(operands) 22 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(i))'; 23 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(i)); 24 | nnzX{i}=length(instrX); 25 | [liX,kY]=ismember(subsX,subsY,'rows'); 26 | instrXs(kY(liX),i)=instrX(liX); 27 | subsY=[subsY;subsX(~liX,:)]; 28 | instrXs(end+1:size(subsY,1),i)=instrX(~liX); % grow instrXs 29 | end 30 | [~,k]=sortrows(subsY,size(subsY,2):-1:1); 31 | subsY=subsY(k,:)'; 32 | instrXs=instrXs(k,:); 33 | 34 | %% Determine instructions for Y 35 | instrY=nan(size(subsY,2),1); 36 | nTerms=sum(instrXs~=0,2); 37 | 38 | [instrXs,k]=sort(instrXs,2,'ascend'); % sort terms by instructions 39 | indXs=reshape(parameters(k),size(k)); % to fix the case of a single instruction 40 | 41 | % "sums of 1 term" - no instruction needed 42 | k=(nTerms==1 & indXs(:,end)==1); 43 | instrY(k)=instrXs(k,end); 44 | 45 | %% Compute instructions 46 | for n=1:max(nTerms) 47 | k=find(nTerms==n & (n>1 | indXs(:,end)==-1)); 48 | if ~isempty(k) 49 | parameters=num2cell(indXs(k,end-n+1:end),2); 50 | instructions=num2cell(instrXs(k,end-n+1:end),2); 51 | instrY(k)=newInstructions(obj,obj.Itypes.I_sum,parameters,instructions,thisExp); 52 | end 53 | end 54 | 55 | if verboseLevel>0 56 | fprintf(' sparsify: size=%-10s, nnz=%4d (%6.2f%%) <- plus(',... 57 | ['[',index2str(osize),']'],length(instrY),100*length(instrY)/prod(osize)); 58 | for i=1:length(operands) 59 | fprintf('size=%-10s, nnz=%4d; ',['[',index2str(osize),']'],nnzX{i}); 60 | end 61 | fprintf(')\n'); 62 | end 63 | end -------------------------------------------------------------------------------- /lib/@csparse/sparsity_rdivide.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY,instructions]=sparsity_rdivide(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'rdivide', allocates the required memory, and 4 | % determines the instructions needed to compute each of its nonzero 5 | % elements. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | osize=getOne(obj.vectorizedOperations,'osize',thisExp); 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | 15 | subsY=zeros(0,1); 16 | 17 | %% Get instructions for operands 18 | osize1=getOne(obj.vectorizedOperations,'osize',operands(1)); 19 | subsX1=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 20 | instrX1=getOne(obj.vectorizedOperations,'instructions',operands(1)); 21 | 22 | osize2=getOne(obj.vectorizedOperations,'osize',operands(2)); 23 | subsX2=getOne(obj.vectorizedOperations,'subscripts',operands(2)); 24 | instrX2=getOne(obj.vectorizedOperations,'instructions',operands(2)); 25 | 26 | if isempty(osize2) 27 | % division by scalar 28 | %fprintf('sparsity_rdivide: division by scalar\n'); 29 | if isempty(instrX2) 30 | error('sparsity_rdivide: structurally zero scalar for x2 not allowed in x1./x2') 31 | end 32 | subsY=subsX1; 33 | %% Determine instructions for Y 34 | operands=[instrX1';instrX2*ones(1,length(instrX1))]; 35 | elseif isempty(osize1) 36 | % scalar divided by 37 | %fprintf('sparsity_rdivide: scalar divided by\n'); 38 | if isempty(instrX2) 39 | error('sparsity_rdivide: structurally zero scalar for x2 not allowed in x1./x2') 40 | end 41 | subsY=subsX2; 42 | %% Determine instructions for Y 43 | operands=[instrX1*ones(1,length(instrX2));instrX2']; 44 | elseif myisequal(osize1,osize2) 45 | % entry-wise division 46 | %fprintf('sparsity_rdivide: entry-wise division\n'); 47 | if size(subsX2,2)~=prod(osize) 48 | error('sparsity_rdivide: structurally zero values for x2 not allowed in x1./x2') 49 | end 50 | [kX2,kX1]=ismember(subsX2',subsX1','rows'); 51 | subsY=subsX1(:,kX1(kX2)); 52 | %% Determine instructions for Y 53 | operands=[instrX1(kX1(kX2))';instrX2(kX2)']; 54 | else 55 | osize1,osize2,; 56 | error('sparsity_rdivide: mismatched sizes in x1./x2'); 57 | end 58 | if isempty(operands) 59 | instrY=zeros(0,1); 60 | else 61 | operands=mat2cell(operands,2,ones(size(operands,2),1)); 62 | instrY=newInstructions(obj,obj.Itypes.I_div,{[]},operands,thisExp); 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_subsref.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY]=sparsity_subsref(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'subsref' and returns the positions in memory 4 | % of the nonzero elements 5 | % 6 | % This file is part of Tencalc. 7 | % 8 | % Copyright (C) 2012-21 The Regents of the University of California 9 | % (author: Dr. Joao Hespanha). All rights reserved. 10 | 11 | verboseLevel=0; 12 | 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | S=getOne(obj.vectorizedOperations,'parameters',thisExp); 15 | oosize=getOne(obj.vectorizedOperations,'osize',operands(1)); 16 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 17 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(1)); 18 | 19 | if verboseLevel>0 20 | t0=clock(); 21 | n0=instructionsTableHeight(); 22 | fprintf('\n sparsify_subsref(%3d): X ndim=%d, nnz=%d\n',... 23 | thisExp,size(subsX,1),length(instrX)); 24 | end 25 | 26 | switch S.type 27 | case '()', 28 | if length(S.subs)~=size(subsX,1) 29 | error(['mismatch between object length (%d) and ' ... 30 | 'indexing length (%d)'],size(subsX,1),length(S.subs)); 31 | end 32 | %S.subs{:} 33 | ind_y=(1:length(S.subs{1}))'; 34 | ind_subsref=S.subs{1}(:); 35 | for i=2:length(S.subs) 36 | % prune uninteresting rows in ind_y for next expansion 37 | k1=ismember(ind_subsref,subsX(1:i-1,:)','rows'); 38 | ind_subsref=ind_subsref(k1,:); 39 | ind_y=ind_y(k1,:); 40 | 41 | % expand next dimension 42 | ind_subsref=[kron(ones(length(S.subs{i}),1),ind_subsref),... 43 | kron(S.subs{i}(:),ones(size(ind_subsref,1),1))]; 44 | ind_y =[kron(ones(length(S.subs{i}),1),ind_y),... 45 | kron((1:length(S.subs{i}))',ones(size(ind_y,1),1))]; 46 | end 47 | % ind_subsref(1:min(20,end),:) 48 | % size(ind_subsref) 49 | % ind_y(1:min(20,end),:) 50 | % size(ind_y) 51 | % size(subsX) 52 | 53 | %tic 54 | [lia,k2]=ismember(ind_subsref,subsX','rows'); 55 | k1=(1:size(ind_subsref,1))'; 56 | k1=k1(lia); 57 | k2=k2(lia); 58 | % toc; 59 | % if any(any(ind_subsref(k1,:)'~=subsX(:,k2))) 60 | % error('ismember mismatch'); 61 | % end 62 | 63 | subsY=ind_y(k1,:)'; 64 | instrY=instrX(k2); 65 | 66 | otherwise, 67 | error('subsref of type ''%s'' not implemented\n',S.type); 68 | end 69 | 70 | if verboseLevel>0 71 | fprintf(' sparsify_subsref(%3d): Y ndim=%d, nnz=%d, new instr=%4d (%d..%d) (%.2f sec)\n',... 72 | thisExp,size(subsY,1),length(instrY),... 73 | instructionsTableHeight()-n0,n0+1,instructionsTableHeight(),etime(clock,t0)); 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /lib/@csparse/sparsity_transpose.m: -------------------------------------------------------------------------------- 1 | function [subsY,instrY]=sparsity_transpose(obj,thisExp) 2 | % Computes the sparsity pattern for an elementary expression 3 | % 'thisExp' of type 'subsref' and returns the positions in memory 4 | % of the nonzero elements 5 | % 6 | % This file is part of Tencalc. 7 | % 8 | % Copyright (C) 2012-21 The Regents of the University of California 9 | % (author: Dr. Joao Hespanha). All rights reserved. 10 | 11 | verboseLevel=0; 12 | 13 | operands=getOne(obj.vectorizedOperations,'operands',thisExp); 14 | 15 | subsX=getOne(obj.vectorizedOperations,'subscripts',operands(1)); 16 | instrX=getOne(obj.vectorizedOperations,'instructions',operands(1)); 17 | 18 | if verboseLevel>0 19 | t0=clock(); 20 | n0=instructionsTableHeight(); 21 | fprintf('\n sparsify_transpose(%3d): X ndim=%d, nnz=%d\n',... 22 | thisExp,size(subsX,1),length(instrX)); 23 | end 24 | 25 | if size(subsX,1)~=2 26 | error('transpose only valid for 2D matrices (%d dimensions instead)',size(subsX,1)); 27 | end 28 | subsY=subsX([2,1],:); 29 | instrY=instrX; 30 | 31 | if verboseLevel>0 32 | fprintf(' sparsify_transpose(%3d): Y ndim=%d, nnz=%d, new instr=%4d (%d..%d) (%.2f sec)\n',... 33 | thisExp,size(subsY,1),length(instrY),... 34 | instructionsTableHeight()-n0,n0+1,instructionsTableHeight(),etime(clock,t0)); 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/@csparse/writeCprofiling.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tencalc. 3 | 4 | Copyright (C) 2012-21 The Regents of the University of California 5 | (author: Dr. Joao Hespanha). All rights reserved. 6 | */ 7 | 8 | void profilingViewFP(FILE *fp) 9 | { 10 | int nGroups=sizeof(countCallGroup)/sizeof(countCallGroup[0]); 11 | int nGets =sizeof(getNames)/sizeof(getNames[0]); 12 | int nSets =sizeof(setNames)/sizeof(setNames[0]); 13 | int nCopies=sizeof(copyNames)/sizeof(copyNames[0]); 14 | int nFlops =sizeof(flopsNames)/sizeof(flopsNames[0]); 15 | 16 | fprintf(fp,"Operation Count\n"); 17 | int64_t c=0; 18 | for (int i=0;i <2345678><2345678><23456789> 27 | for (int i=0;i <2345678><23456789> 39 | for (int i=0;i <2345678><23456789> 50 | for (int i=0;i <2345678><23456789> 61 | for (int i=0;i2 && msize(end)==1 36 | msize(end)=[]; 37 | end 38 | 39 | if ~isequal(msize,size(value)) && (prod(msize)>0 || ~isempty(value)) 40 | disp(value) 41 | error('Tconstant: size [msize=%s, osize=%s] incompatible with value [%s]\n',index2str(msize),index2str(osize),index2str(size(value))); 42 | end 43 | 44 | if nnz(value)==0 45 | obj=Tzeros(osize); 46 | updateFile2table(obj,1); 47 | elseif nnz(value)==prod(msize) && isequal(value,ones(msize)) 48 | obj=Tones(osize); 49 | updateFile2table(obj,1); 50 | elseif length(osize)==2 && osize(1)==osize(2) && isequal(value,speye(osize)) 51 | obj=Teye(osize); 52 | updateFile2table(obj,1); 53 | else 54 | obj=Tcalculus('constant',osize,double(value),[],{},1); 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /lib/Teye.m: -------------------------------------------------------------------------------- 1 | function obj=Teye(varargin) 2 | % var = Teye([]) 3 | % 4 | % var = Teye([n1,n2,...,na,n1,n2,...,na]) 5 | % 6 | % var = Teye(n1,n2,...,na,n1,n2,...,na) 7 | % 8 | % Returns a Tcalculus identity tensor. The integers n1,n2,...,na 9 | % specify the dimension of each index of the tensor. Note that an 10 | % identity tensor is expected to have the first half of the 11 | % dimensions equal to the second half. 12 | % 13 | % This file is part of Tencalc. 14 | % 15 | % Copyright (C) 2012-21 The Regents of the University of California 16 | % (author: Dr. Joao Hespanha). All rights reserved. 17 | 18 | if nargin==1 19 | osize=varargin{1}; 20 | else 21 | osize=[varargin{:}]; 22 | end 23 | if mod(length(osize),2)~=0 24 | osize 25 | error('eye matrix must have an even number of indices'); 26 | end 27 | if ~isempty(osize) 28 | ind1=1:length(osize)/2; 29 | ind2=ind1(end)+1:length(osize); 30 | else 31 | ind1=[]; 32 | ind2=[]; 33 | end 34 | if ~myisequal(osize(ind1),osize(ind2)) 35 | osize,ind1,ind2 36 | error('first and second half of dimensions for eye matrix must correspond to compatible sizes'); 37 | end 38 | if isempty(osize) 39 | obj =Tcalculus('ones',osize,[],[],{},1); 40 | else 41 | obj =Tcalculus('eye',osize,[],[],{},1); 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/TltiConstraints.m: -------------------------------------------------------------------------------- 1 | function [stateConstraints,y,z]=TltiConstraints(A,B,C,D,G,H,x0,x,u,Ty,Tz); 2 | % [stateConstraints,y,z]=TltiConstraints(A,B,C,D,G,H,x0,x,u,Ty,Tz); 3 | % 4 | % These commands generate constraints for optimization involving a discrete-time LTI system 5 | % 6 | % Inputs: 7 | % A,B,C,D,G,H - state-space model of an LTI system with nx states, nu inputs, 8 | % ny measured outputs (C,D), and nz controlled 9 | % outputs (G,H) 10 | % C and/or G may be empty if the outputs y and/ot z 11 | % are not needed 12 | % x0 - nx column vector with initial state x(0) 13 | % x - nx by Tu Tcalculus tensor variable with state vectors x(1), x(2), ..., x(Tu) 14 | % u - nu by Tu matrix with control inputs u(0), u(1), ..., u(Tu-1) 15 | % Ty - desired time length for the measured output vector (see output y) 16 | % Tz - desired time length for the controlle output vector (see output z) 17 | % 18 | % Output: 19 | % stateConstraints - constraints of the form 20 | % x(t+1) = A x(t) + B u(t) for times 0,1, ... Tu-1 21 | % y - ny by Ty matrix with outputs y(0), y(1), ..., y(Ty-1) 22 | % (only returned is C is not empty) 23 | % z - nz by Tz matrix with outputs y(0), y(1), ..., y(Tz-1) 24 | % (only returned is G is not empty) 25 | % 26 | % This file is part of Tencalc. 27 | % 28 | % Copyright (C) 2012-21 The Regents of the University of California 29 | % (author: Dr. Joao Hespanha). All rights reserved. 30 | 31 | if ismember(class(B),{'Tvariable','Tcalculus'}) 32 | nx=msize(B,1); 33 | nu=msize(B,2); 34 | else 35 | nx=size(B,1); 36 | nu=size(B,2); 37 | end 38 | if ismember(class(u),{'Tvariable','Tcalculus'}) 39 | Tu=msize(u,2); 40 | else 41 | Tu=size(u,2); 42 | end 43 | 44 | u=reshape(u,[nu,Tu]); 45 | A=reshape(A,[nx,nx]); 46 | B=reshape(B,[nx,nu]); 47 | stateConstraints=(x==A*[x0,x(:,1:Tu-1)]+B*u); 48 | 49 | 50 | if ~isempty(C) 51 | if ismember(class(C),{'Tvariable','Tcalculus'}) 52 | ny=msize(C,1); 53 | else 54 | ny=size(C,1); 55 | end 56 | C=reshape(C,[ny,nx]); 57 | D=reshape(D,[ny,nu]); 58 | y=C*[x0,x(:,1:Ty-1)]+D*u(:,1:Ty); 59 | end 60 | 61 | 62 | if ~isempty(G) 63 | if ismember(class(G),{'Tvariable','Tcalculus'}) 64 | nz=msize(G,1); 65 | else 66 | nz=size(G,1); 67 | end 68 | G=reshape(G,[nz,nx]); 69 | H=reshape(H,[nz,nu]); 70 | z=G*[x0,x(:,1:Tz-1)]+H*u(:,1:Tz); 71 | end 72 | 73 | end 74 | -------------------------------------------------------------------------------- /lib/Tones.m: -------------------------------------------------------------------------------- 1 | function obj=Tones(varargin) 2 | % var = Tones([]) 3 | % 4 | % var = Tones([n1,n2,...,na]) 5 | % 6 | % var = Tones(n1,n2,...,na) 7 | % 8 | % Returns a Tcalculus tensor with all entries equal to 1. 9 | % The integers n1,n2,...,na specify the dimension of each index of the tensor. 10 | % 11 | % This file is part of Tencalc. 12 | % 13 | % Copyright (C) 2012-21 The Regents of the University of California 14 | % (author: Dr. Joao Hespanha). All rights reserved. 15 | 16 | if nargin==1 17 | osize=varargin{1}; 18 | else 19 | osize=[varargin{:}]; 20 | end 21 | obj=Tcalculus('ones',osize,[],[],{},1); 22 | end 23 | -------------------------------------------------------------------------------- /lib/Tvariable.m: -------------------------------------------------------------------------------- 1 | function obj=Tvariable(name,osize,nowarningsamesize,nowarningever) 2 | % var = Tvariable(name,[n1,n2,...,na],nowarningsamesize,nowarningever) 3 | % 4 | % Returns a Tcalculus tensor symbolic variable. The integers 5 | % n1,n2,...,na specify the dimension of each index of the tensor. 6 | % When the tensor dimensions are missing, they are guessed from the 7 | % value (removing singleton dimensions at the end). 8 | % 9 | % The optional 3rd argument 'nowarningsamesize', prevents a warning 10 | % that is given when one attempts to create a variable that already 11 | % exists. The warning is only omitted when the new variable has the 12 | % same size as the existing one. 13 | % 14 | % The optional 4th argument 'nowarningever', prevents a warning 15 | % that is given when one attempts to create a variable that already 16 | % exists. The warning is always omitted, regardless of the variable sizes. 17 | % 18 | % This file is part of Tencalc. 19 | % 20 | % Copyright (C) 2012-21 The Regents of the University of California 21 | % (author: Dr. Joao Hespanha). All rights reserved. 22 | 23 | if ~ischar(name) 24 | error('Tvariable: 1st parameter must be a string (variable name)') 25 | end 26 | 27 | if nargin==1 28 | % variable name together with size 29 | s=regexp(name,'(\w+)(\[[^\]]*\])','tokens'); 30 | if length(s)==1 && length(s{1})==2 31 | osize=s{1}{2}; 32 | name=s{1}{1}; 33 | end 34 | end 35 | 36 | if ~isvarname(name) 37 | error('Tvariable: 1st parameter must be a valid variable name (not ''%s'')',name) 38 | end 39 | 40 | if ~exist('osize','var') 41 | osize=[]; 42 | end 43 | 44 | if nargin<3 45 | nowarningsamesize=false; 46 | end 47 | if ~islogical(nowarningsamesize) 48 | error('Tvariable: (optional) 3rd argument must be boolean'); 49 | end 50 | 51 | if nargin<4 52 | nowarningever=false; 53 | end 54 | if ~islogical(nowarningever) 55 | error('Tvariable: (optional) 4rd argument must be boolean'); 56 | end 57 | 58 | if ischar(osize) 59 | osize=evalin('caller',osize); 60 | end 61 | 62 | obj=Tcalculus('variable',osize,name,[],{},1,nowarningsamesize,nowarningever); 63 | 64 | if nargout==0 65 | assignin('caller',name,obj); 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /lib/TvariablesMPC.m: -------------------------------------------------------------------------------- 1 | function [Ts,xMeas,xFut,uPast,uFut,dynamics]=TvariablesMPC(nX,nU,T,delay,fun,varargin); 2 | % [Ts,xMeas,xFut,uPast,uFut,dynamics]=TvariablesMPC(nX,nU,T,delay,fun,varargin); 3 | % 4 | % Create the key Tvariables needed to create an MPC solver 5 | % and also the Tcalculus constraints corresponding to the dynamics 6 | % 7 | % Inputs (all scalars): 8 | % nX - state dimension 9 | % nU - input dimension 10 | % T - horizon length 11 | % delay - input delay 12 | % fun - function handle for the ODE dynamics, of the form 13 | % @(x,u,parameter1,parameter2,...) 14 | % parameter1, parameter2, .... - parameters for fun 15 | % 16 | % Outputs: 17 | % Ts [] - Tcalculus variable with sampling interval 18 | % xMeas [nX,1] - Tcalculus variable with (current) measured state 19 | % [ x(t) ] 20 | % xFut [nX,T] - Tcalculus variable with future state vector 21 | % [ x(t+Ts), x(t+2*Ts), ..., x(t+T*Ts) ]; 22 | % uPast [nU,delay] - Tcalculus variable with previously computed inputs 23 | % [u(t), u(t+Ts), ..., u(t+(delay-1)*Ts) ] 24 | % (only needed if delay>1) 25 | % uFut [nU,T-delay] - Tcalculus variable with previously computed inputs 26 | % [u(t+delay*Ts), ... , u(t+(T-1)*Ts) ] 27 | % dynamics - Tcalculus constraint encoding trapezoidal integration, 28 | % but with u assumed held constant (ZOH) 29 | % between sampling times. 30 | % 31 | % Attention: The variables created will have precisely the names 32 | % Ts,xMeas,xFut,uPast,uFut 33 | % which will be important to when calling the corresponding 34 | % setV_... and setP_... 35 | % functions prior to calling the solver 36 | % 37 | % This file is part of Tencalc. 38 | % 39 | % Copyright (C) 2012-21 The Regents of the University of California 40 | % (author: Dr. Joao Hespanha). All rights reserved. 41 | 42 | Tvariable Ts []; 43 | 44 | Tvariable xMeas [nX,1]; 45 | Tvariable xFut [nX,T]; 46 | 47 | Tvariable uPast [nU,delay]; 48 | Tvariable uFut [nU,T-delay]; 49 | 50 | xPast=[xMeas,xFut(:,1:end-1)]; 51 | uAll=[uPast,uFut]; 52 | dynamics = xFut-xPast==.5*Ts*(fun(xFut,uAll,varargin{:})+fun(xPast,uAll,varargin{:})); 53 | 54 | end -------------------------------------------------------------------------------- /lib/Tzeros.m: -------------------------------------------------------------------------------- 1 | function obj=Tzeros(varargin) 2 | % var = Tzeros([]) 3 | % 4 | % var = Tzeros([n1,n2,...,na]) 5 | % 6 | % var = Tzeros(n1,n2,...,na) 7 | % 8 | % Returns a Tcalculus tensor with all entries equal to 0. 9 | % The integers n1,n2,...,na specify the dimension of each index of the tensor. 10 | % 11 | % This file is part of Tencalc. 12 | % 13 | % Copyright (C) 2012-21 The Regents of the University of California 14 | % (author: Dr. Joao Hespanha). All rights reserved. 15 | 16 | if nargin==1 17 | osize=varargin{1}; 18 | else 19 | osize=[varargin{:}]; 20 | end 21 | obj=Tcalculus('zeros',osize,[],[],{},1); 22 | end 23 | -------------------------------------------------------------------------------- /lib/bitrate.m: -------------------------------------------------------------------------------- 1 | function br=bitrate(snr) 2 | % br=bitrate(snr) 3 | % 4 | % Returns Shannon's error-free bit-rate per Hz, for an analog 5 | % communication channel subject to additive white Gaussian noise with 6 | % the given signal-to-noise ration: 7 | % br=log2(1+snr) 8 | % 9 | % This file is part of Tencalc. 10 | % 11 | % Copyright (C) 2012-21 The Regents of the University of California 12 | % (author: Dr. Joao Hespanha). All rights reserved. 13 | 14 | if isequal(class(snr),'Tcalculus') 15 | br=compose(snr,@(x__)log(1+x__)/log(2),@(x__)1./(1+x__)/log(2),@(x__)-1./(1+x__).^2); 16 | else 17 | br=log(1+snr)/log(2); 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /lib/class2compute.m: -------------------------------------------------------------------------------- 1 | function varargout=class2compute(varargin) 2 | % To get help, type class2compute('help') 3 | % 4 | % This file is part of Tencalc. 5 | % 6 | % Copyright (C) 2012-21 The Regents of the University of California 7 | % (author: Dr. Joao Hespanha). All rights reserved. 8 | 9 | %% Function global help 10 | declareParameter(... 11 | 'Help', { 12 | 'Creates a set of matlab functions for performing a csparse computation.' 13 | ' ' 14 | 'The computation is performed through a matlab class with methods' 15 | 'for the set, get, and copy operations.' 16 | }); 17 | 18 | localVariables_=parameters4compute(localVariables_); 19 | 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | %% Retrieve parameters and inputs 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | 24 | [stopNow,params]=setParameters(nargout,varargin); 25 | if stopNow 26 | return 27 | end 28 | 29 | if ~csparseObject.tprod2matlab 30 | warning('csparseObject should have been created with tprod2matlab=true for faster matlab code. Use "csparseObject=csparse();csparseObject.tprod2matlab=true;" to create the csparse object.'); 31 | end 32 | 33 | %% transfer any folder in classname into folder 34 | [folder,classname]=fileparts(fsfullfile(folder,classname)); 35 | 36 | %% create folder if it does not exist 37 | if ~strcmp(folder,'.') && ~exist(folder,'dir') 38 | fprintf('class2compute: outputs folder ''%s'' does not exist, creating it\n',folder); 39 | if mkdir(folder)==0 40 | error('Unable to create folder ''%s''\n',folder) 41 | end 42 | end 43 | 44 | rmpath(folder); 45 | addpath(folder); 46 | 47 | %% Fix class when gotten from pedigree 48 | classname=regexprep(classname,'+TS=','_TS_'); 49 | classname=regexprep(classname,'-','_'); 50 | classname=regexprep(classname,'+','_'); 51 | 52 | classHelp=helpFromTemplate(classname,csparseObject.template); 53 | 54 | fprintf(' creating matlab code... '); 55 | t_compile2matlab=clock(); 56 | compile2matlab(csparseObject,... 57 | fsfullfile(folder,sprintf('%s.m',classname)),... 58 | fsfullfile(folder,sprintf('%s.log',classname)),... 59 | classHelp,profiling); 60 | statistics.time.compile2matlab=etime(clock,t_compile2matlab); 61 | 62 | fprintf(' done creating matlab code (%.3f sec)\n',etime(clock,t_compile2matlab)); 63 | 64 | rehash path; 65 | 66 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 67 | %% Set outputs 68 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 69 | 70 | varargout=setOutputs(nargout,params); 71 | end 72 | -------------------------------------------------------------------------------- /lib/clp.m: -------------------------------------------------------------------------------- 1 | function [alpha,k]=clp(x,dx) 2 | % [alpha,k]=clp(x,dx) 3 | % 4 | % Canonical linear proram (LP): For a given x with all entries >=0 , 5 | % computes the scalar 6 | % max { alpha >0 : x + alpha dx >= 0 } 7 | % x and dx must have the same size. 8 | % 9 | % Used by ipm Newton solvers to determine the step size. 10 | % 11 | % This file is part of Tencalc. 12 | % 13 | % Copyright (C) 2012-21 The Regents of the University of California 14 | % (author: Dr. Joao Hespanha). All rights reserved. 15 | 16 | k=find(dx<0); 17 | if isempty(k) 18 | alpha=inf; 19 | else 20 | [alpha,kk]=min(-x(k)./dx(k)); 21 | k=k(kk); 22 | end 23 | end -------------------------------------------------------------------------------- /lib/csparse/compileInstructionsTable.m: -------------------------------------------------------------------------------- 1 | % This file is part of Tencalc. 2 | % 3 | % Copyright (C) 2012-21 The Regents of the University of California 4 | % (author: Dr. Joao Hespanha). All rights reserved. 5 | 6 | %% Unload previous library 7 | if libisloaded('instructionsTable') 8 | unloadlibrary('instructionsTable'); 9 | elseif exist('instructionsTable_load','file') 10 | try 11 | instructionsTable_load(0); 12 | catch me 13 | end 14 | end 15 | 16 | %% Go to csparse folder 17 | s=which('compileInstructionsTable'); 18 | p=fileparts(s); 19 | thisDir=pwd; 20 | cd(p); 21 | 22 | %% Create hesder file with enum & defines 23 | fid=fopen('instructionsTableTypes.h','w'); 24 | fprintf(fid,'// This file is automatically generated by compileInstructionsTable.m\n'); 25 | 26 | [iTypes,pTypes]=instructionTypes(); 27 | 28 | % enum with instruction types 29 | f=fields(iTypes); 30 | fprintf(fid,'typedef enum instructionType_e {\n'); 31 | for i=1:length(f) 32 | fprintf(fid,' %s=%d,\n',f{i},getfield(iTypes,f{i})); 33 | end 34 | fprintf(fid,'} instructionType_t;\n'); 35 | 36 | % defines with profile types 37 | f=fields(pTypes); 38 | fprintf(fid,'// profile defines\n'); 39 | for i=1:length(f) 40 | fprintf(fid,'#define %s %d\n',f{i},getfield(pTypes,f{i})); 41 | end 42 | fprintf(fid,'#define P_nCountFlops %d\n',length(f)); 43 | fclose(fid); 44 | 45 | %% Call cmextools 46 | try 47 | if 1 48 | createGateway('template','instructionsTableUTHash.c',... 49 | 'callType','dynamicLibraryWithGateways',... 50 | 'CfunctionsSource','instructionsTableUTHash.c',... 51 | 'dynamicLibrary','instructionsTable',... 52 | 'verboseLevel',1); 53 | else 54 | createGateway('template','instructionsTable.c',... 55 | 'callType','dynamicLibrary',... 56 | 'CfunctionsSource','instructionsTable.c',... 57 | 'dynamicLibrary','instructionsTable',... 58 | 'verboseLevel',1); 59 | end 60 | %!nm -a instructionsTable.dylib 61 | %!otool -Tvt instructionsTable.dylib 62 | 63 | cd(thisDir) 64 | catch me 65 | cd(thisDir) 66 | rethrow(me) 67 | end 68 | 69 | %% Load new library 70 | [notfound,warnings]=loadlibrary('instructionsTable'); 71 | -------------------------------------------------------------------------------- /lib/csparse/instructionsTableHeight4MEX.c: -------------------------------------------------------------------------------- 1 | /* mex -largeArrayDims COPTIMFLAGS="-Ofast -DNDEBUG" CFLAGS="\$CFLAGS -Wall" instructionsTableHeight4MEX.c */ 2 | 3 | #include 4 | #include "mex.h" 5 | 6 | #include "instructionsTable.h" 7 | 8 | void mexFunction( int nlhs, mxArray *plhs[], 9 | int nrhs, const mxArray *prhs[]) 10 | { 11 | /* outputs */ 12 | int64_t *height; 13 | 14 | /* Process inputs */ 15 | 16 | /* Check # inputs */ 17 | if(nrhs!=0) { 18 | mexErrMsgIdAndTxt("instructionsTableHeight4MEX:nrhs", "0 inputs required, %d found.",nrhs); 19 | return; } 20 | 21 | 22 | /* Process outputs */ 23 | 24 | /* Check # outputs */ 25 | if(nlhs!=1) { 26 | mexErrMsgIdAndTxt("instructionsTableHeight4MEX:nrhs", "1 outputs required, %d found.",nlhs); 27 | return; } 28 | 29 | /* output height */ 30 | { mwSize dims[]={1,1}; 31 | plhs[0] = mxCreateNumericArray(2,dims,mxINT64_CLASS,mxREAL); 32 | height=mxGetData(plhs[0]); } 33 | 34 | /* Call function */ 35 | void *libHandle = dlopen("instructionsTable.dylib", RTLD_NOW); 36 | if (!libHandle) { printf("[%s] Unable to open library: %s\n",__FILE__, dlerror());return; } 37 | void (*instructionsTableHeight4MEX)( /* outputs */ 38 | int64_t *height) = dlsym(libHandle, "instructionsTableHeight4MEX"); 39 | if (!instructionsTableHeight4MEX) { printf("[%s] Unable to get symbol: %s\n",__FILE__, dlerror());return; } 40 | instructionsTableHeight4MEX(height); 41 | dlclose(libHandle); 42 | } 43 | -------------------------------------------------------------------------------- /lib/csparse/instructionsTableTypes.h: -------------------------------------------------------------------------------- 1 | // This file is automatically generated by compileInstructionsTable.m 2 | typedef enum instructionType_e { 3 | I_set=1, 4 | I_load=2, 5 | I_sum=3, 6 | I_sumprod=4, 7 | I_inv=5, 8 | I_minus_inv_sqr=6, 9 | I_2_inv_cube=7, 10 | I_div=8, 11 | I_minus_dot=9, 12 | I_minus_dot_div=10, 13 | I_plus_minus_dot=11, 14 | I_plus_sqr=12, 15 | I_plus_abs=13, 16 | I_plus_minus_dot_div=14, 17 | I_min=15, 18 | I_min0=16, 19 | I_max=17, 20 | I_max0=18, 21 | I_max_abs=19, 22 | I_clp=20, 23 | I_exp=21, 24 | I_log=22, 25 | I_cos=23, 26 | I_minus_cos=24, 27 | I_sin=25, 28 | I_minus_sin=26, 29 | I_round=27, 30 | I_ceil=28, 31 | I_floor=29, 32 | I_abs=30, 33 | I_sign=31, 34 | I_sqrt=32, 35 | I_Dsqrt=33, 36 | I_DDsqrt=34, 37 | I_sqr=35, 38 | I_2times=36, 39 | I_2=37, 40 | I_cube=38, 41 | I_3sqr=39, 42 | I_6times=40, 43 | I_atan=41, 44 | I_Datan=42, 45 | I_DDatan=43, 46 | I_srelu=44, 47 | I_dsrelu=45, 48 | I_ddsrelu=46, 49 | I_relu=47, 50 | I_heaviside=48, 51 | I_zero=49, 52 | I_componentwise=50, 53 | I_luS2A=51, 54 | I_luS2Asym=52, 55 | I_mldivideA2F1=53, 56 | I_mldivideA2Fn=54, 57 | I_Mnorm2=55, 58 | I_Mnorm1=56, 59 | I_Mnorminf=57, 60 | I_Mplus=58, 61 | I_Mmtimes=59, 62 | I_Mtimes=60, 63 | I_Msum=61, 64 | I_Mmin=62, 65 | I_Mmin2=63, 66 | I_Mmax=64, 67 | I_Mmax2=65, 68 | I_Mones=66, 69 | I_Mzeros=67, 70 | I_Meye=68, 71 | I_Mdiag=69, 72 | I_Mclp=70, 73 | I_Mctranspose=71, 74 | I_Msubsref=72, 75 | I_Mtprod=73, 76 | I_Mtprod_matlab=74, 77 | I_Mpermute_matlab=75, 78 | I_Mfull=76, 79 | I_Mreshape=77, 80 | I_Mvec2tensor=78, 81 | I_Mrepmat=79, 82 | I_Mcat=80, 83 | I_Mlu=81, 84 | I_Mlu_l=82, 85 | I_Mlu_u=83, 86 | I_Mlu_d=84, 87 | I_Mlu_sym=85, 88 | I_Mldl=86, 89 | I_Mldl_d=87, 90 | I_Mldl_l=88, 91 | I_Mchol=89, 92 | I_Mdet_ldl=90, 93 | I_Mdet_lu=91, 94 | I_Mlogdet_ldl=92, 95 | I_Mlogdet_lu=93, 96 | I_Minv_ldl=94, 97 | I_Minv_lu=95, 98 | I_Mmldivide_l1=96, 99 | I_Mmldivide_u=97, 100 | I_Mmldivide_u1=98, 101 | I_Mmldivide_d=99, 102 | I_Mmldivide_lu=100, 103 | I_Mrdivide=101, 104 | I_Mcompose=102, 105 | I_Mcomponentwise=103, 106 | } instructionType_t; 107 | // profile defines 108 | #define P_nsum 1 109 | #define P_nprod 2 110 | #define P_ndiv 3 111 | #define P_nif 4 112 | #define P_nclp 5 113 | #define P_nabs 6 114 | #define P_nround 7 115 | #define P_nceil 8 116 | #define P_nfloor 9 117 | #define P_nsign 10 118 | #define P_nsqrt 11 119 | #define P_npow 12 120 | #define P_ntrig 13 121 | #define P_nlog 14 122 | #define P_nexp 15 123 | #define P_cpwise 16 124 | #define P_numfpack 17 125 | #define P_nCountFlops 17 126 | -------------------------------------------------------------------------------- /lib/cube.m: -------------------------------------------------------------------------------- 1 | function y=cube(x) 2 | % y=cube(x) 3 | % 4 | % returns the element-wise cube of x 5 | % 6 | % This file is part of Tencalc. 7 | % 8 | % Copyright (C) 2012-21 The Regents of the University of California 9 | % (author: Dr. Joao Hespanha). All rights reserved. 10 | 11 | y=x.^3; 12 | end 13 | 14 | -------------------------------------------------------------------------------- /lib/isTcalculus.m: -------------------------------------------------------------------------------- 1 | function bool=isTcalculus(obj) 2 | % 3 | % This file is part of Tencalc. 4 | % 5 | % Copyright (C) 2012-21 The Regents of the University of California 6 | % (author: Dr. Joao Hespanha). All rights reserved. 7 | 8 | bool=false; 9 | end -------------------------------------------------------------------------------- /lib/logdet.m: -------------------------------------------------------------------------------- 1 | function y=logdet(A) 2 | % logdet - Natural logarithm of the determinant of a matrix 3 | % 4 | % logdet(A) returns the natural logarithm of the determinant of the 5 | % square matrix A. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | warning('this is a very bad way to cpmpute log-det\n'); 13 | y=log(det(A)); 14 | end 15 | -------------------------------------------------------------------------------- /lib/memory2subscript.m: -------------------------------------------------------------------------------- 1 | function subscripts=memory2subscript(tsize,linear) 2 | % subscripts=memory2subscript(tsize,linear) 3 | % Returns an array of 1-based subscripts, corresponding to 1-based linear indexing 4 | % for a tensor of size 'tsize'. 5 | % Somewhat similar to Matlab's 'ind2sub' but returns a matrix with the subcripts. 6 | % Inputs: 7 | % tsize (1xn) - tensor size 8 | % linear (1xN) - vector with 1-based indexes into the tensor 9 | % Output: 10 | % subscripts (nxN) - matrix with 1-based subscripts, each column corresonding 11 | % to one entry of tsize 12 | % 13 | % This file is part of Tencalc. 14 | % 15 | % Copyright (C) 2012-21 The Regents of the University of California 16 | % (author: Dr. Joao Hespanha). All rights reserved. 17 | 18 | subscripts=zeros(length(tsize),length(linear),'uint64'); 19 | k=[1 cumprod(tsize(1:end-1))]; 20 | for i = length(tsize):-1:1, 21 | vi = rem(linear-1, k(i)) + 1; 22 | subscripts(i,:) = 1+(linear - vi)'/k(i) ; 23 | linear = vi; 24 | end 25 | end -------------------------------------------------------------------------------- /lib/myeye.m: -------------------------------------------------------------------------------- 1 | function obj=myeye(osize) 2 | % var = myeye([]) 3 | % var = myeye([n1,n2,...,na,n1,n2,...,na]) 4 | % Returns an identity tensor. The integers n1,n2,...,na specify the 5 | % dimension of each index of the tensor. Note that an identity 6 | % tensor is expected to have the first half of the dimensions equal 7 | % to the second half. 8 | % 9 | % This file is part of Tencalc. 10 | % 11 | % Copyright (C) 2012-21 The Regents of the University of California 12 | % (author: Dr. Joao Hespanha). All rights reserved. 13 | 14 | if isempty(osize) 15 | obj=1; 16 | return; 17 | end 18 | ind1=1:length(osize)/2; 19 | ind2=ind1(end)+1:length(osize); 20 | if length(ind1)~=length(ind2) 21 | osize 22 | ind1,ind2 23 | error('eye matrix must have an even number of indices'); 24 | end 25 | if ~isequal(osize(ind1),osize(ind2)) 26 | osize,ind1,ind2 27 | error('first and second half of dimensions for eye matrix must correspond to compatible sizes'); 28 | end 29 | obj = zeros(osize); 30 | if 1 31 | k=(1:osize(ind1(1)))'; 32 | for i=2:length(ind1) 33 | k=[kron(ones(osize(ind1(i)),1),k),kron((1:osize(ind1(i)))',ones(size(k,1),1))]; 34 | end 35 | kk=cell(size(k,2),1); 36 | for i=1:size(k,2) 37 | kk{i}=k(:,i); 38 | end 39 | ind=sub2ind(osize,kk{:},kk{:}); 40 | obj(ind)=1; 41 | else 42 | % untested but should be faster 43 | osize1=osize(1:length(osize)/2) 44 | sub1=memory2subscript(osize1,1:prod(osize1)) 45 | [sub1;sub1] 46 | ind=sub2ind(osize,sub1,sub1) 47 | error 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /lib/myisequal.m: -------------------------------------------------------------------------------- 1 | function bool=myisequal(a,b) 2 | % version of the matlab function isqual that deals correctly with 3 | % empty arrays (e.g., [] == ones(1,0)) 4 | % 5 | % This file is part of Tencalc. 6 | % 7 | % Copyright (C) 2012-21 The Regents of the University of California 8 | % (author: Dr. Joao Hespanha). All rights reserved. 9 | 10 | if isempty(a) && isempty(b) 11 | bool=true; 12 | return 13 | end 14 | bool=isequal(a,b); 15 | end 16 | -------------------------------------------------------------------------------- /lib/norm2.m: -------------------------------------------------------------------------------- 1 | function obj=norm2(obj1,S) 2 | % norm2 - Squared quadratic norm 3 | % 4 | % norm2(x) returns the sum of the square of all entries of 5 | % the tensor x, which for matrices corresponds to the square 6 | % of the Frobenius norm of x. 7 | % 8 | % norm2(x,S) returns the value of the quadratic form . This 9 | % form is only applicable when x is a vector (tensor with 1 10 | % dimension) and S a square matrix (tensor with 2 dimensions). 11 | % 12 | % This file is part of Tencalc. 13 | % 14 | % Copyright (C) 2012-21 The Regents of the University of California 15 | % (author: Dr. Joao Hespanha). All rights reserved. 16 | 17 | if nargin<2 18 | obj=sum(obj1(:).^2); 19 | else 20 | mx=size(obj1); 21 | ms=size(S); 22 | if length(mx)==2 && length(ms)==2 && mx(2)==1 && ms(1)==mx(1) && ms(2)==mx(1) 23 | obj=obj1'*S*obj1; 24 | else 25 | error('norm2: norm2(x,S) called with x[%s] not a column vector and/or S[%s] not a square matrix of compatible size\n',index2str(size(obj1)),index2str(size(S))); 26 | end 27 | end 28 | 29 | end 30 | -------------------------------------------------------------------------------- /lib/packExpressions.m: -------------------------------------------------------------------------------- 1 | function outputExpression=packExpressions(inputExpressions) 2 | % outputExpression=packExpressions(inputExpressions) 3 | % 4 | % Takes as inputs a cell array of Tcalculus expressions and creates a 5 | % single Tcalculus vector (1-index) that is obtained by reshaping all 6 | % the input variables to vectors and stacking them all on top of each 7 | % other. 8 | % 9 | % This file is part of Tencalc. 10 | % 11 | % Copyright (C) 2012-21 The Regents of the University of California 12 | % (author: Dr. Joao Hespanha). All rights reserved. 13 | 14 | if isempty(inputExpressions) 15 | %warning('packExpression: packing an empty input expression\n'); 16 | outputExpression=Tconstant([],[0]); 17 | else 18 | for k=1:length(inputExpressions) 19 | inputExpressions{k}=reshape(inputExpressions{k},prod(size(inputExpressions{k}))); 20 | end 21 | outputExpression=cat(1,inputExpressions{:}); 22 | end 23 | end -------------------------------------------------------------------------------- /lib/packVariables.m: -------------------------------------------------------------------------------- 1 | function [outVariable,whereVariables,packCmd,unpackCmd,varargout]=packVariables(inVariables,outVariableName,varargin) 2 | % [outVariable,whereVariables,packCmd,unpackCmd,out1,out2,... ]=packvariables(inVariables,outVariableName,in1,in2,...) 3 | % 4 | % Takes as inputs a cell array of Tcalculus input variables 5 | % 'inVariables' and creates a single Tcalculus vector (1-index) 6 | % 'outVariable' (named 'outVariableName') that is obtained by 7 | % reshaping all the input variables to vectors and stacking them all 8 | % on top of each other. 9 | % 10 | % The input variables in 'inVariables' are then replaced in all the 11 | % Tcalculus expressions 12 | % in1,in2,... 13 | % to create new Tcalculus expressions 14 | % out1,out2,... 15 | % whose dependence on the input variables in 'inVariables' has been 16 | % replaced by approproate dependences on the 'outVariable'. 17 | % See 'help Tcalculus/substitute' 18 | % 19 | % The output 'whereVariables' is a cell array with the indices of 20 | % where each variable is stored in 'outVariable' 21 | % 22 | % The outputs 'packCmd' and 'unpackCmd' return strings with MATLAB 23 | % commands that can be used to pack and unpack a cell array of MATLAB 24 | % numerical variables into the vector. 25 | % 26 | % This file is part of Tencalc. 27 | % 28 | % Copyright (C) 2012-21 The Regents of the University of California 29 | % (author: Dr. Joao Hespanha). All rights reserved. 30 | 31 | nowarningsamesize=true; 32 | nowarningever=true; 33 | 34 | verboseLevel=0; 35 | 36 | n=0; 37 | packCmd=sprintf('%s=[',outVariableName); 38 | unpackCmd=''; 39 | whereVariables=cell(length(inVariables),1); 40 | for i=1:length(inVariables) 41 | if ~isequal(inVariables{i}.type,'variable') 42 | inVariables{i} 43 | inVariables{i}.type 44 | error('Can only pack variables (not %s)', inVariables{i}.type); 45 | end 46 | len=prod(size(inVariables{i})); 47 | packCmd=sprintf('%sreshape(%s,%d,1);',packCmd,name(inVariables{i}),len); 48 | unpackCmd=sprintf('%s%s=reshape(%s(%d:%d),%s);',... 49 | unpackCmd,inVariables{i}.name,outVariableName,n+1,n+len,... 50 | index2str(msize(inVariables{i}))); 51 | whereVariables{i}=n+1:n+len; 52 | n=n+len; 53 | end 54 | packCmd=[packCmd,']']; 55 | 56 | outVariable=Tvariable(outVariableName,n,nowarningsamesize,nowarningever); 57 | 58 | if verboseLevel>0 59 | global substituteCounter; 60 | substituteCounter=0; 61 | end 62 | 63 | varargout={}; 64 | for i=1:length(varargin) 65 | varargout{i}=substitute(varargin{i},inVariables,outVariable); 66 | end 67 | if verboseLevel>0 68 | fprintf(' packVariables: %d substitutions\n',substituteCounter); 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/pdist2t.m: -------------------------------------------------------------------------------- 1 | function dist2=pdist2t(X,Y,method) 2 | % dist2=pdist2t(X,Y) 3 | % 4 | % Returns the square of the Euclidean distances between points in 5 | % two vectors: 6 | % 7 | % Inputs: 8 | % X - N x Nx matrix with Nx points in N-dimensional space 9 | % Y - N x Ny matrix with Ny points in N-dimensional space 10 | % 11 | % Outputs: 12 | % dist2 - NxM matrix with the square of the Euclidean distances 13 | % between the points X and Y 14 | % 15 | % Attention: this function is inpired by Matlab's pdist2, but 16 | % differs from it in the following aways: 17 | % 1) the input matrices X & Y are transposed 18 | % 3) only works with squaredeuclidean (smooth) 19 | % 20 | % This file is part of Tencalc. 21 | % 22 | % Copyright (C) 2012-21 The Regents of the University of California 23 | % (author: Dr. Joao Hespanha). All rights reserved. 24 | 25 | if nargin<3 26 | method='euclidean'; 27 | end 28 | 29 | [N,Nx]=size(X); 30 | [n,Ny]=size(Y); 31 | 32 | if ~isequal(N,n) 33 | error('mismatch between dimensions of X ([%s]) and Y ([%s])\n',... 34 | index2str(size(X)),index2str(size(Y))); 35 | end 36 | 37 | switch method 38 | case 'squaredeuclidean' 39 | if isequal(class(X),'Tcalculus') || isequal(class(Y),'Tcalculus') 40 | relPos=repmat(reshape(X,[N,Nx,1]),[1,1,Ny])-repmat(reshape(Y,[N,1,Ny]),[1,Nx,1]); 41 | dist2=sum(sqr(relPos),1); 42 | else 43 | dist2=pdist2(X',Y',method); 44 | end 45 | otherwise 46 | fprintf('method ''%s'' not implemented for Tcalculus/pdist2t (use ''squaredeuclidean'')\n',... 47 | method); 48 | end 49 | 50 | end 51 | -------------------------------------------------------------------------------- /lib/private/checkOutputExpressions.m: -------------------------------------------------------------------------------- 1 | function [outputExpressions,outputNames]=checkOutputExpressions(outputExpressions) 2 | % This file is part of Tencalc. 3 | % 4 | % Copyright (C) 2012-21 The Regents of the University of California 5 | % (author: Dr. Joao Hespanha). All rights reserved. 6 | 7 | if ~iscell(outputExpressions) && ~isstruct(outputExpressions) 8 | outputExpressions 9 | error('outputExpressions must be a cell array of Tcalculus variables'); 10 | end 11 | 12 | if iscell(outputExpressions) 13 | outputNames=cell(length(outputExpressions),1); 14 | for i=1:length(outputExpressions) 15 | outputNames{i}=sprintf('y%d',i); 16 | if ~ismember(class(outputExpressions{i}),{'Tcalculus','double'}) 17 | outputExpressions{i} 18 | error('outputExpression{%d} is not a Tcalculus variable',i); 19 | end 20 | end 21 | else 22 | outputNames=fields(outputExpressions); 23 | for i=1:length(outputNames) 24 | if ~ismember(class(outputExpressions.(outputNames{i})),{'Tcalculus','double'}) 25 | outputExpressions.(outputNames{i}) 26 | error('outputExpression.%s is not a Tcalculus variable',outputNames{i}); 27 | end 28 | end 29 | outputExpressions=struct2cell(outputExpressions); 30 | end 31 | [outputExpressions{:}]=toCalculus(outputExpressions{:}); 32 | outputExpressions=outputExpressions(:); 33 | outputNames=outputNames(:); 34 | end -------------------------------------------------------------------------------- /lib/private/checkParameters.m: -------------------------------------------------------------------------------- 1 | function parameters=checkParameters(parameters) 2 | % This file is part of Tencalc. 3 | % 4 | % Copyright (C) 2012-21 The Regents of the University of California 5 | % (author: Dr. Joao Hespanha). All rights reserved. 6 | 7 | if isa(parameters,'Tcalculus') 8 | parameters={parameters}; 9 | end 10 | 11 | if isa(parameters,'struct') 12 | parameters=struct2cell(parameters); 13 | end 14 | 15 | if ~iscell(parameters) 16 | parameters 17 | error('parameters must be a cell array of Tcalculus variables'); 18 | end 19 | 20 | for i=1:length(parameters) 21 | if ~isequal(class(parameters{i}),'Tcalculus') 22 | parameters{i} 23 | error('all parameters must be of the type ''variable'' (%dth is of type ''%s'')\n',... 24 | i,class(parameters{i})); 25 | end 26 | if ~isequal(type(parameters{i}),'variable') 27 | parameters{i} 28 | error('all parameters must be of the type ''variable'' (%dth is of type ''%s'')\n',... 29 | i,type(parameters{i})); 30 | end 31 | end 32 | 33 | end -------------------------------------------------------------------------------- /lib/private/packVariables.m: -------------------------------------------------------------------------------- 1 | function [outVariable,whereVariables,packCmd,unpackCmd,varargout]=packVariables(inVariables,outVariableName,varargin) 2 | % [outVariable,whereVariables,packCmd,unpackCmd,out1,out2,... ]=packvariables(inVariables,outVariableName,in1,in2,...) 3 | % 4 | % Takes as inputs a cell array of Tcalculus input variables 5 | % 'inVariables' and creates a single Tcalculus vector (1-index) 6 | % 'outVariable' (named 'outVariableName') that is obtained by 7 | % reshaping all the input variables to vectors and stacking them all 8 | % on top of each other. 9 | % 10 | % The input variables in 'inVariables' are then replaced in all the 11 | % Tcalculus expressions 12 | % in1,in2,... 13 | % to create new Tcalculus expressions 14 | % out1,out2,... 15 | % whose dependence on the input variables in 'inVariables' has been 16 | % replaced by approproate dependences on the 'outVariable'. 17 | % See 'help Tcalculus/substitute' 18 | % 19 | % The output 'whereVariables' is a cell array with the indices of 20 | % where each variable is stored in 'outVariable' 21 | % 22 | % The outputs 'packCmd' and 'unpackCmd' return strings with MATLAB 23 | % commands that can be used to pack and unpack a cell array of MATLAB 24 | % numerical variables into the vector. 25 | % 26 | % This file is part of Tencalc. 27 | % 28 | % Copyright (C) 2012-21 The Regents of the University of California 29 | % (author: Dr. Joao Hespanha). All rights reserved. 30 | 31 | nowarningsamesize=true; 32 | nowarningever=true; 33 | 34 | verboseLevel=0; 35 | 36 | n=0; 37 | packCmd=sprintf('%s=[',outVariableName); 38 | unpackCmd=''; 39 | whereVariables=cell(length(inVariables),1); 40 | for i=1:length(inVariables) 41 | if ~isequal(inVariables{i}.type,'variable') 42 | inVariables{i} 43 | inVariables{i}.type 44 | error('Can only pack variables (not %s)',inVariables{i}.type); 45 | end 46 | len=prod(size(inVariables{i})); 47 | packCmd=sprintf('%sreshape(%s,%d,1);',packCmd,name(inVariables{i}),len); 48 | unpackCmd=sprintf('%s%s=reshape(%s(%d:%d),%s);',... 49 | unpackCmd,inVariables{i}.name,outVariableName,n+1,n+len,... 50 | index2str(msize(inVariables{i}))); 51 | whereVariables{i}=n+1:n+len; 52 | n=n+len; 53 | end 54 | 55 | packCmd=[packCmd,']']; 56 | 57 | outVariable=Tvariable(outVariableName,n,nowarningsamesize,nowarningever); 58 | 59 | if verboseLevel>0 60 | global substituteCounter; 61 | substituteCounter=0; 62 | end 63 | 64 | varargout={}; 65 | for i=1:length(varargin) 66 | varargout{i}=substitute(varargin{i},inVariables,outVariable); 67 | end 68 | if verboseLevel>0 69 | fprintf(' packVariables: %d substitutions\n',substituteCounter); 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /lib/private/storeExpressions.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | %%% Storage of intermediate expressions 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | % 5 | % This file is part of Tencalc. 6 | % 7 | % Copyright (C) 2012-21 The Regents of the University of California 8 | % (author: Dr. Joao Hespanha). All rights reserved. 9 | 10 | classdef storeExpressions < handle 11 | 12 | properties 13 | prefix=''; 14 | functions={}; 15 | expressions={}; 16 | constants={}; 17 | end 18 | 19 | methods 20 | 21 | function obj=storeExpressions(prefix) 22 | if nargin>0 23 | obj.prefix=prefix; 24 | end 25 | end 26 | 27 | function fname=storeConstant(store,fun) 28 | 29 | for i=1:size(store.constants,1) 30 | if strcmp(store.constants{i,2},fun) 31 | fname=store.constants{i,1}; 32 | return 33 | end 34 | end 35 | fname=sprintf('%sc%d',store.prefix,size(store.constants,1)); 36 | store.constants(end+1,:)={fname,fun}; 37 | 38 | end 39 | 40 | function fname=storeExpression(store,fun) 41 | 42 | for i=1:size(store.expressions,1) 43 | if strcmp(store.expressions{i,2},fun) 44 | fname=store.expressions{i,1}; 45 | return 46 | end 47 | end 48 | fname=sprintf('%se%d',store.prefix,size(store.expressions,1)); 49 | store.expressions(end+1,:)={fname,fun}; 50 | 51 | end 52 | 53 | function [strConstants,strExpressions]=str(store) 54 | strConstants=[]; 55 | strExpressions=[]; 56 | for i=1:size(store.constants,1) 57 | strConstants=sprintf('%s %s=%s\n',strConstants,... 58 | store.constants{i,1},store.constants{i,2}); 59 | end 60 | for i=1:size(store.expressions,1) 61 | strExpressions=sprintf('%s %s=%s\n',strExpressions,... 62 | store.expressions{i,1},store.expressions{i,2}); 63 | end 64 | end 65 | 66 | function str=strExpression(store,first) 67 | str=[]; 68 | if nargin<2 69 | first=1; 70 | end 71 | for i=first:size(store.expressions,1) 72 | str=sprintf('%s %s=%s\n',str,... 73 | store.expressions{i,1},store.expressions{i,2}); 74 | end 75 | end 76 | 77 | function disp(store) 78 | [strConstants,strExpressions]=str(store); 79 | if ~isempty(strConstants) 80 | fprintf('constants:\n'); 81 | disp(strConstants) 82 | end 83 | if ~isempty(strExpressions) 84 | fprintf('expressions:\n'); 85 | disp(strExpressions) 86 | end 87 | end 88 | end 89 | end -------------------------------------------------------------------------------- /lib/private/variableIndices.m: -------------------------------------------------------------------------------- 1 | function isSensitivity=variableIndices(u,optimizationVariables,whereVariables,sensitivityVariables) 2 | % find indices of sensitivity variables in u 3 | % 4 | % This file is part of Tencalc. 5 | % 6 | % Copyright (C) 2012-21 The Regents of the University of California 7 | % (author: Dr. Joao Hespanha). All rights reserved. 8 | 9 | isSensitivity=false(length(u),1); 10 | 11 | for i=1:length(sensitivityVariables) 12 | if strcmp(type(sensitivityVariables{i}),'subsref') 13 | S=parameters(sensitivityVariables{i}); 14 | sensitivityVariables{i}=Tcalculus(operands(sensitivityVariables{i})); 15 | ind=1:prod(size(sensitivityVariables{i})); 16 | ind=reshape(ind,msize(sensitivityVariables{i})); 17 | ind=subsref(ind,S); 18 | else 19 | ind=-1; 20 | end 21 | if ~strcmp(type(sensitivityVariables{i}),'variable') 22 | sensitivityVariables{i} 23 | error('all sensitivityVariables must be of the type ''variable'' (%dth is of type ''%s'')\n',... 24 | i,type(sensitivityVariables{i})); 25 | end 26 | found=false; 27 | for j=1:length(optimizationVariables) 28 | if isequal(sensitivityVariables{i},optimizationVariables{j}) 29 | if ind<0 30 | fprintf(' sensitivityVariable %s: %d values\n',sensitivityVariables{i}.name,length(whereVariables{j})); 31 | isSensitivity(whereVariables{j})=true; 32 | else 33 | fprintf(' sensitivityVariable %s[...]: %d values\n',sensitivityVariables{i}.name,length(whereVariables{j}(ind))); 34 | isSensitivity(whereVariables{j}(ind))=true; 35 | end 36 | found=true; 37 | break; 38 | end 39 | end 40 | if ~found 41 | error('sensitivityVariable %s is not an optimizationVariable\n',name(sensitivityVariables{i})); 42 | end 43 | end 44 | if any(isSensitivity) 45 | fprintf(' %d sensitivity variables\n',sum(isSensitivity)); 46 | end 47 | end -------------------------------------------------------------------------------- /lib/relu.m: -------------------------------------------------------------------------------- 1 | function y=relu(x) 2 | % relu - Rectified linear unit activation function. 3 | % 4 | % relu(X) returns a tensor with the same size as X, with 5 | % each entry equal the the corresponding entry of X or 0, 6 | % depending on whether the entry is positive or not. Same 7 | % as max(X,0). 8 | % 9 | % This file is part of Tencalc. 10 | % 11 | % Copyright (C) 2012-21 The Regents of the University of California 12 | % (author: Dr. Joao Hespanha). All rights reserved. 13 | 14 | y=max(x,0); 15 | end -------------------------------------------------------------------------------- /lib/rm_tmps.m: -------------------------------------------------------------------------------- 1 | % Removes from the current directory all solvers whose names start with 'tmp' 2 | % 3 | % This file is part of Tencalc. 4 | % 5 | % Copyright (C) 2012-21 The Regents of the University of California 6 | % (author: Dr. Joao Hespanha). All rights reserved. 7 | 8 | % erase all objects before erasing classes 9 | clear all; 10 | 11 | % remove previous solvers from current directory 12 | delete('toremove.m','tmp*'); 13 | rc=rmdir('@tmp*','s'); 14 | 15 | 16 | -------------------------------------------------------------------------------- /lib/serialize.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hespanha/tenscalc/0632eb83d6be854406f4d3794bb4e92221fdbc13/lib/serialize.m -------------------------------------------------------------------------------- /lib/sqr.m: -------------------------------------------------------------------------------- 1 | function y=sqr(x) 2 | % sqr - Square of tensor entries 3 | % 4 | % sqr(X) returns the element-wise square of X, i.e., X.^2 or X.*X 5 | % 6 | % This file is part of Tencalc. 7 | % 8 | % Copyright (C) 2012-21 The Regents of the University of California 9 | % (author: Dr. Joao Hespanha). All rights reserved. 10 | 11 | y=x.^2; 12 | end 13 | 14 | -------------------------------------------------------------------------------- /lib/srelu.m: -------------------------------------------------------------------------------- 1 | function y=srelu(x) 2 | % srelu - Soft rectified linear unit activation function. 3 | % 4 | % srelu(X) returns a tensor with the same size as X, with 5 | % the "soft" rectified linear unit activation function of 6 | % the entries of X. Same as log(1+exp(x)) or 7 | % x+Log(1+exp(-x)) 8 | % 9 | % This file is part of Tencalc. 10 | % 11 | % Copyright (C) 2012-21 The Regents of the University of California 12 | % (author: Dr. Joao Hespanha). All rights reserved. 13 | 14 | y=log(1+exp(x)); 15 | end -------------------------------------------------------------------------------- /lib/subscript2memory.m: -------------------------------------------------------------------------------- 1 | function linear=subscript2memory(tsize,subscript) 2 | % linear=subscript2memory(tsize,subscript) 3 | % Returns an array of 1-based linear indexing, corresponding to 1-based subscripts, 4 | % for a tensor of size 'tsize'. 5 | % Somewhat similar to Matlab's 'sub2ind' but takes a matrix with the subcripts. 6 | % Inputs: 7 | % tsize (1xn) - tensor size 8 | % subscripts (nxN) - matrix with 1-based subscripts, each column corresonding 9 | % to one entry of tsize 10 | % Output: 11 | % linear (1xN) - vector with 1-based indexes into the tensor 12 | % 13 | % This file is part of Tencalc. 14 | % 15 | % Copyright (C) 2012-21 The Regents of the University of California 16 | % (author: Dr. Joao Hespanha). All rights reserved. 17 | 18 | linear=ones(1,size(subscript,2),'uint64'); 19 | k=uint64([1 cumprod(tsize(1:end-1))]); 20 | subscript=uint64(subscript); 21 | for i = length(tsize):-1:1, 22 | linear=linear+(subscript(i,:)-1)*k(i); 23 | end 24 | end -------------------------------------------------------------------------------- /lib/toCalculus.m: -------------------------------------------------------------------------------- 1 | function varargout=toCalculus(varargin) 2 | % [aa,bb,...] = Tconstant(a,b,...) 3 | % 4 | % Converts its argument in TC tensors. If the arguments are already 5 | % TC tensors they remain unchnaged; otherwise they are converted to 6 | % TC tensors using Tconstant. 7 | % 8 | % This file is part of Tencalc. 9 | % 10 | % Copyright (C) 2012-21 The Regents of the University of California 11 | % (author: Dr. Joao Hespanha). All rights reserved. 12 | 13 | varargout=varargin; 14 | for i=1:length(varargin) 15 | if isa(varargin{i},'Tcalculus') 16 | continue; 17 | elseif isnumeric(varargin{i}) 18 | varargout{i}=Tconstant(varargin{i}); 19 | updateFile2table(varargout{i},2); 20 | else 21 | varargin{i} 22 | error('toCalculus: cannot convert class ''%s'' to ''Tcalculus''',class(varargin{i})); 23 | end 24 | end 25 | end 26 | 27 | -------------------------------------------------------------------------------- /lib/tprod.m: -------------------------------------------------------------------------------- 1 | function y=tprod(varargin) 2 | % 3 | % This file is part of Tencalc. 4 | % 5 | % Copyright (C) 2012-21 The Regents of the University of California 6 | % (author: Dr. Joao Hespanha). All rights reserved. 7 | 8 | y=mytprod(varargin{:}); 9 | 10 | end 11 | 12 | -------------------------------------------------------------------------------- /lib/traceinv.m: -------------------------------------------------------------------------------- 1 | function y=traceinv(A) 2 | % traceinv - Trace of the inverse of a matrix 3 | % 4 | % traceinv(lu(A)) or traceinv(ldl(A)) return the natural 5 | % logarithm of the determinant of the square matrix A. 6 | % 7 | % This file is part of Tencalc. 8 | % 9 | % Copyright (C) 2012-21 The Regents of the University of California 10 | % (author: Dr. Joao Hespanha). All rights reserved. 11 | 12 | y=trace(inv(A)); 13 | end 14 | -------------------------------------------------------------------------------- /lib/tsCross.m: -------------------------------------------------------------------------------- 1 | function [y,ts]=tsCross(x1,x2,ts); 2 | % [y,ts]=tsCross(x1,x2,ts); 3 | % 4 | % Computes a scalar-valued time-series (y,ts) that represents the 5 | % cross product of two n-vector time-series (x1,ts) and (x2,ts) 6 | % 7 | % Inputs: 8 | % x1 [3 x N] - values of the 1st time series at the given times 9 | % (one time per column) 10 | % x2 [3 x N] - values of the 2nd time series at the given times 11 | % (one time per column) 12 | % ts [N x 1] - vector of times 13 | % (for TC variables size(ts)=N) 14 | % 15 | % Output 16 | % y [3 x N] - values of the dot product at the given times 17 | % (one time per column) 18 | % ts [N x 1] - vector of times (equal to the corresponding input) 19 | % 20 | % This file is part of Tencalc. 21 | % 22 | % Copyright (C) 2012-21 The Regents of the University of California 23 | % (author: Dr. Joao Hespanha). All rights reserved. 24 | 25 | if nargin<3 26 | ts=(1:size(x1,2))'; 27 | else 28 | ts=ts(:); 29 | end 30 | 31 | if length(size(x1))~=2 || length(size(x2))~=2 || size(x1,1)~=3 || size(x2,1)~=3 32 | error('tsCross: inputs must be time series of 3-vectors ([%s],[%s])\n',... 33 | index2str(size(x1)),index2str(size(x2))); 34 | end 35 | 36 | if length(ts)~=size(x1,2) || length(ts)~=size(x2,2) 37 | error('tsCross: length of sample times does not match size of inputs (%d,[%s],[%s])\n',... 38 | length(ts),index2str(size(x1)),index2str(size(x2))); 39 | end 40 | 41 | if isequal(class(x1),'Tcalculus') || isequal(class(x2),'Tcalculus') 42 | % y=[x1(2,:).*x2(3,:)-x1(3,:).*x2(2,:); 43 | % x1(3,:).*x2(1,:)-x1(1,:).*x2(3,:); 44 | % x1(1,:).*x2(2,:)-x1(2,:).*x2(1,:);]; 45 | y=x1([2,3,1],:).*x2([3,1,2],:)-x1([3,1,2],:).*x2([2,3,1],:); 46 | else 47 | y=cross(x1,x2,1); 48 | end 49 | end 50 | 51 | function test 52 | % Numeric 53 | ts=pi/2:pi/10:4*pi+pi/2; 54 | x=[sin(ts).*cos(ts);cos(ts).*cos(ts);sin(ts)]; 55 | y=tsCross(x,x,ts); 56 | 57 | plot(ts,x','-x',ts,y','-+'); 58 | legend('x1','x2','x3','y1','y2','y3') 59 | 60 | % Symbolic 61 | Tvariable x [3,length(ts)] 62 | y=tsCross(x,x,ts) 63 | end -------------------------------------------------------------------------------- /lib/tsDot.m: -------------------------------------------------------------------------------- 1 | function [y,ts]=tsDot(x1,x2,ts); 2 | % [y,ts]=tsDot(x1,x2,ts); 3 | % 4 | % Computes a scalar-valued time-series (y,ts) that represents the 5 | % dot product of two n-vector time-series (x1,ts) and (x2,ts) 6 | % 7 | % Inputs: 8 | % x1 [n x N] - values of the 1st time series at the given times 9 | % (one time per column) 10 | % x2 [n x N] - values of the 2nd time series at the given times 11 | % (one time per column) 12 | % ts [N x 1] - vector of times 13 | % (for TC variables size(ts)=N) 14 | % 15 | % Output 16 | % y [1 x N] - values of the dot product at the given times 17 | % (for TC variables size(y)=N) 18 | % (one time per column) 19 | % ts [N x 1] - vector of times (equal to the corresponding input) 20 | % 21 | % This file is part of Tencalc. 22 | % 23 | % Copyright (C) 2012-21 The Regents of the University of California 24 | % (author: Dr. Joao Hespanha). All rights reserved. 25 | 26 | if nargin<3 27 | ts=(1:size(x1,2))'; 28 | else 29 | ts=ts(:); 30 | end 31 | 32 | if length(size(x1))~=2 || length(size(x2))~=2 33 | error('tsDot: inputs must be time series of vectors ([%s],[%s])\n',... 34 | index2str(size(x1)),index2str(size(x2))); 35 | end 36 | 37 | if length(ts)~=size(x1,2) || length(ts)~=size(x2,2) 38 | error('tsDot: length of sample times does not match size of inputs (%d,[%s],[%s])\n',... 39 | length(ts),index2str(size(x1)),index2str(size(x2))); 40 | end 41 | 42 | if isequal(class(x1),'Tcalculus') || isequal(class(x2),'Tcalculus') 43 | y=tprod(x1,[-1,1],x2,[-1,1]); 44 | else 45 | %y=sum(x1.*x2,1); 46 | y=mytprod(x1,[-1,1],x2,[-1,1])'; 47 | end 48 | end 49 | 50 | function test 51 | % Numeric 52 | ts=pi/2:pi/10:4*pi+pi/2; 53 | x=[sin(ts).*cos(ts);cos(ts).*cos(ts);sin(ts)]; 54 | y=tsDot(x,x,ts); 55 | 56 | plot(ts,x','-x',ts,y','-+'); 57 | legend('x1','x2','x3','y') 58 | 59 | % Symbolic 60 | Tvariable x [2,length(ts)] 61 | y=tsDot(x,x,ts) 62 | end -------------------------------------------------------------------------------- /lib/tsIntegral.m: -------------------------------------------------------------------------------- 1 | function y=tsIntegral(x,ts); 2 | % y=tsIntegral(x,ts) 3 | % 4 | % Integrates a vector-valued time series using the trapesoidal method. 5 | % 6 | % Inputs: 7 | % x [n x N] - values of the function at the given times 8 | % (one time per column) 9 | % ts [N x 1] - vector of times 10 | % 11 | % Output 12 | % y [n x 1] - integral of the function from ts(1) to ts(N) 13 | % ts [N x 1] - vector of times (equal to the corresponding input) 14 | % 15 | % This file is part of Tencalc. 16 | % 17 | % Copyright (C) 2012-21 The Regents of the University of California 18 | % (author: Dr. Joao Hespanha). All rights reserved. 19 | 20 | if isa(ts,'Tcalculus') 21 | if isempty(size(ts)) 22 | scalarTs=true; 23 | elseif length(size(ts))==1 24 | scalarTs=false; 25 | else 26 | error('tsIntegral: requires Tcalculus times vector to be a scalars or a one-dimensional (not size=[%s])\n',... 27 | index2str(size(ts))); 28 | end 29 | else 30 | if numel(ts)==1 31 | scalarTs=true; 32 | elseif size(ts,2)==numel(ts) 33 | scalarTs=false; 34 | else 35 | error('tsIntegral: requires times vector to be a column vector (not size=[%s])\n',... 36 | index2str(size(ts))); 37 | end 38 | end 39 | 40 | xsize=size(x); 41 | if length(xsize)<1 || length(xsize)>2 42 | error('tsIntegral: only implemented for time series of vectors ([%s])\n',... 43 | index2str(xsize)); 44 | end 45 | 46 | if ~scalarTs && length(ts)~=xsize(end) 47 | error('tsIntegral: length of sample times does not match size of input (%d,[%s])\n',... 48 | length(ts),index2str(xsize)); 49 | end 50 | 51 | if isa(ts,'Tcalculus') 52 | whichtprod=@tprod; 53 | else 54 | whichtprod=@mytprod; 55 | end 56 | 57 | if scalarTs 58 | % not very efficient to create this vector of mostly equal entries 59 | dt=[.5*ts;ts*ones(xsize(end)-2,1);.5*ts]; 60 | y=whichtprod(dt,-1,x,[1:length(xsize)-1,-1]); 61 | else 62 | dt=.5*[ts(2)-ts(1);ts(3:end)-ts(1:end-2);ts(end)-ts(end-1)]; 63 | y=whichtprod(dt,-1,x,[1:length(xsize)-1,-1]); 64 | end 65 | end 66 | 67 | function test 68 | % Numeric 69 | ts=pi/2:pi/10:4*pi+pi/2; 70 | x=[sin(ts);cos(ts)]; 71 | 72 | plot(ts,x','-x'); 73 | legend('sin','cos') 74 | 75 | y=tsIntegral(x,ts) 76 | 77 | % Symbolic 78 | Tvariable x [2,length(ts)] 79 | y=tsIntegral(x,ts) 80 | end 81 | -------------------------------------------------------------------------------- /lib/tsIntegrate.m: -------------------------------------------------------------------------------- 1 | function [intX,ts]=tsIntegrate(x,x0,ts,method); 2 | % [intX,ts]=tsIntegrate(x,x0,ts,method); 3 | % 4 | % Integrates a vector-valued time series (x,ts). The time 5 | % derivative is computed assuming that the input time-series is 6 | % piecewise quadratic. 7 | % 8 | % Inputs: 9 | % x [n x N] - values of the function at the given times 10 | % (one time per column) 11 | % x0 [n x 1] - initial value 12 | % ts [N x 1] - vector of times 13 | % or 14 | % ts [1 x 1] - (constant) sample interval 15 | % 16 | % method - integration method (euler, trapesoidal, invtsDerivative) 17 | % 18 | % 19 | % Output 20 | % intX [n x N] - integral of the function at the given times 21 | % (one time per column) 22 | % ts [N x 1] - vector of times (equal to the corresponding input) 23 | % 24 | % This file is part of Tencalc. 25 | % 26 | % Copyright (C) 2012-21 The Regents of the University of California 27 | % (author: Dr. Joao Hespanha). All rights reserved. 28 | 29 | if nargin<4 30 | method='trapesoidal'; 31 | method='euler'; 32 | end 33 | 34 | if isequal(class(ts),'Tcalculus') && length(size(ts))~=1 && ~isempty(size(ts)) 35 | error('tsIntegrate: requires times vector to be scalars or one-dimensional ([%s])\n',... 36 | index2str(size(ts))); 37 | end 38 | 39 | if ~isequal(class(ts),'Tcalculus') && size(ts,2)~=1 40 | error('tsIntegrate: requires times vector to be a column vector ([%s])\n',... 41 | index2str(size(ts))); 42 | end 43 | 44 | if length(size(x))~=2 45 | error('tsIntegrate: only implemented for time series of vectors ([%s])\n',... 46 | index2str(size(x))); 47 | end 48 | 49 | if length(ts)~=1 && length(ts)~=size(x,2) 50 | error('tsIntegrate: length of sample times does not match size of input (%d,[%s])\n',... 51 | length(ts),index2str(size(x))); 52 | end 53 | 54 | if length(ts)>1 55 | switch (method) 56 | case 'euler' 57 | intX=[x0,x0+cumsum(repmat(diff(ts'),size(x,1),1).*x(:,1:end-1),2)]; 58 | otherwise 59 | error('not implemented'); 60 | end 61 | else % if length(ts)>1 62 | switch (method) 63 | case 'euler' 64 | % causal but not quite symmetric 65 | intX=[x0,x0+ts'*cumsum(x(:,1:end-1),2)]; 66 | case 'trapesoidal' 67 | % not quite causal, but more accurate 68 | intX=[x0,x0+(ts/2)*cumsum(x(:,1:end-1)+x(:,2:end),2)]; 69 | case 'invtsDerivative' 70 | % inverse of tsDerivative (up to an errorin sample 71 | % before last) -- introduces high frequency 72 | %x 73 | intXodd=cumsum([x0,2*ts*x(:,2:2:end-1)],2); 74 | intXeven=cumsum([x0+ts/2*(x(:,1)+x(:,2)),2*ts*x(:,3:2:end-1)],2); 75 | intX=zeros(size(x)); 76 | intX(:,1:2:end)=intXodd; 77 | intX(:,2:2:end)=intXeven; 78 | intX(:,end)=(2*intX(:,end-1)-.5*intX(:,end-2)+ts*x(:,end))/1.5; 79 | %intX 80 | otherwise 81 | error('unknown mehtod %s',method); 82 | end 83 | end 84 | end 85 | 86 | function test 87 | % Numeric 88 | ts=pi/2:pi/10:4*pi+pi/2; 89 | x=[sin(ts);cos(ts)]; 90 | intX1=tsIntegrate(x,[0;0],ts'); 91 | intX2=tsIntegrate(x,[0;0],ts(2)-ts(1)); 92 | 93 | plot(ts,x','-x',ts,intX1','-+',ts,intX2','-x'); 94 | legend('sin','cos','d sin','d cos','d sin','d cos') 95 | 96 | % Symbolic 97 | Tvariable x [2,length(ts)] 98 | intX=tsIntegrate(x,[0;0],ts) 99 | end -------------------------------------------------------------------------------- /lib/tsQdot.m: -------------------------------------------------------------------------------- 1 | function [y,ts]=tsQdot(q1,q2,ts); 2 | % [y,ts]=tsQdot(q1,q2,ts); 3 | % 4 | % Computes a 4-vector time-series (y,ts) that represents the product 5 | % of two quaternions (q1,ts), (q2,ts). Specifically, 6 | % y = q1 x q2 7 | % If any of the input quaternions is a 3-vector, it is assumed to be a 8 | % pure quaternion. 9 | 10 | % Inputs: 11 | % q1 [4 x N] - values of the quaternion at the given times 12 | % (one time per column) 13 | % or [3 x N], in which case q1 is a pure quaternion 14 | % q1 [4 x N] - values of the quaternion at the given times 15 | % (one time per column) 16 | % or [3 x N], in which case q2 is a pure quaternion 17 | % ts [N x 1] - vector of times 18 | % 19 | % Output 20 | % y [4 x N] - values of the rotated function at the given times 21 | % (one time per column) 22 | % ts [N x 1] - vector of times (equal to the corresponding input) 23 | % 24 | % This file is part of Tencalc. 25 | % 26 | % Copyright (C) 2012-21 The Regents of the University of California 27 | % (author: Dr. Joao Hespanha). All rights reserved. 28 | 29 | if nargin<3 30 | ts=(1:size(q1,2))'; 31 | else 32 | ts=ts(:); 33 | end 34 | 35 | if length(size(q1))~=2 || size(q1,1)<3 || size(q1,1)>4 36 | error('tsQdot: first input must be a time series of 3-vectors or 4-vectors ([%s])\n',... 37 | index2str(size(q1))); 38 | end 39 | 40 | if length(size(q2))~=2 || size(q2,1)<3 || size(q2,1)>4 41 | error('tsQdot: first input must be a time series of 3-vectors or 4-vectors ([%s])\n',... 42 | index2str(size(q2))); 43 | end 44 | 45 | if length(ts)~=size(q1,2) || length(ts)~=size(q2,2) 46 | error('tsQdot: length of sample times does not match size of inputs (%d,[%s],[%s])\n',... 47 | length(ts),index2str(size(q1)),index2str(size(q2))); 48 | end 49 | 50 | if ~isequal(class(q1),'Tcalculus') && ~isequal(class(q2),'Tcalculus') 51 | whichtprod=@mytprod; 52 | else 53 | whichtprod=@tprod; 54 | end 55 | 56 | % pq=[p0*q0-p'*q; 57 | % q0*p+p0*q+cross(p,q)]; 58 | 59 | if size(q1,1)==4 && size(q2,1)==3 60 | % full x pure quaternion 61 | if isequal(class(q1),'Tcalculus') 62 | q10=reshape(q1(1,:),length(ts)); 63 | else 64 | q10=q1(1,:)'; 65 | end 66 | y=[reshape(-tsDot(q1(2:4,:),q2,ts),1,size(q1,2)); 67 | whichtprod(q10,[2],q2,[1,2])+tsCross(q1(2:4,:),q2,ts)]; 68 | elseif size(q1,1)==4 && size(q2,1)==4 69 | % full x full quaternion 70 | if isequal(class(q1),'Tcalculus') 71 | q10=reshape(q1(1,:),length(ts)); 72 | else 73 | q10=q1(1,:)'; 74 | end 75 | if isequal(class(q2),'Tcalculus') 76 | q20=reshape(q2(1,:),length(ts)); 77 | else 78 | q20=q2(1,:)'; 79 | end 80 | y00=q10.*q20; 81 | if ~isequal(class(y00),'Tcalculus') 82 | y00=y00'; 83 | end 84 | y=[reshape(y00-tsDot(q1(2:4,:),q2(2:4,:),ts),1,size(q1,2)); 85 | whichtprod(q10,[2],q2(2:4,:),[1,2])+whichtprod(q20,[2],q1(2:4,:),[1,2])+tsCross(q1(2:4,:),q2(2:4,:),ts)]; 86 | else 87 | error('tsQdot: not implemented for sizes [%s], [%s]\n', ... 88 | index2str(size(q1)),index2str(size(q2))); 89 | end 90 | end 91 | 92 | function test 93 | % Numeric 94 | ts=pi/2:pi/10:4*pi+pi/2; 95 | x=ones(3,length(ts)) 96 | omega=rand(3,1); 97 | omega=omega/norm(omega,2); 98 | theta=ts; 99 | q=[cos(theta/2);omega*sin(theta/2)]; 100 | y=tsQdot(q,x,ts) 101 | 102 | plot(ts,q','-x',ts,y','-+'); 103 | legend('q1','q2','q3','q4','y1','y2','y3','y4') 104 | 105 | % Symbolic 106 | Tvariable x [3,length(ts)] 107 | Tvariable q [4,length(ts)] 108 | y=tsQdot(q,x,ts) 109 | end -------------------------------------------------------------------------------- /lib/vec2tensor.m: -------------------------------------------------------------------------------- 1 | function y=vec2tensor(obj1,sz,subs,dim) 2 | % vec2tensor - Expands a vector to a sparse tensor 3 | % 4 | % vec2tensor(X,sz,subs), given 5 | % * Tcalculus n-vector X (tensor with size [n]) a 6 | % * vector sz with d integers 7 | % * nxd matrix subs of subscripts 8 | % returns 9 | % * Tcalculus tensor Y with size sz, with the nonzero entries 10 | % taken from X, with 11 | % Y(subs(i,:))=X(i) for i=1:n 12 | % 13 | % vec2tensor(X,sz,subs,dim), given 14 | % * Tcalculus tensor X with size(X,dim)=n 15 | % * vector sz with d integers 16 | % * nxd matrix subs of subscripts 17 | % returns 18 | % * Tcalculus tensor Y with size similar to that of X, but the dim 19 | % dimension expanded to the sizes in sz, and the nonzero entries 20 | % taken from X, with 21 | % Y(...,subs(i,:),...)=X(...,i,...) for i=1:n 22 | % where the ... denote indices of the dimensions before and 23 | % after dim 24 | % 25 | % This file is part of Tencalc. 26 | % 27 | % Copyright (C) 2012-21 The Regents of the University of California 28 | % (author: Dr. Joao Hespanha). All rights reserved. 29 | 30 | if nargin<4 31 | dim=[]; 32 | end 33 | 34 | if ndims(obj1)<1 35 | error('vec2tensor can only be used for tensors with 1 or more dimensions') 36 | end 37 | 38 | if ~isempty(dim) && length(dim)~=1 39 | disp(dim) 40 | error('vec2tensorc''s 4rd argument dim must be a scalar') 41 | end 42 | 43 | if ~isempty(dim) && dim>ndims(obj1) 44 | error('vec2tensor''s 4th argument dim (%d) must be no larger than number of tensor dimensions [%s]\n',... 45 | dim,index2str(size(obj1))) 46 | end 47 | 48 | if length(sz)~=size(subs,2) 49 | error('vec2tensor: length of 2nd argument sz (%d) must match number of columns of 3rd argument subs ([%s])',... 50 | length(sz),index2str(subs)); 51 | end 52 | 53 | osize1=size(obj1); 54 | if size(subs,1)~=osize1(dim) 55 | error('vec2tensor: number of rows of 3rd argument subs (size(subs)=[%s]) must match size(X[%s],dim=%d)',... 56 | index2str(size(subs)),index2str(osize1),dim); 57 | end 58 | 59 | for i=1:length(sz) 60 | if any(subs(:,i)<1) 61 | error('subsref: subscript in dimension %d smaller than 1\n',i); 62 | end 63 | if any(subs(:,i)>sz(i)) 64 | error('vec2tensor: subscript in dimension %d exceeds tensor dimension (%d)\n',i,sz(i)) 65 | end 66 | end 67 | 68 | % convert osize1 to tenscal sizes 69 | if osize1(end)==1 70 | osize1(end)=[]; 71 | end 72 | 73 | osize=[osize1(1:dim-1),sz(:)',osize1(dim+1:end)]; 74 | k=find(obj1); 75 | v=obj1(k); 76 | subscripts=memory2subscript(osize1,k); 77 | if ~isempty(dim) 78 | subscripts=[subscripts(1:dim-1,:); 79 | subs(subscripts(dim,:),:)'; 80 | subscripts(dim+1:end,:)]; 81 | else 82 | subscripts=subs'; 83 | end 84 | 85 | if size(subscripts,1)==2 86 | y=sparse(double(subscripts(1,:)),double(subscripts(2,:)),v,osize(1),osize(2)); 87 | else 88 | k=subscript2memory(osize,subscripts); 89 | % accumulate repeated subscripts 90 | vv=sparse(k,ones(1,numel(k),class(k)),v); 91 | kk=find(vv); 92 | vv=vv(kk); 93 | msize=osize; 94 | while length(msize)<2 95 | msize(end+1)=1; 96 | end 97 | y=zeros(msize); 98 | y(kk)=vv; 99 | end 100 | end -------------------------------------------------------------------------------- /readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | # 5 | # Project at https://readthedocs.org/projects/tenscalc/ 6 | # Required 7 | version: 2 8 | 9 | # Build documentation in the docs/ directory with Sphinx 10 | sphinx: 11 | configuration: doc/sphinx/conf.py 12 | builder: html 13 | fail_on_warning: true 14 | 15 | # Optionally build your docs in additional formats such as PDF and ePub 16 | formats: all 17 | 18 | python: 19 | version: 3.7 20 | install: 21 | - requirements: doc/sphinx/requirements.txt 22 | 23 | --------------------------------------------------------------------------------