You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用工厂方法根据变量状态实例化不同Eigen求解器?

不用工厂方法的简便解决方案

方案1:使用C++17 std::variant(推荐)

std::variant可以存储不同类型的对象,既能让solver在全局作用域保持有效,又不用写复杂的工厂逻辑,完美适配你的场景。

代码示例:

#include <appropriateHeaders.h>
#include <variant>
#include <string>

// 定义包含所有求解器类型的variant
using SolverVariant = std::variant<
    Eigen::SimplicialLLT<Eigen::SparseMatrix<double>>,
    Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>>
    // 在这里补充剩下的10种求解器类型
>;

int main() {
    std::string solverType;
    read_solverType_from_file(solverType);

    SolverVariant solver;

    // 根据类型初始化variant
    if (solverType == "SimplicialLLT") {
        solver = Eigen::SimplicialLLT<Eigen::SparseMatrix<double>>();
    } else if (solverType == "SimplicialLDLT") {
        solver = Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>>();
    }
    // 补充其他10种类型的判断分支

    // 使用std::visit统一调用求解器接口
    std::visit([&](auto& s) {
        // 这里写入所有需要用solver执行的逻辑,比如:
        s.compute(your_sparse_matrix);
        auto result = s.solve(your_rhs_vector);
        // 处理计算结果的逻辑...
    }, solver);

    return 0;
}

这个方案的优势:

  • solver在main函数全程有效,不会出现作用域问题
  • 无需维护基类和工厂代码,实现简洁
  • 所有求解器的通用逻辑只需写一次(在visit的lambda表达式中)

方案2:将业务逻辑内联到判断块中

如果你的项目暂不支持C++17,或者觉得variant太复杂,可以直接把使用solver的代码放到对应的if/else块里。虽然会有代码重复,但实现成本最低:

#include <appropriateHeaders.h>
#include <string>

// 抽离通用的结果处理逻辑为模板函数,避免重复代码
template<typename SolverType>
void process_solution(SolverType& solver, const Eigen::SparseMatrix<double>& mat, const Eigen::VectorXd& rhs) {
    solver.compute(mat);
    auto result = solver.solve(rhs);
    // 统一的结果处理逻辑...
}

int main() {
    std::string solverType;
    read_solverType_from_file(solverType);

    // 假设已定义好稀疏矩阵和右端项
    Eigen::SparseMatrix<double> mat;
    Eigen::VectorXd rhs;

    if (solverType == "SimplicialLLT") {
        Eigen::SimplicialLLT<Eigen::SparseMatrix<double>> solver;
        process_solution(solver, mat, rhs);
    } else if (solverType == "SimplicialLDLT") {
        Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> solver;
        process_solution(solver, mat, rhs);
    }
    // 补充其他10种类型的判断分支

    return 0;
}

方案3:基于基类的简化多态

如果上面两个方案都不满足,也可以利用Eigen求解器的公共基类Eigen::SparseSolverBase,用智能指针存储实例。虽然有点接近工厂模式,但实现起来很简单:

#include <appropriateHeaders.h>
#include <string>
#include <memory>

int main() {
    std::string solverType;
    read_solverType_from_file(solverType);

    std::unique_ptr<Eigen::SparseSolverBase<Eigen::SimplicialLLT<Eigen::SparseMatrix<double>>>> solver;

    if (solverType == "SimplicialLLT") {
        solver = std::make_unique<Eigen::SimplicialLLT<Eigen::SparseMatrix<double>>>();
    } else if (solverType == "SimplicialLDLT") {
        solver = std::make_unique<Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>>>();
    }
    // 补充其他类型的初始化分支

    // 使用求解器
    solver->compute(your_sparse_matrix);
    auto result = solver->solve(your_rhs_vector);

    return 0;
}

内容的提问来源于stack exchange,提问作者1Teaches2Learn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:35:25