<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/shell/shell_content_renderer_client.h"

#include "base/callback.h"
#include "base/command_line.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/layouttest_support.h"
#include "content/shell/shell_render_process_observer.h"
#include "content/shell/shell_switches.h"
#include "content/shell/webkit_test_runner.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
#include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/WebTestProxy.h"
#include "v8/include/v8.h"

using WebKit::WebFrame;
using WebTestRunner::WebTestProxyBase;

namespace content {

namespace {

bool IsLocalhost(const std::string& host) {
  return host == "127.0.0.1" || host == "localhost";
}

bool HostIsUsedBySomeTestsToGenerateError(const std::string& host) {
  return host == "255.255.255.255";
}

bool IsExternalPage(const GURL& url) {
  return !url.host().empty() &&
         (url.SchemeIs(chrome::kHttpScheme) ||
          url.SchemeIs(chrome::kHttpsScheme)) &&
         !IsLocalhost(url.host()) &&
         !HostIsUsedBySomeTestsToGenerateError(url.host());
}

}  // namespace

ShellContentRendererClient::ShellContentRendererClient() {
  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
    EnableWebTestProxyCreation(
        base::Bind(&ShellContentRendererClient::WebTestProxyCreated,
                   base::Unretained(this)));
  }
}

ShellContentRendererClient::~ShellContentRendererClient() {
}

void ShellContentRendererClient::RenderThreadStarted() {
  shell_observer_.reset(new ShellRenderProcessObserver());
}

bool ShellContentRendererClient::OverrideCreatePlugin(
    RenderView* render_view,
    WebKit::WebFrame* frame,
    const WebKit::WebPluginParams& params,
    WebKit::WebPlugin** plugin) {
  std::string mime_type = params.mimeType.utf8();
  if (mime_type == content::kBrowserPluginMimeType) {
    // Allow browser plugin in content_shell only if it is forced by flag.
    // Returning true here disables the plugin.
    return !CommandLine::ForCurrentProcess()->HasSwitch(
        switches::kEnableBrowserPluginForAllViewTypes);
  }
  return false;
}

bool ShellContentRendererClient::WillSendRequest(
    WebFrame* frame,
    PageTransition transition_type,
    const GURL& url,
    const GURL& first_party_for_cookies,
    GURL* new_url) {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (!command_line->HasSwitch(switches::kDumpRenderTree))
    return false;
  if (!command_line->HasSwitch(switches::kAllowExternalPages) &&
      IsExternalPage(url) && !IsExternalPage(first_party_for_cookies)) {
    ShellRenderProcessObserver::GetInstance()->test_delegate()->printMessage(
        std::string("Blocked access to external URL " + url.spec() + "\n"));
    *new_url = GURL();
    return true;
  }
  *new_url = RewriteLayoutTestsURL(url);
  return true;
}

void ShellContentRendererClient::WebTestProxyCreated(RenderView* render_view,
                                                     WebTestProxyBase* proxy) {
  WebKitTestRunner* test_runner = new WebKitTestRunner(render_view);
  if (!ShellRenderProcessObserver::GetInstance()->test_delegate()) {
    ShellRenderProcessObserver::GetInstance()->SetMainWindow(render_view,
                                                             test_runner,
                                                             test_runner);
  }
  test_runner->set_proxy(proxy);
  proxy->setDelegate(
      ShellRenderProcessObserver::GetInstance()->test_delegate());
  proxy->setInterfaces(
      ShellRenderProcessObserver::GetInstance()->test_interfaces());
}

GURL ShellContentRendererClient::RewriteLayoutTestsURL(const GURL& url) {
  const char kPrefix[] = "file:///tmp/LayoutTests/";
  const int kPrefixLen = arraysize(kPrefix) - 1;

  if (url.spec().compare(0, kPrefixLen, kPrefix, kPrefixLen))
    return url;

  FilePath replace_path =
      ShellRenderProcessObserver::GetInstance()->webkit_source_dir().Append(
          FILE_PATH_LITERAL("LayoutTests/"));
#if defined(OS_WIN)
  std::string utf8_path = WideToUTF8(replace_path.value());
#else
  std::string utf8_path =
      WideToUTF8(base::SysNativeMBToWide(replace_path.value()));
#endif
  std::string new_url =
      std::string("file://") + utf8_path + url.spec().substr(kPrefixLen);
  return GURL(new_url);
}

}  // namespace content
<commit_msg>[content shell] add support for the WebTestPlugin<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/shell/shell_content_renderer_client.h"

#include "base/callback.h"
#include "base/command_line.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/layouttest_support.h"
#include "content/shell/shell_render_process_observer.h"
#include "content/shell/shell_switches.h"
#include "content/shell/webkit_test_runner.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
#include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/WebTestPlugin.h"
#include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/WebTestProxy.h"
#include "v8/include/v8.h"

using WebKit::WebFrame;
using WebTestRunner::WebTestPlugin;
using WebTestRunner::WebTestProxyBase;

namespace content {

namespace {

bool IsLocalhost(const std::string& host) {
  return host == "127.0.0.1" || host == "localhost";
}

bool HostIsUsedBySomeTestsToGenerateError(const std::string& host) {
  return host == "255.255.255.255";
}

bool IsExternalPage(const GURL& url) {
  return !url.host().empty() &&
         (url.SchemeIs(chrome::kHttpScheme) ||
          url.SchemeIs(chrome::kHttpsScheme)) &&
         !IsLocalhost(url.host()) &&
         !HostIsUsedBySomeTestsToGenerateError(url.host());
}

}  // namespace

ShellContentRendererClient::ShellContentRendererClient() {
  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
    EnableWebTestProxyCreation(
        base::Bind(&ShellContentRendererClient::WebTestProxyCreated,
                   base::Unretained(this)));
  }
}

ShellContentRendererClient::~ShellContentRendererClient() {
}

void ShellContentRendererClient::RenderThreadStarted() {
  shell_observer_.reset(new ShellRenderProcessObserver());
}

bool ShellContentRendererClient::OverrideCreatePlugin(
    RenderView* render_view,
    WebKit::WebFrame* frame,
    const WebKit::WebPluginParams& params,
    WebKit::WebPlugin** plugin) {
  std::string mime_type = params.mimeType.utf8();
  if (mime_type == content::kBrowserPluginMimeType) {
    // Allow browser plugin in content_shell only if it is forced by flag.
    // Returning true here disables the plugin.
    return !CommandLine::ForCurrentProcess()->HasSwitch(
        switches::kEnableBrowserPluginForAllViewTypes);
  }
  if (params.mimeType == WebTestPlugin::mimeType()) {
    *plugin = WebTestPlugin::create(
        frame,
        params,
        ShellRenderProcessObserver::GetInstance()->test_delegate());
    return true;
  }
  return false;
}

bool ShellContentRendererClient::WillSendRequest(
    WebFrame* frame,
    PageTransition transition_type,
    const GURL& url,
    const GURL& first_party_for_cookies,
    GURL* new_url) {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (!command_line->HasSwitch(switches::kDumpRenderTree))
    return false;
  if (!command_line->HasSwitch(switches::kAllowExternalPages) &&
      IsExternalPage(url) && !IsExternalPage(first_party_for_cookies)) {
    ShellRenderProcessObserver::GetInstance()->test_delegate()->printMessage(
        std::string("Blocked access to external URL " + url.spec() + "\n"));
    *new_url = GURL();
    return true;
  }
  *new_url = RewriteLayoutTestsURL(url);
  return true;
}

void ShellContentRendererClient::WebTestProxyCreated(RenderView* render_view,
                                                     WebTestProxyBase* proxy) {
  WebKitTestRunner* test_runner = new WebKitTestRunner(render_view);
  if (!ShellRenderProcessObserver::GetInstance()->test_delegate()) {
    ShellRenderProcessObserver::GetInstance()->SetMainWindow(render_view,
                                                             test_runner,
                                                             test_runner);
  }
  test_runner->set_proxy(proxy);
  proxy->setDelegate(
      ShellRenderProcessObserver::GetInstance()->test_delegate());
  proxy->setInterfaces(
      ShellRenderProcessObserver::GetInstance()->test_interfaces());
}

GURL ShellContentRendererClient::RewriteLayoutTestsURL(const GURL& url) {
  const char kPrefix[] = "file:///tmp/LayoutTests/";
  const int kPrefixLen = arraysize(kPrefix) - 1;

  if (url.spec().compare(0, kPrefixLen, kPrefix, kPrefixLen))
    return url;

  FilePath replace_path =
      ShellRenderProcessObserver::GetInstance()->webkit_source_dir().Append(
          FILE_PATH_LITERAL("LayoutTests/"));
#if defined(OS_WIN)
  std::string utf8_path = WideToUTF8(replace_path.value());
#else
  std::string utf8_path =
      WideToUTF8(base::SysNativeMBToWide(replace_path.value()));
#endif
  std::string new_url =
      std::string("file://") + utf8_path + url.spec().substr(kPrefixLen);
  return GURL(new_url);
}

}  // namespace content
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <codecvt>
//#include <cstddef>
#include <locale>
#include <clocale>
#include <string>
#include <iomanip>
#include <ctime>

#include "cp-neural.h"

using std::wcout; using std::wstring;
using std::cerr; using std::vector;

class Text {
private:
    bool isinit=false;
    bool readDataFile(string inputfile) {
        std::wifstream txtfile(inputfile, std::ios::binary);
        if (!txtfile.is_open()) {
            return false;
        }
        txtfile.imbue(std::locale("en_US.UTF-8"));
        wstring ttext((std::istreambuf_iterator<wchar_t>(txtfile)),
                     std::istreambuf_iterator<wchar_t>());
        txtfile.close();
        text=ttext;
        filename=inputfile;
        return true;
    }
public:
    wstring text;
    string filename;
    std::map<wchar_t,int> freq;
    std::map<wchar_t,int> w2v;
    std::map<int,wchar_t> v2w;
    Text(string filename) {
        if (readDataFile(filename)) {
            for (auto wc : text) {
                freq[wc]++;
            }
            int it=0;
            for (auto wc : freq) {
                w2v[wc.first]=it;
                v2w[it]=wc.first;
                ++it;
            }
            isinit=true;
            cerr << "Freq:" << freq.size() << ", w2v:" << w2v.size() << ", v2w:" << v2w.size() << endl;
        }
    }
    ~Text() {

    }
    bool isInit() {
        return isinit;
    }
    int vocsize() {
        if (!isinit) return 0;
        return (int)v2w.size();
    }

    wstring sample(int len) {
        int p=std::rand()%(text.size()-len);
        return text.substr(p,len);
    }
};

void currentDateTime(wstring& timestr) {
    time_t     now = time(0);
    struct tm  tstruct;
    char       buf[80];
    tstruct = *localtime(&now);
    // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime
    // for more information about date/time format
    strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
    timestr=std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(buf);
}

