我写了一个带有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 (+)
?
答案 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。
确保同时获得core和F# 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
解决方案仅在列表中进行一次。