制作一个三维数组MATLAB

时间:2015-08-29 01:12:36

标签: matlab multidimensional-array vectorization

在MATLAB中我有

if List[0] = 'RecordScreen' then
begin
  // Start a short timer...
end
else if List[0] = 'RecordScreenDone' then
begin
  // stop the timer...
end;

...

procedure TimerElapsed;
var
  JpegStream: TMemoryStream;
  pic: TBitmap;
begin
  JpegStream := TMemoryStream.Create;
  try
    pic := TBitmap.Create;
    try
      ScreenShot(0,0,pic);
      BMPtoJPGStream(pic, JpegStream);
    finally
      pic.Free;
    end;
    try
      AConn.Client.IOHandler.LargeStream := True;
      AConn.Client.IOHandler.Write(JpegStream, 0, True);
    except
      // stop the timer...
    end;
  finally
    JpegStream.Free;
  end;

我还有一个名为X的100000x2矩阵,每行有两组数据 - p是第一列,x是第二列。

我想计算exp ^( - S * X(j,2))。(* Z. ^ X(j,1))其中j索引该行。结果应该是100x100x100000矩阵。然后将沿第3维平均,并生成网格图。我尝试过使用for循环

type
  TMyContext = class(TIdServerContext)
  public
    //...
    RecordScreen: Boolean;
    IsRecording: Boolean;
  end;

procedure TMainForm.idtcpsrvrMainExecute(AContext: TIdContext);
var
  Dir, PicName: string;
  PicStream: TMemoryStream;
  Ctx: TMyContext;
begin
  Ctx := TMyContext(AContext);
  Sleep(50);

  if not Ctx.RecordScreen then
  begin
    if Ctx.IsRecording then
    begin
      AContext.Connection.IOHandler.WriteLn('RecordScreenDone');
      Ctx.IsRecording := False;
    end;
    Exit;
  end;

  if not Ctx.IsRecording then
  begin
    AContext.Connection.IOHandler.WriteLn('RecordScreen');
    Ctx.IsRecording := True;
  end;

  PicStream := TMemoryStream.Create;
  try
    AContext.Connection.IOHandler.LargeStream := True;
    AContext.Connection.IOHandler.ReadStream(PicStream, -1, False);

    if not Ctx.RecordScreen then
    begin
      AContext.Connection.IOHandler.WriteLn('RecordScreenDone');
      Ctx.IsRecording := False;
      Exit;
    end;

    try
      Dir := IncludeTrailingBackslash(Ctx.ClinetDir + ScreenshotsDir);
      ForceDirectories(Dir);
      PicName := Dir + 'Screen-' + DateTimeToFilename + '.JPG';
      PicStream.SaveToFile(PicName);
      TThread.Queue(nil,
        procedure
        begin
          fScreenRecord.imgScreen.Picture.LoadFromFile(PicName);
        end;
      );
    except
    end;
  finally
    PicStream.Free;
  end;
end;

生成我需要的100x100x100000阵列。但是这给了我错误

[Z,S]=meshgrid(0.01:0.01:1)

我不确定为什么会这样?任何人都可以找到一种更好的方法来试图找到我想要的结果吗?因为我猜测可以有一个完全矢量化的解决方案(或者至少使用for循环)?

1 个答案:

答案 0 :(得分:2)

假设您使用两个以上的嵌套循环来获取ZS,因此代码总共会有三个嵌套循环。

现在,矢量化技术在类似于这些的可矢量化嵌套循环案例中没有改变 - 分别处理涉及不同迭代器的代码的不同部分。因此,这里有三个迭代器,其中两个长度为100,第三个为100000。将矢量化的想法放在简明的评论文本中,并使用基于bsxfun的代码解决您的案例 -

%// Get vectorized equivalent of exp(-S.*X(j,2)) and keeping in mind that
%// since the last (3rd) dimension of final output has length same as the 
%// number of elements in X(:,2), so "throw" this to 3rd dim with permute. 
%// Then, use bsxfun to let the broadcasting being taken care off by MATLAB.
p1 = exp(-bsxfun(@times,V.',permute(X(:,2),[3 2 1]))); %//'

%// Going with same philosophy as before, get vectorized (Z.^X(j,1))
p2 = bsxfun(@power,V,permute(X(:,1),[3 2 1]));

%// Finally "merge" earlier two parts for final output
phi_out = bsxfun(@times,p1,p2);