int main(int argc, char *argv[]) {
#ifndef __APPLE__
    std::setlocale(LC_ALL, "");
#else
    setlocale(LC_ALL, "");
    std::wcout.imbue(std::locale("en_US.UTF-8"));
#endif
    wcout << L"Rnn-Readär" << std::endl;

    bool allOk=true;
    if (argc!=2) {
        cerr << L"rnnreader <path-to-text-file>" << endl;
        exit(-1);
    }
    Text txt(argv[1]);
    if (!txt.isInit()) {
        cerr << "Cannot initialize Text object from inputfile: " << argv[1] << endl;
        exit(-1);
    }

    wcout << L"Text size: " << txt.text.size() << endl;

    wcout << L"Size of vocabulary:" << txt.freq.size() << std::endl;
/*    for (auto f : txt.freq) {
        int c=(int)f.first;
        wstring wc(1,f.first);
        wcout << wc << L"|" <<  wchar_t(f.first) << L"(0x" << std::hex << c << L")" ": " << std::dec <<  f.second << endl;
    }
*/
    Color::Modifier red(Color::FG_RED);
    Color::Modifier green(Color::FG_GREEN);
    Color::Modifier def(Color::FG_DEFAULT);

    int T=96;

    int N=(int)txt.text.size() / (T+1);
    cerr << N << " Max datasets" << endl;
    MatrixN Xr(N,T);
    MatrixN yr(N,T);

    wstring chunk,chunky;
    int n=0;
    for (int i=0; i<N; i++) {
        wstring smp = txt.sample(T+1);
        chunk=smp.substr(0,T);
        chunky=smp.substr(1,T);
        for (int t=0; t<T; t++) {
            Xr(i,t)=txt.w2v[chunk[t]];
            yr(i,t)=txt.w2v[chunky[t]];
        }
        ++n;
    }

    int maxN = 100000;
    if (n>maxN) n=maxN;
    int n1=n*0.9;
    int dn=(n-n1)/2;
    if (n1+2*dn > n) {
        cerr << "Math doesn't work out." << endl;
    }

    cerr << n1 << " datasets, " << dn << " test-sets, " << dn << " validation-sets" << endl;

/*    MatrixN X(n1,T);
    MatrixN y(n1,T);
    MatrixN Xv(dn,T);
    MatrixN yv(dn,T);
    MatrixN Xt(dn,T);
    MatrixN yt(dn,T);
*/
    MatrixN X=Xr.block(0,0,n1,T);
    MatrixN y=yr.block(0,0,n1,T);
    MatrixN Xv=Xr.block(n1,0,dn,T);
    MatrixN yv=yr.block(n1,0,dn,T);
    MatrixN Xt=Xr.block(n1+dn,0,dn,T);
    MatrixN yt=yr.block(n1+dn,0,dn,T);

    unsigned int ctm=(unsigned int)std::time(0);
    std::srand(ctm);

    cpInitCompute("Rnnreader");
    registerLayers();

    LayerBlockOldStyle lb(R"({"name":"rnnreader","init":"orthonormal"})"_json);
    int VS=txt.vocsize();
    int H=128; // 400;
    int BS=64; // 96;
    float clip=5.0;

    //int D=64;
    // CpParams cp0;
    // cp0.setPar("inputShape",vector<int>{T});
    // cp0.setPar("V",VS);
    // cp0.setPar("D",D);
    // cp0.setPar("clip",clip);
    // cp0.setPar("init",(string)"orthonormal");
    // lb.addLayer("WordEmbedding","WE0",cp0,{"input"});

    string rnntype="LSTM"; // or "RNN"
    cerr << "RNN-type: " << rnntype << endl;

    json j0;
    string oName{"OH0"};
    j0["inputShape"]=vector<int>{T};
    j0["V"]=VS;
    lb.addLayer("OneHot",oName,j0,{"input"});

    string nName;
    json j1;
    j1["inputShape"]=vector<int>{VS,T};
    j1["N"]=BS;
    j1["H"]=H;
    j1["forgetgateinitones"]=true;
    //j1["forgetbias"]=0.10;
    j1["clip"]=clip;
    int layer_depth1=2; // 6;
    j1["H"]=H;
    for (auto l=0; l<layer_depth1; l++) {
        if (l>0) j1["inputShape"]=vector<int>{H,T};
        nName="lstm"+std::to_string(l);
        lb.addLayer(rnntype,nName,j1,{oName});
        oName=nName;
    }

    json j10;
    j10["inputShape"]=vector<int>{H,T};
    j10["M"]=VS;
    lb.addLayer("TemporalAffine","af1",j10,{oName});

    json j11;
    j11["inputShape"]=vector<int>{VS,T};
    lb.addLayer("TemporalSoftmax","sm1",j11,{"af1"});

    if (!lb.checkTopology(true)) {
        allOk=false;
        cerr << red << "Topology-check for LayerBlock: ERROR." << def << endl;
    } else {
        cerr << green << "Topology-check for LayerBlock: ok." << def << endl;
    }

    //json jc;
    //lb.getLayerConfiguration(jc);
    //cerr << jc.dump(4) << endl;

    // preseverstates no longer necessary for training!
    json jo(R"({"verbose":true,"shuffle":false,"preservestates":false,"notests":false,"nofragmentbatches":true,"epsilon":1e-8})"_json);
    jo["lossfactor"]=1.0/(floatN)T;  // Allows to normalize the loss with T.
    json j_opt(R"({"learning_rate":2.2e-2})"_json);
    j_opt["inputShape"]=vector<int>{H,T};
    json j_loss(R"({"name":"temporalsoftmax"})"_json);
    j_loss["inputShape"]=vector<int>{H,T};
    floatN dep=3.0; // 70.0;
    floatN sep=0.0;
    jo["epochs"]=(floatN)dep;
    jo["batch_size"]=BS;
    floatN lr_decay = 0.99; // 0.15;

    Optimizer *pOpt=optimizerFactory("Adam",j_opt);
    t_cppl OptimizerState{};
    Loss *pLoss=lossFactory("TemporalCrossEntropy",j_loss);

    for (int i=0; i<1000; i++) {
        jo["startepoch"]=(floatN)sep;
        j_opt["learning_rate"] = floatN(j_opt["learning_rate"]) * lr_decay;
        pOpt->updateOptimizerParameters(j_opt);
        t_cppl states;
        t_cppl statesv;
        states["y"] = new MatrixN(y);
        statesv["y"] = new MatrixN(yv);
        lb.train(X, &states, Xv, &statesv, pOpt, &OptimizerState, pLoss, jo);
        cppl_delete(&states);
        cppl_delete(&statesv);

        sep+=dep;

        int pos=rand() % 1000 + 5000;
        wstring instr=txt.text.substr(pos,T);

        MatrixN xg(1,T);
        for (int i=0; i<T; i++) {
            xg(0,i)=txt.w2v[instr[i]];
       }
        wstring sout{};
        Layer* plstm0=lb.layerMap["lstm0"];
        t_cppl statesg{};
        plstm0->genZeroStates(&statesg, 1);

        int g,t,v;
        for (g=0; g<300; g++) {
            t_cppl cache{};

            /* MatrixN probs_xx=*/ lb.forward(xg,&cache, &statesg);
            // Forward generates the 'wrong' permutation of output. QUick-hack is abusing the 'cache' to get the permutation.
            if (cache.find("sm1-probst")==cache.end()) {
                cerr << "probst didn't make it, FATAL" << endl;
                exit(1);
            }
            MatrixN probst=*(cache["sm1-probst"]); // XXX check if temporal softmax uses redundant morpher!
            MatrixN probsd=MatrixN(T,VS);
            for (t=0; t<T; t++) {
                for (v=0; v<VS; v++) {
                    probsd(t,v)=probst(0,t*VS+v);
                }
            }
            int li = -1;
            for (t=0; t<T; t++) {
                vector<floatN> probs(VS);
                vector<floatN> index(VS);
                for (v=0; v<VS; v++) {
                    probs[v]=probsd(t,v);
                    index[v]=v;
                }
                li=(int)index[randomChoice(index, probs)];
            }
            cppl_delete(&cache);

            for (int t=0; t<T-1; t++) {
                xg(0,t)=xg(0,t+1);
            }
            xg(0,T-1)=li;
            sout += txt.v2w[li];
        }
        wcout << "output: " << sout << endl;
        wstring timestr;
        currentDateTime(timestr);
        std::wofstream fl("rnnreader.txt", std::ios_base::app);
        fl << "---- " << timestr << ", ep:" << sep << " ---" << endl;
        fl << sout << endl;
        fl.close();
        cppl_delete(&statesg);
    }
    delete pOpt;
    cppl_delete(&OptimizerState);
    delete pLoss;
}
<commit_msg>default lr_decay algo<commit_after>#include <iostream>
#include <fstream>
#include <codecvt>
//#include <cstddef>
#include <locale>
#include <clocale>
#include <string>
#include <iomanip>
#include <ctime>

#include "cp-neural.h"

using std::wcout; using std::wstring;
using std::cerr; using std::vector;

class Text {
private:
    bool isinit=false;
    bool readDataFile(string inputfile) {
        std::wifstream txtfile(inputfile, std::ios::binary);
        if (!txtfile.is_open()) {
            return false;
        }
        txtfile.imbue(std::locale("en_US.UTF-8"));
        wstring ttext((std::istreambuf_iterator<wchar_t>(txtfile)),
                     std::istreambuf_iterator<wchar_t>());
        txtfile.close();
        text=ttext;
        filename=inputfile;
        return true;
    }
public:
    wstring text;
    string filename;
    std::map<wchar_t,int> freq;
    std::map<wchar_t,int> w2v;
    std::map<int,wchar_t> v2w;
    Text(string filename) {
        if (readDataFile(filename)) {
            for (auto wc : text) {
                freq[wc]++;
            }
            int it=0;
            for (auto wc : freq) {
                w2v[wc.first]=it;
                v2w[it]=wc.first;
                ++it;
            }
            isinit=true;
            cerr << "Freq:" << freq.size() << ", w2v:" << w2v.size() << ", v2w:" << v2w.size() << endl;
        }
    }
    ~Text() {

    }
    bool isInit() {
        return isinit;
    }
    int vocsize() {
        if (!isinit) return 0;
        return (int)v2w.size();
    }

    wstring sample(int len) {
        int p=std::rand()%(text.size()-len);
        return text.substr(p,len);
    }
};

void currentDateTime(wstring& timestr) {
    time_t     now = time(0);
    struct tm  tstruct;
    char       buf[80];
    tstruct = *localtime(&now);
    // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime
    // for more information about date/time format
    strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
    timestr=std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(buf);
}

