help me learn to read documentation

2015-10-01 Thread Robin via Digitalmars-d-learn
Hi. I like to learn programming by examples but I need help 
learning how to read documentation. I have some idea of how it 
works in some aspects but in others i get completely stuck 
because there are no examples or code snippets.


I am using dgame (dgame-dev.de) and im reading the documentation 
for changing the background text of my font in my program.
I have the basic code for font creation but i need to make 
changes to the colors.


import std.stdio;
import std.system;

import Dgame.System;
import Dgame.Window;
import Dgame.Graphic;
import Dgame.Audio;
import Dgame.Math;

void main()
{
 Font dejavu = Font("resources/dejavu.ttf", 12);
 Text CurrentFps = new Text(dejavu);

 ..window loop
}

The documentation here 
(http://dgame-dev.de/index.php?controller=learn=package=graphic=Text=0.6)...
gives me the Text() class but i dont know how to use "foreground, 
background, and Font mode" or at least turn it into usable syntax.


Re: help me learn to read documentation

2015-10-01 Thread Robin via Digitalmars-d-learn

On Friday, 2 October 2015 at 01:20:50 UTC, Adam D. Ruppe wrote:

On Thursday, 1 October 2015 at 19:15:39 UTC, Robin wrote:

[...]


Those describe simple class members, so you can set them 
through assignment:


 Text CurrentFps = new Text(dejavu);
 // change to white on black
 CurrentFps.foreground = Color4b.White;
 CurrentFps.background = Color4b.Black;
 // change mode
 CurrentFps.mode = Font.Mode.Shaded;


I haven't actually used this library, but since the doc 
describes it with variable syntax (`Color4b foreground;`) that 
means you should be able to just assign to them like ordinary 
object member variables.


Wow, thank you so much. I have never seen code like that before 
but the documentation there made me scratch my head.


Thank you.


Rational of some DMD decisions

2015-02-08 Thread Robin via Digitalmars-d-learn

Hiho,

as I am currently very insterested in compiler implementation I 
often look into the DMD github and look how things are done 
there. Often I find myself curious about things at first but find 
out the rational behind certain implementation decisions.


One thing I can't figure out is the different approach with pre- 
and postfix expressions. While prefix expressions inherit from 
UnaExp (unary expression) which makes sense to me as it is an 
expression with only one parameter (in general) the postfix inc 
and decrement expressions are inherited from BinExpr (binary 
expression) which define their second expression to be an integer 
expression with a value of 1.


So I am very curious about the rational behind this design 
decision. Why do Postfix expression not inherit from UnaExp, too? 
Am I missing something very important?


Thanks in advance! =)

I hope this is the right place to ask questions about the DMD 
compiler.


Regards,
Robin


Re: Rational of some DMD decisions

2015-02-08 Thread Robin via Digitalmars-d-learn
Thank you for your reply. I didn't know that it isn't possible to 
overload the post-inc and decrement operators in Dlang but I 
think I don't even miss this feature if pre-inc/dec is still 
available. =)


Re: Code doesn't work - why?

2014-09-17 Thread Robin via Digitalmars-d-learn

Hiho,

thank you for your response on my topic.

However, I still do not understand why it didn't work for struct 
value types since I do not perform any mutations on the state 
objects during execution of the code.


The only thing happening with them is that they are getting 
copied bitwise and thus should have the same entries in the 
associative array as the original source, or am I wrong with this?


When value types are copied bitwise then the associative array 
should also be copied that way or at least point to the same 
mapping as the source and thus shouldn't be empty after copying.


What changes are required in order to make it work with struct 
value types as well? I even tried to change getNext to work with 
pointer return values instead but that did not help either.


Regards,
Rob


Re: Code doesn't work - why?

2014-09-17 Thread Robin via Digitalmars-d-learn

Hiho,

thank you for your response!

You just showed me my flaws while programming with value types. I 
think the only close solution is to work with pointers to the 
created states within the associative array instead of direct 
value types.


Thanks for clearing this up to me. =)

Regards,
Rob


Re: Code doesn't work - why?

2014-09-17 Thread Robin via Digitalmars-d-learn
Here is the fully working code for everyone experiencing similar 
bugs or problems with pointers and value types. =)


struct DeterministicState {
public:
	this(string name, bool isFinal, DeterministicState *[char] 
transits...) {

this.name = name;
this.finalState = isFinal;
this.addTransits(transits);
}

this(string name, bool isFinal) {
this.name = name;
this.finalState = isFinal;
}

this(bool isFinal, DeterministicState *[char] transits...) {
this(, isFinal, transits);
}

this(DeterministicState *[char] transits...) {
this(, false, transits);
}

void addTransits(DeterministicState *[char] newTransits) {
foreach (immutable key; newTransits.keys) {
transits[key] = newTransits[key];
}
}

string getName() const {
return name;
}

bool isFinalState() const {
return finalState;
}

bool hasNext(char input) const {
return (input in transits) ? true : false;
}

DeterministicState * getNext(char input) {
return transits[input];
}

string toString() const {
return name;
}

private:
string name;
DeterministicState *[char] transits;
bool finalState;
}

