1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

root/trunk/examples/det_minor.cpp @ 616

Revision 616, 13.0 KB (checked in by janderss, 2 years ago)

some examples

Line 
1/*
2 *    This file is part of CasADi.
3 *
4 *    CasADi -- A symbolic framework for dynamic optimization.
5 *    Copyright (C) 2010 by Joel Andersson, Moritz Diehl, K.U.Leuven. All rights reserved.
6 *
7 *    CasADi is free software; you can redistribute it and/or
8 *    modify it under the terms of the GNU Lesser General Public
9 *    License as published by the Free Software Foundation; either
10 *    version 3 of the License, or (at your option) any later version.
11 *
12 *    CasADi is distributed in the hope that it will be useful,
13 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 *    Lesser General Public License for more details.
16 *
17 *    You should have received a copy of the GNU Lesser General Public
18 *    License along with CasADi; if not, write to the Free Software
19 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20 *
21 */
22
23#include "casadi/sx/sx_matrix.hpp"
24#include "casadi/mx/mx.hpp"
25#include "casadi/stl_vector_tools.hpp"
26#include "casadi/fx/sx_function.hpp"
27#include "casadi/fx/fx.hpp"
28#include <ctime>
29
30using namespace std;
31using namespace CasADi;
32
33/** Determinant example from ADOL-C */
34
35#include <cstdio>
36#include <iostream>
37
38/*----------------------------------------------------------------------------
39 ADOL-C -- Automatic Differentiation by Overloading in C++
40 File:     detexam.cpp
41 Revision: $Id: detexam.cpp 91 2010-02-24 07:56:58Z awalther $
42 Contents: modified computation of determinants
43
44 Copyright (c) Andrea Walther, Andreas Griewank, Andreas Kowarz,
45               Hristo Mitev, Sebastian Schlenkrich, Jean Utke, Olaf Vogel
46 
47 This file is part of ADOL-C. This software is provided as open source.
48 Any use, reproduction, or distribution of the software constitutes
49 recipient's acceptance of the terms of the accompanying license file.
50 
51---------------------------------------------------------------------------*/
52
53/****************************************************************************/
54/*                                                                 INCLUDES */
55//#include <adolc.h>
56//#include <../examples/additional_examples/clock/myclock.h>
57
58
59double myclock(){
60  return clock() / double(CLOCKS_PER_SEC);
61}
62
63
64/****************************************************************************/
65/*                                                           DOUBLE ROUTINE */
66int n,it;
67double** PA;
68double pdet( int k, int m ) {
69    if (m == 0)
70        return 1.0 ;
71    else {
72        double* pt = PA[k-1];
73        double t = 0;
74        int p = 1;
75        int s;
76        if (k%2)
77            s = 1;
78        else
79            s = -1;
80        for (int i=0; i<n; i++) {
81            int p1 = 2*p;
82            if (m%p1 >= p) {
83                if (m == p) {
84                    if (s>0)
85                        t += *pt;
86                    else
87                        t -= *pt;
88                } else {
89                    if (s>0)
90                        t += *pt*pdet(k-1, m-p);
91                    else
92                        t -= *pt*pdet(k-1, m-p);
93                }
94                s = -s;
95            }
96            ++pt;
97            p = p1;
98        }
99        return t;
100    }
101}
102
103/****************************************************************************/
104/*                                                          SX ROUTINE */
105SX** A;
106SX zero = 0;
107SX det( int k, int m ) {
108    if (m == 0)
109        return 1.0;
110    else {
111        SX* pt = A[k-1];
112        SX t = zero;
113        int p = 1;
114        int s;
115        if (k%2)
116            s = 1;
117        else
118            s = -1;
119        for (int i=0; i<n; i++) {
120            int p1 = 2*p;
121            if (m%p1 >= p) {
122                if (m == p) {
123                    if (s>0)
124                        t += *pt;
125                    else
126                        t -= *pt;
127                } else {
128                    if (s>0)
129                        t += *pt*det(k-1, m-p);
130                    else
131                        t -= *pt*det(k-1, m-p);
132                }
133                s = -s;
134            }
135            ++pt;
136            p = p1;
137        }
138        return t;
139    }
140}
141
142/****************************************************************************/
143/*                                                             MAIN PROGRAM */
144int main() {
145    int i, j;
146    int tag = 1;
147    fprintf(stdout,"COMPUTATION OF DETERMINANTS Type 1 (ADOL-C Example)\n\n");
148    fprintf(stdout,"order of matrix = ? \n");
149    scanf("%d",&n);
150    A  = new SX*[n];
151    PA = new double*[n];
152    int n2 = n*n;
153    double* a = new double[n2];
154
155    /*--------------------------------------------------------------------------*/
156    /* Preparation */
157    double diag = 0;
158    int m = 1;
159    double* pa = a;
160    for (i=0; i<n; i++) {
161        m *= 2;
162        PA[i] = new double[n];
163        double* ppt = PA[i];
164        for (j=0; j<n; j++) {
165            *ppt++ = j/(1.0+i);
166            *pa++  = j/(1.0+i);
167        }
168        diag += PA[i][i];   // val corrected to value 2/23/91
169        PA[i][i] += 1.0;
170        a[i*n+i] += 1.0;
171    }
172    diag += 1;
173
174    /*--------------------------------------------------------------------------*/
175    double t0 = myclock();                               /* building graph */
176
177    for (i=0; i<n; i++) {
178        A[i] = new SX[n];
179        SX* pt = A[i];
180    }
181vector<SX> symA(n*n);
182make_symbolic(symA,"A");
183for (int i=0; i<n*n; i++)
184  A[i%n][i/n] = symA[i];
185
186    SX deter;
187    deter = det(n,m-1);
188
189    double t1 = myclock();
190
191
192// making function
193SXFunction fcn(symA,deter);
194fcn.setOption("ad_order",1);
195fcn.init();
196vector<double>& inp = fcn.input().data();
197    for (i=0; i<n; i++) {
198        double* ppt = PA[i];
199        for (j=0; j<n; j++)
200            inp[i+n*j] = *ppt++;
201    }
202
203    double t2 = myclock();
204
205// evaluate
206fcn.evaluate();
207
208
209// get result
210    double detout = 0.0;
211    detout = fcn.output().data()[0];
212
213    double t3 = myclock();
214
215
216// evaluate 100 times
217for(int k=0; k<100; ++k)
218  fcn.evaluate();
219
220  double t4 = myclock();
221
222
223// evaluate 100 times
224fcn.input().dataA()[0] = 1;
225for(int k=0; k<100; ++k)
226  fcn.evaluate(0,1);
227
228  double t5 = myclock();
229
230// evaluate 100 times
231for(int k=0; k<100; ++k)
232  fcn.evaluate(1,0);
233
234  double t6 = myclock();
235
236//    deter >>= detout;
237//    trace_off();
238    fprintf(stdout,"\n %f =? %f should be the same \n",detout,diag);
239//ld " << t1-t0 << endl;
240cout << "time for constructing graph " << t1-t0 << endl;
241cout << "time for making function " << t2-t1 << endl;
242cout << "graph+function+1 evaluation " << t3-t0 << endl;
243cout << "1 evaluation " << (t4-t3)/100 << endl;
244cout << "1 reverse " << (t5-t4)/100 << endl;
245cout << "1 forward " << (t6-t5)/100 << endl;
246
247
248
249#if 0
250
251    /*--------------------------------------------------------------------------*/
252    int tape_stats[STAT_SIZE];
253
254    tapestats(tag,tape_stats);
255
256    fprintf(stdout,"\n    independents            %d\n",tape_stats[NUM_INDEPENDENTS]);
257    fprintf(stdout,"    dependents              %d\n",tape_stats[NUM_DEPENDENTS]);
258    fprintf(stdout,"    operations              %d\n",tape_stats[NUM_OPERATIONS]);
259    fprintf(stdout,"    operations buffer size  %d\n",tape_stats[OP_BUFFER_SIZE]);
260    fprintf(stdout,"    locations buffer size   %d\n",tape_stats[LOC_BUFFER_SIZE]);
261    fprintf(stdout,"    constants buffer size   %d\n",tape_stats[VAL_BUFFER_SIZE]);
262    fprintf(stdout,"    maxlive                 %d\n",tape_stats[NUM_MAX_LIVES]);
263    fprintf(stdout,"    valstack size           %d\n\n",tape_stats[TAY_STACK_SIZE]);
264
265    /*--------------------------------------------------------------------------*/
266    int itu = 8-n;
267    itu = itu*itu*itu*itu;
268    itu = itu > 0 ? itu : 1;
269    double raus;
270
271    /*--------------------------------------------------------------------------*/
272    double t10 = myclock();                             /* 1. time (original) */
273    for (it = 0; it < itu; it++)
274        raus = pdet(n,m-1);
275    double t11 = myclock();
276    double rtu = itu/(t11-t10);
277
278    double* B = new double[n2];
279    double* detaut = new double[1];
280
281    /*--------------------------------------------------------------------------*/
282    double t40 = myclock();                      /* 4. time (forward no keep) */
283    for (it = 0; it < itu; it++)
284        forward(tag,1,n2,0,a,detaut);
285    double t41 = myclock();
286
287    /*--------------------------------------------------------------------------*/
288    double t20 = myclock();                         /* 2. time (forward+keep) */
289    for(it = 0; it < itu; it++)
290        forward(tag,1,n2,1,a,detaut);
291    double t21 = myclock();
292    // fprintf(stdout,"\n %f =? %f should be the same \n",detout,*detaut);
293
294    double u[1];
295    u[0] = 1.0;
296
297    /*--------------------------------------------------------------------------*/
298    double t30 = myclock();                              /* 3. time (reverse) */
299    for (it = 0; it < itu; it++)
300        reverse(tag,1,n2,0,u,B);
301    double t31 = myclock();
302
303    /*--------------------------------------------------------------------------*/
304    /* output of results */
305    // optional generation of tape_doc.tex
306    // tape_doc(tag,1,n2,a,detaut);
307    fprintf(stdout,"\n first base? :   \n");
308    for (i=0; i<n; i++) {
309        adouble sum = 0;
310        adouble* pt;
311        pt = A[i];
312        for (j=0; j<n; j++)
313            sum += (*pt++)*B[j];
314        fprintf(stdout,"%E ",sum.value());
315    }
316    fprintf(stdout,"\n\n times for ");
317    fprintf(stdout,"\n tracing          : \t%E",(t01-t00)*rtu);
318    fprintf(stdout," units \t%E    seconds",(t01-t00));
319    fprintf(stdout,"\n forward (no keep): \t%E",(t41-t40)*rtu/itu);
320    fprintf(stdout," units \t%E    seconds",(t41-t40)/itu);
321    fprintf(stdout,"\n forward + keep   : \t%E",(t21-t20)*rtu/itu);
322    fprintf(stdout," units \t%E    seconds",(t21-t20)/itu);
323    fprintf(stdout,"\n reverse          : \t%E",(t31-t30)*rtu/itu);
324    fprintf(stdout," units \t%E    seconds\n",(t31-t30)/itu);
325
326#endif
327    return 1;
328}
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355#if 0
356int n;
357SX **A;                        // A is an n x n matrix
358SX zero = 0;
359
360SX det(int k, int m)           // k <= n is the order of the submatrix
361{ if (m == 0)                       // its column indices
362        return 1.0;
363    else                              // are encoded in m
364    {
365        SX *pt = A[k-1];
366        SX   t = zero;
367        int p = 1;
368        int s;
369        if (k%2)
370            s = 1;
371        else
372            s = -1;
373        for(int i=0; i<n; i++) {
374            int p1 = 2*p;
375            if (m%p1 >= p) {
376                if (m == p) {
377                    if (s>0)
378                        t += *pt;
379                    else
380                        t -= *pt;
381                } else {
382                    if (s>0)
383                        t += *pt*det(k-1, m-p); // recursive call to det
384                    else
385                        t -= *pt*det(k-1, m-p); // recursive call to det
386                }
387                s = -s;
388            }
389            ++pt;
390            p = p1;
391        }
392        return t;
393    }
394}
395
396int main() {
397  clock_t time1 = clock();
398
399    int i,j, m = 1;
400    int tag = 1;
401    int keep = 1;
402
403    cout << "COMPUTATION OF DETERMINANTS (ADOL-C Documented Example)\n\n";
404    n = 5;
405
406//    cin >> n;
407
408    A = new SX*[n];
409    SX ad;
410
411    SXMatrix Amat("A",n,n);
412    double Aval[n][n];
413
414    double detout = 0.0, diag = 1.0;// here keep the intermediates for
415    for (i=0; i<n; i++)             // the subsequent call to reverse
416    { m *= 2;
417        A[i] = new SX[n];
418        for (j=0; j<n; j++){
419            Aval[i][j] = j/(1.0+i);      // make all elements of A independent
420            A[i][j] = Amat(i,j);
421        }
422        diag += Aval[i][i];       // value(adouble) converts to double
423        A[i][i] += 1.0;
424    }
425    ad = det(n,m-1);                // actual function call.
426
427   clock_t time2 = clock();
428   cout << "graph built after " << (time2-time1)/double(CLOCKS_PER_SEC) << " seconds." << endl;
429
430  // Create a function
431  SXFunction ffcn(Amat,ad);
432  ffcn->initAD(1);
433
434   clock_t time3 = clock();
435   cout << "graph sorted after " << (time3-time1)/double(CLOCKS_PER_SEC) << " seconds." << endl;
436
437  // Give a value
438  vector<double>& ip = ffcn->getInput();
439  for(int i=0; i<n; ++i)
440    for(int j=0; j<n; ++j)
441      ip[j+i*n] = Aval[i][j];
442
443  // Evaluate
444  for(int i=0; i<100; ++i){
445    ffcn->evaluate();
446  }
447
448   clock_t time4 = clock();
449   cout << "function evaluated 100 times after " << (time4-time1)/double(CLOCKS_PER_SEC) << " seconds." << endl;
450
451return 0;
452
453
454  // Get output
455  detout = ffcn->getOutput()[0];
456
457    printf("\n %f - %f = %f  (should be 0)\n",detout,diag,detout-diag);
458
459    double u[1];
460    u[0] = 1.0;
461    double* B = new double[n*n];
462
463    // set a backward seed
464    ffcn->getOutputSeed()[0] = u[0];
465
466    // Evaluate backwards
467    ffcn->evaluateAdj();
468
469    // Get the result
470    vector<double>& ider = ffcn->getInputSeed();
471    for(int i=0; i<n*n; ++i)
472      B[i] = ider[i];
473
474    cout << " \n first base? : ";
475    for (i=0; i<n; i++) {
476        double sum = 0;
477        for (j=0; j<n; j++)             // the matrix A times the first n
478            sum += Aval[i][j]*B[j];          // components of the gradient B
479        cout << sum << " ";      // must be a Cartesian basis vector
480    }
481    cout << "\n";
482
483    return 1;
484
485}
486
487#endif
Note: See TracBrowser for help on using the browser.