<commit_before>/******************************************************************************
 *  Copyright (c) 2014 Jinming Hu
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: db_tablemgr_test.cc
 *  Version: 1.0
 *  Author: Jinming Hu
 *  E-mail: hjm211324@gmail.com
 *  Date: Oct. 24, 2014
 *  Time: 09:44:22
 *  Description:
 *****************************************************************************/
#include <iostream>
#include <cassert>
#include "../src/db_tablemanager.h"
#include "../src/db_fields.h"

int main() {
    using namespace std;
    using namespace Database;

    DBTableManager table;

    DBFields fields;
    /*
    static constexpr uint64 TYPE_INT8    = 0;
    static constexpr uint64 TYPE_UINT8   = 1;
    static constexpr uint64 TYPE_INT16   = 2;
    static constexpr uint64 TYPE_UINT16  = 3;
    static constexpr uint64 TYPE_INT32   = 4;
    static constexpr uint64 TYPE_UINT32  = 5;
    static constexpr uint64 TYPE_INT64   = 6;
    static constexpr uint64 TYPE_UINT64  = 7;
    static constexpr uint64 TYPE_BOOL    = 8;
    static constexpr uint64 TYPE_CHAR    = 9;
    static constexpr uint64 TYPE_UCHAR   = 10;
    static constexpr uint64 TYPE_FLOAT   = 11;
    static constexpr uint64 TYPE_DOUBLE  = 12;
    */

    // test create
    fields.insert(DBFields::TYPE_UINT64, 8, 1, "Student ID");
    fields.insert(DBFields::TYPE_CHAR, 100, 0, "Student name");
    fields.insert(DBFields::TYPE_BOOL, 1, 0, "Clever or Foolish");

    int rtv;
    rtv = table.create("student", fields, 4096);
    assert(rtv == 0);

    rtv = table.open("student");
    assert(rtv == 0);

    cout << "Table name: " << table._table_name << endl;
    cout << "Number of fields: " << table._num_fields << endl;
    cout << "Pages in each map page: " << table._pages_each_map_page << endl;
    cout << "Record length: " << table._record_length << endl;
    cout << "Number of records in each page: " << table._num_records_each_page << endl;
    cout << "Last empty slots map page: " << table._last_empty_slots_map_page << endl;
    cout << "Last record page: " << table._last_record_page << endl;

    cout << "Empty slots: " << table._empty_slots_map.size() << endl;
    for (int i = 0; i < table._empty_slots_map.size(); ++i) {
        if (table._empty_slots_map[i])
            cout << "    " << i << endl;
    }

    cout << "DBField info: " << endl;
    DBFields& fields2 = table._fields;
    cout << "Num fields: " << fields2.size() << endl;
    cout << "Total length: " << fields2.recordLength() << endl;

    for (int i = 0; i < fields2.size(); ++i)
        cout << fields2.field_id()[i] << ' ' << fields2.field_type()[i] << ' '
             << fields2.field_length()[i] << ' ' << fields2.primary_key()[i] << ' '
             << fields2.field_name()[i] << endl;

    unsigned long long student_id = 0x2001;
    char student_name[1000] = "John Idiot";
    bool clever = 1;

    // insert until the first map page is full
    for (int i = 0; i < 32573 * 37; ++i) {
        student_id += 1;
        clever ^= 1;
        rtv = table.insertRecord({ &student_id, student_name, &clever });
        assert(rtv == 0);
    }

    cout << table._file->write_times << endl
         << table._file->read_times << endl;

    // close table
    rtv = table.close();
    assert(rtv == 0);

    rtv = table.open("student");
    assert(rtv == 0);

    for (int i = 0; i < 38; ++i) {
        student_id += 1;
        clever ^= 1;
        rtv = table.insertRecord({ &student_id, student_name, &clever });
        assert(rtv == 0);
    }

    /*
    // test traverse function
    ofstream fout("traverse_result", fstream::out | fstream::binary);
    auto writeTofile = [&fout, &table](const char* record, const RID rid) {
        fout.write(record, table._record_length);
    };

    table.traverseRecords(writeTofile);
    */

    cout << table._file->write_times << endl
         << table._file->read_times << endl;

    rtv = table.close();
    assert(rtv == 0);

    // test remove
    // rtv = table.remove("student");
    // cout << rtv << endl;

}
<commit_msg>find optimal page size for buffer<commit_after>/******************************************************************************
 *  Copyright (c) 2014 Jinming Hu
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: db_tablemgr_test.cc
 *  Version: 1.0
 *  Author: Jinming Hu
 *  E-mail: hjm211324@gmail.com
 *  Date: Oct. 24, 2014
 *  Time: 09:44:22
 *  Description:
 *****************************************************************************/
#include <iostream>
#include <cassert>
#include "../src/db_tablemanager.h"
#include "../src/db_fields.h"

int main() {
    using namespace std;
    using namespace Database;

    DBTableManager table;

    DBFields fields;
    /*
    static constexpr uint64 TYPE_INT8    = 0;
    static constexpr uint64 TYPE_UINT8   = 1;
    static constexpr uint64 TYPE_INT16   = 2;
    static constexpr uint64 TYPE_UINT16  = 3;
    static constexpr uint64 TYPE_INT32   = 4;
    static constexpr uint64 TYPE_UINT32  = 5;
    static constexpr uint64 TYPE_INT64   = 6;
    static constexpr uint64 TYPE_UINT64  = 7;
    static constexpr uint64 TYPE_BOOL    = 8;
    static constexpr uint64 TYPE_CHAR    = 9;
    static constexpr uint64 TYPE_UCHAR   = 10;
    static constexpr uint64 TYPE_FLOAT   = 11;
    static constexpr uint64 TYPE_DOUBLE  = 12;
    */

    // test create
    fields.insert(DBFields::TYPE_UINT64, 8, 1, "Student ID");
    fields.insert(DBFields::TYPE_CHAR, 100, 0, "Student name");
    fields.insert(DBFields::TYPE_BOOL, 1, 0, "Clever or Foolish");

    int rtv;
    // optimal on my mac
    rtv = table.create("student", fields, 4096 * 4);
    assert(rtv == 0);

    rtv = table.open("student");
    assert(rtv == 0);

    cout << "Table name: " << table._table_name << endl;
    cout << "Number of fields: " << table._num_fields << endl;
    cout << "Pages in each map page: " << table._pages_each_map_page << endl;
    cout << "Record length: " << table._record_length << endl;
    cout << "Number of records in each page: " << table._num_records_each_page << endl;
    cout << "Last empty slots map page: " << table._last_empty_slots_map_page << endl;
    cout << "Last record page: " << table._last_record_page << endl;

    cout << "Empty slots: " << table._empty_slots_map.size() << endl;
    for (int i = 0; i < table._empty_slots_map.size(); ++i) {
        if (table._empty_slots_map[i])
            cout << "    " << i << endl;
    }

    cout << "DBField info: " << endl;
    DBFields& fields2 = table._fields;
    cout << "Num fields: " << fields2.size() << endl;
    cout << "Total length: " << fields2.recordLength() << endl;

    for (int i = 0; i < fields2.size(); ++i)
        cout << fields2.field_id()[i] << ' ' << fields2.field_type()[i] << ' '
             << fields2.field_length()[i] << ' ' << fields2.primary_key()[i] << ' '
             << fields2.field_name()[i] << endl;

    unsigned long long student_id = 0x2001;
    char student_name[1000] = "John Idiot";
    bool clever = 1;

    // insert until the first map page is full
    for (int i = 0; i < 32573 * 37; ++i) {
        student_id += 1;
        clever ^= 1;
        rtv = table.insertRecord({ &student_id, student_name, &clever });
        assert(rtv == 0);
    }

    // close table
    rtv = table.close();
    assert(rtv == 0);

    rtv = table.open("student");
    assert(rtv == 0);

    for (int i = 0; i < 38; ++i) {
        student_id += 1;
        clever ^= 1;
        rtv = table.insertRecord({ &student_id, student_name, &clever });
        assert(rtv == 0);
    }

    /*
    // test traverse function
    ofstream fout("traverse_result", fstream::out | fstream::binary);
    auto writeTofile = [&fout, &table](const char* record, const RID rid) {
        fout.write(record, table._record_length);
    };

    table.traverseRecords(writeTofile);
    */

    rtv = table.close();
    assert(rtv == 0);

    // test remove
    // rtv = table.remove("student");
    // cout << rtv << endl;

}
<|endoftext|>


