Как решать уравнения в Scilab API

Я не понимаю, в чем ошибка при расчете системы линейных уравнений. Мне нужно решить систему линейных уравнений с помощью Scilab API на языке C, но я получаю слишком маленькие значения. Проверил решение, ответ должен быть: [0;1]. Бесплатное специально комментируется, потому что программа сразу вылетает.

Я думал ошибка в 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

Пытался решить SLAU через Scilab API, но особого результата не добился. Я не уверен, правильно ли я это делаю.

Вы неправильно используете прототип dgesv, см. netlib.org/lapack/explore-html-3.6.1/d7/d3b/…

Stéphane Mottelet 06.05.2024 11:28

Дополнительные вопросы о Scilab можно задать на сайте scilab.discourse.group, спасибо.

Stéphane Mottelet 06.05.2024 11:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

См. приведенный ниже фиксированный код. У вас выше было несколько проблем:

  1. Второй аргумент dgesv должен быть равен единице
  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;
}

Инструкции по компиляции и ссылки предоставлены не были (исходник выше предполагается сохранить в sci_foo6.c):

 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.

Большое спасибо! Я очень долго искал ответ, но только вы смогли ответить! Очень благодарен!

Zoow 06.05.2024 19:31

Другие вопросы по теме