int main(int argc, char *argv[]) {
#ifndef __APPLE__
    std::setlocale(LC_ALL, "");
#else
    setlocale(LC_ALL, "");
    std::wcout.imbue(std::locale("en_US.UTF-8"));
#endif
    wcout << L"Rnn-Readär" << std::endl;

    bool allOk=true;
    if (argc!=2) {
        cerr << L"rnnreader <path-to-text-file>" << endl;
        exit(-1);
    }
    Text txt(argv[1]);
    if (!txt.isInit()) {
        cerr << "Cannot initialize Text object from inputfile: " << argv[1] << endl;
        exit(-1);
    }

    wcout << L"Text size: " << txt.text.size() << endl;

    wcout << L"Size of vocabulary:" << txt.freq.size() << std::endl;
/*    for (auto f : txt.freq) {
        int c=(int)f.first;
        wstring wc(1,f.first);
        wcout << wc << L"|" <<  wchar_t(f.first) << L"(0x" << std::hex << c << L")" ": " << std::dec <<  f.second << endl;
    }
*/
    Color::Modifier red(Color::FG_RED);
    Color::Modifier green(Color::FG_GREEN);
    Color::Modifier def(Color::FG_DEFAULT);

    int T=96;

    int N=(int)txt.text.size() / (T+1);
    cerr << N << " Max datasets" << endl;
    MatrixN Xr(N,T);
    MatrixN yr(N,T);

    wstring chunk,chunky;
    int n=0;
    for (int i=0; i<N; i++) {
        wstring smp = txt.sample(T+1);
        chunk=smp.substr(0,T);
        chunky=smp.substr(1,T);
        for (int t=0; t<T; t++) {
            Xr(i,t)=txt.w2v[chunk[t]];
            yr(i,t)=txt.w2v[chunky[t]];
        }
        ++n;
    }

    int maxN = 100000;
    if (n>maxN) n=maxN;
    int n1=n*0.9;
    int dn=(n-n1)/2;
    if (n1+2*dn > n) {
        cerr << "Math doesn't work out." << endl;
    }

    cerr << n1 << " datasets, " << dn << " test-sets, " << dn << " validation-sets" << endl;

/*    MatrixN X(n1,T);
    MatrixN y(n1,T);
    MatrixN Xv(dn,T);
    MatrixN yv(dn,T);
    MatrixN Xt(dn,T);
    MatrixN yt(dn,T);
*/
    MatrixN X=Xr.block(0,0,n1,T);
    MatrixN y=yr.block(0,0,n1,T);
    MatrixN Xv=Xr.block(n1,0,dn,T);
    MatrixN yv=yr.block(n1,0,dn,T);
    MatrixN Xt=Xr.block(n1+dn,0,dn,T);
    MatrixN yt=yr.block(n1+dn,0,dn,T);

    unsigned int ctm=(unsigned int)std::time(0);
    std::srand(ctm);

    cpInitCompute("Rnnreader");
    registerLayers();

    LayerBlockOldStyle lb(R"({"name":"rnnreader","init":"orthonormal"})"_json);
    int VS=txt.vocsize();
    int H=128; // 400;
    int BS=64; // 96;
    float clip=5.0;

    //int D=64;
    // CpParams cp0;
    // cp0.setPar("inputShape",vector<int>{T});
    // cp0.setPar("V",VS);
    // cp0.setPar("D",D);
    // cp0.setPar("clip",clip);
    // cp0.setPar("init",(string)"orthonormal");
    // lb.addLayer("WordEmbedding","WE0",cp0,{"input"});

    string rnntype="LSTM"; // or "RNN"
    cerr << "RNN-type: " << rnntype << endl;

    json j0;
    string oName{"OH0"};
    j0["inputShape"]=vector<int>{T};
    j0["V"]=VS;
    lb.addLayer("OneHot",oName,j0,{"input"});

    string nName;
    json j1;
    j1["inputShape"]=vector<int>{VS,T};
    j1["N"]=BS;
    j1["H"]=H;
    j1["forgetgateinitones"]=true;
    //j1["forgetbias"]=0.10;
    j1["clip"]=clip;
    int layer_depth1=2; // 6;
    j1["H"]=H;
    for (auto l=0; l<layer_depth1; l++) {
        if (l>0) j1["inputShape"]=vector<int>{H,T};
        nName="lstm"+std::to_string(l);
        lb.addLayer(rnntype,nName,j1,{oName});
        oName=nName;
    }

    json j10;
    j10["inputShape"]=vector<int>{H,T};
    j10["M"]=VS;
    lb.addLayer("TemporalAffine","af1",j10,{oName});

    json j11;
    j11["inputShape"]=vector<int>{VS,T};
    lb.addLayer("TemporalSoftmax","sm1",j11,{"af1"});

    if (!lb.checkTopology(true)) {
        allOk=false;
        cerr << red << "Topology-check for LayerBlock: ERROR." << def << endl;
    } else {
        cerr << green << "Topology-check for LayerBlock: ok." << def << endl;
    }

    //json jc;
    //lb.getLayerConfiguration(jc);
    //cerr << jc.dump(4) << endl;

    // preseverstates no longer necessary for training!
    json jo(R"({"verbose":true,"shuffle":false,"preservestates":false,"notests":false,"nofragmentbatches":true,"epsilon":1e-8})"_json);
    jo["lossfactor"]=1.0/(floatN)T;  // Allows to normalize the loss with T.
    json j_opt(R"({"learning_rate":5.e-2})"_json);
    j_opt["inputShape"]=vector<int>{H,T};
    json j_loss(R"({"name":"temporalsoftmax"})"_json);
    j_loss["inputShape"]=vector<int>{H,T};
    floatN dep=3.0; // 70.0;
    floatN sep=0.0;
    jo["epochs"]=(floatN)dep;
    jo["batch_size"]=BS;
    jo["lr_decay"] = 0.99;
    // XXX: regularization crashes the training.
    //jo["regularization"]=1e-5;
    //jo["regularization_decay"]=0.95;

    Optimizer *pOpt=optimizerFactory("Adam",j_opt);
    t_cppl OptimizerState{};
    Loss *pLoss=lossFactory("TemporalCrossEntropy",j_loss);

    for (int i=0; i<1000; i++) {
        jo["startepoch"]=(floatN)sep;
        t_cppl states;
        t_cppl statesv;
        states["y"] = new MatrixN(y);
        statesv["y"] = new MatrixN(yv);
        lb.train(X, &states, Xv, &statesv, pOpt, &OptimizerState, pLoss, jo);
        cppl_delete(&states);
        cppl_delete(&statesv);

        sep+=dep;

        int pos=rand() % 1000 + 5000;
        wstring instr=txt.text.substr(pos,T);

        MatrixN xg(1,T);
        for (int i=0; i<T; i++) {
            xg(0,i)=txt.w2v[instr[i]];
       }
        wstring sout{};
        Layer* plstm0=lb.layerMap["lstm0"];
        t_cppl statesg{};
        plstm0->genZeroStates(&statesg, 1);

        int g,t,v;
        for (g=0; g<300; g++) {
            t_cppl cache{};

            /* MatrixN probs_xx=*/ lb.forward(xg,&cache, &statesg);
            // Forward generates the 'wrong' permutation of output. QUick-hack is abusing the 'cache' to get the permutation.
            if (cache.find("sm1-probst")==cache.end()) {
                cerr << "probst didn't make it, FATAL" << endl;
                exit(1);
            }
            MatrixN probst=*(cache["sm1-probst"]); // XXX check if temporal softmax uses redundant morpher!
            MatrixN probsd=MatrixN(T,VS);
            for (t=0; t<T; t++) {
                for (v=0; v<VS; v++) {
                    probsd(t,v)=probst(0,t*VS+v);
                }
            }
            int li = -1;
            for (t=0; t<T; t++) {
                vector<floatN> probs(VS);
                vector<floatN> index(VS);
                for (v=0; v<VS; v++) {
                    probs[v]=probsd(t,v);
                    index[v]=v;
                }
                li=(int)index[randomChoice(index, probs)];
            }
            cppl_delete(&cache);

            for (int t=0; t<T-1; t++) {
                xg(0,t)=xg(0,t+1);
            }
            xg(0,T-1)=li;
            sout += txt.v2w[li];
        }
        wcout << "output: " << sout << endl;
        wstring timestr;
        currentDateTime(timestr);
        std::wofstream fl("rnnreader.txt", std::ios_base::app);
        fl << "---- " << timestr << ", ep:" << sep << " ---" << endl;
        fl << sout << endl;
        fl.close();
        cppl_delete(&statesg);
    }
    delete pOpt;
    cppl_delete(&OptimizerState);
    delete pLoss;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
//#include <codecvt>
//#include <cstddef>
#include <locale>
#include <string>
#include <iomanip>

#include "cp-neural.h"

using std::wcout; using std::wstring;
using std::cerr; using std::vector;

class Text {
private:
    bool isinit=false;
    bool readDataFile(string inputfile) {
        std::wifstream txtfile(inputfile, std::ios::binary);
        if (!txtfile.is_open()) {
            return false;
        }
        txtfile.imbue(std::locale("en_US.UTF8"));
        wstring ttext((std::istreambuf_iterator<wchar_t>(txtfile)),
                     std::istreambuf_iterator<wchar_t>());
        txtfile.close();
        text=ttext;
        filename=inputfile;
        return true;
    }
public:
    wstring text;
    string filename;
    std::map<wchar_t,int> freq;
    std::map<wchar_t,int> w2v;
    std::map<int,wchar_t> v2w;
    Text(string filename) {
        if (readDataFile(filename)) {
            for (auto wc : text) {
                freq[wc]++;
            }
            int it=0;
            for (auto wc : freq) {
                w2v[wc.first]=it;
                v2w[it]=wc.first;
                ++it;
            }
            isinit=true;
            cerr << "Freq:" << freq.size() << ", w2v:" << w2v.size() << ", v2w:" << v2w.size() << endl;
        }
    }
    ~Text() {

    }
    bool isInit() {
        return isinit;
    }
    int vocsize() {
        if (!isinit) return 0;
        return v2w.size();
    }
};

int main(int argc, char *argv[]) {
    std::setlocale (LC_ALL, "");
    wcout << L"Rnn-Readär" << std::endl;

    bool allOk=true;
    if (argc!=2) {
        cerr << "rnnreader <path-to-text-file>" << endl;
        exit(-1);
    }
    Text txt(argv[1]);
    if (!txt.isInit()) {
        cerr << "Cannot initialize Text object from inputfile: " << argv[1] << endl;
        exit(-1);
    }

    wcout << L"Text size: " << txt.text.size() << endl;

    wcout << L"Size of vocabulary:" << txt.freq.size() << std::endl;
/*    for (auto f : txt.freq) {
        int c=(int)f.first;
        wstring wc(1,f.first);
        wcout << wc << L"|" <<  wchar_t(f.first) << L"(0x" << std::hex << c << L")" ": " << std::dec <<  f.second << endl;
    }
*/
    Color::Modifier red(Color::FG_RED);
    Color::Modifier green(Color::FG_GREEN);
    Color::Modifier def(Color::FG_DEFAULT);

    int T=1;
    int N=txt.text.size()-T-1;

    MatrixN Xr(N,T);
    MatrixN yr(N,T);

    wstring chunk,chunky;
    int n=0;
    for (int i=0; i<N-T-1; i+=T) {
        chunk=txt.text.substr(i,T);
        chunky=txt.text.substr(i+1,T);
        for (int t=0; t<T; t++) {
            Xr(i,t)=txt.w2v[chunk[t]];
            yr(i,t)=txt.w2v[chunky[t]];
            ++n;
        }
    }

    int maxN = 50000;
    if (n>maxN) n=maxN;
    int n1=n*0.9;
    int dn=(n-n1)/2;

    cerr << n1 << " datasets" << endl;

/*    MatrixN X(n1,T);
    MatrixN y(n1,T);
    MatrixN Xv(dn,T);
    MatrixN yv(dn,T);
    MatrixN Xt(dn,T);
    MatrixN yt(dn,T);
*/
    MatrixN X=Xr.block(0,0,n1,T);
    MatrixN y=yr.block(0,0,n1,T);
    MatrixN Xv=Xr.block(n1,0,dn,T);
    MatrixN yv=yr.block(n1,0,dn,T);
    MatrixN Xt=Xr.block(n1+dn,0,dn,T);
    MatrixN yt=yr.block(n1+dn,0,dn,T);
/*

    X=Xr.block(0,0,100000,T);
    y=yr.block(0,0,100000,T);
    Xv=Xr.block(100000,0,10000,T);
    yv=yr.block(100000,0,10000,T);
    Xt=Xr.block(110000,0,10000,T);
    yt=yr.block(110000,0,10000,T);
*/
/*
    X=Xr.block(0,0,10000,T);
    y=yr.block(0,0,10000,T);
    Xv=Xr.block(10000,0,1000,T);
    yv=yr.block(10000,0,1000,T);
    Xt=Xr.block(11000,0,1000,T);
    yt=yr.block(11000,0,1000,T);
*/
    cpInitCompute("Rnnreader");
    registerLayers();

    LayerBlock lb("{name='rnnreader';init='orthonormal';initfactor=0.001}");
    int VS=txt.vocsize();
    int H=64;
    int D=128;
    int BS=64;
    float clip=5.0;

    CpParams cp0;
    cp0.setPar("inputShape",vector<int>{T});
    cp0.setPar("V",VS);
    cp0.setPar("D",D);
    lb.addLayer("WordEmbedding","WE0",cp0,{"input"});

    CpParams cp1;
    cp1.setPar("inputShape",vector<int>{D,T});
    cp1.setPar("N",BS);
    cp1.setPar("H",H);
    cp1.setPar("clip",clip);
    lb.addLayer("RNN","rnn1",cp1,{"WE0"});

    CpParams cp2;
    cp2.setPar("inputShape",vector<int>{H,T});
    cp2.setPar("N",BS);
    cp2.setPar("H",H);
    cp2.setPar("clip",clip);
    lb.addLayer("RNN","rnn2",cp2,{"rnn1"});

    CpParams cp3;
    cp3.setPar("inputShape",vector<int>{H,T});
    cp3.setPar("N",BS);
    cp3.setPar("H",H);
    cp3.setPar("clip",clip);
    lb.addLayer("RNN","rnn3",cp3,{"rnn2"});

    CpParams cp10;
    cp10.setPar("inputShape",vector<int>{H,T});
    //cp10.setPar("T",T);
    //cp10.setPar("D",H);
    cp10.setPar("M",VS);
    lb.addLayer("TemporalAffine","af1",cp10,{"rnn3"});

    CpParams cp11;
    cp11.setPar("inputShape",vector<int>{VS,T});
    lb.addLayer("TemporalSoftmax","sm1",cp11,{"af1"});

    if (!lb.checkTopology(true)) {
        allOk=false;
        cerr << red << "Topology-check for LayerBlock: ERROR." << def << endl;
    } else {
        cerr << green << "Topology-check for LayerBlock: ok." << def << endl;
    }

/*    wstring chunk;
    chunk = txt.text.substr(512,128);
    wcout << chunk << endl;
*/
    // CpParams cpo("{verbose=true;epsilon=1e-8}");
    CpParams cpo("{verbose=false;epsilon=1e-8}");
    cpo.setPar("learning_rate", (floatN)1e-2); //2.2e-2);
    cpo.setPar("lr_decay", (floatN)0.95);
    //cpo.setPar("regularization", (floatN)1.);

    floatN dep=1.0;
    floatN sep=0.0;
    cpo.setPar("epochs",(floatN)dep);
    cpo.setPar("batch_size",BS);

    MatrixN xg(1,T);
    MatrixN xg2(1,T);
    wstring sg;
    for (int i=0; i<10000; i++) {

        cpo.setPar("startepoch", (floatN)sep);
        cpo.setPar("maxthreads", (int)1); // RNN can't cope with threads.

        Layer *prnn1=lb.layerMap["rnn1"];
        prnn1->params["ho"]->setZero();
        /*Layer *prnn2=lb.layerMap["rnn2"];
        prnn2->params["ho"]->setZero();
        Layer *prnn3=lb.layerMap["rnn3"];
        prnn3->params["ho"]->setZero();
*/
        floatN cAcc=lb.train(X, y, Xv, yv, "Adam", cpo);
        sep+=dep;

        int pos=rand() % 1000 + 5000;
        wstring instr=txt.text.substr(pos,T);

        for (int i=0; i<T; i++) {
            if (i<instr.size()) {
                xg(0,i)=txt.w2v[instr[i]];
            } else {
                xg(0,i)=txt.w2v[L' '];
            }
        }
        /*
        for (auto wc : instr) {
            sg[0]=wc;
            xg(0,0)=txt.w2v[sg[0]];
            MatrixN z(0,0);
            MatrixN yg=lb.forward(xg,z,nullptr);
        }
        */
        //xg(0,0)=txt.w2v[sg[0]];
        for (int rep=0; rep<3; rep++) {
            //Layer *prnn=lb.layerMap["rnn1"];
            //prnn->params["ho"]->setZero();
            cerr << "------------" << rep << "--------------------------" << endl;
            for (int g=0; g<200; g++) {
                //wcout << g << L">";
                MatrixN z(0,0);

                //for (int i; i<xg.cols(); i++) wcout << txt.v2w[xg(0,i)];
                //wcout << L"<" << endl << L">";

                MatrixN yg=lb.forward(xg,z,nullptr);
                for (int t=0; t<T; t++) {
                    vector<floatN> probs(D);
                    vector<floatN> index(D);
                    for (int d=0; d<D; d++) {
                        probs[d]=yg(0,t*D+d);
                        index[d]=d;
                    }
                    int ind=(int)index[randomChoice(index, probs)];
/*                    float mx=-1000.0;
                    int ind=-1;
                    for (int d=0; d<VS; d++) {
                        floatN p=yg(0,t*D+d);
                        floatN pr=p*((floatN)(rand()%100)/5000.0+0.98);
                        if (pr>mx) {
                            mx=pr; // yg(0,t*D+d);
                            ind=d;
                        }
                    }
*/
                    wchar_t cw=txt.v2w[ind];
                    //if (t==0) wcout << L"[" << cw << L"<";
                    //wcout << L"<" << cw << L">";
                    wcout << cw;
                    xg2(0,t)=ind;
                }
                //wcout << L"<" << endl;
                for (int t=T-1; t>0; t--) xg(0,t)=xg(0,t-1);
                xg(0,0)=xg2(0,0);
                //xg=xg2;
            }
            wcout << endl;
        }
    }
    /*
    floatN train_err, val_err, test_err;
    bool evalFinal=true;
    if (evalFinal) {
        train_err=lb.test(X, y, cpo.getPar("batch_size", 50));
        val_err=lb.test(Xv, yv, cpo.getPar("batch_size", 50));
        test_err=lb.test(Xt, yt, cpo.getPar("batch_size", 50));

        cerr << "Final results on RnnReader after " << cpo.getPar("epochs",(floatN)0.0) << " epochs:" << endl;
        cerr << "      Train-error: " << train_err << " train-acc: " << 1.0-train_err << endl;
        cerr << " Validation-error: " << val_err <<   "   val-acc: " << 1.0-val_err << endl;
        cerr << "       Test-error: " << test_err <<  "  test-acc: " << 1.0-test_err << endl;
    }
    //return cAcc;
    */
    cpExitCompute();
}
<commit_msg>smaller hidden vector<commit_after>#include <iostream>
#include <fstream>
//#include <codecvt>
//#include <cstddef>
#include <locale>
#include <string>
#include <iomanip>

#include "cp-neural.h"

using std::wcout; using std::wstring;
using std::cerr; using std::vector;

class Text {
private:
    bool isinit=false;
    bool readDataFile(string inputfile) {
        std::wifstream txtfile(inputfile, std::ios::binary);
        if (!txtfile.is_open()) {
            return false;
        }
        txtfile.imbue(std::locale("en_US.UTF8"));
        wstring ttext((std::istreambuf_iterator<wchar_t>(txtfile)),
                     std::istreambuf_iterator<wchar_t>());
        txtfile.close();
        text=ttext;
        filename=inputfile;
        return true;
    }
public:
    wstring text;
    string filename;
    std::map<wchar_t,int> freq;
    std::map<wchar_t,int> w2v;
    std::map<int,wchar_t> v2w;
    Text(string filename) {
        if (readDataFile(filename)) {
            for (auto wc : text) {
                freq[wc]++;
            }
            int it=0;
            for (auto wc : freq) {
                w2v[wc.first]=it;
                v2w[it]=wc.first;
                ++it;
            }
            isinit=true;
            cerr << "Freq:" << freq.size() << ", w2v:" << w2v.size() << ", v2w:" << v2w.size() << endl;
        }
    }
    ~Text() {

    }
    bool isInit() {
        return isinit;
    }
    int vocsize() {
        if (!isinit) return 0;
        return v2w.size();
    }
};

int main(int argc, char *argv[]) {
    std::setlocale (LC_ALL, "");
    wcout << L"Rnn-Readär" << std::endl;

    bool allOk=true;
    if (argc!=2) {
        cerr << "rnnreader <path-to-text-file>" << endl;
        exit(-1);
    }
    Text txt(argv[1]);
    if (!txt.isInit()) {
        cerr << "Cannot initialize Text object from inputfile: " << argv[1] << endl;
        exit(-1);
    }

    wcout << L"Text size: " << txt.text.size() << endl;

    wcout << L"Size of vocabulary:" << txt.freq.size() << std::endl;
/*    for (auto f : txt.freq) {
        int c=(int)f.first;
        wstring wc(1,f.first);
        wcout << wc << L"|" <<  wchar_t(f.first) << L"(0x" << std::hex << c << L")" ": " << std::dec <<  f.second << endl;
    }
*/
    Color::Modifier red(Color::FG_RED);
    Color::Modifier green(Color::FG_GREEN);
    Color::Modifier def(Color::FG_DEFAULT);

    int T=1;
    int N=txt.text.size()-T-1;

    MatrixN Xr(N,T);
    MatrixN yr(N,T);

    wstring chunk,chunky;
    int n=0;
    for (int i=0; i<N-T-1; i+=T) {
        chunk=txt.text.substr(i,T);
        chunky=txt.text.substr(i+1,T);
        for (int t=0; t<T; t++) {
            Xr(i,t)=txt.w2v[chunk[t]];
            yr(i,t)=txt.w2v[chunky[t]];
            ++n;
        }
    }

    int maxN = 50000;
    if (n>maxN) n=maxN;
    int n1=n*0.9;
    int dn=(n-n1)/2;

    cerr << n1 << " datasets" << endl;

/*    MatrixN X(n1,T);
    MatrixN y(n1,T);
    MatrixN Xv(dn,T);
    MatrixN yv(dn,T);
    MatrixN Xt(dn,T);
    MatrixN yt(dn,T);
*/
    MatrixN X=Xr.block(0,0,n1,T);
    MatrixN y=yr.block(0,0,n1,T);
    MatrixN Xv=Xr.block(n1,0,dn,T);
    MatrixN yv=yr.block(n1,0,dn,T);
    MatrixN Xt=Xr.block(n1+dn,0,dn,T);
    MatrixN yt=yr.block(n1+dn,0,dn,T);
/*

    X=Xr.block(0,0,100000,T);
    y=yr.block(0,0,100000,T);
    Xv=Xr.block(100000,0,10000,T);
    yv=yr.block(100000,0,10000,T);
    Xt=Xr.block(110000,0,10000,T);
    yt=yr.block(110000,0,10000,T);
*/
/*
    X=Xr.block(0,0,10000,T);
    y=yr.block(0,0,10000,T);
    Xv=Xr.block(10000,0,1000,T);
    yv=yr.block(10000,0,1000,T);
    Xt=Xr.block(11000,0,1000,T);
    yt=yr.block(11000,0,1000,T);
*/
    cpInitCompute("Rnnreader");
    registerLayers();

    LayerBlock lb("{name='rnnreader';init='orthonormal';initfactor=0.001}");
    int VS=txt.vocsize();
    int H=192;
    int D=128;
    int BS=64;
    float clip=5.0;

    CpParams cp0;
    cp0.setPar("inputShape",vector<int>{T});
    cp0.setPar("V",VS);
    cp0.setPar("D",D);
    lb.addLayer("WordEmbedding","WE0",cp0,{"input"});

    CpParams cp1;
    cp1.setPar("inputShape",vector<int>{D,T});
    cp1.setPar("N",BS);
    cp1.setPar("H",H);
    cp1.setPar("clip",clip);
    lb.addLayer("RNN","rnn1",cp1,{"WE0"});

    CpParams cp2;
    cp2.setPar("inputShape",vector<int>{H,T});
    cp2.setPar("N",BS);
    cp2.setPar("H",H);
    cp2.setPar("clip",clip);
    lb.addLayer("RNN","rnn2",cp2,{"rnn1"});

    CpParams cp3;
    cp3.setPar("inputShape",vector<int>{H,T});
    cp3.setPar("N",BS);
    cp3.setPar("H",H);
    cp3.setPar("clip",clip);
    lb.addLayer("RNN","rnn3",cp3,{"rnn2"});

    CpParams cp10;
    cp10.setPar("inputShape",vector<int>{H,T});
    //cp10.setPar("T",T);
    //cp10.setPar("D",H);
    cp10.setPar("M",VS);
    lb.addLayer("TemporalAffine","af1",cp10,{"rnn3"});

    CpParams cp11;
    cp11.setPar("inputShape",vector<int>{VS,T});
    lb.addLayer("TemporalSoftmax","sm1",cp11,{"af1"});

    if (!lb.checkTopology(true)) {
        allOk=false;
        cerr << red << "Topology-check for LayerBlock: ERROR." << def << endl;
    } else {
        cerr << green << "Topology-check for LayerBlock: ok." << def << endl;
    }

/*    wstring chunk;
    chunk = txt.text.substr(512,128);
    wcout << chunk << endl;
*/
    // CpParams cpo("{verbose=true;epsilon=1e-8}");
    CpParams cpo("{verbose=false;epsilon=1e-8}");
    cpo.setPar("learning_rate", (floatN)1e-2); //2.2e-2);
    cpo.setPar("lr_decay", (floatN)0.95);
    //cpo.setPar("regularization", (floatN)1.);

    floatN dep=1.0;
    floatN sep=0.0;
    cpo.setPar("epochs",(floatN)dep);
    cpo.setPar("batch_size",BS);

    MatrixN xg(1,T);
    MatrixN xg2(1,T);
    wstring sg;
    for (int i=0; i<10000; i++) {

        cpo.setPar("startepoch", (floatN)sep);
        cpo.setPar("maxthreads", (int)1); // RNN can't cope with threads.

        Layer *prnn1=lb.layerMap["rnn1"];
        prnn1->params["ho"]->setZero();
        /*Layer *prnn2=lb.layerMap["rnn2"];
        prnn2->params["ho"]->setZero();
        Layer *prnn3=lb.layerMap["rnn3"];
        prnn3->params["ho"]->setZero();
*/
        floatN cAcc=lb.train(X, y, Xv, yv, "Adam", cpo);
        sep+=dep;

        int pos=rand() % 1000 + 5000;
        wstring instr=txt.text.substr(pos,T);

        for (int i=0; i<T; i++) {
            if (i<instr.size()) {
                xg(0,i)=txt.w2v[instr[i]];
            } else {
                xg(0,i)=txt.w2v[L' '];
            }
        }
        /*
        for (auto wc : instr) {
            sg[0]=wc;
            xg(0,0)=txt.w2v[sg[0]];
            MatrixN z(0,0);
            MatrixN yg=lb.forward(xg,z,nullptr);
        }
        */
        //xg(0,0)=txt.w2v[sg[0]];
        for (int rep=0; rep<3; rep++) {
            //Layer *prnn=lb.layerMap["rnn1"];
            //prnn->params["ho"]->setZero();
            cerr << "------------" << rep << "--------------------------" << endl;
            for (int g=0; g<200; g++) {
                //wcout << g << L">";
                MatrixN z(0,0);

                //for (int i; i<xg.cols(); i++) wcout << txt.v2w[xg(0,i)];
                //wcout << L"<" << endl << L">";

                MatrixN yg=lb.forward(xg,z,nullptr);
                for (int t=0; t<T; t++) {
                    vector<floatN> probs(D);
                    vector<floatN> index(D);
                    for (int d=0; d<D; d++) {
                        probs[d]=yg(0,t*D+d);
                        index[d]=d;
                    }
                    int ind=(int)index[randomChoice(index, probs)];
/*                    float mx=-1000.0;
                    int ind=-1;
                    for (int d=0; d<VS; d++) {
                        floatN p=yg(0,t*D+d);
                        floatN pr=p*((floatN)(rand()%100)/5000.0+0.98);
                        if (pr>mx) {
                            mx=pr; // yg(0,t*D+d);
                            ind=d;
                        }
                    }
*/
                    wchar_t cw=txt.v2w[ind];
                    //if (t==0) wcout << L"[" << cw << L"<";
                    //wcout << L"<" << cw << L">";
                    wcout << cw;
                    xg2(0,t)=ind;
                }
                //wcout << L"<" << endl;
                for (int t=T-1; t>0; t--) xg(0,t)=xg(0,t-1);
                xg(0,0)=xg2(0,0);
                //xg=xg2;
            }
            wcout << endl;
        }
    }
    /*
    floatN train_err, val_err, test_err;
    bool evalFinal=true;
    if (evalFinal) {
        train_err=lb.test(X, y, cpo.getPar("batch_size", 50));
        val_err=lb.test(Xv, yv, cpo.getPar("batch_size", 50));
        test_err=lb.test(Xt, yt, cpo.getPar("batch_size", 50));

        cerr << "Final results on RnnReader after " << cpo.getPar("epochs",(floatN)0.0) << " epochs:" << endl;
        cerr << "      Train-error: " << train_err << " train-acc: " << 1.0-train_err << endl;
        cerr << " Validation-error: " << val_err <<   "   val-acc: " << 1.0-val_err << endl;
        cerr << "       Test-error: " << test_err <<  "  test-acc: " << 1.0-test_err << endl;
    }
    //return cAcc;
    */
    cpExitCompute();
}
<|endoftext|>


<commit_before>#include <iterator>

#include "coverage.h"
#include "geos/geom/Geometry.h"
#include "numericrange.h"
#include "numericdomain.h"
#include "table.h"
#include "featurecoverage.h"
#include "feature.h"
#include "featureiterator.h"

using namespace Ilwis;

FeatureIterator::FeatureIterator() :
    _isInitial(true)
{
}

FeatureIterator::FeatureIterator(const IFeatureCoverage& fcoverage, quint32 level) : _fcoverage(fcoverage), _isInitial(true),_types(itFEATURE), _level(level)
{
    init();
}

FeatureIterator::FeatureIterator(const Ilwis::IFeatureCoverage &fcoverage, const std::vector<quint32> &subset, quint32 level) :
    _fcoverage(fcoverage),
    _isInitial(true),
    _subset(subset),
    _types(itFEATURE),
    _level(level)
{
    init();
}

FeatureIterator::FeatureIterator(const Ilwis::IFeatureCoverage &fcoverage, IlwisTypes types, quint32 level) :
    _fcoverage(fcoverage),
    _isInitial(true),
    _types(types),
    _level(level)
{

}
FeatureIterator::FeatureIterator(const FeatureIterator &iter)
{
    _fcoverage = iter._fcoverage;
    _isInitial = iter._isInitial;
    _iterFeatures = iter._iterFeatures;
    _subset = iter._subset;
    _iterPosition = iter._iterPosition;
    _types = iter._types;
    _level = iter._level;
    _flow = iter._flow;
}

FeatureIterator &FeatureIterator::operator ++()
{
    if (!init()){
       move();
    }
    return *this;
}

FeatureIterator FeatureIterator::operator ++(int)
{
    init();
    FeatureIterator temp(*this);
    if(!move())
        return end();
    return temp;
}

FeatureIterator &FeatureIterator::operator +(int distance)
{
    if(!init()) {
        move(distance);
    }
    return *this;

}

FeatureIterator &FeatureIterator::operator -(int distance)
{
    if(!init()) {
        move(-distance);
    }
    return *this;
}

bool FeatureIterator::operator ==(const FeatureIterator &iter)
{
    return _iterFeatures == iter._iterFeatures;
}

bool FeatureIterator::operator !=(const FeatureIterator &iter)
{
       return _iterFeatures != iter._iterFeatures;
}

SPFeatureI FeatureIterator::operator *()
{
     init();
     if ( _currentLevel == 0)
        return *_iterFeatures;
     else if ( _currentIndexes.size() > 0) {
         quint32 raw = (*_subIterator).first; // index of domain value for subfeature
         QString domvalue = _fcoverage->attributeDefinitionsRef(_currentLevel).index(raw);
         return (*_iterFeatures)[domvalue];
     }

     return SPFeatureI();
}

FeatureIterator FeatureIterator::end() const
{
    FeatureIterator temp(*this);
    temp._iterFeatures = _fcoverage->_features.end();
    return temp;
}

FeatureIterator FeatureIterator::end()
{
    FeatureIterator temp(*this);
    temp._iterFeatures = _fcoverage->_features.end();
    return temp;
}

bool FeatureIterator::init()
{
    if ( _isInitial)     {
        const qint32 rootLevel = 0;
        _currentIndexes = _fcoverage->attributeDefinitions(rootLevel).indexes();
         _currentLevel = _level;
        _useVectorIter = _subset.size() == 0 || _subset.size() == _fcoverage->featureCount();
        _isInitial = false;
        if ( !_fcoverage->connector()->dataIsLoaded()) {
            bool ok = _fcoverage->connector()->loadData(_fcoverage.ptr());
            if (!ok)
                return false;
        }
        if ( _fcoverage->_features.size() > 0 ) {
            _iterPosition = 0;
            _iterFeatures = _fcoverage->_features.begin();
             Feature *feature = static_cast<Feature *>(_fcoverage->_features[rootLevel].get());
            _subIterator = feature->_subFeatures.begin();
            if ( _subset.size() > 0) {
                _iterFeatures += _subset[_iterPosition];
            }
        }
    } else
        return false;
    return true;
}

bool FeatureIterator::moveFlat(qint32 distance){
    if ( _currentLevel != 0)
        return moveBreadthFirst(distance);

    if (_useVectorIter){
        _iterFeatures += distance;
        if ( _iterFeatures == _fcoverage->_features.end()) {
            _iterFeatures = _fcoverage->_features.end();
            return false;
        }
        if (_types != itFEATURE ){ // if we only want to include certain geometry types we need to move until we encounter one
            while (!hasType((*_iterFeatures)->geometryType(),_types))
                move(1);
        }
    }else {
        if ( (qint32)_iterPosition + distance < 0) {
            _iterPosition = 0;
            _iterFeatures = _fcoverage->_features.end();
            return false;
        }
        _iterPosition += distance;
        if ( _iterPosition >= _subset.size()) {
            _iterPosition = _subset.size();
            _iterFeatures = _fcoverage->_features.end();
            return false;
        }
        _iterFeatures = _fcoverage->_features.begin() + _subset[_iterPosition];

    }
    return true;
}

bool FeatureIterator::moveBreadthFirst(qint32 distance){
    // TODO : only one level deep atm, is the most used case if at all. later a full breadth first

    ++_iterFeatures; // move the main feature, as the subiterator is constant this should access level x in the subiterator
    if (_iterFeatures == _fcoverage->_features.end()){ // completed one level, move to next level
        ++_currentLevel;
        _iterFeatures = _fcoverage->_features.begin(); // main feature iterator back to beginning
        ++_subIterator; // next level of subfeatures
    }
    Feature *feature = static_cast<Feature *>((*_iterFeatures).get());
    if ( !feature)
        return false;

    // move fails if there are no more features to iterate on
    return !atEndOfFeatures();
}

bool FeatureIterator::moveDepthFirst(qint32 distance){

    if ( _currentLevel != 0)
        ++_subIterator; // move on subfeatures
    ++_currentLevel;
    Feature *feature = static_cast<Feature *>((*_iterFeatures).get());
    if ( _subIterator == feature->_subFeatures.end()){
        ++_iterFeatures; // to next level 0 feature
        _currentLevel = 0;
        if ( !atEndOfFeatures()) {
            // reset iteration state of subfeatures
            feature = static_cast<Feature *>((*_iterFeatures).get());
           _subIterator = feature->_subFeatures.begin();
        }

    }

    // move fails if there are no more features to iterate on
    return !atEndOfFeatures();

}

bool FeatureIterator::atEndOfFeatures()
{
    return _iterFeatures == _fcoverage->_features.end();
}

bool FeatureIterator::move(qint32 distance) {
    bool ok = false;
    switch ( _flow){
    case fFLAT:
        ok =  moveFlat(distance);
        break;
    case fBREADTHFIRST:
        ok = moveBreadthFirst(distance);
        break;
    case fDEPTHFIRST:
        ok = moveDepthFirst(distance);
        break;
    }
    return ok;
}
FeatureIterator::Flow FeatureIterator::flow() const
{
    return _flow;
}

void FeatureIterator::flow(const Flow &flow)
{
    _flow = flow;
}

<commit_msg>added guard<commit_after>#include <iterator>

#include "coverage.h"
#include "geos/geom/Geometry.h"
#include "numericrange.h"
#include "numericdomain.h"
#include "table.h"
#include "featurecoverage.h"
#include "feature.h"
#include "featureiterator.h"

using namespace Ilwis;

FeatureIterator::FeatureIterator() :
    _isInitial(true)
{
}

FeatureIterator::FeatureIterator(const IFeatureCoverage& fcoverage, quint32 level) : _fcoverage(fcoverage), _isInitial(true),_types(itFEATURE), _level(level)
{
    init();
}

FeatureIterator::FeatureIterator(const Ilwis::IFeatureCoverage &fcoverage, const std::vector<quint32> &subset, quint32 level) :
    _fcoverage(fcoverage),
    _isInitial(true),
    _subset(subset),
    _types(itFEATURE),
    _level(level)
{
    init();
}

FeatureIterator::FeatureIterator(const Ilwis::IFeatureCoverage &fcoverage, IlwisTypes types, quint32 level) :
    _fcoverage(fcoverage),
    _isInitial(true),
    _types(types),
    _level(level)
{

}
FeatureIterator::FeatureIterator(const FeatureIterator &iter)
{
    _fcoverage = iter._fcoverage;
    _isInitial = iter._isInitial;
    _iterFeatures = iter._iterFeatures;
    _subset = iter._subset;
    _iterPosition = iter._iterPosition;
    _types = iter._types;
    _level = iter._level;
    _flow = iter._flow;
}

FeatureIterator &FeatureIterator::operator ++()
{
    if (!init()){
       move();
    }
    return *this;
}

FeatureIterator FeatureIterator::operator ++(int)
{
    init();
    FeatureIterator temp(*this);
    if(!move())
        return end();
    return temp;
}

FeatureIterator &FeatureIterator::operator +(int distance)
{
    if(!init()) {
        move(distance);
    }
    return *this;

}

FeatureIterator &FeatureIterator::operator -(int distance)
{
    if(!init()) {
        move(-distance);
    }
    return *this;
}

bool FeatureIterator::operator ==(const FeatureIterator &iter)
{
    return _iterFeatures == iter._iterFeatures;
}

bool FeatureIterator::operator !=(const FeatureIterator &iter)
{
       return _iterFeatures != iter._iterFeatures;
}

SPFeatureI FeatureIterator::operator *()
{
     init();
     if ( _currentLevel == 0){
         if (_iterFeatures == _fcoverage->_features.end())
             return SPFeatureI();
        return *_iterFeatures;
     }
     else if ( _currentIndexes.size() > 0) {
         quint32 raw = (*_subIterator).first; // index of domain value for subfeature
         QString domvalue = _fcoverage->attributeDefinitionsRef(_currentLevel).index(raw);
         return (*_iterFeatures)[domvalue];
     }

     return SPFeatureI();
}

FeatureIterator FeatureIterator::end() const
{
    FeatureIterator temp(*this);
    temp._iterFeatures = _fcoverage->_features.end();
    return temp;
}

FeatureIterator FeatureIterator::end()
{
    FeatureIterator temp(*this);
    temp._iterFeatures = _fcoverage->_features.end();
    return temp;
}

bool FeatureIterator::init()
{
    if ( _isInitial)     {
        const qint32 rootLevel = 0;
        _currentIndexes = _fcoverage->attributeDefinitions(rootLevel).indexes();
         _currentLevel = _level;
        _useVectorIter = _subset.size() == 0 || _subset.size() == _fcoverage->featureCount();
        _isInitial = false;
        if ( !_fcoverage->connector()->dataIsLoaded()) {
            bool ok = _fcoverage->connector()->loadData(_fcoverage.ptr());
            if (!ok)
                return false;
        }
        if ( _fcoverage->_features.size() > 0 ) {
            _iterPosition = 0;
            _iterFeatures = _fcoverage->_features.begin();
             Feature *feature = static_cast<Feature *>(_fcoverage->_features[rootLevel].get());
            _subIterator = feature->_subFeatures.begin();
            if ( _subset.size() > 0) {
                _iterFeatures += _subset[_iterPosition];
            }
        }
    } else
        return false;
    return true;
}

bool FeatureIterator::moveFlat(qint32 distance){
    if ( _currentLevel != 0)
        return moveBreadthFirst(distance);

    if (_useVectorIter){
        _iterFeatures += distance;
        if ( _iterFeatures == _fcoverage->_features.end()) {
            _iterFeatures = _fcoverage->_features.end();
            return false;
        }
        if (_types != itFEATURE ){ // if we only want to include certain geometry types we need to move until we encounter one
            while (!hasType((*_iterFeatures)->geometryType(),_types))
                move(1);
        }
    }else {
        if ( (qint32)_iterPosition + distance < 0) {
            _iterPosition = 0;
            _iterFeatures = _fcoverage->_features.end();
            return false;
        }
        _iterPosition += distance;
        if ( _iterPosition >= _subset.size()) {
            _iterPosition = _subset.size();
            _iterFeatures = _fcoverage->_features.end();
            return false;
        }
        _iterFeatures = _fcoverage->_features.begin() + _subset[_iterPosition];

    }
    return true;
}

bool FeatureIterator::moveBreadthFirst(qint32 distance){
    // TODO : only one level deep atm, is the most used case if at all. later a full breadth first

    ++_iterFeatures; // move the main feature, as the subiterator is constant this should access level x in the subiterator
    if (_iterFeatures == _fcoverage->_features.end()){ // completed one level, move to next level
        ++_currentLevel;
        _iterFeatures = _fcoverage->_features.begin(); // main feature iterator back to beginning
        ++_subIterator; // next level of subfeatures
    }
    Feature *feature = static_cast<Feature *>((*_iterFeatures).get());
    if ( !feature)
        return false;

    // move fails if there are no more features to iterate on
    return !atEndOfFeatures();
}

bool FeatureIterator::moveDepthFirst(qint32 distance){

    if ( _currentLevel != 0)
        ++_subIterator; // move on subfeatures
    ++_currentLevel;
    Feature *feature = static_cast<Feature *>((*_iterFeatures).get());
    if ( _subIterator == feature->_subFeatures.end()){
        ++_iterFeatures; // to next level 0 feature
        _currentLevel = 0;
        if ( !atEndOfFeatures()) {
            // reset iteration state of subfeatures
            feature = static_cast<Feature *>((*_iterFeatures).get());
           _subIterator = feature->_subFeatures.begin();
        }

    }

    // move fails if there are no more features to iterate on
    return !atEndOfFeatures();

}

bool FeatureIterator::atEndOfFeatures()
{
    return _iterFeatures == _fcoverage->_features.end();
}

bool FeatureIterator::move(qint32 distance) {
    bool ok = false;
    switch ( _flow){
    case fFLAT:
        ok =  moveFlat(distance);
        break;
    case fBREADTHFIRST:
        ok = moveBreadthFirst(distance);
        break;
    case fDEPTHFIRST:
        ok = moveDepthFirst(distance);
        break;
    }
    return ok;
}
FeatureIterator::Flow FeatureIterator::flow() const
{
    return _flow;
}

void FeatureIterator::flow(const Flow &flow)
{
    _flow = flow;
}

<|endoftext|>


<commit_before>/*
Copyright (C) 2011 by Rio Yokota, Simon Layton, Lorena Barba

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include <FMM_plan.hpp>
#include <SphericalLaplaceKernel.hpp>
#include <UnitKernel.hpp>
// #include <CartesianLaplaceKernel.hpp>
#include <CartesianLaplaceKernel2.hpp>
#include <CartesianYukawaKernel.hpp>

// modify error checking for counting kernel
// TODO: Do this much better...
// #define UNIT_KERNEL
//#define SPH_KERNEL
//#define CART_KERNEL
#define YUKAWA_KERNEL

template <typename Box>
void print_box(const Box& b, std::string padding = std::string()) {
  std::cout << padding << "Box " << b.index()
            << " (Level " << b.level() << ", Parent " << b.parent().index() << "): "
            << b.morton_index() << "    " << b.center() << "\n";

  padding.append(2,' ');
  if (!b.is_leaf()) {
    for (auto ci = b.child_begin(); ci != b.child_end(); ++ci)
      print_box(*ci, padding);
  } else {
    for (auto ci = b.body_begin(); ci != b.body_end(); ++ci)
      std::cout << padding << "Point " << ci->index() << ": "
		<< ci->morton_index() << "\t" << ci->point() << "\n";
  }
}

// Random number in [0,1)
inline double drand() {
  return ::drand48();
}

int main(int argc, char **argv)
{
  int numBodies = 100;
  bool checkErrors = true;
  bool printBox = false;
  FMMOptions opts;
  opts.set_theta(1 / sqrtf(4));    // Multipole acceptance criteria
  opts.NCRIT = 10;

  // parse command line args
  for (int i = 1; i < argc; ++i) {
    if (strcmp(argv[i],"-N") == 0) {
      i++;
      numBodies = atoi(argv[i]);
    } else if (strcmp(argv[i],"-theta") == 0) {
      i++;
      opts.THETA = (double)atof(argv[i]);
      opts.set_theta(opts.THETA);
    } else if (strcmp(argv[i],"-nocheck") == 0) {
      checkErrors = false;
    } else if (strcmp(argv[i],"-bottomup") == 0) {
      opts.tree = FMMOptions::BOTTOMUP;
    } else if (strcmp(argv[i],"-evaluator") == 0) {
      i++;
      if (strcmp(argv[i],"FMM") == 0) {
        opts.evaluator = FMMOptions::FMM;
      } else if (strcmp(argv[i],"TREECODE") == 0) {
        opts.evaluator = FMMOptions::TREECODE;
      } else {
        printf("[W]: Unknown evaluator type: \"%s\"\n",argv[i]);
      }
    } else if (strcmp(argv[i],"-ncrit") == 0) {
      i++;
      opts.NCRIT = (unsigned)atoi(argv[i]);
    } else if (strcmp(argv[i],"-printbox") == 0) {
      printBox = true;
    } else {
      printf("[W]: Unknown command line arg: \"%s\"\n",argv[i]);
    }
  }

  // Init the FMM Kernel
#ifdef SPH_KERNEL
  typedef SphericalLaplaceKernel kernel_type;
  kernel_type K(5);
#endif
#ifdef CART_KERNEL
  typedef CartesianLaplaceKernel<5> kernel_type;
  kernel_type K;
#endif
#ifdef YUKAWA_KERNEL
  typedef CartesianYukawaKernel kernel_type;
  kernel_type K(6,0.5);
#endif
#ifdef UNIT_KERNEL
  typedef UnitKernel kernel_type;
  kernel_type K;
#endif
  typedef kernel_type::point_type point_type;
  typedef kernel_type::charge_type charge_type;
  typedef kernel_type::result_type result_type;

  // Init points and charges
  std::vector<point_type> points(numBodies);
  for (int k = 0; k < numBodies; ++k)
    points[k] = point_type(drand(), drand(), drand());
  //std::vector<point_type> target_points = points;

  std::vector<charge_type> charges(numBodies);
  for (int k = 0; k < numBodies; ++k)
    charges[k] = drand();

  // Build the FMM
  //fmm_plan plan = fmm_plan(K, bodies, opts);
  FMM_plan<kernel_type> plan = FMM_plan<kernel_type>(K, points, opts);
  if (printBox) {
    print_box(plan.otree.root());
  }

  // Execute the FMM
  //fmm_execute(plan, charges, target_points);
  std::vector<result_type> result = plan.execute(charges, points);

  // Check the result
  // TODO: More elegant
  if (checkErrors) {
    std::vector<result_type> exact(numBodies);

    // Compute the result with a direct matrix-vector multiplication
    Direct::matvec(K, points, charges, exact);

#if defined(SPH_KERNEL) || defined(CART_KERNEL) || defined(YUKAWA_KERNEL)
    result_type rdiff, rnorm;
    for (unsigned k = 0; k < result.size(); ++k) {
      printf("[%03d] exact: %lg, FMM: %lg\n", k, exact[k][0], result[k][0]);

      rdiff = (result[k] - exact[k]) * (result[k] - exact[k]);
      rnorm = exact[k] * exact[k];
    }

    printf("Error (pot) : %.4e\n", sqrt(rdiff[0] / rnorm[0]));
    printf("Error (acc) : %.4e\n", sqrt((rdiff[1]+rdiff[2]+rdiff[3]) /
					(rnorm[1]+rnorm[2]+rnorm[3])));
#endif
#ifdef UNIT_KERNEL
    int wrong_results = 0;
    for (unsigned k = 0; k < result.size(); ++k) {
      printf("[%03d] exact: %lg, FMM: %lg\n", k, exact[k], result[k]);

      if ((exact[k] - result[k]) / exact[k] > 1e-13)
	++wrong_results;
    }
    printf("Wrong counts: %d\n", wrong_results);
#endif
  }
}
<commit_msg>Added command line parameter for P<commit_after>/*
Copyright (C) 2011 by Rio Yokota, Simon Layton, Lorena Barba

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include <FMM_plan.hpp>
#include <SphericalLaplaceKernel.hpp>
#include <UnitKernel.hpp>
// #include <CartesianLaplaceKernel.hpp>
#include <CartesianLaplaceKernel2.hpp>
#include <CartesianYukawaKernel.hpp>

// modify error checking for counting kernel
// TODO: Do this much better...
// #define UNIT_KERNEL
//#define SPH_KERNEL
//#define CART_KERNEL
#define YUKAWA_KERNEL

template <typename Box>
void print_box(const Box& b, std::string padding = std::string()) {
  std::cout << padding << "Box " << b.index()
            << " (Level " << b.level() << ", Parent " << b.parent().index() << "): "
            << b.morton_index() << "    " << b.center() << "\n";

  padding.append(2,' ');
  if (!b.is_leaf()) {
    for (auto ci = b.child_begin(); ci != b.child_end(); ++ci)
      print_box(*ci, padding);
  } else {
    for (auto ci = b.body_begin(); ci != b.body_end(); ++ci)
      std::cout << padding << "Point " << ci->index() << ": "
		<< ci->morton_index() << "\t" << ci->point() << "\n";
  }
}

// Random number in [0,1)
inline double drand() {
  return ::drand48();
}

int main(int argc, char **argv)
{
  int numBodies = 100;
  bool checkErrors = true;
  bool printBox = false;
  FMMOptions opts;
  opts.set_theta(1 / sqrtf(4));    // Multipole acceptance criteria
  opts.NCRIT = 10;
  unsigned P = 6; // default truncation #

  // parse command line args
  for (int i = 1; i < argc; ++i) {
    if (strcmp(argv[i],"-N") == 0) {
      i++;
      numBodies = atoi(argv[i]);
    } else if (strcmp(argv[i],"-theta") == 0) {
      i++;
      opts.THETA = (double)atof(argv[i]);
      opts.set_theta(opts.THETA);
    } else if (strcmp(argv[i],"-nocheck") == 0) {
      checkErrors = false;
    } else if (strcmp(argv[i],"-bottomup") == 0) {
      opts.tree = FMMOptions::BOTTOMUP;
    } else if (strcmp(argv[i],"-evaluator") == 0) {
      i++;
      if (strcmp(argv[i],"FMM") == 0) {
        opts.evaluator = FMMOptions::FMM;
      } else if (strcmp(argv[i],"TREECODE") == 0) {
        opts.evaluator = FMMOptions::TREECODE;
      } else {
        printf("[W]: Unknown evaluator type: \"%s\"\n",argv[i]);
      }
    } else if (strcmp(argv[i],"-ncrit") == 0) {
      i++;
      opts.NCRIT = (unsigned)atoi(argv[i]);
    } else if (strcmp(argv[i],"-printbox") == 0) {
      printBox = true;
    } else if (strcmp(argv[i],"-P") == 0) {
      i++;
      P = atoi(argv[i]);
    } else {
      printf("[W]: Unknown command line arg: \"%s\"\n",argv[i]);
    }
  }

  // Init the FMM Kernel
#ifdef SPH_KERNEL
  typedef SphericalLaplaceKernel kernel_type;
  kernel_type K(P);
#endif
#ifdef CART_KERNEL
  (void) P;
  typedef CartesianLaplaceKernel<5> kernel_type;
  kernel_type K;
#endif
#ifdef YUKAWA_KERNEL
  typedef CartesianYukawaKernel kernel_type;
  kernel_type K(P,0.5);
#endif
#ifdef UNIT_KERNEL
  typedef UnitKernel kernel_type;
  kernel_type K;
#endif
  typedef kernel_type::point_type point_type;
  typedef kernel_type::charge_type charge_type;
  typedef kernel_type::result_type result_type;

  // Init points and charges
  std::vector<point_type> points(numBodies);
  for (int k = 0; k < numBodies; ++k)
    points[k] = point_type(drand(), drand(), drand());
  //std::vector<point_type> target_points = points;

  std::vector<charge_type> charges(numBodies);
  for (int k = 0; k < numBodies; ++k)
    charges[k] = drand();

  // Build the FMM
  //fmm_plan plan = fmm_plan(K, bodies, opts);
  FMM_plan<kernel_type> plan = FMM_plan<kernel_type>(K, points, opts);
  if (printBox) {
    print_box(plan.otree.root());
  }

  // Execute the FMM
  //fmm_execute(plan, charges, target_points);
  std::vector<result_type> result = plan.execute(charges, points);

  // Check the result
  // TODO: More elegant
  if (checkErrors) {
    std::vector<result_type> exact(numBodies);

    // Compute the result with a direct matrix-vector multiplication
    Direct::matvec(K, points, charges, exact);

#if defined(SPH_KERNEL) || defined(CART_KERNEL) || defined(YUKAWA_KERNEL)
    result_type rdiff, rnorm;
    for (unsigned k = 0; k < result.size(); ++k) {
      printf("[%03d] exact: %lg, FMM: %lg\n", k, exact[k][0], result[k][0]);

      rdiff = (result[k] - exact[k]) * (result[k] - exact[k]);
      rnorm = exact[k] * exact[k];
    }

    printf("Error (pot) : %.4e\n", sqrt(rdiff[0] / rnorm[0]));
    printf("Error (acc) : %.4e\n", sqrt((rdiff[1]+rdiff[2]+rdiff[3]) /
					(rnorm[1]+rnorm[2]+rnorm[3])));
#endif
#ifdef UNIT_KERNEL
    int wrong_results = 0;
    for (unsigned k = 0; k < result.size(); ++k) {
      printf("[%03d] exact: %lg, FMM: %lg\n", k, exact[k], result[k]);

      if ((exact[k] - result[k]) / exact[k] > 1e-13)
	++wrong_results;
    }
    printf("Wrong counts: %d\n", wrong_results);
#endif
  }
}
<|endoftext|>


<commit_before>#include "GamepadController.hpp"
#include <algorithm>

using namespace std;

namespace {
constexpr auto Dribble_Step_Time = RJ::Seconds(0.125);
constexpr auto Kicker_Step_Time = RJ::Seconds(0.125);
const float AXIS_MAX = 32768.0f;
// cutoff for counting triggers as 'on'
const float TRIGGER_CUTOFF = 0.9;
}

std::vector<int> GamepadController::controllersInUse = {};
int GamepadController::joystickRemoved = -1;

GamepadController::GamepadController()
    : _controller(nullptr), _lastDribblerTime(), _lastKickerTime() {
    // initialize using the SDL joystick
    if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0) {
        cerr << "ERROR: SDL could not initialize game controller system! SDL "
                "Error: " << SDL_GetError() << endl;
        return;
    }

    // Attempt to add additional mappings (relative to run)
    if (SDL_GameControllerAddMappingsFromFile(
            ApplicationRunDirectory()
                .filePath("../external/sdlcontrollerdb/gamecontrollerdb.txt")
                .toStdString()
                .c_str()) == -1) {
        cout << "Failed adding additional SDL Gamecontroller Mappings: "
             << SDL_GetError() << endl;
    }

    // Controllers will be detected later if needed.
    connected = false;
    controllerId = -1;
    robotId = -1;
    openJoystick();
}

GamepadController::~GamepadController() {
    QMutexLocker(&mutex());
    SDL_GameControllerClose(_controller);
    _controller = nullptr;
    SDL_Quit();
}

void GamepadController::openJoystick() {
    if (SDL_NumJoysticks()) {
        // Open the first available controller
        for (int i = 0; i < SDL_NumJoysticks(); ++i) {
            // setup the joystick as a game controller if available
            if (std::find(controllersInUse.begin(), controllersInUse.end(),
                          i) == controllersInUse.end() &&
                SDL_IsGameController(i)) {
                std::cout << i << std::endl;
                SDL_GameController* controller;
                controller = SDL_GameControllerOpen(i);

                if (controller != nullptr) {
                    _controller = controller;
                    connected = true;
                    controllerId = i;
                    controllersInUse.push_back(i);
                    sort(controllersInUse.begin(), controllersInUse.end());
                    cout << "Using " << SDL_GameControllerName(_controller)
                         << " game controller as controller # "
                         << controllersInUse.size() << endl;
                    break;
                } else {
                    cerr << "ERROR: Could not open controller! SDL Error: "
                         << SDL_GetError() << endl;
                }
                return;
            }
        }
    }
}

void GamepadController::closeJoystick() {
    cout << "Closing " << SDL_GameControllerName(_controller) << endl;
    SDL_GameControllerClose(_controller);
    auto index =
        find(controllersInUse.begin(), controllersInUse.end(), controllerId);
    if (index != controllersInUse.end()) {
        for (auto i = index + 1; i != controllersInUse.end(); i++) {
            *i -= 1;
        }
        controllersInUse.erase(index);
    }
    controllerId = -1;

    robotId = -1;
    connected = false;
}

bool GamepadController::valid() const { return connected; }

void GamepadController::update() {
    QMutexLocker(&mutex());
    SDL_GameControllerUpdate();

    RJ::Time now = RJ::now();

    if (connected) {
        // Check if dc
        if (joystickRemoved > 0 && controllerId > joystickRemoved) {
            controllerId -= 1;
        }
        if (!SDL_GameControllerGetAttached(_controller)) {
            closeJoystick();
            return;
        }
    } else {
        // Check if new controller found
        // TODO use the SDL event API to only run this if we receive a connected
        // event.
        openJoystick();
        if (!connected) {
            return;
        }
    }

    /*
     *  DRIBBLER ON/OFF
     */
    if (SDL_GameControllerGetButton(_controller,
                                    SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) {
        _controls.dribble = true;
    } else if (SDL_GameControllerGetAxis(_controller,
                                         SDL_CONTROLLER_AXIS_TRIGGERLEFT) /
                   AXIS_MAX >
               TRIGGER_CUTOFF) {
        _controls.dribble = false;
    }

    /*
     *  DRIBBLER POWER
     */
    if (SDL_GameControllerGetButton(_controller, SDL_CONTROLLER_BUTTON_A)) {
        if ((now - _lastDribblerTime) >= Dribble_Step_Time) {
            _controls.dribblerPower = max(_controls.dribblerPower - 0.1, 0.0);
            _lastDribblerTime = now;
        }
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_Y)) {
        if ((now - _lastDribblerTime) >= Dribble_Step_Time) {
            _controls.dribblerPower = min(_controls.dribblerPower + 0.1, 1.0);
            _lastDribblerTime = now;
        }
    } else {
        // Let dribbler speed change immediately
        _lastDribblerTime = now - Dribble_Step_Time;
    }

    /*
     *  KICKER POWER
     */
    if (SDL_GameControllerGetButton(_controller, SDL_CONTROLLER_BUTTON_X)) {
        if ((now - _lastKickerTime) >= Kicker_Step_Time) {
            _controls.kickPower = max(_controls.kickPower - 0.1, 0.0);
            _lastKickerTime = now;
        }
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_B)) {
        if ((now - _lastKickerTime) >= Kicker_Step_Time) {
            _controls.kickPower = min(_controls.kickPower + 0.1, 1.0);
            _lastKickerTime = now;
        }
    } else {
        _lastKickerTime = now - Kicker_Step_Time;
    }

    /*
     *  KICK TRUE/FALSE
     */
    _controls.kick = SDL_GameControllerGetButton(
        _controller, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);

    /*
     *  CHIP TRUE/FALSE
     */
    _controls.chip = SDL_GameControllerGetAxis(
                         _controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) /
                         AXIS_MAX >
                     TRIGGER_CUTOFF;

    /*
     *  VELOCITY ROTATION
     */
    // Logitech F310 Controller
    _controls.rotation =
        -1 * SDL_GameControllerGetAxis(_controller, SDL_CONTROLLER_AXIS_LEFTX) /
        AXIS_MAX;

    /*
     *  VELOCITY TRANSLATION
     */
    auto rightX =
        SDL_GameControllerGetAxis(_controller, SDL_CONTROLLER_AXIS_RIGHTX) /
        AXIS_MAX;
    auto rightY =
        -SDL_GameControllerGetAxis(_controller, SDL_CONTROLLER_AXIS_RIGHTY) /
        AXIS_MAX;

    Geometry2d::Point input(rightX, rightY);

    // Align along an axis using the DPAD as modifier buttons
    if (SDL_GameControllerGetButton(_controller,
                                    SDL_CONTROLLER_BUTTON_DPAD_DOWN)) {
        input.y() = -fabs(rightY);
        input.x() = 0;
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_DPAD_UP)) {
        input.y() = fabs(rightY);
        input.x() = 0;
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_DPAD_LEFT)) {
        input.y() = 0;
        input.x() = -fabs(rightX);
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) {
        input.y() = 0;
        input.x() = fabs(rightX);
    }

    // Floating point precision error rounding
    if (_controls.kickPower < 1e-1) _controls.kickPower = 0;
    if (_controls.dribblerPower < 1e-1) _controls.dribblerPower = 0;
    if (fabs(_controls.rotation) < 5e-2) _controls.rotation = 0;
    if (fabs(input.y()) < 5e-2) input.y() = 0;
    if (fabs(input.x()) < 5e-2) input.x() = 0;

    _controls.translation = Geometry2d::Point(input.x(), input.y());
}