struct DeterministicFiniteAutomaton {
public:
DeterministicState *[] input(char[] input) {
DeterministicState *[] trace = [ start ];
auto currentState = trace[0];
foreach (immutable c; input) {
if (!currentState.hasNext(c)) {
writeln(currentState.toString() ~  has no next for  ~ 
to!string(c));

break;
} else {
writeln(currentState.toString() ~  has next for  ~ 
to!string(c));

}
currentState = currentState.getNext(c);
trace ~= currentState;
}
return trace;
}

this(DeterministicState * start) {
this.start = start;
}

private:
DeterministicState * start;
}

void main()
{
auto s0 = DeterministicState(s0, false);
auto s1 = DeterministicState(s1, false);
auto s2 = DeterministicState(s2, true);
s0.addTransits(['0' :  s1, '1' :  s2]);
s1.addTransits(['0' :  s0, '1' :  s2]);
s2.addTransits(['0' :  s2, '1' :  s2]);
auto dfa = DeterministicFiniteAutomaton( s0);
auto trace = dfa.input(0001.dup);
foreach (t; trace) {
writeln(t.toString());
}
writeln(Trace Length =  ~ to!string(trace.length));
}

Regards,
Rob


Re: Code doesn't work - why?

2014-09-17 Thread Robin via Digitalmars-d-learn
This is actually a good question as this code isn't really 
complex or doesn't require the best possible performance.
But in case I will ever need optimum performance I should have 
learned how to handle tasks with value types which is the main 
reason why I chose them instead of reference types - for learning 
purposes.


- can't hurt! ;)

Regards,
Rob


Code doesn't work - why?

2014-09-16 Thread Robin via Digitalmars-d-learn

Hello,

I came back to D after a longer break and just wanted to set up a 
small project to further get in contact with this language.


However, it seems that the codes which simply shall simulate a 
deterministic finit automaton do not work correctly.


CODE ---

struct DeterministicState {
public:
	this(string name, bool isFinal, DeterministicState[char] 
transits...) {

this.name = name;
this.finalState = isFinal;
this.addTransits(transits);
}

this(string name, bool isFinal) {
this.name = name;
this.finalState = isFinal;
}

this(bool isFinal, DeterministicState[char] transits...) {
this(, isFinal, transits);
}

this(DeterministicState[char] transits...) {
this(, false, transits);
}

void addTransits(DeterministicState[char] newTransits) {
foreach (immutable key; newTransits.keys) {
transits[key] = newTransits[key];
}
}

string getName() const {
return name;
}

bool isFinalState() const {
return finalState;
}

bool hasNext(char input) const {
return (input in transits) ? true : false;
}

DeterministicState getNext(char input) {
return transits[input];
}

string toString() const {
return name;
}

private:
string name;
DeterministicState[char] transits;
bool finalState;
}

struct DeterministicFiniteAutomaton {
public:
DeterministicState[] input(char[] input) {
DeterministicState[] trace = [ start ];
auto currentState = trace[0];
foreach (immutable c; input) {
if (currentState.hasNext(c) == false) {
writeln(currentState.toString() ~  has next for  ~ 
to!string(c));

break;
} else {
writeln(currentState.toString() ~  has NO next for  ~ 
to!string(c));

}
currentState = currentState.getNext(c);
trace ~= currentState;
}
return trace;
}

this(DeterministicState start) {
this.start = start;
}

private:
DeterministicState start;
}

void main()
{
auto s0 = DeterministicState(s0, false);
auto s1 = DeterministicState(s1, false);
auto s2 = DeterministicState(s2, true);
s0.addTransits(['0' : s1, '1' : s2]);
s1.addTransits(['0' : s0, '1' : s2]);
s2.addTransits(['0' : s2, '1' : s2]);
auto dfa = DeterministicFiniteAutomaton(s0);
auto trace = dfa.input(0001.dup);
foreach (t; trace) {
writeln(t.toString());
}
writeln(Trace Length =  ~ to!string(trace.length));
}

---

The output is the following:

s0 has NO next for 0
s1 has next for 0
s0
s1
Trace Length = 2

Which states that the trace for input 0001 has just a length of 
2 instead of 4. And I do not really understand why s1 has no next 
item while it was defined in main.


I hope someone can clear things up for me. I really don't get why 
this isn't working as intended.


Regards,
Rob


Re: Strange segfault (Derelict/OpenGL)

2014-08-30 Thread Robin Schroer via Digitalmars-d-learn

On Friday, 29 August 2014 at 15:20:00 UTC, Mike Parker wrote:
As the README in Derelict 3 points out, that project is no 
longer updated. You should be using the binding from the 
DerelictOrg project [1] for anything new.


[1] https://github.com/DerelictOrg/



stitch


