SolverANI.cpp 4.39 KB
Newer Older
1 2 3 4
#include "SolverANI.h"

namespace INMOST {

Dmitry Bagaev's avatar
Dmitry Bagaev committed
5
    SolverANI::SolverANI() {
6 7 8

    };

Dmitry Bagaev's avatar
Dmitry Bagaev committed
9
    SolverInterface *SolverANI::Copy(const SolverInterface *other) {
10 11 12 13 14 15 16
        throw INMOST::SolverUnsupportedOperation; //later
    };

    void SolverANI::Assign(const SolverInterface *other) {
        throw INMOST::SolverUnsupportedOperation; //later
    }

Dmitry Bagaev's avatar
Dmitry Bagaev committed
17
    void SolverANI::Setup(int *argc, char ***argv, SolverParameters &p) {
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
        solver.n = 0;
        m.n = 0;
    }

    void SolverANI::SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner) {
        bool modified_pattern = ModifiedPattern;
        if (m.n != 0) {
            modified_pattern = true;
        }
        if (modified_pattern) {
            local_size = A.Size();

            if (m.n != 0) {
                free(m.ia);
                free(m.ja);
                free(m.A);
                m.n = 0;
            }
            INMOST_DATA_ENUM_TYPE nnz = 0, k = 0, q = 1, shift = 1;
            int n = A.Size();
            int *ia = (int *) malloc(sizeof(int) * (n + 1));
            for (Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) nnz += it->Size();
            int *ja = (int *) malloc(sizeof(int) * nnz);
            double *values = (double *) malloc(sizeof(double) * nnz);
            ia[0] = shift;
            for (Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) {
                for (Sparse::Row::iterator jt = it->Begin(); jt != it->End(); jt++) {
                    ja[k] = jt->first + 1;
                    values[k] = jt->second;
                    k++;
                }
                shift += it->Size();
                ia[q++] = shift;
            }
            m.n = n;
            m.ia = ia;
            m.ja = ja;
            m.A = values;
        } else {
            INMOST_DATA_ENUM_TYPE nnz = 0, k = 0;
            for (Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) nnz += it->Size();
            double *values = (double *) malloc(sizeof(double) * nnz);
            k = 0;
            for (Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++)
                for (Sparse::Row::iterator jt = it->Begin(); jt != it->End(); jt++)
                    values[k++] = jt->second;
            free(m.A);
            m.A = values;
        }
        if (solver.n == 0)
            initbcg(&solver, &m);
        else
            newmatrixbcg(&solver, &m, OldPreconditioner);
    }

    bool SolverANI::Solve(INMOST::Sparse::Vector &RHS, INMOST::Sparse::Vector &SOL) {
        INMOST_DATA_ENUM_TYPE vbeg, vend;
        RHS.GetInterval(vbeg, vend);
        vector rhs, solution;

        rhs.n = local_size;
        rhs.v = (double *) malloc(sizeof(double) * local_size);
        memcpy(rhs.v, &RHS[vbeg], sizeof(double) * local_size);

        solution.n = local_size;
        solution.v = (double *) malloc(sizeof(double) * local_size);
        memcpy(solution.v, &SOL[vbeg], sizeof(double) * local_size);

Dmitry Bagaev's avatar
Dmitry Bagaev committed
86
        bool result = (solvebcg_ani(&solver, &rhs, &solution) == 0);
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
        if (result) {
            memcpy(&SOL[vbeg], solution.v, sizeof(double) * local_size);
        }
        return result;
    }

    bool SolverANI::Clear() {
        if (m.n != 0) {
            free(m.ia);
            free(m.ja);
            free(m.A);
            m.n = 0;
        }
        if (solver.n != 0) {
            free(solver.rW);
            free(solver.iW);
            solver.n = 0;
        }
        return true;
    }

    bool SolverANI::isMatrixSet() {
        return m.n != 0;
    }

Dmitry Bagaev's avatar
Dmitry Bagaev committed
112 113 114 115 116 117 118 119 120 121 122
    std::string SolverANI::GetParameter(std::string name) const {
        std::cout << "SolverANI::GetParameter unsupported operation" << std::endl;
        //throw INMOST::SolverUnsupportedOperation;
        return "";
    }

    void SolverANI::SetParameter(std::string name, std::string value) {
        std::cout << "SolverANI::SetParameter unsupported operation" << std::endl;
        //throw INMOST::SolverUnsupportedOperation;
    }

123
    INMOST_DATA_ENUM_TYPE SolverANI::Iterations() const {
124 125 126
        return static_cast<INMOST_DATA_ENUM_TYPE>(solver.ITER);
    }

127
    INMOST_DATA_REAL_TYPE SolverANI::Residual() const {
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
        return solver.RESID;
    }

    const std::string SolverANI::ReturnReason() const {
        return "Unspecified for ANI";
    }

    const std::string SolverANI::SolverName() const {
        return "ani";
    }

    void SolverANI::Finalize() {

    }

    SolverANI::~SolverANI() {
        this->Clear();
    }
}