JoystickControlValues GamepadController::getJoystickControlValues() {
    QMutexLocker(&mutex());
    return _controls;
}

void GamepadController::reset() {
    QMutexLocker(&mutex());
    _controls.dribble = false;
}
<commit_msg>this probably won't help<commit_after>#include "GamepadController.hpp"
#include <algorithm>

using namespace std;

namespace {
constexpr auto Dribble_Step_Time = RJ::Seconds(0.125);
constexpr auto Kicker_Step_Time = RJ::Seconds(0.125);
const float AXIS_MAX = 32768.0f;
// cutoff for counting triggers as 'on'
const float TRIGGER_CUTOFF = 0.9;
}

std::vector<int> GamepadController::controllersInUse = {};
int GamepadController::joystickRemoved = -1;

GamepadController::GamepadController()
    : _controller(nullptr), _lastDribblerTime(), _lastKickerTime() {
    // initialize using the SDL joystick
    if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0) {
        cerr << "ERROR: SDL could not initialize game controller system! SDL "
                "Error: " << SDL_GetError() << endl;
        return;
    }

    // Attempt to add additional mappings (relative to run)
    if (SDL_GameControllerAddMappingsFromFile(
            ApplicationRunDirectory()
                .filePath("../external/sdlcontrollerdb/gamecontrollerdb.txt")
                .toStdString()
                .c_str()) == -1) {
        cout << "Failed adding additional SDL Gamecontroller Mappings: "
             << SDL_GetError() << endl;
    }

    // Controllers will be detected later if needed.
    connected = false;
    controllerId = -1;
    robotId = -1;
    openJoystick();
}