On 8/29/2014 9:16 PM, Robin Schroer wrote:

On Friday, 29 August 2014 at 11:51:47 UTC, Marc Schütz wrote:


display.Display.render() is what tries to render the triangle 
using a

glBegin-block.


Some code would be helpful. My first thought is that you aren't 
loading properly. DerelictGL3 does not load deprecated 
functions, but you're trying to call a deprecated function. Are 
you loading DerelictGL or DerelictGL3?




So, I dug around a lot. I am using DerelictOrg, sorry if this was 
unclear, I was under the impression that it is still version 3. 
But anyway, I found out that some of my GL code is actually 
refering to null pointers because I have been using deprecated 
functions. So I am able to establish an OpenGL 3.3 context 
without crashing (although my test does not render yet, but that 
is another problem).


Thank you to everyone nudging me in the right direction.

--

Robin Schroer


Strange segfault (Derelict/OpenGL)

2014-08-29 Thread Robin Schroer via Digitalmars-d-learn

I'm not entirely sure where to post, so I will put it here.

I'm playing around with D and Derelict 3 to make something with 
OpenGL (don't really know what yet). I managed to open a window, 
add an OpenGL context, clear the screen and flip buffers. But as 
soon as I try to render a triangle, my program crashes. I already 
tried hardcoding values in the shaders to rule them out. I end up 
with:


Error executing command run: Program exited with code -11

Upon running with gdb, I get:

Program received signal SIGSEGV, Segmentation fault.
0x in ?? ()

which is not really helpful to me.

dub -v's output:

[...]

Full exception: 
object.Exception@source/dub/generators/build.d(405): Program 
exited with code -11


dub(pure @safe bool std.exception.enforce!(bool).enforce(bool, 
lazy const(char)[], immutable(char)[], ulong)+0x6b) [0x67346f]
dub(void 
dub.generators.build.BuildGenerator.runTarget(dub.internal.vibecompat.inet.path.Path, 
const(dub.compilers.compiler.BuildSettings), 
immutable(char)[][])+0x4dc) [0x62db70]
dub(void 
dub.generators.build.BuildGenerator.generateTargets(dub.generators.generator.GeneratorSettings, 
const(dub.generators.generator.ProjectGenerator.TargetInfo[immutable(char)[]]))+0x231) 
[0x62a75d]
dub(void 
dub.generators.generator.ProjectGenerator.generate(dub.generators.generator.GeneratorSettings)+0x2de) 
[0x62f9a2]
dub(void dub.dub.Dub.generateProject(immutable(char)[], 
dub.generators.generator.GeneratorSettings)+0xaa) [0x5f1f46]
dub(int dub.commandline.GenerateCommand.execute(dub.dub.Dub, 
immutable(char)[][], immutable(char)[][])+0x677) [0x5e5b6b]
dub(int dub.commandline.BuildCommand.execute(dub.dub.Dub, 
immutable(char)[][], immutable(char)[][])+0x8d) [0x5e5e81]
dub(int dub.commandline.RunCommand.execute(dub.dub.Dub, 
immutable(char)[][], immutable(char)[][])+0x8d) [0x5e6041]
dub(int 
dub.commandline.runDubCommandLine(immutable(char)[][])+0x1211) 
[0x5e3b8d]

dub(_Dmain+0x20) [0x5e2334]
dub(void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).runAll().void __lambda1()+0x18) [0x6ce504]
dub(void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate())+0x2a) 
[0x6ce45e]
dub(void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).runAll()+0x30) [0x6ce4c4]
dub(void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate())+0x2a) 
[0x6ce45e]

dub(_d_run_main+0x1a3) [0x6ce3df]
dub(main+0x25) [0x5e2979]
/lib64/libc.so.6(__libc_start_main+0xf5) [0x3dcae21d65]

I am using the current master versions of Derelict, dub 0.9.21, 
dmd v2.066.0, on Linux 3.15.7 x86_64


I can post my source if needed, but it is quite a lot already. 
I'm not really sure if it is my fault or a bug in Derelict or 
dmd, hopefully someone is able to track this down.


--

Robin Schroer


Re: Strange segfault (Derelict/OpenGL)

2014-08-29 Thread Robin Schroer via Digitalmars-d-learn

On Friday, 29 August 2014 at 11:51:47 UTC, Marc Schütz wrote:

On Friday, 29 August 2014 at 11:23:34 UTC, Robin Schroer wrote:

Upon running with gdb, I get:

Program received signal SIGSEGV, Segmentation fault.
0x in ?? ()

which is not really helpful to me.


Can you still try to get a backtrace with `bt`? This looks like 
it's calling a null function pointer. I'm not familiar with 
Derelict, but I remember that some initialization needs to be 
done which involves setting up function pointers; your problem 
is probably related to that.


Yes, I can:

Program received signal SIGSEGV, Segmentation fault.
0x in ?? ()
(gdb) bt
#0  0x in ?? ()
#1  0x004ad33e in display.Display.render() 
(this=0x77ecfe00)

