MQL5 中的范畴论 (第 1 部分)

文章介绍了范畴论中的基本概念,如域(集合)和态射(函数)。通过C++类`CElement`和`CDomain`展示了域的实现,强调了元素的唯一性和域的基数管理。接着,文章讨论了态射的不同类型,如单态、表态、同构、自同态和自同构,并提供了一个简单的`CMorphism`类来表示态射。最后,`CHomomorphism`类用于组织同态,管理域之间的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

范畴域态射(Morphisms)是范畴论的基本概念。 在范畴论中,范畴是元素的域(又名集合),以及态射(或箭头又名映射,又名函数)它们之间的集合。 在这些文章中,我们取箭头、函数或映射作为态射的基本单位。 这些态射针对范畴内每个域中的元素之间的关系进行编码,并且可将它们组合成更复杂的态射。

集合是数学中的基本概念,它们在范畴论中起着关键作用。 在范畴论中,我们将它们称为用于定义特定“种类”元素的域。 典型情况,如果我们研究域范畴,范畴的“元素”将是域本身。 这些域,通常但又并非总是,继续包含构成态射基础的其它元素。 此范畴中的态射将是域之间的函数,这些函数是一个域的每个元素与另一个域的唯一元素相关联的规则。 例如,如果我们有两个域 A 和 B,则从 A 到 B 的态射将是一个规则,它将 A 的每个元素分配给 B 的唯一元素。当态射从 A 转运到 B 时,A 被称为“本域”,而 B 是“协域”。 本域中的所有元素都将与协域中的至少一个元素有关系。 本域中的任何元素都不会保持“未映射”状态。 然而,协域中的某些元素可能是“未映射”的。 这经常表示如下。

//+------------------------------------------------------------------+
//| ELEMENT CLASS                                                    |
//+------------------------------------------------------------------+
class CElement
   {
      protected:
      
      int                           cardinal;
      vector                        element;
      
      public:
      
      bool                          Cardinality(int Value) { if(Value>=0 && Value<INT_MAX) { cardinal=Value; element.Init(cardinal); return(true); } return(false); }
      int                           Cardinality() { return(cardinal); }
      
      double                        Get(int Index) { if(Index>=0 && Index<Cardinality()) { return(element[Index]); } return(EMPTY_VALUE); }
      bool                          Set(int Index,double Value) { if(Index>=0 && Index<Cardinality()) { element[Index]=Value; return(true); } return(false); }
      
                                    CElement(void)
                                    {
                                       Cardinality(0);
                                    };
                                    ~CElement(void) {};
   };

故此,从上面的清单中,我们可以从定义一个元素开始。 这是一个域的基本单位,您可以把它当作一个“集合的成员”。 该单元可以采用任何数据类型,无论是双精度型还是整数型,不过若要满足更复杂的数据类型和运算时,向量类型将更加灵活。 它允许可扩展性。 其大小,'cardinal' 参数受到保护,只能通过 Cardinality()' 函数访问或修改。 保护其访问可确保无论何时修改向量,都会相应调整其大小。 向量 “element” 本身也受到保护,以防止无效的索引错误。 故此,仅允许通过 “Get()” 和 “Set()” 函数进行访问。 'Set()' 函数还返回一个布尔值来验证赋值是否成功。

//+------------------------------------------------------------------+
//| DOMAIN CLASS                                                     |
//+------------------------------------------------------------------+
class CDomain
   {
      protected:
      
      int                           cardinal;
      CElement                      elements[];
      
      public:
      
      bool                          Cardinality(int Value) { if(Value>=0 && Value<INT_MAX) { cardinal=Value; ArrayResize(elements,cardinal); return(true); } return(false); }
      int                           Cardinality() { return(cardinal); }
      
      bool                          Get(int Index,CElement &Element) { if(Index>=0 && Index<Cardinality()) { Element=elements[Index]; return(true); } return(false); }
      bool                          Set(int Index,CElement &Value,bool IsNew=false) { if(Index>=0 && Index<Cardinality()) { if(!IsNew||New(Value)<0) { elements[Index]=Value; return(true); }} return(false); }
      
      //only unique elements allowed
      int                           New(CElement &Value)
                                    {
                                       bool _new=-1;
                                       //
                                       for(int o=0; o<cardinal; o++)
                                       {
                                          if(ElementMatch(Value,elements[o]))
                                          {
                                             _new=o;
                                             break;
                                          }
                                       }
                                       
                                       return(_new);
                                    }
      
                                    CDomain(void)
                                    {
                                       Cardinality(0);
                                    };
                                    ~CDomain(void) {};
   };