<commit_before>#ifndef LIBKOPETE_UI_AVATARSELECTORWIDGET_CPP
#define LIBKOPETE_UI_AVATARSELECTORWIDGET_CPP
/*
    avatarselectorwidget.cpp - Widget to manage and select user avatar

    Copyright (c) 2007      by Michaël Larouche       <larouche@kde.org>
    Copyright (c) 2007         Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>

    Kopete    (c) 2002-2007 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/
#include "avatarselectorwidget.h"

// Qt includes
#include <QListWidget>
#include <QListWidgetItem>
#include <QIcon>
#include <QPainter>

// KDE includes
#include <kdebug.h>
#include <klocale.h>
#include <kurl.h>
#include <kfiledialog.h>
#include <kpixmapregionselectordialog.h>

#include "ui_avatarselectorwidget.h"

namespace Kopete
{
namespace UI
{

class AvatarSelectorWidgetItem : public QListWidgetItem
{
public:
	AvatarSelectorWidgetItem(QListWidget *parent)
	 : QListWidgetItem(parent, QListWidgetItem::UserType)
	{}

	void setAvatarEntry(Kopete::AvatarManager::AvatarEntry entry)
	{
		m_entry = entry;

		QSize s(96,96);

		if (listWidget())
		    s = listWidget()->iconSize();

		QPixmap pix;
		if (entry.path.isEmpty())
		{
			// draw a fake image telling there is no avatar
			pix = QPixmap(s);
			QPainter p(&pix);
			p.fillRect(pix.rect(), Qt::white);
			p.drawText(pix.rect(), Qt::TextWordWrap | Qt::AlignCenter, i18n("No Avatar"));
		}
		else
		{
			pix = QPixmap(entry.path).scaled(s);
		}

		// draw a border around the avatar
		QPainter p(&pix);
		p.setBrush(Qt::NoBrush);
		p.drawRect(0,0,pix.width()-1,pix.height()-1);

		setIcon(pix);
	}

	Kopete::AvatarManager::AvatarEntry avatarEntry() const
	{
		return m_entry;
	}

private:
	Kopete::AvatarManager::AvatarEntry m_entry;
};

class AvatarSelectorWidget::Private
{
public:
	Private()
	 : selectedItem(0), noAvatarItem(0)
	{}

	Ui::AvatarSelectorWidget mainWidget;
	QListWidgetItem *selectedItem;
	QString currentAvatar;
	AvatarSelectorWidgetItem * noAvatarItem;
	AvatarSelectorWidgetItem * addItem(Kopete::AvatarManager::AvatarEntry entry);
};

AvatarSelectorWidget::AvatarSelectorWidget(QWidget *parent)
 : QWidget(parent), d(new Private)
{
	d->mainWidget.setupUi(this);

	// use icons on buttons
	d->mainWidget.buttonAddAvatar->setIcon( KIcon("list-add") );
	d->mainWidget.buttonRemoveAvatar->setIcon( KIcon("edit-delete") );

	// Connect signals/slots
	connect(d->mainWidget.buttonAddAvatar, SIGNAL(clicked()), this, SLOT(buttonAddAvatarClicked()));
	connect(d->mainWidget.buttonRemoveAvatar, SIGNAL(clicked()), this, SLOT(buttonRemoveAvatarClicked()));
	connect(d->mainWidget.listUserAvatar, SIGNAL(itemClicked(QListWidgetItem*)),
	        this, SLOT(listSelectionChanged(QListWidgetItem*)));
	connect(Kopete::AvatarManager::self(), SIGNAL(avatarAdded(Kopete::AvatarManager::AvatarEntry)),
	        this, SLOT(avatarAdded(Kopete::AvatarManager::AvatarEntry)));
	connect(Kopete::AvatarManager::self(), SIGNAL(avatarRemoved(Kopete::AvatarManager::AvatarEntry)),
	        this, SLOT(avatarRemoved(Kopete::AvatarManager::AvatarEntry)));

	// Add a "No Avatar" option
	Kopete::AvatarManager::AvatarEntry empty;
	empty.name = i18n("No Avatar");
	empty.contact = 0;
	empty.category = Kopete::AvatarManager::User;
	d->noAvatarItem = d->addItem(empty);

	// List avatars of User category
	Kopete::AvatarQueryJob *queryJob = new Kopete::AvatarQueryJob(this);
	connect(queryJob, SIGNAL(result(KJob*)), this, SLOT(queryJobFinished(KJob*)));
	queryJob->setQueryFilter( Kopete::AvatarManager::User );

	queryJob->start();
}

AvatarSelectorWidget::~AvatarSelectorWidget()
{
	delete d;
}

Kopete::AvatarManager::AvatarEntry AvatarSelectorWidget::selectedEntry() const
{
	Kopete::AvatarManager::AvatarEntry result;

	if( d->selectedItem )
	{
		result = static_cast<AvatarSelectorWidgetItem*>(d->selectedItem)->avatarEntry();
	}

	return result;
}

void AvatarSelectorWidget::setCurrentAvatar(const QString &path)
{
	d->currentAvatar = path;

	//try to find the avatar in the list
	QList<QListWidgetItem*> itemList = d->mainWidget.listUserAvatar->findItems("", Qt::MatchContains);
	QList<QListWidgetItem*>::iterator it = itemList.begin();

	while (it != itemList.end())
	{
		AvatarSelectorWidgetItem *item = static_cast<AvatarSelectorWidgetItem*>(*it);
		if (item->avatarEntry().path == path)
		{
			item->setSelected(true);
			listSelectionChanged( item );
			return;
		}
		++it;
	}

}

void AvatarSelectorWidget::buttonAddAvatarClicked()
{
	KUrl imageUrl = KFileDialog::getImageOpenUrl( KUrl(), this );
	if( !imageUrl.isEmpty() )
	{
		// TODO: Download image
		if( !imageUrl.isLocalFile() )
			return;

		// Crop the image
		QImage avatar = KPixmapRegionSelectorDialog::getSelectedImage( QPixmap(imageUrl.path()), 96, 96, this );

		QString imageName = imageUrl.fileName();

		Kopete::AvatarManager::AvatarEntry newEntry;
		// Remove extension from filename
		newEntry.name = imageName.left( imageName.lastIndexOf('.') );
		newEntry.image = avatar;
		newEntry.category = Kopete::AvatarManager::User;

		Kopete::AvatarManager::AvatarEntry addedEntry = Kopete::AvatarManager::self()->add( newEntry );
		if( addedEntry.path.isEmpty() )
		{
			//TODO add a real error message
			//d->mainWidget.labelErrorMessage->setText( i18n("Kopete cannot add this new avatar because it could not save the avatar image in user directory.") );
			return;
		}

		// select the added entry and show the user tab
		QList<QListWidgetItem *> foundItems = d->mainWidget.listUserAvatar->findItems( addedEntry.name, Qt::MatchContains );
		if( !foundItems.isEmpty() )
		{
			AvatarSelectorWidgetItem *item = dynamic_cast<AvatarSelectorWidgetItem*>( foundItems.first() );
			if ( !item )
				return;
			item->setSelected( true );
		}

	}
}

void AvatarSelectorWidget::buttonRemoveAvatarClicked()
{
	// if no item was selected, just exit
	if ( !d->mainWidget.listUserAvatar->selectedItems().count() )
		return;

	AvatarSelectorWidgetItem *selectedItem = dynamic_cast<AvatarSelectorWidgetItem*>( d->mainWidget.listUserAvatar->selectedItems().first() );
	if( selectedItem )
	{
		if ( selectedItem != d->noAvatarItem )
		{
			if( !Kopete::AvatarManager::self()->remove( selectedItem->avatarEntry() ) )
			{
				kDebug(14010) << "Removing of avatar failed for unknown reason.";
			}
		}
	}
}

void AvatarSelectorWidget::queryJobFinished(KJob *job)
{
	Kopete::AvatarQueryJob *queryJob = static_cast<Kopete::AvatarQueryJob*>(job);
	if( !queryJob->error() )
	{
		QList<Kopete::AvatarManager::AvatarEntry> avatarList = queryJob->avatarList();
		Kopete::AvatarManager::AvatarEntry entry;
		foreach(entry, avatarList)
		{
			d->addItem(entry);
		}
	}
	else
	{
		//TODO add a real error message
		//d->mainWidget.labelErrorMessage->setText( queryJob->errorText() );
	}
}

void AvatarSelectorWidget::avatarAdded(Kopete::AvatarManager::AvatarEntry newEntry)
{
	d->addItem(newEntry);
}

void AvatarSelectorWidget::avatarRemoved(Kopete::AvatarManager::AvatarEntry entryRemoved)
{
	// Same here, avatar can be only removed from listUserAvatar
	foreach(QListWidgetItem *item, d->mainWidget.listUserAvatar->findItems("",Qt::MatchContains))
	{
		// checks if this is the right item
		AvatarSelectorWidgetItem *avatar = dynamic_cast<AvatarSelectorWidgetItem*>(item);
		if (!avatar || avatar->avatarEntry().name != entryRemoved.name)
		    continue;

		kDebug(14010) << "Removing " << entryRemoved.name << " from list.";

		int deletedRow = d->mainWidget.listUserAvatar->row( item );
		QListWidgetItem *removedItem = d->mainWidget.listUserAvatar->takeItem( deletedRow );
		delete removedItem;

		int newRow = --deletedRow;
		if( newRow < 0 )
			newRow = 0;

		// Select the previous avatar in the list, thus selecting a new avatar
		// and deselecting the avatar being removed.
		d->mainWidget.listUserAvatar->setCurrentRow( newRow );
		// Force update
		listSelectionChanged( d->mainWidget.listUserAvatar->item(newRow) );
	}
}

void AvatarSelectorWidget::listSelectionChanged(QListWidgetItem *item)
{
	d->mainWidget.buttonRemoveAvatar->setEnabled( item != d->noAvatarItem );
	d->selectedItem = item;
}

AvatarSelectorWidgetItem * AvatarSelectorWidget::Private::addItem(Kopete::AvatarManager::AvatarEntry entry)
{
	kDebug(14010) << "Entry(" << entry.name << "): " << entry.category;

	// only use User avatars
	if( !(entry.category & Kopete::AvatarManager::User) )
	    return 0;

	AvatarSelectorWidgetItem *item = new AvatarSelectorWidgetItem(mainWidget.listUserAvatar);
	item->setAvatarEntry(entry);
	if (entry.path == currentAvatar)
		item->setSelected(true);
	return item;
}

} // Namespace Kopete::UI

} // Namespace Kopete

#include "avatarselectorwidget.moc"
#endif // LIBKOPETE_UI/AVATARSELECTORWIDGET_CPP
<commit_msg>Fix bug 157683: Adding avatar crashes kopete We have to check if avatar isn't null.<commit_after>#ifndef LIBKOPETE_UI_AVATARSELECTORWIDGET_CPP
#define LIBKOPETE_UI_AVATARSELECTORWIDGET_CPP
/*
    avatarselectorwidget.cpp - Widget to manage and select user avatar

    Copyright (c) 2007      by Michaël Larouche       <larouche@kde.org>
    Copyright (c) 2007         Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>

    Kopete    (c) 2002-2007 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/
#include "avatarselectorwidget.h"

// Qt includes
#include <QListWidget>
#include <QListWidgetItem>
#include <QIcon>
#include <QPainter>

// KDE includes
#include <kdebug.h>
#include <klocale.h>
#include <kurl.h>
#include <kfiledialog.h>
#include <kpixmapregionselectordialog.h>

#include "ui_avatarselectorwidget.h"

namespace Kopete
{
namespace UI
{

class AvatarSelectorWidgetItem : public QListWidgetItem
{
public:
	AvatarSelectorWidgetItem(QListWidget *parent)
	 : QListWidgetItem(parent, QListWidgetItem::UserType)
	{}

	void setAvatarEntry(Kopete::AvatarManager::AvatarEntry entry)
	{
		m_entry = entry;

		QSize s(96,96);

		if (listWidget())
		    s = listWidget()->iconSize();

		QPixmap pix;
		if (entry.path.isEmpty())
		{
			// draw a fake image telling there is no avatar
			pix = QPixmap(s);
			QPainter p(&pix);
			p.fillRect(pix.rect(), Qt::white);
			p.drawText(pix.rect(), Qt::TextWordWrap | Qt::AlignCenter, i18n("No Avatar"));
		}
		else
		{
			pix = QPixmap(entry.path).scaled(s);
		}

		// draw a border around the avatar
		QPainter p(&pix);
		p.setBrush(Qt::NoBrush);
		p.drawRect(0,0,pix.width()-1,pix.height()-1);

		setIcon(pix);
	}

	Kopete::AvatarManager::AvatarEntry avatarEntry() const
	{
		return m_entry;
	}

private:
	Kopete::AvatarManager::AvatarEntry m_entry;
};

class AvatarSelectorWidget::Private
{
public:
	Private()
	 : selectedItem(0), noAvatarItem(0)
	{}

	Ui::AvatarSelectorWidget mainWidget;
	QListWidgetItem *selectedItem;
	QString currentAvatar;
	AvatarSelectorWidgetItem * noAvatarItem;
	AvatarSelectorWidgetItem * addItem(Kopete::AvatarManager::AvatarEntry entry);
};

AvatarSelectorWidget::AvatarSelectorWidget(QWidget *parent)
 : QWidget(parent), d(new Private)
{
	d->mainWidget.setupUi(this);

	// use icons on buttons
	d->mainWidget.buttonAddAvatar->setIcon( KIcon("list-add") );
	d->mainWidget.buttonRemoveAvatar->setIcon( KIcon("edit-delete") );

	// Connect signals/slots
	connect(d->mainWidget.buttonAddAvatar, SIGNAL(clicked()), this, SLOT(buttonAddAvatarClicked()));
	connect(d->mainWidget.buttonRemoveAvatar, SIGNAL(clicked()), this, SLOT(buttonRemoveAvatarClicked()));
	connect(d->mainWidget.listUserAvatar, SIGNAL(itemClicked(QListWidgetItem*)),
	        this, SLOT(listSelectionChanged(QListWidgetItem*)));
	connect(Kopete::AvatarManager::self(), SIGNAL(avatarAdded(Kopete::AvatarManager::AvatarEntry)),
	        this, SLOT(avatarAdded(Kopete::AvatarManager::AvatarEntry)));
	connect(Kopete::AvatarManager::self(), SIGNAL(avatarRemoved(Kopete::AvatarManager::AvatarEntry)),
	        this, SLOT(avatarRemoved(Kopete::AvatarManager::AvatarEntry)));

	// Add a "No Avatar" option
	Kopete::AvatarManager::AvatarEntry empty;
	empty.name = i18n("No Avatar");
	empty.contact = 0;
	empty.category = Kopete::AvatarManager::User;
	d->noAvatarItem = d->addItem(empty);

	// List avatars of User category
	Kopete::AvatarQueryJob *queryJob = new Kopete::AvatarQueryJob(this);
	connect(queryJob, SIGNAL(result(KJob*)), this, SLOT(queryJobFinished(KJob*)));
	queryJob->setQueryFilter( Kopete::AvatarManager::User );

	queryJob->start();
}

AvatarSelectorWidget::~AvatarSelectorWidget()
{
	delete d;
}

Kopete::AvatarManager::AvatarEntry AvatarSelectorWidget::selectedEntry() const
{
	Kopete::AvatarManager::AvatarEntry result;

	if( d->selectedItem )
	{
		result = static_cast<AvatarSelectorWidgetItem*>(d->selectedItem)->avatarEntry();
	}

	return result;
}

void AvatarSelectorWidget::setCurrentAvatar(const QString &path)
{
	d->currentAvatar = path;

	//try to find the avatar in the list
	QList<QListWidgetItem*> itemList = d->mainWidget.listUserAvatar->findItems("", Qt::MatchContains);
	QList<QListWidgetItem*>::iterator it = itemList.begin();

	while (it != itemList.end())
	{
		AvatarSelectorWidgetItem *item = static_cast<AvatarSelectorWidgetItem*>(*it);
		if (item->avatarEntry().path == path)
		{
			item->setSelected(true);
			listSelectionChanged( item );
			return;
		}
		++it;
	}

}

void AvatarSelectorWidget::buttonAddAvatarClicked()
{
	KUrl imageUrl = KFileDialog::getImageOpenUrl( KUrl(), this );
	if( !imageUrl.isEmpty() )
	{
		// TODO: Download image
		if( !imageUrl.isLocalFile() )
			return;

		QPixmap pixmap( imageUrl.path() );
		if ( pixmap.isNull() )
			return;

		// Crop the image
		QImage avatar = KPixmapRegionSelectorDialog::getSelectedImage( pixmap, 96, 96, this );

		QString imageName = imageUrl.fileName();

		Kopete::AvatarManager::AvatarEntry newEntry;
		// Remove extension from filename
		newEntry.name = imageName.left( imageName.lastIndexOf('.') );
		newEntry.image = avatar;
		newEntry.category = Kopete::AvatarManager::User;

		Kopete::AvatarManager::AvatarEntry addedEntry = Kopete::AvatarManager::self()->add( newEntry );
		if( addedEntry.path.isEmpty() )
		{
			//TODO add a real error message
			//d->mainWidget.labelErrorMessage->setText( i18n("Kopete cannot add this new avatar because it could not save the avatar image in user directory.") );
			return;
		}

		// select the added entry and show the user tab
		QList<QListWidgetItem *> foundItems = d->mainWidget.listUserAvatar->findItems( addedEntry.name, Qt::MatchContains );
		if( !foundItems.isEmpty() )
		{
			AvatarSelectorWidgetItem *item = dynamic_cast<AvatarSelectorWidgetItem*>( foundItems.first() );
			if ( !item )
				return;
			item->setSelected( true );
		}

	}
}

void AvatarSelectorWidget::buttonRemoveAvatarClicked()
{
	// if no item was selected, just exit
	if ( !d->mainWidget.listUserAvatar->selectedItems().count() )
		return;

	AvatarSelectorWidgetItem *selectedItem = dynamic_cast<AvatarSelectorWidgetItem*>( d->mainWidget.listUserAvatar->selectedItems().first() );
	if( selectedItem )
	{
		if ( selectedItem != d->noAvatarItem )
		{
			if( !Kopete::AvatarManager::self()->remove( selectedItem->avatarEntry() ) )
			{
				kDebug(14010) << "Removing of avatar failed for unknown reason.";
			}
		}
	}
}

void AvatarSelectorWidget::queryJobFinished(KJob *job)
{
	Kopete::AvatarQueryJob *queryJob = static_cast<Kopete::AvatarQueryJob*>(job);
	if( !queryJob->error() )
	{
		QList<Kopete::AvatarManager::AvatarEntry> avatarList = queryJob->avatarList();
		Kopete::AvatarManager::AvatarEntry entry;
		foreach(entry, avatarList)
		{
			d->addItem(entry);
		}
	}
	else
	{
		//TODO add a real error message
		//d->mainWidget.labelErrorMessage->setText( queryJob->errorText() );
	}
}

void AvatarSelectorWidget::avatarAdded(Kopete::AvatarManager::AvatarEntry newEntry)
{
	d->addItem(newEntry);
}

void AvatarSelectorWidget::avatarRemoved(Kopete::AvatarManager::AvatarEntry entryRemoved)
{
	// Same here, avatar can be only removed from listUserAvatar
	foreach(QListWidgetItem *item, d->mainWidget.listUserAvatar->findItems("",Qt::MatchContains))
	{
		// checks if this is the right item
		AvatarSelectorWidgetItem *avatar = dynamic_cast<AvatarSelectorWidgetItem*>(item);
		if (!avatar || avatar->avatarEntry().name != entryRemoved.name)
		    continue;

		kDebug(14010) << "Removing " << entryRemoved.name << " from list.";

		int deletedRow = d->mainWidget.listUserAvatar->row( item );
		QListWidgetItem *removedItem = d->mainWidget.listUserAvatar->takeItem( deletedRow );
		delete removedItem;

		int newRow = --deletedRow;
		if( newRow < 0 )
			newRow = 0;

		// Select the previous avatar in the list, thus selecting a new avatar
		// and deselecting the avatar being removed.
		d->mainWidget.listUserAvatar->setCurrentRow( newRow );
		// Force update
		listSelectionChanged( d->mainWidget.listUserAvatar->item(newRow) );
	}
}

void AvatarSelectorWidget::listSelectionChanged(QListWidgetItem *item)
{
	d->mainWidget.buttonRemoveAvatar->setEnabled( item != d->noAvatarItem );
	d->selectedItem = item;
}

AvatarSelectorWidgetItem * AvatarSelectorWidget::Private::addItem(Kopete::AvatarManager::AvatarEntry entry)
{
	kDebug(14010) << "Entry(" << entry.name << "): " << entry.category;

	// only use User avatars
	if( !(entry.category & Kopete::AvatarManager::User) )
	    return 0;

	AvatarSelectorWidgetItem *item = new AvatarSelectorWidgetItem(mainWidget.listUserAvatar);
	item->setAvatarEntry(entry);
	if (entry.path == currentAvatar)
		item->setSelected(true);
	return item;
}

} // Namespace Kopete::UI

} // Namespace Kopete

#include "avatarselectorwidget.moc"
#endif // LIBKOPETE_UI/AVATARSELECTORWIDGET_CPP
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <gtest/gtest.h>
#include <arrayfire.h>
#include <vector>
#include <complex>
#include <testHelpers.hpp>

using namespace af;
using namespace std;

TEST(GettingStarted, SNIPPET_getting_started_gen)
{

    //! [ex_getting_started_gen]
    // Generate an array of size three filled with zeros.
    // If no data type is specified, ArrayFire defaults to f32.
    // The af::constant function generates the data on the device.
    array zeros      = constant(0, 3);

    // Generate a 1x4 array of uniformly distributed [0,1] random numbers
    // The af::randu function generates the data on the device.
    array rand1      = randu(1, 4);

    // Generate a 2x2 array (or matrix, if you prefer) of random numbers
    // sampled from a normal distribution.
    // The af::randn function generates data on the device.
    array rand2      = randn(2, 2);

    // Generate a 3x3 identity matrix. The data is generated on the device.
    array iden       = af::identity(3, 3);

    // Lastly, create a 2x1 array (column vector) of uniformly distributed
    // 32-bit complex numbers (c32 data type):
    array randcplx   = randu(2, 1, c32);
    //! [ex_getting_started_gen]

    {
        vector<float> output;
        output.resize(zeros.elements());
        zeros.host(&output.front());
        ASSERT_EQ(f32, zeros.type());
        for(unsigned i = 0; i < zeros.elements(); i++) ASSERT_FLOAT_EQ(0, output[i]);
    }

    if (!noDoubleTests<double>()) {
        array ones       = constant(1, 3, 2, f64);
        vector<double> output(ones.elements());
        ones.host(&output.front());
        ASSERT_EQ(f64, ones.type());
        for(unsigned i = 0; i < ones.elements(); i++) ASSERT_FLOAT_EQ(1, output[i]);
    }

    {
        vector<float> output;
        output.resize(iden.elements());
        iden.host(&output.front());
        for(unsigned i = 0; i < iden.dims(0); i++)
            for(unsigned j = 0; j < iden.dims(1); j++)
                if(i == j)  ASSERT_FLOAT_EQ(1, output[i * iden.dims(0) + j]);
                else        ASSERT_FLOAT_EQ(0, output[i * iden.dims(0) + j]);
    }
}

TEST(GettingStarted, SNIPPET_getting_started_init)
{
    //! [ex_getting_started_init]
    // Create a six-element array on the host
    float hA[] = {0, 1, 2, 3, 4, 5};

    // Which can be copied into an ArrayFire Array using the pointer copy
    // constructor. Here we copy the data into a 2x3 matrix:
    array A(2, 3, hA);

    // ArrayFire provides a convenince function for printing af::array
    // objects in case you wish to see how the data is stored:
    af_print(A);

    // This technique can also be used to populate an array with complex
    // data (stored in {{real, imaginary}, {real, imaginary},  ... } format
    // as found in C's complex.h and C++'s <complex>.
    // Below we create a 3x1 column vector of complex data values:
    std::vector< std::complex<float> > hB(A.elements());
    array a(&hB.front()); // 3x1 column vector of complex numbers

    //! [ex_getting_started_init]

    vector<float> out(A.elements());
    A.host(&out.front());
    for(unsigned int i = 0; i < out.size(); i++) ASSERT_FLOAT_EQ(hA[i], out[i]);
}

TEST(GettingStarted, SNIPPET_getting_started_print)
{
    //! [ex_getting_started_print]
    // Generate two arrays
    array a = randu(2, 2);
    array b = constant(1, 2, 1);

    // Print them to the console using af_print
    af_print(a);
    af_print(b);

    // Print the results of an expression involving arrays:
    af_print(a.col(0) + b + .4);
    //! [ex_getting_started_print]
    array result = a.col(0) + b + 0.4;
    vector<float> outa(a.elements());
    vector<float> outb(b.elements());
    vector<float> out(result.elements());

    a.host(&outa.front());
    b.host(&outb.front());
    result.host(&out.front());

    for(unsigned i = 0; i < outb.size(); i++) ASSERT_FLOAT_EQ(outa[i] + outb[i] + 0.4, out[i]);
}

TEST(GettingStarted, SNIPPET_getting_started_dims)
{
    //! [ex_getting_started_dims]
    // Create a 4x5x2 array of uniformly distributed random numbers
    array a = randu(4,5,2);
    // Determine the number of dimensions using the numdims() function:
    printf("numdims(a)  %d\n",  a.numdims()); // 3

    // We can also find the size of the individual dimentions using either
    // the `dims` function:
    printf("dims = [%lld %lld]\n", a.dims(0), a.dims(1)); // 4,5

    // Or the elements of a af::dim4 object:
    dim4 dims = a.dims();
    printf("dims = [%lld %lld]\n", dims[0], dims[1]); // 4,5
    //! [ex_getting_started_dims]

    //! [ex_getting_started_prop]
    // Get the type stored in the array. This will be one of the many
    // `af_dtype`s presented above:
    printf("underlying type: %d\n", a.type());

    // Arrays also have several conveience functions to determine if
    // an Array contains complex or real values:
    printf("is complex? %d    is real? %d\n", a.iscomplex(), a.isreal());

    // if it is a column or row vector
    printf("is vector? %d  column? %d  row? %d\n", a.isvector(), a.iscolumn(), a.isrow());

    // and whether or not the array is empty and how much memory it takes on
    // the device:
    printf("empty? %d  total elements: %lld  bytes: %lu\n", a.isempty(), a.elements(), a.bytes());
    //! [ex_getting_started_prop]

    ASSERT_EQ(f32, a.type());
    ASSERT_TRUE(a.isreal());
    ASSERT_FALSE(a.iscomplex());
    ASSERT_FALSE(a.isvector());
    ASSERT_FALSE(a.iscolumn());
    ASSERT_FALSE(a.isrow());
    ASSERT_FALSE(a.isempty());
    ASSERT_EQ(40, a.elements());

    ASSERT_EQ(f32, a.type());
    ASSERT_EQ(f32, a.type());

    ASSERT_EQ(4, dims[0]);
    ASSERT_EQ(4, a.dims(0));
    ASSERT_EQ(5, dims[1]);
    ASSERT_EQ(5, a.dims(1));
}

TEST(GettingStarted, SNIPPET_getting_started_arith)
{
    //! [ex_getting_started_arith]
    array R = randu(3, 3);
    af_print(constant(1, 3, 3) + af::complex(sin(R)));  // will be c32

    // rescale complex values to unit circle
    array a = randn(5, c32);
    af_print(a / abs(a));

    // calculate L2 norm of vectors
    array X = randn(3, 4);
    af_print(sqrt(sum(pow(X, 2))));     // norm of every column vector
    af_print(sqrt(sum(pow(X, 2), 0)));  // same as above
    af_print(sqrt(sum(pow(X, 2), 1)));  // norm of every row vector
    //! [ex_getting_started_arith]
}

TEST(GettingStarted, SNIPPET_getting_started_dev_ptr)
{
#ifdef __CUDACC__
    //! [ex_getting_started_dev_ptr]
    // Create an array on the host, copy it into an ArrayFire 2x3 ArrayFire array
    float host_ptr[] = {0,1,2,3,4,5};
    array a(2, 3, host_ptr);

    // Create a CUDA device pointer, populate it with data from the host
    float *device_ptr;
    cudaMalloc((void**)&device_ptr, 6*sizeof(float));
    cudaMemcpy(device_ptr, host_ptr, 6*sizeof(float), cudaMemcpyHostToDevice);

    // Convert the CUDA-allocated device memory into an ArrayFire array:
    array b(2,3, device_ptr, afDevice); // Note: afDevice (default: afHost)
    // Note that ArrayFire takes ownership over `device_ptr`, so memory will
    // be freed when `b` id destructed. Do not call cudaFree(device_ptr)!

    //! [ex_getting_started_dev_ptr]
#endif //__CUDACC__
}

TEST(GettingStarted, SNIPPET_getting_started_ptr)
{
#ifdef __CUDACC__
    //! [ex_getting_started_ptr]
    // Create an array consisting of 3 random numbers
    array a = randu(3, f32);

    // Copy an array on the device to the host:
    float * host_a = a.host<float>();
    // access the host data as a normal array
    printf("host_a[2] = %g\n", host_a[2]);  // last element
    // and free memory using delete:
    delete[] host_a;

    // Get access to the device memory for a CUDA kernel
    float * d_cuda = a.device<float>();    // no need to free this
    float value;
    cudaMemcpy(&value, d_cuda + 2, sizeof(float), cudaMemcpyDeviceToHost);
    printf("d_cuda[2] = %g\n", value);
    a.unlock(); // unlock to allow garbage collection if necessary

    // Because OpenCL uses references rather than pointers, accessing memory
    // is similar, but has a somewhat clunky syntax. For the C-API
    cl_mem d_opencl = (cl_mem) a.device<float>();
    // for the C++ API, you can just wrap this object into a cl::Buffer
    // after calling clRetainMemObject.

    //! [ex_getting_started_ptr]
#endif //__CUDACC__
}

TEST(GettingStarted, SNIPPET_getting_started_scalar)
{
    //! [ex_getting_started_scalar]
    array a = randu(3);
    float val = a.scalar<float>();
    printf("scalar value: %g\n", val);
    //! [ex_getting_started_scalar]
}

TEST(GettingStarted, SNIPPET_getting_started_bit)
{
    //! [ex_getting_started_bit]
    int h_A[] = {1, 1, 0, 0, 4, 0, 0, 2, 0};
    int h_B[] = {1, 0, 1, 0, 1, 0, 1, 1, 1};
    array A = array(3, 3, h_A), B = array(3, 3, h_B);
    af_print(A); af_print(B);

    array A_and_B = A & B; af_print(A_and_B);
    array  A_or_B = A | B; af_print(A_or_B);
    array A_xor_B = A ^ B; af_print(A_xor_B);
    //! [ex_getting_started_bit]

    vector<int> Andout(A_and_B.elements());
    vector<int> Orout(A_or_B.elements());
    vector<int> Xorout(A_xor_B.elements());
    A_and_B.host(&Andout.front());
    A_or_B.host(&Orout.front());
    A_xor_B.host(&Xorout.front());

    for(unsigned int i = 0; i < Andout.size(); i++) ASSERT_FLOAT_EQ(h_A[i] & h_B[i], Andout[i]);
    for(unsigned int i = 0; i < Orout.size(); i++)  ASSERT_FLOAT_EQ(h_A[i] | h_B[i], Orout[i]);
    for(unsigned int i = 0; i < Xorout.size(); i++) ASSERT_FLOAT_EQ(h_A[i] ^ h_B[i], Xorout[i]);
}

TEST(GettingStarted, SNIPPET_getting_started_constants)
{
    //! [ex_getting_started_constants]
    array A = randu(5,5);
    A(where(A > .5)) = af::NaN;

    array x = randu(10e6), y = randu(10e6);
    double pi_est = 4 * sum<float>(hypot(x,y) < 1) / 10e6;
    printf("estimation error: %g\n", fabs(Pi - pi_est));
    //! [ex_getting_started_constants]

    ASSERT_LE(fabs(Pi-pi_est), 0.005);
}

<commit_msg>Fix incorrect array construction.<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <gtest/gtest.h>
#include <arrayfire.h>
#include <vector>
#include <complex>
#include <testHelpers.hpp>

using namespace af;
using namespace std;

TEST(GettingStarted, SNIPPET_getting_started_gen)
{

    //! [ex_getting_started_gen]
    // Generate an array of size three filled with zeros.
    // If no data type is specified, ArrayFire defaults to f32.
    // The af::constant function generates the data on the device.
    array zeros      = constant(0, 3);

    // Generate a 1x4 array of uniformly distributed [0,1] random numbers
    // The af::randu function generates the data on the device.
    array rand1      = randu(1, 4);

    // Generate a 2x2 array (or matrix, if you prefer) of random numbers
    // sampled from a normal distribution.
    // The af::randn function generates data on the device.
    array rand2      = randn(2, 2);

    // Generate a 3x3 identity matrix. The data is generated on the device.
    array iden       = af::identity(3, 3);

    // Lastly, create a 2x1 array (column vector) of uniformly distributed
    // 32-bit complex numbers (c32 data type):
    array randcplx   = randu(2, 1, c32);
    //! [ex_getting_started_gen]

    {
        vector<float> output;
        output.resize(zeros.elements());
        zeros.host(&output.front());
        ASSERT_EQ(f32, zeros.type());
        for(unsigned i = 0; i < zeros.elements(); i++) ASSERT_FLOAT_EQ(0, output[i]);
    }

    if (!noDoubleTests<double>()) {
        array ones       = constant(1, 3, 2, f64);
        vector<double> output(ones.elements());
        ones.host(&output.front());
        ASSERT_EQ(f64, ones.type());
        for(unsigned i = 0; i < ones.elements(); i++) ASSERT_FLOAT_EQ(1, output[i]);
    }

    {
        vector<float> output;
        output.resize(iden.elements());
        iden.host(&output.front());
        for(unsigned i = 0; i < iden.dims(0); i++)
            for(unsigned j = 0; j < iden.dims(1); j++)
                if(i == j)  ASSERT_FLOAT_EQ(1, output[i * iden.dims(0) + j]);
                else        ASSERT_FLOAT_EQ(0, output[i * iden.dims(0) + j]);
    }
}

TEST(GettingStarted, SNIPPET_getting_started_init)
{
    //! [ex_getting_started_init]
    // Create a six-element array on the host
    float hA[] = {0, 1, 2, 3, 4, 5};

    // Which can be copied into an ArrayFire Array using the pointer copy
    // constructor. Here we copy the data into a 2x3 matrix:
    array A(2, 3, hA);

    // ArrayFire provides a convenince function for printing af::array
    // objects in case you wish to see how the data is stored:
    af_print(A);

    // This technique can also be used to populate an array with complex
    // data (stored in {{real, imaginary}, {real, imaginary},  ... } format
    // as found in C's complex.h and C++'s <complex>.
    // Below we create a 3x1 column vector of complex data values:
    std::vector< std::complex<float> > hB(A.elements());
    array dB(3, 1, &hB[0]); // 3x1 column vector of complex numbers

    //! [ex_getting_started_init]

    vector<float> out(A.elements());
    A.host(&out.front());
    for(unsigned int i = 0; i < out.size(); i++) ASSERT_FLOAT_EQ(hA[i], out[i]);
}

TEST(GettingStarted, SNIPPET_getting_started_print)
{
    //! [ex_getting_started_print]
    // Generate two arrays
    array a = randu(2, 2);
    array b = constant(1, 2, 1);

    // Print them to the console using af_print
    af_print(a);
    af_print(b);

    // Print the results of an expression involving arrays:
    af_print(a.col(0) + b + .4);
    //! [ex_getting_started_print]
    array result = a.col(0) + b + 0.4;
    vector<float> outa(a.elements());
    vector<float> outb(b.elements());
    vector<float> out(result.elements());

    a.host(&outa.front());
    b.host(&outb.front());
    result.host(&out.front());

    for(unsigned i = 0; i < outb.size(); i++) ASSERT_FLOAT_EQ(outa[i] + outb[i] + 0.4, out[i]);
}

TEST(GettingStarted, SNIPPET_getting_started_dims)
{
    //! [ex_getting_started_dims]
    // Create a 4x5x2 array of uniformly distributed random numbers
    array a = randu(4,5,2);
    // Determine the number of dimensions using the numdims() function:
    printf("numdims(a)  %d\n",  a.numdims()); // 3

    // We can also find the size of the individual dimentions using either
    // the `dims` function:
    printf("dims = [%lld %lld]\n", a.dims(0), a.dims(1)); // 4,5

    // Or the elements of a af::dim4 object:
    dim4 dims = a.dims();
    printf("dims = [%lld %lld]\n", dims[0], dims[1]); // 4,5
    //! [ex_getting_started_dims]

    //! [ex_getting_started_prop]
    // Get the type stored in the array. This will be one of the many
    // `af_dtype`s presented above:
    printf("underlying type: %d\n", a.type());

    // Arrays also have several conveience functions to determine if
    // an Array contains complex or real values:
    printf("is complex? %d    is real? %d\n", a.iscomplex(), a.isreal());

    // if it is a column or row vector
    printf("is vector? %d  column? %d  row? %d\n", a.isvector(), a.iscolumn(), a.isrow());

    // and whether or not the array is empty and how much memory it takes on
    // the device:
    printf("empty? %d  total elements: %lld  bytes: %lu\n", a.isempty(), a.elements(), a.bytes());
    //! [ex_getting_started_prop]

    ASSERT_EQ(f32, a.type());
    ASSERT_TRUE(a.isreal());
    ASSERT_FALSE(a.iscomplex());
    ASSERT_FALSE(a.isvector());
    ASSERT_FALSE(a.iscolumn());
    ASSERT_FALSE(a.isrow());
    ASSERT_FALSE(a.isempty());
    ASSERT_EQ(40, a.elements());

    ASSERT_EQ(f32, a.type());
    ASSERT_EQ(f32, a.type());

    ASSERT_EQ(4, dims[0]);
    ASSERT_EQ(4, a.dims(0));
    ASSERT_EQ(5, dims[1]);
    ASSERT_EQ(5, a.dims(1));
}

TEST(GettingStarted, SNIPPET_getting_started_arith)
{
    //! [ex_getting_started_arith]
    array R = randu(3, 3);
    af_print(constant(1, 3, 3) + af::complex(sin(R)));  // will be c32

    // rescale complex values to unit circle
    array a = randn(5, c32);
    af_print(a / abs(a));

    // calculate L2 norm of vectors
    array X = randn(3, 4);
    af_print(sqrt(sum(pow(X, 2))));     // norm of every column vector
    af_print(sqrt(sum(pow(X, 2), 0)));  // same as above
    af_print(sqrt(sum(pow(X, 2), 1)));  // norm of every row vector
    //! [ex_getting_started_arith]
}

TEST(GettingStarted, SNIPPET_getting_started_dev_ptr)
{
#ifdef __CUDACC__
    //! [ex_getting_started_dev_ptr]
    // Create an array on the host, copy it into an ArrayFire 2x3 ArrayFire array
    float host_ptr[] = {0,1,2,3,4,5};
    array a(2, 3, host_ptr);

    // Create a CUDA device pointer, populate it with data from the host
    float *device_ptr;
    cudaMalloc((void**)&device_ptr, 6*sizeof(float));
    cudaMemcpy(device_ptr, host_ptr, 6*sizeof(float), cudaMemcpyHostToDevice);

    // Convert the CUDA-allocated device memory into an ArrayFire array:
    array b(2,3, device_ptr, afDevice); // Note: afDevice (default: afHost)
    // Note that ArrayFire takes ownership over `device_ptr`, so memory will
    // be freed when `b` id destructed. Do not call cudaFree(device_ptr)!

    //! [ex_getting_started_dev_ptr]
#endif //__CUDACC__
}

TEST(GettingStarted, SNIPPET_getting_started_ptr)
{
#ifdef __CUDACC__
    //! [ex_getting_started_ptr]
    // Create an array consisting of 3 random numbers
    array a = randu(3, f32);

    // Copy an array on the device to the host:
    float * host_a = a.host<float>();
    // access the host data as a normal array
    printf("host_a[2] = %g\n", host_a[2]);  // last element
    // and free memory using delete:
    delete[] host_a;

    // Get access to the device memory for a CUDA kernel
    float * d_cuda = a.device<float>();    // no need to free this
    float value;
    cudaMemcpy(&value, d_cuda + 2, sizeof(float), cudaMemcpyDeviceToHost);
    printf("d_cuda[2] = %g\n", value);
    a.unlock(); // unlock to allow garbage collection if necessary

    // Because OpenCL uses references rather than pointers, accessing memory
    // is similar, but has a somewhat clunky syntax. For the C-API
    cl_mem d_opencl = (cl_mem) a.device<float>();
    // for the C++ API, you can just wrap this object into a cl::Buffer
    // after calling clRetainMemObject.

    //! [ex_getting_started_ptr]
#endif //__CUDACC__
}

TEST(GettingStarted, SNIPPET_getting_started_scalar)
{
    //! [ex_getting_started_scalar]
    array a = randu(3);
    float val = a.scalar<float>();
    printf("scalar value: %g\n", val);
    //! [ex_getting_started_scalar]
}

TEST(GettingStarted, SNIPPET_getting_started_bit)
{
    //! [ex_getting_started_bit]
    int h_A[] = {1, 1, 0, 0, 4, 0, 0, 2, 0};
    int h_B[] = {1, 0, 1, 0, 1, 0, 1, 1, 1};
    array A = array(3, 3, h_A), B = array(3, 3, h_B);
    af_print(A); af_print(B);

    array A_and_B = A & B; af_print(A_and_B);
    array  A_or_B = A | B; af_print(A_or_B);
    array A_xor_B = A ^ B; af_print(A_xor_B);
    //! [ex_getting_started_bit]

    vector<int> Andout(A_and_B.elements());
    vector<int> Orout(A_or_B.elements());
    vector<int> Xorout(A_xor_B.elements());
    A_and_B.host(&Andout.front());
    A_or_B.host(&Orout.front());
    A_xor_B.host(&Xorout.front());

    for(unsigned int i = 0; i < Andout.size(); i++) ASSERT_FLOAT_EQ(h_A[i] & h_B[i], Andout[i]);
    for(unsigned int i = 0; i < Orout.size(); i++)  ASSERT_FLOAT_EQ(h_A[i] | h_B[i], Orout[i]);
    for(unsigned int i = 0; i < Xorout.size(); i++) ASSERT_FLOAT_EQ(h_A[i] ^ h_B[i], Xorout[i]);
}

TEST(GettingStarted, SNIPPET_getting_started_constants)
{
    //! [ex_getting_started_constants]
    array A = randu(5,5);
    A(where(A > .5)) = af::NaN;

    array x = randu(10e6), y = randu(10e6);
    double pi_est = 4 * sum<float>(hypot(x,y) < 1) / 10e6;
    printf("estimation error: %g\n", fabs(Pi - pi_est));
    //! [ex_getting_started_constants]

    ASSERT_LE(fabs(Pi-pi_est), 0.005);
}

<|endoftext|>


<commit_before>/*******************************************************************************
 * libproxy - A library for proxy configuration
 * Copyright (C) 2006 Nathaniel McCallum <nathaniel@natemccallum.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 ******************************************************************************/

