1# 2# This file is part of CasADi. 3# 4# CasADi -- A symbolic framework for dynamic optimization. 5# Copyright (C) 2010-2014 Joel Andersson, Joris Gillis, Moritz Diehl, 6# K.U. Leuven. All rights reserved. 7# Copyright (C) 2011-2014 Greg Horn 8# 9# CasADi is free software; you can redistribute it and/or 10# modify it under the terms of the GNU Lesser General Public 11# License as published by the Free Software Foundation; either 12# version 3 of the License, or (at your option) any later version. 13# 14# CasADi is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17# Lesser General Public License for more details. 18# 19# You should have received a copy of the GNU Lesser General Public 20# License along with CasADi; if not, write to the Free Software 21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22# 23# 24# -*- coding: utf-8 -*- 25""" 26Demonstration on how the algorithm of an MX function can be accessed and its operations can be transversed. 27""" 28 29from casadi import * 30import numpy 31 32# Create a function 33a = MX.sym('a') 34b = MX.sym('b',2) 35c = MX.sym('c',2,2) 36f = Function("f", [a,b,c], [3*mtimes(c,b)*a + b], ['a', 'b', 'c'], ['r']) 37 38# Input values of the same dimensions as the above 39input_val = [numpy.array([2.0]),\ 40 numpy.array([3.0,4.0]),\ 41 numpy.array([[5.0,1.0],[8.0,4.0]])] 42 43# Output values to be calculated of the same dimensions as the above 44output_val = [numpy.zeros(2)] 45 46# Work vector 47work = [ None for i in range(f.sz_w())] 48 49# Loop over the algorithm 50for k in range(f.n_instructions()): 51 52 # Get the atomic operation 53 op = f.instruction_id(k) 54 55 o = f.instruction_output(k) 56 i = f.instruction_input(k) 57 58 if(op==OP_CONST): 59 v = f.instruction_MX(k).to_DM() 60 assert v.is_dense() 61 work[o[0]] = np.array(v) 62 print('work[{o[0]}] = {v}'.format(o=o,v=v)) 63 else: 64 if op==OP_INPUT: 65 work[o[0]] = input_val[i[0]] 66 print('work[{o[0]}] = input[{i[0]}] ---> {v}'.format(o=o,i=i,v=work[o[0]])) 67 elif op==OP_OUTPUT: 68 output_val[o[0]] = work[i[0]] 69 print('output[{o[0]}] = work[{i[0]}] ---> {v}'.format(o=o,i=i,v=output_val[o[0]])) 70 elif op==OP_ADD: 71 work[o[0]] = work[i[0]] + work[i[1]] 72 print('work[{o[0]}] = work[{i[0]}] + work[{i[1]}] ---> {v}'.format(o=o,i=i,v=work[o[0]])) 73 elif op==OP_MUL: 74 work[o[0]] = work[i[0]] * work[i[1]] 75 print('work[{o[0]}] = work[{i[0]}] * work[{i[1]}] ---> {v}'.format(o=o,i=i,v=work[o[0]])) 76 elif op==OP_MTIMES: 77 work[o[0]] = np.dot(work[i[1]], work[i[2]])+work[i[0]] 78 print('work[{o[0]}] = work[{i[1]}] @ work[{i[2]}] + work[{i[0]}] ---> {v}'.format(o=o,i=i,v=work[o[0]])) 79 else: 80 disp_in = ["work[" + str(a) + "]" for a in i] 81 debug_str = print_operator(f.instruction_MX(k),disp_in) 82 raise Exception('Unknown operation: ' + str(op) + ' -- ' + debug_str) 83 84print('------') 85print('Evaluated ' + str(f)) 86print('Expected: ', f.call(input_val)) 87print('Got: ', output_val) 88