STL 与 allocator

STL 的 allocator 的角色是对 memory model 封装的接口,STL 将其作为一种 concept,它必须(详细的说明见这里):

  • 定义 value_type,pointer、reference、const_pointer、const_reference、size_type、difference_type;
  • default constructible,定义 address(通过引用返回指针),allocate 和 deallocate(分配和释放内存),max_size 以及 construct 和 destroy;

allocator 在 STL 的用法是通过 container 的参数传递进去,container 就在 allocator 的接口上工作,比如维护需要的内存,需要的时候创建对象。需要注意的是 allocator 提供的 construct 仅仅支持 copy constructor。wikipedia 上介绍了 allocator 的一些历史,从中我们不难看出最初 allocator 给予的期望还是很高的,但是和实际妥协的结果造就了我们现在看到的版本。

与 allocator 提供的功能相似,在 memory 里面还提供了 get_temporary_buffer 和 return_temporary_buffer 用来获得和释放内存(与 allocate 与 deallocate 类似),然后用 uninitialized_copy 和 uninitialized_fill(_n) 来填充这些区域,与 algorithm 里面的 copy 和 fill 不同的是,后者要求对象已经被创建(调用过构造函数)因而使用的是 operator= 进行赋值,而这些函数会主动调用 copy constructor,构造新的对象。似乎没有提供一个类似 destroy 的函数。

在 Matlab 里面内存的分配往往通过 mxMalloc 和 mxFree 进行内存管理,这应该是在 Matlab 自己控制的内存池里面进行的内存分配。那么在写某些 mex 程序的时候我们希望使用它们为我们创建的对象提供 memory model,一种直接的想法就是利用特定的 allocator,或者直接替换掉全局的 new/delete operator。

boost.pool 也提供了对应的 allocator,对应 boost::pool、boost::fast_pool 都有自己的 allocator,利用好 allocator 可以直接改变 STL 的行为和性能。

——————
And Nahor lived after he begat Terah an hundred and nineteen years, and begat sons and daughters.

STL 与 allocator

Matlab 的 OOP

一直没有仔细看过 Matlab 的 OOP。这次稍微学习了一下。Matlab 的 class 定义使用 classdef … end 结构。注意的是,和 C++ 和 Java 需要编译不同,Matlab 的类完全可以在内存里面存在实例化对象时,其源文件被更改,这时 Matlab 会给出警告,要求先 clear 那些对象才能产生新的对象。类定义放在一个 .m 文件里面即可,还有一种是创建一个 @ClassName 目录,里面 ClassName.m 里面写类定义,而在别的 .m 里面实现方法,文件名和方法名一致。

classdef 这个里面含有两个最常用的 section,一个是 properties … end,另一个是 methods … end,和 C++ 等设置访问权限类似,这里可以用 (SetAccess = private, GetAcess=public) 这种方式指定成员被访问的限制,property 可以在 properties 里面指定初识值。这里如果需要继承,是在 classdef 后使用 < parentClass 的方法,最常见的父类可能就是 handle。

properties

property 默认的是 public,这点和 C++ 不同。

另有一种 property 是 Dependent = true 的,表明其获得依赖于别的属性,一般使用 get.PropertyName 方法提供访问方法。另外某些 property 需要 set.PropertyName 方法进行设置,这样类设计者可以控制该属性的取值。另外有 (set?)getPropValue 方法用于实现通过字符串(对应 property name)访问成员的逻辑。

methods

methods 出了构造函数以外均和 python 类似,即第一个参数是对象本身。构造函数需要返回对象,但参数列表里面没有对象。

静态方法需要在 method 后面用 Static 表明。私有方法需要用 Aceess=private 表明。

如果希望通过 disp 显示对象,需要实现 disp 方法。

events

matlab 也支持消息通讯机制(继承 handle),在 events 段可以声明支持的 event 名称(即 signal),Matlab 通过调用 notify( obj, ‘EventName’) 激活关联的 callback functions,而通过 addlistener( obj, ‘EventName’, functionHandle ) 注册一个 callback function(即 slot)。但是 Matlab 的 event 机制并不像 signal/slots 那么灵活,不是一个很好的 delegation 的实现。

下面是一个简单的例子:

classdef myclass < handle
  events
    valueChanged
  end

  properties ( SetAccess = public, GetAccess = public)
    value
  end

  methods
    function obj = myclass( v )
      obj.value = v ;
    end

    function disp( obj )
      disp( obj.value ) ;
    end

    function obj = set.value( obj, v )
      if v < 0
        error( 'the value must be non-negative!' ) ;
      end
      obj.value = v ;
      notify( obj, 'valueChanged' ) ;
    end
  end
end

运行的脚本如下

a = myclass(1) ;
addlistener( a, 'valueChanged', @(x, y) disp(sin( x.value ) ) ) ;
a.value =  2 ;

——————
And his brother’s name was Jubal: he was the father of all such as handle the harp and organ.

Matlab 的 OOP

scatter 的问题

我们都知道可以利用 scatter/scatter3 画出散点图,利用参数 s/c 决定每个点的颜色。但是很奇怪的事情是

scatter(x, y, [], c);
print -painters -depsc2 my.eps

在 c 为一个 RGB 数组的时候会出现错误。Matlab 做图输出有 3 种 render,这里的 -painters 参数选择的就是最常用的,输出格式是矢量的 render(另外两种是 zbuffer 和 opengl,但均仅仅支持点阵图片)。有时候也许我们并没有一个标量来衡量颜色,而仅仅知道那一点的 RGB,这个时候 print 命令就不会正常的输出我们想要的格式了,它会抱怨, RGB 不被 painters 支持。

一个解决方案是

scatter(x, y, [], 1:length(x));
colormap(c);
print -painters -depsc2 my.eps

我有点怀疑 painters 是设置了一个 pallete,而 colormap 就是这个 pallete。但是像这样暴力的设置 pallelte 是比较 ws 的,更好的办法还是指定一个固定的 pallete,通过对 c 进行 clustering 获得每个样本颜色的代表元。然后传进 scatter 代表元的 id,重新设置 colormap 即可,但是会损失颜色的精度,产生的 eps 文件会相对较小一点。

给个例子吧…

Query 数据的可视化

——————
Let not the sword-blade mock its handle for being blunt.

scatter 的问题