Package org.grouplens.lenskit.scored

Source Code of org.grouplens.lenskit.scored.PackedScoredIdListTest

/*
* LensKit, an open source recommender systems toolkit.
* Copyright 2010-2014 LensKit Contributors.  See CONTRIBUTORS.md.
* Work on LensKit has been funded by the National Science Foundation under
* grants IIS 05-34939, 08-08692, 08-12148, and 10-17697.
*
* This program 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 program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.grouplens.lenskit.scored;

import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
import it.unimi.dsi.fastutil.doubles.DoubleList;
import org.grouplens.lenskit.symbols.Symbol;
import org.grouplens.lenskit.symbols.TypedSymbol;
import org.junit.Before;
import org.junit.Test;

import java.util.Iterator;
import java.util.List;
import java.util.Random;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

/**
* Test a packed scored ID list.
*
* @author <a href="http://www.grouplens.org">GroupLens Research</a>
*/
public class PackedScoredIdListTest {
    ScoredIdListBuilder builder;

    @Before
    public void createEmptyList() {
        builder = new ScoredIdListBuilder();
    }

    @Test
    public void testEmptyList() {
        assertThat(builder.size(), equalTo(0));
        PackedScoredIdList list = builder.build();
        assertThat(list.size(), equalTo(0));
        assertThat(list.isEmpty(), equalTo(true));
        try {
            list.get(0);
            fail("get(0) on empty list should throw exception");
        } catch (IndexOutOfBoundsException e) {
            /* expected */
        }
        assertThat(list.iterator().hasNext(), equalTo(false));
        assertThat(list.fastIterator().hasNext(), equalTo(false));
    }

    @Test
    public void testAddScoredId() {
        builder.add(new ScoredIdBuilder(42, 3.5).build());
        assertThat(builder.size(), equalTo(1));
        PackedScoredIdList list = builder.build();
        assertThat(list.size(), equalTo(1));
        assertThat(list.isEmpty(), equalTo(false));
        ScoredId id = list.get(0);
        assertThat(id, notNullValue());
        assertThat(id.getId(), equalTo(42L));
        assertThat(id.getScore(), equalTo(3.5));
        assertThat(id.getUnboxedChannelSymbols(), hasSize(0));

        Iterator<ScoredId> iter = list.iterator();
        assertThat(Lists.newArrayList(iter),
                   contains(id));
        assertThat(iter.hasNext(), equalTo(false));
    }

    @Test
    public void testAddRaw() {
        builder.add(42, 3.5);
        assertThat(builder.size(), equalTo(1));
        PackedScoredIdList list = builder.build();
        assertThat(list.size(), equalTo(1));
        assertThat(list.isEmpty(), equalTo(false));
        ScoredId id = list.get(0);
        assertThat(id, notNullValue());
        assertThat(id.getId(), equalTo(42L));
        assertThat(id.getScore(), equalTo(3.5));
        assertThat(id.getUnboxedChannelSymbols(), hasSize(0));

        Iterator<ScoredId> iter = list.iterator();
        assertThat(Lists.newArrayList(iter),
                   contains(id));
        assertThat(iter.hasNext(), equalTo(false));
    }

    @Test
    public void testAddWithChannels() {
        Symbol sym = Symbol.of("HACKEM MUCHE");
        builder.addChannel(sym);
        builder.add(new ScoredIdBuilder(42, 3.5).addChannel(sym, Math.PI).build());
        PackedScoredIdList list = builder.build();
        assertThat(list.size(), equalTo(1));
        assertThat(list.isEmpty(), equalTo(false));
        ScoredId id = list.get(0);
        assertThat(id, notNullValue());
        assertThat(id.getId(), equalTo(42L));
        assertThat(id.getScore(), equalTo(3.5));

        assertThat(id.getUnboxedChannelSymbols(), contains(sym));
        assertThat(id.getUnboxedChannelValue(sym), equalTo(Math.PI));

        Iterator<ScoredId> iter = list.iterator();
        assertThat(Lists.newArrayList(iter),
                   contains(id));
        assertThat(iter.hasNext(), equalTo(false));
    }

    @Test
    public void testAddTwo() {
        Symbol sym = Symbol.of("HACKEM MUCHE");
        ScoredId id1 = new ScoredIdBuilder(42, 3.5).addChannel(sym, Math.PI).build();
        ScoredId id2 = new ScoredIdBuilder(38, 2.6).addChannel(sym, Math.E).build();
        builder.addChannel(sym);
        builder.add(id1);
        builder.add(id2);
        assertThat(builder.size(), equalTo(2));
        PackedScoredIdList list = builder.build();
        assertThat(list.get(0), equalTo(id1));
        assertThat(list.get(1), equalTo(id2));

        Iterator<ScoredId> iter = list.iterator();
        assertThat(Lists.newArrayList(iter),
                   contains(id1, id2));
        assertThat(iter.hasNext(), equalTo(false));
    }