at source/dgame/display.d:95
#2  0x004a01d5 in D main (args=...) at source/app.d:41
#3  0x004cd9af in rt.dmain2._d_run_main() ()
#4  0x004cd902 in rt.dmain2._d_run_main() ()
#5  0x004cd968 in rt.dmain2._d_run_main() ()
#6  0x004cd902 in rt.dmain2._d_run_main() ()
#7  0x004cd883 in _d_run_main ()
#8  0x004acfb5 in main ()

display.Display.render() is what tries to render the triangle 
using a glBegin-block.


Re: Strange segfault (Derelict/OpenGL)

2014-08-29 Thread Robin Schroer via Digitalmars-d-learn

On Friday, 29 August 2014 at 12:41:38 UTC, ponce wrote:

On Friday, 29 August 2014 at 11:23:34 UTC, Robin Schroer wrote:

I'm not entirely sure where to post, so I will put it here.

I'm playing around with D and Derelict 3 to make something 
with OpenGL (don't really know what yet). I managed to open a 
window, add an OpenGL context, clear the screen and flip 
buffers. But as soon as I try to render a triangle, my program 
crashes.


As John Colvin said, forgetting to call DerelictGL3.reload() is 
a common error.


I definitely reload after setting the context and before trying 
to render.


Re: How to return range constructs?

2014-03-01 Thread Robin

Hiho,

@anonimous:
Thank you for that hint with rdmd, I was already wondering what 
that was.


@Mike Parker:
Thank you very much for clearing that up for me. I really needed 
such a clear answer about this topic. So D language is highly 
advanced in meta programming and I should really begin to use it. 
=)


Robin


Re: Template error on compiling ...

2014-03-01 Thread Robin

Hiho,

thank you for your responses.
This D language meta programming sounds funny and strange to
someone who has never really worked with something like this but
I understand its importance and will look more into working with
it. =)

Robin


How to return range constructs?

2014-02-28 Thread Robin

Hiho,

for experimental and learning reasons I am working on a simple 
matrix library for D. And since ranges seem to be a cool feature 
of the D language I am currently trying to understand them and 
use them more in my codes.


So I thought that it would be a nice feature if I could create 
methods to return specific ranges for certain matrix instances, 
e.g. something like getRowRange(size_t row) or 
getColumnRange(size_t col) which returns a range to easily 
iterate through a single row- or column vector of a matrix 
instance with a simple foreach loop.


I store the matrix data within a single dimensional array for 
performance purposes instead of a jagged array:


private
{
T[] data;
Dimension dim;
}

The Dimension 'dim' is an object holding the number of rows and 
columns as well as some handy methods and properties such as 
isSquare etc.


So my question is: How to define such a method which returns a 
range for a single row or column vector? The range should be 
modifiable depending on whether the matrix instance is 
const/immutable or not. Or isn't that possible at all? I thought 
that it could be tricky for row vectors since their data wouldn't 
be dense in memory.


I've looked into the std.range documentation but doesn't seem to 
get a clue how to get this working. And if it works - what range 
type would fit best for my purposes - or do I need to create a 
sub-class of a certain range type specially fit for my matrix?


My try so far:

module neoLab.core.ColumnVectorRange;

import std.range;
import neoLab.core.Matrix;

final class ColumnVectorRange(T) : RandomAccessFinite!T {
private
{
T[] data;
size_t cur = 0;
size_t length = 0;
}

this(const ref Matrix m, size_t row)
in
{
assert(row  m.getDimension().rows, Row index is invalid.);
}
body
{
this.data = m.data;
this.length = m.getDimension().cols;
}

ColumnVectorRange!T save() {
// What does this do?
}

override T opIndex(size_t index) {
return this.data[index]; // this correct?
}

override T moveAt(size_t index) {
return this.data[this.cur]; // this good?
}

override size_t length() {
return this.length;
}

override alias opDollar = this.length; // Is this nessecary?

override ColumnVectorRange!E opSlice(size_t, size_t) {
// What does this do in particular?
}
}

I highly appreciate tips and answers! =)

Thanks in advance.

Robin


Re: How to return range constructs?

2014-02-28 Thread Robin

Hiho,

ok thanks - I haven't known that interfaces are not a must 
extend like in java to serve as a real interface to something. 
This is strange to me in first place but has its pros.


And when I want to build up a RandomAccessFinite I just have to 
implement the other methods as well, okay. :D
Is this performance intense to iterate over these custom ranges 
instead of iterating plainly without them or is the compiler 
optimizing the overhead away?


I have got another problem with my current implementation. My 
data field is private (as you can see from my first post) and I 
don't really want to create a public getter for it (because of 
the encapsulation) but I either don't want to copy it everytime I 
create a range for my matrix. On top of all I want to have 
seperate source files instead of one huge file (one module) where 
I can access everything (which is what I would need atm). So is 
there another way to solve this problem? Or do I really have to 
merge all my files into one big giantic file so that they are all 
in the same module?