#include "../extension_pacrunner.hpp"
using namespace libproxy;

#ifdef APPLE
// JavaScriptCore.h requires CoreFoundation
// This is only found on Mac OS X
#include <JavaScriptCore/JavaScriptCore.h>
#else
#include <JavaScriptCore/JavaScript.h>
#endif
#include "pacutils.h"

#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif

#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif

static char *jstr2str(JSStringRef str, bool release) throw (bad_alloc)
{
	char *tmp = new char[JSStringGetMaximumUTF8CStringSize(str)+1];
	JSStringGetUTF8CString(str, tmp, JSStringGetMaximumUTF8CStringSize(str)+1);
	if (release) JSStringRelease(str);
	return tmp;
}

static JSValueRef dnsResolve(JSContextRef ctx, JSObjectRef /*func*/, JSObjectRef /*self*/, size_t argc, const JSValueRef argv[], JSValueRef* /*exception*/)
{
	if (argc != 1)                         return NULL;
	if (!JSValueIsString(ctx, argv[0]))    return NULL;

	// Get hostname argument
	char *tmp = jstr2str(JSValueToStringCopy(ctx, argv[0], NULL), true);

	// Look it up
	struct addrinfo *info;
	if (getaddrinfo(tmp, NULL, NULL, &info))
		return NULL;
	delete tmp;

	// Try for IPv4
	tmp = new char[INET6_ADDRSTRLEN+1];
	if (getnameinfo(info->ai_addr, info->ai_addrlen,
					tmp, INET6_ADDRSTRLEN+1,
					NULL, 0,
					NI_NUMERICHOST)) {
			freeaddrinfo(info);
			delete tmp;
			return NULL;
		}
	freeaddrinfo(info);

	// Create the return value
	JSStringRef str = JSStringCreateWithUTF8CString(tmp);
	JSValueRef  ret = JSValueMakeString(ctx, str);
	JSStringRelease(str);
	delete tmp;

	return ret;
}

