LANGUAGE | スカ友 | 俺、関東の国王だけど (イケメンだ(28)、彼女がほしい) 人類の品種 言葉の起源 虫は宇宙人です 日本語は海豚の言葉に由来します ペンギン(ウルトラマン) 関東無政府主義国へようこそ! simulationライブラリで純粋な関数式プログラミングを
simulationライブラリで純粋な関数式プログラミングを
0   関東の国王      2019年1月13日 日 14:44
simulationライブラリで純粋な関数式プログラミングをします。
これではすべてのプログラムを記述できます。
C#, C++, F#バーがあります。

サンプル(太陽と地球のシュミレーション)もつけています(C#での)。
あと、このライブラリを用いて書いた「UI」ライブラリ(2D)もありますよ:
http://x0000.net/topic.aspx?id=3688-0

純粋な関数式とは、状態あり変数も関数式です(下記の「class State<T>」を参照)

C#:

namespace Simulation
{
   interface IUpdate
   {
       void Update();
   void Flush();
   }

   class Manager
   {
       public static Manager TheManager = new Manager();
       private LinkedList<IUpdate> Updates = new LinkedList<IUpdate>();
   public void Add(IUpdate update)
   {
   Updates.AddLast(update);
   }
   public void Update()
   {
   foreach(IUpdate i in Updates)
   i.Update();
   }
   public void Flush()
   {
   foreach(IUpdate i in Updates)
   i.Flush();
   }
   };
   

   interface IVar<T>
   {
       T v();
   };

   class CachedVar<T> : IVar<T>, IUpdate
   {
       private Func<T> FuncValue;
   private T Value;
   private bool Calculated;
       public CachedVar(Func<T> funcValue)
   {
   FuncValue = funcValue;
   Calculated = false;
   Manager.TheManager.Add(this);
   }
   public T v()
   {
   if (Calculated)
   return Value;
   else
   return Value = FuncValue();
   }
   public void Update(){}
   public void Flush()
   {
   Calculated = false;
   }
   };

   class State<T> : IVar<T>, IUpdate
   {
       private Func<T,T> FuncState;
   private T Current, Next;
       public State(T defaultValue, Func<T,T> funcState)
   {
           Current = defaultValue;
   FuncState = funcState;
   Manager.TheManager.Add(this);
   }
   public T v()
   {
   return Current;
   }
   public void Update()
   {
   Next = FuncState(Current);
   }
   public void Flush()
   {
   Current = Next;
   }
   }
}

C#のサンプルです:

namespace SimulationCSharp
{
   public partial class Form1 : Form
   {
       bool Exit = false;

       struct Vec
       {
           public double X, Y;
           public Vec(double x, double y) { X = x; Y = y; }
           public double Norm() { return Math.Sqrt(X * X + Y * Y); }
           public static Vec operator +(Vec v1, Vec v2) { return new Vec(v1.X + v2.X, v1.Y + v2.Y); }
           public static Vec operator -(Vec v1, Vec v2) { return new Vec(v1.X - v2.X, v1.Y - v2.Y); }
           public static Vec operator *(double k, Vec v) { return new Vec(k * v.X, k * v.Y); }
           public static Vec operator *(Vec v, double k) { return new Vec(v.X * k, v.Y * k); }
           public static Vec operator /(Vec v, double k) { return new Vec(v.X / k, v.Y / k); }
       }

       public Form1()
       {
           InitializeComponent();
       }

       private double AU = 149597870691; // m
       private double Year = 3600 * 24 * 365.256363004;
       private double G = 6.67300e-11; // m3*kg-1*s-2
       private double M = 1.98892e30; // kg 太陽
       private double m = 5.9742e24; // kg 地球
       private Vec vm0 = new Vec(30287, 0); // m/s 近日点での速度

       double TScale = 3600 * 24 * 7;
       double dt;
       long t1 = DateTime.Now.Ticks / 1000000;

       State<Vec> sM;
       State<Vec> sm;
       State<Vec> vM;
       State<Vec> vm;

       CachedVar<Vec> r_mM;
       CachedVar<Vec> r_Mm;
       CachedVar<Vec> gm;
       CachedVar<Vec> gM;

       private void Form1_Load(object sender, EventArgs e)
       {
           r_mM = new CachedVar<Vec>(() => sM.v() - sm.v());
           r_Mm = new CachedVar<Vec>(() => sm.v() - sM.v());
           gm = new CachedVar<Vec>(() => G * M * r_mM.v() / Math.Pow(r_mM.v().Norm(), 3));
           gM = new CachedVar<Vec>(() => G * m * r_Mm.v() / Math.Pow(r_Mm.v().Norm(), 3));

           sM = new State<Vec>(new Vec(0.0, 0.0), (x) => x + vM.v() * dt);
           sm = new State<Vec>(new Vec(0.0, 0.9832898912 * AU), (x) => x + vm.v() * dt); // 近日点
           vM = new State<Vec>(new Vec(0.0, 0.0), (x) => x + gM.v() * dt);
           vm = new State<Vec>(vm0, (x) => x + gm.v() * dt);
       }

       private void Form1_FormClosed(object sender, FormClosedEventArgs e)
       {
           Exit = true;
       }

       private void Form1_Shown(object sender, EventArgs e)
       {
           while (Exit == false)
           {
               long t2 = DateTime.Now.Ticks / 1000000;
               dt = TScale * Math.Min(t2 - t1, 0.05);
               t1 = t2;

               Manager.TheManager.Update();

               btnSun.Left = this.Width / 2 + (int)(100.0 * sM.v().X / AU);
               btnSun.Top = this.Height / 2 - (int)(100.0 * sM.v().Y / AU);
               btnEarth.Left = this.Width / 2 + (int)(100.0 * sm.v().X / AU);
               btnEarth.Top = this.Height / 2 - (int)(100.0 * sm.v().Y / AU);

               Manager.TheManager.Flush();

               Application.DoEvents();
           }
       }
   }
}
この記事は 2019年7月9日 火 18:54 に作者によって編集されました
1   関東の国王      2019年1月13日 日 14:44
C++:

#include <list>
#include <functional>

namespace simulation
{

class IUpdate
{
public:
virtual void Update()=0;
virtual void Flush()=0;
};

class Manager
{
private:
std::list<IUpdate *> m_pUpdates;
public:
Manager()
{
m_pUpdates = std::list<IUpdate *>();
}
void Add(IUpdate *pUpdate)
{
m_pUpdates.push_back(pUpdate);
}
void Update()
{
for(std::list<IUpdate *>::iterator i = m_pUpdates.begin(); i != m_pUpdates.end(); i++)
(*i)->Update();
}
void Flush()
{
for(std::list<IUpdate *>::iterator i = m_pUpdates.begin(); i != m_pUpdates.end(); i++)
(*i)->Flush();
}
};

Manager *g_pManager = new Manager;
double g_dt = 0.0;

template <class T> class IVar
{
public:
virtual T v()=0;
};

template <class T> class CachedVar : public IVar<T>, IUpdate
{
private:
std::tr1::function<T()> m_fValue;
T m_Value;
bool m_bCalculated;
public:
CachedVar(std::tr1::function<T()> fValue)
{
m_fValue = fValue;
m_bCalculated = false;
Manager->Add(this);
}
virtual T v()
{
if (m_bCalculated)
return m_Value;
else
return m_Value = m_fValue();
}
virtual void Update(){}
virtual void Flush()
{
m_bCalculated = false;
}
};

template <class T> class State : public IVar<T>, IUpdate
{
private:
std::tr1::function<T(T)> m_fState;
T m_Current, m_Next;
public:
State(T defaultValue, std::tr1::function<T(T)> fState)
{
m_fState = fState;
m_Current = defaultValue;
Manager->Add(this);
}
virtual T v()
{
return m_Current;
}
virtual void Update()
{
m_Next = m_fState(m_Current);
}
virtual void Flush()
{
m_Current = m_Next;
}
};

}
この記事は 2019年5月15日 水 4:29 に作者によって編集されました
2   関東の国王      2019年1月13日 日 14:46
F#:

namespace Simulation

   open System
   open System.Collections.Generic

   type IUpdate = interface
       abstract Update : unit -> unit
       abstract Flush : unit -> unit
   end

   module Manager =
       let Updates = new LinkedList<IUpdate>()
       let Add (update : IUpdate) = ignore (Updates.AddLast update)
       let Update () = for i in Updates do i.Update()
       let Flush () = for i in Updates do i.Flush()

   type IVar<'T> = interface
       abstract v : unit -> 'T
   end

   type CachedVar<'T> = class
       interface IVar<'T> with
           member x.v () =
               if x.Calculated then
                   x.Value
               else
                   x.Value <- x.FuncValue.Invoke ()
                   x.Value
       end
       interface IUpdate with
           member x.Update () = ()
           member x.Flush () = x.Calculated <- false
       end
       val mutable FuncValue : Func<'T>
       [<DefaultValue>]
       val mutable Value : 'T
       val mutable Calculated : bool
       new (funcValue : Func<'T>) as x =
           {
               FuncValue = funcValue;
               Calculated = false
           }
           then
               Manager.Add x
   end

   type State<'T> = class
       interface IVar<'T> with
           member x.v () = x.Current
       end
       interface IUpdate with
           member x.Update () = x.Next <- x.FuncState.Invoke(x.Current)
           member x.Flush () = x.Current <- x.Next
       end
       val mutable FuncState : Func<'T,'T>
       val mutable Current : 'T
       [<DefaultValue>]
       val mutable Next : 'T
       new (defaultValue : 'T, funcState : Func<'T,'T>) as x =
           {
               Current = defaultValue;
               FuncState = funcState
           }
           then
               Manager.Add x
   end
この記事は 2019年5月15日 水 4:30 に作者によって編集されました
  返信
3   https://pomodorr.com/      2019年5月26日 日 19:33
Thank you for every other great article. The place else could anyone get
that type of information in such a perfect manner of writing?
I've a presentation subsequent week, and I am on the search for such information.
  返信
4   pomodor.com      2019年5月28日 火 11:49
It's in fact very difficult in this busy life to listen news on Television, therefore
I simply use internet for that purpose, and take the latest news.
  返信
5   Salesforce Gadget      2019年7月4日 木 7:01
Do you have a spam issue on this site; I also am a blogger,
and I was wanting to know your situation; we have created some
nice practices and we are looking to trade solutions with
other folks, why not shoot me an email if interested.
  返信
6   Salesforce Gadget      2019年7月4日 木 11:05
Way cool! Some very valid points! I appreciate you writing this write-up plus the rest of the site is also really good.
名前      編集用パスワード(省略可)    パスワードの記憶
数式 αβγ IPA http:// 画像 B I U
(添付ファイルは http://up.x0000.net/ にアップロードしてください)