生成已知维度的空矩阵

时间:2016-05-14 18:45:08

标签: matlab matrix octave

我想在Octave中生成已知维度的矩阵。问题是我不想用零初始化矩阵。矩阵只包含0或1,但没有分配任何值的元素(单元格)必须保持空白。计划在“协作过滤”算法中使用这样的矩阵。

我是Ocatve和'Collaborative Filtering'algos的新手。试图在网上寻找解决方案但无济于事。关键词网上的空矩阵是指零维的数组或以“”作为值的char矩阵。

2 个答案:

答案 0 :(得分:4)

数值数组不能包含空值。通常在这种情况下,人们会使用NaN作为占位符值。

%// Initialize a 3D matrix of NaN values
data = nan(2, 3, 4);

size(data)
%//  2   3   4

然后很容易区分占位符值和实际数据。您可以使用isnan检测它们。

创建空值数组的唯一方法(由于性能损失而非常不鼓励)是使用单元格数组。

data = cell(2, 3, 4);

答案 1 :(得分:0)

  

问题是我不想用零初始化矩阵。矩阵只包含0或1,但没有分配任何值的元素(单元格)必须保持空白。

你错了。您可能认为矩阵仅包含值0或1,但实际上它的值为0,1或未设置。你不能有一个空白值,你总是需要一些价值。或者至少不是你想的那样空白。从非常低的水平来看,所有的叮咬都需要有一个值(0或1),它们不能是空白的。因此,如果您想要一个空白值,则需要将某个值解释为空白。

您的数据将有3种状态:true,false和空白。您将需要每点至少2位(请注意,即使是逻辑/ bool数据类型,只需要1位,actually take up 8 bits (1 byte))。

使用NaN

这可能看起来像简单的解决方案,但实际上非常糟糕。这将是对内存的巨大浪费(如果您正在进行协同过滤,那么您将拥有非常大的矩阵。)

原因是如果您使用NaN,您的数据必须是单数或双数。这至少分别是32位或64位。请记住,您实际上只需要2位。当然,您可以创建具有NaN值的自己的数据类型。

octave> vals = NaN (3, 3) # 3x3 matrix of type double (default)
vals =

   NaN   NaN   NaN
   NaN   NaN   NaN
   NaN   NaN   NaN

octave> vals = NaN (3, 3, "single") # 3x3 matrix of type single
vals =

   NaN   NaN   NaN
   NaN   NaN   NaN
   NaN   NaN   NaN

使用单元格矩阵

cell array是一种数据类型,其中每个单元格可以是任何Octave值。这包括另一个单元阵列,任何维度的矩阵,甚至是一个空数组。你可以使用一个空数组作为空白,但这对于内存和速度来说都是非常低效的,并且你将无法使用大多数函数,因为它们可以在数字数组上工作,而不是单元数组。

octave> vals = cell (3, 3); # create 3x3 cell matrix
octave> vals{2,3} = true; # set value
octave> vals{2,3} = false; # set value
octave> vals{2,3} = []; # unset value
octave> cumsum (vals)
error: cumsum: wrong type argument 'cell'
octave> nnz (vals)
error: nnz: wrong type argument 'cell array'
octave> find (vals)
error: find: wrong type argument 'cell'

使用8位整数

这是我最常使用的内容。使用带符号的8位,可以使用0表示空白,-1表示false,使用1表示true(或者对您最有意义的任何内容)。

octave> vals = zeros (3, 3, "int8");

使用单独的矩阵来跟踪空白值

如果你真的想要一个0和1的矩阵,那么你需要一个单独的矩阵来跟踪已设置的值。在这种情况下,两个矩阵都可以是逻辑类型,因此每个数据点占用8位,每个数据点总共16位。它还有一个问题,你需要保持两个矩阵同步。

octave> vals = false (3, 3);
octave> set_vals = false (size (vals));

制作自己的课程

要么使用old @class type的新classdef(需要Octave 4.0.0),你可以在自己的类中封装上面的任何策略(我个人会使用8位整数)。如果使用带符号的8位,这会移动知道哪个值(-1或0)表示空白的逻辑。或者,如果您更喜欢为空值使用单独的矩阵,那么将保持值同步的逻辑移动到setter方法。