void HarmonicModelling::createJacobian( const RVector & model ) {
    //!! jacobian = transpose( A );
    RMatrix * jacobian = dynamic_cast < RMatrix * > ( jacobian_ );
    
    if ( jacobian->rows() != nt_ || jacobian->cols() != np_ ) {
        jacobian->resize( nt_, np_ );

        for ( size_t i = 0 ; i < np_ ; i++ ){
            for ( size_t j = 0 ; j < nt_ ; j++ ){
                (*jacobian)[ j ][ i ] = A_[ i ][ j ];
            }
        }
    }
}
Exemple #2
0
int main( int argc, char *argv [] )
{
    std::string dataFile( NOT_DEFINED );
    double errPerc = 3.0, lambda = 20.0, lambdaIP = 1.0, maxDepth = 0.0;
    int nlay = 30, maxIter = 20;
    bool verbose = false, lambdaOpt = false, isBlocky = false, isRobust = false, optimizeChi1 = false;

    OptionMap oMap;
    oMap.setDescription("DC1dsmooth - smooth 1d dc resistivity inversion");
    oMap.add( verbose,      "v" , "verbose"       , "Verbose output." );
    oMap.add( lambdaOpt,    "O" , "OptimizeLambda", "Optimize model smoothness using L-curve." );
    oMap.add( isRobust,     "R" , "RobustData"    , "Robust (L1) data weighting." );
    oMap.add( isBlocky,     "B" , "BlockyModel"   , "Blocky (L1) model constraints." );
    oMap.add( optimizeChi1, "C" , "OptimizeChi1"  , "Optimize lambda subject to chi^2=1." );
    oMap.add( maxIter,      "i:", "maxIter"       , "Maximum iteration number." );
    oMap.add( lambda,       "l:", "lambda"        , "Regularization strength lambda." );
    oMap.add( lambdaIP,     "r:", "lambdaIP"      , "Regularization strength lambda for IP." );
    oMap.add( errPerc,      "e:", "error"         , "Error percentage" );
    oMap.add( nlay,         "n:", "nLay"          , "Number of layers" );
    oMap.add( maxDepth,     "d:", "maxDepth"      , "Maximum depth" );
    oMap.addLastArg( dataFile, "Datafile" );
    oMap.parse( argc, argv );

    /*! Data: read data file from column file */
    RMatrix abmnr; 
    loadMatrixCol( abmnr, dataFile ); //! read data
    RVector ab2(  abmnr[ 0 ] );        //! first column
    RVector mn2(  abmnr[ 1 ] );        //! second column
    RVector rhoa( abmnr[ 2 ] );        //! third column

    /*! Define discretization according to AB/2 */
    if ( maxDepth == 0.0 ) {
        maxDepth = max( ab2 ) / 2;   //! rule of thumb
        std::cout << "Maximum depth estimated to " << maxDepth << std::endl;
    }
    RVector thk( nlay - 1, maxDepth / ( nlay - 1 ) );
    thk *= ( maxDepth / sum( thk ) );
    RVector model( nlay, median( rhoa ) );

    /*! Transformations: log for app. resisivity and thickness, logLU for resistivity */
//    TransLogLU< RVector > transRho( lbound, ubound );
    TransLog< RVector > transRho;
    TransLog< RVector > transRhoa;

    /*! Forward operator, transformations and constraints */
    DC1dRhoModelling f( thk, ab2, mn2, false );
    f.region( 0 )->setTransModel( transRho );

    /*! Error estimation */
    double current = 0.1, errVolt = 0;//1e-4;
    RVector voltage( rhoa * f( RVector( 3, 1.0 ) ) * current );
    RVector error = errVolt / voltage + errPerc / 100.0;
    vcout << "error min/max = " << min( error ) << "/" << max( error ) << std::endl;

    /*! Set up inversion with full matrix, data and forward operator */
    RInversion inv( rhoa, f, verbose );
    inv.setTransData( transRhoa );
    inv.setRelativeError( error );
    inv.setLambda( lambda );
    inv.setModel( model );
    inv.setBlockyModel( isBlocky );
    inv.setRobustData( isRobust );
    inv.setOptimizeLambda( lambdaOpt );
    inv.setMaxIter( maxIter );
    inv.setDeltaPhiAbortPercent( 0.5 );
    inv.stopAtChi1( false );

    if ( optimizeChi1 ) {
        model = inv.runChi1( 0.1 );
    } else {
        model = inv.run();
    }
    if ( verbose ) std::cout << "model = " << model << std::endl;
    save( model, "resistivity.vec" );
    save( thk, "thickness.vec" );
    save( inv.response(), "response.vec" );
    
    if ( abmnr.cols() > 3 ) {
        if ( verbose ) std::cout << "Found ip values, doing ip inversion" << std::endl;
        //! imaginary apparent resistivity
        RVector rhoai( rhoa * sin( abmnr[ 3 ] / 1000 ) );
        //! linear modelling operator using the amplitude jacobian
        Mesh mesh( createMesh1D( thk.size() ) );
        LinearModelling fIP( mesh, f.jacobian(), verbose );
        fIP.region( 0 )->setTransModel( transRho );
        //! IP (imaginary resistivity) inversion using fIP
        RInversion invIP( rhoai, fIP, verbose );
        invIP.setAbsoluteError( rhoai / abmnr[ 3 ] * 1.0 );
        invIP.setBlockyModel( isBlocky );
        invIP.setRobustData( isRobust );
        invIP.setLambda( lambdaIP );
        invIP.setRecalcJacobian( false );
        invIP.stopAtChi1( false );
        RVector ipModel( nlay, median( rhoai ) );
        invIP.setModel( ipModel );
        ipModel = invIP.run();
        RVector phase = atan( ipModel / model ) * 1000.;
        save( phase, "phase.vec" );
        RVector aphase = atan( invIP.response() / rhoa ) * 1000.;
        save( aphase, "aphase.vec" ); 
    }

    return EXIT_SUCCESS;
}
int main( int argc, char *argv [] ){

    bool lambdaOpt = false, isRobust = false, isBlocky = false, doResolution = false;
    bool useAppPar = false, useTan = false, useWater = false, optimizeChi1 = false;
    double lambda = 1, lbound = 0, ubound = 0, errbabs = 20;
    int maxIter = 10, verboseCount = 0, ctype = 0;
    std::string matFile( "A.mat" ), bFile( "b.vec" );

    OptionMap oMap;
    oMap.setDescription("Description. InvLinearMat - Linear Inversion with given matrix and vector\n");
    oMap.addLastArg( bFile, "Data file" );
    oMap.add( verboseCount, "v" , "verbose", "Verbose/debug/dosave mode (multiple use)." );
    oMap.add( lambdaOpt,    "O" , "OptimizeLambda", "Optimize model smoothness using L-curve." );
    oMap.add( optimizeChi1, "C" , "OptimizeChi1", "Optimize lambda subject to chi^2=1." );
    oMap.add( doResolution, "D" , "doResolution", "Do resolution analysis." );
    oMap.add( isRobust,     "R" , "RobustData", "Robust (L1) data weighting." );
    oMap.add( isBlocky,     "B" , "BlockyModel", "Blocky (L1) model constraints." );
    oMap.add( useTan,       "T" , "useTan", "Use (co-)Tan instead of Log for LU." );
    oMap.add( useAppPar,    "A" , "useAppPar", "Use apparent parameter transformation." );
    oMap.add( useWater,     "W" , "useWater", "Use water content transformation." );
    oMap.add( matFile,      "m:", "matFile", "Matrix file [A.mat]" );
    oMap.add( lambda,       "l:", "lambda", "Regularization strength lambda[100]." );
    oMap.add( lbound,       "b:", "lbound", "Lower parameter bound[0]" );
    oMap.add( ubound,       "u:", "ubound", "Upper parameter bound[0-inactive]" );
    oMap.add( errbabs,      "e:", "error", "Absolute error level" );
    oMap.add( maxIter,      "i:", "maxIter", "Maximum Iteration number" );
    oMap.parse( argc, argv );
    bool verbose = ( verboseCount > 0 ), debug = ( verboseCount > 1 ), dosave = ( verboseCount > 2 );

    RMatrix A;
    if ( ! loadMatrixSingleBin( A, matFile ) ) { std::cerr << "Did not find A.mat!" << std::endl; return EXIT_OPEN_FILE; }
    RVector b; load( b, bFile );
    size_t nModel( A.cols() );
    dcout << "size(A) = " << A.rows() << "x" << nModel << "size(b) = " << b.size() << std::endl;

    RVector Asum( A * RVector( nModel, 1.0 ) );
    RVector xapp( b / Asum );
    DEBUG save( xapp, "xapp.vec" );
    dcout << "apparent x: min/max = " << min( xapp ) << "/" << max( xapp ) << std::endl;

    Mesh mesh( createMesh1D( nModel ) );
    DEBUG mesh.save( "mesh1d.bms" );
    mesh.showInfos();
    for ( size_t i = 0; i < mesh.cellCount(); i ++ ) mesh.cell( i ).setAttribute( 2.0 + i );
    mesh.createNeighbourInfos();

    LinearModelling f( mesh, A, verbose );
    f.regionManager().region( 0 )->setConstraintType( ctype );

    Trans < RVector > * transData;
    Trans < RVector > * transModel;
    if ( useAppPar ) {
        if ( useTan ) {
            if ( ubound <= lbound ) ubound = lbound + 1.0;
            transData = new TransNest< RVector >( *new TransCotLU< RVector >( lbound, ubound ),
                                                  *new TransLinear< RVector >( RVector( xapp / b ) ) );
            transModel = new TransCotLU< RVector >( lbound, ubound );
        } else {
            transData = new TransNest< RVector >( *new TransLogLU< RVector >( lbound, ubound ),
                                                  *new TransLinear< RVector >( RVector( xapp / b ) ) );
            transModel = new TransLogLU< RVector >( lbound, ubound );
        }
    } else {
        transData = new Trans< RVector >( );
        transModel = new Trans< RVector >( );
    }
    /*! set up inversion */
    RInversion inv( b, f, *transData, *transModel, verbose, dosave );

    inv.setRecalcJacobian( false ); //! no need since it is linear
    inv.setLambda( lambda );
    inv.setOptimizeLambda( lambdaOpt );
    inv.setRobustData( isRobust );
    inv.setBlockyModel( isBlocky );
    inv.setMaxIter( maxIter );
    inv.setDeltaPhiAbortPercent( 1.0 );
    RVector error( errbabs / b);
    vcout << "error: min/max = " << min( error ) << "/" << max( error ) << std::endl;
    inv.setError( error );

    RVector x( nModel, mean( xapp ) );
    inv.setModel( x );
    inv.setReferenceModel( x );

    if ( optimizeChi1 ) { x = inv.runChi1(); } else { x = inv.run(); }
    vcout << "x = " << x << std::endl;
    save( x, "x.vec" );

    if ( doResolution ) {
        RVector resolution( nModel );
        RVector resMDiag ( nModel );
        RMatrix resM;
        for ( size_t iModel = 0; iModel < nModel; iModel++ ) {
            resolution = inv.modelCellResolution( iModel );
            resM.push_back( resolution );
            resMDiag[ iModel ] = resolution[ iModel ];
        }
        save( resMDiag, "resMDiag.vec" );
        save( resM, "resolution.matrix" );
    }

    delete transData;
    delete transModel;

    return EXIT_SUCCESS;
}
Exemple #4
0
int main( int argc, char *argv [] )
{
    bool lambdaOpt = false, doResolution = false, useTan = false, optimizeChi1 = false;
    double lambda = 10.0, lambdaIP = 1.0, lbound = 0.0, ubound = 0.0, errPerc = 3.0;
    int maxIter = 10, nlay = 3, verboseCount = 0, linCount = 0;
    std::string modelFile( NOT_DEFINED ), dataFileName;

    OptionMap oMap;
    oMap.setDescription("Description. DC1dInv - 1D block inversion of dc resistivity data\n");
    oMap.addLastArg( dataFileName, "Data file" );
    oMap.add( verboseCount, "v" , "verbose", "Verbose/debug/dosave mode (multiple use)." );
    oMap.add( lambdaOpt,    "O" , "OptimizeLambda", "Optimize model smoothness using L-curve." );
    oMap.add( doResolution, "D" , "doResolution", "Do resolution analysis." );
    oMap.add( optimizeChi1, "C" , "OptimizeChi1", "Optimize lambda subject to chi^2=1." );
    oMap.add( useTan,       "T" , "useTan", "Use (co-)Tan instead of Log for LU." );
    oMap.add( linCount,     "L" , "dataLin", "Use linear trafo for data, 2x also for model." );
    oMap.add( maxIter,      "i:", "maxIter", "Maximum iteration number." );
    oMap.add( lambda,       "l:", "lambda", "Regularization strength lambda." );
    oMap.add( lambdaIP,     "r:", "lambdaIP", "Regularization strength lambda for IP." );
    oMap.add( errPerc,      "e:", "error", "Error percentage" );
    oMap.add( nlay,         "n:", "nlay", "Number of layers" );
    oMap.add( lbound,       "b:", "lbound", "Lower Resistivity bound" );
    oMap.add( ubound,       "u:", "ubound", "Upper Resistivity bound" );
    oMap.add( modelFile,    "m:", "modelFile", "Model file for pure modelling. file: thick_i rho_i\\n" );
    oMap.parse( argc, argv );

    bool verbose = ( verboseCount > 0 ), debug = ( verboseCount > 1 ), dosave = ( verboseCount > 2 );
    bool dataLin = ( linCount > 0 ), modelLin = ( linCount > 1 );
    
    /*! Data: read data file from column file */
    RMatrix abmnr; 
    loadMatrixCol( abmnr, dataFileName ); //! read data
    RVector ab2(  abmnr[ 0 ] );        //! first column
    RVector mn2(  abmnr[ 1 ] );        //! second column
    RVector rhoa( abmnr[ 2 ] );        //! third column

    /*! Define discretization according to AB/2 */
    double maxDep = max( ab2 ) / 2;   //! rule of thumb
    std::cout << "Maximum depth estimated to " << maxDep << std::endl;
    
    DC1dModelling f( nlay, ab2, mn2, debug );

    /*! Error estimation */
    double current = 0.1, errVolt = 0;//1e-4;
    RVector voltage( rhoa * f( RVector( 3, 1.0 ) ) * current );
    RVector error = errVolt / voltage + errPerc / 100.0;
    vcout << "error min/max = " << min( error ) << "/" << max( error ) << std::endl;

    /*! Transformations: log for app. resisivity and thickness, logLU for resistivity */
//    TransLog< RVector > transThk;
//    TransLogLU< RVector > transRho( lbound, ubound );
//    TransLog< RVector > transRhoa;
    Trans< RVector > *transThk, *transRho, *transRhoa;
    if ( modelLin ) {
         transThk = new Trans< RVector >;
         transRho = new Trans< RVector >;
    } else {
        transThk = new TransLog< RVector >;
        if ( useTan ) {
            transRho = new TransCotLU< RVector >( lbound, ubound );
        } else {
            transRho = new TransLogLU< RVector >( lbound, ubound );
        }
    }
    if ( dataLin ) {
        transRhoa = new Trans< RVector >;
    } else {
        transRhoa = new TransLog< RVector >;
    }

    f.region( 0 )->setTransModel( *transThk );
    f.region( 1 )->setTransModel( *transRho );

    double paraDepth = max( ab2 ) / 3;
    vcout << "Paradepth = " << paraDepth << std::endl;
    f.region( 0 )->setStartValue( paraDepth / nlay / 2.0 );
    f.region( 1 )->setStartValue( median( rhoa ) );

    RVector model;//( f.createDefaultStartModel() );
    model = f.createStartVector();
//    model[ nlay ] *= 1.5; //! in order to make thicknesses sensitive
    DEBUG save( model, "start.vec" );

    /*! Set up inversion with full matrix, data and forward operator */
    RInversion inv( rhoa, f, verbose, dosave );    
    inv.setTransData( *transRhoa );
    inv.setMarquardtScheme( 0.8 ); //! 0th order local decreasing regularization
    inv.setLambda( lambda );
    inv.setOptimizeLambda( lambdaOpt );
    inv.setMaxIter( maxIter );
    inv.setRelativeError( error );              //! error model
    inv.setModel( model );       //! starting model
    inv.setDeltaPhiAbortPercent( 0.5 );

    /*! actual computation: run the inversion */
    if ( optimizeChi1 ) {
        model = inv.runChi1( 0.1 );
    } else {
        model = inv.run();
    }

    RVector thk( nlay - 1 );
    RVector res( nlay );
    for ( int i = 0 ; i < nlay - 1 ; i++ ) thk[ i ] = model[ i ];
    for ( int i = 0 ; i < nlay ; i++ ) res[ i ] = model[ nlay - 1 + i ];
    save( res, "resistivity.vec" );
    save( thk, "thickness.vec" );
    save( inv.response(), "response.vec" );
    
    if ( verbose ) {
        RVector cumz( thk );
        for ( size_t i = 1 ; i < thk.size() ; i++ ) cumz[i] = cumz[ i-1 ] + thk[i];
        cumz.round(0.1);        
		res.round(0.1);        
        std::cout << "Res = " << res << std::endl;
        std::cout << "  z =  " << cumz << std::endl;
    }

    if ( abmnr.cols() > 3 ) { //** IP present
//        if ( verbose ) std::cout << "Found ip values, doing ip inversion" << std::endl;
        //! imaginary apparent resistivity
        RVector rhoai( rhoa * sin( abmnr[ 3 ] / 1000. ) );
        //! modelling operator from fixed layer 
        Mesh ipMesh( createMesh1D( nlay ) );
        DC1dRhoModelling fIP( thk, ab2, mn2, verbose );
        fIP.region( 0 )->setTransModel( *transRho );
        //! IP (imaginary resistivity) inversion using fIP
        RInversion invIP( rhoai, fIP, verbose );
        invIP.setAbsoluteError( rhoai / abmnr[ 3 ] * 1.0 );
        //! take jacobian from real valued problems
        invIP.setModel( res );
        invIP.checkJacobian(); //! force jacobian calculation
        invIP.setRecalcJacobian( false );
        
        invIP.setLambda( lambdaIP );
        invIP.setLocalRegularization( true ); //! Marquardt method
        invIP.setModel( model );       //! starting model
        invIP.stopAtChi1( false );
        RVector ipModel( nlay, median( rhoai ) );
        invIP.setModel( ipModel );
        ipModel = invIP.run();
        RVector phase = atan( ipModel / res ) * 1000.;
        save( phase, "phase.vec" );
        RVector aphase = atan( invIP.response() / rhoa ) * 1000.;
        save( aphase, "aphase.vec" );         
        std::cout << " ip =  " << phase << std::endl;
    }
    
    if ( doResolution ) {
        size_t nModel( 2 * nlay - 1 );
        RVector resolution( nModel );
        RVector resMDiag ( nModel );
        RMatrix resM;
        for ( size_t iModel = 0; iModel < nModel; iModel++ ) {
            resolution = inv.modelCellResolution( iModel );
            resM.push_back( resolution );
            resMDiag[ iModel ] = resolution[ iModel ];
        }
        save( resMDiag, "resMDiag.vec" );
        save( resM,     "resM" );
        vcout << "diagRM = " << resMDiag << std::endl;
    }

    return EXIT_SUCCESS;
}