在lapack solver dgbsv的行主要布局中编写带状矩阵

时间:2017-03-12 17:24:16

标签: linear-algebra intel-mkl lapacke

我想解决这个线性系统Ax = b,其中:

A =  
    [-0.23  2.54  -3.66  0;  
     -6.98  2.46  -2.73  -2.73;  
      0     2.56   2.46   4.07;  
      0     0     -4.78   3.82]

b = [4.42 27.13 -6.14  10.5]

,解决方案应该是

x = [-2  3  1  -4]

是一个带状矩阵,其低带等于1,高带等于2

使用DGBSV求解器解决如下

#include <stdlib.h>
#include <stdio.h>
#include "mkl_lapacke.h"
#define N 4
int main() { 
    int i;
    MKL_INT ipiv[N];
    double a[16] = { 0,    -0.23,  2.54, -3.66,
                    -6.98,  2.46, -2.73, -2.13,
                     2.56,  2.46,  4.07,  0,
                    -4.78,  3.82,  0,     0};

    double b[4] =  {4.42, 27.13, -6.14, 10.5};

    LAPACKE_dgbsv( LAPACK_ROW_MAJOR, N, 1, 2, 1, a, N, ipiv, b, 1);

    for(i=0;i<N;i++)
        printf("%f\n", b[i]);
}

代码在dgbsv解算器中中止。当我写矩阵a和b指针时,它给出了地址的值。

2 个答案:

答案 0 :(得分:1)

对于你问题中所述的输入,即,

A =  
[-0.23  2.54  -3.66  0;  
 -6.98  2.46  -2.73  -2.73;  
  0     2.56   2.46   4.07;  
  0     0     -4.78   3.82]

b = [4.42 27.13 -6.14  10.5]

解决方案(解决系统密集问题)我得到的是:

[-3.77599, -1.28156, -1.85975, 0.421568]

但是,对于代码,有几件事值得一提。函数LAPACKE_dgbsv基本上做的是它检查输入的有效性,然后调用函数LAPACKE_dgbsv_work。如果此函数检测到提供的布局为LAPACK_ROW_MAJOR,则它仅转置其输入(矩阵,右侧)并将所有这些传递给LAPACKE_dgbsv,其中LAPACK_ROW_MAJOR期望列{~3}的列主要版本}。

因此,如果您的代码指定a,则数组LAPACKE_dgbsv应包含上面链接中指定的压缩矩阵的行主要版本。此外,或许更重要的是,a需要数组kl中的额外空间,以便它可以存储LU分解的结果。具体而言,必须有额外的#include <stdlib.h> #include <stdio.h> #include "mkl_lapacke.h" #define N 4 int main() { int i; MKL_INT ipiv[N]; double b[4] = {4.42, 27.13, -6.14, 10.5}; double a[] = { 0, 0, 0, 0, 0, 0, -3.66, -2.73, 0, 2.54, -2.73, 4.07, -0.23, 2.46, 2.46, 3.82, -6.98, 2.56, -4.78, 0}; MKL_INT info = LAPACKE_dgbsv(LAPACK_ROW_MAJOR, N, 1, 2, 1, a, N, ipiv, b, 1); //printf("%d\n", info); for(i=0;i<N;i++) printf("%f\n", b[i]); } 行。

因此

-3.775989
-1.281561
-1.859751
0.421568

然后产生:

import tensorflow as tf
import tflearn
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.estimator import regression

#px_train:pixel data, data_train: additional data 
px_train, data_train, px_cv, data_cv, labels_train, labels_cv = prepare_data(path, filename)

img_aug = ImageAugmentation()
img_aug.add_random_flip_leftright()
img_aug.add_random_rotation(max_angle = 89.)
img_aug.add_random_blur(sigma_max=3.)
img_aug.add_random_flip_updown()
img_aug.add_random_90degrees_rotation(rotations = [0, 1, 2, 3])

#I can only pass image data here to apply data_augmentation 
convnet = input_data(shape = [None, 96, 96, 1], name = 'input', data_augmentation = img_aug)

convnet = conv_2d(convnet, 32, 2, activation = 'relu')
convnet = max_pool_2d(convnet, 2)                                   

convnet = conv_2d(convnet, 64, 2, activation = 'relu')
convnet = max_pool_2d(convnet, 2)                                   

convnet = tf.reshape(convnet, [-1, 24*24*64])    
#convnet = tf.concat((convnet, conv_feat), 1)
#If I concatenated data like above, where could I tell Tensorflow to assign the variable conv_feat to my 'data_train' values?

convnet = fully_connected(convnet, 1024, activation = 'relu')
convnet = dropout(convnet, 0.8)

convnet = fully_connected(convnet, 99, activation = 'softmax')
convnet = regression(convnet, optimizer = 'adam', learning_rate = 0.01, loss = 'categorical_crossentropy', name = 'labels')

model = tflearn.DNN(convnet)

#I can't add additional 'input' labels here to pass my 'data_train'. TF gives error.
model.fit({'input': np.array(px_train).reshape(-1, 96, 96, 1)}, {'labels': labels_train}, n_epoch = 50, validation_set = ({'input': np.array(px_cv).reshape(-1, 96, 96, 1)}, {'labels': labels_cv}), snapshot_step = 500, show_metric = True, run_id = 'Test')

与使用密集求解器获得的解决方案一致。

答案 1 :(得分:0)

问题可能是gbsv函数期望矩阵A有2KL + KU + 1行的空间,而你的代码只分配KL + KU + 1行。如果这是错误的猜测,您可以查看LAPACKE_dgbsv包装器here的实现。