OPTS=-std=c++11 -O3 -L. #-Wall
CPPFLAGS=-std=c++11 -O3 -L.
OBJECTDIR=obj
TARGETDIR=targets
RNNTARGETS=$(addprefix $(TARGETDIR)/,rnn_rtrl_eucl rnn_rk1_eucl rnn_rk2_eucl rnn_rk10_eucl\
	rnn_rtrl_qdop rnn_rk1_qdop rnn_rk2_qdop rnn_rk10_qdop\
	rnn_bptt_eucl rnn_bptt_qdop)
LRNNTARGETS=$(addprefix $(TARGETDIR)/,lrnn_rtrl_eucl lrnn_rk1_eucl lrnn_rk2_eucl lrnn_rk10_eucl\
	lrnn_rtrl_qdop lrnn_rk1_qdop lrnn_rk2_qdop lrnn_rk10_qdop\
	lrnn_bptt_eucl lrnn_bptt_qdop)

all: $(RNNTARGETS) $(LRNNTARGETS) 

VPATH=src:obj:headers

NNOBJFILES=$(addprefix $(OBJECTDIR)/,network.o outputweights.o qdmetric.o)
RNNOBJFILES=$(addprefix $(OBJECTDIR)/,rnn.o lrnn.o) \
	    headers/model.h $(NNOBJFILES)

$(TARGETDIR)/rnn_bptt_eucl: main.cpp bptt.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN -DBPTT $^ -lrand -o $@

$(TARGETDIR)/rnn_bptt_qdop: main.cpp bptt.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN -DUSE_METRIC -DBPTT $^ -lrand -o $@

$(TARGETDIR)/rnn_rk1_eucl: main.cpp rankone.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN $^ -lrand -o $@ 

$(TARGETDIR)/rnn_rk2_eucl: main.cpp rankn.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN -DRKN -DRANK=2 $^ -lrand -o $@

$(TARGETDIR)/rnn_rk10_eucl: main.cpp rankn.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN -DRKN -DRANK=10 $^ -lrand -o $@

$(TARGETDIR)/rnn_rk1_qdop: main.cpp rankone.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN -DUSE_METRIC $^ -lrand -o $@

$(TARGETDIR)/rnn_rk2_qdop: main.cpp rankn.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN -DUSE_METRIC -DRKN -DRANK=2 $^ -lrand -o $@

$(TARGETDIR)/rnn_rk10_qdop: main.cpp rankn.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN -DUSE_METRIC -DRKN -DRANK=10 $^ -lrand -o $@

$(TARGETDIR)/rnn_rtrl_eucl: main.cpp rtrl.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN -DRTRL $^ -lrand -o $@

$(TARGETDIR)/rnn_rtrl_qdop: main.cpp rtrl.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_RNN -DRTRL -DUSE_METRIC $^ -lrand -o $@

$(TARGETDIR)/lrnn_rk1_eucl: main.cpp rankone.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN $^ -lrand -o $@

$(TARGETDIR)/lrnn_rk2_eucl: main.cpp rankn.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN -DRKN -DRANK=2 $^ -lrand -o $@

$(TARGETDIR)/lrnn_rk10_eucl: main.cpp rankn.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN -DRKN -DRANK=10 $^ -lrand -o $@

$(TARGETDIR)/lrnn_rk1_qdop: main.cpp rankone.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN -DUSE_METRIC $^ -lrand -o $@

$(TARGETDIR)/lrnn_rk2_qdop: main.cpp rankn.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN -DUSE_METRIC -DRKN -DRANK=2 $^ -lrand -o $@

$(TARGETDIR)/lrnn_rk10_qdop: main.cpp rankn.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN -DUSE_METRIC -DRKN -DRANK=10 $^ -lrand -o $@

$(TARGETDIR)/lrnn_rtrl_eucl: main.cpp rtrl.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN -DRTRL $^ -lrand -o $@

$(TARGETDIR)/lrnn_rtrl_qdop: main.cpp rtrl.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN -DRTRL -DUSE_METRIC $^ -lrand -o $@

$(TARGETDIR)/lrnn_bptt_eucl: main.cpp bptt.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN -DBPTT $^ -lrand -o $@

$(TARGETDIR)/lrnn_bptt_qdop: main.cpp bptt.o $(RNNOBJFILES)
	g++ $(OPTS) -DUSE_LRNN -DUSE_METRIC -DBPTT $^ -lrand -o $@

$(OBJECTDIR)/%.o: %.cpp
	g++ -c $(CPPFLAGS) $< -o $@

$(OBJECTDIR)/model.o:rnn.h bptt.h

$(OBJECTDIR)/rankone.o: rankone.h librand.a

$(OBJECTDIR)/rankn.o: rankn.h librand.a

$(OBJECTDIR)/rtrl.o: rtrl.h librand.a

$(OBJECTDIR)/bptt.o: bptt.h librand.a

$(OBJECTDIR)/network.o: network.h librand.a vector.h

$(OBJECTDIR)/outputweights.o: network.h 

$(OBJECTDIR)/qdmetric.o: qdmetric.h vector.h

$(OBJECTDIR)/rnn.o: network.h rnn.h

$(OBJECTDIR)/lrnn.o: network.h lrnn.h rnn.h

ctw: librand.a

librand.a: $(OBJECTDIR)/rand.o rand.h 
	ar -r $@ $<

synthanbn: synthanbn.cpp rand.h
	g++ -O9 $< -lrand -o $@

clean:
	rm -f librand.a
	rm -f $(OBJECTDIR)/*
	rm -f $(TARGETDIR)/*
