如何在 Scilab API 中求解方程

问题描述 投票:0回答:1

我不明白计算线性方程组的错误是什么。 我需要使用 C 中的 Scilab API 求解线性方程组,但我得到的值太小。查了一下答案,答案应该是:

[0;1]
。 特意注释了Free,因为程序立刻就崩溃了

我以为错误出在

dgesv_
,但很奇怪,因为它是一个 Scilab 函数,为什么它的解法不正确。也许输出有问题?

代码:

#include "api_scilab.h"
#include "Scierror.h"
#include "BOOL.h"
#include "localization.h"

extern void dgesv_(int* n, int* nrhs, double* A, int* lda, int* ipiv, double* b, int* ldb, int* info);

static const char fname[] = "foo6";

int sci_foo6(scilabEnv env, int nin, scilabVar* in, int nopt, scilabOpt* opt, int nout, scilabVar* out)
{
    int i = 0;
    int n = 0; // System dimension
    double* A = NULL; // Coefficient matrix
    double* b = NULL; // Right-hand side vector
    double* x = NULL; // Solution
    int info = 0;

    /* Check the number of input and output arguments */
    if (nin != 2 || nout != 1) {
        Scierror(77, _("%s: Wrong number of input or output arguments: 2 inputs and 1 output expected.\n"), fname);
        return 1;
    }

    /* Check the types of input arguments */
    if (scilab_isDouble(env, in[0]) == 0 || scilab_isMatrix2d(env, in[0]) == 0 ||
        scilab_isComplex(env, in[0]) == 1 || scilab_isDouble(env, in[1]) == 0 ||
        scilab_isMatrix2d(env, in[1]) == 0 || scilab_isComplex(env, in[1]) == 1) {
        Scierror(999, _("%s: Wrong type for input arguments. Double matrices expected.\n"), fname);
        return 1;
    }

    /* Get the dimension of the coefficient matrix */
    int rowA = 0, colA = 0, rowB = 0, colB = 0;
    scilab_getDim2d(env, in[0], &rowA, &colA);
    scilab_getDim2d(env, in[1], &rowB, &colB);
    if (rowA != colA || rowB != rowA || colB != 1) {
        Scierror(999, _("%s: Incorrect dimensions. Coefficient matrix should be square and vector should be a column vector of the same size.\n"), fname);
        return 1;
    }
    n = rowA;

    /* Get data from input arguments */
    scilab_getDoubleArray(env, in[0], &A);
    scilab_getDoubleArray(env, in[1], &b);

    /* Solve the system of linear equations */
    x = (double*)malloc(n * sizeof(double));
    dgesv_(&n, &n, A, &n, b, x, &n, &info);
    if (info != 0) {
        Scierror(999, _("%s: LAPACK dgesv function failed with error code %d.\n"), fname, info);
        free(x);
        return 1;
    }

    /* Create the output argument and copy the result */
    out[0] = scilab_createDoubleMatrix2d(env, 1, n, 0);
    double* xPtr = NULL;
    scilab_getDoubleArray(env, out[0], &xPtr);

    for (i = 0; i < n; i++) {
        xPtr[i] = x[i];
    }

    //free(x);
    return 0;
}

结论:

--> A = [2, 1; -1, 2]; 
 
--> b = [1; 2]; 
 
--> x = foo6(A, b); 
 
--> disp(x); 
 
   5.27D-314   2.64D-314

尝试通过 Scilab API 解决 SLAU,但效果不佳。我不确定我这样做是否正确。

c ubuntu scilab
1个回答
0
投票

请参阅下面的固定代码。您上面的代码有几个问题:

  1. dgesv 的第二个参数必须等于 1
  2. 整数主元数组丢失
  3. 右侧 b 被解覆盖,因此您必须将初始 b 复制到 x 中。
#include "api_scilab.h"
#include "Scierror.h"
#include "BOOL.h"
#include "localization.h"

extern void dgesv_(int* n, int* nrhs, double* A, int* lda, int* ipiv, double* b, int* ldb, int* info);

static const char fname[] = "foo6";

int sci_foo6(scilabEnv env, int nin, scilabVar* in, int nopt, scilabOpt* opt, int nout, scilabVar* out)
{
    int i = 0;
    int n = 0; // System dimension
    int iOne = 1;
    double* A = NULL; // Coefficient matrix
    double* b = NULL; // Right-hand side vector
    double* x = NULL; // Solution
    int* iPiv = NULL;
    int info = 0;

    /* Check the number of input and output arguments */
    if (nin != 2 || nout != 1) {
        Scierror(77, _("%s: Wrong number of input or output arguments: 2 inputs and 1 output expected.\n"), fname);
        return 1;
    }

    /* Check the types of input arguments */
    if (scilab_isDouble(env, in[0]) == 0 || scilab_isMatrix2d(env, in[0]) == 0 ||
        scilab_isComplex(env, in[0]) == 1 || scilab_isDouble(env, in[1]) == 0 ||
        scilab_isMatrix2d(env, in[1]) == 0 || scilab_isComplex(env, in[1]) == 1) {
        Scierror(999, _("%s: Wrong type for input arguments. Double matrices expected.\n"), fname);
        return 1;
    }

    /* Get the dimension of the coefficient matrix */
    int rowA = 0, colA = 0, rowB = 0, colB = 0;
    scilab_getDim2d(env, in[0], &rowA, &colA);
    scilab_getDim2d(env, in[1], &rowB, &colB);
    if (rowA != colA || rowB != rowA || colB != 1) {
        Scierror(999, _("%s: Incorrect dimensions. Coefficient matrix should be square and vector should be a column vector of the same size.\n"), fname);
        return 1;
    }
    n = rowA;

    /* Get data from input arguments */
    scilab_getDoubleArray(env, in[0], &A);
    scilab_getDoubleArray(env, in[1], &b);

    /* Solve the system of linear equations */
    x = (double*)malloc(n * sizeof(double));
    for (i = 0; i < n; i++) {
        x[i] = b[i];
    }

    iPiv = (int*)malloc(n * sizeof(int));
    dgesv_(&n, &iOne, A, &n, iPiv, x, &n, &info);
    if (info != 0) {
        Scierror(999, _("%s: LAPACK dgesv function failed with error code %d.\n"), fname, info);
        free(x);
        free(iPiv);
        return 1;
    }

    /* Create the output argument and copy the result */
    out[0] = scilab_createDoubleMatrix2d(env, 1, n, 0);
    double* xPtr = NULL;
    scilab_getDoubleArray(env, out[0], &xPtr);

    for (i = 0; i < n; i++) {
        xPtr[i] = x[i];
    }

    free(x);
    free(iPiv);
    return 0;
}
 ilib_build('foo6',['foo6','sci_foo6','csci6'],"sci_foo6.c",[]);
 exec loader.sce
--> A = [2, 1; -1, 2]; 

--> b = [1;2];

--> x = foo6(A,b)
 x  = 

   0.   1.
© www.soinside.com 2019 - 2024. All rights reserved.