无法执行赋值,因为左侧的大小为 1×7×7,右侧的大小为 6×6

如何解决无法执行赋值,因为左侧的大小为 1×7×7,右侧的大小为 6×6

我正在寻找一种方法来为 2 个给定矩阵找到相同的特征向量,这样我就可以进行联合对角化。为此,我发现并尝试使用以下函数中的 qndiag(来自 https://github.com/pierreablin/qndiag.git ):

function [D,B,infos] = qndiag(C,varargin)
% Joint diagonalization of matrices using the quasi-Newton method
%
% The algorithm is detailed in:
%
%    P. Ablin,J.F. Cardoso and A. Gramfort. Beyond Pham’s algorithm
%    for joint diagonalization. Proc. ESANN 2019.
%    https://www.elen.ucl.ac.be/Proceedings/esann/esannpdf/es2019-119.pdf
%    https://hal.archives-ouvertes.fr/hal-01936887v1
%    https://arxiv.org/abs/1811.11433
%
% The function takes as input a set of matrices of size `(p,p)`,stored as
% a `(n,p,p)` array,`C`. It outputs a `(p,`B`,such that the
% matrices `B * C(i,:,:) * B'` are as diagonal as possible.
%
% There are several optional parameters which can be provided in the
% varargin variable.
%
% Optional parameters:
% --------------------
% 'B0'                        Initial point for the algorithm.
%                             If absent,a whitener is used.
% 'weights'                   Weights for each matrix in the loss:
%                             L = sum(weights * KL(C,C')).
%                             No weighting (weights = 1) by default.
% 'maxiter'                   (int) Maximum number of iterations to perform.
%                             Default : 1000
%
% 'tol'                       (float) A positive scalar giving the tolerance at
%                             which the algorithm is considered to have converged.
%                             The algorithm stops when  |gradient| < tol.
%                             Default : 1e-6
%
% lambda_min                  (float) A positive regularization scalar. Each
%                             eigenvalue of the Hessian approximation below
%                             lambda_min is set to lambda_min.
%
% max_ls_tries                (int),Maximum number of line-search tries to
%                             perform.
%
% return_B_list               (bool) Chooses whether or not to return the list
%                              of iterates.
%
% verbose                     (bool) Prints informations about the state of the
%                             algorithm if True.
%
% Returns
% -------
% D : Set of matrices jointly diagonalized
% B : Estimated joint diagonalizer matrix.
% infos : structure containing monitoring informations,containing the times,%     gradient norms and objective values.
%
% Example:
% --------
%
%  [D,B] = qndiag(C,'maxiter',100,'tol',1e-5)
%
% Authors: Pierre Ablin <pierre.ablin@inria.fr>
%          Alexandre Gramfort <alexandre.gramfort@inria.fr>
%
% License: MIT
% First tests
if nargin == 0,error('No signal provided');
end
if length(size(C)) ~= 3,error('Input C should be 3 dimensional');
end
if ~isa (C,'double'),fprintf ('Converting input data to double...');
  X = double(X);
end
% Default parameters
C_mean = squeeze(mean(C,1));
[p,d] = eigs(C_mean);
p = fliplr(p);
d = flip(diag(d));
B = p' ./ repmat(sqrt(d),1,size(p,1));
max_iter = 1000;
tol = 1e-6;
lambda_min = 1e-4;
max_ls_tries = 10;
return_B_list = false;
verbose = false;
weights = [];
% Read varargin
if mod(length(varargin),2) == 1,error('There should be an even number of optional parameters');
end
for i = 1:2:length(varargin)
    param = lower(varargin{i});
    value = varargin{i + 1};
    switch param
        case 'B0'
            B0 = value;
        case 'max_iter'
            max_iter = value;
        case 'tol'
            tol = value;
        case 'weights'
            weights = value / mean(value(:));
        case 'lambda_min'
            lambda_min = value;
        case 'max_ls_tries'
            max_ls_tries = value;
        case 'return_B_list'
            return_B_list = value;
        case 'verbose'
            verbose = value;
        otherwise
            error(['Parameter ''' param ''' unknown'])
    end
end
[n_samples,n_features,~] = size(C);
D = transform_set(B,C,false);
current_loss = NaN;
% Monitoring
if return_B_list
    B_list = []
end
t_list = [];
gradient_list = [];
loss_list = [];
if verbose
    print('Running quasi-Newton for joint diagonalization');
    print('iter | obj | gradient');
end
for t=1:max_iter
    if return_B_list
        B_list(k) = B;
    end
    diagonals = zeros(n_samples,n_features);
    for k=1:n_samples
        diagonals(k,:) = diag(squeeze(D(k,:)));
    end
    % Gradient
    if isempty(weights)
        G = squeeze(mean(bsxfun(@rdivide,D,...
                                reshape(diagonals,n_samples,1)),...
                         1)) - eye(n_features);
    else
        G = squeeze(mean(...
                bsxfun(@times,...
                        reshape(weights,1),...
                        bsxfun(@rdivide,...
                               reshape(diagonals,1))),...
                    1)) - eye(n_features);
    end
    g_norm = norm(G);
    if g_norm < tol
        break
    end
    % Hessian coefficients
    if isempty(weights)
        h = mean(bsxfun(@rdivide,...
                        reshape(diagonals,n_features),1);
    else
        h = mean(bsxfun(@times,...
                 1);
    end
    h = squeeze(h);
    % Quasi-Newton's direction
    dt = h .* h' - 1.;
    dt(dt < lambda_min) = lambda_min;  % Regularize
    direction = -(G .* h' - G') ./ dt;
    % Line search
    [success,new_D,new_B,new_loss,direction] = ...
        linesearch(D,direction,current_loss,max_ls_tries,weights);
    D = new_D;
    B = new_B;
    current_loss = new_loss;
    % Monitoring
    gradient_list(t) = g_norm;
    loss_list(t) = current_loss;
    if verbose
        print(sprintf('%d  - %.2e - %.2e',t,g_norm))
    end
end
infos = struct();
infos.t_list = t_list;
infos.gradient_list = gradient_list;
infos.loss_list = loss_list;
if return_B_list
    infos.B_list = B_list
end
end
function [op] = transform_set(M,diag_only)
    [n,~] = size(D);
    if ~diag_only
        op = zeros(n,p);
        for k=1:length(D)
            op(k,:) = M * squeeze(D(k,:)) * M';
        end
    else
        op = zeros(n,:) = sum(M .* (squeeze(D(k,:)) * M'),1);
        end
    end
end
function [v] = slogdet(A)
    v = log(abs(det(A)));
end
function [out] = loss(B,is_diag,weights)
    [n,~] = size(D);
    if ~is_diag
        diagonals = zeros(n,p);
        for k=1:n
            diagonals(k,:)));
        end
    else
        diagonals = D;
    end
    logdet = -slogdet(B);
    if ~isempty(weights)
        diagonals = bsxfun(@times,diagonals,reshape(weights,n,1));
    end
    out = logdet + 0.5 * sum(log(diagonals(:))) / n;
end
function [success,delta] = linesearch(D,n_ls_tries,~] = size(D);
    step = 1.;
    if current_loss == NaN
        current_loss = loss(B,false);
    end
    success = false;
    for n=1:n_ls_tries
        M = eye(p) + step * direction;
        new_D = transform_set(M,true);
        new_B = M * B;
        new_loss = loss(new_B,true,weights);
        
        if new_loss < current_loss
            success = true;
            break
        end
        step = step / 2;
    end
    new_D = transform_set(M,false);
    delta = step * direction;
end

我将它与以下脚本一起使用,您可以通过下载本文底部的 2 个输入矩阵进行测试:

clc; clear
m=7  % dimension
n=2   % number of matrices
% Load spectro and WL+GCph+XC
FISH_GCsp = load('Fisher_GCsp_flat.txt');
FISH_XC = load('Fisher_XC_GCph_WL_flat.txt');
% Marginalizing over uncommon parameters between the two matrices
COV_GCsp_first = inv(FISH_GCsp);
COV_XC_first = inv(FISH_XC);
COV_GCsp = COV_GCsp_first(1:m,1:m);
COV_XC = COV_XC_first(1:m,1:m);
% Invert to get Fisher matrix
FISH_sp = inv(COV_GCsp);
FISH_xc = inv(COV_XC);
% Drawing a random set of commuting matrices
C=zeros(n,m,m);
B0=zeros(n,m);
C(1,:) = FISH_sp
C(2,:) = FISH_xc
%[D,'max_iter',1e6,1e-6);
[D,B] = qndiag(C);
% Print diagonal matrices
B*C(1,:)*B'
B*C(2,:)*B'

但不幸的是,我收到以下错误:

Unable to perform assignment because the size of the left side is 1-by-7-by-7 and the size of the
right side is 6-by-6.
Error in qndiag>transform_set (line 224)
            op(k,:)) * M';
Error in qndiag (line 128)
D = transform_set(B,false);
Error in compute_joint_diagonalization (line 32)
[D,B] = qndiag(C);

我不明白函数 squeeze 最重要的效用:为什么函数 eigs 返回只返回 6 个值而不是 7 就像我的数据(输入矩阵的大小为 7x7).

这个数组维度问题可能有什么问题,我该如何解决?

我把 2 个输入文件放在这里:

Matrix Fisher_GCsp_flat.txt

Matrix Fisher_XC_GCph_WL_flat.txt

您可以测试上面为这两个矩阵调用 qndiag 的代码。

更新 1

为了让有兴趣的人快速测试代码,我放了一个存档链接:

Archive_Matlab_StackOver.tar

您只需在 Matlab 下解压并执行脚本 compute_joint_diagonalization.m,您通常会看到上述错误(关于 eigssqueeze 函数的使用)。

它应该可以帮助您了解此问题的根源。

更新 2

如果我用 [p,d] = eigs(C_mean) 替换 [p,d] = eigs(C_mean,7) ,我会收到另一个错误:

Index in position 1 exceeds array bounds (must not exceed 2).

Error in qndiag>transform_set (line 224)
            op(k,:)) * M';

Error in qndiag (line 128)
D = transform_set(B,false);

Error in compute_joint_diagonalization (line 27)
[D,B] = qndiag(C);

但是,使用的 2 个矩阵的维度是 7x7,应该使用 eigs(C_mean,7) 正确处理。

更新 3

op,Mk 的大小等于(包括错误信息之后):

size(D) =
     2     7     7

length(D) =
     7
   
size(M) =
     7     7

size(op) =
     2     7     7

Index in position 1 exceeds array bounds (must not exceed 2).

Error in qndiag>transform_set (line 231)
            op(k,B] = qndiag(C);

注意 k 从 1 到 length(D)=7 变化。

这些尺寸是否会出现问题?

解决方法

来自 eigsdocumentation

d = eigs(A) 返回矩阵 A 的六个最大幅值特征值的向量。

如果您想要所有七个,则需要调用 d = eigs(A,7)d = eig(A)。对于小矩阵(例如 eig 获取所有特征值通常更容易,而不是使用 eigs 获取子集。

编辑:响应您的“更新 3”

for k=1:length(D) 应替换为 for k=1:n。这需要在两行上进行更改。从您的错误消息来看,它们是第 231 和 236 行。

L = length(X) 返回 X 中最大数组维度的长度,在您的情况下为 7,即对于第一个维度来说太高了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res