GamepadController::~GamepadController() {
    QMutexLocker(&mutex());
    SDL_GameControllerClose(_controller);
    _controller = nullptr;
    SDL_Quit();
}

void GamepadController::openJoystick() {
    if (SDL_NumJoysticks()) {
        // Open the first available controller
        for (int i = 0; i < SDL_NumJoysticks(); ++i) {
            // setup the joystick as a game controller if available
            if (std::find(controllersInUse.begin(), controllersInUse.end(),
                          i) == controllersInUse.end() &&
                SDL_IsGameController(i)) {
                std::cout << i << std::endl;
                SDL_GameController* controller;
                controller = SDL_GameControllerOpen(i);

                if (controller != nullptr) {
                    _controller = controller;
                    connected = true;
                    controllerId = i;
                    controllersInUse.push_back(i);
                    sort(controllersInUse.begin(), controllersInUse.end());
                    cout << "Using " << SDL_GameControllerName(_controller)
                         << " game controller as controller # "
                         << controllersInUse.size() << endl;
                    break;
                } else {
                    cerr << "ERROR: Could not open controller! SDL Error: "
                         << SDL_GetError() << endl;
                }
                return;
            }
        }
    }
}

void GamepadController::closeJoystick() {
    cout << "Closing " << SDL_GameControllerName(_controller) << endl;
    SDL_GameControllerClose(_controller);
    auto index =
        find(controllersInUse.begin(), controllersInUse.end(), controllerId);
    if (index != controllersInUse.end()) {
        controllersInUse.erase(index);
        std::cout<<"controllers in use: "<<std::endl;
        for (; index != controllersInUse.end(); index++) {
          std::cout<<*index<<std::endl;
          *index -= 1;
        }
    }
    controllerId = -1;

    robotId = -1;
    connected = false;
}