    @Test
    public void testAddWithDefaultChannel() {
        Symbol sym = Symbol.of("HACKEM MUCHE");
        ScoredId id = new ScoredIdBuilder(42, 3.5).build();
        ScoredId withDefault = new ScoredIdBuilder(42, 3.5).addChannel(sym, -1).build();
        PackedScoredIdList list = builder.addChannel(sym, -1)
                                         .add(id)
                                         .build();
        assertThat(list.get(0), equalTo(withDefault));
    }

    @Test
    public void testAddWithDefaultTypedChannel() {
        TypedSymbol<String> sym = TypedSymbol.of(String.class, "HACKEM MUCHE");
        ScoredId id = new ScoredIdBuilder(42, 3.5).build();
        ScoredId withDefault = new ScoredIdBuilder(42, 3.5).addChannel(sym, "foo").build();
        PackedScoredIdList list = builder.addChannel(sym, "foo")
                                         .add(id)
                                         .build();
        assertThat(list.get(0), equalTo(withDefault));
    }

    @Test
    public void testAddWithDefaultDefaultChannel() {
        Symbol sym = Symbol.of("HACKEM MUCHE");
        ScoredId id = new ScoredIdBuilder(42, 3.5).build();
        ScoredId withDefault = new ScoredIdBuilder(42, 3.5).addChannel(sym, 0).build();
        PackedScoredIdList list = builder.addChannel(sym)
                                         .add(id)
                                         .build();
        assertThat(list.get(0), equalTo(withDefault));
    }

    @Test
    public void testAddWithDefaultDefaultTypedChannel() {
        TypedSymbol<String> sym = TypedSymbol.of(String.class, "HACKEM MUCHE");
        ScoredId id = new ScoredIdBuilder(42, 3.5).build();
        ScoredId withDefault = new ScoredIdBuilder(42, 3.5).build();
        PackedScoredIdList list = builder.addChannel(sym)
                                         .add(id)
                                         .build();
        assertThat(list.get(0), equalTo(withDefault));
    }

    @Test
    public void testAddMany() {
        Random rng = new Random();
        DoubleList vals = new DoubleArrayList(25);
        for (int i = 0; i < 25; i++) {
            double v = rng.nextGaussian() + Math.PI;
            builder.add(i, v);
            vals.add(v);
        }
        assertThat(builder.size(), equalTo(25));
        PackedScoredIdList list = builder.build();
        assertThat(list, hasSize(25));
        for (int i = 0; i < 25; i++) {
            ScoredId id = new ScoredIdBuilder(i, vals.getDouble(i)).build();
            assertThat(list.get(i), equalTo(id));
        }
    }

    @Test
    public void testAddManyWithChannels() {
        Symbol sym = Symbol.of("VALUE");
        TypedSymbol<String> str = TypedSymbol.of(String.class, "STRING");
        builder.addChannel(sym)
               .addChannel(str);
        Random rng = new Random();
        List<ScoredId> ids = Lists.newArrayListWithCapacity(25);
        for (int i = 0; i < 25; i++) {
            double v = rng.nextGaussian() + Math.PI;
            ScoredId id = new ScoredIdBuilder(i, v)
                    .addChannel(sym, Math.log(v))
                    .addChannel(str, Double.toString(v))
                    .build();
            ids.add(id);
            builder.add(id);
        }
        PackedScoredIdList list = builder.build();
        assertThat(list, hasSize(25));
        for (int i = 0; i < 25; i++) {
            assertThat(list.get(i), equalTo(ids.get(i)));
        }
        // check equality for good measure
        assertThat(list, equalTo(ids));
    }

    @Test
    public void testAddAll() {
        Symbol sym = Symbol.of("VALUE");
        TypedSymbol<String> str = TypedSymbol.of(String.class, "STRING");
        builder.addChannel(sym)
               .addChannel(str);
        Random rng = new Random();
        List<ScoredId> ids = Lists.newArrayListWithCapacity(25);
        for (int i = 0; i < 25; i++) {
            double v = rng.nextGaussian() + Math.PI;
            ScoredId id = new ScoredIdBuilder(i, v)
                    .addChannel(sym, Math.log(v))
                    .addChannel(str, Double.toString(v))
                    .build();
            ids.add(id);
        }
        builder.addAll(ids);
        PackedScoredIdList list = builder.build();
        assertThat(list, hasSize(25));
        for (int i = 0; i < 25; i++) {
            assertThat(list.get(i), equalTo(ids.get(i)));
        }
        // check equality for good measure
        assertThat(list, equalTo(ids));
    }