static JSValueRef myIpAddress(JSContextRef ctx, JSObjectRef func, JSObjectRef self, size_t /*argc*/, const JSValueRef[] /*argv*/, JSValueRef* /*exception*/)
{
	char hostname[1024];
	if (!gethostname(hostname, 1023)) {
		JSStringRef str = JSStringCreateWithUTF8CString(hostname);
		JSValueRef  val = JSValueMakeString(ctx, str);
		JSStringRelease(str);
		JSValueRef ip = dnsResolve(ctx, func, self, 1, &val, NULL);
		return ip;
	}
	return NULL;
}

class webkit_pacrunner : public pacrunner {
public:
	~webkit_pacrunner() {
		JSGarbageCollect(this->jsctx);
		JSGlobalContextRelease(this->jsctx);
	}

	webkit_pacrunner(string pac, const url& pacurl) throw (bad_alloc) : pacrunner(pac, pacurl) {
		JSStringRef str  = NULL;
		JSObjectRef func = NULL;

		// Create the basic context
		if (!(this->jsctx = JSGlobalContextCreate(NULL))) goto error;

		// Add dnsResolve into the context
		str = JSStringCreateWithUTF8CString("dnsResolve");
		func = JSObjectMakeFunctionWithCallback(this->jsctx, str, dnsResolve);
		JSObjectSetProperty(this->jsctx, JSContextGetGlobalObject(this->jsctx), str, func, kJSPropertyAttributeNone, NULL);
		JSStringRelease(str);

		// Add myIpAddress into the context
		str = JSStringCreateWithUTF8CString("myIpAddress");
		func = JSObjectMakeFunctionWithCallback(this->jsctx, str, myIpAddress);
		JSObjectSetProperty(this->jsctx, JSContextGetGlobalObject(this->jsctx), str, func, kJSPropertyAttributeNone, NULL);
		JSStringRelease(str);

		// Add all other routines into the context
		str = JSStringCreateWithUTF8CString(JAVASCRIPT_ROUTINES);
		if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL)) goto error;
		JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL);
		JSStringRelease(str);

		// Add the PAC into the context
		str = JSStringCreateWithUTF8CString(pac.c_str());
		if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL)) goto error;
		JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL);
		JSStringRelease(str);
		return;

	error:
		if (str) JSStringRelease(str);
		if (this->jsctx) {
			JSGarbageCollect(this->jsctx);
			JSGlobalContextRelease(this->jsctx);
		}
		throw bad_alloc();
	}

	string run(const url& url_) throw (bad_alloc) {
		JSStringRef str = NULL;
		JSValueRef  val = NULL;
		string      tmp;

		// Run the PAC
		tmp = string("FindProxyForURL(\"") + url_.to_string() + string("\", \"") + url_.get_host() + "\");";
		str = JSStringCreateWithUTF8CString(tmp.c_str());
		if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL))            goto error;
		if (!(val = JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL))) goto error;
		if (!JSValueIsString(this->jsctx, val))                               goto error;
		JSStringRelease(str);

		// Convert the return value to a string
		return jstr2str(JSValueToStringCopy(this->jsctx, val, NULL), true);

	error:
		if (str) JSStringRelease(str);
		throw bad_alloc();
	}