因此,其内包括元素的域类,已在上面介绍过了。 它的主要变量 “elements[]” 和它的大小 “cardinal” 如同上述在元素类中一样受到保护。 这里略有不同的是添加了 “New()” 方法。 该函数帮助检查所要添加到域中的新对象,并确保它们的唯一性。 范畴域仅包含唯一对象。 不允许有重复。 

由于我们有这两个类,我们可以尝试构造一些域。 我们来尝试一个偶数和一个奇数域。 我们可以运行一个脚本来引用这些类。 脚本清单如下所示。

//+------------------------------------------------------------------+
//| INPUTS                                                           |
//+------------------------------------------------------------------+
input int __domain_elements=3;
input int __domain_morphisms=5;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
   {
      //Declare a sets of natural even & odd numbers
      CDomain _evens,_odds;
      CreateNumberDomain(_evens,__domain_elements,2);
      CreateNumberDomain(_odds,__domain_elements,2,1);
      
      printf(__FUNCSIG__+" evens are... "+PrintDomain(_evens));
      
      printf(__FUNCSIG__+" odds are... "+PrintDomain(_odds));
   }

创建数字函数是一种使用自然数填充域的简单方法。 所有代码都附在文末,但为清楚起见,此处展示出它的设置。

'PrintSet()' 函数是我们经常提到的一种资源丰富的方法。 它简单地令我们能使用相应的括号和逗号查看域的内容,精心将元素向量结构与整体域结构分离。 如果我们运行上面的脚本,这就是我们应该看到的。

2022.12.08 18:49:13.890 ct_1 (EURGBP.ln,MN1) void OnStart() evens are... {(2.0),(4.0),(6.0),(8.0),(10.0),(12.0),(14.0)}

2022.12.08 18:49:13.890 ct_1 (EURGBP.ln,MN1) void OnStart() odds are... {(1.0),(3.0),(5.0),(7.0),(9.0),(11.0),(13.0)}

在括号中都是每个域的各种元素,因为它们是向量数据类型,这意味着它们本身可以有多个条目。 若发生这种情况时,在每个带有括号的条目之间出现逗号,如此来帮助定义元素边界的位置。

态射也是范畴论中的一个重要概念,它们为域中元素之间的关系进行编码。 根据范畴论规则,每个态射将域中的一个元素映射到协域中的一个元素。 这些函数可以组合成更复杂的态射,它们可以用来研究集合的性质,以及它们与其它集合的关系,正如我们将看到的。

通览伊始,态射有 5 种主要类型,可用于描述给定类别中对象之间的关系。 一些最常见的类型是:

  1. 单态:这些是单射(injective)态射,这意味着它们将源域中的每个元素映射到协域中的唯一对象。 不会有两个态射映射到协域中的同一对象。 在这种情况下,您也许有一些对象在目标中无映射。
  2. 表态:这些是漫射(surjective)态射,这意味着域中的元素映射到协域中的所有元素。 换言之,协域中没有任何元素会保持无映射。 在这种实例下,协域中的元素通常少于源集合中的元素。
  3. 同构:同构是双射(bijective)态射,这意味着它们在源和目标范畴中的对象之间建立一对一的对应关系。 它们既是单射的,也是漫射的,因为源集合和目标集合具有相同数量的对象。
  4. 自同态:自同态是从元素到自身的态射。 它构成了一个恒等映射,即一组链接回域的自同态。
  5. 自同构:自同构是同构和自同态的映射组合。

我们看看如何以 MQL 实现态射类,以及它与域的分组作为同态。

