点产品功能

时间:2017-07-19 18:30:24

标签: .net matrix f#

我写了一个带有2个列表的点积函数:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;


public class ScratchPaper extends JFrame {
    private static final long serialVersionUID = 1L;
    private static final int GRIDSIZE = 8;
    private JPanel[][] whitePanel = new WhitePanel[GRIDSIZE][GRIDSIZE];
    private JPanel[][] blackPanel = new BlackPanel[GRIDSIZE][GRIDSIZE];
    private Random rand = new Random();
    JButton b1 = new JButton("Btn1");
    JButton b2 = new JButton("Btn2");
    JButton b3 = new JButton("Btn3"); 
    JLabel l1 = new JLabel("Lbl1");
    JLabel l2 = new JLabel("Lbl2");
    JLabel l3 = new JLabel("Lbl3");
    JPanel panel = new JPanel();

    private JComponent[][] randObjects = {{b1, b2, b3}, {l1, l2, l3}, {panel, panel, panel}};
    private Color[] randColors = {Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE, Color.MAGENTA};


    public ScratchPaper() {
        initGUI();
        setTitle("EXAMPLE");
        pack();
        setLocationRelativeTo(null);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    private void initGUI() {
        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new GridLayout(GRIDSIZE, GRIDSIZE)); // makes 8*8 grid
        add(centerPanel, BorderLayout.CENTER);

        MouseAdapter ma = new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                Component clickedComp = findComponentAt(e.getPoint());
                JPanel target = (JPanel) clickedComp;
                panel.setBackground(randColors[rand.nextInt(randColors.length)]);

                if (target instanceof WhitePanel){
                    target.add(randObjects[rand.nextInt(randObjects.length)][rand.nextInt(randObjects[0].length)]); 
                    target.updateUI();
                }
            }
        };
        addMouseListener(ma);

         for (int row=0; row<GRIDSIZE; row++) {
            for (int col=0; col<GRIDSIZE; col++) {
                whitePanel[row][col] = new WhitePanel(row, col);
                blackPanel[row][col] = new BlackPanel(row, col);

                if ((row%2 == 0 && col%2 == 0) || ((row+1)%2 == 0 && (col+1)%2 == 0)) {
                    centerPanel.add(whitePanel[row][col]);
                } 
                else {
                    centerPanel.add(blackPanel[row][col]);
                }
            }
         }
    }


    public static void main(String args[]) {
        try {
            String className = UIManager.getCrossPlatformLookAndFeelClassName();
            UIManager.setLookAndFeel(className);
        } catch (Exception ex) {
            System.out.println(ex);
        }

        EventQueue.invokeLater(new Runnable(){
            @Override
            public void run(){
                new ScratchPaper();
            }
        });
    }

    class WhitePanel extends JPanel {   
        private static final int SIZE = 50;

        public WhitePanel(int row, int col) {
            Dimension size = new Dimension(SIZE, SIZE);
            setPreferredSize(size);
            setBackground(Color.WHITE);
        }
    }

    class BlackPanel extends JPanel {
        private static final int SIZE = 50;

        public BlackPanel(int row, int col) {
            Dimension size = new Dimension(SIZE, SIZE);
            setPreferredSize(size);
            setBackground(Color.BLACK);
        }
    }
}

有没有更好的方法来计算点积而不使用let inline dot a b = List.zip a b |> List.map (fun (a, b) -> a * b) |> List.reduce (+)

3 个答案:

答案 0 :(得分:6)

一种较短的方法是使用List.map2

let inline dot a b = List.map2 (*) a b |> List.sum

另一种方法是使用List.fold2

let inline dot a b = List.fold2 (fun state x y -> state + x * y) LanguagePrimitives.GenericZero a b

答案 1 :(得分:3)

我同样需要使用带有矩阵的F#进行神经网络,但你可以使用向量。

我使用MathNet Numerics,其中包含许多其他函数dot product

确保同时获得coreF# extensions

如果您正在使用神经网络并将MathNet Numerics与矩阵一起使用,那么您可能需要Sigmoid function

MathNet Raise Scalar by a Matrix

这是与F#中使用MathNet数字矩阵的神经网络相关的反向传播example

答案 2 :(得分:3)

在提议的三个中,我认为使用List.fold2的那个是最快的:

let inline dot1 a b =
    List.zip a b
    |> List.map (fun (a, b) -> a * b)
    |> List.reduce (+)

let inline dot2 a b = List.map2 (*) a b |> List.sum

// Modified with 0.0 instead of 0 and no 'inline'
let dot3 a b = List.fold2 (fun state x y -> state + x * y) 0.0 a b

let xs = [0.0..1000000.0]

> dot1 xs xs;;
Real: 00:00:00.242,

> dot2 xs xs;;
Real: 00:00:00.070

> dot3 xs xs;;
Real: 00:00:00.003

压缩这两个列表可能相当昂贵。 map2-sum解决方案更快,但在列表中迭代两次。 fold2解决方案仅在列表中进行一次。