bool GamepadController::valid() const { return connected; }

void GamepadController::update() {
    QMutexLocker(&mutex());
    SDL_GameControllerUpdate();

    RJ::Time now = RJ::now();

    if (connected) {
        // Check if dc
        if (joystickRemoved > 0 && controllerId > joystickRemoved) {
            controllerId -= 1;
        }
        if (!SDL_GameControllerGetAttached(_controller)) {
            closeJoystick();
            return;
        }
    } else {
        // Check if new controller found
        // TODO use the SDL event API to only run this if we receive a connected
        // event.
        openJoystick();
        if (!connected) {
            return;
        }
    }

    /*
     *  DRIBBLER ON/OFF
     */
    if (SDL_GameControllerGetButton(_controller,
                                    SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) {
        _controls.dribble = true;
    } else if (SDL_GameControllerGetAxis(_controller,
                                         SDL_CONTROLLER_AXIS_TRIGGERLEFT) /
                   AXIS_MAX >
               TRIGGER_CUTOFF) {
        _controls.dribble = false;
    }

    /*
     *  DRIBBLER POWER
     */
    if (SDL_GameControllerGetButton(_controller, SDL_CONTROLLER_BUTTON_A)) {
        if ((now - _lastDribblerTime) >= Dribble_Step_Time) {
            _controls.dribblerPower = max(_controls.dribblerPower - 0.1, 0.0);
            _lastDribblerTime = now;
        }
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_Y)) {
        if ((now - _lastDribblerTime) >= Dribble_Step_Time) {
            _controls.dribblerPower = min(_controls.dribblerPower + 0.1, 1.0);
            _lastDribblerTime = now;
        }
    } else {
        // Let dribbler speed change immediately
        _lastDribblerTime = now - Dribble_Step_Time;
    }

    /*
     *  KICKER POWER
     */
    if (SDL_GameControllerGetButton(_controller, SDL_CONTROLLER_BUTTON_X)) {
        if ((now - _lastKickerTime) >= Kicker_Step_Time) {
            _controls.kickPower = max(_controls.kickPower - 0.1, 0.0);
            _lastKickerTime = now;
        }
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_B)) {
        if ((now - _lastKickerTime) >= Kicker_Step_Time) {
            _controls.kickPower = min(_controls.kickPower + 0.1, 1.0);
            _lastKickerTime = now;
        }
    } else {
        _lastKickerTime = now - Kicker_Step_Time;
    }

    /*
     *  KICK TRUE/FALSE
     */
    _controls.kick = SDL_GameControllerGetButton(
        _controller, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);

    /*
     *  CHIP TRUE/FALSE
     */
    _controls.chip = SDL_GameControllerGetAxis(
                         _controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) /
                         AXIS_MAX >
                     TRIGGER_CUTOFF;

    /*
     *  VELOCITY ROTATION
     */
    // Logitech F310 Controller
    _controls.rotation =
        -1 * SDL_GameControllerGetAxis(_controller, SDL_CONTROLLER_AXIS_LEFTX) /
        AXIS_MAX;

    /*
     *  VELOCITY TRANSLATION
     */
    auto rightX =
        SDL_GameControllerGetAxis(_controller, SDL_CONTROLLER_AXIS_RIGHTX) /
        AXIS_MAX;
    auto rightY =
        -SDL_GameControllerGetAxis(_controller, SDL_CONTROLLER_AXIS_RIGHTY) /
        AXIS_MAX;

    Geometry2d::Point input(rightX, rightY);

    // Align along an axis using the DPAD as modifier buttons
    if (SDL_GameControllerGetButton(_controller,
                                    SDL_CONTROLLER_BUTTON_DPAD_DOWN)) {
        input.y() = -fabs(rightY);
        input.x() = 0;
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_DPAD_UP)) {
        input.y() = fabs(rightY);
        input.x() = 0;
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_DPAD_LEFT)) {
        input.y() = 0;
        input.x() = -fabs(rightX);
    } else if (SDL_GameControllerGetButton(_controller,
                                           SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) {
        input.y() = 0;
        input.x() = fabs(rightX);
    }

    // Floating point precision error rounding
    if (_controls.kickPower < 1e-1) _controls.kickPower = 0;
    if (_controls.dribblerPower < 1e-1) _controls.dribblerPower = 0;
    if (fabs(_controls.rotation) < 5e-2) _controls.rotation = 0;
    if (fabs(input.y()) < 5e-2) input.y() = 0;
    if (fabs(input.x()) < 5e-2) input.x() = 0;

    _controls.translation = Geometry2d::Point(input.x(), input.y());
}