private:
	JSGlobalContextRef jsctx;
};

PX_PACRUNNER_MODULE_EZ(webkit, "JSObjectMakeFunctionWithCallback", "webkit");
<commit_msg>fix the webkit mac fix :)<commit_after>/*******************************************************************************
 * libproxy - A library for proxy configuration
 * Copyright (C) 2006 Nathaniel McCallum <nathaniel@natemccallum.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 ******************************************************************************/

#include "../extension_pacrunner.hpp"
using namespace libproxy;

#ifdef __APPLE__
// JavaScriptCore.h requires CoreFoundation
// This is only found on Mac OS X
#include <JavaScriptCore/JavaScriptCore.h>
#else
#include <JavaScriptCore/JavaScript.h>
#endif
#include "pacutils.h"

#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif

#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif

static char *jstr2str(JSStringRef str, bool release) throw (bad_alloc)
{
	char *tmp = new char[JSStringGetMaximumUTF8CStringSize(str)+1];
	JSStringGetUTF8CString(str, tmp, JSStringGetMaximumUTF8CStringSize(str)+1);
	if (release) JSStringRelease(str);
	return tmp;
}

static JSValueRef dnsResolve(JSContextRef ctx, JSObjectRef /*func*/, JSObjectRef /*self*/, size_t argc, const JSValueRef argv[], JSValueRef* /*exception*/)
{
	if (argc != 1)                         return NULL;
	if (!JSValueIsString(ctx, argv[0]))    return NULL;

	// Get hostname argument
	char *tmp = jstr2str(JSValueToStringCopy(ctx, argv[0], NULL), true);

	// Look it up
	struct addrinfo *info;
	if (getaddrinfo(tmp, NULL, NULL, &info))
		return NULL;
	delete tmp;

	// Try for IPv4
	tmp = new char[INET6_ADDRSTRLEN+1];
	if (getnameinfo(info->ai_addr, info->ai_addrlen,
					tmp, INET6_ADDRSTRLEN+1,
					NULL, 0,
					NI_NUMERICHOST)) {
			freeaddrinfo(info);
			delete tmp;
			return NULL;
		}
	freeaddrinfo(info);

	// Create the return value
	JSStringRef str = JSStringCreateWithUTF8CString(tmp);
	JSValueRef  ret = JSValueMakeString(ctx, str);
	JSStringRelease(str);
	delete tmp;

	return ret;
}