Robin


Template error on compiling ...

2014-02-28 Thread Robin

Hiho,

I am currently working on a matrix library (matrices are 
templated structs) and have just implemented so-called 
ElementalOperations which perform certain tasks on mutable 
matrices.


There is an abstract ElementalOperation where three different 
ElementalOperation types inherit from. These ElementalOperations 
are structured like that:


module neoLab.core.ScaleRowOperation;

import neoLab.core.ElementalOperation;
import neoLab.core.Matrix;

final class ScaleRowOperation(T = double) : ElementalOperation
if (!hasIndirections!T)
{
private
{
size_t row = 0;
T factor = 1;
}

this(size_t row, T factor) pure nothrow {
this.row = row;
this.factor = factor;
}

override void opCall(ref Matrix m) pure nothrow {
foreach (immutable col; 0 .. m.getDimension().cols) {
m[this.row, col] *= this.factor;
}
}

override string toString() const pure nothrow {
return Scale all elements of row  ~ this.row ~
 by factor  ~ this.factor ~ .;
}
}

So it is a fairly simple concept until now and I haven't spend 
time on improving its performance as I run into a strange 
compiler error, telling me the following:


neoLab/core/ElementalOperation.d(6): Error: struct 
neoLab.core.Matrix.Matrix(T = double) if (!hasIndirections!T) is 
used as a type
neoLab/core/SwapRowsOperation.d(18): Error: struct 
neoLab.core.Matrix.Matrix(T = double) if (!hasIndirections!T) is 
used as a type


The matrix struct is defined as follows:

struct Matrix(T = double) if (!hasIndirections!T)

In the documentation hasIndirections!T reads:
Returns true if and only if T's representation includes at least 
one of the following:

- a  raw pointer U*;
- an array U[];
- a  reference to a class type C.
- an associative array.
- a  delegate.

I don't know why this error occures at all. In my opinion it 
shouldn't, or am I doing something wrong again?


Thanks in advance for help. =)

Robin


Re: Template error on compiling ...

2014-02-28 Thread Robin

Hiho,

both

opCall(ref Matrix!() m)

opCall(ref Matrix!T m)

aswell as

opCall(ref Matrix!(m))

or just

opCall(ref Matrix m)

give me all the same error as the one stated in the first post 
... :/


Nothing really seems to work here.

Robin


Re: Template error on compiling ...

2014-02-28 Thread Robin

Hiho,

aww, that's a noob mistake of me.

Thanks!

Should take a closer look at the error messages next time a 
should think more about their special meaning ...


It works now while it feels strange that I have to template the 
three classes as I am only working with references to matrix and 
in my understanding this shouldn't affect the compilate. But, 
well, in the end it works now.^^


Robin


Re: How to return range constructs?

2014-02-28 Thread Robin

Hiho,

sorry for the double post but I can't find an edit button.

I have managed to write a custom ForwardRange based on your code 
as I wished it to behave. However, the assertion fails on 
compilation, now. The only thing I have changed is that I have 
added a constructor as well as changing the type of T[] to 
Matrix!T pointer type.


The general layout stayed the same and I don't think that a 
constructor may break the ForwardRange interface.


Do you know what's wrong here?

Here is the code:
http://dpaste.dzfl.pl/8718b09cb825

Besides that ... are there nicer workarounds to prevent using 
matrix by value instead of storing it as a pointer which is kind 
of unsafe?


Thanks in advance!

Robin


Re: Template error on compiling ...

2014-02-28 Thread Robin

Hiho,

just for you: the whole code! =)
http://dpaste.dzfl.pl/cd1537571a4d

The idea is that I have matrix instances and so-called 
ElementalOperations which are able to operate on matrices to 
solve certain algorithms object oriented without nasty loops and 
so on.


This had worked perfectly in my java implementation so far.

Robin


Re: How to return range constructs?

2014-02-28 Thread Robin

Hiho,

I have made matrix a struct for a better performance and since 
everybody here on the forums was complaining about that it should 
be a struct type.


When I uncomment the currently commented assertion I get linking 
errors. (these strange and nearly unreadable error messages.)


Here is a part of them:
ColumnVectorForwardRange.o: In function 
`_D6neoLab4core6Matrix13__T6MatrixTdZ6Matrix6__ctorMFNaNbNcxmxmxbZS6neoLab4core6Matrix13__T6MatrixTdZ6Matrix':
neoLab/core/Matrix.d:(.text._D6neoLab4core6Matrix13__T6MatrixTdZ6Matrix6__ctorMFNaNbNcxmxmxbZS6neoLab4core6Matrix13__T6MatrixTdZ6Matrix+0x31): 
undefined reference to 
`_D6neoLab4core9Dimension9Dimension6__ctorMFNaNbNcxmxmZS6neoLab4core9Dimension9Dimension'

ColumnVectorForwardRange.o: In function

... many many many lines of error messages ...