    @Test
    public void testIterateFast() {
        Symbol sym = Symbol.of("VALUE");
        TypedSymbol<String> str = TypedSymbol.of(String.class, "STRING");
        builder.addChannel(sym)
               .addChannel(str);
        Random rng = new Random();
        List<ScoredId> ids = Lists.newArrayListWithCapacity(25);
        for (int i = 0; i < 25; i++) {
            double v = rng.nextGaussian() + Math.PI;
            ScoredId id = new ScoredIdBuilder(i, v)
                    .addChannel(sym, Math.log(v))
                    .addChannel(str, Double.toString(v))
                    .build();
            ids.add(id);
            builder.add(id);
        }
        PackedScoredIdList list = builder.build();
        assertThat(list, hasSize(25));
        int i = 0;
        for (ScoredId id: list) {
            assertThat(id, equalTo(ids.get(i)));
            i++;
        }
    }

    @Test
    public void testFailOnInvalidChannel() {
        Symbol sym = Symbol.of("symbol");
        ScoredId idWithoutSymbol = new ScoredIdBuilder(72, 8.5).addChannel(sym, 3.5).build();
        try {
            builder.add(idWithoutSymbol);
            fail("add should fail with unknown symbol");
        } catch (IllegalArgumentException e) {
            /* expected */
        }
    }

    @Test
    public void testFailOnInvalidTypedChannel() {
        TypedSymbol<String> sym = TypedSymbol.of(String.class, "symbol");
        ScoredId idWithoutSymbol = new ScoredIdBuilder(72, 8.5).addChannel(sym, "foo").build();
        try {
            builder.add(idWithoutSymbol);
            fail("add should fail with unknown symbol");
        } catch (IllegalArgumentException e) {
            /* expected */
        }
    }

    @Test
    public void testIgnoreInvalidChannel() {
        Symbol sym = Symbol.of("symbol");
        ScoredId id = new ScoredIdBuilder(72, 8.5).addChannel(sym, 3.5).build();
        PackedScoredIdList list = builder.ignoreUnknownChannels()
                                         .add(id)
                                         .build();
        assertThat(FluentIterable.from(list).first().get().hasUnboxedChannel(sym),
                   equalTo(false));
    }

    @Test
    public void testIgnoreInvalidTypedChannel() {
        TypedSymbol<String> sym = TypedSymbol.of(String.class, "symbol");
        ScoredId id = new ScoredIdBuilder(72, 8.5).addChannel(sym, "foo").build();
        PackedScoredIdList list = builder.ignoreUnknownChannels()
                                         .add(id)
                                         .build();
        assertThat(FluentIterable.from(list).first().get().hasChannel(sym),
                   equalTo(false));
    }

    @Test
    public void testOmitsNullChannels() {
        TypedSymbol<String> sym = TypedSymbol.of(String.class, "foo");
        PackedScoredIdList list = builder.addChannel(sym)
                                         .add(42, 3.9)
                                         .build();
        ScoredId sid = list.get(0);
        assertThat(sid.hasChannel(sym), equalTo(false));
        assertThat(sid.getChannels(), hasSize(0));
        assertThat(sid.getChannelSymbols(), hasSize(0));
        assertThat(sid.getChannelValue(sym), nullValue());
    }

    @Test
    public void testIncludesUnboxedChannels() {
        Symbol sym = Symbol.of("foo");
        TypedSymbol<Double> tsym = sym.withType(Double.class);
        PackedScoredIdList list = builder.addChannel(sym)
                                         .add(42, 3.9)
                                         .build();
        ScoredId sid = list.get(0);
        assertThat(sid.hasUnboxedChannel(sym), equalTo(true));
        assertThat(sid.hasChannel(tsym), equalTo(true));
        assertThat(sid.getChannels(), hasSize(1));
        assertThat(sid.getChannelSymbols(), contains((TypedSymbol) tsym));
        assertThat(sid.getChannelValue(tsym), equalTo(0.0));
        assertThat(sid.getChannels().iterator().next().getSymbol(),
                   equalTo((TypedSymbol) tsym));
    }
}
TOP

Related Classes of org.grouplens.lenskit.scored.PackedScoredIdListTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.