static JSValueRef myIpAddress(JSContextRef ctx, JSObjectRef func, JSObjectRef self, size_t /*argc*/, const JSValueRef[] /*argv*/, JSValueRef* /*exception*/)
{
	char hostname[1024];
	if (!gethostname(hostname, 1023)) {
		JSStringRef str = JSStringCreateWithUTF8CString(hostname);
		JSValueRef  val = JSValueMakeString(ctx, str);
		JSStringRelease(str);
		JSValueRef ip = dnsResolve(ctx, func, self, 1, &val, NULL);
		return ip;
	}
	return NULL;
}

class webkit_pacrunner : public pacrunner {
public:
	~webkit_pacrunner() {
		JSGarbageCollect(this->jsctx);
		JSGlobalContextRelease(this->jsctx);
	}

	webkit_pacrunner(string pac, const url& pacurl) throw (bad_alloc) : pacrunner(pac, pacurl) {
		JSStringRef str  = NULL;
		JSObjectRef func = NULL;

		// Create the basic context
		if (!(this->jsctx = JSGlobalContextCreate(NULL))) goto error;

		// Add dnsResolve into the context
		str = JSStringCreateWithUTF8CString("dnsResolve");
		func = JSObjectMakeFunctionWithCallback(this->jsctx, str, dnsResolve);
		JSObjectSetProperty(this->jsctx, JSContextGetGlobalObject(this->jsctx), str, func, kJSPropertyAttributeNone, NULL);
		JSStringRelease(str);

		// Add myIpAddress into the context
		str = JSStringCreateWithUTF8CString("myIpAddress");
		func = JSObjectMakeFunctionWithCallback(this->jsctx, str, myIpAddress);
		JSObjectSetProperty(this->jsctx, JSContextGetGlobalObject(this->jsctx), str, func, kJSPropertyAttributeNone, NULL);
		JSStringRelease(str);

		// Add all other routines into the context
		str = JSStringCreateWithUTF8CString(JAVASCRIPT_ROUTINES);
		if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL)) goto error;
		JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL);
		JSStringRelease(str);

		// Add the PAC into the context
		str = JSStringCreateWithUTF8CString(pac.c_str());
		if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL)) goto error;
		JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL);
		JSStringRelease(str);
		return;

	error:
		if (str) JSStringRelease(str);
		if (this->jsctx) {
			JSGarbageCollect(this->jsctx);
			JSGlobalContextRelease(this->jsctx);
		}
		throw bad_alloc();
	}

	string run(const url& url_) throw (bad_alloc) {
		JSStringRef str = NULL;
		JSValueRef  val = NULL;
		string      tmp;

		// Run the PAC
		tmp = string("FindProxyForURL(\"") + url_.to_string() + string("\", \"") + url_.get_host() + "\");";
		str = JSStringCreateWithUTF8CString(tmp.c_str());
		if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL))            goto error;
		if (!(val = JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL))) goto error;
		if (!JSValueIsString(this->jsctx, val))                               goto error;
		JSStringRelease(str);

		// Convert the return value to a string
		return jstr2str(JSValueToStringCopy(this->jsctx, val, NULL), true);

	error:
		if (str) JSStringRelease(str);
		throw bad_alloc();
	}

private:
	JSGlobalContextRef jsctx;
};

PX_PACRUNNER_MODULE_EZ(webkit, "JSObjectMakeFunctionWithCallback", "webkit");
<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     mne_epoch_data_list.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     July, 2012
*
* @section  LICENSE
*
* Copyright (C) 2012, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief     Definition of the MNEEpochDataList Class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "mne_epoch_data_list.h"

#include <utils/mnemath.h>

//*************************************************************************************************************
//=============================================================================================================
// Qt INCLUDES
//=============================================================================================================

#include <QPointer>
#include <QtConcurrent>
#include <QDebug>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace FIFFLIB;
using namespace MNELIB;
using namespace UTILSLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

MNEEpochDataList::MNEEpochDataList()
{

}

//*************************************************************************************************************

MNEEpochDataList::~MNEEpochDataList()
{
//    MNEEpochDataList::iterator i;
//    for( i = this->begin(); i!=this->end(); ++i) {
//        if (*i)
//            delete (*i);
//    }
}

//*************************************************************************************************************

MNEEpochDataList MNEEpochDataList::readEpochs(const FiffRawData& raw,
                                              const MatrixXi& events,
                                              float tmin,
                                              float tmax,
                                              qint32 event,
                                              const QMap<QString,double>& mapReject,
                                              const QStringList& lExcludeChs,
                                              const RowVectorXi& picks)
{
    MNEEpochDataList data;

    // Select the desired events
    qint32 count = 0;
    qint32 p;
    MatrixXi selected = MatrixXi::Zero(1, events.rows());
    for (p = 0; p < events.rows(); ++p)
    {
        if (events(p,1) == 0 && events(p,2) == event)
        {
            selected(0,count) = p;
            ++count;
        }
    }
    selected.conservativeResize(1, count);
    if (count > 0) {
        printf("%d matching events found\n",count);
    } else {
        printf("No desired events found.\n");
        return MNEEpochDataList();
    }

    // If picks are empty, pick all
    RowVectorXi picksNew = picks;
    if(picks.cols() <= 0) {
        picksNew.resize(raw.info.chs.size());
        for(int i = 0; i < raw.info.chs.size(); ++i) {
            picksNew(i) = i;
        }
    }

    fiff_int_t event_samp, from, to;
    fiff_int_t dropCount = 0;
    MatrixXd timesDummy;
    MatrixXd times;

    MNEEpochData* epoch = Q_NULLPTR;

    for (p = 0; p < count; ++p) {
        // Read a data segment
        event_samp = events(selected(p),0);
        from = event_samp + tmin*raw.info.sfreq;
        to   = event_samp + floor(tmax*raw.info.sfreq + 0.5);

        epoch = new MNEEpochData();

        if(raw.read_raw_segment(epoch->epoch, timesDummy, from, to, picksNew)) {
            if (p == 0) {
                times.resize(1, to-from+1);
                for (qint32 i = 0; i < times.cols(); ++i)
                    times(0, i) = ((float)(from-event_samp+i)) / raw.info.sfreq;
            }

            epoch->event = event;
            epoch->tmin = tmin;
            epoch->tmax = tmax;

            epoch->bReject = checkForArtifact(epoch->epoch,
                                              raw.info,
                                              mapReject,
                                              lExcludeChs);

            if (epoch->bReject) {
                dropCount++;
            }

            //Check if data block has the same size as the previous one
            if(!data.isEmpty()) {
                if(epoch->epoch.size() == data.last()->epoch.size()) {
                    data.append(MNEEpochData::SPtr(epoch));//List takes ownwership of the pointer - no delete need
                }
            } else {
                data.append(MNEEpochData::SPtr(epoch));//List takes ownwership of the pointer - no delete need
            }
        } else {
            printf("Can't read the event data segments\n");
        }
    }

    qDebug() << "MNEEpochDataList::readEpochs - Read a total of"<< data.size() <<"epochs of type" << event << "and marked"<< dropCount <<"for rejection";

    return data;
}

//*************************************************************************************************************

FiffEvoked MNEEpochDataList::average(FiffInfo& info, fiff_int_t first, fiff_int_t last, VectorXi sel, bool proj)
{
    FiffEvoked p_evoked;

    printf("Calculate evoked... ");

    MatrixXd matAverage;

    if(this->size() > 0) {
        matAverage = MatrixXd::Zero(this->at(0)->epoch.rows(), this->at(0)->epoch.cols());
    } else {
        p_evoked.aspect_kind = FIFFV_ASPECT_STD_ERR;
        return p_evoked;
    }

    if(sel.size() > 0) {
        p_evoked.nave = sel.size();

        for(qint32 i = 0; i < sel.size(); ++i) {
            matAverage.array() += this->at(sel(i))->epoch.array();
        }
    } else {
        p_evoked.nave = this->size();

        for(qint32 i = 0; i < this->size(); ++i) {
            matAverage.array() += this->at(i)->epoch.array();
        }
    }
    matAverage.array() /= p_evoked.nave;

    printf("%d averages used [done]\n ", p_evoked.nave);

    p_evoked.setInfo(info, proj);

    p_evoked.aspect_kind = FIFFV_ASPECT_AVERAGE;

    p_evoked.first = first;
    p_evoked.last = last;

    p_evoked.times = RowVectorXf::LinSpaced(this->first()->epoch.cols(), this->first()->tmin, this->first()->tmax);

    p_evoked.comment = QString::number(this->at(0)->event);

    if(p_evoked.proj.rows() > 0) {
        matAverage = p_evoked.proj * matAverage;
        printf("\tSSP projectors applied to the evoked data\n");
    }

    p_evoked.data = matAverage;

    return p_evoked;
}

//*************************************************************************************************************

void MNEEpochDataList::applyBaselineCorrection(QPair<QVariant, QVariant>& baseline)
{
    // Run baseline correction
    QMutableListIterator<MNEEpochData::SPtr> i(*this);
    while (i.hasNext()) {
        i.next()->applyBaselineCorrection(baseline);
    }
}

//*************************************************************************************************************