ColumnVectorForwardRange.o: In function 
`_D6neoLab4core6Matrix13__T6MatrixTdZ6Matrix6randomFxmxmdddZS6neoLab4core6Matrix13__T6MatrixTdZ6Matrix':
neoLab/core/Matrix.d:(.text._D6neoLab4core6Matrix13__T6MatrixTdZ6Matrix6randomFxmxmdddZS6neoLab4core6Matrix13__T6MatrixTdZ6Matrix+0x145): 
undefined reference to 
`_D6neoLab4core9Dimension9Dimension4sizeMxFNaNbNdZm'

collect2: error: ld returned 1 exit status
--- errorlevel 1

Robin


Re: Optimize my code =)

2014-02-22 Thread Robin

Hiho,

as I used the ldmd wrapper for ldc2 I was able to use the same
arguments given via the cmdfile. These were: -release
-noboundscheck -O and -inline.

Robin


Re: Optimize my code =)

2014-02-20 Thread Robin

Hiho,

here are the results of both compilers (DMD and LDC2) on my 
system:


LDC:
=
allocationTest ...
Time required: 5 secs, 424 msecs
multiplicationTest ...
Time required: 1 secs, 744 msecs
toStringTest ...
Time required: 0 secs, 974 msecs
transposeTest ...
Time required: 0 secs, 998 msecs
scalarMultiplicationTest ...
Time required: 0 secs, 395 msecs
matrixAddSubTest ...
Time required: 0 secs, 794 msecs
matrixEqualsTest ...
Time required: 0 secs, 0 msecs
identityMatrixTest ...
Time required: 0 secs, 393 msecs
=

DMD:
=
allocationTest ...
Time required: 3 secs, 161 msecs
multiplicationTest ...
Time required: 2 secs, 6 msecs
toStringTest ...
Time required: 1 secs, 365 msecs
transposeTest ...
Time required: 1 secs, 45 msecs
scalarMultiplicationTest ...
Time required: 0 secs, 405 msecs
matrixAddSubTest ...
Time required: 0 secs, 809 msecs
matrixEqualsTest ...
Time required: 0 secs, 430 msecs
identityMatrixTest ...
Time required: 0 secs, 350 msecs
=

All in all I must say that I am more pleased with the DMD results 
as I am kind of worried about the LDC allocation test performance 
...


I also had to rewrite parts of the codes as some functions just 
weren't pure or nothrow such as the whole things around 
this.data[] += other.data[].


Robin


Re: Optimize my code =)

2014-02-18 Thread Robin
, dualcore 
2,2ghz, 4gb ram)


There are still many ways to further improve the performance. For 
examply by using LDC on certain hardwares, paralellism and 
perhaps by implementing COW with no GC dependencies. And of 
course I may miss many other possible optimization features of D.


I by myself can say that I have learn a lot and that's the most 
important thing above everything else for me here.


Thank you all for this very interesting conversation! You - the 
community - are a part what makes D a great language. =)


Robin


Re: Optimize my code =)

2014-02-17 Thread Robin

Hiho,

I currently haven't got enough time to respond to all what have 
been said since my last post.

However, here is the simple code:
http://dpaste.dzfl.pl/3df8694eb47d

Thanks in advance!
I am really looking forward to your editing! =)

Robin


Re: Optimize my code =)

2014-02-17 Thread Robin

Hiho,

thank you for your code improvements and suggestions.

I really like the foreach loop in D as well as the slight (but 
existing) performance boost over conventional for loops. =)


Another success of the changes I have made is that I have 
achieved to further improve the matrix multiplication performance 
from 3.6 seconds for two 1000x1000 matrices to 1.9 seconds which 
is already very close to java and c++ with about 1.3 - 1.5 
seconds.


The key to victory was pointer arithmetics as I notices that I 
have used them in the C++ implementation, too. xD


The toString implementation has improved its performance slightly 
due to the changes you have mentioned above: 1.37 secs - 1.29 
secs


I have also adjusted all operator overloadings to the new style 
- I just haven't known about that new style until then - thanks!


I will just post the whole code again so that you can see what I 
have changed.


Keep in mind that I am still using DMD as compiler and thus 
performance may still raise once I use another compiler!


All in all I am very happy with the code analysis and its 
improvements!
However, there were some strange things of which I am very 
confused ...


void allocationTest() {
writeln(allocationTest ...);
sw.start();
auto m1 = Matrix!double(1, 1);
{ auto m2 = Matrix!double(1, 1); }
{ auto m2 = Matrix!double(1, 1); }
{ auto m2 = Matrix!double(1, 1); }
//{ auto m2 = Matrix!double(1, 1); }
sw.stop();
printBenchmarks();
}