JoystickControlValues GamepadController::getJoystickControlValues() {
    QMutexLocker(&mutex());
    return _controls;
}

void GamepadController::reset() {
    QMutexLocker(&mutex());
    _controls.dribble = false;
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

class HeapSort {
private:
	vector<int> data;
	void Heapify();
	void HeapifyDown(int root, int bottom);
	bool HasChildren(int root, int bottom) const;
public:
	HeapSort(vector<int> input);
	void Sort();
};

void HeapSort::Heapify() {
	//Element at (length/2 - 1) is guaranteed to be the last node with children
	for (int i=(data.size()/2)-1; i>=0; --i) {
		HeapifyDown(i, data.size()-1);
	}
}

void HeapSort::HeapifyDown(int root, int bottom) {
	while (HasChildren(root, bottom)) {
		//Sift down until we reach a childless node
		int maxChild = root * 2 + 1;
		//Left child definitely exists, check if right child does
		int rightChildPos = root * 2 + 2;
		if (rightChildPos <= bottom) {
			//Check if right child is bigger
			if (data.at(rightChildPos) > data.at(maxChild)) {
				maxChild = rightChildPos;
			}
		}
		//Now we have the greatest child, check if it's larger than the root
		if (data.at(root) < data.at(maxChild)) {
			//Child is bigger, swap them
			iter_swap(data.begin()+root, data.begin()+maxChild);
			//Set the root now to that child
			root = maxChild;
		} else {
			//Root is already the largest, we're done
			return;
		}
	}
}

bool HeapSort::HasChildren(int root, int bottom) const {
	//Return if a left child exists
	return (root*2 + 1) <= bottom;
}

HeapSort::HeapSort(vector<int> input) : data(input) {}

void HeapSort::Sort() {
	Heapify();
	int endPos = data.size()-1;
	while (endPos >= 0) {
		//Top of the heap is the greatest, swap it with the back
		iter_swap(data.begin(), data.begin()+endPos);
		//Step the back down one because that element is now in the sorted position
		--endPos;
		//Now heapify down the new root element
		HeapifyDown(0, endPos);
	}
	for (auto i : data) {
		cout << i << " ";
	}
	cout << endl;
}

int main() {
	vector<int> inputNumbers;

	//Read numbers
	int num;
	while (cin >> num) {
		inputNumbers.emplace_back(num);
	}

	HeapSort heapSort(inputNumbers);
	heapSort.Sort();

	return 0;
}
<commit_msg>removed old versions<commit_after><|endoftext|>