void MNEEpochDataList::dropRejected()
{
    QMutableListIterator<MNEEpochData::SPtr> i(*this);
    while (i.hasNext()) {
        if (i.next()->bReject) {
            i.remove();
        }
    }
}

//*************************************************************************************************************

void MNEEpochDataList::pick_channels(const RowVectorXi& sel)
{
    QMutableListIterator<MNEEpochData::SPtr> i(*this);
    while (i.hasNext()) {
        i.next()->pick_channels(sel);
    }
}

//*************************************************************************************************************

bool MNEEpochDataList::checkForArtifact(const MatrixXd& data,
                                        const FiffInfo& pFiffInfo,
                                        const QMap<QString,double>& mapReject,
                                        const QStringList& lExcludeChs)
{
    //qDebug() << "MNEEpochDataList::checkForArtifact - Doing artifact reduction for" << mapReject;

    bool bReject = false;

    //Prepare concurrent data handling
    QList<ArtifactRejectionData> lchData;
    QList<int> lChTypes;

    if(mapReject.contains("grad") ||
       mapReject.contains("mag") ) {
        lChTypes << FIFFV_MEG_CH;
    }

    if(mapReject.contains("eeg")) {
        lChTypes << FIFFV_EEG_CH;
    }

    if(mapReject.contains("eog")) {
        lChTypes << FIFFV_EOG_CH;
    }

    if(lChTypes.isEmpty()) {
        return bReject;
    }

    for(int i = 0; i < pFiffInfo.chs.size(); ++i) {
        if(lChTypes.contains(pFiffInfo.chs.at(i).kind)
           && !lExcludeChs.contains(pFiffInfo.chs.at(i).ch_name)
           && !pFiffInfo.bads.contains(pFiffInfo.chs.at(i).ch_name)
           && pFiffInfo.chs.at(i).chpos.coil_type != FIFFV_COIL_BABY_REF_MAG
           && pFiffInfo.chs.at(i).chpos.coil_type != FIFFV_COIL_BABY_REF_MAG2) {
            ArtifactRejectionData tempData;
            tempData.data = data.row(i);

            switch (pFiffInfo.chs.at(i).kind) {
            case FIFFV_MEG_CH:
                if(pFiffInfo.chs.at(i).unit == FIFF_UNIT_T) {
                    tempData.dThreshold = mapReject["mag"];
                } else if(pFiffInfo.chs.at(i).unit == FIFF_UNIT_T_M) {
                    tempData.dThreshold = mapReject["grad"];
                }
            break;

            case FIFFV_EEG_CH:
                tempData.dThreshold = mapReject["eeg"];
            break;

            case FIFFV_EOG_CH:
                tempData.dThreshold = mapReject["eog"];
            break;
            }

            tempData.sChName = pFiffInfo.chs.at(i).ch_name;
            lchData.append(tempData);
        }
    }

    if(lchData.isEmpty()) {
        qDebug() << "MNEEpochDataList::checkForArtifact - No channels found to scan for artifacts. Do not reject. Returning.";

        return bReject;
    }

    //qDebug() << "MNEEpochDataList::checkForArtifact - lchData.size()" << lchData.size();

    //Start the concurrent processing
    QFuture<void> future = QtConcurrent::map(lchData, checkChThreshold);
    future.waitForFinished();

    for(int i = 0; i < lchData.size(); ++i) {
        if(lchData.at(i).bRejected) {
            bReject = true;
            qDebug() << "MNEEpochDataList::checkForArtifact - Reject trial because of channel"<<lchData.at(i).sChName;
            break;
        }
    }

    return bReject;
}

//*************************************************************************************************************

void MNEEpochDataList::checkChThreshold(ArtifactRejectionData& inputData)
{
    RowVectorXd temp = inputData.data;

    // Remove offset
    //temp = temp.array() - temp(0);

    double min = temp.minCoeff();
    double max = temp.maxCoeff();

    // Peak to Peak
    double pp = max - min;

    if(std::fabs(pp) > inputData.dThreshold) {
        inputData.bRejected = true;
    } else {
        inputData.bRejected = false;
    }

//    qDebug() << "MNEEpochDataList::checkChThreshold - min" << min;
//    qDebug() << "MNEEpochDataList::checkChThreshold - max" << max;
//    qDebug() << "MNEEpochDataList::checkChThreshold - pp" << pp;
//    qDebug() << "MNEEpochDataList::checkChThreshold - inputData.dThreshold" << inputData.dThreshold;

//    //If absolute vaue of min or max if bigger than threshold -> reject
//    if((std::fabs(min) > inputData.dThreshold) || (std::fabs(max) > inputData.dThreshold)) {
//        inputData.bRejected = true;
//    } else {
//        inputData.bRejected = false;
//    }
}
<commit_msg>replaced dumb pointer with smart pointer because it wasn't being deleted<commit_after>//=============================================================================================================
/**
* @file     mne_epoch_data_list.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     July, 2012
*
* @section  LICENSE
*
* Copyright (C) 2012, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief     Definition of the MNEEpochDataList Class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "mne_epoch_data_list.h"

#include <utils/mnemath.h>

//*************************************************************************************************************
//=============================================================================================================
// Qt INCLUDES
//=============================================================================================================

#include <QPointer>
#include <QtConcurrent>
#include <QDebug>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace FIFFLIB;
using namespace MNELIB;
using namespace UTILSLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

MNEEpochDataList::MNEEpochDataList()
{

}

//*************************************************************************************************************

MNEEpochDataList::~MNEEpochDataList()
{
//    MNEEpochDataList::iterator i;
//    for( i = this->begin(); i!=this->end(); ++i) {
//        if (*i)
//            delete (*i);
//    }
}

//*************************************************************************************************************

MNEEpochDataList MNEEpochDataList::readEpochs(const FiffRawData& raw,
                                              const MatrixXi& events,
                                              float tmin,
                                              float tmax,
                                              qint32 event,
                                              const QMap<QString,double>& mapReject,
                                              const QStringList& lExcludeChs,
                                              const RowVectorXi& picks)
{
    MNEEpochDataList data;

    // Select the desired events
    qint32 count = 0;
    qint32 p;
    MatrixXi selected = MatrixXi::Zero(1, events.rows());
    for (p = 0; p < events.rows(); ++p)
    {
        if (events(p,1) == 0 && events(p,2) == event)
        {
            selected(0,count) = p;
            ++count;
        }
    }
    selected.conservativeResize(1, count);
    if (count > 0) {
        printf("%d matching events found\n",count);
    } else {
        printf("No desired events found.\n");
        return MNEEpochDataList();
    }

    // If picks are empty, pick all
    RowVectorXi picksNew = picks;
    if(picks.cols() <= 0) {
        picksNew.resize(raw.info.chs.size());
        for(int i = 0; i < raw.info.chs.size(); ++i) {
            picksNew(i) = i;
        }
    }

    fiff_int_t event_samp, from, to;
    fiff_int_t dropCount = 0;
    MatrixXd timesDummy;
    MatrixXd times;

    QScopedPointer<MNEEpochData> epoch(Q_NULLPTR);

    for (p = 0; p < count; ++p) {
        // Read a data segment
        event_samp = events(selected(p),0);
        from = event_samp + tmin*raw.info.sfreq;
        to   = event_samp + floor(tmax*raw.info.sfreq + 0.5);

        epoch.reset(new MNEEpochData());

        if(raw.read_raw_segment(epoch->epoch, timesDummy, from, to, picksNew)) {
            if (p == 0) {
                times.resize(1, to-from+1);
                for (qint32 i = 0; i < times.cols(); ++i)
                    times(0, i) = ((float)(from-event_samp+i)) / raw.info.sfreq;
            }

            epoch->event = event;
            epoch->tmin = tmin;
            epoch->tmax = tmax;

            epoch->bReject = checkForArtifact(epoch->epoch,
                                              raw.info,
                                              mapReject,
                                              lExcludeChs);

            if (epoch->bReject) {
                dropCount++;
            }

            //Check if data block has the same size as the previous one
            if(!data.isEmpty()) {
                if(epoch->epoch.size() == data.last()->epoch.size()) {
                    data.append(MNEEpochData::SPtr(epoch.take()));//List takes ownwership of the pointer - no delete need
                }
            } else {
                data.append(MNEEpochData::SPtr(epoch.take()));//List takes ownwership of the pointer - no delete need
            }
        } else {
            printf("Can't read the event data segments\n");
        }
    }

    qDebug() << "MNEEpochDataList::readEpochs - Read a total of"<< data.size() <<"epochs of type" << event << "and marked"<< dropCount <<"for rejection";

    return data;
}

//*************************************************************************************************************

FiffEvoked MNEEpochDataList::average(FiffInfo& info, fiff_int_t first, fiff_int_t last, VectorXi sel, bool proj)
{
    FiffEvoked p_evoked;

    printf("Calculate evoked... ");

    MatrixXd matAverage;

    if(this->size() > 0) {
        matAverage = MatrixXd::Zero(this->at(0)->epoch.rows(), this->at(0)->epoch.cols());
    } else {
        p_evoked.aspect_kind = FIFFV_ASPECT_STD_ERR;
        return p_evoked;
    }

    if(sel.size() > 0) {
        p_evoked.nave = sel.size();

        for(qint32 i = 0; i < sel.size(); ++i) {
            matAverage.array() += this->at(sel(i))->epoch.array();
        }
    } else {
        p_evoked.nave = this->size();

        for(qint32 i = 0; i < this->size(); ++i) {
            matAverage.array() += this->at(i)->epoch.array();
        }
    }
    matAverage.array() /= p_evoked.nave;

    printf("%d averages used [done]\n ", p_evoked.nave);

    p_evoked.setInfo(info, proj);

    p_evoked.aspect_kind = FIFFV_ASPECT_AVERAGE;

    p_evoked.first = first;
    p_evoked.last = last;

    p_evoked.times = RowVectorXf::LinSpaced(this->first()->epoch.cols(), this->first()->tmin, this->first()->tmax);

    p_evoked.comment = QString::number(this->at(0)->event);

    if(p_evoked.proj.rows() > 0) {
        matAverage = p_evoked.proj * matAverage;
        printf("\tSSP projectors applied to the evoked data\n");
    }

    p_evoked.data = matAverage;

    return p_evoked;
}

//*************************************************************************************************************

void MNEEpochDataList::applyBaselineCorrection(QPair<QVariant, QVariant>& baseline)
{
    // Run baseline correction
    QMutableListIterator<MNEEpochData::SPtr> i(*this);
    while (i.hasNext()) {
        i.next()->applyBaselineCorrection(baseline);
    }
}

//*************************************************************************************************************

void MNEEpochDataList::dropRejected()
{
    QMutableListIterator<MNEEpochData::SPtr> i(*this);
    while (i.hasNext()) {
        if (i.next()->bReject) {
            i.remove();
        }
    }
}

//*************************************************************************************************************

void MNEEpochDataList::pick_channels(const RowVectorXi& sel)
{
    QMutableListIterator<MNEEpochData::SPtr> i(*this);
    while (i.hasNext()) {
        i.next()->pick_channels(sel);
    }
}

//*************************************************************************************************************

bool MNEEpochDataList::checkForArtifact(const MatrixXd& data,
                                        const FiffInfo& pFiffInfo,
                                        const QMap<QString,double>& mapReject,
                                        const QStringList& lExcludeChs)
{
    //qDebug() << "MNEEpochDataList::checkForArtifact - Doing artifact reduction for" << mapReject;

    bool bReject = false;

    //Prepare concurrent data handling
    QList<ArtifactRejectionData> lchData;
    QList<int> lChTypes;

    if(mapReject.contains("grad") ||
       mapReject.contains("mag") ) {
        lChTypes << FIFFV_MEG_CH;
    }

    if(mapReject.contains("eeg")) {
        lChTypes << FIFFV_EEG_CH;
    }

    if(mapReject.contains("eog")) {
        lChTypes << FIFFV_EOG_CH;
    }

    if(lChTypes.isEmpty()) {
        return bReject;
    }

    for(int i = 0; i < pFiffInfo.chs.size(); ++i) {
        if(lChTypes.contains(pFiffInfo.chs.at(i).kind)
           && !lExcludeChs.contains(pFiffInfo.chs.at(i).ch_name)
           && !pFiffInfo.bads.contains(pFiffInfo.chs.at(i).ch_name)
           && pFiffInfo.chs.at(i).chpos.coil_type != FIFFV_COIL_BABY_REF_MAG
           && pFiffInfo.chs.at(i).chpos.coil_type != FIFFV_COIL_BABY_REF_MAG2) {
            ArtifactRejectionData tempData;
            tempData.data = data.row(i);

            switch (pFiffInfo.chs.at(i).kind) {
            case FIFFV_MEG_CH:
                if(pFiffInfo.chs.at(i).unit == FIFF_UNIT_T) {
                    tempData.dThreshold = mapReject["mag"];
                } else if(pFiffInfo.chs.at(i).unit == FIFF_UNIT_T_M) {
                    tempData.dThreshold = mapReject["grad"];
                }
            break;

            case FIFFV_EEG_CH:
                tempData.dThreshold = mapReject["eeg"];
            break;

            case FIFFV_EOG_CH:
                tempData.dThreshold = mapReject["eog"];
            break;
            }

            tempData.sChName = pFiffInfo.chs.at(i).ch_name;
            lchData.append(tempData);
        }
    }

    if(lchData.isEmpty()) {
        qDebug() << "MNEEpochDataList::checkForArtifact - No channels found to scan for artifacts. Do not reject. Returning.";

        return bReject;
    }

    //qDebug() << "MNEEpochDataList::checkForArtifact - lchData.size()" << lchData.size();

    //Start the concurrent processing
    QFuture<void> future = QtConcurrent::map(lchData, checkChThreshold);
    future.waitForFinished();

    for(int i = 0; i < lchData.size(); ++i) {
        if(lchData.at(i).bRejected) {
            bReject = true;
            qDebug() << "MNEEpochDataList::checkForArtifact - Reject trial because of channel"<<lchData.at(i).sChName;
            break;
        }
    }

    return bReject;
}

//*************************************************************************************************************

void MNEEpochDataList::checkChThreshold(ArtifactRejectionData& inputData)
{
    RowVectorXd temp = inputData.data;

    // Remove offset
    //temp = temp.array() - temp(0);

    double min = temp.minCoeff();
    double max = temp.maxCoeff();

    // Peak to Peak
    double pp = max - min;

    if(std::fabs(pp) > inputData.dThreshold) {
        inputData.bRejected = true;
    } else {
        inputData.bRejected = false;
    }

//    qDebug() << "MNEEpochDataList::checkChThreshold - min" << min;
//    qDebug() << "MNEEpochDataList::checkChThreshold - max" << max;
//    qDebug() << "MNEEpochDataList::checkChThreshold - pp" << pp;
//    qDebug() << "MNEEpochDataList::checkChThreshold - inputData.dThreshold" << inputData.dThreshold;

//    //If absolute vaue of min or max if bigger than threshold -> reject
//    if((std::fabs(min) > inputData.dThreshold) || (std::fabs(max) > inputData.dThreshold)) {
//        inputData.bRejected = true;
//    } else {
//        inputData.bRejected = false;
//    }
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

// PUBLIC API
#include <disir/disir.h>

#include "test_helper.h"

class DisirInstanceTest : public testing::Test
{
    void SetUp()
    {
        status = DISIR_STATUS_OK;
        disir = NULL;
    }

    void TearDown()
    {
    }

public:
    enum disir_status status;
    struct disir *disir;
};

TEST_F (DisirInstanceTest, should_create_destroy_disir_instance)
{
    status = disir_instance_create (NULL, NULL, &disir);
    ASSERT_EQ (DISIR_STATUS_OK, status);
    ASSERT_TRUE (disir != NULL);

    status = disir_instance_destroy (&disir);
    ASSERT_EQ (DISIR_STATUS_OK, status);
    ASSERT_TRUE (disir == NULL);
}

<commit_msg>test: update the renamed struct disir<commit_after>#include <gtest/gtest.h>

// PUBLIC API
#include <disir/disir.h>

#include "test_helper.h"

class DisirInstanceTest : public testing::Test
{
    void SetUp()
    {
        status = DISIR_STATUS_OK;
        disir = NULL;
    }

    void TearDown()
    {
    }

public:
    enum disir_status status;
    struct disir_instance *disir;
};

TEST_F (DisirInstanceTest, should_create_destroy_disir_instance)
{
    status = disir_instance_create (NULL, NULL, &disir);
    ASSERT_EQ (DISIR_STATUS_OK, status);
    ASSERT_TRUE (disir != NULL);

    status = disir_instance_destroy (&disir);
    ASSERT_EQ (DISIR_STATUS_OK, status);
    ASSERT_TRUE (disir == NULL);
}

<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*
 * This is mostly a compilation test to ensure that DBN is accepting
 * enough input types
 */