This is the most confusing code snippet. I have just changed the 
whole allocation for all m1 and m2 from new Matrix!double (on 
heap) to Matrix!double (on stack) and the performance dropped 
significantly - the benchmarked timed raised from 2,3 seconds to 
over 25 seconds!! Now look at the code above. When I leave it as 
it is now, the code requires about 2,9 seconds runtime, however, 
when enabeling the currently out-commented line the code takes 14 
to 25 seconds longer! mind blown ... 0.o This is extremely 
confusion as I allocate these matrices on the stack and since I 
have allocated them within their own scoped-block they should 
instantly release their memory again so that no memory 
consumption takes place for more than 2 matrices at the same 
time. This just wasn't the fact as far as I have tested it.


Another strange things was that the new opEquals implementation:

bool opEquals(const ref Matrix other) const pure nothrow {
if (this.dim != other.dim) {
return false;
}
foreach (immutable i; 0 .. this.dim.size) {
if (this.data[i] != other.data[i]) return false;
}
return true;
}

is actually about 20% faster than the one you have suggested. 
With the single line of return (this.dim == other.dim  
this.data[] == other.data[]).


The last thing I haven't quite understood is that I tried to 
replace


auto t = Matrix(other).transposeAssign();

in the matrix multiplication algorithm with its shorter and 
clearer form


auto t = other.transpose(); // sorry for the nasty '()', but I 
like them! :/


This however gave me wonderful segmentation faults on runtime 
while using the matrix multiplication ...


And here is the complete and improved code:
http://dpaste.dzfl.pl/7f8610efa82b

Thanks in advance for helping me! =)

Robin


Re: Optimize my code =)

2014-02-16 Thread Robin

Hiho,

thanks again for your answers!

I don't know where to start ...

@Stanislav Blinov:
I am not currently aware of the move semantics in D or what it 
is called there. However, I am not quite sure if D does an 
equally good job as C++ in determining if a value can be moved or 
not. I have made some simple tests which showed me that the 
swap-assignment and the move-constructor are never called in D at 
code where C++ would certainly take them, instead D just copies 
values which were in fact rvalues ... (Maybe I just don't get the 
whole thing behind the scenes - and I am really hoping it.)


My statement that the in and body block of the assignment 
operator slows down the whole code isn't true anymore. Don't know 
what fixed it tough.


@bearophile:
Yeah, you are completely right - I am super confused at the 
moment. I always thought that D would be much easier to learn 
than C++ as all the people always say that C++ is the most 
complex language. After what I have learned so far D seems to be 
much more complex which isn't bad in general, but the learning 
curve doesn't feel so well atm as I am mainly confused by many 
things instead of getting what happens behind the scene. (e.g. 
move semantics, the whole army of modifiers, immutability which 
result in zero performance boost in non-paralell environments, 
the fact that classes are by-ref and structs are by-val is also 
confusing from time to time to be honest.)


When I started to write the C++ matrix library after I have 
written the Java matrix library to get to know what both 
languages can achive I have also had to start learning C++ as 
well. I bought a book and after 2-3 weeks I got the concepts and 
everything went as excepted and no things seemed to be hidden 
behind the scenes from me, the programmer which was in fact a 
nice experience when trying to optimize the code until it was 
equally fast as the java code or even faster. D seems to be more 
problematic when it comes to learning how to optimize the code.


To summarize, I am still a beginner and learn this language as it 
has got cool, new and advanced features, it has not so many 
legacy issues (like C++), it unites object orientated, functional 
as well as imperative and paralell programming paradigms (still 
amazed by that fact!), runs native and isn't bound to any 
operating system or a huge runtime environment (java/c#). That's 
why I am learning D! =)


I would love to see how much performance a D vetaran like you is 
able to grab out of my codes. Just tell me where I shall upload 
them and I will do so. Don't expect too much as I am still a 
beginner and as this project has just started. I didn't want to 
implement the whole functionality before I know how to do it with 
a good result. ;-)


The matrix multiplication you have posted has some cool features 
in it. I especially like the pure one with all that functional 
stuff. :D


@Nick Sabalausky:

Don't be shocked at the bad performance of a beginner D 
programmer. At least I am not shocked yet that my D 
implementation isn't performing as well as the highly optimized 
C++11 implementation or the JIT-optimized Java implementation. In 
general one can not compare the results of a native compilation 
optimization which shall run on different hardwares and a JIT 
optimization which is able to pull out every single optimization 
routine because it knows the system and all its components to 
compile at.


There is also the LDC2 and the GDC which should also improve the 
general performance quite a bit.


However, what is true is, that it is (at least for me) harder to 
learn how to write efficient code for D than it was to learn it 
for C++. And keep in mind that my Java implementation (which runs 
nearly as fast as the C++ implementation) is written just to fit 
for performance. I have had to do dirty things (against the 
general Java mentality) in order to achive this performance. 
Besides that I couldn't implement a generic solution in Java 
which wasn't five to ten times slower than without generics as 
generics in Java are a runtime feature. So all in all Java is 
only good in performance if you don't use it as Java (purely 
object oriented etc.) ... but it works! :D