//+------------------------------------------------------------------+
//| MORPHISM CLASS                                                   |
//+------------------------------------------------------------------+
class CMorphism
   {
      public:
      
      int                           domain;
      int                           codomain;
      
      CElement                      morphism;
      
      bool                          Morph(CDomain &D,CDomain &C,CElement &DE,CElement &CE,bool Add=true)
                                    {
                                       int _d=D.New(DE),_c=C.New(CE);
                                       //
                                       if(_d>=0 && _c>=0)
                                       {
                                          if(DE.Cardinality()==CE.Cardinality())
                                          {
                                             domain=_d;
                                             codomain=_c;
                                             
                                             morphism.Cardinality(DE.Cardinality());
                                             
                                             if(Add)
                                             {
                                                for(int c=0;c<morphism.Cardinality();c++)
                                                {
                                                   morphism.Set(c,CE.Get(c)-DE.Get(c));
                                                }
                                             }
                                             else
                                             {
                                                for(int c=0;c<morphism.Cardinality();c++)
                                                {
                                                   if(DE.Get(c)!=0.0){ morphism.Set(c,CE.Get(c)/DE.Get(c)); }
                                                }
                                             }
                                          }
                                       }
                                       
                                       return(false);
                                    }
      
      
                                    CMorphism(void){ domain=-1; codomain=-1; };
                                    ~CMorphism(void){};
   };

态射类是非常基本的,只有域和协域索引参数以及一个 “Morph” 函数,本文当中我们不会关注该函数。 此处省略了对相应域集合和协域集合的引用,因为它们列在伞形同态类中,如下所示。

//+------------------------------------------------------------------+
//| HOMO-MORPHISM CLASS                                              |
//+------------------------------------------------------------------+
class CHomomorphism
   {
      protected:
      
      int                           cardinal;
      
      CMorphism                     morphism[];
      
      public:
      
      bool                          init;
      
      CDomain                       domain;
      CDomain                       codomain;
      
      bool                          Cardinality(int DomainIndex,int CodomainIndex,bool Add=true)
                                    { 
                                       bool _morphed=true; 
                                       
                                       if
                                       (
                                       !init
                                       )
                                       {
                                          _morphed=false; return(_morphed); 
                                       }
                                       
                                       if
                                       (
                                       DomainIndex<0 || DomainIndex>=domain.Cardinality() ||
                                       CodomainIndex<0 || CodomainIndex>=codomain.Cardinality()
                                       )
                                       {
                                          _morphed=false; return(_morphed); 
                                       }
                                       
                                       for(int m=0;m<cardinal;m++)
                                       {
                                          if(DomainIndex==morphism[m].domain)
                                          {
                                             _morphed=false; break;
                                          }
                                       } 
                                       
                                       if(_morphed)
                                       {
                                          cardinal++;
                                          ArrayResize(morphism,cardinal);
                                          CElement _de,_ce;
                                          if(domain.Get(DomainIndex,_de) && codomain.Get(CodomainIndex,_ce))
                                          {
                                             morphism[cardinal-1].Morph(domain,codomain,_de,_ce,Add);
                                          }
                                       }
                                       
                                       return(_morphed); 
                                    };
      
      int                           Cardinality()
                                    {
                                       return(cardinal);
                                    };
                                    
      bool                          Get(int Index,CMorphism &Morphism)
                                    {
                                       if(Index>=0 && Index<Cardinality())
                                       {
                                          
                                          return(true);
                                       }
                                       
                                       return(false);
                                    };
                                    
      bool                          Set(int Index,CMorphism &Value)
                                    {
                                       if
                                       (
                                       Index>=0 && Index<Cardinality() && 
                                       Value.domain>=0 && Value.domain<domain.Cardinality() &&
                                       Value.codomain>=0 && Value.codomain<codomain.Cardinality()
                                       )
                                       {
                                          if(!MorphismMatch(Index,Value,morphism,Cardinality()))
                                          {
                                             morphism[Index]=Value;
                                             return(true);
                                          }
                                          
                                       }
                                       
                                       return(false);
                                    };
                                    
      void                          Init(CDomain &Domain,CDomain &Codomain)
                                    {
                                       domain=Domain;
                                       codomain=Codomain;
                                       
                                       init=true;
                                    }
      
      
                                    CHomomorphism(void){ init=false; cardinal=0; };
                                    ~CHomomorphism(void){};
   };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值