#include <vector>
#include <list>
#include <deque>

#include "catch.hpp"
#include "template_test.hpp"

#include "dll/rbm.hpp"
#include "dll/dense_layer.hpp"
#include "dll/dyn_rbm.hpp"
#include "dll/dbn.hpp"
#include "dll/trainer/stochastic_gradient_descent.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

namespace {

struct dbn_double {
    using dbn_t =
        dll::dbn_desc<
            dll::dbn_layers<
                dll::dense_desc<28 * 28, 200, dll::weight_type<double>>::layer_t,
                dll::dense_desc<200, 10, dll::weight_type<double>>::layer_t
            >
            , dll::trainer<dll::sgd_trainer>
            , dll::batch_size<10>
            , dll::momentum
        >::dbn_t;

    static void init(dbn_t& net){
        net.learning_rate = 0.05;
        net.initial_momentum = 0.9;
    }
};

struct dbn_float {
    using dbn_t =
        dll::dbn_desc<
            dll::dbn_layers<
                dll::dense_desc<28 * 28, 200, dll::weight_type<float>>::layer_t,
                dll::dense_desc<200, 10, dll::weight_type<float>>::layer_t
            >
            , dll::trainer<dll::sgd_trainer>
            , dll::batch_size<10>
            , dll::momentum
        >::dbn_t;

    static void init(dbn_t& net){
        net.learning_rate = 0.05;
        net.initial_momentum = 0.9;
    }
};

struct dyn_dbn_float {
    using dbn_t =
        dll::dbn_desc<
            dll::dbn_layers<
                dll::dyn_dense_desc<dll::weight_type<float>>::layer_t,
                dll::dyn_dense_desc<dll::weight_type<float>>::layer_t
            >
            , dll::trainer<dll::sgd_trainer>
            , dll::batch_size<10>
            , dll::momentum
        >::dbn_t;

    static void init(dbn_t& net){
        net.initial_momentum = 0.9;
        net.learning_rate = 0.05;
        net.template init_layer<0>(28 * 28, 200);
        net.template init_layer<1>(200, 10);
    }
};

struct dyn_dbn_double {
    using dbn_t =
        dll::dbn_desc<
            dll::dbn_layers<
                dll::dyn_dense_desc<dll::weight_type<double>>::layer_t,
                dll::dyn_dense_desc<dll::weight_type<double>>::layer_t
            >
            , dll::trainer<dll::sgd_trainer>
            , dll::batch_size<10>
            , dll::momentum
        >::dbn_t;

    static void init(dbn_t& net){
        net.initial_momentum = 0.9;
        net.learning_rate = 0.05;
        net.template init_layer<0>(28 * 28, 200);
        net.template init_layer<1>(200, 10);
    }
};

} // end of anonymous namespace

#define TYPES_TEST_PREFIX "dense_dbn"
#define TYPES_TEST_T1 dbn_float
#define TYPES_TEST_T2 dbn_double
#define TYPES_TEST_T3 dyn_dbn_float
#define TYPES_TEST_T4 dyn_dbn_double
#define TYPES_TEST_NO_PRE

#include "dbn_types_test.inl"
<commit_msg>Cleanup<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*
 * This is mostly a compilation test to ensure that DBN is accepting
 * enough input types
 */

#include <vector>
#include <list>
#include <deque>

#include "catch.hpp"
#include "template_test.hpp"

#include "dll/dense_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/trainer/stochastic_gradient_descent.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

namespace {

struct dbn_double {
    using dbn_t =
        dll::dbn_desc<
            dll::dbn_layers<
                dll::dense_desc<28 * 28, 200, dll::weight_type<double>>::layer_t,
                dll::dense_desc<200, 10, dll::weight_type<double>>::layer_t
            >
            , dll::trainer<dll::sgd_trainer>
            , dll::batch_size<10>
            , dll::momentum
        >::dbn_t;

    static void init(dbn_t& net){
        net.learning_rate = 0.05;
        net.initial_momentum = 0.9;
    }
};

struct dbn_float {
    using dbn_t =
        dll::dbn_desc<
            dll::dbn_layers<
                dll::dense_desc<28 * 28, 200, dll::weight_type<float>>::layer_t,
                dll::dense_desc<200, 10, dll::weight_type<float>>::layer_t
            >
            , dll::trainer<dll::sgd_trainer>
            , dll::batch_size<10>
            , dll::momentum
        >::dbn_t;

    static void init(dbn_t& net){
        net.learning_rate = 0.05;
        net.initial_momentum = 0.9;
    }
};

struct dyn_dbn_float {
    using dbn_t =
        dll::dbn_desc<
            dll::dbn_layers<
                dll::dyn_dense_desc<dll::weight_type<float>>::layer_t,
                dll::dyn_dense_desc<dll::weight_type<float>>::layer_t
            >
            , dll::trainer<dll::sgd_trainer>
            , dll::batch_size<10>
            , dll::momentum
        >::dbn_t;

    static void init(dbn_t& net){
        net.initial_momentum = 0.9;
        net.learning_rate = 0.05;
        net.template init_layer<0>(28 * 28, 200);
        net.template init_layer<1>(200, 10);
    }
};

struct dyn_dbn_double {
    using dbn_t =
        dll::dbn_desc<
            dll::dbn_layers<
                dll::dyn_dense_desc<dll::weight_type<double>>::layer_t,
                dll::dyn_dense_desc<dll::weight_type<double>>::layer_t
            >
            , dll::trainer<dll::sgd_trainer>
            , dll::batch_size<10>
            , dll::momentum
        >::dbn_t;

    static void init(dbn_t& net){
        net.initial_momentum = 0.9;
        net.learning_rate = 0.05;
        net.template init_layer<0>(28 * 28, 200);
        net.template init_layer<1>(200, 10);
    }
};

} // end of anonymous namespace

#define TYPES_TEST_PREFIX "dense_dbn"
#define TYPES_TEST_T1 dbn_float
#define TYPES_TEST_T2 dbn_double
#define TYPES_TEST_T3 dyn_dbn_float
#define TYPES_TEST_T4 dyn_dbn_double
#define TYPES_TEST_NO_PRE

#include "dbn_types_test.inl"
<|endoftext|>