@All of you:
What I have done since the last time:
I have changed my mind - matrix is now a value type. However, I 
wasn't sure about this step because I planned to implement dense 
and sparse matrices which could inherit from a basic matrix 
implementation in thus required to be classes.


I have also removed that nasty final struct statement.^^

However, benchmarks stayed the same since the last post.

Hopefully I haven't forgotten to say anything important ...

Robin


Re: Optimize my code =)

2014-02-15 Thread Robin

Hiho,

wow, first of all: this community is awesome - so many kind and 
interesting answers. =)


With your help I was able to achieve a performance boost for 
several different operations.


Some benchmarks:

Allocation of 5 10.000 x 10.000 matrices in a row:
Before: ~8,2 seconds
After: ~2,3 seconds (with the minimallyInitializedArray!)

Multiplication of two 1000x1000 matrices:
Before: ~14,8 seconds
After: ~4,3 seconds

However, I think there is still much potential in order to 
further optimize this code. Let me tell you what changes I have 
mainly performed on the code so far ...


Matrix is still a class but I changed it to a final class 
preventing matrix methods to be virtual. Dimension is now a final 
struct (don't know if 'final' is affecting structs in any way 
tough ...). This mainly gave the multiplication a huge 
performance boost.


When converting the Matrix to a struct from class the 
multiplication even lowered from ~4.3 seconds to about 3.6 
seconds. However, I am currently not sure if I want matrices to 
be structs (value types).


Besides that I tried to add nothrow and pure as attribute to 
every possible method. However, as it turned out I wasn't able to 
add the pure modifier to any method as I always called an impure 
method with it (as stated by the compiler). This actually made 
sense most of the times and I think the only pure methods now are 
the constructor methods of the Dimension struct.


What may still speed up things?

In my tests it turned out that the simple code:

auto m1 = Matrix!double.random(1000, 1000, -10, 10, 0.25);
auto m2 = Matrix!double.random(1000, 1000, -10, 10, 0.25);
auto m3 = m1 * m2;

Called the normal copy-constructor. This is sad as it would be a 
huge performance boost if it would make use of the move 
semantics. (In the C++ matrix codes this scenario would actually 
call move assignment operator for matrix m3 which is much much 
faster than copying.)


But I haven't figured out yet how to use move semantics in D with 
class objects. Or is that just possible with struct value types?


I have also tried the LDC compiler. However, it gave me some 
strange bugs. E.g. it didn't like the following line:


ref Matrix transpose() const {
return new Matrix(this).transposeAssign();
}

And it forced me to change it to:

ref Matrix transpose() const {
auto m = new Matrix(this);
m.transposeAssign();
return m;
}

Which is kind of ugly ...
I hope that this is getting fixed soon, as I imply it as correct 
D code because the DMD is capable to compile this correctly.


Some of you came up with the thing that transposing the matrix 
before multiplication of both takes place must be much slower 
than without the transposition. In my former Java and C++ 
programs I have already tested what strategy is faster and it 
turned out that cache efficiency DOES matter of course. There are 
also papers explaining why a transpose matrix multiplication may 
be faster than without transposing.
In the end this is just a test suite and there is already an even 
faster approach of a matrix multiplication which runs in O(n^2.8) 
instead of O(n^3) as my current simple solution. And with the 
power of OpenCL (or similar) one could even lift a matrix 
multiplication to the GPU and boom.^^ But the current task is to 
find general optimized code for the D language - this thread 
already helped me much!


I wasn't aware that D is actually capable of lazy evaluations 
other than the if-pseude-lazy-evaluation which is kind of cool. 
However, I still have to look that up in order to maybe find a 
use for it in these codes.


SIMD instructions also sound extremely cool but a little bit too 
complex regarding the fact that I am fairly new to D and still 
learning basics of this language.


In the end I wanted to state something which I found very 
iritating. Bearophile stated correctly that my pre-conditions for 
the index operators are all wrong and corrected my code with some 
smooth additions:


T opIndex(in size_t row, in size_t col) const nothrow
in {
assert(row  nRows);
assert(col  nCols);
} body {
return data[dim.offset(row, col)];
}

The in and body statements are cool as far as I realize what they 
are for. However, in the benchmarks they had a clear and 
noticable negative impact on the matrix multiplication which 
raised to ~8 seconds from ~4 seconds with his code compared to 
mine. When leaving out the in and body statement block and using 
only one normal block as follows, it stayed at the 4 seconds 
duration for that task and so I think that the compiler won't 
optimize things in an 'in' code block - is that right?


T opIndex(in size_t row, in size_t col) const nothrow {
assert(row  nRows);
assert(col  nCols);
return data[dim.offset(row, col)];
}

Thanks again for all your helpful comments and thanks in advance 
- I am eagerly looking forward for your future comments! =)


Robin


Optimize my code =)

2014-02-14 Thread Robin
() method which 
creates a matrix with random values. There it is unnecessary that 
the (sometimes huge) array is completely initialized with the 
type's init value.


Thanks in advance!

Robin