1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/**************************************************************************
begin : April 19 2004
version : 1.0
copyright : (C) 2004 by Gleb Beliakov
email : gleb@deakin.edu.au
An example of how to use lint package with TNT library
this program:
1. randomly generates data
2. Builds the interpolant
3. computes the value of the interpolant and compates it with the test
data (model function)
4. reports preprocessing and evaluation time and the accuracy of
approximation
* *
* Gleb Beliakov, 2004 *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation, *
* Inc., 59 Temple Place Suite 330, Boston, MA 02111-1307 USA. *
***************************************************************************/
#include <cstdlib>
#include <iostream>
using namespace std;
#include "interpol.h"
int dim=3;
int npts=1000;
real LipConst=10;
// generates a random number (real) between x and y
real myrand(real x, real y)
{
if(x>y)
return y + ((x-y)*rand())/(RAND_MAX);
else if(x<y)
return x + ((y-x)*rand())/(RAND_MAX);
return x;
}
// test function, here just a product of sin(2x)sin(2y),...
real fun2(real* dat)
{
// return 0;
int j;
real s=1;
for(j=0;j<dim;j++)
s*=sin(2*dat[j]);
return s;
}
int main(int argc, char *argv[])
{
int j,i;
// arrays to store the data
dVec dat(dim);
dMat XData(npts,dim);
dVec YData(npts);
// interpolant object
STCInterpolant LipInt;
// generate data randomly
for(i=0;i<npts;i++) {
for(j=0;j<dim;j++) {
dat[j]=myrand(3.0,0);
XData[i][j]=dat[j];
}
YData[i]=fun2(dat.begin());
}
ResetTime();
// set Lipschitz const
LipInt.SetData(dim,npts,&(XData[0][0]),YData.begin(),0);
// assumes all the data are distinct.
// If this needs to be tested, use LipInt.GetData(dim,npts,&(XData[0][0]),YData.begin(), 1); command, with the last
// parameter =1. This may be slow.
// if necessary, compute Lipschitz constant (slow)
// LipConst=LipInt.DetermineLipschitz();
LipInt.SetConstants(LipConst);
LipInt.Construct();
// if the dimension is >5, it is better to use explicit method, in which case use
// LipInt.ConstructExplicit();
cout<< ElapsedTime()<< " (s) - Preprocessing time" <<endl;
ResetTime();
// testing evaluation
int k2,K2=1000; // how many test function evaluations
real w,w1, err, err2; // compute the error of approximation
err2=err=0;
for(k2=0;k2<K2;k2++) {
for(j=0;j<dim;j++) dat[j]=myrand(3.0,0); // randomly choose a test point
w=LipInt.ValueSlack(dat); // evaluate the interpolant
w1=fun2(dat.begin()); // the true function
w=fabs(w-w1); // compute the error
if(err<w) err=w;
err2+=w*w;
}
err2=sqrt(err2/K2); // average error RMSE
cout<< ElapsedTime()<< " (s) evaluation, average time is "<< ElapsedTime()/K2 <<endl;
cout << "max error "<<err<<endl;
cout << "av error "<<err2<<endl;
// other examples of evaluating interpolant:
for(j=0;j<dim;j++) dat[j]=myrand(3.0,0); // randomly choose a test point
w=LipInt.ValueSlackExplicit(dat); // using dVec, but explicit evaluation
real dat1[10]; // dim <10
for(j=0;j<dim;j++) dat1[j]=myrand(3.0,0); // randomly choose a test point
w=LipInt.Value(dim,dat1); // using real*, slack variable automatically computed
w=LipInt.ValueExplicit(dim,dat.begin()); // using real*, but explicit evaluation
w=0;
for(j=0;j<dim;j++) w+=dat1[j]; // precompute slack variable
dat1[dim]= 1.0-w;
w=LipInt.Value(dim+1,dat1); // slack variable will not ve computed inside Value, this is a little faster
// as it does not require an extra copying of the vector dat1 to accomodate slack variable
w=LipInt.ValueExplicit(dim+1,dat1);
// the same, but using dVec interface
dVec dat2(dim+1);
w=0;
for(j=0;j<dim;j++) {dat2[j]=myrand(3.0,0); w+=dat2[j];} // precompute slack variable
dat2[dim]= 1.0-w;
w=LipInt.Value(dat2);
w=LipInt.ValueExplicit(dat2);
// of course, we can have several interpolants at the same time
STCInterpolant LipInt1, LipInt2;
// but be aware of memory limitations for large data sets
// one interpolant requires about 500 Mb RAM for dim=5 and npts=10000 or dim=3, npts=300000
return 0;
}
|